[Deep Learning] ゼロから作るDeep LearningのCNNをKerasで作ってみる

[ゼロから作るDeep Learning](https://www.amazon.co.jp/ゼロから作るDeep-Learning-―Pythonで学ぶディープラーニングの理論と実装-斎藤-康毅/dp/4873117585/ref=sr_1_1?ie=UTF8&qid=1527370773&sr=8-1&keywords=ゼロから作る+deep+learning)の2回目の読書が終了しました。 前回読んだ時も実際に手を動かしながら確認したのですが、他の本を読んんだりして再度読み返すと更に理解が深まった気がします。 写経しただけでは実際に理解したとは言えないので、Kerasを使ってCNNを実際に作成して見る事にしました。 (実際には[Kerasのサンプルソース](https://github.com/keras-team/keras/blob/master/examples/mnist_cnn.py)を参考にしまくっています) ## CNNネットワーク ネットワークは以下の形です。 ``` 画像 -> 1.Conv -> ReLU -> 2.Pooling -> 3.Affine -> ReLU -> 4.Affine -> Softmax ``` #### 1.Conv 畳み込み層, Filter:30, Filter Size:(5,5), Pading:0, Strides:1 #### 2.Pooling Maxプーリング #### 3.Affine 100層の隠れ層(全結合層) #### 4.Affine 出力層10層の全結合層 ### ポイント Kerasで実装する際には、いくつかの層をまとめて記述する必要があります。 例えば、ConvとReLUはConv2Dでまとめて記述します。 PoolingはMaxPooling2Dを使い, 全結合層はDenseを使います。 Denseは出力のactivationを指定する事ができるので、ReLUを指定します。 ## ソースコード ```python # coding:utf-8 # # Kerasでゼロから作るDeep LearningのCNNを作成する # import keras from keras.datasets import mnist from keras.models import Sequential from keras.layers import Dense, Flatten, Dropout from keras.layers import Conv2D, MaxPooling2D from keras import backend as K import pandas as pd import matplotlib.pyplot as plt batch_size = 32 num_classes = 10 epochs = 20 # input image demensions img_rows, img_cols = 28, 28 # the data, split between tran and sets (x_train, y_train), (x_test, y_test) = mnist.load_data() # 画像のチャンネルが先か後かでデータをreshapeする print(K.image_data_format()) if K.image_data_format() == 'channels_first': x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols) x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols) input_shape = (1, img_rows, img_cols) else: x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1) x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1) input_shape = (img_rows, img_cols, 1) print(x_train.shape) #(60000, 28, 28, 1)が出力される # 学習データを0-1の範囲に正規化する x_train = x_train.astype('float32') x_test = x_test.astype('float32') x_train /= 255 x_test /= 255 print('x_train shape:', x_train.shape) print(x_train.shape[0], 'train samples') print(x_test.shape[0], 'test samples') # convertclass vectors to binary matrices # one_hot_label に変換する処理 y_train = keras.utils.to_categorical(y_train, num_classes) y_test = keras.utils.to_categorical(y_test, num_classes) # # ここからモデルの構築 # Conv-ReLU-Pooling -- Affine-ReLU -- Affine-Softmax # model = Sequential() model.add(Conv2D(30, kernel_size=(5, 5), strides=1, activation='relu', input_shape=input_shape)) model.add(MaxPooling2D(pool_size=(2, 2))) # これを入れないとエラーになる model.add(Flatten()) model.add(Dense(100, activation='relu')) model.add(Dense(num_classes, activation='softmax')) # 損失関数 交差エントロピー誤差平均 # 最適化関数 Adadelta model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adadelta(), metrics=['accuracy']) # 学習を行う history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(x_test, y_test)) # plot learning history plt.style.use("ggplot") df = pd.DataFrame(history.history) df.index += 1 df.index.name = "epoch" df[["acc", "val_acc"]].plot(linewidth=2) plt.savefig("plt_acc_history.png") df[["loss", "val_loss"]].plot(linewidth=2) plt.savefig("plt_loss_history.png") score = model.evaluate(x_test, y_test) print("Test loss:", score[0]) print("Test accuracy:", score[1]) ``` Kerasで作成する上でのポイントはConv2D層の後にFlatten()を入れる必要があります。 それを入れないと実行時にエラーになってしまいます。 ``` `gutter:false; ValueError: Error when checking target: expected dense_2 to have 4 dimensions, but got array with shape (60000, 10) ``` 解決の参考にしたのは以下のページです [stackoverflow](https://stackoverflow.com/questions/47050571/valueerror-error-when-checking-target-expected-dense-2-to-have-4-dimensions-b) 参考にしたソースにも入っていたのですが、ネットワークを作成する部分は自分で作成したので必要な事に気づくのが遅れました。 ### 学習結果 学習結果は認識率99%のかなり良い感じ。 認識率と損失のグラフを確認すると、訓練データとテストデータに若干乖離があります。 (過学習の恐れあり)
過学習を防ぐためには、Dropout層を入れると良いようなのでDropout層を入れて実験してみました。 その結果はまたの機会にまとめます。

0 件のコメント :

コメントを投稿