ニューラルネットワーク
バイアスを明示的にし、結果を出力する際に活性化関数を用意する。
活性化関数は非線形関数を用いる必要がある。線形関数を用いると中間層がなくなるネットワークができてしまうため
a = b + w1*x1 + w2*x2
のとき
y = h(a)
hを活性化関数と呼ぶ
分類問題と回帰問題に使える。どの問題に使うかで活性化関数が変わる。
分類問題
データがどのクラスに存在するか。人の画像から男か女か判断する
回帰問題
データの予測
活性化関数
ステップ関数
入力が0を超えたら1 それ以外は0 矩形波みたいになる。
def step_function(x):
if x > 0:
return 1
else:
return 0
シグモイド関数
xが無限に近くにつれ、1に近い値を出力し、0に近くと0に近い値を出力する。
h(x) = 1 / 1 + exp(-x)
import numpy as np
def sigmoid(x)
return 1 / (1 + np.exp(-x))
行列の積
多次元配列 - 行列 - に対して積をとっていく。
weight に対して注意することは、
w * x = c
のとき
wの列数と、xの行数を一致しないと積をとることはできない。出力cは、w行数、xの列数の行列となる。
numpyでは、Numpy.dotを使う。
実装例
forward : 入力から出力方向への伝達処理のこと
identity_function : 出力層の活性化関数として利用。恒等関数と言う。
import numpy as np
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def identity_function(x):
return x
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
z1 = sigmoid(a1)
a2 = np.dot(z1, W2) + b2
z2 = sigmoid(a2)
a3 = np.dot(z2, W3) + b3
y = identity_function(a3)
return y
network = init_network()
x = np.array([1.0, 0.5])
y = forward(network, x)
print(y)
出力層の設計
活性化関数を利用する際の注意事項
回帰問題 : 恒等関数
分類問題 : ソフトマックス関数
恒等関数
入力をそのまま出力にする。
ソフトマックス関数
全ての入力信号から影響を受ける値を出力する。
0 .. 1 の間に出力が収まる。確率として解釈が可能。
cは階乗する際にオーバーフローを発生させない対策
import numpy as np
def softmax(a):
c = np.max(a)
exp_a = np.exp(a - c)
sum_exp_a = np.sum(exp_a)
y = exp_a / sum_exp_a
return y
出力層のニューロンの数
解くべき問題に応じて、決定する必要がある。
0 .. 9 の手書き文字の認識では、10個の出力ニューロンを用意する。