人工ニューロン

人工ニューロン

人工ニューロン (Artificial Neuron)

神経細胞のモデル化

 前回記事 で扱った生物の神経細胞(ニューロン)の機能になぞらえて、コンピュータ上に「複数の信号を受け取り、適当な重み(荷重)を加えて足し合わせて、活性化関数によって強度を調整して出力する」という関数を設計します。

 このようなモデルを 人工ニューロン (Artificial Neuron) とよびます。

 「人工」をつけているのは、もちろん本物のニューロンと区別するためですが、機械学習の分野では単に「ニューロン」とよぶのが一般的です。

 説明を簡単にするために、$2$つの信号 $(x_0,x_1)$ が入力される次のような人工ニューロンを考えます。

人工ニューロン(Artificial Neuron)

 それぞれの入力信号を重み $w_0,\ w_1$ を掛けて足し合わせ、さらにバイアスパラメータ $w_2$ を加えた値 $u$ を、このニューロンに対する入力総和とよびます。
 
\[u=w_0x_0+w_1x_1+w_2\]
 線形基底関数モデルのときと同じように、常に $1$ の値をとるような疑似信号 $x_2$ を導入して、入力総和を
 
\[u=w_0x_0+w_1x_1+w_2x_2\]
と書くことにすると、$2$つのベクトル
 
\[\boldsymbol{w}=\begin{bmatrix}w_0\\w_1\\w_2\end{bmatrix},\quad\boldsymbol{x}=\begin{bmatrix}x_0\\x_1\\x_2\end{bmatrix}\]
の内積を使って、

\[u=\boldsymbol{w}\cdot\boldsymbol{x}\]
と表すことができます。入力総和を活性化関数 $f(x)$ に通すことによって値を調整し、これをニューロンの出力 $y=f(u)$ とします。
 
\[y=f(u)=f(\boldsymbol{w}\cdot\boldsymbol{x})\]

単体ニューロンの実装

 Python で単体の人工ニューロンを実装してみましょう。
 活性化関数としては シグモイド関数 を採用します。

# リストM8-A-1

import numpy as np

# シグモイド関数
def sigmoid(x):
    f = 1 / (1 + np.exp(-x))
    return f

# 人工ニューロン
def neuron(x, w):
    u = np.dot(x, w)
    y = sigmoid(u)
    return y

 neuron()関数には信号をいくつでも入力できますが、上にも述べたように、ベクトルの最後の成分はバイアスです。$N$ 個の信号を入力するモデルでは $N+1$ 個のベクトル成分が必要です。とりあえずは信号を $2$ 個にして、neuron() に $\boldsymbol{w}=(2,-1.5,0.2),\ \boldsymbol{x}=(1,2,1)$ を渡してみましょう。

# リストM8-A-2

# 重みを設定
w = np.array([2, -1.5, 0.2])

# ニューロンへの入力
x = np.array([1, 2, 1])

# ニューロンからの出力
y = neuron(x, w)

print(y)
0.31002551887238755

 w や x の値を変えれば、出力は色々な値をとりますが、シグモイド関数を通しているので、必ず $0$ から $1$ の範囲に収まります。

 $x_0$-$x_1$ 平面の上に $y=f(u)$ の値をプロットすれば、$x_0$ と $x_1$ の組合わせに応じた出力変化を可視化できます。matplotlib.pyplot と mpl_toolkits.mplot3d をインポートして、3Dグラフを描いてみましょう。

# リストM8-A-3

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# 解像度を設定
xn = 33

# x0-x1平面上に格子点を作成
x0 = np.linspace(-1.0, 1.0, xn)
x1 = np.linspace(-1.0, 1.0, xn)
X0, X1 = np.meshgrid(x0, x1)

# x0,x1の重みを1.0,-1.0に設定
# バイアスの重みを0.2に設定
w = np.array([1.0, -1.0, 0.2])

# ニューロンの出力を格納する変数
Z = np.zeros((xn, xn))

# すべての格子点でニューロンからの出力を計算
for i in range(xn):
    for j in range(xn):
        Z[j][i] = neuron(w, [i, j, 1])

# FigureとAxesを追加
fig = plt.figure(figsize = (10, 6))
ax = fig.add_subplot(111, projection='3d')

# 軸ラベルを設定
ax.set_xlabel("x0", size = 16, labelpad = 10)
ax.set_ylabel("x1", size = 16, labelpad = 10)
ax.set_zlabel("y", size = 16)

# 曲面を描画
ax.plot_surface(X0, X1, Z, color = "green")

# 表示角度を設定
ax.view_init(45, 60)

plt.show()

人工ニューロン(Artificial Neuron)の出力

 これは見覚えのある図ですね。分類問題 で使用した2変数 ロジシティック関数 のグラフです。入力総和 $u$ は $x_0$ と $x_1$ の線形結合なので、それをシグモイド関数に渡せば、$x_0$ と $x_1$ を変数とするロジシティック関数になります。一般に $x_0,\ x_1,\ \cdots,\ x_{N-1}$ の入力があれば $N$変数ロジシティック関数を計算することになります。次回記事では数個のニューロンをつないで小さなニューラルネットワークを作って出力の様子を調べてみます。