Keras从零训练Xception历史准确率近100% 评估全预测1准确率仅50%
问题描述
在Keras框架下开展二分类任务,选择不加载预训练权重、从零训练Xception模型时出现异常:
- 训练过程生成的历史曲线显示训练准确率持续攀升直至接近100%,验证准确率始终维持在50%左右,初看属于过拟合表现
- 实际核验发现模型对所有样本的预测结果始终接近1,并非过拟合
- 训练结束后手动在训练集、验证集、测试集上做评估,三个数据集准确率均在50%上下,和训练过程中记录的接近100%的训练集准确率存在明显矛盾
- 除模型创建逻辑外,使用完全相同的代码训练加载预训练权重的Xception模型,可正常运行
注:训练所用的x_train_xception已经过keras.applications.xception.preprocess_input函数完成预处理。
训练代码
inLayerX = Input((512, 512, 4)) xceptionModel = keras.applications.Xception( include_top=True, weights=None, input_tensor=inLayerX, classes=1, classifier_activation='sigmoid' ) xceptionModel.compile(loss='binary_crossentropy', metrics=['accuracy']) history = xceptionModel.fit( x_train_xception, y_train, batch_size=batch_size, epochs=epochs, validation_data=(x_val_xception, y_val) ) _, accTest = xceptionModel.evaluate(x_test_xception, y_test) _, accVal = xceptionModel.evaluate(x_val_xception, y_val) _, accTrain = xceptionModel.evaluate(x_train_xception, y_train) print("Training accuracy {:.2%}".format(accTrain)) print("Validation accuracy {:.2%}".format(accVal)) print("Test accuracy {:.2%}".format(accTest))
运行输出
2/2 [==============================] - 6s 2s/step - loss: 1.2063 - accuracy: 0.5000 1/1 [==============================] - 4s 4s/step - loss: 1.2960 - accuracy: 0.4667 4/4 [==============================] - 5s 1s/step - loss: 1.2025 - accuracy: 0.5083 Training accuracy 50.83% Validation accuracy 46.67% Test accuracy 50.00%
核心异常特征
- 模型对所有样本预测值均接近1,验证集、测试集50%左右的准确率符合该行为的预期
- 训练过程记录的训练准确率持续上升接近100%,但训练结束后手动在训练集上评估的准确率仅为50.83%,二者存在明显矛盾
- 相同训练逻辑下,加载预训练权重的Xception模型可正常训练,无该异常
异常原因分析
- 输入通道数与模型结构设计不匹配:Keras内置Xception是为3通道RGB图像设计的,代码中定义的输入为4通道,未做任何结构适配直接传入模型。加载预训练权重时,通道数不匹配会直接触发报错,问题会被即时暴露;从零训练时不会触发通道校验,但模型底层卷积接收到的输入分布完全偏离设计预期,训练过程极不稳定。
- BatchNorm层训练与推理行为不一致:Xception结构中大量使用BatchNorm层:训练阶段BatchNorm使用当前批次的实时均值、方差做归一化,同时更新全局滑动平均统计量;推理阶段(执行evaluate/predict操作时)则直接使用训练过程累计的滑动平均统计量做归一化。从零训练且输入分布异常时,模型会过度依赖当前batch的实时统计量拟合出和标签匹配的输出,表现为训练过程中准确率持续走高;但一旦切换到推理模式,尚未收敛的滑动平均统计量完全失真,模型输出直接坍塌为全1,所有数据集的评估准确率都停留在随机猜测的50%水平。
- 预处理逻辑适配缺失:
keras.applications.xception.preprocess_input是针对3通道RGB图像设计的预处理函数,作用是将像素值从[0,255]范围缩放到[-1,1]区间。4通道输入下,第4个通道的数值如果没有做对应缩放,会进一步放大输入分布的偏移,加剧训练不稳定问题。
内容的提问来源于stack exchange,提问作者Liathan
相关产品推荐
相关产品推荐

