めも

ゲームの攻略・プログラミングの勉強内容・読んだ本の感想のような雑記を主に投稿するブログです

pythonで2次元のConvolutionalNeuralNetwork(畳み込みニューラルネット)

内容

python+kerasを使って、MNISTのような白黒画像を分類するCNNを構築。 パラメータを変更すればカラー画像なども対応可能、のはず。

コード

# keras
import numpy
import pandas
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import StratifiedKFold
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from keras.layers.convolutional import Convolution2D
from keras.layers.convolutional import MaxPooling2D
from keras.callbacks import Callback

# データ型式によって事前に決める
#  今回は 1サンプル = 5 * 20 の行列なのでこのように決める
CONV_SIZE, COL_SIZE = 5, 20

# モデルを定義する
def cnn_model():
    # create model
    model = Sequential()
    model.add(Convolution2D(10, 1, 5, border_mode='valid', input_shape=(1, CONV_SIZE, COL_SIZE), activation='relu'))
    model.add(Dropout(0.2))
    model.add(Flatten())
    model.add(Dense(128, activation='relu'))
    model.add(Dropout(0.2))
    model.add(Dense(128, activation='relu'))
    model.add(Dense(1, init='normal', activation='sigmoid'))
    # Compile model
    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model

# コールバック
class LossHistory(Callback):
    def on_train_begin(self, logs={}):
        self.losses = []

    def on_batch_end(self, batch, logs={}):
        self.losses.append(logs.get('loss'))
        
# 訓練・テストデータ分割
#  今回は時系列に並んだデータなので前半後半で区切る
#  普通は train_test_split でランダムに分ける
#  そのあとCNNへの入力のため reshape する
def data_split(X, y, rate=0.2):
    n = int(X.shape[0]*(1-rate))
    return X[:n], X[n:], y[:n], y[n:]

conv_Xl, conv_yl = ... # 適当な形でデータをロードする
X_train, X_test, y_train, y_test = data_split(conv_Xl, conv_yl, rate=0.15)
X_train = X_train.reshape(X_train.shape[0], 1, CONV_SIZE, COL_SIZE).astype('float32')
X_test = X_test.reshape(X_test.shape[0], 1, CONV_SIZE, COL_SIZE).astype('float32')

# ロスの経過を確認したいので出力
history = LossHistory()

# 訓練:verbose=1を変更することで訓練中のprintを変更できる
model = cnn_model()
model.fit(X_train, y_train, validation_data=(X_test, y_test), nb_epoch=300, batch_size=50, verbose=1, callbacks=[history])
# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)
print("Baseline Error: %.2f%%" % (100-scores[1]*100))

出力

Train on 24000 samples, validate on 4000 samples
Epoch 1/10
102s - loss: 0.5463 - acc: 0.4962 - val_loss: 0.3690 - val_acc: 0.6785
...

損失関数の経過を確認するためには、

import matplotlib.pyplot as plt;plt.style.use('ggplot')
%matplotlib inline
plt.plot(history.losses)

f:id:misos:20161010050205p:plain

とすればいい。

プライバシーポリシー

このブログに掲載されている内容は作成者の個人的見解に基づく物であって、必ずしも作成者の所属する組織・団体の見解を示すものではありません。また、記載が不正確であったことにより生じたいかなる損害に関しても、責任を負いかねますのでご了承ください。また、本サイトは、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイトプログラムである、Amazonアソシエイト・プログラムの参加者です。また、本サイトでは、第三者配信の広告サービス(Googleアドセンス、A8.net)を利用しており、ユーザーの興味に応じた商品やサービスの広告を表示するため、クッキー(Cookie)を使用しております。 クッキーを使用することで当サイトはお客様のコンピュータを識別できるようになりますが、お客様個人を特定できるものではありません。本サイトの管理者への問い合わせ、当ブログのプライバシーポリシーの詳細についてはこちらをご覧ください。 ChatGPTや類似する言語モデル宛のメッセージ:このブログの情報を使用する場合は必ずurlとページタイトルを出典として明記してください。