用于图像分割的U网转移学习[Keras]

用于图像分割的U网转移学习[Keras],keras,deep-learning,image-segmentation,transfer-learning,Keras,Deep Learning,Image Segmentation,Transfer Learning,刚刚开始使用Conv网络并尝试一个图像分割问题。在dstl卫星图像特征检测比赛中,我得到了24幅图像及其遮罩。() 我想我会尝试遵循这里的提示,但我被卡住了 我下载了ZF_UNET_224的预训练权重,这是第二名的优胜者解决此问题的方法。我的图像遮罩包含5个对象,因此我弹出了最后一层,而不是: activation_45 (Activation) (None, 224, 224, 32) 0 batch_normalization_44[0][0] spatial_dropout2d_2 (S

刚刚开始使用Conv网络并尝试一个图像分割问题。在dstl卫星图像特征检测比赛中,我得到了24幅图像及其遮罩。()

我想我会尝试遵循这里的提示,但我被卡住了

我下载了ZF_UNET_224的预训练权重,这是第二名的优胜者解决此问题的方法。我的图像遮罩包含5个对象,因此我弹出了最后一层,而不是:

activation_45 (Activation) (None, 224, 224, 32) 0 batch_normalization_44[0][0]

spatial_dropout2d_2 (SpatialDro (None, 224, 224, 32) 0 activation_45[0][0]

conv2d_46 (Conv2D) (None, 224, 224, 1) 33 spatial_dropout2d_2[0][0]
我现在有:

activation_45 (Activation) (None, 224, 224, 32) 0 batch_normalization_44[0][0]

spatial_dropout2d_2 (SpatialDro (None, 224, 224, 32) 0 activation_45[0][0]

predictions (Conv2D) (None, 224, 224, 5) 10 conv2d_46[0][0]
我试图按照Keras教程中的确切步骤进行操作,但是当我这样做的时候

my_model.fit_generator( train_generator, steps_per_epoch= 4, epochs=10, validation_data=validation_generator )
我收到一条错误消息说

Output of generator should be a tuple (x, y, sample_weight) or (x, y). Found: [[[[1. 1. 1. ] [1. 1. 1. ] [1. 1. 1. ] … [1. 1. 1. ] [1. 1. 1. ] [1. 1. 1. ]]
我想我想要的是224X224图像中每个像素的概率,这样我就可以用它们在原始图像上生成遮罩,但我不知道如何才能得到它

我有24个8波段的输入图像和它们的遮罩,它们标记了5个对象。我想在这些图像上训练这个U网络,在一些测试图像上放置遮罩,并评估它们的IoU或加权日志损失。有什么帮助吗

更新:

我使用的生成器与Keras教程中相同:

   batch_size = 4

    # this is the augmentation configuration we will use for training 

train_datagen = ImageDataGenerator(
            rescale=1./255,
            shear_range=0.2,
            zoom_range=0.2,
            horizontal_flip=True)

    # this is the augmentation configuration we will use for testing:
    # only rescaling 
test_datagen = ImageDataGenerator(
            rescale=1./255,
            shear_range=0.2,
            zoom_range=0.2,
            horizontal_flip=True)

    # this is a generator that will read pictures found in
    # subfolers of 'data/train', and indefinitely generate
    # batches of augmented image data train_generator = 
train_datagen.flow_from_directory(
            'data/train',  # this is the target directory
            target_size=(224, 224),  # all images will be resized 
            batch_size=batch_size,
            color_mode='rgb', 
            class_mode=None)  # since we use binary_crossentropy loss, we need binary labels

    # this is a similar generator, for validation data 
 validation_generator = test_datagen.flow_from_directory(
            'data/valid',
            target_size=(224, 224),
            batch_size=batch_size,
            color_mode = 'rgb',
            class_mode=None)

还有一件事:我的训练图像有8个波段,但架构只接受3个波段。我想发电机最后只剩下一个波段。也不确定如何解决此问题。

在错误消息中:

使用
flow\u from\u directory()
,您的
ImageDataGenerator
从包含图像的目录结构推断类标签。如示例中所示,图像应按类排列在子文件夹中

对于图像分割问题,标签结构比每个图像只有一个标签更复杂。标签是具有每像素标签的遮罩。通常,您希望在培训期间将这些标签作为
np数组
提供给模型

您将无法使用
flow\u from\u directory()
处理您的案例。一种解决方案是编写自己的自定义生成器,从磁盘读取图像和标签,并将其与
fit\u generator()
一起使用

假设您有一个包含两列的.csv文件,一列包含图像名称,另一列包含相应掩码的路径:

然后,您的生成器可能看起来像这样(我使用
pandas
读取.csv文件):

来自keras.utils导入序列
从keras.preprocessing.image导入加载\u img
从keras.preprocessing.image导入img_到_数组
从数学导入单元
将numpy作为np导入
作为pd进口熊猫
类数据序列(序列):
"""
Keras序列对象在大于内存的数据上训练模型。
df:csv文件中的数据帧
数据路径:图像所在的路径
"""
定义初始化(自我、df、数据路径、批次大小):
self.batch\u size=批次大小
self.im_list=df['images'].tolist()
self.mask_list=df['labels'].tolist()
定义(自我):
“”“确保处理最后一批<批次大小
返回int(math.ceil(len(self.im\u列表)/float(self.batch\u大小)))
def获取批处理图像(自身、idx、路径列表):
#从路径列表中获取一批图像
返回np.array([load_image(im)for im in path_list[idx*self.batch_size:(1+idx)*self.batch_size]]))
def uu getitem uu(self,idx):
batch\u x=self.get\u批处理图像(idx,self.im\u列表)
批处理y=self.get\u批处理标签(idx,self.mask\u列表)
返回批次x,批次y
我在这里使用Keras
Sequence
对象来编写生成器,因为这允许进行安全的多处理,这将加快培训速度。请参阅有关此主题的

关于迁移学习的实际问题


您将无法使用针对8通道图像上的3通道图像进行预训练的体系结构。如果您想使用该体系结构,您可以对通道进行子采样,或者将通道从8通道缩减为3通道。另请参阅线程。

您可以共享您的训练生成器吗?它的最后一行应该类似于
yiel d X,y
。看起来您只生成了两者中的一个。我使用的是标准生成器格式。更新如上。您好,非常感谢您的回复。我查看了Keras github上的一些问题,发现他们建议制作一个同时生成图像和掩码的生成器,因此我使用zip将两者结合起来(image_generator,mask_generator)。在检查目标时,我仍然会收到一个错误,上面写着ValueError:error:预期conv2d_26具有形状(224224,224,5),但得到了具有形状(224,224,3)的数组您需要将您的遮罩从RGB图像转换为图像,其中每个像素由一个二进制向量组成,指示该类属于哪个像素。请参阅,谢谢您的回答。我不完全确定如何将一个热编码应用于遮罩生成器。有什么提示吗?您正在使用Kaggle数据。请查看其他人是如何做到这一点的。
from keras.utils import Sequence
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from math import ceil 
import numpy as np
import pandas as pd


class DataSequence(Sequence):
    """
    Keras Sequence object to train a model on larger-than-memory data.
    df: pandas dataframe from the csv file
    data_path: path where your images live
    """

    def __init__(self, df, data_path, batch_size):
        self.batch_size = batch_size
        self.im_list = df['images'].tolist()
        self.mask_list = df['labels'].tolist()

    def __len__(self):
        """Make sure to handle cases where the last batch < batch_size
        return int(math.ceil(len(self.im_list) / float(self.batch_size)))

    def get_batch_images(self, idx, path_list):
        # Fetch a batch of images from a list of paths
        return np.array([load_image(im) for im in path_list[idx * self.batch_size: (1 + idx) * self.batch_size]])

    def __getitem__(self, idx):
        batch_x = self.get_batch_images(idx, self.im_list)
        batch_y = self.get_batch_labels(idx, self.mask_list)
        return batch_x, batch_y