この記事は個人的なお勉強用のメモです。
このお勉強の位置
深層学習 Day 3
Section 1 再帰型ニューラルネットワークの概念
Section 2 LSTM
Section 3 GRU ← これ
Section 4 双方向RNN
Section 5 Seq2Seq
Section 6 Word2vec
Section 7 Attention Mechanism
講義
LSTMの課題
LSTMはパラメータ数が多く、計算負荷が高い。
⇒ GRUで解決
GRUとは
Gated Recurrent Unit
LSTMに比べてパラメータが少なく、計算負荷が低い。
精度は同等またはそれ以上。
演習チャレンジ(GRU)
def gru(x, h, W_r, U_r, W_z, U_z, W, U):
r = _sigmoid(x.dot(W_r.T) + h.dot(U_r.T)
z = _sigmoid(x.dot(W_z.T) + h.dot(U_z.T)
h_bar = np.tanh(x.dot(W.T) + (r * h).dot(U.t))
h_new = (1 - z) * h + z * h_bar
return h_new
赤本2の C.2 節にある図を見ながら答えを書いたら正解だった。
GRUの構造
- 隠れ状態 h あり、記憶セル c なし
- resestゲート:過去の隠れ状態 h を無視する割合
- updateゲート:隠れ状態 h を更新する割合
- LSTMのforgetゲートとしての動作は、(1-z) * zの部分。
- LSTMのinuputゲートとしての動作は、z * h_bar の部分。
- z が大きいと、inputゲート側に傾いて動作する。
- z が小さいと、forgetゲート側に傾いて動作する。
- 隠れ状態が更新されるとき、過去の隠れ状態を 2 つの方面から参照する
- h_bar の作成と参照
- 新しい隠れ状態の作成のために直接参照
実装演習
なし。
確認テスト
LSTMとCECが抱える課題
LSTMの課題:
パラメータ数が多く、計算負荷が高い。
CECの課題:
重みが一律になってしまい、NNの学習特性が無い。
LSTMとGRUの違い
LSTMはパラメータ数が多く計算負荷が高い。
GRUはパラメータ数が少なく計算負荷が低い。
修了テスト~練習問題~
問題18(GRUとLSTM)
- GRUとLSTMはゲートを使用する。ゲートによって防ぐのは勾配爆発ではなく勾配消失である。
- どちらが性能がいいとは言えない。使い分ける。
- GRUに記憶セルはない。LSTMには記憶セルがある。
- LSTMには3つのゲート(input,forget,output)が、GRUには2つのゲート(reset,update)がある。
問題19、問題20、問題21(GRU)
※ 図 1 内の r の左付近の矢印の向きが逆になっている。
def GRU:
def __init__(self, input_size=input_size, hidden_size=hidden_size):
self.w_z, self_w_r, self.w_c = \
np.random.randn(input_size + hidden_size, hidden_size) for i in range(3)
self.b_z, self.b_r, self.b_c = \
(np.random.randn(hidden_size) for i in range(3)
def forward(self, x, h_prev):
inputs = np.concaterate([x, h_prev], axis=0)
z = sigmoid(np.matmul(inputs, self.w_z) + self.b_z)
r = sigmoid(np.matmul(inputs, self.w_r) + self.b_r)
_c = np.concatenate([h_prev * r, x], axis=0)
c = np.tanh(np.matmul(_c, self.w_c) + self.b_c)
h_next = (z * c) + ((1 - z) * h_prev)
return h_next
np.random.randn関数:標準正規分布の乱数を返す。引数にはサイズを指定する。
問題19
第一引数を、重みに掛ける入力と考える。
第二引数を、次の計算時の重みに掛ける入力と考える。
図 1 によると、x (input) と h (hidden) を入力にしている。
また、図 1 によると、r を求めた後の次の計算対象は h (hidden) である。
問題20
h_prevの列数:hidden_size
x の列数:input_size
_c の列数 = h_prev と x を axis=1 で連結した列数:input_size + hidden_size
また、self.w_c の行数が input_size + hidden_size であることからも明らか。
問題21
1 - z は隠れ状態 h に影響する。
z は入力 x から tanh で得られた値 c (変数名は h_bar とも) に影響する。