機械学習の基礎まとめ【ニューラルネットワークの推論(順方向への伝播)】

この記事を読むのに必要な時間は約 13 分です。

今回はニューラルネットワークについて、

 

「ニューラルネットワークって何?」

「パーセプトロンとニューラルネットワークとの違いは??」

「ニューラルネットワークを実装すると??」

 

この辺りをまとめてみました。

 

ちなみにJDLAのG検定でも出題される内容です。

この記事を書いている僕はシステムエンジニア6年目

 

普段はJavaでWebアプリを作ったりSQL書いたり・・・、

なので最近流行りのPython、数学、人工知能、デープラーニングができる人には正直憧れています。。。。

 

 

自分も一から勉強してこの辺りできるようになりたい、、画像認識モデルを作ったりして、アプリに組み込みたい!

これが機械学習、深層学習の勉強を始めたきっかけでした。

 

 

体系的に、この分野の基礎から学ぼうとJDLAのG検定の勉強をして合格するところまでいきました。

次のステップとして、

実際にPythonでコードを書きながら機械学習や深層学習の知識を深めているところです。。。

 

 

今回は、JDLAのG検定にも出題される「ニューラルネットワーク」についてまとめてみました。

 

ニューラルネットワークとは

 

 

「人間の脳内にある神経ニューロンとその繋がりを数式的なモデルで表現したもの」がニューロンです。

と、文字で書いてもさっぱりなので、、、

 

まず、ニューラルネットワークを図で表すと以下のようになります。

 

 

 

上の図において、左の列を入力層、真ん中の列を中間層もしくは隠れ層、右の列を出力層といいます。

ニューラルネットワークでは、入力信号が入力層から中間層にそれぞれ伝送され、最終的に出力層に伝送されます。

 

また、入力層から順に第0層、第1層、第2層となるので「2層ネットワーク」とも呼ばれます。

 

 

ニューロンのつながり方や入力信号の伝送に関して言えば、ニューラルネットワークはパーセプトロンと全く同じです。

 

パーセプトロンの詳細については以下の記事を参考にしてください。

機械学習の基礎まとめ【パーセプトロン】

 

 

ニューラルネットワークとパーセプトロンの違い

 

 

では、ニューラルネットワークとパーセプトロンとの大きな違いは何か。。。

 

それは、利用する活性化関数です。

 

活性化関数の詳細については以下の記事を参考にしてください。

機械学習の基礎まとめ【活性化関数(ステップ、シグモイド、ReLU、ソフトマックス)】

 

厳密に言うと、パーセプトロンはニューラルネットワークの一種で、

活性化関数にステップ関数を利用するニューラルネットワークをパーセプトロンと言います。

 

それぞれの関数をグラフにしたものが以下です。

 

 

破線がステップ関数で、入力値が0より大きければ1、小さければ0を返却する関数です。

実線がシグモイド関数で、入力値が小さければ小さい実数、大きければ大きい実数(0.23とか0.89とか)で返却する関数です。

 

また、どちらの関数も非線形関数である点、

入力信号が大きくなればなるほど大きい値(0〜1の範囲の値)を返す点が共通しています。

 

 

3層ニューラルネットワークの実装

 

それでは、実際に以下の3層ニューラルネットワークをPythonで実装して、

ニューラルネットワークの順方向への信号の伝播を確認してみます。

 

 

上のニューラルネットワークをPythonで実装すると、

Python
def sigmoid(x):
  return 1 / (1 + np.exp(-x))

def softmax(x):
  c = np.max(x)
  exp_a = np.exp(x - c) # オーバーフロー対策
  sum_exp_a = np.sum(exp_a)
  y = exp_a / sum_exp_a
  
  return y

#ニューラルネットワークのバイアス、重み設定
def init_network():
  network = {}
  network['W1'] = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
  network['b1'] = np.array([0.1, 0.2, 0.3])
  network['W2'] = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])
  network['b2'] = np.array([0.1, 0.2])
  network['W3'] = np.array([[0.1, 0.3], [0.2, 0.4]])
  network['b3'] = np.array([0.1, 0.2])
  
  return network

# 入力信号の順方向への信号の伝送
def forward(network, x):
  W1, W2, W3 = network['W1'], network['W2'], network['W3']
  b1, b2, b3 = network['b1'], network['b2'], network['b3']
  
  a1 = np.dot(x, W1) + b1 #第0層から第1層へ信号を伝送
  z1 = sigmoid(a1) #第1層のニューロン内でのシグモイド関数による値の変換
  a2 = np.dot(z1, W2) + b2 #第1層から第2層へ信号を伝送
  z2 = sigmoid(a2) #第2層のニューロン内でのシグモイド関数による値の変換
  a3 = np.dot(z2, W3) + b3 #第2層から第3層へ信号を伝送
  y = softmax(a3) #第3層のニューロン内でのソフトマックス関数による値の変換

  return y

network = init_network()
x = np.array([1.0, 0.5])
y = forward(network, x)
print(y)

 

出力結果は以下になりました。

 

 

ソースコードの解説

まず、多次元配列について確認します。

Python
network['W1'] = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])

 

\(W1\)は2行3列の2次元配列です。

2次元配列のことを行列と呼び、配列の横方向の並びを、縦方向の並びをと呼びます。

数式で表すと、

$$W1 = \begin{pmatrix} 0.1 & 0.3 & 0.5 \\ 0.2 & 0.4 & 0.6 \end{pmatrix}$$

 

また、Pythonで行列の形状、次元数を確認すると以下のようになります。

Python
import numpy as np

W1 = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
print("行×列:", W1.shape)
print("次元数:", np.ndim(W1))

 

 

 

次に、行列の計算について確認します。

Python
a1 = np.dot(x, W1) + b1 #第0層から第1層へ信号を伝送

 

上記のソースコードでは、入力信号\(x\)と重み\(W1\)の内積を計算し、バイアス\(b1\)を足しています。

数式で表すと以下の計算を行います。

\(a1 = \begin{pmatrix} 1.0 & 0.5 \end{pmatrix} \begin{pmatrix} 0.1 & 0.3 & 0.5 \\ 0.2 & 0.4 & 0.6 \end{pmatrix} + \begin{pmatrix} 0.1 & 0.2 & 0.3 \end{pmatrix}\)

 

\(= \begin{pmatrix} 0.1 \times 0.1 + 0.5 \times 0.2 & 0.1 \times 0.3 + 0.5 \times 0.4 & 0.1 \times 0.5 + 0.5 \times 0.6 \end{pmatrix} \)

 

\( + \begin{pmatrix} 0.1 & 0.2 & 0.3 \end{pmatrix}\)

 

\(= \begin{pmatrix} 0.11 + 0.1 & 0.23 + 0.2 & 0.35 + 0.3 \end{pmatrix}\)

 

\(= \begin{pmatrix} 0.21 & 0.43 & 0.65 \end{pmatrix}\)

 

ニューラルネットワークのプログラムでは、

上記の行列の内積や和の計算、活性化関数による値の変換をネットワークの層の数だけ繰り返しています。

 

まとめ

 

 

今回はニューラルネットワークの推論(順方向への伝播)について確認しました。

この推論によって、

例えば手書き数字が0〜9のどれかを分類できたりします。

 

以下は抑えておきましょう。

  • ニューラルネットワークでは、活性化関数としてシグモイド関数のような滑らかに変化する関数を利用する
  • 多次元配列の内積や和を使うことでニューラルネットワークが簡単に実装できる

 

 

今回はニューラルネットワークの推論(順方向への伝播)でしたが、

ニューラルネットワークの学習(逆方向への伝播)によって今まで手動で設定していた重みを自動で最適化することもできます。

 

その辺りの内容はまた別の記事にまとめたいと思います。

 

 

参考にした資料

 

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください