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

Keras使用无增强ImageDataGenerator训练CNN不收敛怎么办

问题描述

我使用Keras API在Cifar10数据集上训练CNN模型,相关实现代码如下:

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()

conv_network = Input(shape=(32, 32, 3), name="img")
x = Conv2D(filters=32, kernel_size=(3,3), strides=2, activation="relu")(conv_network)
x = Conv2D(filters=64, kernel_size=(3,3), strides=2, activation="relu")(x)
x = Conv2D(filters=128, kernel_size=(3,3), strides=2, activation="relu")(x)
x = Flatten()(x)
x = Dense(1024, activation='relu')(x)
output = Dense(10, activation='softmax')(x)

model = tf.keras.Model(conv_network, output, name="convolutional_network")

model.compile(loss='sparse_categorical_crossentropy',optimizer='Adam', metrics=['accuracy'])

正常训练场景

最初直接传入原始数据训练模型,代码如下:

r = model.fit(x_train, y_train, epochs=25,validation_data=(x_test, y_test))

该方式下模型可正常训练,训练集准确率随训练轮次逐步提升,第10轮训练集准确率可达89.01%,日志内容如下:

Epoch 1/25
1563/1563 [==============================] - 7s 4ms/step - loss: 1.7196 - accuracy: 0.4259 - val_loss: 1.3780 - val_accuracy: 0.5105
Epoch 2/25
1563/1563 [==============================] - 6s 4ms/step - loss: 1.2711 - accuracy: 0.5519 - val_loss: 1.2598 - val_accuracy: 0.5600
Epoch 3/25
1563/1563 [==============================] - 7s 4ms/step - loss: 1.1004 - accuracy: 0.6137 - val_loss: 1.2390 - val_accuracy: 0.5776
Epoch 4/25
1563/1563 [==============================] - 7s 4ms/step - loss: 0.9520 - accuracy: 0.6678 - val_loss: 1.2774 - val_accuracy: 0.5767
Epoch 5/25
1563/1563 [==============================] - 7s 4ms/step - loss: 0.7858 - accuracy: 0.7257 - val_loss: 1.3226 - val_accuracy: 0.5921
Epoch 6/25
1563/1563 [==============================] - 6s 4ms/step - loss: 0.6334 - accuracy: 0.7791 - val_loss: 1.5789 - val_accuracy: 0.5586
Epoch 7/25
1563/1563 [==============================] - 6s 4ms/step - loss: 0.5178 - accuracy: 0.8227 - val_loss: 1.7296 - val_accuracy: 0.5730
Epoch 8/25
1563/1563 [==============================] - 6s 4ms/step - loss: 0.4163 - accuracy: 0.8589 - val_loss: 2.0499 - val_accuracy: 0.5682
Epoch 9/25
1563/1563 [==============================] - 6s 4ms/step - loss: 0.3794 - accuracy: 0.8739 - val_loss: 2.0991 - val_accuracy: 0.5820
Epoch 10/25
1563/1563 [==============================] - 7s 4ms/step - loss: 0.3453 - accuracy: 0.8901 - val_loss: 2.3261 - val_accuracy: 0.5697

异常训练场景

使用未配置任何数据增强逻辑的ImageDataGenerator生成数据流训练时,模型预测结果完全随机、无训练效果,训练代码如下:

datagen = ImageDataGenerator()

model.fit(datagen.flow(x_train, y_train, batch_size=32),
          steps_per_epoch=50000 / 32,
          epochs=10)

对应的训练日志显示,损失值虽然持续下降,但准确率始终维持在10%左右的10分类随机猜测水平,无任何提升,日志内容如下:

Epoch 1/10
1562/1562 [==============================] - 7s 4ms/step - loss: 1.6822 - accuracy: 0.1010
Epoch 2/10
1562/1562 [==============================] - 7s 4ms/step - loss: 1.2881 - accuracy: 0.0982
Epoch 3/10
1562/1562 [==============================] - 7s 4ms/step - loss: 1.1302 - accuracy: 0.0987
Epoch 4/10
1562/1562 [==============================] - 7s 4ms/step - loss: 0.9817 - accuracy: 0.1001
Epoch 5/10
1562/1562 [==============================] - 7s 4ms/step - loss: 0.8215 - accuracy: 0.1011
Epoch 6/10
1562/1562 [==============================] - 7s 4ms/step - loss: 0.6760 - accuracy: 0.1000
Epoch 7/10
1562/1562 [==============================] - 7s 4ms/step - loss: 0.5445 - accuracy: 0.1005
Epoch 8/10
1562/1562 [==============================] - 7s 4ms/step - loss: 0.4660 - accuracy: 0.1006
Epoch 9/10
1562/1562 [==============================] - 7s 4ms/step - loss: 0.4048 - accuracy: 0.1002
Epoch 10/10
1562/1562 [==============================] - 7s 4ms/step - loss: 0.3641 - accuracy: 0.1006
问题原因与修正方法

核心错误是标签维度不匹配:

  • tf.keras.datasets.cifar10.load_data()返回的标签y_train、y_test是形状为(样本数, 1)的二维列向量,不是sparse_categorical_crossentropy损失期望的形状为(样本数,)的一维整数数组。
  • 直接向model.fit()传入数组数据时,Keras内部会自动做维度适配,挤压多余的标签维度,因此训练可以正常进行。
  • 但ImageDataGenerator.flow()生成批次数据时,不会自动对标签做维度压缩,输出的批次标签形状为(batch_size, 1),不符合损失函数和准确率指标的输入要求,会触发错误的广播计算:你看到的损失下降只是数值计算的假象,准确率统计完全失效,模型根本没有在正确的监督信号下更新参数,因此准确率始终卡在随机猜测水平。

修正操作很简单,加载数据后手动压缩标签维度即可,建议同时做像素值归一化加快收敛:

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
# 压缩标签维度为一维
y_train = y_train.squeeze()
y_test = y_test.squeeze()
# 归一化像素值到0-1区间
x_train = x_train / 255.0
x_test = x_test / 255.0

完成上述处理后,再用ImageDataGenerator生成数据流训练,模型就可以正常收敛。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 08:31:09