我正在使用Keras / Tensorflow进行回归CNN . 我有一个多输出前馈模型,我已经训练了一些成功 . 该模型采用201x201灰度图像并返回两个回归目标 .

以下是输入/目标对的示例:

enter image description here
与(z = 562.59,a = 4.53)相关联

这个问题存在分析解决方案,所以我知道它是可以解决的 .

这是模型架构:

model_input = keras.Input(shape=input_shape, name='image')                                                        
x = model_input                                                                                                   
x = Conv2D(32, kernel_size=(3, 3), activation='relu')(x)                                                          
x = MaxPooling2D(pool_size = (2,2))(x)                                                                            
x = Conv2D(32, kernel_size=(3, 3), activation='relu')(x)                                                          
x = MaxPooling2D(pool_size = (2,2))(x)                                                                            
x = Conv2D(32, kernel_size=(3, 3), activation='relu')(x)                                                          
x = MaxPooling2D(pool_size = (2,2))(x)                                                                            
x = Conv2D(16, kernel_size=(3, 3), activation='relu')(x)                                                          
x = MaxPooling2D(pool_size = (4,4))(x)                                                                            
x = Flatten()(x)                                                                                                 
model_outputs = list()
out_names = ['z', 'a']                                                                             
for i in range(2):
    out_name = out_names[i]                                                              
    local_output= x
    local_output = Dense(10, activation='relu')(local_output)
    local_output = Dropout(0.2)(local_output)
    local_output = Dense(units=1, activation='linear', name = out_name)(local_output)
    model_outputs.append(local_output)
model = Model(model_input, model_outputs)
model.compile(loss = 'mean_squared_error', optimizer='adam', loss_weights = [1,1])

我的目标是在不同的比例,所以我将其中一个(名字'a')标准化到范围[0,1]进行训练 . 以下是我如何重新缩放:

def rescale(min, max, list):
    scalar = 1./(max-min)
    list = (list-min)*scalar
    return list

其中每个参数的最小值,最大值是先验已知的并且是常数 .

这是我训练的方式:

model.fit({'image' : x_train},
          {'z' : z_train, 'a' : a_train},         
          batch_size = 32,
          epochs=20,
          verbose=1,
          validation_data = ({'image' : x_test},
                             {'z' : z_test, 'a' : a_test}))

当我预测'a'时,我得到了相当好的准确度,但有一个偏移量:

enter image description here

这是一个相当容易解决的问题,我只是对预测应用线性拟合并将其反转为重新缩放:

enter image description here

但我想不出为什么会发生这种情况的原因 . 我已经将同样的模型架构用于其他问题,并且我再次获得相同的偏移量 . 以前有人见过这种事吗?

编辑:此偏移发生在我的多个不同模型中,每个模型预测不同的参数,但以相同的方式重新调整/预处理 . 无论我训练多少个历元,都会发生这种情况,更多的训练导致预测更紧密地拥抱绿线(在第一个图中) .

作为临时解决方案,我训练了一个单节点模型,将输入作为原始模型的预测,输出作为基础事实 . 这很好地训练,并纠正偏移 . 但奇怪的是,我可以将此重新缩放模型应用于任何具有此问题的模型,并且它可以很好地校正偏移 .

基本上:偏移对于多个不同模型具有相同的权重,这预测完全不同的参数 . 这让我觉得与激活或正规化有关 .