keras访问预训练模型层参数冻结

keras access layer parameter of pre-trained model to freeze

我保存了一个多层的 LSTM。现在,我想加载它并微调最后一个 LSTM 层。如何定位该层并更改其参数?

训练并保存的简单模型示例:

model = Sequential()
# first layer  #neurons 
model.add(LSTM(100, return_sequences=True, input_shape=(X.shape[1], 
X.shape[2])))
model.add(LSTM(50, return_sequences=True))
model.add(LSTM(25))
model.add(Dense(1))
model.compile(loss='mae', optimizer='adam')

我可以加载并重新训练它,但我找不到定位特定层并冻结所有其他层的方法。

一个简单的解决方案是为每一层命名,即

model.add(LSTM(50, return_sequences=True, name='2nd_lstm'))

然后,加载模型后,您可以遍历图层并冻结与名称条件匹配的图层:

for layer in model.layers:
    if layer.name == '2nd_lstm':
        layer.trainable = False

然后您需要重新编译您的模型以使更改生效,之后您可以照常恢复训练。

如果您之前构建并保存了模型,现在只想加载它并微调最后一个 LSTM 层,那么您需要将其他层的 trainable 属性 设置为False。首先,使用 model.summary() 方法找到层的名称(或层的索引,从顶部开始从零开始计数)。例如,这是为我的一个模型生成的输出:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_10 (InputLayer)        (None, 400, 16)           0         
_________________________________________________________________
conv1d_2 (Conv1D)            (None, 400, 32)           4128      
_________________________________________________________________
lstm_2 (LSTM)                (None, 32)                8320      
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 33        
=================================================================
Total params: 12,481
Trainable params: 12,481
Non-trainable params: 0
_________________________________________________________________

然后将除LSTM层外的所有层的可训练参数设置为False

方法一:

for layer in model.layers:
    if layer.name != `lstm_2`
        layer.trainable = False

方法二:

for layer in model.layers:
    layer.trainable = False

model.layers[2].trainable = True  # set lstm to be trainable

# to make sure 2 is the index of the layer
print(model.layers[2].name)    # prints 'lstm_2'

不要忘记再次编译模型以应用这些更改。