如何修改Keras中ResNet50代码实现无预训练权重全层从头训练?
代码修改方案:无预训练权重从头训练ResNet50
核心修改点
- 创建ResNet50时必须指定
weights=None,避免加载默认的ImageNet预训练权重 - 可选调整:回归任务建议将最后一层激活函数改为
linear,同时降低Adam优化器的学习率
修改后的完整代码
from tensorflow.keras.applications import ResNet50 from tensorflow.keras import layers, Model import tensorflow as tf # 创建无预训练权重的ResNet50基础模型 pre_trained_model = ResNet50(input_shape=(150, 150, 3), include_top=False, weights=None) # 关键:不加载预训练权重 # 确保所有层可训练(原代码这部分正确,保留) for layer in pre_trained_model.layers: layer.trainable = True # 追加自定义层(原逻辑保留,可选调整最后一层激活) last_layer = pre_trained_model.get_layer('conv5_block3_3_bn') last_output = last_layer.output x = layers.Flatten()(last_output) x = layers.Dense(1024, activation='relu')(x) x = layers.Dropout(0.2)(x) x = layers.Dense(3, activation='linear')(x) # 回归任务建议用linear激活 # 构建完整模型 model = Model(pre_trained_model.input, x) # 编译模型,调整学习率 model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001), # 降低学习率提升稳定性 loss="mean_squared_error", metrics=["mse"])
修改说明
weights=None:这是实现"无预训练权重从头训练"的核心,Keras默认会加载ImageNet预训练权重,必须显式设置为None才能让所有层权重随机初始化。- 最后一层激活函数:如果你的任务是回归预测连续值,
relu会限制输出为非负数,改用linear能输出任意实数,更符合回归任务的需求;如果你的输出确实只需要非负值,可以保留relu。 - 学习率调整:0.01的学习率对于深层网络从头训练来说过高,容易导致训练震荡、难以收敛,建议从0.0001或0.001开始尝试,根据训练曲线再调整。
- 全层可训练:原代码中循环设置
layer.trainable = True的逻辑正确,确保ResNet50的所有卷积层都能参与权重更新,实现真正的从头训练。
内容的提问来源于stack exchange,提问作者Ross
相关产品推荐
相关产品推荐

