基于Inception迁移学习重复运行后训练准确率骤降问题求助
问题诊断与修复方案
你的代码存在几个关键问题,直接导致测试不同dense值时准确率暴跌:
1. Dense层单元数使用字符串类型
第二个测试代码中,dense = ["256", "512", "1024", "2048"]将单元数定义为字符串,而Keras的Dense层要求units参数必须是整数类型。虽然部分情况下框架会自动转换,但这可能引发不可预期的初始化异常。
修复:将列表改为整数类型:
dense = [256, 512, 1024, 2048]
2. 输出层激活函数与损失函数不匹配
输出层使用softmax激活,但损失函数却用了BinaryCrossentropy(from_logits=True),这是完全不兼容的组合:
- 若为二分类任务:输出层应使用
sigmoid激活,损失函数对应BinaryCrossentropy()(去掉from_logits=True);若保留from_logits=True,则输出层不要加激活函数。 - 若为多分类任务:输出层用
softmax,损失函数应使用CategoricalCrossentropy(标签为one-hot编码)或SparseCategoricalCrossentropy(标签为整数)。
修复(假设是二分类任务):
# 输出层改为sigmoid outputs = Dense(num_classes, activation='sigmoid')(x) # 损失函数匹配sigmoid输出 model_diff_dense.compile( optimizer=tf.keras.optimizers.Adadelta(learning_rate=learningrate), loss=tf.keras.losses.BinaryCrossentropy(), metrics=['accuracy'] )
3. Adadelta优化器的学习率设置不合理
Adadelta的默认学习率是1.0,它的更新逻辑依赖于累积的梯度平方和参数更新量,你设置的0.0001过小,会导致参数更新幅度几乎可以忽略,模型根本无法有效学习。
修复:调整Adadelta的学习率至合理范围:
optimizer = tf.keras.optimizers.Adadelta(learning_rate=1.0)
若担心学习率过大,可逐步调整到0.5或0.1,但不要使用0.0001这种量级。
优化后的完整测试dense值代码
dense = [256, 512, 1024, 2048] learningrate = 1.0 # 调整Adadelta学习率 epochs_values = 5 # 增加训练轮数,让模型有收敛空间 train_accuracy_list = [] train_loss_list = [] val_accuracy_list = [] val_loss_list = [] test_accuracy_list = [] test_loss_list = [] for units in dense: print(f"Current dense units: {units}") # 重新构建分类头部 x = base_model.output x = GlobalAveragePooling2D()(x) x = Dense(units, activation='relu')(x) outputs = Dense(num_classes, activation='sigmoid')(x) # 二分类用sigmoid model_diff_dense = Model(inputs=base_model.input, outputs=outputs) model_diff_dense.compile( optimizer=tf.keras.optimizers.Adadelta(learning_rate=learningrate), loss=tf.keras.losses.BinaryCrossentropy(), metrics=['accuracy'] ) train_history = model_diff_dense.fit( train_generator, epochs=epochs_values, validation_data=valid_generator ) test_loss, test_acc = model_diff_dense.evaluate(test_generator) print(f'Test accuracy for {units}: {test_acc}') train_accuracy_list.append(train_history.history['accuracy']) train_loss_list.append(train_history.history['loss']) val_accuracy_list.append(train_history.history['val_accuracy']) val_loss_list.append(train_history.history['val_loss']) test_accuracy_list.append(test_acc) test_loss_list.append(test_loss)
额外建议
- 增加训练轮数:原代码
epochs_values=1太少,模型来不及收敛,至少设置5-10轮观察指标变化。 - 监控验证集指标:若验证集准确率同步下降,说明是训练逻辑问题;若验证集正常,可能是训练集过拟合,但你的情况更倾向于训练不充分或损失函数不匹配。
内容的提问来源于stack exchange,提问作者LXun
相关产品推荐
相关产品推荐

