Deep Learning資格試験 深層学習 順伝播ネットワーク
はじめに
日本ディープラーニング協会の Deep Learning 資格試験(E 資格)の受験に向けて、調べた内容をまとめていきます。
ニューラルネットワーク全体像
深層学習の発展は、人間の神経回路網を模したニューラルネットワークとうい数理モデルが基となっており、解決すべき問題に応じてさまざまなモデルが提案されている。
入力層
ニューラルネットワークの全体として、入力層から中間層にデータが変換されながら渡されて、活性化関数を通して出力層へデータが出力される。
入力層はニューラルネットワークに何かしらの数値を渡される。受け取る場所をノードという。入力層から中間層へ渡すときに重みを準備する。入力ノード毎に重要な項目であれば重みが大きくなり、重要でない項目の重みは小さくなる。重みだけで表現できない場合にバイアスで調整する。
入力層の設計
- 入力層として取るべきでないデータ
- 欠損値が多いデータ
- 誤差の大きいデータ
- 出力そのもの、出力を加工した情報
- 連続性のないデータ(背番号とか)
- 無意味な数が割り当てられているデータ
- 欠損値の扱い
- ゼロで詰める
- 欠損値を含む集合を除外する
- 入力として採用しない
- データの結合
- 数値の正規化・正則化
中間層(隠れ層)
中間層の出力は、入力層の計算結果(総入力)に対して、活性化関数を通すと得られる。中間層のの出力は次のネットワークの入力値となる。
活性化関数
シグモイド関数
- 0 ~ 1 の間を緩やかに変化する関数である。
- 課題として、大きな値では出力の変化が微小なため、勾配消失問題を引き起こす事がある。
- 微分すると最大値は 0.25 である。(
の場合)x=0
- 微分すると下記の計算となる。
ソースコードはゼロから作る Deep Learningから引用
# シグモイド関数
def sigmoid(x):
return 1 / (1 + np.exp(-x))
# シグモイド関数の導関数
def sigmoid_grad(x):
return (1.0 - sigmoid(x)) * sigmoid(x)
ReLU 関数
- 入力が0を超えていれば、その入力をそのまま出力し、0以下ならば0を出力する関数である。
- 勾配消失問題の回避とスパース化に貢献することで良い成果をもたらしている。
- 微分すると下記の結果となる。
ソースコード
ソースコードはゼロから作る Deep Learningから引用
# ReLU関数
def relu(x):
return np.maximum(0, x)
# ReLU関数の導関数
def relu_grad(x):
grad = np.zeros_like(x)
grad[x>=0] = 1
return grad
ハイパボリックタンジェント(tanh)関数
- -1.0 ~ 1.0 の範囲の数値に変換して出力する関数である。
- 座標点(0, 0)を基点(変曲点)として点対称である。
- 微分すると最大値は 1.0 である。(
の場合)x=0
- 微分すると下記の計算となる。
ソースコード
ソースコードはゼロから作る Deep Learningから引用
# tanh関数
def tanh(x):
return np.tanh(x)
恒等写像(回帰)
ソフトマックス関数(多クラス分類)
- 微分すると下記の計算となる。
ここで、
つまり、
オーバーフロー対策について
ソフトマックス関数には、入力の各要素すべてに同じスカラーを加えても、ソフトマックス関数の出力は変わらない。
この性質は、ソフトマックス関数の分子と分母に任意の定数をかけることで、導くことができる。この性質から、ソフトマックス関数は入力の差のみに依存する。
この性質を用いると、オーバーフロー対策として、入力
ソースコード
ソースコードはゼロから作る Deep Learningから引用
import numpy as np
def softmax(x):
x = x - np.max(x, axis=-1, keepdims=True) # オーバーフロー対策
return np.exp(x) / np.sum(np.exp(x), axis=-1, keepdims=True)
ソフトマックス関数をニューラルネットワークに適用することを考慮して、順伝播処理と逆伝播処理を行うクラスを Softmax クラスとして実装すると、下記のようになる。
class Softmax():
def __init__(self):
self.params , self.grads = [], []
self.out = None
def forward(self, x):
self.out = = softmax(x)
return self.out
def backward(self, dout):
dx = self.out * dout
sumdx = np.sum(dx, axis=1, keepdims=True)
dx -= self.out * sumdx
return dx
誤差逆伝播法(バックプロパゲーション)
誤差勾配の計算
どう計算するか?
算出された誤差を、出力層側から順に微分し、前の層前の層へと伝播する。
最小限の計算で各パラメータでの微分値を解析的に計算する手法。
計算結果(=誤差)から微分を逆算することで、不要な再帰的計算を避けて微分を算出できる。
誤差伝搬法はどのように計算している
下記の定義がある場合に、
つまり、
※
誤差関数
二乗和誤差
微分すると
交差エントロピー
微分すると
ソースコード
ソースコードはゼロから作る Deep Learningから引用
def cross_entropy_error(y, t):
"""
y : ソフトマックス関数の出力
t : 正解ラベル
"""
if y.ndim == 1:
t = t.reshape(1, t.size)
y = y.reshape(1, y.size)
# 教師データがone-hot-vectorの場合、正解ラベルのインデックスに変換
if t.size == y.size:
t = t.argmax(axis=1)
batch_size = y.shape[0]
delta = 1e-7
return -np.sum(np.log(y[np.arange(batch_size), t] + delta)) / batch_size
class SoftmaxWithLoss:
def __init__(self):
self.loss = None
self.y = None # softmaxの出力
self.t = None # 教師データ
def forward(self, x, t):
self.t = t
self.y = softmax(x)
self.loss = cross_entropy_error(self.y, self.t)
return self.loss
def backward(self, dout=1):
batch_size = self.t.shape[0]
if self.t.size == self.y.size: # 教師データがone-hot-vectorの場合
dx = (self.y - self.t) / batch_size
else:
dx = self.y.copy()
dx[np.arange(batch_size), self.t] -= 1
dx = dx / batch_size
return dx
Discussion