我正在通过Keras(Tensor Flow后端,Ubuntu 14.04,Cuda 8,带cudnn)培训暹罗风格的CNN来解决这个奇怪的问题 . 简而言之,CNN具有共享的权重集,其接收两个图像,合并它们各自的FC层,然后估计回归 . 我正在使用带有Adam优化器的MSE丢失(使用默认参数) . 我已经用不同类型的问题多次这样做了,从未见过以下内容 .

基本上发生的事情是在第一个时代,一切似乎都训练得很好,并且损失正在缓慢下降,正如预期的那样(使用32的批量大小结束在约3.3的MSE附近) . 回归估计了9维连续值向量 .

然后,一旦第二个纪元开始,损失就会急剧下降(至~4e-07) . 你会想“哦,你的损失真的很小 - 我赢了”,但当我通过预测新的输入来检查训练的重量时(我使用检查指针根据损失丢弃最好的权重集) ,我的行为很奇怪 . 无论输入是什么(不同的图像,随机噪声作为输入,甚至是零),我总能获得相同的输出 . 进一步检查显示共享权重中的最后一个FC层都是零 .

如果我看到第一个时代之后的权重,当一切看起来都“正常”时,这不会发生 - 我只是没有得到最佳结果(有道理 - 只发生了一个时代) . 这只发生在第二个时代和之后 .

有没有人见过这个?有任何想法吗?你认为这对我来说是一个愚蠢的错误,还是一些奇怪的错误?

有关我的网络拓扑的更多详细信息 . 以下是共享权重:

shared_model = Sequential()

shared_model.add(Convolution2D(nb_filter=96, nb_row=9, nb_col=9, activation='relu', subsample=(2,2), input_shape=(3,height,width)))
shared_model.add(MaxPooling2D(pool_size=(2,2)))
shared_model.add(Convolution2D(nb_filter=256, nb_row=3, nb_col=3, activation='relu', subsample=(2,2)))
shared_model.add(MaxPooling2D(pool_size=(2,2)))
shared_model.add(Convolution2D(nb_filter=256, nb_row=3, nb_col=3, activation='relu'))
shared_model.add(MaxPooling2D(pool_size=(2,2)))
shared_model.add(Convolution2D(nb_filter=512, nb_row=3, nb_col=3, activation='relu', subsample=(1,1)))

shared_model.add(Flatten())

shared_model.add(Dense(2048, activation='relu'))
shared_model.add(Dropout(0.5))

然后我将它们合并为回归,如下所示:

input_1 = Input(shape=(3,height,width))
input_2 = Input(shape=(3,height,width))
encoded_1 = shared_model(input_1)
encoded_2 = shared_model(input_2)
encoded_merged = merge([encoded_1, encoded_2], mode='concat', concat_axis=-1)
fc_H = Dense(9, activation='linear')
h_loss = fc_H(encoded_merged)
model = Model(input=[input_1, input_2], output=h_loss)

最后,每个时期都会训练大约1,000,000个样本,所以应该有大量的数据需要训练 . 我从未见过FC层被设置为全零 . 即便如此,当训练数据不是全零时,我也不明白这是如何造成非常低的损失的 .