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

TensorFlow CNN仅预测单一类别问题求助

问题

使用TensorFlow构建自定义CNN用于三分类任务,数据集无类别不平衡问题,但模型始终只预测单一类别。CNN架构如下:

model = tf.keras.Sequential([
    Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 1), padding='same', data_format = 'channels_last'),
    BatchNormalization(),
    MaxPooling2D((2, 2), padding='same'),
    Conv2D(64, (3, 3), activation='relu', padding='same'),
    BatchNormalization(),
    MaxPooling2D((2, 2), padding='same'),
    Conv2D(128, (3, 3), activation='relu', padding='same'),
    BatchNormalization(),
    MaxPooling2D((2, 2), padding='same'),
    Conv2D(256, (3, 3), activation='relu', padding='same'),
    BatchNormalization(),
    MaxPooling2D((2, 2), padding='same'),
    Flatten(),
    Dense(256, activation='relu', kernel_regularizer=tf.keras.regularizers.l2(0.01)),
    Dropout(0.5),
    Dense(128, activation='relu', kernel_regularizer=tf.keras.regularizers.l2(0.01)),
    Dropout(0.5),
    Dense(3, activation='softmax')
])

已尝试调整学习率、添加BatchNormalization、Dropout及L2正则化,结果未改善。训练10轮后的分类报告:

precision    recall  f1-score   support

          no       0.00      0.00      0.00     10000
      sphere       0.33      1.00      0.50     10000
        vort       0.00      0.00      0.00     10000

    accuracy                           0.33     30000
   macro avg       0.11      0.33      0.17     30000
weighted avg       0.11      0.33      0.17     30000

有时预测的单一类别会变化,但始终只输出一类。数据集已做打乱处理:

BATCH_SIZE = 32
train_dataset = train_dataset.shuffle(buffer_size=train_len).batch(BATCH_SIZE)
val_dataset = val_dataset.batch(BATCH_SIZE)
解决方案
  • 匹配损失函数与标签编码方式
    三分类任务用softmax输出层时,必须保证损失函数和标签编码对应:

    • 若标签是整数编码,用SparseCategoricalCrossentropy:
      model.compile(optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(), metrics=['accuracy'])
      
    • 若标签是one-hot编码,用CategoricalCrossentropy:
      model.compile(optimizer='adam', loss=tf.keras.losses.CategoricalCrossentropy(), metrics=['accuracy'])
      

    编码与损失函数不匹配会直接导致模型学习失效,偏向单一类别。

  • 降低正则化强度
    当前L2正则化系数0.01过大,会过度压制模型特征学习能力。建议先将系数降到0.001或0.0001,甚至暂时移除正则化,验证模型是否能正常区分类别。

  • 检查数据预处理

    1. 确认输入数据是否归一化:未归一化的0-255像素值会导致训练不稳定,需缩放到[0,1]区间:
      train_dataset = train_dataset.map(lambda x, y: (x / 255.0, y))
      val_dataset = val_dataset.map(lambda x, y: (x / 255.0, y))
      
    2. 随机抽取样本验证标签分布,确保没有出现标签错位或单类别占比异常的情况。
  • 调整模型复杂度与训练轮数
    当前模型规模较大,但仅训练10轮可能未收敛。可以先简化模型(比如减少卷积核数量或去掉一层全连接层),让模型先学会基础的类别区分能力,再逐步增加复杂度。同时将训练轮数提升到30-50轮,观察训练损失和精度的变化趋势。

  • 优化器与学习率调整
    尝试更换优化器,比如用SGD配合0.001的学习率替代Adam,部分数据集上SGD的稳定性更好。也可以使用学习率调度器,让学习率随训练逐步降低:

    lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(
        initial_learning_rate=0.001,
        decay_steps=10000,
        decay_rate=0.9)
    optimizer = tf.keras.optimizers.Adam(learning_rate=lr_schedule)
    
  • 验证数据集加载有效性
    检查shuffle操作是否真正生效:随机查看几个训练批次的标签分布,确认每个批次都包含三类样本。同时验证验证集的标签是否正常,避免验证集本身存在异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 22:12:53