多分类任务中准确率超90%但模型全预测一类的原因分析
多分类任务中训练准确率虚高但模型仅预测单一类别的原因与解决方案
问题背景
在3分类视频帧分类任务中,出现以下异常现象:
- 训练数据集类别平衡(总样本15849,A类3906、B类5955、O类5988)
- 模型训练2个epoch后训练准确率>90%,但验证准确率仅约35%
- 通过自定义Callback记录混淆矩阵发现,模型始终只预测单一类别,且准确率计算逻辑验证无误
模型结构如下:
model = tf.keras.Sequential([ tf.keras.layers.Rescaling(scale=1./255., offset=0.0), mobilenet_custom, tf.keras.layers.GlobalAveragePooling2D(), tf.keras.layers.Dense(128, activation='relu'), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(32, activation='relu'), tf.keras.layers.Dense(3, activation='softmax') ])
其中mobilenet_custom是修改输入通道为7、使用随机权重的tf.keras.applications.MobileNetV2模型。
核心原因与对应解决方案
1. 损失函数与标签格式不匹配
如果标签是稀疏编码(单个整数0/1/2)却使用categorical_crossentropy,或是独热编码((batch_size,3)格式)却使用sparse_categorical_crossentropy,会导致损失计算异常:模型会倾向于预测占比稍高的类别,同时训练准确率因损失计算错误出现虚高。
解决方法:
- 标签为独热编码时,设置
loss='categorical_crossentropy' - 标签为稀疏整数时,设置
loss='sparse_categorical_crossentropy' - 检查模型编译时的损失函数,确保和标签格式完全匹配
2. 随机权重MobileNetV2的特征提取失效
你使用的是随机初始化权重的MobileNetV2,且输入通道修改为7(原模型为3通道)。随机初始化的深层卷积层无法有效提取特征,后续全连接层只能学习到简单偏向性,直接输出单一类别;训练准确率虚高是因为模型在随机拟合训练数据的噪声。
解决方法:
- 加载ImageNet预训练权重并适配7通道输入:
# 加载3通道预训练模型 base_model = tf.keras.applications.MobileNetV2(input_shape=(224,224,3), weights='imagenet', include_top=False) # 创建7通道输入层 new_input = tf.keras.layers.Input(shape=(224,224,7)) # 复制原第一层卷积的预训练权重到新层的前3通道,后4通道随机初始化 original_conv_weights = base_model.layers[0].get_weights() new_conv_weights = [ np.concatenate([original_conv_weights[0], np.random.normal(0, 0.01, (3,3,4,32))], axis=2), original_conv_weights[1] ] new_conv = tf.keras.layers.Conv2D(32, (3,3), strides=(2,2), padding='same', use_bias=True, name='Conv1')(new_input) new_conv.set_weights(new_conv_weights) # 连接后续预训练层 x = new_conv for layer in base_model.layers[1:]: x = layer(x) mobilenet_custom = tf.keras.Model(new_input, x) - 冻结预训练层的前若干层,仅训练新增卷积层和顶部全连接层,避免预训练特征被破坏
3. 训练数据加载或标签存在错误
即使数据集统计平衡,也可能存在数据生成器加载时的标签错位问题:比如训练数据的标签被错误统一设为某一类,但统计时的标签是正确的,导致模型学到“预测某类就能得高准确率”的错误规律。
解决方法:
- 随机抽取训练集的几个batch,手动检查
X_batch与y_batch的对应关系,确认标签和样本匹配 - 打印训练过程中的部分
y_true和y_pred,验证模型在训练数据上的预测是否真的正确,不要仅依赖准确率指标
4. 学习率设置过高
过高的学习率会导致模型训练不稳定,权重更新幅度过大,直接收敛到“预测单一类别”的局部最优解,此时训练准确率因batch内样本分布巧合出现虚高。
解决方法:
- 将学习率从默认的
1e-3调低至1e-4或1e-5,使用ReduceLROnPlateau调度器动态调整 - 观察训练损失曲线,若波动剧烈则说明学习率过高
5. 输出层与损失函数的配合异常
虽然使用了softmax激活,但如果损失函数不匹配、或训练时标签传递错误,会导致模型输出概率分布极端化,全部偏向某一类别。
解决方法:
- 标签为独热编码时,使用
metrics=['accuracy'];标签为稀疏整数时,使用metrics=['sparse_categorical_accuracy'],避免指标计算错误 - 预测时打印
y_pred的具体数值,查看是否所有样本的概率都集中在某一类(如99%以上概率属于O类),若是则说明模型未学到有效特征
内容的提问来源于stack exchange,提问作者Khamyl
相关产品推荐
相关产品推荐

