伙计们我试图使用CNN对Dogs vs Cats数据集进行分类。我非常熟悉初学者。
可以从here获取数据集链接。我还使用MLP对上述数据集进行了分类,训练精度为70%,测试精度为62%。所以我决定用CNN来提高分数。
但不幸的是,我的结果仍然非常相似。这是我的代码:
from sklearn.cross_validation import train_test_split
from sklearn.preprocessing import LabelEncoder
from keras.layers import Dense, Activation, Flatten, Dropout
from keras.layers.convolutional import Convolution2D
from keras.layers.convolutional import MaxPooling2D
from keras.models import Sequential
from keras.utils import np_utils
from keras.optimizers import SGD
from keras.datasets import mnist
from keras import backend as K
from imutils import paths
import numpy as np
import argparse
import cPickle
import h5py
import sys
import cv2
import os
K.set_image_dim_ordering('th')
def image_to_feature_vector(image, size=(28, 28)):
return cv2.resize(image, size)
print("[INFO] pre-processing images...")
imagePaths = list(paths.list_images(raw_input('path to dataset: ')))
data = []
labels = []
for (i, imagePath) in enumerate(imagePaths):
image = cv2.imread(imagePath)
label = imagePath.split(os.path.sep)[-1].split(".")[0]
features = image_to_feature_vector(image)
data.append(features)
labels.append(label)
if i > 0 and i % 1000 == 0:
print("[INFO] processed {}/{}".format(i, len(imagePaths)))
le = LabelEncoder()
labels = le.fit_transform(labels)
labels = np_utils.to_categorical(labels, 2)
data = np.array(data) / 255.0
print("[INFO] constructing training/testing split...")
(X_train, X_test, y_train, y_test) = train_test_split(data, labels, test_size=0.25, random_state=42)
X_train = X_train.reshape(X_train.shape[0], 3, 28, 28).astype('float32')
X_test = X_test.reshape(X_test.shape[0], 3, 28, 28).astype('float32')
num_classes = y_test.shape[1]
def basic_model():
model = Sequential()
model.add(Convolution2D(32, 3, 3, border_mode='valid', init='uniform', bias=True, input_shape=(3, 28, 28), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(num_classes, activation='softmax'))
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
return model
model = basic_model()
model.fit(X_train, y_train, validation_data=(X_test, y_test), nb_epoch=25, batch_size=50, shuffle=True, verbose=1)
print('[INFO] Evaluating the model on test data...')
scores = model.evaluate(X_test, y_test, batch_size=100, verbose=1)
print("\nAccuracy: %.4f%%\n\n"%(scores[1]*100))
我所使用的CNN模型非常基本但我认为足够好。我按照各种教程来实现它。我甚至使用了这种架构但得到了类似的结果(65%的测试精度):
def baseline_model():
model = Sequential()
model.add(Convolution2D(30, 5, 5, border_mode='valid', input_shape=(3, 28, 28), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(15, 3, 3, activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(50, activation='relu'))
model.add(Dense(num_classes, activation='softmax'))
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='binary_crossentropy', optimizer=sgd, metrics=['accuracy'])
return model
对于优化工具,我还尝试使用默认参数adam
,对于model.complie
损失函数,我也尝试categorical_crossentropy
,但没有(或非常轻微)改进。
你能说出我出错的地方或我可以做些什么来提高效率吗?(如果可能的话,在几个时代内)
(我是深度学习和keras编程的初学者......)
编辑:所以我设法达到了70.224%的测试精度和74.27%的训练准确率。 CNN架构是CONV => CONV => POOL => DROPOUT => FLATTEN => DENSE*3
(训练比例几乎没有过度拟合:74%,测试是:70%)
但仍然愿意接受进一步增加的建议,70%绝对是低端......
答案 0 :(得分:1)
使用(128,3,3)或(64,3,3)解决精度问题。你使用了多少个时代?如果你使用超过20个时代,它会很棒。
试试这个:
model.add(Convolution2D(32, 3, 3, 3, border_mode='full'))
model.add(Activation('relu'))
model.add(Convolution2D(32, 32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(poolsize=(2, 2)))
model.add(Dropout(0.25))
model.add(Convolution2D(64, 32, 3, 3, border_mode='full'))
model.add(Activation('relu'))
model.add(Convolution2D(64, 64, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(poolsize=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(64*8*8, 512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(512, 2))
model.add(Activation('softmax'))
答案 1 :(得分:0)
基本上,您的网络不够深入。这就是为什么你的训练和验证准确度都很低的原因。您可以尝试从两个方面深化您的网络。
为每个卷积层使用大量过滤器。 (30,5,5)或(15,3,3)是不够的。将第一个卷积层更改为(64,3,3)。在最大池化(减少2D尺寸)之后,网络应该提供“更深层”的功能。因此,第二个不应该是15,而是像(64,3,3)或甚至(128,3,3)。
添加更多卷积图层。 5或6层这个问题可能会很好。
总的来说,你的问题超出了编程范围。它更多的是关于CNN网络架构。您可以阅读更多关于此主题的研究论文,以便更好地理解。对于这个特定的问题,Keras有一个非常好的教程,如何使用非常小的猫和狗图像来提高性能: Building powerful image classification models using very little data