KerasClassifier训练准确率高但交叉验证得分低问题求助
类别不平衡下Keras模型过拟合+分类偏移问题求助
模型代码
def baseline_model(): # create model model = Sequential() model.add(Dense(64, input_dim=2561 ,activation='relu', kernel_regularizer=regularizers.l2(0.001))) model.add(Dropout(0.2)) model.add(Dense(64, activation='relu', kernel_regularizer=regularizers.l2(0.001))) model.add(Dropout(0.2)) model.add(Dense(6, activation='softmax')) # Compile model model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) return model estimator = KerasClassifier(build_fn=baseline_model, epochs=50, batch_size=30, verbose=1,validation_split=0.2, shuffle=True, class_weight=weights) kfold = KFold(n_splits=2, shuffle=True, random_state=seed) results = cross_val_score(estimator, X_selected, Y, cv=kfold) print("Baseline: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))
(注:原文中iestimator应为estimator,已修正)
问题背景
- 训练准确率表现优异,但验证准确率仅约50%,交叉验证得分同样偏低
- 数据集6个类别分布严重失衡:
- AD: 1021
- NC: 288
- MCI: 229
- DLB: 169
- VaD: 91
- NPH: 84
- 混淆矩阵显示模型严重偏向多数类AD,大量其他类别样本被误判为AD
- 已尝试手动设置类别权重:
{0: 0.30721514854717596, 1: 1.856015779092702, 2: 1.3697234352256187, 3: 1.0891203703703705, 4: 3.734126984126984, 5: 3.446886446886447},但问题未得到改善
针对性解决方案
1. 优化类别权重计算
使用工具自动生成平衡权重,避免手动计算误差:
from sklearn.utils.class_weight import compute_class_weight import numpy as np # 针对独热编码的Y,先转换为类别索引 y_labels = np.argmax(Y, axis=1) class_weights = compute_class_weight('balanced', classes=np.unique(y_labels), y=y_labels) class_weights_dict = dict(enumerate(class_weights))
2. 压制过拟合
训练/验证准确率差距大的核心是过拟合,在现有L2正则、Dropout基础上补充:
- 降低模型复杂度:将Dense层神经元数量从64降至32,或减少一层隐藏层
- 增强Dropout强度:把Dropout比例从0.2提升至0.3-0.5
- 添加早停机制:监控验证集损失,停止无效迭代并恢复最优权重
from tensorflow.keras.callbacks import EarlyStopping early_stop = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True) # 传入KerasClassifier中 estimator = KerasClassifier(build_fn=baseline_model, epochs=50, batch_size=30, verbose=1, validation_split=0.2, shuffle=True, class_weight=class_weights_dict, callbacks=[early_stop])
- 数据平衡处理:对少数类使用SMOTE/ADASYN过采样,或对多数类AD做欠采样(优先过采样,避免丢失信息)
3. 更换评估指标
准确率在类别不平衡场景下参考性差,改用更可靠的指标:
from sklearn.metrics import f1_score, classification_report # 交叉验证指定F1宏平均为评分标准 results = cross_val_score(estimator, X_selected, Y, cv=kfold, scoring='f1_macro') print("F1 Macro: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100)) # 训练后输出详细分类报告 estimator.fit(X_selected, Y) y_pred = estimator.predict(X_val) print(classification_report(np.argmax(Y_val, axis=1), y_pred))
4. 调整训练策略
- 降低Adam学习率至0.0001,避免训练后期震荡
- 提升交叉验证折数至5或10,结果更具代表性
- 确保输入特征完成标准化/归一化,这是全连接模型的性能基础
内容的提问来源于stack exchange,提问作者StrWrs_Nerd
相关产品推荐
相关产品推荐

