【初心者向け】『ゼロから作る Deep Learning』要点まとめ
前置き
AIエンジニア、データサイエンティストを目指してブログに勉強記録を綴っていくことにした。
深層学習を勉強していく上で将来的にボトルネックになるのは、
「フレームワークの運用」ではなく「理論の理解」
らしいので(実際共感している)、まずはブラックボックス化したフレームワークを学ぶ前に、理論の理解に時間をかけようと思い、深層学習の入門書として『ゼロから作る Deep Learning』を友人のAIエンジニアから薦められたため、当該書を一週間かけて読んでみた。
本当にゼロから理解できる内容で、今後何度も立ち返ることになりそうな良書だったので、整理して要点をまとめようと思う。
なお、数式やコードは本を参照すれば良いので、ここでは定性的な理解を言語化することに留める。
前提知識
1章:Python入門
- 基本的なPythonの文法
- Numpyの扱い方
- Matplotlibの扱い方
この章に関しては簡潔すぎるので、機械学習の基本を身につけるなら他の書籍で勉強した方が良い。
scikit-learnでとりあえず実装に慣れたいならこれ。
2章:パーセプトロン
- 単層パーセプトロンでは線形領域しか表せないので、AND、ORゲートのみ表現できる
- 2層にすれば非線形領域も表せるので、XORゲートを表現できる
- 多層パーセプトロンによって理論上コンピュータを表現できる
- 電気回路における「抵抗」は電流の”流れにくさ”、パーセプトロンにおける「重み」は信号の ”流れやすさ” に対応している
パーセプトロンは、脳神経の信号伝達の仕組みを数理モデル化したものと解釈できる。
大学のモデリングとシミュレーションの授業で「ライフゲーム」によるコンピュータの表現を学んだが、このように視覚化されないと「0と1の出力の集合によってコンピュータが表現できる」と言われてもあまり腹落ちしない気はする。
参考動画↓
この後出てくるニューラルネットワークの最小単位がこのパーセプトロンなので、ニューラルネットで詰まったらこの章に立ち返る。
3章:ニューラルネットワーク
- NNは適切な重みパラメータを ”自動で” 学習できる
- 一つのニューロンの内部には、前層からの出力結果aと、活性化関数によって変換されたy=h(a)が含まれる
- 活性化関数は最近ではシグモイド関数よりReLU関数が主流になっている
- 活性化関数には線形関数を用いてはならない
- 出力層の活性化関数は、回帰問題では恒等関数、分類問題ではソフトマックス関数を使う
- ソフトマックス関数の出力はそのまま「確率」として解釈できる
- one-hot表現とは、例えば [0,0,0,0,1,0,0,0,0] のように正解ラベルのみ1で、それ以外は0で表記する方法
- 分類問題では、出力層のニューロンの数と分類するクラスを対応させる
- コンピュータは小さい行列を少しずつ計算するより、大きい行列を一気に計算する方が高速になる。そのためのまとまった入力データをバッチと言う
4章:ニューラルネットワークの学習
- 訓練データの中からランダムに一部のデータ(=ミニバッチ)を取り出し、その損失関数の和を小さくすることが目的
- 損失関数はNNの "性能の悪さ" の指標
- 損失関数としては、「2乗和誤差」と「交差エントロピー誤差」がよく使われる
- 各重みパラメータの勾配を数値微分によって算出し、損失関数が小さくなる方向に重みパラメータを更新していく(=学習)
5章:誤差逆伝播法
- 計算グラフを使えば、計算過程を視覚的に理解できる
- 出力層から入力層に向かって、偏微分演算子に注目して連鎖律から逆向きに計算する
- 構成要素をレイヤとして実装することで、内部をブラックボックス化し、レイヤの出力と入力から効率的に勾配を計算できる
6章:学習に関するテクニック
- パラメータの更新方法として、一番単純な確率的勾配降下法(SGD)では効率が悪いことがある
- Momentumは物理学の減衰運動を模倣したモデルで、ボールがお椀を転がるような動きをする
- AdaGradは学習係数の減衰を考えるモデルで、過去全ての勾配の2乗和を記憶している。そのため、初めは大きく、徐々に小さく学習していくが、無限に学習するといずれ更新量は0になってしまう
- RMSPropはAdaGradの改良版で、過去の勾配情報は次第に忘れ、新しい勾配情報を大きく反映する
- AdamはMomentumとAdaGradの融合版
- 重みの初期値はランダムに設定しないと均一になってしまう
- 活性化関数の後の出力データ(=アクティベーション)は、重みの初期値によって変化する。
- アクティベーションがシグモイド関数によって0と1に偏る分布になると、勾配消失してしまう。一方、標準偏差を小さくしてまとめても分布が偏り、「表現力の制限」が起きる。これでは層をディープにする意味がなくなる
- 「Xavierの初期値」や「Heの初期値」を使うと上手くいくことがあり、ReLU関数を使う場合に特化している
- Batch Normalizationは、入力されたミニバッチを「平均0、分散1に正規化」するBatch Normレイヤを中間層に挟むことで、学習を高速化し、重みの初期値にロバスト(=頑健)になる
- 過学習抑制のために、Weight decayとDropoutが使われる
- 過学習は重みパラメータが大きな値を取ることで起きる。
- Weight decay(荷重減衰)は損失関数に重みのL2ノルムを加えることで、重みが大きくなることを抑える
- しかし、複雑なNNではWeight decayでは対応が難しくなる
- Dropoutはニューロンをランダムに消去し、過学習を抑える
- データセットは「訓練データ」「検証データ」「テストデータ」に分けられる
- 訓練データは、パラメータ(重みやバイアス)の学習に使う
- 検証データはハイパーパラメータ(人の手で設定した値)の性能評価のために使う
- テストデータはモデルの汎化性能を評価するために(理想的には一度だけ)使う
- NNのハイパラ最適化では、規則的な探索であるグリッドサーチより、ランダムサンプリングした方が良い結果になる
7章:畳み込みニューラルネットワーク
- 全結合層(Affineレイヤ)では、1次元配列にして計算をするため、データの形状が無視されてしまい、形状に関する重要な情報が損なわれてしまう
- 一方、畳み込み層(Convolutionレイヤ)では形状を維持したまま計算ができる
- CNNでは畳み込み層の入出力データを特徴マップと呼ぶ
- 畳み込み演算では、入力データとフィルターの積和演算を行う。CNNでは、このフィルターのパラメータがこれまでの「重み」に対応する
- CNNでは、バイアスは1×1のデータで、フィルター適用後の全ての要素に加算される
- 入力データのチャンネル数とフィルターのチャンネル数は対応している
- フィルターの個数と出力データのチャンネル数は対応している
- 入力データを一束にまとめたバッチ処理を行うことで、ネットワークには4次元データが流れている
- プーリング層は縦横方向の空間を小さくする演算である
- Maxプーリングとは、各ウインドウの最大値のみを抽出することである
- プーリング層の特徴として以下の3点が挙げられる
①学習するパラメータがない
②チャンネル数が変化しない
③微小な位置変化に対してロバスト
- im2col関数でフィルター(重み)にとって都合の良いように入力データを展開し、フィルターと積和演算する
8章:ディープラーニング
- さらに認識精度を高めるために、アンサンブル学習、学習係数の減衰、Data Augmentation(データ拡張)などが挙げられる
- Data Augmentationは、移動、回転、画像の一部を切り出す「crop処理」、左右を反転させる「flip処理」、輝度の変化、拡大縮小、などがある
- ネットワークを深くすると、多くの問題で性能が向上する
- 代表的なCNNモデルには以下が挙げられる
①VGG
基本的なCNN構造。3×3の小さなフィルターによる畳み込み層を連続させている。
②GoogLeNet
ネットワークが縦方向だけでなく、横方向にも幅がある「インセプション構造」を取っている。サイズの異なるフィルターとプーリング層を並列し、その結果を結合する。
③ResNet
ディープラーニングでは層を深くし過ぎると、逆に性能が劣るということがあった。そこで畳み込み層をまたぐ「スキップ構造」を導入し、入力のxを2層分スキップさせて出力を f(x) + x とすることで、層を深くしても逆伝播で勾配消失が起きにくいモデルにした。
- 転移学習とは、学習済みの重みパラメータのデータを別のネットワークにコピぺすること
以上。
まとめることでとても自分の勉強になった。
6月25日に自然言語処理版の第二弾が出版されるみたいなので楽しみ。
(レポート課題めっちゃ溜まってんのに4000文字も書いてる場合じゃなかった)