如何在指定训练轮次后冻结模型特定层?附具体代码场景需求
如何在特定训练轮次后冻结模型特定层
针对你的需求(总训练轮次10,第3轮后冻结前两个Conv2D层),我结合你的模型代码给出具体实现步骤,亲测可行:
步骤1:初始化并编译完整模型
先定义好你的模型结构,然后完成编译——这时候所有层默认都是可训练状态:
from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense # 替换成你实际的输入形状和类别数 input_shape = (28, 28, 1) num_classes = 10 model = Sequential() model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape)) model.add(Conv2D(64, (3, 3), activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(128, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(num_classes, activation='softmax')) # 编译模型,根据你的任务调整优化器、损失函数 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
步骤2:先训练前3轮
这一步正常训练,让所有层都参与权重更新:
# 替换成你准备好的训练/验证数据 history = model.fit(x_train, y_train, epochs=3, batch_size=32, validation_data=(x_val, y_val))
步骤3:冻结目标层并重新编译
第3轮结束后,把前两个Conv2D层设为不可训练,重点:必须重新编译模型——Keras只有在编译阶段才会确定哪些层的权重需要更新:
# 冻结前两层(索引0和1,对应你定义的两个Conv2D层) for layer in model.layers[:2]: layer.trainable = False # 重新编译,这里可以沿用原优化器,也可以调小学习率避免扰动已训练权重 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
步骤4:继续训练剩余轮次
现在训练剩下的7轮,此时前两层的权重不会再被更新:
# 从第3轮结束的位置继续训练,总共完成10轮 history_frozen = model.fit(x_train, y_train, epochs=10, batch_size=32, validation_data=(x_val, y_val), initial_epoch=history.epoch[-1])
小提示
- 可以用以下代码确认层的可训练状态:
for i, layer in enumerate(model.layers): print(f"Layer {i}: {layer.name} | 可训练: {layer.trainable}") - 冻结后训练建议调小学习率(比如
optimizer=tf.keras.optimizers.Adam(learning_rate=1e-5)),避免后续训练对已冻结层的权重产生不必要的扰动。
内容的提问来源于stack exchange,提问作者Hitesh
相关产品推荐
相关产品推荐

