You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

卷积神经网络训练异常:初始准确率高随轮次下降且测试集准确率为0

多标签分类训练异常排查

任务与代码

使用Tensorflow/Keras开展多标签分类任务(共3个二分类标签,取值0/1),模型结构和训练代码如下:

模型结构

model.add(layers.Conv2D(32, kernel_size=3, padding='same', activation='relu', input_shape=(64, 64, 1)))
model.add(layers.MaxPooling2D(pool_size=2))
model.add(layers.Conv2D(24, kernel_size=3, padding='same', activation='relu'))
model.add(layers.MaxPooling2D(pool_size=2))
model.add(layers.Conv2D(16, kernel_size=3, padding='same', activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(144, activation='relu'))
model.add(layers.Dense(3, activation='sigmoid'))

训练代码

model.compile(optimizer='sgd',
              loss = tf.keras.losses.BinaryCrossentropy(),
              metrics=['accuracy'])

history = model.fit(train_images, train_labels, epochs=50, 
                    validation_data=(val_images, val_labels))

异常表现

  • 第一个epoch准确率超90%
  • 训练轮次增加后,准确率逐渐降至50%左右,偶尔随机回升至70%
  • 训练集、验证集均呈现此规律
  • 测试集准确率为0

问题分析与解决办法

1. 替换默认accuracy指标

默认accuracy计算的是样本所有标签全对的比例,完全不适合多标签任务。初始高准确率是因为数据集标签分布极端(比如多数样本标签全0/全1),模型瞎蒙就蒙对了,后续训练学特征反而打破了这种巧合,导致准确率下降。

改用多标签专用指标:

model.compile(optimizer='sgd',
              loss=tf.keras.losses.BinaryCrossentropy(),
              metrics=[tf.keras.metrics.BinaryAccuracy(name='binary_acc'),
                       tf.keras.metrics.Precision(),
                       tf.keras.metrics.Recall()])

BinaryAccuracy会统计每个标签的分类准确率,能真实反映模型性能。

2. 排查数据集问题

测试集准确率为0肯定是数据集环节出了问题:

  • 检查训练/验证/测试集的标签分布是否一致,避免测试集标签与训练集完全脱节
  • 确认所有数据集的预处理统一:比如图像是否归一化、通道数是否匹配输入的(64,64,1)单通道
  • 检查测试集标签加载是否正确,有没有出现标签全0/全1的错误

3. 调低SGD学习率

SGD默认学习率0.01可能过高,导致模型参数更新幅度过大,训练过程震荡,准确率忽高忽低。试试调低学习率:

optimizer=tf.keras.optimizers.SGD(learning_rate=0.001)

4. 优化模型结构

在卷积层后加入BatchNormalization稳定训练,全连接层加入Dropout防止过拟合:

model.add(layers.Conv2D(32, kernel_size=3, padding='same', activation='relu', input_shape=(64, 64, 1)))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D(pool_size=2))
model.add(layers.Conv2D(24, kernel_size=3, padding='same', activation='relu'))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D(pool_size=2))
model.add(layers.Conv2D(16, kernel_size=3, padding='same', activation='relu'))
model.add(layers.BatchNormalization())
model.add(layers.Flatten())
model.add(layers.Dense(144, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(3, activation='sigmoid'))

5. 调整标签判断阈值

sigmoid输出默认用0.5作为标签判断阈值,但如果数据集标签不平衡,这个阈值可能不合适。可以根据验证集的Precision-Recall曲线确定最优阈值。


内容的提问来源于stack exchange,提问作者Ann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 22:20:26