本記事では、深層学習における重要な要素であるニューラルネットワークについて解説します。
ニューラルネットワークの起源:パーセプトロン
まず、ニューラルネットワークの起源と言えるパーセプトロン(単純パーセプトロン)について説明します。パーセプトロンの仕組みはニューラルネットワークの基礎ですので、パーセプトロンについて理解しておくことは重要です。
パーセプトロンは複数の信号を受け取ったときに、一つの信号を出力するアルゴリズムのことです。ここで出力するのは0か1のどちらかの値です。なぜ0と1なのかというと、コンピューターの世界では情報を0と1の二つの値で処理するのが普通だからです。例えば、値が0のときは電流を流さない、値が1ならば電流を流す、といった具合です。このパーセプトロンは人間の脳における神経回路を人工的に、簡単に再現したものとなっています。
まず以下の図1のように、二つの入力を受け取る簡単なパーセプトロンを考えてみます。
ここで、は入力信号、は出力信号、はそれぞれの信号に固有のパラメータであり、重みと呼ばれます。ニューロンでは入力された信号に重みを乗算した総和が計算され、その総和がある閾値を超えたときにのみ1が出力されます。また、閾値を超えなかった場合には0が出力されます。なお、1を出力することを発火と呼びます。
これを数学的な式で表すと、次のようになります。
式(1)
パーセプトロンではこのように、複数の入力信号のそれぞれに対して固有の重みが定義されます。この重みの値によって、どの入力信号の寄与を重視するか、ということを調整するためです。
なお、この式(1)はを不等号の反対側に移項させることによって、以下のようにも表すことができます。
式(2)
パーセプトロンをPythonで体験
なお、このパーセプトロンをPythonで簡単に実装すると以下のようになります。ここで、重みはx1, x2それぞれについて適当に0.2、0.8と設定し、バイアスは-0.7に設定しました。
このように表したときのをバイアスと呼びます。式を見てわかる通り、バイアスは本質的には閾値と同じ役割で、発火のしやすさを調整するパラメータです。
コンピューターの世界では情報を0と1の二値で処理するのが普通なので0と1を入れて試してみましたが、このように入力した値によって0か1のどちらかが出力されることを確認できました。これを水平方向の軸を、垂直方向の軸をに設定してグラフとして可視化すると以下の図3のようになります。
直線より下の領域の値を受け取ると0を出力し、直線より上の領域の値を受け取ると1を出力します。つまり、パーセプトロンにより入力の値を0を出力する領域と1を出力する領域の二つの領域に分けることができます。これは、重みやバイアスなどのパラメータを調整することでデータを分割する直線を自由に作り出せるということを意味します。
これで我々は直線によりデータを分割できるようになったわけですが、しかし直線で分割できない場合はどうすればよいのでしょうか。
多層パーセプトロンの登場
パーセプトロンの式(2)をよく見ると、領域の分割に用いている関数が一次関数なのだから直線で分割することになっているようです。そこで、もっと複雑な曲線を描く関数を使って分割すればよいではないかと思うでしょう。
しかし、もっと良い方法があります。それは、このパーセプトロンをいくつも重ねることです。例えば、以下の図6のように重ねることができます。
これは、一層目のパーセプトロンから受け取った値を二層目のパーセプトロンが受け取り、それによって出力される値をまた三層目のパーセプトロンが受け取ってを出力するという構造になっています。このようにパーセプトロンを重ねていくと、パラメータを調整することで曲線による分割が可能になります。感覚的には、曲線も小さな直線がつながることでできている、という様に理解できると思います。なお、図6には表記されていませんがそれぞれのパーセプトロンにはもちろん重みやバイアスが設定されているということに注意してください。
このようにパーセプトロンをいくつも重ねたものを多層パーセプトロンと言います。実は、ニューラルネットワークもこの多層パーセプトロンと同じような仕組みになっています。
ニューラルネットワークとは
ここまでで多層パーセプトロンについて説明しましたが、ニューラルネットワークは多層パーセプトロンの仕組みを発展させたものです。これまでの文脈から言うと、ニューラルネットワークとは単純な関数を組み合わせることによってより複雑な関数を表現するもののことを言います。ニューラルネットワークは多層パーセプトロンと似ていますが、基本的にニューラルネットワークの方が性能が高いです。
パーセプトロンの説明で直線、曲線という言葉が出てきましたが、プロットすると直線になる関数を一般的に、線形な関数、曲線になる関数を非線形な関数と言います(より正確には、数学的な線形性を満たすものを線形、満たさないものを非線形と言います)。ニューラルネットワークは線形な関数、非線形な関数を多数組み合わせて複雑な関数を表現します。
パーセプトロンの説明での式(2)は次のように、ステップ関数(0を超えたら1を出力し、そうでなければ1を出力する関数、は任意の実数)を用いて表すことができます。
式(3)
この式(3)では、によって計算されたある値を、というように代入しています。
活性化関数
こののような、入力信号の総和をどのように発火させるかを決定する関数を活性化関数と呼びます。
活性化関数には非線形な関数が使われます。また、このような線形な変換と活性化関数の組み合わせはニューロンと呼ばれ、ニューラルネットワークにおける最小単位と言えます。つまり、多層パーセプトロンはパーセプトロンが多数重なってできていたのに対して、ニューラルネットワークはこのニューロンが多数組み合わさってできています。
では、例として3層だけの簡単なニューラルネットワークを作成してみます。
上の図7において、入力層は二つ、中間層は三つ、出力層は二つのニューロンから構成されています。なお、この図7において重みやバイアスは明示されていません。第一層から第二層のn1への推移における重み、バイアスを明示してみると以下の図8のようになります。
ここで示した第一層から第二層のn1への推移を式で表すと以下のように書けます。
式(4)
ここで右上の(1)といった数字は一層目からの推移におけるパラメータであるということを表しています。重みにおける右下の数字は、どのニューロンからどのニューロンへの重みなのかということを表します。二つある数字のうち、左の数字が前層のニューロン番号、右の数字は次層のニューロン番号を表します。例えば、一層目の一番目のニューロンから二層目の三番目のニューロンへの重みならば、のように表せます。同様に、二層目の2番目のニューロンから三層目の1番目のニューロンへの重みならばのように表せます。バイアスの右下の数字はどのニューロンへのバイアスなのかを表します。式(4)の例では、とからの重みをそれぞれとおき、バイアスはとおいています。図8において、バイアスを明示的に表現するためにニューロンのように図示していることに注意してください。
これまでの知識より、一層目から二層目への式を全て書き出すと以下のようになります。
式(5)
これは行列でまとめることにより、以下のようによりシンプルに書くことができます(行列の知識がない場合無理にこのように書く必要はありません)。
式(6)
同様に、二層目から三層目への式は以下のように書くことができます。
式(7)
ここでは最後の出力層について何も特別な処理は行いませんでしたが、一般的には解きたい問題によって最後の出力(ここでは)を他の関数に代入します(例えば分類問題ではソフトマックス関数に代入することによって出力を確率的な数値として得ます)。
なお、これらの式における行列同士の積の演算に注意してください。具体的には、以下の図9のように行列の行数と列数に注意する必要があります。
シグモイド関数
では、図7のニューラルネットワークをPythonで簡単に実装してみようと思いますが、今回、活性化関数にはシグモイド関数(標準シグモイド関数)を用います。シグモイド関数は式で書くと
と表される関数で、ある数値を入力として与えると、その値を0~1の範囲の値に変換して返します。この関数は以下のグラフを見てわかるとおり、非線形な関数です。
使う活性化関数を決めたところで、ニューラルネットワークを実装してみます。ここまでに説明したことしかしておらず、特別難しい処理は行っていません。使うパラメータは適当なものを用いています。
今回作成したニューラルネットワークに[0.3 ,0.6]という適当な入力値を入れたら[0.62602576 ,1.2074438]という出力を得られることが確認できました。この出力0.62602576 ,1.2074438という数値がそれぞれ図7のにあたります。
ここでは3層の簡単なニューラルネットワークを構築しただけでしたが、実際に使われているニューラルネットワークはより層が深く、学習の精度を高めるために様々な工夫がなされています。また、今回はニューラルネットワークについての解説を主旨としているので学習の詳しい仕組みについては解説しませんが、学習は重みやバイアスなどのパラメータを更新し、最適な値に調整することで行います。
まとめ
本記事を通して特に伝えたかったのは、
- パーセプトロンがニューラルネットワークの起源であるということ
- パーセプトロンでは複雑な関数を表現できないが、層を増やした多層パーセプトロンならば複雑な関数を表現できるということ
- ニューラルネットワークは多層パーセプトロンの考え方を発展させ、パーセプトロンの代わりにニューロンを多数つなぎ合わせたものだということ
です。また、ニューロンでは線形な変換に非線形な変換を施しているということと、重みやバイアスは調整すべき重要なパラメータであることなども押さえておいてください。
参考文献
- 斎藤康毅 『ゼロから作るDeepLearning pythonで学ぶディープラーニングの理論と実装』 オライリー・ジャパン. 2016
- Eli stevens, Luca Antiga, Thomas Viehmann 『Pytorch実践入門 ディープラーニングの基礎から実装へ』後藤勇輝, 小川雄太郎, 櫻井亮佑, 大串和正 訳. 株式会社マイナビ. 2021