site_review: 2021-12-10 04:59:20.216843 【技術本】ゼロから作るDeepLearning❸

【技術本】ゼロから作るDeepLearning❸

https://amzn.to/3GuSz2i


【技術本】ゼロから作るDeepLearning❸


x postへポスト
独自の機械学習用フレームワークをゼロから実装し、最終的にはCNN, RNN(LSTM含む)を構築して機械学習できるまでが記述されている。Numpyなどの特殊なデータ型を使う以外は、機械学習の実装部は完全にフルスクラッチで中身を見ることができる。更に小さい機能開発、機能改良を積み上げていくインクリメンタル開発による、python実装によるフレームワーク開発を追体験できる。実開発におけるpython仕様を活用した色々なハックによる知見を得られるのも見所。
今回は、各種機能の位置付けなどの知識はある程度前提とされるが、それに関しては前シリーズ1〜2までを読んでおけば問題ない。
記載されている数式も高校数学レベルであり、それ以上は説明もなされている。
技術書は英文を和訳したものが多いが、本書は日本人による純国語による文体で書かれているのも相まって、非常にわかりやすく記載されている。
機械学習の処理の中身を理解したい人に価値が出てくる著作だと感じた。

----
以下、内容メモ

●第1ステージ:微分を自動で求める
機械学習における、逆伝播でニューロンが微分を求める際、順伝播時の入力xの値、微分した値、順伝播時の呼び出し元ニューロンへの参照が必要になる。それらをクラス変数や順伝播関数、逆伝播関数を実装した独自の変数格納用クラス(Variable)を定義設計する。
数値微分:テイラー展開によって、前進差分近似「(f(x+h)-f(x))/h」より中心差分近似「(f(x+h)-(x-h))/2h」の方が、真の微分値に近い。数値微分は桁落ちによる誤差と、計算量が多いという問題がある。その双方の問題を解決するのがバックプロパゲーション(誤差逆伝播法)
逆伝播による連鎖の実装は、再帰でなくループの方がメモリ効率をよく実装できる。再帰の場合は、全ての工程中で変数の参照が保持され続けるためメモリ効率が悪い。

unittestパッケージによる、テストコードの作成方法、自動実行方法
Numpyのallclose関数で、近似によるassert結果比較を実装できる。

p65,p276:機械学習の多くの学習では出力は一つになる。その一つの出力の微分を求めたい場合は逆伝播に
よる処理の方が効率が良い。
順伝播では、n*nの行列を伝播する。逆伝播ではn個のベクトルを伝播(「n個のベクトル」と「n*nのヤコビ行列の対角行列(対角成分以外が0)」との積=「n個のベクトル」になる)する。これが、逆伝播の計算効率の良さ。

●第2ステージ:自然なコードで表現する
Variableクラスの関数の引数を可変長に対応:f(self, *input) アスタリスクで任意数の引数に対応
Variableクラスを再使用可能変数にする:微分結果の引き継ぎ(同一計算でのインスタンス再使用)や、クリアする機能(別計算でのインスタンス再使用)に対応
Variableを使用した複雑な計算グラフに対応するため、計算順序の優先度(世代)の設計
メモリ管理の効率化:a = b = c = Noneなど不要になった変数にNoneを与えて参照をゼロにする
Variableクラスに便利なクラス変数(変数名称の設定)を追加し、また変数はNumPy 配列を扱うので、それと同様の関数(ndim, size, dtype..など)をクラス関数として追加してデータを確認できるようにする。
演算子のオーバーロード:+,-,*,/などの演算子を独自実装でオーバロードして、Variableクラスの計算で利用できるようにする。
 計算時の左項対応:(__add__(+), __mul__(*), __sub__(-), __truediv__(/), __neg__(-), __pow__(**))右項対応はrをつける。(__radd__)など
演算子オーバライド対応により、複雑な計算グラフが必要な関数(matyas, Goldstein-Price)の自動微分を求められるようになる。
フレームワークをパッケージとしてまとめる:__init__.pyでのクラスインポートや、演算子オーバライド定義などの初期設定

●第3ステージ:高階微分を実現する
微分の微分を繰り返す高階微分を実現できる実装にする。
Graphvizによる計算グラフの可視化
三角関数のsin関数をテイラー展開を使って実装
勾配を求める:
 勾配下降法の実装:ローゼンブロック(放物線状の谷間を持ち、それが長くバナナのように伸びた形状)のような形状から勾配を見つけるのは苦手
 ニュートン法:2次近似でも、勾配下降法よりはるかに少ない反復で最適解にたどり着く
高階微分を求められるように、微分格納変数の型を第1ステージで設計したVariableクラスに変更する。
それに伴い、Mul,Neg,Sub,Div,Powクラスの逆伝播(backward)の実装の修正
三角関数のcos,tanh関数の追加と実装
高階微分の計算グラフの可視化

●第4ステージ:ニューラルネットワークを作る
以下の関数の追加:順伝播と逆伝播の実装
 reshape関数の実装:テンソル(多次元配列)の形状を変える
 transpose関数:行列の転置
 sum関数:テンソルの和を求める
 broadast_to関数:ブロードキャストを行う、要素のコピー
 matmul関数:行列の積
ここまでの実装で、線形問題を学習して解くことができるようになる。
 線形回帰の実装と学習結果:線形に分布した二次グラフのノイズからy=Wx+bという実線を見つける。(損失関数は平均2乗誤差を使用)

非線形な問題を解く:
 シグモイド関数の実装(非線形問題対応のための活性化関数)
 非線形曲線を描く二次グラフの問題を解く

パラメータや、ニューラルネットワークの層をまとめるラッパークラスの実装
勾配下降法を行うクラスの実装

多値分類問題を解く:
 以下の関数の実装
  ソフトマックス関数:多値分類をする
  損失関数:交差エントロピー誤差で実装
 スパイラルデータセットで、渦巻きのパターン分類の問題を解く

現状では学習データを全てメモリ展開しなくてはならないので、ミニバッチで実行できる実装へ改良
MNISTによる文字認識の学習を行う

●第5ステージ:DeZeroで挑む
GPU対応
 numpyからcupyを利用に切り替えられるように実装を修正
モデルの保存と読み込み
 学習途中、学習済みのモデルを保存したり読み込んだりできるようにする。
 np.save, np.loadを活用。

ドロップアウト(ランダムでニューロンの接続を切って学習する)機能追加

CNN(畳み込みニューラルネットワーク)の実装
 畳み込み:特定n*n(n=畳み込む範囲)の行列とフィルタの積で行列の1成分のデータにまとめて畳み込む
 パディング:畳み込みは出力サイズが小さくなるため、ディープなネットワークではサイズが小さくなりすぎて畳み込み処理ができなくなるので、データの周囲に固定データを付加して対応する。
 ストライド:フィルタを適用する位置の間隔

プーリング層
 MAXプーリング:n*n(n=プーリングを適応する範囲)の行列データから最大の成分を行列の1成分にする。他に平均値を出すAveragプーリングもある。微小な入力なズレに対して、プーリングは同じような結果を返すことができる。>入力のズレに対してロバスト(頑健)

以上を踏まえ以下の関数を実装
 conv2d関数:畳み込み層
 pooling関数:プーリング層

ここまででCNNモデルを定義して実装できる。
 VGG16(2014ILSVRCで準優勝したモデル)を実装
 学習済みVGG16モデルyを読み込んでみる。
 PILデータによる画像分類の実践

RNN(リカレント・ニューラルネットワークモデル)データモデルの実装
RNNの改良LSTMレイヤの実装

以上。


x postへポスト


  Copyright 2021-2025 REVIEW_SITE ALL RIGHTS RESERVED.
  このサイトについて/お問い合わせ
  プライバシーポリシー
  総合トップページへ