我正在尝试使用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-3
或lr = 1e-4
。
更多想法
Dropout
在过度拟合的情况下是一个很好的正则化层,但这里不是问题,首先构建一个没有它的模型,如果需要,稍后添加它。- 不要认为
GlobalAveragePooling2D()
在这里是一个好主意,请尝试用Flatten()
层替换它。 - 如果您有大型数据集,请尝试增加batch_size
- 规范化图像有助于更好更快地收敛,因此请尝试使用
train_x = train_x / 255.0
缩放输入数组
有了前面提到的所有想法,我设法通过修改您的实现来达到更高的准确性。
对于您的卷积层,您应该使用 ReLU 作为激活函数,此外,如果它是两个类,您应该在输出层中使用 sigmoid,并在编译时binary_crossentropy。
你只有两个类,也许你有一个类不平衡问题,这可能是你准确性较低的原因,当你转换为一维矩阵时,尝试使用Flatten()