【フレームワークを使用せず】ゼロから作る物体検出AIモデル
【No.1】ニューラルネットワークの理解(その1)
1. 本記事について
本シリーズの実質第1回目として、ニューラルネットワークがどういったものかについて解説していきます。その1〜その4の4回を予定しています。
理解が終わったら、実際にニューラルネットワークをPythonで実装していくという予定です。
ニューラルネットワークは、物体検出に限らず、ディープラーニングにおいて土台となる概念となりますので、まずはここの理解を進めていきます。
なお、本シリーズを進めていくにあたり、参考にさせていただく書籍があります。オライリー・ジャパンから出版されている「ゼロから作るDeep Learning ーPythonで学ぶディープラーニングの理論と実装」です。
非常に有名な書籍ですので、皆さんご存知かもしれませんが、もしご覧になったことがないという方は、めちゃくちゃおすすめです。
2016年初版で、だいぶ前の書籍ではありますが、深層学習の根本から解説されており、今読み返しても新たな発見があったりしますので、是非。
脱線してしまいましたが、上記書籍を参考にさせていただいております。
2. ニューラルネットワークについて
ニューラルネットワークとは、人間の脳内における処理を模して構築した学習モデルです。
図1を見ると、多数の丸と矢印が存在します。丸をニューロン(神経細胞)やノードといったりします。
図1の一番左側の層(\(x_1\)〜\(x_5\))を入力層といいます。物体検出の場合、入力は画像データですので、入力層の1つ1つのノードには、各画素値が入力されます。
例えば、縦224ピクセル、横224ピクセルのカラー画像の場合、224*224*3=150528個のノードが存在することになります。
入力層は、後述する計算をした後、一つ右側の層へ数値を渡します。
図1の真ん中の層(\(z_1\)〜\(z_3\))は中間層、若しくは隠れ層と呼ばれます。入力層から数値(物体検出の場合画素値)を受け取り、後述する計算をした後、次の中間層、若しくは出力層へ情報を渡します。
図1の場合、中間層は1層のみですが、基本的には何層も中間層が存在することがほとんどです。中間層が多ければ、その分より複雑な推論を行うことができるイメージです。
図1の一番右側の層(\(y_1\)、\(y_2\))を出力層といいます。中間層から数値を受け取り、後述する計算をした後、最終的に数値を出力します。
例えば、YOLOv1の場合、1470個の出力ノードがあります(クラス=20)。
別の例として、画像認識で「犬」か「猫」を判別する場合、出力層は2つのノードになります。
この様に、入力層〜出力層まで、そのモデルによって、ノードの数や中間層の数は実に様々です。
3. ニューラルネットワークの計算
先ほど「後述する」と申し上げた、具体的な計算について解説します。
図2は、図1を簡略化したものになります。Cのノードを中心に見てみます。
CはAのノードから\(x_1\)という信号を受け取るのですが、その際\(x_1\)と\(w_1\)を乗算して受け取ります。\(w_1\)を重みといいます。
重みはそれぞれの信号に固有の数値です。
この時、ノードCが受け取る数値は以下となります。
式1
ノードは、それぞれに閾値を持っており、渡された入力値が閾値を超えた場合、1を出力します。超えなければ0を出力します。
この時、\(y\)をノードCが出力する信号、\(θ\)をノードCが持っている閾値とします。\(y\)の式にすると以下になります。
式2
単純にいうと、あるノードにおいて、入力信号が閾値を超えた場合次のノードへ信号を出力するという構造です。この構造は、脳の神経回路を参考に構成されています。
今後の処理の為に、式2を変形して以下にします。
尚、以下の\(b\)を「バイアス」と呼びます。
式3
次に、入力のノードを1つ追加したモデルを例にみてみます。
図3は、入力がAとBの2つのノードから受け取りますが、考え方は先ほどと同様です。
重みを乗算したそれぞれの入力値について総和をとります。
この時、ノードCが受け取る数値は以下となります。
式4
この時\(y\)の式は以下となります。
式5
変形して以下となります。
式6
4. 活性化関数について
式6に関して、以下の様に変形をします。
式7
式7は、\(y=f(x)\)の形にしたものです。\(f(x)\)は、先程の「0を超えたら1になり、そうでなければ0になる」関数ということになります。
\(x\)には、ここでは \(x_1w_1 + x_2w_2 + b\) が代入されます。
この場合の\(f(x)\)関数には実は名前があり、ステップ関数という関数です。
式8
グラフにすると、以下の様になります。
今回のステップ関数のような、入力の総和をどの様に出力に繋げるか、その部分を司る関数を活性化関数といいます。
活性化関数にはいくつか種類があるのですが、本シリーズではYOLOv1に用いられているLeaky ReLUという活性化関数を解説します。
Leaky ReLUは、ReLUという活性化関数の派生系です。まずReLUがどういうものか解説します。
ReLU
ReLUは以下の式で表せます。
式9
入力値が0以下の時、出力値が常に0なります。入力値が0超の時、出力値が入力値と同じ値になります。
言葉ではわかりづらいと思いますので、グラフで確認してみます。
Leaky ReLU
Leaky ReLUは以下の式で表せます。
式10
ReLUは入力値が0以下の時、出力値が常に0でしたが、Leaky ReLUは0より下の値をとります。
こちらもグラフで確認した方がわかりやすいと思いますので、見てみます。
Leakyの意味は「漏れている」だそうで、ReLUと比較して0以下の時に文字通り負の方向に「漏れている」形になります。
YOLOv1では、活性化関数にLeaky ReLUを採用しています。ですので、本シリーズでも、活性化関数は基本的にLeaky ReLUを使用します。
なお、式9の\(α\)は定数で、値は0.01をとることが多い様ですが、今回は\(α=0.1\)でいこうと思います。
5. 各層の入力処理
先述の内容をふまえ、各層毎の入力処理をみていこうと思います。
入力層→中間層
図4で示した箇所について、式に表すと以下の様になります。
式11
\(z_2\)、\(z_3\)についても同様に式に表します。
式12
式13
中間層→出力層
中間層から出力層にかけての計算となります。
内容は入力層→出力層と同様ですが、活性化関数をする必要がないので(次へ伝達しない為)、当該計算は行いません。
式14
式15
以上で全ての式が出揃いましたので、最後に、具体的に入力から出力までの計算を行ってみます。
入力値と重みを以下の様にします(各値は適当です)。
式16
式16を元に、ニューラルネットワークの式11〜式15を計算します。
式17
最終的に、最終的な出力値(\(y1\)、\(y2\))は以下の様になりました。
ニューラルネットワークにおける、入力から出力への基本的な処理は以上になります。
物体検出のモデルにおいて、ニューラルネットワークでの処理を経た出力値\(y\)は、この後ロス関数へ渡されていくことになります。
6. まとめ
今回はニューラルネットワークについての概要と実際の計算について解説しました。
また、活性化関数について解説しました。
次回も是非みてみてください!
7. 参考文献
斎藤康毅 著 「ゼロから作るDeep Learning ーPythonで学ぶディープラーニングの理論と実装」
Link
Search