どうも、カタミチです。
さて、パーセプトロンの続きですね。前回は、AND回路、OR回路、NAND回路を見ましたが、今回は少し毛色が違うXOR回路について見てみましょう。
XOR回路
XOR回路は、以下の特徴を持っています。
・x1、x2がともに0のとき、yは0
・x1、x2のどちらかが0でどちらかが1のとき、yは1
・x1、x2がともに1のとき、yは0
これを実現するための、パーセプトロンのw1、w2、θの値を探してみると…
$$ y= \begin{cases} 0\;(w_1x_1+w_2x_2\leqq\theta) \\ 1\;(w_1x_1+w_2x_2>\theta) \end{cases} $$
ない!
ありません。重みw1、w2の値や閾値θの値をどう調整しても、XOR回路の特徴を満たすことはできません。(ちなみに、θを左辺に移項して、-θを別の文字bにで表現しておく方が後々はいいのですが、本質的には同じなのでとりあえずθのまま進めます。bはバイアスと呼ばれます)
さて、なぜパーセプトロンがXOR回路を満たすことができないか?というのを、何となくグラフで説明してみたいと思います。
まず、パーセプトロンの式のうち、y=1になる下の式を変形してみます。
変形!
\begin{align} w_1x_1+w_2x_2&>\theta \\ w_2x_2&>-w_1x_1+\theta \\ x_2&>-\frac{w_1}{w_2}x_1+\frac{\theta}{w_2} \end{align}
はい、こんな感じです。ここで、w1、w2、θはすべて勝手に決めることができますから、わかりやすくするために、新しい文字で勝手に置き換えちゃいましょう。
\begin{align} -\frac{w_1}{w_2}=a,\; \frac{\theta}{w_2}=b \end{align}
そうすると、変形した式は…
\begin{align} x_2>ax_1+b \end{align}
こうなりますね。x1を横軸に、x2を縦軸に取ったグラフを書いてみると、傾きがa、切片がbの直線の上側の領域ってことになります。傾きaはマイナスにすることもプラスにすることも自由ですし、bもどんな値も取れますので、自由にまっすぐ線を引くことができます。
傾きaが正の場合は、こんな感じの領域。
そして、傾きaが負の場合はこんな感じの領域になります。
一番最初のパーセプトロンの式に戻ると、「y=1となるのは、x1、x2が青く塗られた領域にあるとき」ということになります。同じように考えると、「y=0となるのは、青く塗られていない領域にあるとき」ということになりますね。
つまり、このx1-x2平面上で、y=0とy=1をキレイに分割できる線が引くことができれば、それはつまりパーセプトロンの式で表現できるということになります。
実は、上の図の「傾きが負の場合」という例は、OR回路を表していました。
復習ですが、OR回路は「x1=x2=0のときにyが0になって、それ以外のときはyが1になる」回路でしたね。先ほどの領域と重ねてみると…
はい、バッチリ青いところにy=1が収まって、y=0は青から外れていますね。
さて、今回のテーマであるXOR回路を、x1-x2平面上に置いてみましょう。
どん!
はい、こんな感じですね。
よし、これをy=0とy=1で分かれるように直線を引いてみよう!
…
…
…
だめだー!
どう頑張っても引けませんね。つまり、XOR回路はパーセプトロンでは表現できないということになります。
しかし実は、パーセプトロンにはまだ奥の手があります。それが…パーセプトロンを重ねるということです。こんな感じ。
x1、x2とyとの間に、s1、s2が挟まりました。s1がNAND回路になるように重みと閾値(バイアス)を調整し、s2はOR回路になるように重みと閾値(バイアス)を調整します。で、s1とs2からyに向かう重みと閾値(バイアス)をAND回路になるように調整します。
これまでに作った関数を総動員してPythonでコードをXOR回路を書いてみると…
こうなります。
s1として、NAND回路の結果を出力し、s2としてOR回路の結果を出力。そのs1とs2を入力として、AND回路の結果をyとして返します。
さて、XOR関数を実行してみると…
はい、冒頭に書いたXOR回路を満たしてますね!こうなるともはや、平面上で表現できなくなるので、視覚的にイメージするのが難しくなりますが、層を重ねることで、直線で分けられないような出力結果を得ることができる…ということになります。
ちなみに、このように層を複数重ねたパーセプトロンを多層パーセプトロン(multi-layered perceptron)と言います。
ということで
重みやバイアス(閾値)を調整するだけで、色んな形の出力が得られるイメージが付きましたね。調整の結果として出来上がるのは、入力値に対して、意図した形の出力値が得られるもの…つまりこれ、全体で関数を作ってるってことになりますよね。
層やニューロンの数を増やすことで、より複雑な関数が表現できそうだ、というのも何となく感じ取れました。
さて、次からはいよいよニューラルネットワークですね。楽しみです(^-^)
ではまた。