冻结的Keras模型中失落层是否仍处于活动状态(即trainable = False)?

时间:2019-08-15 00:57:28

标签: tensorflow machine-learning keras keras-layer dropout

我有两个训练有素的模型(model_Amodel_B),并且他们两个都有辍学层。我冻结了model_Amodel_B并将它们合并到一个新的密集层中以获得model_AB(但是我没有删除model_Amodel_B的辍学层)。 model_AB的权重将是不可训练的,除了增加的密集层。

现在我的问题是:当我训练model_A时,model_Bmodel_AB中的辍学层是否处于活动状态(即神经元掉落)?

1 个答案:

答案 0 :(得分:6)

简短的回答:,即使您将神经元的trainable属性设置为False,辍学层也会继续在训练过程中丢弃神经元

长答案: Keras中有两种不同的概念:

  • 更新图层的权重和状态:这是通过该图层的trainable属性进行控制的,即,如果设置了layer.trainable = False,则权重和内部图层的状态将不会更新。

  • 在培训和测试阶段的行为:如您所知,在培训和测试阶段,辍学之类的图层可能会有不同的行为。使用keras.backend.set_learning_phase()设置Keras中的学习阶段。例如,当您呼叫model.fit(...)时,学习阶段会自动设置为1(即训练),而当您使用model.predict(...)时,学习阶段会自动设置为0(即测试)。此外,请注意,学习阶段1(即训练)并不一定意味着更新层的权重/状态。您可以在学习阶段为1(即训练阶段)的情况下运行模型,但不会更新权重;只是图层将切换到其训练行为(有关更多信息,请参见this answer)。此外,还有另一种方法来设置每个阶段的学习阶段,方法是在张量上调用层时传递training=True参数(有关更多信息,请参见this answer)。

因此,根据以上几点,当您在辍学层上设置trainable=False并将其用于训练模式时(例如,通过调用model.fit(...)或手动将学习阶段设置为训练,如下例所示) ,神经元仍将被退出层丢弃。

以下是可重现的示例,它说明了这一点:

from keras import layers
from keras import models
from keras import backend as K
import numpy as np

inp = layers.Input(shape=(10,))
out = layers.Dropout(0.5)(inp)

model = models.Model(inp, out)
model.layers[-1].trainable = False  # set dropout layer as non-trainable
model.compile(optimizer='adam', loss='mse') # IMPORTANT: we must always compile model after changing `trainable` attribute

# create a custom backend function so that we can control the learning phase
func = K.function(model.inputs + [K.learning_phase()], model.outputs)

x = np.ones((1,10))
# learning phase = 1, i.e. training mode
print(func([x, 1]))
# the output will be:
[array([[2., 2., 2., 0., 0., 2., 2., 2., 0., 0.]], dtype=float32)]
# as you can see some of the neurons have been dropped

# now set learning phase = 0, i.e test mode
print(func([x, 0]))
# the output will be:
[array([[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]], dtype=float32)]
# unsurprisingly, no neurons have been dropped in test phase