Python 用于U-Net图像分割的Keras图像生成器中的分割验证数据
我正在尝试训练一个用于图像分割的U-net网络 我克隆了这个存储库(),它有一个U-net的Keras实现 我的数据组织在存储库中的3个文件夹中: 列车/图像:包含原始图像 序列/标签:包含原始图像的遮罩 test/:包含新的原始图像,以查看网络在培训后的性能 我得到了一个可以分段的网络,但它在培训期间不使用验证数据 我希望有一个验证失败,并有一个回调停止培训时,验证失败没有改善Python 用于U-Net图像分割的Keras图像生成器中的分割验证数据,python,keras,image-segmentation,Python,Keras,Image Segmentation,我正在尝试训练一个用于图像分割的U-net网络 我克隆了这个存储库(),它有一个U-net的Keras实现 我的数据组织在存储库中的3个文件夹中: 列车/图像:包含原始图像 序列/标签:包含原始图像的遮罩 test/:包含新的原始图像,以查看网络在培训后的性能 我得到了一个可以分段的网络,但它在培训期间不使用验证数据 我希望有一个验证失败,并有一个回调停止培训时,验证失败没有改善 model_checkpoint = ModelCheckpoint('unet_master.hdf5', mon
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预先定义的(请参见末尾)
现在,我正在尝试生成Validation_生成器,但没有成功
我读过这期:
本教程:
但我没办法。
我的问题是理解在我的案例中什么是“数据”。是火车文件夹吗?为什么我必须有一个图像发生器和一个遮罩发生器
我已尝试为图像和遮罩创建一个生成器,并为验证创建另一个生成器,如下所示:
#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,
color_mode = image_color_mode,
target_size = target_size,
subset='training',
batch_size = batch_size,
save_to_dir = save_to_dir,
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,
color_mode = image_color_mode,
target_size = target_size,
subset='validation',
batch_size = batch_size,
save_to_dir = save_to_dir,
seed = seed)
这将产生:
找到了164张属于2类的图片。
找到了164张属于2类的图片。
找到了68张属于2类的图片
然后我跑:
model_checkpoint = ModelCheckpoint('unet_master.hdf5', monitor='val_loss',verbose=1, save_best_only=True)
#added earlystopping
earlystopping = EarlyStopping(monitor='val_loss', patience=10, verbose=1, mode='min')
callbacks_list = [model_checkpoint, earlystopping]
model=unet()
model.fit_generator(my_new_generator, validation_data=validation_generator, steps_per_epoch=20,epochs=1,callbacks=callbacks_list)
我得到的错误是:
ValueError:无法将输入数组从形状(256256,1)广播到形状(1)
我知道图像生成器和遮罩生成器是错误的,因为如果我在图像生成器中循环,我会看到图像和遮罩。但我不知道我做错了什么
非常感谢您对如何分割数据进行验证的任何帮助
多谢各位
使用的功能:
def adjustData(img,mask,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],index[1],np.zeros(len(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],
class_mode = None,
color_mode = image_color_mode,
target_size = target_size,
batch_size = batch_size,
save_to_dir = save_to_dir,
save_prefix = image_save_prefix,
seed = seed)
mask_generator = mask_datagen.flow_from_directory(
train_path,
classes = [mask_folder],
class_mode = None,
color_mode = mask_color_mode,
target_size = target_size,
batch_size = batch_size,
save_to_dir = save_to_dir,
save_prefix = mask_save_prefix,
seed = seed)
train_generator = zip(image_generator, mask_generator)
for (img,mask) in train_generator:
img,mask = adjustData(img,mask,flag_multi_class,num_class)
yield (img,mask)
def adjustData(img、mask、flag\u multi\u class、num\u class):
如果(标记多类):
img=img/255
掩码=掩码[:,:,:,0]如果(len(mask.shape)==4)其他掩码[:,:,0]
新的掩码=np.0(mask.shape+(num\u类)
对于范围内的i(num_类):
#对于图像中的一个像素,在mask中找到类并将其转换为一个热向量
#索引=np,其中(掩码=i)
#索引掩码=(索引[0]、索引[1]、索引[2]、np.zeros(len(索引[0])、dtype=np.int64)+i如果(len(掩码形状)==4)其他(索引[0]、索引[1]、np.zeros(len(索引[0])、dtype=np int64)+i)
#新屏蔽[索引屏蔽]=1
新的屏蔽[mask==i,i]=1
new_mask=np.Reformate(new_mask,(new_mask.shape[0],new_mask.shape[1]*new_mask.shape[2],new_mask.shape[3])如果标记了multi_类,则为np.Reformate(new_mask,(new_mask.shape[0]*new_mask.shape[1],new_mask.shape[2]))
掩码=新的\u掩码
elif(np.max(img)>1):
img=img/255
掩码=掩码/255
遮罩[遮罩>0.5]=1
面具