我正在尝试使用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
答案 0 :(得分: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-3
或lr = 1e-4
。
Dropout
是一个很好的正则化层,以防过度拟合,这里不是问题所在,首先建立一个没有模型的模型,然后在需要时添加它。GlobalAveragePooling2D()
是个好主意,请尝试用Flatten()
层替换它。train_x = train_x / 255.0
缩放输入数组利用前面提到的所有想法,我仅通过修改实现即可设法达到更高的准确性。
答案 1 :(得分:0)
对于conv层,您应该使用ReLU作为激活函数,而且,如果是两个类,则在输出层中应使用sigmoid,编译时应使用binary_crossentropy。
答案 2 :(得分:0)
您只拥有两个类,也许您有一个类不平衡问题,这可能是准确性较低的原因,并在转换为一维矩阵时尝试使用Flatten()