1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

深層学習 Day 3 - Section 2 LSTM のまとめ

Last updated at Posted at 2020-11-20

この記事は個人的なお勉強用のメモです。

このお勉強の位置

深層学習 Day 3

Section 1 再帰型ニューラルネットワークの概念
Section 2 LSTM ← これ
Section 3 GRU
Section 4 双方向RNN
Section 5 Seq2Seq
Section 6 Word2vec
Section 7 Attention Mechanism

講義

RNNの課題

時系列を遡ると勾配が消失する。
長い時系列の学習が困難。

LSTMで上記の課題を解決できる。

用語

勾配爆発

逆伝播すると勾配が指数関数に大きくなってしまうこと。

勾配クリッピング

勾配のノルムがしきい値を超えたら、
勾配のノルムを正規化すること。
シンプルなRNNの勾配爆発は、勾配クリッピングによって解決できる。

演習チャレンジ(勾配クリッピング)

def gradient_clipping(grad, threshold):
  norm = np.linalg.norm(grad)
  rate = threshold / norm
  if rate < 1:
    return grad * rate
  return grad

np.linalg.norm関数:ノルムを計算して出力

講義では 「gradient * rate」が正解と言っているが
「grad * rate」が正解だと思う。

また、素朴な疑問だが、「勾のノルムがしきい値より大きいとき」なので
rateという変数を使うのではなく、

def gradient_clipping(grad, threshold):
  norm = np.linalg.norm(grad)
  rate = threshold / norm
  if norm > threshhold:
    return grad * (norm / threshold)
  return grad

の方がわかりやすいと思ったが、後で赤本2の 6.1.4 項を読んで、納得した。
rate 変数を先に作っておけば、複数の勾配を更新するときに
rate 変数を使えて便利なため。

LSTM

Long short-term memory
RNNとは構造が全く異なる。

CEC

Constant Error Carousel
勾配を1に保つ。

※ 勾配消失:勾配 < 1
 勾配爆発:勾配 > 1

CECの課題1:
 単にCECを導入すると、重みが一律になってしまう(NNの学習特性が無い)。
解決法:
 入力ゲートと出力ゲートの追加

CECの課題2:
 CECは過去の情報をすべて保管し続けてしまう。
解決法:
 忘却ゲートの追加

CECの課題3:
 CECに保存されている値が他のゲートに影響を与えていない。
 (任意のタイミングで他のノードに伝播させたり、任意のタイミングで忘却させたい。)
解決法:
 覗き穴結合の追加

入力ゲートと出力ゲート

重みを持つ入力ゲートと出力ゲートを加えることで
CECの課題を解決。
入力や出力によって重みを変化させる。

忘却ゲート

過去の情報が要らなくなったときに、情報を忘却する。

演習チャレンジ(LSTM)

def lstm(x, prev_h, prev_c, W, U, b):
  lstm_in = _activation(x.dot(W.T)) + prev_h.dot(U.T) + b)
  a, i, f, o = np.hsplit(lstm_in, 4)
  a = np.tanh(a)
  input_gate = _sigmoid(i)
  forget_gate = _sigmoid(f)
  output_gate = _sigmoid(o)
  c = input_gate * a + forget_gate * c
  h = output_gate * np.tanh(c)
  return c, h

新しいセルの状態=計算されたセルへの入力 × 入力ゲート +
         1ステップ前のセルの状態 × 忘却ゲート

覗き穴結合

CEC自身の値に、重み行列を介して伝播可能にした構造。

  • CECから入力ゲートへの覗き穴結合
  • CECから出力ゲートへの覗き穴結合
  • CECから忘却ゲートへの覗き穴結合

実装演習

なし

確認テスト

シグモイド関数の微分

シグモイド関数を微分すると $f(z)(1-f(z))$ になる。
この値が最大になるのは、$f(z)=1-f(z)$ のとき。
すなわち、$f(z)=0.5$ のとき。
このとき、シグモイド関数の値は $0.5\times (1-0.5)=0.25$ になる。

LSTMのゲート

「映画おもしろかったね。ところで、とてもお腹が空いたから何か____。」

「とても」が無くなっても空欄に影響を及ぼさないのだから、
「とても」は不要な言葉になる。
つまり、忘却ゲートによって忘却されても問題ない。

修了テスト~練習問題~

問題15(LSTM)

LSTMの構造

(i):入力ゲート
(f):忘却ゲート
(o):出力ゲート

問題16と問題17(LSTM)

LSTMのサンプルコード

class LSTM:
  def __init__(self, input_size=input_size, hidden_size=hidden_size):
    self.input_size, self.hidden_size = input_size, hidden_size
    self.weight = np.random.randn(self.input_size + self.hidden_size, self.hidden_size * 4)
    self.bios = np.random.randn(self.hidden_size * 4)

  def forward(self, x, h_prev, c_prev):
    inputs = np.concaterate([x, h_prev], axis=1) # xとh_prevを一つにまとめる。
    inputs = np.matmul(inputs, self.weight) + self.bios
    i, f, o, g = np.hsplit(inputs, 4)
    input_gate, forget_gate, output_gate, g = sigmoid(i), sigmoid(f), sigmoid(o), np.tanh(g)
    c_next = (c_prev * forget_gate) + (g * input_gate) # 
    h_next = np.tanh(c_next) * output_gate
    return h_next, c_next

問題16

各ゲートの値はスカラー値である(sigmoid関数の戻り値なので)。
スカラー値を行列に掛けるには、*(アスタリスク)の演算子を使う。

※ 選択肢1の「gorget_gate」は、おそらく「forget_gate」のスペルミス。

問題17

次の隠れ状態 h_next は、次の記憶セル c_next に tanh を作用させて、
出力ゲート output_get を掛けることによって更新する。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?