重现的简单代码如下
import tensorflow as tf
import tensorflow.keras as keras
inp = keras.Input((3, 3))
layer = keras.layers.Dense(1)
tar = layer(inp)
tar2 = layer(inp, training=False)
model2 = keras.Model(inp, tar2)
model2.compile(loss='mse', optimizer=keras.optimizers.Adam(0.01))
# fit
a = tf.random.normal((1, 3, 3))
b = tf.random.normal((1, 3, 1))
model2.fit(a, b)
如果您在训练之前/之后检查
model2.trainable_variables
,您可以轻松检查model2
的参数已更改,这意味着它已经被训练了。
我应该怎么做才能在训练期间不更新特定时间的特定层?
我需要的原因是,我的方案是重用我之前制作的一些层,并且我不希望在我仍然更新模型中的其他层时再次训练这些层。如下:
inp1 = keras.Input((2, 3))
inp2 = keras.Input((4, 3))
layer1 = keras.layers.Dense(1)
intermediate_output1 = layer1(inp1)
intermediate_output2 = layer1(inp2, training=False) # I don't want to train this layer again for inp2.
added = tf.concat([intermediate_output1, intermediate_output2], axis=1)
layer2 = keras.layers.Dense(2)
final_output = layer2(added)
final_output.shape # [None, 6, 4]
layer = tf.keras.layers.Dense(12)
layer.trainable = False
您也可以对模型执行此操作,然后该模型的所有层都将被冻结。
model.trainable = False
model.layers[0].trainable # -> False
。对于大多数层来说,这不会改变任何事情,例如Dense
层在推理训练和验证中的行为相同。但例如
Dropout
层在训练中和外部表现不同。通常,在训练之外会禁用 dropout 层。inp = tf.keras.layers.Input((12,))
drop = tf.keras.layers.Dropout()(inp, training=True)
在此示例中,您将获得一个
Monte Carlo Dropout
层。这是一个始终处于活动状态的
Dropout
层,无论训练或测试时间如何。