我正在使用Keras / Tensorflow进行回归CNN。我有一个多输出前馈模型,我已经对其进行了成功的训练。该模型将获取一张201x201灰度图像,并返回两个回归目标。
以下是输入/目标对的示例:
存在针对此问题的分析解决方案,因此我知道它可以解决。
这是模型架构:
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'时,我获得了相当不错的准确度,但是有一个偏移量:
这是一件很容易修复的事情,我只是对预测应用线性拟合并将其反转以重新缩放:
但是我想不出为什么会首先发生这种情况的原因。对于其他问题,我使用了相同的模型架构,并且再次得到了相同的偏移量。有人看过这种东西吗?
编辑:此偏移量发生在多个不同的Mine模型中,每个模型都预测不同的参数,但以相同的方式重新缩放/预处理。无论我训练多少个纪元,它都会发生,更多的训练会导致预测更加紧贴绿线(在第一张图中)。
作为临时的解决方法,我训练了一个单节点模型,以将输入作为原始模型的预测,并将输出作为基本事实。这样可以很好地训练并纠正偏移量。不过,奇怪的是,我可以将此重缩放模型应用于出现此问题的任何模型,并且它可以同样好地校正偏移量。
基本上:对于多个不同的模型,其偏移量具有相同的权重,这些模型可以预测完全不同的参数。这使我认为与激活或正则化有关。