Aidemy 2020/11/10
はじめに
こんにちは、んがょぺです!バリバリの文系ですが、AIの可能性に興味を持ったのがきっかけで、AI特化型スクール「Aidemy」に通い、勉強しています。ここで得られた知識を皆さんと共有したいと思い、Qiitaでまとめています。以前のまとめ記事も多くの方に読んでいただけてとても嬉しいです。ありがとうございます!
今回は、深層学習・画像認識の三つ目の投稿になります。どうぞよろしくお願いします。
*本記事は「Aidemy」での学習内容を「自分の言葉で」まとめたものになります。表現の間違いや勘違いを含む可能性があります。ご了承ください。
今回学ぶこと
・Kerasの便利な機能
・モデルの精度を上げる手法について
便利な機能
学習過程の表示
・学習を進める中で、精度がどのように変化したのかを視覚化する方法__がある。例えば変数「history」に「model.fit()」を格納したとすると、「history.history['acc']」で精度の変化を得ることができる。あとはこれを「plt.plot()」__すれば可視化できる。
・また、前のChapterでは汎化精度の計算を__「model.evaluate(X_test,y_test)」で行っていたが、「model.fit()」の引数に「validation_data=(X_test,y_test)」を追加することで、同様に__汎化精度を計算してくれる。
・同様に、汎化精度の変化を取得するときは__「history.history['val_acc']」__で行い、可視化すると良い。
Early Stopping
・学習回数が多すぎても、一定のところを超えると精度が落ちていく。このような場合は__学習を早めに打ち切る__ことが大切である。このようなときに使えるのが__「Early Stopping」である。
・Early Stoppingは、学習用、テスト用データとは別に検証用データを持っておき、学習ごとにそのデータの評価と学習データの評価の誤差をとり、誤差が広がってきたタイミングで学習をストップするというものである。
・コードとしては、まず「es=EarlyStopping()」としてインスタンスを作成する。あとはmodel.fit()の引数に「callbacks=[es]」というようにするだけでよい。
・インスタンスの引数としては「monitor」で何を評価の誤差として監視するかを指定し、「patience」でその監視している値が何エポック改善されなかったら学習を打ち切るかを指定、「mode」には「モデルの改善」は指定した値が「増加」したら改善なのか、「減少」したら改善なのかを、それぞれ「'max'」「'min'」で指定する。これを「'auto'」__としたときは、自動で推測してくれる。
モデル構造の出力
・モデルの構造を確認したいときは、これを__画像で出力する__手法がある。方法は__「plot_model(model, to_file='model.png')」というようにするだけである。
・また、各層ごとに名前を設定したい場合は、「model.add()」で層を以下するときに、引数に「name」__を加えれば良い。
・コード
・結果
精度を上げる方法
最適化
・学習率は、学習が進むにつれて変化させる__ほうがうまく学習できることが多い。このことを「学習率の最適化」__といい、__Adam、RMSprop、Adagrad__などが使われる。
ドロップアウト
・これまでにも何度も出てきているが、過学習を防ぎ、精度を上げるのに使われる手法としては__ドロップアウト__が挙げられる。これは、ランダムでデータを除去することで汎化されやすくする手法である。
ファインチューニング(転移学習)
・ファインチューニング__(転移学習)__は以前にも学習しているが、他のモデルの一部を使用__して学習させる手法である。画像認識で言えば、最後の全結合層だけを変更し、畳み込み層はそのまま使用する。
・画像認識のモデルとしては、Kerasでは「Xception、VGG16、VGG19、ResNet50、InceptionV3」__の5つの画像分類モデルを、__ImageNet__で学習した重みをダウンロードして使うことができる。以下では__VGG16__のモデルを作った例を記載する。
・以上のコードについて、まずは__「input_tensor」で入力の形を与える。これを定義したら、実際にVGGのモデルを作成する。「VGG16()」で作成することができる。引数としては、「include_top」で元のモデルの全結合層を使用するかをTrueorFalseで指定し、「weights='imagenet'」でimagenetで学習した重みを使用するように指定、「input_tensor」__で先ほど定義した入力の形を記載する。
・ここまで行ったら、次は出力層(全結合層)付近のモデル__(top_model)を別に作成していく。top_modelの入力層は、VGGモデル(畳み込み層)の出力を受け取るので、「Flatten()」とする。input_shapeは「vgg16.output_shape[1:]」とすることで、VGGモデルの出力の形(二次元)を取得できる。
・あとは普通のモデルと同様に層を追加すれば良い。出力層まで追加したら、次は「入力はvgg16.input、出力はtop_modelにvggの出力を入れたもの」__とする最終的なモデルを作成する。
・以上で層の追加は終わりで、ここからはコンパイルと学習を行っていくが、その前に、VGGモデル部分の重みは変更されないように設定しておく。
・コンパイルと学習には特に変更点はない。一点だけ、転移学習を行うときは最適化関数は__「SGD」__にすると良い。
まとめ
・学習の精度は__「history['acc']」を「plt.plot()」することで可視化できる。
・model.evaluate()を使わずとも、model,fit()に「validation_data」を設定することでモデルの__汎化精度を計算__してくれる。
・EarlyStoppingを使う時は、インスタンスを作成してから、model.fit()の引数「callbacks」でそれを指定すれば良い。
・モデル構造を画像として可視化したい時は、「plot_model(model,to_file)」__で行える。
・精度を上げる方法としては、最適化やドロップアウトがあるほか、__転移学習__を行うこともある。例えば画像認識だったら、畳み込み層は__VGG16__で転移させ、出力層付近のモデルは自分で実装して、結合することで全体のモデルを実装する。
今回は以上です。最後まで読んでいただき、ありがとうございました。