4.9 Deep Learning 3層ニューラルネットワークの実装 1

なぜ、Deep Learningに行列の内積や、パーセプトロンの説明が必要かというと、最終目標である言語処理を学習するRNNにそれらすべてが必要だからである。本をただ、写しているわけではない。

ここでは上図4.9-1に示すような3層ニューラルネットワークを対象として、
その入力から出力への順方向への処理(フォワード方向への処理)を実装する。
実装については次回説明する。

ここで必要な理解は、重みの記号の表記である。下図に示す。

上図は入力層のx2のニューロンから、次層のニューロンa1^(1)への
重みだけをピックアップして図示している。

上図の通り、重みや隠れ層のニューロンの右上には「(1)」とある。
これは第1層の重み、第1層のニューロン、ということを意味する番号である。
また、重みの右下には2つの数字(1 2)が並ぶが、これは、次層のニューロンと前層のニューロンのインデックス番号から構成される。たとえば、上図右上で説明しているw12^(1)は前層の2番目のニューロン(x2)から次層の1番目のニューロンa1^(1)への重みであることを意味する。

重み右下の数字は、次層、前層の順に並ぶことに注意されたい。

 

Deep Learning 4.8 行列の内積

2行2列の行列同士の内積は下記のように計算する。

これのPythonの実績は下記のようになる。


dot(A,B)は行列Aと行列Bの内積であり、dot(B,A)は行列Bと行列Aの内積の結果であるが、行列の積では、演算順序が異なると(A*BかB*A)、結果が異なることがありうる。また、行列の1行目の列数と,行列の1列目の行数が異なると、行列の内積は計算自体ができない。下記のようにエラーになる。

Deep Learning 4.7 行列と配列

4.7.1 Pythonの多次元配列の実装

配列の次元数はndim()関数で取得できる。(number of dimensionの略、多分)
A.shapeの結果はタプルになっている。Aは一次元配列なので、奇妙な出力になっているらしい。

上記は2行3列の行列を実装しているが、3×2の二次元配列と、処理的には言うのでB.shapeの出力は(3,2)となっている。

Deep Learning 4.6 ReLU関数

ReLU(Rectified Linear Unit)(Rectify:正す)関数は、入力が0を超えていれば、
それをそのまま出力し、0以下ならば0を出力する関数である。
現在この関数が主に活性化関数として使用されている。

ReLU関数を数式で表すと、次の式のように書くことができる。

\begin{eqnarray} h(x)= \begin{cases}
x & x > 0 \\
0 & x \leqq 0 \tag{1.7}
\end{cases}
\end{eqnarray}

シンプルな関数で、実装も簡単である。
def relu(x):
return np.maximum(0, x)

maximumという関数は入力された値のうち、大きい方の値を選んで出力する関数である。

Deep Learning 4.5 シグモイド関数とステップ関数の比較

青い破線がステップ関数、オレンジの曲線がシグモイド関数を表す。出力量を水に例えると、ステップ関数はししおどしのように、水を流すか流さないか、2つの動きのみをするに対して、シグモイド関数は水車のように、流れてきた水の量に比例して、次へ流す水の量を調整する。

見た目は、異なるが、入力が0に近ければ0に近い値を(0を)1に近ければ1に近い値を出力する非線形関数(*1)であり、どんなに入力信号が大きくても出力は0から1の間に押し込める点が共通している。

(*1):線形関数は1本の直線であらわされる関数であり、それ以外は非線形関数である。

ニューラルネットワークでは、活性化関数に非線形関数を使用しなくてはならない。
線形関数を使用すると、どんなに層を深くしても、入力と出力の間に一定の関係ができてしまうことは、直観的にわかるだろう。

例えば、活性化関数にh(x)=cxのみを使用した、3層のネットワーク構造を考えると、y(x) = h(h(h(x))))で表されるが、y(x) =h(h(h(x)))) = h(h(cx))) = h(c*c*x) = c*c*c*xとなり、y(x) = ax(ただし、a=c*c*c(定数))の一回の掛け算で表現でき、実質隠れ層である中間層はいらなくなる。

このため、多層構造の恩恵を得るためには、活性化関数に非線形関数を使用する必要がある。

シグモイド関数は、ニューラルネットワークに古くから利用されていたが、現在使われている活性化関数はReLU(Rectified Linear Unit)関数であり、シグモイド関数よりかなりシンプルである。 次回示すことにする。