Python u-net中的多层灰度输入

Python u-net中的多层灰度输入,python,tensorflow,keras,image-segmentation,Python,Tensorflow,Keras,Image Segmentation,我已经使用(256,256,1)灰度输入和(256,256,1)二进制标签成功地训练了一个用于细胞分割特定任务的u-net。我在Keras中使用了zhixuhao的unet实现(git rep.)。我现在尝试的是使用多个灰度层作为输入来训练同一个模型 为了使事情更简单,让我们假设我想要使用2个灰度图像im1和im2,每个图像的大小(256,256,1)。标签Y与im1和im2相同。我想给模型输入一个大小(256,256,2),其中第三轴的第一个分量是im1,第二个分量是im2 为此,我将列车数据

我已经使用
(256,256,1)
灰度输入和
(256,256,1)
二进制标签成功地训练了一个用于细胞分割特定任务的u-net。我在Keras中使用了zhixuhao的unet实现(git rep.)。我现在尝试的是使用多个灰度层作为输入来训练同一个模型

为了使事情更简单,让我们假设我想要使用2个灰度图像
im1
im2
,每个图像的大小
(256,256,1)
。标签
Y
im1
im2
相同。我想给模型输入一个大小
(256,256,2)
,其中第三轴的第一个分量是
im1
,第二个分量是
im2

为此,我将列车数据生成器更改为:

def MultipleInputGenerator(train_path, sub_path_1, sub_path_2, image_folder='images', mask_folder='masks', batch_size, aug_dict, images_color_mode='grayscale', masks_color_mode='grayscale',
            flag_multi_class=False, num_class=2, target_size=(256,256), seed=1):

    # Keras generator
    image_datagen = ImageDataGenerator(**aug_dict)
    mask_datagen = ImageDataGenerator(**aug_dict)

    # Multiple input data augmentation
    image_generator_1 = image_datagen.flow_from_directory(
            sub_path_1,
            classes = [image_folder],
            class_mode = None,
            color_mode = images_color_mode,
            target_size = target_size,
            batch_size = batch_size,
            seed = seed)

    image_generator_2 = image_datagen.flow_from_directory(
            sub_path_2,
            classes = [image_folder],
            class_mode = None,
            color_mode = images_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 = masks_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_1, image_generator_2, mask_generator)

    for (img1, img2, mask) in train_generator:
        img1, mask1 = adjustData(img1, mask, flag_multi_class, num_class)
        img2, mask2 = adjustData(img2, mask, flag_multi_class, num_class)
        yield (np.stack((img1, img2), axis=0), mask1)
adjustData
是一个辅助功能,它将数组从[0,255]标准化为[0,1]

如您所见,我尝试在单个输入中堆叠灰度数组。 创建unet模型时,我将输入大小从
(256,256,1)
更改为
(256,256,2)

train_gen = MultipleInputGenerator(train_folder, sub_path_1, sub_path_2, batch_size, aug_dict=data_gen_args)
model = unet(input_size=(256,256,2))
model.fit_generator(train_gen, steps_per_epoch=train_steps, epochs=epochs)
但是,当启动命令:
python3 main.py
时,它开始正确加载数据,但随后无法训练模型:

Found 224 images belonging to 1 classes.
Epoch 1/2
Found 224 images belonging to 1 classes.
Found 224 images belonging to 1 classes.
Traceback (most recent call last):
  File "main.py", line 50, in <module>
    model.fit_generator(train_gen, steps_per_epoch=train_steps, epochs=epochs)
  File "*/virtenv/env1/lib/python3.6/site-packages/keras/legacy/interfaces.py", line 91, in wrapper
    return func(*args, **kwargs)
  File "*/virtenv/env1/lib/python3.6/site-packages/keras/engine/training.py", line 1732, in fit_generator
    initial_epoch=initial_epoch)
  File "*/virtenv/env1/lib/python3.6/site-packages/keras/engine/training_generator.py", line 220, in fit_generator
    reset_metrics=False)
  File "*/virtenv/env1/lib/python3.6/site-packages/keras/engine/training.py", line 1508, in train_on_batch
    class_weight=class_weight)
  File "*/virtenv/env1/lib/python3.6/site-packages/keras/engine/training.py", line 579, in _standardize_user_data
    exception_prefix='input')
  File "*/virtenv/env1/lib/python3.6/site-packages/keras/engine/training_utils.py", line 135, in standardize_input_data
    'with shape ' + str(data_shape))
ValueError: Error when checking input: expected input_1 to have 4 dimensions, but got array with shape (2, 32, 256, 256, 1)
找到224个属于1个类的图像。
纪元1/2
找到224张属于1类的图像。
找到224张属于1类的图像。
回溯(最近一次呼叫最后一次):
文件“main.py”,第50行,在
模型安装发电机(发电机组,每历元步数=发电机组步数,历元数=历元数)
包装器中的第91行文件“*/virtenv/env1/lib/python3.6/site packages/keras/legacy/interfaces.py”
返回函数(*args,**kwargs)
文件“*/virtenv/env1/lib/python3.6/site packages/keras/engine/training.py”,第1732行,在fit_生成器中
初始_历元=初始_历元)
文件“*/virtenv/env1/lib/python3.6/site packages/keras/engine/training\u generator.py”,第220行,在fit\u generator中
重置(度量值=False)
文件“*/virtenv/env1/lib/python3.6/site packages/keras/engine/training.py”,第1508行,在批量生产中
等级重量=等级重量)
文件“*/virtenv/env1/lib/python3.6/site packages/keras/engine/training.py”,第579行,在用户数据中
异常(前缀为“输入”)
标准化输入数据中的文件“*/virtenv/env1/lib/python3.6/site packages/keras/engine/training\u utils.py”,第135行
“带形状”+str(数据形状))
ValueError:检查输入时出错:预期输入_1有4个维度,但得到了具有形状(2、32、256、256、1)的数组
32为批次大小

除了RGB图像外,是否有人已经设法使用多层输入来训练unet(或任何其他CNN)?或者有没有人知道我该如何让它工作


谢谢。

您期望的输入形状是
(32,256,256,2)
,而生成器的输出形状是
(2,32,256,256,1)
。这是因为
np.stack
比输入数组增加了一个额外的维度。您可以通过在
train\u生成器中使用
np.concatenate
而不是
np.stack
来解决此问题,如下所示:

yield (np.concatenate((img1, img2), axis=-1), mask1)

希望能有所帮助。

正如@bit01所建议的,
np.stack
比输入数组增加了一个维度!为了让事情顺利进行,我编辑了
多输入按钮生成器
函数的最后一行,如下所示:

img = np.squeeze(np.stack((img1, img2), axis=3), axis=4)
yield (img, mask1)

它应该可以与
np一起使用。也可以连接
,但我没有尝试过。

您好,谢谢您的回答!我用一种类似的方法(我在np.stack之后使用了np.squeeze),我将在下面编写我的代码的最终版本。正如im2定义为(256,256,2),你是指多模态图像吗?我不确定我是否完全理解你的问题。我可以访问同一张图片的多个灰色图像,每个图像都突出显示了原始图片中的不同元素(例如,如果原来的图片是由一组人组成的:那么我就可以考虑4张灰色图像:1张一张,所有的人都穿着裤子,2张一条,所有的人都穿着短裤,3张一张,所有的人都穿着T恤,4张一张戴着帽子的人,我想把这些多张2D图像叠加成一张3D输入。