こんにちは,学生エンジニアの迫佑樹(@yuki_99_s)です.
先日の大学の講義でニューラルネットワークを扱ったのですが,それがめちゃめちゃわかりやすかったんです.
そこで,ニューラルネットワークの基礎の基礎を,高校生でもわかる簡単な数学だけを使って解説してみようと思います.
理解のしやすさを念頭に置いたので,ニューラルネットワーク・機械学習を専門に学ばれている方からすれば違和感を感じる表現もあるかもしれませんがご了承ください.
ニューラルネットワークとは
よく聞く,ニューラルネットワークなのですが,一体何なんでしょうか?
これは,とてもざっくり説明すると,人間の脳の仕組みをコンピュータに適用したものです.
人間の脳には,ニューロンと呼ばれる神経細胞があります.
このニューロンは,他のニューロンから信号を受け取ったり,信号を受け渡したりすることによって,情報を処理しています.
つまり,この仕組みをコンピュータで再現してあげると,人間の脳と同じ能力をコンピュータがもてるのではないかと考えたわけですね.
それがニューラルネットワークの始まりです.
ニューロンモデル
それでは,ニューラルネットワークを作る前に,まずはニューロン単体で考えてあげる必要があります.
先程述べたように,ニューロンは信号を受取り,その情報を処理して受け渡します.
つまり,以下のようにモデル化出来ます.
\(x\)という信号を受取り,関数\(f\)により処理して,\(y\)という信号を受け渡している状況です.
ここで,重みとバイアスを導入します.
受け取った信号をそのまま処理するのではなく,信号を重み付けのために重みの\(w\)をかけ,さらに定数項として,バイアス\(b\)と呼ばれるものを足してあげます.
すると,ニューロンモデルは以下のようになりますね.
入力信号\(x\)に,重み\(w\)がかけられ,定数項としてバイアス\(b\)が足されるので,入力信号は\(wx+b\)となります.
それが,関数fによって処理されるので,出力は,\(y=f(wx+b)\)となります.
処理用の関数の正体
それでは,\(y=f(wx+b)\)における関数fとはどのような関数なのでしょうか.
これは\(f(x) = \frac{1}{1+e^{-x}}\)という形の関数で,シグモイド関数と呼ばれます.
\(f(x) = \frac{1}{1+e^{-x}}\)をグラフ化してみると以下のようになります.
なるほど,\(f(x) = \frac{1}{1+e^{-x}}\)は\(x\)が\(-\infty\)に行けば行くほど0に近づき,\(x\)が\(\infty\)に行くほど,1に近づく,そんな関数ですね.
ここで,\(y=f(wx+b)\)は,\(f(x) = \frac{1}{1+e^{-x}}\)より,\(f(wx+b) = \frac{1}{1+e^{-(wx+b)}}\)となるわけです.
整理してみましょう.
複数入力の場合
今までは,入力が一つの場合を見てきました.
そこで,複数入力の場合をみてみましょう.
複数の場合も特に難しいわけではありません.
それぞれの入力\(x_1,x_2,x_3\)に,重みがそれぞれ\(w_1,w_2,w_3\)かかり,バイアス\(b\)を足してあげたのを関数\(f\)で処理すればいいので,出力は,\(f(w_1x_1+w_2x_2+w_3x_3+b)\)となるだけなんですよ.
ここで\(w_1x_1+w_2x_2+w_3x_3\)というのは,\({\bf w} = \begin{bmatrix}w_1 \\ w_2 \\ w_3 \end{bmatrix}\)と,\({\bf x} = \begin{bmatrix}x_1 \\ x_2 \\ x_3 \end{bmatrix}\)の内積で書くことができますね.
つまり,出力は\(f( {\bf w}^T {\bf x}+b)\)と書くことができます.
少し見た目がシンプルになりましたね.
このニューロンを,複数つなぐと,どんどんいろんな出力を作ることが出来ます.
この,入力と出力の間に隠れたニューロンのことを,隠れニューロンと呼びます.また,その隠れニューロンが層になってるところを,中間層と呼びます.
また,いきなりどこかから入力信号が現れるのもおかしな話なので,入力信号を出すニューロンをはじめにおいてあげましょう.
すると,以下のような感じになります.
なんとなく,人間の脳っぽいことをやっているなっていうイメージが出来たのではないでしょうか.
ニューラルネットワークの近似定理
ニューラルネットワークには,大事な性質があります.
それが,隠れ層が1層のニューラルネットワークは,任意の関数を任意の精度で近似することができるということ
どういうことかを実例を出しながら説明していきますね.
ニューラルネットワークで,信号処理を行う時,\(f(x) = \frac{1}{1+e^{-x}}\)より,\(f(wx+b) = \frac{1}{1+e^{-(wx+b)}}\)という関数を使うのは先程話したとおりです.
この,重み\(w\)の値を変えてみましょう.
重み\(w\)を増加させると,\(x=0\)付近での曲線の勾配がきつくなっているのがわかります.
重み\(w\)を極めて大きくすると,単位ステップ関数(x<0でf(x)=0,x>0でf(x)=1となるような関数)に近づきます.
それでは,次に,バイアスの値を変えてみます.
なるほど,バイアスを変えると段差の位置が変わるわけですね.
では,段差の位置を指定したければどうすればいいでしょうか.
実は,\(-\frac{b}{w}\)の値が,そのまま段差の位置になっています.
この2つの性質を使うと,任意のパルス波を生成することが出来ます.
少しやってみましょう.
まずは,先程の,\(w=1000, b=-750\)のシグモイド関数を-1倍してみます.
そして,\(w=1000, b=-500\)のシグモイド関数と足し合わせてみましょう.
パルス波の幅や高さは,\(w,b\)の値を変えることで自由にいじれます.
ここまでを,ニューラルネットワークのモデルで表してみましょう.
まず,\(w=1000, b=-500\)を与えた時のシグモイド関数と\(w=1000, b=-750\)を与えた時のシグモイド関数は,以下のニューロンモデルになります.
「これらを足し合わせると,パルスを生成できる」というのは,以下のようにモデリングできます.
パルスさえ生成できれば,もう任意の関数を近似するのは簡単です.
中間層の隠れニューロンの数を増やせば,どんどん近似が正確になっていきます.
これで,連続な関数ならば,どんな関数でも近似しちゃうことが出来るわけです.
なんとなく,ニューラルネットワークの仕組みがわかっていただけたら幸いです.