【问题标题】:Keras: How to use fit_generator with multiple outputs of different typeKeras:如何将 fit_generator 与不同类型的多个输出一起使用
【发布时间】:2016-12-22 16:19:06
【问题描述】:

在带有功能 API 的 Keras 模型中,我需要调用 fit_generator 以使用 ImageDataGenerator 对增强图像数据进行训练。
问题是我的模型有两个输出:我试图预测的掩码和一个二进制值。
我显然只想增加输入和掩码输出,而不是二进制值。
我怎样才能做到这一点?

【问题讨论】:

    标签: python deep-learning keras


    【解决方案1】:

    实现这一点的最佳方法似乎是创建一个新的生成器类,扩展 Keras 提供的生成器类,该类解析数据,仅增加图像并产生所有输出。

    【讨论】:

    • 您能与文档字符串共享代码吗?我有代码,但我无法理解其工作原理。
    【解决方案2】:

    下面的例子可能是不言自明的! “虚拟”模型需要 1 个输入(图像)并输出 2 个值。该模型计算每个输出的 MSE。

    x = Convolution2D(8, 5, 5, subsample=(1, 1))(image_input)
    x = Activation('relu')(x)
    x = Flatten()(x)
    x = Dense(50, W_regularizer=l2(0.0001))(x)
    x = Activation('relu')(x)
    
    output1 = Dense(1, activation='linear', name='output1')(x)
    output2 = Dense(1, activation='linear', name='output2')(x)
    
    model = Model(input=image_input, output=[output1, output2])
    model.compile(optimizer='adam', loss={'output1': 'mean_squared_error', 'output2': 'mean_squared_error'})
    

    下面的函数会在训练期间生成批次以供模型使用。它采用训练数据x 和标签y 其中y=[y1, y2]

    def batch_generator(x, y, batch_size, is_train):
        sample_idx = 0
        while True:
           X = np.zeros((batch_size, input_height, input_width, n_channels), dtype='float32')
           y1 = np.zeros((batch_size, mask_height, mask_width), dtype='float32')
           y2 = np.zeros((batch_size, 1), dtype='float32')
    
           # fill up the batch
           for row in range(batch_sz):
               image = x[sample_idx]
               mask = y[0][sample_idx]
               binary_value = y[1][sample_idx]
               # transform/preprocess image
               image = cv2.resize(image, (input_width, input_height))
               if is_train:
                   image, mask = my_data_augmentation_function(image, mask)
               X_batch[row, ;, :, :] = image
               y1_batch[row, :, :] = mask
               y2_batch[row, 0] = binary_value
               sample_idx += 1
    
           # Normalize inputs
           X_batch = X_batch/255.
           yield(X_batch, {'output1': y1_batch, 'output2': y2_batch} ))
    

    最后,我们调用 fit_generator()

    model.fit_generator(batch_generator(X_train, y_train, batch_size, is_train=1))
    

    【讨论】:

    • 中的内容......转换图像......生成批量大小:batch_size。在你的答案中?
    • 我编辑了答案以添加更多细节。希望对您有所帮助。
    • @JMarc 如何将此生成器与ImageDataGenerator 合并,以便它对 Rank-4 图像矩阵进行所有预处理,但输出结果会被输入new_generator() 以映射值图像到y=[y1,y2] 用于训练和验证?
    【解决方案3】:

    如果你已经分离了掩码和二进制值,你可以尝试这样的事情:

    generator = ImageDataGenerator(rotation_range=5.,
                                    width_shift_range=0.1, 
                                    height_shift_range=0.1, 
                                    horizontal_flip=True,  
                                    vertical_flip=True)
    
    def generate_data_generator(generator, X, Y1, Y2):
        genX = generator.flow(X, seed=7)
        genY1 = generator.flow(Y1, seed=7)
        while True:
                Xi = genX.next()
                Yi1 = genY1.next()
                Yi2 = function(Y2)
                yield Xi, [Yi1, Yi2]
    

    因此,您对输入和掩码使用相同的生成器使用相同的种子来定义相同的操作。您可以根据需要更改或不更改二进制值(Y2)。然后,调用 fit_generator():

    model.fit_generator(generate_data_generator(generator, X, Y1, Y2),
                    epochs=epochs)
    

    【讨论】:

    • 单独的掩码和二进制值是什么意思?
    • @Jose 我有类似的问题,我有Y1=df[:,'label_1'].valuesy2=df[:,label_2'].values。在那种情况下我可以使用你的发电机吗?另外,我的图像采用 Rank-4 矩阵的形式。即形状矩阵(rows,weight,height,1) 用于灰度图像并使用最小flow() 方法。
    猜你喜欢
    • 2018-08-30
    • 2021-03-04
    • 2018-08-20
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-20
    相关资源
    最近更新 更多