使用 Keras 顺序模型获得较差的分类准确性



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

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

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 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

您的激活有问题 ->
此层是具有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缩放输入数组

有了前面提到的所有想法,我设法通过修改您的实现来达到更高的准确性。

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

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

最新更新