keras的奇怪训练问题 - FC层中的零点突然大幅下降

时间:2016-12-28 15:10:26

标签: keras

我正在通过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层被设置为全零。即便如此,当训练数据不是全零时,我也不明白这是如何造成非常低的损失。

1 个答案:

答案 0 :(得分:0)

对于似乎由最后一层预测的零,可能发生的是垂死的ReLU问题。尝试LeakyReLU,调整alpha。这对我来说是有效的,它可以消除我会在第一个时期本身得到的零。