2016-10-14 5 views
3

Guys CNNを使用してDogs vs Catsデータセットを分類しようとしています。私は初心者の初心者です。Kers-Tf pythonでCNNを使用してdogs_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%テストの精度)同様の結果を得た:model.complie損失関数のために私もcategorical_crossentropyをしようとしたデフォルトのパラメータでadamと私も試したオプティマイザのために

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 

が、ありましたがない(または非常にわずかな)改善。

私が間違っているつもりですか、私は効率を改善するために何ができるか、どこがお勧めすることはできますか?(いくつかのエポックでは、可能な場合)

(私は深い学習とkerasプログラミング初心者です...)

EDIT:70.224%のテスト精度と74.27%のトレーニング精度に対応しました。 CNNアーキテクチャは(:74%とテストは次のとおりです。トレーニングACCなど一切オーバーフィッティングはほとんどありません70%) CONV => CONV => POOL => DROPOUT => FLATTEN => DENSE*3

しかし、まだそれを更に向上させる提案を開いて、70%が下側に間違いです。 ..

+0

画像を減算してみてくださいスタートを意味:http://stats.stackexchange.com/questions/211436/why-do-we-normalize-images-by-subtracting-をthe-data-sets-and-not-the-c – y300

+0

どのくらいのトレーニングデータがありますか? – TheM00s3

+0

私は25000(各犬と犬の12500)トレーニングセットと12500(各6250)テストセット – pyofey

答えて

0

基本的に、ネットワークの深さは十分ではありません。そのため、トレーニングと検証の精度は低いです。 2つの側面からネットワークを深化させることができます。

  1. 各畳み込みレイヤーには、より多くのフィルタを使用します。 (30,5,5)または(15,3,3)だけでは不十分です。最初の畳み込みレイヤを(64,3,3)に変更します。あなたの2Dサイズを減らす最大プールの後、ネットワークは "より深い"機能を提供するはずです。したがって、2番目は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')) 
関連する問題