我已经为Keras中的一些时间序列训练了以下模型:
input_layer = Input(batch_shape=(56, 3864))
first_layer = Dense(24, input_dim=28, activation='relu',
activity_regularizer=None,
kernel_regularizer=None)(input_layer)
first_layer = Dropout(0.3)(first_layer)
second_layer = Dense(12, activation='relu')(first_layer)
second_layer = Dropout(0.3)(second_layer)
out = Dense(56)(second_layer)
model_1 = Model(input_layer, out)
然后,我定义了一个新模型,其训练层为model_1
,并向其中添加了具有不同速率drp
的丢弃层:
input_2 = Input(batch_shape=(56, 3864))
first_dense_layer = model_1.layers[1](input_2)
first_dropout_layer = model_1.layers[2](first_dense_layer)
new_dropout = Dropout(drp)(first_dropout_layer)
snd_dense_layer = model_1.layers[3](new_dropout)
snd_dropout_layer = model_1.layers[4](snd_dense_layer)
new_dropout_2 = Dropout(drp)(snd_dropout_layer)
output = model_1.layers[5](new_dropout_2)
model_2 = Model(input_2, output)
那么我得到这两个模型的预测结果如下:
result_1 = model_1.predict(test_data, batch_size=56)
result_2 = model_2.predict(test_data, batch_size=56)
我本来以为会得到完全不同的结果,因为第二个模型有新的丢弃层,这两个模型是不同的(IMO),但事实并非如此。两者都产生了相同的结果。为什么会发生这种情况?
3条答案
按热度按时间6za6bjd01#
正如我在注解中提到的,
Dropout
层在推理阶段(即测试模式)是关闭的,因此当您使用model.predict()
时,Dropout
层是不活动的。然而,如果您希望有一个模型在训练和推理阶段都使用Dropout
,您可以在调用它时传递training
参数,如François Chollet所建议的:或者,如果您已经训练了模型,现在想在推理模式下使用它,并保持
Dropout
层(可能还有其他在训练/推理阶段具有不同行为的层,如BatchNormalization
)处于活动状态,您可以定义一个后端函数,该函数接受模型的输入以及Keras学习阶段:px9o7tmv2#
您的问题在最新版本的Tensorflow中有一个简单的解决方案。您可以将call方法的
training
参数设置为true
。您可以运行类似以下代码的代码:通过使用
training=True
,TensorFlow会在推理模式下自动应用Dropout层。ou6hu8tu3#
由于上面已经有了一些工作代码解决方案,我将简单地添加一些关于推理过程中丢弃的细节,以防止混淆。
在原有论文的基础上,Dropout层起到了关闭的作用(将梯度设置为零),以减少过拟合。然而,一旦我们完成了训练并开始测试模型,我们就不“接触”任何神经元,因此,推理时考虑所有单元以做出决策。这导致先前的“死”由于使用了Dropout,神经元权重大于预期值。为防止这种情况,将应用缩放因子来平衡网络节点。更准确地说,如果在训练期间以概率p保留某个单元,则在预测阶段,该单元的传出权重将乘以p。