Kerasを用いた手書き画像認識Ⅲ:畳み込みネットワークを用いたテストコード
前回までのあらすじ
最初はTensorflowを用いて隠れ層を導入したパーセプトロンにて学習を行いました。
ossyaritoori.hatenablog.com
次に,Kerasを導入して3層のニューラルネットワークで学習を行い,改善を得ました。
ossyaritoori.hatenablog.com
今回は畳み込みニューラルネットワークを試してみましょう。
畳み込みネットワーク(CNN)について
画像の認識などにおいて強力な性能を発揮する手法で、
画像の二次元畳み込み(2D Convolution)計算を層間の伝搬に用いる手法です。
以下のサイトが図が見やすくてわかりやすいでしょう。
postd.cc
最近聞いてきた公演によるとプーリング層や全結合層はなくて,GAP層を用いるのが標準になりつつあるそうですね。
環境の下準備
前回の記事でのKerasパッケージの導入のところをきちんとこなしておいてください。
Tensorflow,Kerasを用いた手書き画像認識:MNISTを使ったテストコード - 粗大メモ置き場
KerasにおけるCNNの実装手法
以下にKerasを用いた際のモデルの生成部を示します。
Denseの代わりにConv2Dという関数で畳み込みの層を決めており,
Kernelのサイズや数などを同時に決定しています。
これだけです。まじかよ超簡単じゃん。
model = Sequential() model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape)) model.add(Conv2D(64, (3, 3), 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(Dropout(0.5)) model.add(Dense(num_classes, activation='softmax')) model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adadelta(), metrics=['accuracy'])
流れは,
と言ったところでしょう。
例のごとく他所様からコードをお借りしていますが疑問として,
どうして最初の層が32個のカーネルなのに次の層が64個なんでしょう?
(勉強不足が露呈している)
なんとなく逆の方が良さそうなもんですが何か意味があるんでしょうか。
Kerasを用いたコード
ライブラリとしてKerasをダウンロードしたPC上で動作を確認しています。
実行環境はSpyder3上のIPythonコンソール上で行っています。
詳しい環境については過去記事を漁ってください。
結果:元のコード
数回のEpochを繰り返して精度をブラッシュアップしますが今回は12回目で99%を達成しました。これだけでも十分すごいですが実用上では99.999%より上の性能が求められるようでなんというか大変だなぁ…
Epoch 12/12 60000/60000 [==============================] - 82s - loss: 0.0365 - acc: 0.9887 - val_loss: 0.0289 - val_acc: 0.9901 Test loss: 0.0288566211587 Test accuracy: 0.9901
結果:ちょっと弄ったコード
さっきの畳み込み層の順番を32→64から64→32へと変更してみました。
ほとんど差がありませんね。ただ,かかった時間はこちらのほうが長かったように思います。
確かより「深い層」の方が計算が面倒になるのでそういった事情を考慮して32→64という構造なのかもしれません。
Epoch 12/12 60000/60000 [==============================] - 102s - loss: 0.0450 - acc: 0.9869 - val_loss: 0.0287 - val_acc: 0.9904 Test loss: 0.0286987099324 Test accuracy: 0.9904
後処理
モデルの保存
せっかく作ったモデルですのでもったいないしきちんと保存しましょう。
[TF]KerasでModelとParameterをLoad/Saveする方法 - Qiita
jsonという形式を通してファイルで保存したいとすると,以下のような流れになります。
詳細は今度記事に書きます。pickleというクラスを使います。
import pickle json_string = model.to_json() with open('mnistmodel.pickle', 'wb') as f: pickle.dump(json_string,f)
学習したパラメータの保存
学習したパラメータは.hdf5という形式で保存されます。
model.save_weights('mnistparam.hdf5')
読み出し方は上のURLを参照してください。個別に記事を書くかもしれません。
可視化
可視化についてはgraphvizやらpydot_ngやらをインストールする必要があるのでまた今度書きます。
以下のサイトが役に立つことでしょう。
www.mathgram.xyz