buto > /dev/null

だいたい急に挑戦してゴールにたどり着かずに飽きる日々です

Python ワンちゃんネコちゃん判定~成功版~

ディープラーニングの例でよく取り上げられる「犬or猫判定」をKerasでやってみた! Kaggleはデータセットもお手本モデルも提供されててすごい

^--^データセット^--^

Kaggle: Cat and Dog

^--^パクったモデル^--^

Cat or Dog Classification (3 - Models Comparision)

import keras
from keras.models import Sequential
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers.core import Activation
from keras.layers.core import Flatten
from keras.layers.core import Dropout
from keras.layers.core import Dense
from keras import backend as K
from keras.optimizers import RMSprop, Adam
from keras.regularizers import l2
from keras.utils import np_utils

import numpy as np
import cv2
from matplotlib import pyplot as plt
%matplotlib inline

# 画像の場所
TRAIN_DIR = './cat-and-dog/training_set/training_set'
TEST_DIR = './cat-and-dog/test_set/test_set'
# 画像をリサイズする大きさ
IMG_WIDTH = 100
IMG_HEIGHT = 100

# 学習画像を読み込む
# 学習データをリストにする
train_data = []
train_label = []

# ねこ画像4000枚(training_set/cats/cat.1.jpg~cat.4000.jpg)
for i in range(1,4001):
    image_name = 'cat.' + str(i) + '.jpg'
    # opencvで画像を読み込む
    image = cv2.imread(TRAIN_DIR + '/cats/' + image_name)
    # opencvで画像を100×100にリサイズ
    image = cv2.resize(image, (IMG_WIDTH, IMG_HEIGHT))
    # リサイズした画像を学習データリストに追加
    train_data.append(image)
    # 2クラス分類(犬or猫)なのでラベルは0と1を使用
    train_label.append(0)
    
# いぬ画像4000枚(training_set/dogs/dog.1.jpg~dog.4000.jpg)
for i in range(1,4001):
    image_name = 'dog.' + str(i) + '.jpg'
    image = cv2.imread(TRAIN_DIR + '/dogs/' + image_name)
    image = cv2.resize(image, (IMG_WIDTH, IMG_HEIGHT))
    train_data.append(image)
    train_label.append(1)

# ニューラルネットワークに画像データを入れるためにリスト→配列に変換
train_data = np.array(train_data)

# 正解ラベル(cat,dog)をone-hotエンコード
train_label = keras.utils.to_categorical(train_label, 2)

# テスト画像を読み込む
# テストデータをリストにする
test_data = []
test_label = []

# ねこ画像1000枚(training_set/cats/cat.4001.jpg~cat.5000.jpg)
for i in range(4001,5001):
    image_name = 'cat.' + str(i) + '.jpg'
    image = cv2.imread(TEST_DIR + '/cats/' + image_name)
    image = cv2.resize(image, (IMG_WIDTH, IMG_HEIGHT))
    test_data.append(image)
    test_label.append(0)
    
# いぬ画像1000枚(training_set/dogs/dog.4001.jpg~dog.5000.jpg)
for i in range(4001,5001):
    image_name = 'dog.' + str(i) + '.jpg'
    image = cv2.imread(TEST_DIR + '/dogs/' + image_name)
    image = cv2.resize(image, (IMG_WIDTH, IMG_HEIGHT))
    test_data.append(image)
    test_label.append(1)

# ニューラルネットワークに画像データを入れるためにリスト→配列に変換
test_data = np.array(test_data)

# 正解ラベル(cat,dog)をone-hotエンコード
test_label = keras.utils.to_categorical(test_label, 2)

# CNNモデルを構築
model = Sequential()

model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(100, 100, 3)))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(256, (3, 3), activation='relu'))
model.add(MaxPooling2D((2, 2)))

# 一次元に変換する層
model.add(Flatten())

# 50%の入力ノードを無効にする(過学習の防止)
model.add(Dropout(0.5))
model.add(Dense(512, activation='relu'))
model.add(Dense(2, activation='softmax'))

# モデルの精度を評価する方法を設定
model.compile(loss='categorical_crossentropy', optimizer=RMSprop(lr=1e-4), metrics=['accuracy'])

# モデルの構成を表示
model.summary()

# 学習・テスト実行
history = model.fit(x=train_data, # 学習データ
                    y=train_label, # 学習ラベル
                    batch_size=32, # バッチサイズ
                    epochs=5, # エポック数
                    verbose=1, # 標準出力に進捗を表示するか
                    validation_data=(test_data,test_label) # バリデーション(テスト)データ
                   )

# グラフのサイズ
plt.figure(figsize=(10,6))

# 青線:学習結果
plt.plot(history.history['accuracy'], color='b')
# 赤線:テスト結果
plt.plot(history.history['val_accuracy'], color='r')

plt.tick_params(labelsize=18)
plt.title('epoch - accuracy graph')
# 縦軸:正解率(モデルの精度)
plt.ylabel('accuracy')
# 横軸:エポック数
plt.xlabel('epoch')
plt.legend(['train','test'])
plt.show()