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

训练CNN时accuracy与val_accuracy无变化的解决方案咨询

解决CNN训练中准确率几乎无变化的问题

问题现象

使用TensorFlow和Keras训练卷积神经网络时,训练全程accuracy和val_accuracy数值几乎没有提升,初始训练准确率就达到96%以上,后续epoch中仅维持在该水平。

相关代码

模型定义代码

from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten, Conv2D, MaxPooling2D
import pickle

X = pickle.load(open("X.pickle", "rb"))
y = pickle.load(open("y.pickle", "rb"))

X = X/255.0

model = Sequential()
model.add(Conv2D(64, (3, 3), input_shape=X.shape[1:]))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(64, (3, 3), activation="relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(64, activation="relu"))

model.add(Dense(1, activation="sigmoid"))

model.compile(loss="binary_crossentropy",
              optimizer="adam",
              metrics=["accuracy"])
model.fit(X, y, batch_size=10, epochs=10, validation_split=0.1)

训练数据生成代码

def create_training_data():
    for category in CATEGORIES:
        path = os.path.join(DATADIR, category)
        class_num = CATEGORIES.index(category)
        for img in os.listdir(path):
            try:
                img_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_GRAYSCALE)
                new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))
                training_data.append([new_array, class_num])
            except Exception as e:
                pass

create_training_data()

random.shuffle(training_data)

X = []
y = []
for features, label in training_data:
    X.append(features)
    y.append(label)

X = np.array(X).reshape(-1, IMG_SIZE, IMG_SIZE, 1)
y = np.array(y)

训练日志

2023-01-15 00:36:42.368335: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
Epoch 1/10
70/70 [==============================] - 45s 619ms/step - loss: 0.3039 - accuracy: 0.9627 - val_loss: 0.1211 - val_accuracy: 0.9744
Epoch 2/10
70/70 [==============================] - 42s 600ms/step - loss: 0.1524 - accuracy: 0.9670 - val_loss: 0.1189 - val_accuracy: 0.9744
Epoch 3/10
70/70 [==============================] - 42s 600ms/step - loss: 0.1537 - accuracy: 0.9670 - val_loss: 0.1622 - val_accuracy: 0.9744
Epoch 4/10
70/70 [==============================] - 44s 627ms/step - loss: 0.1563 - accuracy: 0.9670 - val_loss: 0.1464 - val_accuracy: 0.9744
Epoch 5/10
70/70 [==============================] - 42s 604ms/step - loss: 0.1591 - accuracy: 0.9670 - val_loss: 0.1185 - val_accuracy: 0.9744
Epoch 6/10
70/70 [==============================] - 42s 605ms/step - loss: 0.1511 - accuracy: 0.9670 - val_loss: 0.1338 - val_accuracy: 0.9744
Epoch 7/10
70/70 [==============================] - 49s 698ms/step - loss: 0.1623 - accuracy: 0.9670 - val_loss: 0.1188 - val_accuracy: 0.9744
Epoch 8/10
70/70 [==============================] - 50s 709ms/step - loss: 0.1480 - accuracy: 0.9670 - val_loss: 0.1397 - val_accuracy: 0.9744
Epoch 9/10
70/70 [==============================] - 45s 637ms/step - loss: 0.1508 - accuracy: 0.9670 - val_loss: 0.1203 - val_accuracy: 0.9744
Epoch 10/10
70/70 [==============================] - 47s 665ms/step - loss: 0.1716 - accuracy: 0.9670 - val_loss: 0.1238 - val_accuracy: 0.9744

Process finished with exit code 0

问题分析

从日志可见,模型初始训练准确率就极高,后续无提升,核心原因大概率是数据集类别严重不平衡——模型只需预测占比极高的类别就能获得高准确率,无需学习有效特征。此外,模型容量不足、过拟合也可能导致该现象。

解决方法

  • 检查数据集类别分布:执行np.bincount(y)统计两类样本数量,确认是否存在某类占比过高的情况。
  • 处理类别不平衡:
    • 重采样:对少数类样本进行过采样(复制样本),或对多数类进行欠采样(随机删除部分样本);
    • 类别权重:在model.fit()中添加class_weight参数,按类别数量反比计算权重,示例:
      count0 = np.sum(y == 0)
      count1 = np.sum(y == 1)
      total = count0 + count1
      class_weight = {0: total/(2*count0), 1: total/(2*count1)}
      model.fit(X, y, batch_size=32, epochs=10, validation_split=0.1, class_weight=class_weight)
      
  • 调整模型结构:
    • 提升模型容量:增加卷积层数量、扩大卷积核规模(如将64改为128),或增加全连接层神经元数量;
    • 添加Dropout层:在Flatten()后或全连接层后加入Dropout(0.5),抑制过拟合;
  • 优化训练参数:
    • 增大batch size:将当前的10调整为32或64,让梯度更新更稳定;
    • 调整学习率:降低Adam默认学习率(如改为0.0001),或使用学习率调度器动态调整;
  • 数据增强:通过随机翻转、旋转、缩放等操作扩充数据多样性,避免模型记忆训练样本,示例:
    from keras.preprocessing.image import ImageDataGenerator
    
    datagen = ImageDataGenerator(
        rotation_range=15,
        width_shift_range=0.1,
        height_shift_range=0.1,
        horizontal_flip=True
    )
    datagen.fit(X)
    model.fit(datagen.flow(X, y, batch_size=32), epochs=15, validation_split=0.1)
    
  • 验证数据正确性:检查标签是否与样本正确对应,排除错误标注或混入的无效数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 03:01:40