2016-10-14 3 views
3

Ребята Я пытаюсь классифицировать набор данных Dogs vs Cats с помощью CNN. Я глубоко изучаю начинающий кстати.Точность не достаточно высока для набора данных для cat_cats с использованием CNN с пифатом Keras-Tf

Ссылка на набор данных может быть получена от 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

попытаться вычитая изображение означает для начала: http://stats.stackexchange.com/questions/211436/why-do-we-normalize-images-by-subtracting- the-datasets-image-mean-and-not-the-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'))