Deep Learning 3 パーセプトロンのpythonでの実装

pythonには現実、神話とわず大蛇の意味がある。
プログラミング言語Pythonを作った人は、空飛ぶモンティパイソンというコメディTVからとったと言っている。(空飛ぶモンティパイソンについて、調べてみたが、何回読んでも意味不明である。変態の考えることはいつも理解されない(不幸なことだ)。コルトパイソンのパイソンの由来は「ただ、カッコイイから」らしい。こちらのほうがまだわかる。)

バイアスの導入

\begin{eqnarray} y= \begin{cases}
0 & (w_1x_1 + w_2x_2 ) \leqq \theta \\
1 & (w_1x_1 + w_2x_2 ) > \theta \tag{1.1}
\end{cases}
\end{eqnarray}

前回説明した上式においてθ=-bとすると、

\begin{eqnarray} y= \begin{cases}
0 & (b + w_1x_1 + w_2x_2 ) \leqq 0 \\
1 & (b + w_1x_1 + w_2x_2 ) > 0 \tag{1.2}
\end{cases}
\end{eqnarray}

と変形できる。

ここでbをバイアス(bias:偏り,ゲタばき)と呼ぶ。w1,w2は前回説明したように重みである。

この実装を下に示す。

x = np.array([0,1])では 普通の言語で言うところの x[] = {0,1};である。すなわち、
x[0] = 0; x[1] = 1;である。
同様に、w = np.array([0.5,0.5]);  w[] = {0.5,0.5};であり、すなわち、
w[0] = 0.5; w[1] = 0.5;

NumPy配列(Python実装の配列)の乗算では、2つの配列の要素数が同じ場合、その要素どうしが乗算される。(C言語などでは、x[0] * w[0]; x[1] * w[1]; としなければならない。)

np.sum(w*x)については、wの配列とxの配列の乗算の和である。

\begin{equation}
f(x) = \sum_{i=0}^1 x_iw_i = x_0 \times w_0 + x_1 \times w_1\\
= 0 \times 0.5 + 1 \times 0.5 = 0 + 0.5 = 0.5
\end{equation}
とあらわされ、
すなわち、w * x = [0,  1] * [0.5,  0.5] = [0 * 0.5 , 1 *0.5] => [0,  0.5]であり、

np.sum(w*x) = 0+0.5 = 0.5;であり、各要素の総和が計算される。この総和は重み付き和とよばれ、これにバイアスを加算すれば、式(1.2)の計算は終了する。

ここで b= -0.7であり、np.sum(w*x)= 0.5であるのに、なぜ出力結果が-0.2とならず、
-0.199999…という奇妙な浮動小数点数になっているか、不思議に思うだろうが、これは演算誤差とよばれるもので、こちらを参照されたし。

オーバーフローとアンダーフローについてはこちらを参照されたし。

これはテストプログラムなので、修正を省略するが、金融系の例えばATMのプログラムでこのようなことがおきたら、どうなるか想像するだけで恐ろしいであろう。

金融系のIT企業がヤバイのは、ハッキングやウィルス、情報漏洩に加え、こういう問題に神経を削らなければいけないからである。

Deep Learning 2 パーセプトロン

パーセプトロン(あるいは、人工ニューロンや単純パーセプトロンというらしい)、は、ニューラルネットワーク(ディープラーニング)、人工知能が”学習”するのに必要な概念である(らしい)ので、ここで記述しておく。

パーセプトロンは、複数の信号として受け取り、ひとつの信号を出力する。
ここで言う「信号」とは電流や川のような「流れ」を持つイメージである。
電流が導線を流れ、電子eを先に送り出すように、パーセプトロンの信号も流れを作り、情報を先へと伝達していく。ただし、実際の電流とは違い、パーセプトロンの信号は「流す/流さない(1か0)」の二値の値。0を信号を流さない。1を信号を流すとする。

記法や概念は有限オートマトンに似ている。忌まわしいオブジェクト指向のモデリング言語(UML)の、なんかのクラス図や図形にも似ている。クラス図やオブジェクト図、ユースケース図など、あの複雑怪奇な記法を知っていたからと言って、何の役にも立たない(クラス図の表記の専門家しか精確に多重度などは描けないし、そもそも新人の技術者や組み込み系専門の技術者は読めない。さらに悪いことには、ある程度の専門家でも、描く人によって、図形が違う。)狂人のつぶやき、”図画工作の僕のおとうさん”のような物と違って、パーセプトロンは単純で明快である。

\[ x_1, x_2 は入力信号、yは出力信号、w_1,w_2は重みを表す。(wはweightの頭文字)\]

図の〇は「ニューロン」や「ノード」と呼ばれる、(脳細胞の一つと考えるとわかりやすい。)
入力信号は、ニューロンに送られる際に、それぞれに固有の重みが乗算される。
\[(w_1x_1,w_2x_2)\]
ニューロンでは、送られてきた信号の総和が加算され、その総和が限界値を超えたときのみ1を出力する。これをニューロンが発火すると表現することもある。(入力信号がストレスで、限界値を超えるとキレる(1を出力する,または発火する)と考えるとわかりやすいかもしれない。)

ここではその限界値を閾値(しきいち)と呼び、θという記号であらわす。

パーセプトロンの動作原理はこれだけである。以上のことを数式で表すと下のようになる。

 

\begin{eqnarray} y= \begin{cases}
0 & (w_1x_1 + w_2x_2 ) \leqq \theta \\
1 & (w_1x_1 + w_2x_2 ) > \theta \tag{1.1}
\end{cases}
\end{eqnarray}

パーセプトロンは、複数ある入力信号のそれぞれに固有の重み(ex.w1,w2)を持つ。そして、その重みは、各信号の重要性をコントロールする要素として働く。重みが大きければ大きいほど、その重みに対応する信号の重要性が高くなる。

人がストレスでキレる例を挙げれば、家庭のストレス、通勤のストレス、上司のストレスなど様々なストレスがあるが、ある人が、通勤、家族のストレスはあまり感じないが、上司のストレスを大きく感じる場合、通勤、家族(のストレス)の重みは小さく、上司(のストレス)の重みは大きい。