2016-10-14 62 views
3

夥計們我試圖用CNN對Dogs vs Cats數據集進行分類。我深入學習初學btw。準確性不夠高,dog_cats分類數據集使用CNN和Keras-Tf python

數據集鏈接可從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

(幾乎沒有過學習培訓ACC:74%,測試是:70%)

但仍然開放的建議,以進一步提高它,70%絕對是下側。 ..

+0

嘗試減去圖像意味着一個開始:http://stats.stackexchange.com/questions/211436/why-do-we-normalize-images-by-subtracting- the-datasets-image-mean-and-not-c – y300

+0

你有多少訓練數據? – TheM00s3

+0

我有25000(每隻貓和狗12500)訓練集和12500(每個6250)測試集 – pyofey

回答

0

基本上,你的網絡不夠深入。這就是爲什麼你的訓練和驗證準確性都很低。您可以嘗試從兩個方面深化您的網絡。

  1. 對於每個卷積層使用更大數量的濾波器。 (30,5,5)或(15,3,3)是不夠的。將第一個卷積圖層更改爲(64,3,3)。在最大化池,這會減少你的2D尺寸後,網絡應該提供「更深」的功能。因此,第二個不應該是15,而應該是(64,3,3)或者甚至是(128,3,3)。

  2. 添加更多卷積圖層。 5或6層這個問題可能會很好。

總的來說,你的問題是無法編程的。它更多關於CNN網絡架構。您可以閱讀更多關於此主題的研究論文,以便更好地理解。對於這個特定的問題,Keras有一個非常好的教程,關於如何通過非常小的一組貓和狗的圖像來提高性能: Building powerful image classification models using very little data

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')) 
相關問題