使用 keras 顺序模型获得较差的分类精度

Posted

技术标签:

【中文标题】使用 keras 顺序模型获得较差的分类精度【英文标题】:getting bad accuracy of classification using keras sequential model 【发布时间】:2019-10-22 08:04:27 【问题描述】:

我正在尝试使用 keras 序列模型和 tensorflow 构建一个 cnn 模型,以便将图像分为猫和狗两类。图片是从 kaggle 下载的。我将图像存储在 csv 文件中作为训练和测试数据库。问题是我得到了非常糟糕的准确性结果。这是我的代码的一部分。

我尝试使用 vgg16 调整我的模型,但准确性仍然很差。我增加了 epoch 的数量,但仍然没有改善

data_train = pd.read_csv('class_training_pixels.csv')
data_test = pd.read_csv('class_test_pixels.csv')
train_X, valid_X, train_label, valid_label = train_test_split(train_X, train_Y_one_hot, test_size=0.2, random_state=13)
train_X.shape,valid_X.shape,train_label.shape,valid_label.shape
test_X, valid2_X, test_label, valid2_label = train_test_split(test_X, test_Y_one_hot, test_size=0, random_state=13)
batch_size = 20
epochs = 10
num_classes = 2
from keras import backend
from keras import backend
backend.set_image_dim_ordering('tf')
fashion_model = Sequential()
fashion_model.add(Conv2D(32, kernel_size=(3, 3),activation='linear',padding='same',input_shape=(w,h,1)))
fashion_model.add(LeakyReLU(alpha=0.1))
fashion_model.add(MaxPooling2D((2, 2),padding='same'))
fashion_model.add(Dropout(0.25))
fashion_model.add(Conv2D(64, (3, 3), activation='linear',padding='same'))
fashion_model.add(LeakyReLU(alpha=0.1))
fashion_model.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
fashion_model.add(Dropout(0.25))
fashion_model.add(Conv2D(128, (3, 3), activation='linear',padding='same'))
fashion_model.add(LeakyReLU(alpha=0.1))
fashion_model.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
fashion_model.add(Dropout(0.4))
fashion_model.add(GlobalAveragePooling2D())
fashion_model.add(Dense(128, activation='linear'))
fashion_model.add(LeakyReLU(alpha=0.1))
fashion_model.add(Dropout(0.3))
fashion_model.add(Dense(num_classes, activation='softmax'))
fashion_model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adam(lr=.00001),metrics=['accuracy'])
fashion_model.summary()
fashion_train = fashion_model.fit(train_X, train_label, batch_size=batch_size,epochs=epochs,verbose=1,validation_data=(valid_X, valid_label))
val_loss, val_acc = fashion_model.evaluate(test_X, test_Y_one_hot, verbose=0)
print(val_acc, val_loss)
predicted_classes = fashion_model.predict_classes(x_test)
print(predicted_classes)

这是最后一个 epoch 的结果

Epoch 10/10

20/99 [=====>........................] - ETA: 19s - loss: 0.6835 - acc: 0.5500
40/99 [===========>..................] - ETA: 14s - loss: 0.7079 - acc: 0.4250
60/99 [=================>............] - ETA: 9s - loss: 0.7014 - acc: 0.4833 
80/99 [=======================>......] - ETA: 4s - loss: 0.6957 - acc: 0.5125
99/99 [==============================] - 26s 267ms/step - loss: 0.6955 - acc: 0.5051 - val_loss: 0.6943 - val_acc: 0.4400

这里分别是准确率和损失: 0.5 0.6918725371360779

【问题讨论】:

【参考方案1】:

您的激活有问题 -> 该层是一个带有linear 激活函数的Conv2D:

fashion_model.add(Conv2D(64, (3, 3), activation='linear',padding='same'))

这增加了另一个激活函数,它是LeakyRelu

fashion_model.add(LeakyReLU(alpha=0.1))

您必须在其中一个或另一个之间做出选择。 我会建议你删除 LeakyRelu 层并通过 activation='relu' 更改 Conv2D 层内的激活函数。 此外,我认为您可以提高学习率,并使用lr = 1e-3lr = 1e-4

更多想法

Dropout 是一个很好的正则化层,以防过度拟合,这不是问题所在,先构建一个没有它的模型,然后在需要时添加它。 不要认为GlobalAveragePooling2D() 在这里是个好主意,尝试用Flatten() 层替换它。 如果您有大数据集,请尝试增加 batch_size 标准化图像有助于更好更快地收敛,因此请尝试使用 train_x = train_x / 255.0 缩放输入数组

根据前面所述的所有想法,我仅通过修改您的实现就设法达到了更好的准确性。

【讨论】:

谢谢大佬,但是我的准确率还是很差,请问还有什么问题吗? 谢谢您,先生,我采纳了您的建议并得到以下信息:Epoch 10/10 20/99 [=====>...... .........] - ETA: 19s - 损失: 0.5516 - acc: 0.8750 40/99 [==========>............ ......] - ETA:14s - 损失:0.5667 - acc:0.8125 60/99 [========>............] - ETA:9s - 损失:0.5683 - 累积:0.7917 80/99 [==============>......] - 预计到达时间:4 秒 - 损失:0.5686 - 累积:0.7687 99/99 [ =====================] - 26s 264ms/step - loss: 0.5862 - acc: 0.7020 - val_loss: 0.6798 - val_acc: 0.6400, 有一个改进训练 acc,但我仍然得到 0.55 和 0.71 作为 val acc 和 val loss 我想知道结果是否清楚,我很感谢所有的帮助 你能用这些日志更新你的答案吗?会更清楚,请使用您正在运行的新模型! 你说'但我仍然得到 0.55 和 0.71 作为 val acc 和 val loss' 但日志说它比这更好:' val_loss: 0.6798 - val_acc: 0.6400' 我在我的回答你可以试试【参考方案2】:

对于你的卷积层,你应该使用 ReLU 作为你的激活函数,另外,如果它是两个类,你应该在你的输出层使用 sigmoid,在编译时使用 binary_crossentropy。

【讨论】:

基于名称“fashion_model”,我猜你是基于 Fashion MNIST 的现有笔记本,这是多类分类,而不是二元分类。 谢谢你,先生,我做了你推荐的修改,但不幸的是我仍然得到了不好的准确性【参考方案3】:

你只有两个类,也许你有一个类不平衡问题,这可能是你的准确性较低的原因,当你转换为一维矩阵时尝试使用Flatten()

【讨论】:

我在使用之前平衡了我的课程。我确保每个班级都有相同数量的示例。你的意思是使用扁平化而不是重塑?

以上是关于使用 keras 顺序模型获得较差的分类精度的主要内容,如果未能解决你的问题,请参考以下文章

LSTM 文本分类精度差 Keras

Keras CNN 精度要么是静态的,要么对于图像分类来说太高了

使用Keras实现鸢尾花分类

Keras:微调 Inception 时精度下降

凯拉斯,Python。高精度模型总是分类错误

Keras深度学习实战——基于ResNet模型实现性别分类