内容
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)
とすればいい。