Keras训练中精度与损失Epoch间无变化的原因及解决方法
Keras训练精度与损失无变化的原因及解决方法
核心原因分析
1. 变量名不匹配(最直接问题)
你定义的模型是model_2,但训练时调用的是model_1.fit。如果model_1没被正确初始化,Keras要么默认生成一个随机初始化的模型,要么复用之前的错误模型,导致模型完全无法学习,输出的是随机猜测的精度——CIFAR-100共100类,随机猜的精度正好是1%,和你看到的结果完全吻合。
2. 数据加载语法错误
数据加载行x_train, y_train), (x_test, y_test) = keras.datasets.cifar100.load_data()多了一个右括号,这会直接导致代码运行报错,除非你之前手动加载过数据,否则根本拿不到正确的训练集和测试集。
3. 模型结构设计缺陷
- 无padding的卷积导致特征图骤缩:CIFAR-100输入是32×32×3的图像,连续用多个3×3无padding的卷积(默认
padding='valid'),每次卷积宽高都会各减2。经过4次卷积后,特征图变成24×24,再加stride=2的卷积变成11×11,之后MaxPooling后只剩5×5。这种设计会让有效特征丢失严重,模型很难学到有用的模式。 - Flatten层多余参数:
Flatten(input_shape=x_train[0].shape)里的input_shape完全多余,前面的层已经确定了输入维度,这个参数可能引发维度不匹配问题。 - 激活函数拼写不规范:Keras里ReLU的标准写法是
activation='relu'(小写),虽然部分版本兼容大写,但可能存在潜在的兼容性问题。
解决方法
1. 修正基础错误
- 把数据加载行改成正确格式:
(x_train, y_train), (x_test, y_test) = keras.datasets.cifar100.load_data() - 训练时用正确的模型变量:
history_2 = model_2.fit(x_train, y_train, batch_size=512, epochs=50, validation_data=(x_test, y_test), shuffle=True)
2. 优化模型结构
- 添加padding保留特征图尺寸:给卷积层加上
padding='same',这样每次卷积后特征图尺寸不变,避免特征丢失:model_2.add(keras.layers.Conv2D(filters=256, kernel_size=(3,3), padding='same', activation='relu')) - 移除Flatten层的多余参数:
model_2.add(keras.layers.Flatten()) - 调整卷积层规模:256个通道对32×32的小图像来说太夸张,会导致参数爆炸、训练困难。可以减少通道数,同时调整卷积层结构,比如:
model_2 = keras.Sequential() model_2.add(keras.layers.Input(shape=x_train[0].shape)) model_2.add(keras.layers.Conv2D(filters=64, kernel_size=(3,3), padding='same', activation='relu')) model_2.add(keras.layers.Conv2D(filters=64, kernel_size=(3,3), padding='same', activation='relu')) model_2.add(keras.layers.MaxPooling2D(pool_size=(2, 2))) model_2.add(keras.layers.Conv2D(filters=128, kernel_size=(3,3), padding='same', activation='relu')) model_2.add(keras.layers.Conv2D(filters=128, kernel_size=(3,3), padding='same', activation='relu')) model_2.add(keras.layers.MaxPooling2D(pool_size=(2, 2))) model_2.add(keras.layers.Flatten()) model_2.add(keras.layers.Dense(units=256, activation='relu')) # 加一层全连接增强特征表达 model_2.add(keras.layers.Dropout(0.5)) # Dropout防止过拟合 model_2.add(keras.layers.Dense(units=num_of_class, activation='softmax'))
3. 调整训练参数
- 减小batch size:512的batch size太大,可能导致梯度更新不充分,改成64或128试试。
- 微调学习率:Adam默认学习率是0.001,如果模型收敛慢,可以调低到0.0005,比如:
model_2.compile(loss='categorical_crossentropy', optimizer=keras.optimizers.Adam(learning_rate=0.0005), metrics=['accuracy'])
内容的提问来源于stack exchange,提问作者akbar taheri
相关产品推荐
相关产品推荐

