深層学習　画像認識2　モデルの実装

[Aidemy](https://aidemy.net/)　2020/11/10
#はじめに
　こんにちは、んがょぺです！バリバリの文系ですが、AIの可能性に興味を持ったのがきっかけで、AI特化型スクール「Aidemy」に通い、勉強しています。ここで得られた知識を皆さんと共有したいと思い、Qiitaでまとめています。以前のまとめ記事も多くの方に読んでいただけてとても嬉しいです。ありがとうございます！
　今回は、深層学習・画像認識の二つ目の投稿になります。どうぞよろしくお願いします。

＊本記事は「Aidemy」での学習内容を「自分の言葉で」まとめたものになります。表現の間違いや勘違いを含む可能性があります。ご了承ください。

今回学ぶこと
・畳み込みニューラルネットワークについて
・モデルの実装について

#(復習)畳み込みニューラルネットワーク
##概要
・__畳み込みニューラルネットワーク（CNN）__とは、__画像処理__で主に使われる深層学習の手法である。
・Chapter1で使用していた多層パーセプトロン（MLP）は一次元の入力で他を受け取っていたが、CNNは__二次元のままデータを受け取れる__ので、画像のような二次元データを、情報を失わずに学習を行うことができる。

・畳み込みニューラルネットワークは__「畳み込み層」__と__「プーリング層」__からなる。畳み込み層は入力データの一部分に注目して__その画像の特徴を調べる層__のことである。
・__プーリング層__は畳み込み層からの__出力データを縮約__し、データ量を削減する層である。縮約の方法としては、各特徴の最大値をとる__「Maxプーリング」__、平均値を取る__「Averageプーリング」__がある。

・畳み込み層の関係図![スクリーンショット 2020-11-09 12.26.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/4a939228-1e57-3d36-8fc3-9053d328b145.png)

・プーリング層の関係図（Maxプーリング）![スクリーンショット 2020-11-09 12.27.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/74a3057a-ac63-e30e-f100-3640c083ed1d.png)

#層の実装
・今回は__Sequentialモデル__で層の実装を行う。
・層の種類の一つには__「全結合層（Dense）」__がある。これは、入力と出力が全てつながっているような層である。以下のモデルでは、全結合層を2回使っている。

![スクリーンショット 2020-11-09 12.37.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/9f75aa54-53d1-bb73-e99e-ade71b7d82cb.png)

・前項の「畳み込み層」は__「Conv2D()」__で実装できる。__「filters」__にはフィルタの数、__「kernel_size」__にはフィルタのサイズ、__「strides」__はフィルタを一度に動かす距離、__「padding」__は__'same'__なら入力サイズと出力サイズを揃え、__'valid'__なら行わない。

・プーリング層は、Maxプーリングなら__「MaxPooling2D()」__で実装できる。__「pool_size」__はプールする範囲の大きさ、__「strides」__はフィルタを一度に動かす距離を指定する(stridesは指定しなくても良い)。

・これらの入力層については、__「input_dim（一次元）」「input_shape（多次元）」__で入力データの大きさを指定する。例えば、（28×28）のRGB画像データの場合「input_shape=(28,28,3)」となる。

・Conv2DやMaxPooling2Dなどの__2次元の出力をする層__と、Denseのように___1次元の入力を受け取る層__を結合するときは__「平坦化層」__を追加する必要がある。
・平坦化層は__「Flatten()」__で追加でき、特に__引数は必要ない__。

・以下のコードはここまでの層を追加したものの例である。
model.add(Conv2D(input_shape=(28, 28, 3), filters=32, kernel_size=(2, 2), strides=(1, 1), padding="same"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(filters=32, kernel_size=(2, 2), strides=(1, 1), padding="same"))
model.add(MaxPooling2D(pool_size=(2, 2)))

#モデルの学習
##活性化関数の指定
・__「model_add(Activation('関数名'))」__で活性化関数を指定する。シグモイド関数なら__「sigmoid」__、ReLU関数なら__「relu」__、出力層で使われる__「softmax」__がある。

##コンパイル、学習
・モデルに層を追加したら、__コンパイル__を行う。コンパイルでは、__学習率の変更方法__や、__損失関数の指定__、__精度指標の指定__などを行う。より正確にはコンパイルとは、__「高水準のプログラミング言語で書かれたコードを解析し、コンピュータが直接実行可能な機械語にあらかじめ変換すること」__である。
・コンパイルは__「model.compile()」__で行える。__「optimizer」__で学習率を指定、__「loss」__で損失関数を指定、__「metrics」__は精度指標を指定する。
・学習率は__[SGD,RMSprop,Adagrad,Adadelta,Adam]__などがあるがどれを使うかは__探索的に決定__する。
・損失関数は__平均二乗誤差（mean_squared_error）__、__交差エントロピー(category_crossentropy,binary_crossentropy)__などがある。
・__metrics__は__「['accuracy']」__と指定することが多い。

・学習は__「model.fit()」__で行う。これにトレーニングデータの入力とラベルを渡す他、__「batch_size」__で一度に渡すデータ数の指定、__「epochs」__で学習回数を指定する。batch_sizeについては、Chapter1の最後に学んだ__「ミニバッチ学習」__を行うために指定する。

・コード例
![スクリーンショット 2020-11-09 13.55.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/0d7559ed-55a9-fdcc-c6aa-15a1cb409206.png)

##モデルの性能評価
・学習させたモデルに対して、__テストデータで精度評価する__。これは__「model.evaluate()」__で行う。テストデータの入力データとラベルを渡す他、verbose=1とすると計算過程を表示する。

##モデルのセーブ、ロード
・作成したモデル保存するときは__「model.save('model.h5')」__のように行う。
・このモデルを読み込むときは__「model.load_model('model.h5')」__とする。

・また、__人がこのモデルを閲覧したり編集したりするようにする__には、一度__「json」__形式に変換する必要がある。これは__「model.to_json()」__で行う。
・これをロードするには__「model_from_json(変換後のモデル)」__とする。

#まとめ
・画像処理では、二次元の画像データが扱える「畳み込みニューラルネットワーク」が使われる。
・モデルの実装としては、畳み込み層と全結合層を平坦化層で結合することで実装し、コンパイルと学習行ったら、モデルを評価するという手法を使う。

今回は以上です。最後まで読んでいただき、ありがとうございました。