はじめに
MATLAB,Python,Scilab,Julia比較するシリーズの第4章。
第3章では画像処理、座標変換の話がメインだった。
第4章は分類問題関連の話がメインとなる。
基本的には以下の流れとなる。
- 形式ニューロン
- 決定境界線の安定化
- 単純パーセプトロン(線形分類)
- 多層パーセプトロン(非線形分類)
細かいところとしては、誤差関数、連鎖律、勾配降下法、誤差逆伝播法などの話も出てくる。
ちなみに、問答方式じゃない方も記事もある。
問答方式に合わせて内容を強化していく予定。
書籍とか
Pythonで動かして学ぶ!あたらしい線形代数の教科書
https://amzn.to/3OE5bVp
ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装
https://amzn.to/3OBiaax
ゼロからはじめるPID制御
https://amzn.to/3SvzuyR
恋する統計学[回帰分析入門(多変量解析1)] 恋する統計学[記述統計入門]
https://amzn.to/3STAe2i
OpenCVによる画像処理入門
https://amzn.to/498ZUgK
Pythonによる制御工学入門
https://amzn.to/3uskuK5
理工系のための数学入門 ―微分方程式・ラプラス変換・フーリエ解析
https://amzn.to/3UAunQK
その他の章
分類問題とは?
- 本シリーズは分類問題を扱っていく予定。
- 機械学習のカテゴリわけを簡単に説明。
- 分類とクラスタリングは雰囲気似てるけど、違うという扱い。
- 分類問題について簡単に説明。
- 分類手法について列挙。
- この中のパーセプトロンをベースに話を進める。
形式ニューロン
- 形式ニューロンを把握するためのロードマップを提示。
- ヘヴィサイド関数を説明。
- とりあえず、もやっとしたものをYes/Noに変換できるとと思っておけばOK。
- 形式ニューロンの概念図を説明。
- よく見るニューロンの概念図と類似。
- 形式ニューロンの数式を説明。
- 重みと入力の内積の結果をヘヴィサイド関数に渡して0or1にしている。
- 分類問題のHelloWorld総統はANDゲート。
- ANDゲートを形式ニューロンで実現するための構成を説明。
- 2入力1出力の構成になる。
- 代表的な誤差関数について説明。
- MSE:分散と一緒であり、統計的に意味のある数値
- SSE:シンプルであり、利用しやすい
- RMSE:標準偏差的位置づけであり、人間から見て意味のある数値になりやすい。
- 決定境界直線について説明。
- 分類する上で仕分けを行う境界線。
- ANDゲートの場合の想定される決定境界直線を図解。
- 境界線を境にtreu,falseに分かれる。
- この性質がヘヴィサイド関数と相性が良い。
- 境界線を境にtreu,falseに分かれる。
- 決定境界直線の必要性について。
- 推論するだけだったら不要だが、学習済みモデルの性能を評価する際は必要。
- 決定境界直線の特定方法を説明。
- ヘヴィサイド関数の出力が0.5であることを仮定して数式を解けばOK。
- 総当たり法について解説・・・と思いきや、名前のまんま。
- プログラム化の前提だけ決めた。
- 実際のプログラムのフローを記載。
MATLAB
- 形式ニューロンをMATLABで実現。
- ANDの真理値表と同じ結果が得らえれた。
- しかし、決定境界線はギリギリな感じ。
Python
- 形式ニューロンをPython(NumPy)で実現。
- ANDの真理値表と同じ結果が得らえれた。
- そして、決定境界線はギリギリな感じはMATLABのときと一緒。
Scilab
- 形式ニューロンをScilabで実現。
- ANDの真理値表と同じ結果が得らえれた。
- そして、決定境界線はギリギリな感じはMATLABのときと一緒。
Julia
- 形式ニューロンをJuliaで実現。
- ANDの真理値表と同じ結果が得らえれた。
- コードレベルでMATLABと近似。
決定境界線の安定化
- 形式ニューロンのプログラムでは決定境界直線がギリギリのラインに来ていた。
- 上記を解消するため、どうあるべきか。について説明。
- この後に、なぜこうなったか、どうすればかいしょうできるかの話が続く予定。
- 決定境界直線がギリギリなる理由。
- ヘヴィサイド関数の性質に原因がある。
- ヘヴィサイド関数の性質は入力0を境に出力0,1が切り替わるのみで勾配が無い。
- これにより程度の表現ができず、境界直線も適正位置が探せない。
- 決定境界直線をいい感じのところに持っていくにはヘヴィサイド関数を差し替える必要がある。
- ヘヴィサイド関数の原点近辺に傾斜を付けたカスタムヘヴィサイド関数(造語)が良さげ。
MATLAB
- 形式ニューロンの活性化関数をカスタムヘヴィサイド(造語)関数にしたものをMATLABで作成。
- 狙い通りの位置に決定境界直線が移動。
- コードはヘヴィサイド関数をカスタムヘヴィサイド関数に変えただけ。
Python
- 形式ニューロンの活性化関数をカスタムヘヴィサイド(造語)関数にしたものをPython(NumPy)で作成。
- おおよそMATLABと同じ結果に。
- 毎度おなじみの表示上の誤差は出る。
Scilab
- 形式ニューロンの活性化関数をカスタムヘヴィサイド(造語)関数にしたものをScilabで作成。
- おおよそMATLABと同じコード。
- 毎度おなじみのグラフ表示部分に差が出る。
Julia
- 形式ニューロンの活性化関数をカスタムヘヴィサイド(造語)関数にしたものをJuliaで作成。
- 例に漏れずMATLABコードのコピペがベース。
シグモイドによる決定境界安定化
- 決定境界直線の一般的な安定化方法がある。
- シグモイド関数を使用する方法。
- ヘヴィサイド関数のように0,1を表現することを目的とした関数だが、シグモイド関数は全域で勾配がある。
- シグモイド関数の定義について説明。
- 特に理屈はなく、そういうものが存在するって程度。
- カスタムヘヴィサイドとシグモイドの比較。
- 総当たり法では効能の差は出ないが、誤差逆伝播法を使い始めるとシグモイドじゃないと都合が悪い。
MATLAB
- 活性化関数をシグモイド関数にした形式ニューロンをMATLABで実現。
- 結果はカスタムヘヴィサイドの時と一緒。
Python
- 活性化関数をシグモイド関数にした形式ニューロンをPython(NumPy)で実現。
- 結果はカスタムヘヴィサイドの時と一緒。
Scilab
- 活性化関数をシグモイド関数にした形式ニューロンをScilabで実現。
- 結果はカスタムヘヴィサイドの時と一緒。
Julia
- 活性化関数をシグモイド関数にした形式ニューロンをJuliaで実現。
- 結果はカスタムヘヴィサイドの時と一緒。
連鎖律の前準備
- 総当たり法では非効率なので最適化アルゴリズムを使用する。
- 最適化アルゴリズムを使用するには連鎖律が必要。
- 連鎖律を利用するには損失、活性化関数、各層の入力の導関数を求める必要がある。
- 連鎖律を把握するための知識を列挙。
- 恐らく数式ラッシュになる。
- まずは逆数の微分公式。
- 途中、式を分解してそれぞれの導関数を求めてから代入で導出できる。
- 積の微分公式を導出。
- 少しトリッキーなことをする。
- f(x)の極限と、g(x)の極限に分けられるような細工。
- 商の微分方式の話。
- 逆数の微分公式と積の微分公式の合わせ技で導出。
- 商の微分方式はシグモイド関数の導関数導出で生きてくる。
- いままでの公式達を再掲。
- 商の微分公式を使ってシグモイド関数の導関数を求めた。
- 本当に導関数になっているか、オイラー法で求めたシグモイド関数の微分のプロットと比較してみる。
- シグモイド関数、シグモイド関数の導関数の再掲と、シグモイド関数のオイラー法による微分の数式を確認。
- 上記を実現するプログラムを作成して、似た波形になればOKと見なす。
- シグモイド関数の導関数は有名なので間違っていることは無いはず。
MATLAB
- シグモイド関数、シグモイド関数の導関数、シグモイド関数のオイラー法での微分をMATLABで算出。
- グラフで比較し、導出した導関数は正しいと言える結果となった。
Python
- シグモイド関数、シグモイド関数の導関数、シグモイド関数のオイラー法での微分をPythonで算出。
- グラフで比較し、導出した導関数は正しいと言える結果となった。
Scilab
- シグモイド関数、シグモイド関数の導関数、シグモイド関数のオイラー法での微分をScilabで算出。
- グラフで比較し、導出した導関数は正しいと言える結果となった。
Julia
- シグモイド関数、シグモイド関数の導関数、シグモイド関数のオイラー法での微分をJuliaで算出。
- グラフで比較し、導出した導関数は正しいと言える結果となった。
多変量関数の連鎖律
- 多変数関数の連鎖律に突入したが、これを理解するのに必要な知識があるため、それらを列挙。
- 合成関数について説明。
- 単純パーセプトロンも入力層の内積、活性化関数、誤差関数の組み合わせが合成関数と言える。
- 合計関数の微分(連鎖律)について説明。
- まずは1入力1出力な合成関数。
- 合計関数の微分をするための公式はあるが、一応証明もしてみる予定。
- 合成関数の微分(連鎖律)の証明を実施。
- 途中、いろいろトリッキーなことをする。
- 結果としては、中間変数を微分、中間変数での微分の組み合わせで表現しなおせるというもの。
- 多変数関数の連鎖律について説明。
- 数が増えるだけで普通の連鎖律と変わらない。
- 図示&数式があると分かり易い。
- ニューラルネットワークを想定した場合の多変量関数の連鎖律について説明。
- 入力から見た際の関数の伝達ルートが複数になる。
- 変化させたいのは入力ではなく重み。
- ニューラルネットワークの学習を想定した場合、暗黙的に追加される関数として入力群がある。
- イメージ的に1層増える感じになる。
- これはバッチ学習、ミニバッチ学習時の起きる現象。
- と言っても、微分すると重みが消えるので足し算に化ける。
勾配降下法
- 勾配降下法に概念レベルの説明。
- 連鎖律含めた一連の流れを誤差逆伝播法と言う。
- ただし、単純パーセプトロンの段階では逆伝播という言葉にしておく。
- まずは勾配降下法のみの実験をやってみる。
- 勾配降下法をプログラム的に確認する方法としてニューラルネットワークではなく、任意の関数に試す方法がある。
- 三角関数と二次関数を合成したもので試す。
- プログラムのフローを記載。
- 勾配降下法プログラムのフローで分かりにくいところを説明。
- 入力初期値は学習のスタート地点。
- ハイパーパラメータは学習アルゴリズムの設定値。
- グラフへのプロットは履歴付きで。
- プログラムの振る舞いをアニメーションgifで確認。
MATLAB
- 勾配降下法の実験をMATLABで実施。
- 予想通り局所最適解に陥った。
- 局所最適解の回避方法としては学習率を状況に応じて変更する様々は最適化アルゴリズムがある。
- モーメンタム、AdaGrad、Adamなどなど。
Python
- 勾配降下法の実験をPythonで実施。
- 予想通り局所最適解に陥った。
- 局所最適解の回避方法としては学習率を状況に応じて変更する様々は最適化アルゴリズムがある。
- モーメンタム、AdaGrad、Adamなどなど。
Scilab
- 勾配降下法の実験をScilabで実施。
- 予想通り局所最適解に陥った。
- 局所最適解の回避方法としては学習率を状況に応じて変更する様々は最適化アルゴリズムがある。
- モーメンタム、AdaGrad、Adamなどなど。
Julia
- 勾配降下法の実験をJuliaで実施。
- 予想通り局所最適解に陥った。
- 局所最適解の回避方法としては学習率を状況に応じて変更する様々は最適化アルゴリズムがある。
- モーメンタム、AdaGrad、Adamなどなど。
逆伝播
- 誤差逆伝播法とか単純パーセプトロンに関連する用語を確認。
- 様々な都合で、単純パーセプトロンに対する誤差逆伝播法を「逆伝播」と呼称することに。
- 逆伝播を行う単純パーセプトロンの構成を確認。
- 誤差関数は二乗和誤差関数を1/2にしたもの。
- 1/2により微分後の数式がシンプルになる。
- 誤差関数は二乗和誤差関数を1/2にしたもの。
- 一連の合成関数について書き出し。
- 合成関数を構成する各数式を書き出し。
- 誤差関数、活性化関数、入力と重みの内積。
- 合成関数の微分こと連鎖律について説明。
- 学習データを加味した場合の多変量関数の連鎖律について簡単に説明。
- 詳細は後日。
- 連鎖律に於ける誤差関数の位置づけを確認。
- ブロック図的には一番後ろだが、連鎖律としては先頭。
- 誤差関数の確認。
- 誤差関数の偏導関数の確認。
- 活性化関数の微分について説明。
- 活性関数のブロック図と連鎖律上の位置づけを確認。
- シグモイド関数の導関数を復習。
- シグモイド関数の偏導関数を確認。
- 入力層のブロック図と連鎖律上の位置づけを確認。
- 入力層の偏導関数を確認。
- もとの式がシンプルなので偏導関数もシンプル。
- バイアスのブロック図と連鎖律上の位置づけを確認。
- バイアスの偏導関数を確認。
- もとの式がシンプルな上、1次で係数もないので1になる。
- 全体の位置づけ確認。
- 各偏導関数を再掲。
- 各偏導関数を連鎖律に則して結合。
- 入力、出力(ラベル)が複数であるが故に連鎖律のルートが複数になる。
- 上記の図示と数式を説明。
- 入力、出力が複数であるが故の連鎖律の事情のもう一つの考え方。
- 誤差関数は二乗和誤差関数であり、本来であればΣが含まれる。
- よって、連鎖律にもΣが含まれる形を取ると前回と同一の数式が得られる。
- 逆伝播の確認用プログラムのフローを記載。
- 逆伝播の挙動を確認するため、重みの開始位置とバイアスは固定。
- ベクトル、行列演算をプログラム都合に合わせて表現しなおし。
MATLAB
- 逆伝播を行った際の重みの動き方を確認するプログラムをMATLABで作成。
- おおよそ狙ったところに収束。
Python
- 逆伝播を行った際の重みの動き方を確認するプログラムをPythonで作成。
- おおよそ狙ったところに収束。
Scilab
- 逆伝播を行った際の重みの動き方を確認するプログラムをScilabで作成。
- おおよそ狙ったところに収束。
Julia
- 逆伝播を行った際の重みの動き方を確認するプログラムをJuiaで作成。
- おおよそ狙ったところに収束。
単純パーセプトロンで分類
- 単純パーセプトロンの構造について復習。
- 今回扱うのは活性化関数をシグモイド関数に差し替えたもの。
- 逆伝播の復習。
- 重みとバイアスの逆伝播は途中まで一緒。
- よって表現の最適化が可能。
- 重みとバイアスの連鎖律の最適化。
- 共通部分があるので、そこを切り出し。
- プログラムの場合は、こういう共通部分を変数に格納するなどの最適化が可能。
- 単純パーセプトロンで分類のプログラムのフローを確認。
- 逆伝播の実験のときと流れは一緒。
- 学習が進むと決定境界線がどのように動くか確認。
MATLAB
- 単純パーセプトロンの分類をMATLABで実施。
- 想定通り分類可能。
- おおよそ200エポックあれば分類可能。
Python
- 単純パーセプトロンの分類をPythonで実施。
- 想定通り分類可能。
- おおよそ200エポックあれば分類可能。
Scilab
- 単純パーセプトロンの分類をScilabで実施。
- 想定通り分類可能。
- おおよそ200エポックあれば分類可能。
Julia
- 単純パーセプトロンの分類をJuliaで実施。
- 想定通り分類可能。
- おおよそ200エポックあれば分類可能。
非線形分類
- 単純パーセプトロンでは分類できないものがある。
- XORなどの非線形分類を求められるものなどが代表的。
- 決定境界直線を求めるというより決定領域を特定するというイメージになる。
コメント