如何解决在 Keras Image Generator 中拆分验证数据以用于 U-Net 中的图像分割
我正在尝试训练一个用于图像分割的 U-net 网络。
我克隆了这个存储库 (https://github.com/zhixuhao/unet),它具有 U-net 的 Keras 实现。
我的数据组织在 3 个文件夹中,就像在存储库中一样:
train/image : 包含原始图像
train/label : 包含原始图像的掩码
test/ :包含新的原始图像以查看训练后网络的表现。
我得到一个可以分段的网络,但它在训练期间不使用验证数据。
我想要一个验证损失,并在验证损失没有改善时有一个回调来停止训练。
model_checkpoint = ModelCheckpoint('unet_master.hdf5',monitor='val_loss',verbose=1,save_best_only=True)
#earlystopping
earlystopping = EarlyStopping(monitor='val_loss',patience=10,verbose=0,mode='min')
callbacks_list = [model_checkpoint,earlystopping]
#load unet function
model=unet()
model.fit_generator(my_generator,validation_data=validation_generator,steps_per_epoch=1000,epochs=5,callbacks=callbacks_list)
my_generator 是通过 data.py 文件中的 trainGenerator 和 adjustData 函数预先定义的(见最后)
现在我正在尝试生成validaton_generator,但没有成功。
我已阅读此问题:
https://github.com/keras-team/keras/issues/3900#issuecomment-420693239
和本教程:
https://keras.io/api/preprocessing/image/
但我不管理。 我遇到的问题是理解在我的情况下什么是“数据”的等价物。是火车文件夹吗?为什么我必须有一个 image_generator 和一个 mask_generator?
我尝试为图像和蒙版创建一个生成器,并为验证创建另一个生成器,如下所示:
#added 0.3 validation_split to aug_dict
aug_dict = dict(rotation_range=0.2,width_shift_range=0.05,height_shift_range=0.05,shear_range=0.05,zoom_range=0.05,horizontal_flip=True,vertical_flip=True,fill_mode='nearest',validation_split=0.3)
image_color_mode='grayscale'
target_size=(256,256)
batch_size=1
save_to_dir=None
seed=1
image_datagen = ImageDataGenerator(**aug_dict)
mask_datagen = ImageDataGenerator(**aug_dict)
validation_datagen = ImageDataGenerator(**aug_dict)
# i removed class_mode = None,to have it running
image_generator = image_datagen.flow_from_directory(
train_path,color_mode = image_color_mode,target_size = target_size,subset='training',batch_size = batch_size,save_to_dir = save_to_dir,seed = seed)
mask_generator = mask_datagen.flow_from_directory(
mask_path,seed = seed)
train_generator=zip(image_generator,mask_generator)
#function to run the adjustData function
def return_adjusted_generator(train_generator):
for (img,mask) in train_generator:
img,mask = adjustData(img,mask,flag_multi_class=False,num_class=2)
yield (img,mask)
my_new_generator=return_adjusted_generator(train_generator)
validation_generator = validation_datagen.flow_from_directory(
train_path,class_mode = None,subset='validation',seed = seed)
输出:
找到属于 2 个类别的 164 个图像。 找到属于 2 个类别的 164 个图像。 找到属于 2 个类别的 68 张图片。
然后我跑:
model_checkpoint = ModelCheckpoint('unet_master.hdf5',save_best_only=True)
#added earlystopping
earlystopping = EarlyStopping(monitor='val_loss',earlystopping]
model=unet()
model.fit_generator(my_new_generator,steps_per_epoch=20,epochs=1,callbacks=callbacks_list)
我得到的错误是: ValueError: 无法将输入数组从形状 (256,256,1) 广播到形状 (1)
我知道 image_generator 和 mask_generator 是错误的,因为如果我循环遍历 image_generator,我会看到图像和掩码。但我不知道我做错了什么。
非常感谢有关如何拆分数据以进行验证的任何帮助。
谢谢
使用的函数:
def adjustData(img,flag_multi_class,num_class):
if(flag_multi_class):
img = img / 255
mask = mask[:,:,0] if(len(mask.shape) == 4) else mask[:,0]
new_mask = np.zeros(mask.shape + (num_class,))
for i in range(num_class):
#for one pixel in the image,find the class in mask and convert it into one-hot vector
#index = np.where(mask == i)
#index_mask = (index[0],index[1],index[2],np.zeros(len(index[0]),dtype = np.int64) + i) if (len(mask.shape) == 4) else (index[0],dtype = np.int64) + i)
#new_mask[index_mask] = 1
new_mask[mask == i,i] = 1
new_mask = np.reshape(new_mask,(new_mask.shape[0],new_mask.shape[1]*new_mask.shape[2],new_mask.shape[3])) if flag_multi_class else np.reshape(new_mask,(new_mask.shape[0]*new_mask.shape[1],new_mask.shape[2]))
mask = new_mask
elif(np.max(img) > 1):
img = img / 255
mask = mask /255
mask[mask > 0.5] = 1
mask[mask <= 0.5] = 0
return (img,mask)
def trainGenerator(batch_size,train_path,image_folder,mask_folder,aug_dict,image_color_mode = "grayscale",mask_color_mode = "grayscale",image_save_prefix = "image",mask_save_prefix = "mask",flag_multi_class = False,num_class = 2,save_to_dir = None,target_size = (256,256),seed = 1):
'''
can generate image and mask at the same time
use the same seed for image_datagen and mask_datagen to ensure the transformation for image and mask is the same
if you want to visualize the results of generator,set save_to_dir = "your path"
'''
image_datagen = ImageDataGenerator(**aug_dict)
mask_datagen = ImageDataGenerator(**aug_dict)
image_generator = image_datagen.flow_from_directory(
train_path,classes = [image_folder],save_prefix = image_save_prefix,seed = seed)
mask_generator = mask_datagen.flow_from_directory(
train_path,classes = [mask_folder],color_mode = mask_color_mode,save_prefix = mask_save_prefix,seed = seed)
train_generator = zip(image_generator,mask_generator)
for (img,num_class)
yield (img,mask)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。