日本ディープラーニング協会 E資格 JDLA認定プログラム受講記録（その５）

[ラビットチャレンジ](http://ai999.careers/rabbit/)のＥ資格講座、ディープラーニングのＤａｙ３です。
[![card.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/8e9be486-3440-a3d1-db0c-2b7866601b10.png)
](http://ai999.careers/rabbit/)


[日本ディープラーニング協会 E資格 JDLA認定プログラム受講記録（その１）](https://qiita.com/awasirom/items/6cce5ca6d9c446edb2a4)
[日本ディープラーニング協会 E資格 JDLA認定プログラム受講記録（その２）](https://qiita.com/awasirom/items/8a4e91d0cd024dff6df3)
[日本ディープラーニング協会 E資格 JDLA認定プログラム受講記録（その３）](https://qiita.com/awasirom/items/df745bc67a6ca3c24ce4)
[日本ディープラーニング協会 E資格 JDLA認定プログラム受講記録（その４）](https://qiita.com/awasirom/items/2c97f3186ffbe2466dd8)
[日本ディープラーニング協会 E資格 JDLA認定プログラム受講記録（その６）](https://qiita.com/awasirom/items/0858abc1daddd7b33797)

---

セクションの構成は以下の通り。

Section1：再帰型ニューラルネットワークの概念
Section2：LSTM
Section3：GRU
Section4：双方向RNN
Section5：Seq2Seq
Section6：Word2vec
Section7：Attention Mechanism

#Section1：再帰型ニューラルネットワーク（RNN）の概念

####RNN全体像

RNN：時系列データに対応可能なニューラルネットワーク

時系列データ：時間的順序を追って一定間隔ごとに観察され，しかも相互に統計的依存関係が認められるようなデータの系列
↑
テキストの定義ですが、簡単に言うと時間を追って順に記録したデータで、順番に意味がある（順番変えたら意味がない）データ。

なので、

- 毎日の気温
- 月ごとの売り上げ
- 株価

などもそうですが、日付や時間がなくても、

- 音声データ
- テキストデータ

なども時系列データになる。

RNNの構造は下図ようになっている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/76c6ff6a-ea08-3612-ab3c-d00580726ae4.png)

入力は時系列なので、$...,x_{t-1}, x_{t},...$と順番に入力がある。時刻$t$の中間層には、時刻$t-1$の中間層の出力に重み$W$を掛けた値が加えられる（省略しているがそれぞれバイアスも加えられる）。

#####演習問題

(1) ２進数の足し算を予測するAIのソースが与えられており、隠れ層のノード数、重みの初期値、学習率を変更して結果を確認するというもの。

グラフのスケールが１回毎に変わってしまっていたのでY軸を固定、全体を関数化して機械的に回してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/2e097db2-afdc-3f63-8b9b-fa0300493162.png)

今回は、64-1.5-0.5の組み合わせが一番でしたが、傾向が良くわかりませんでした。学習率はもっと増やしても良かったかもしれません。また同じパラメータでも実行する度に結構変わります。

(2) 初期値をXavierに変えたもの。

パラメータにもよるが全般的にギザギザが少なく収束が早くなっているようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/5c371d3e-aa91-226a-e2f5-ad6e0ae011fb.png)


(3) 次は初期値をHeにしたもの。

Xavierと同じか良いように思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/e19976c9-1e22-97a5-48f4-2e7637914eb6.png)


(4) 活性化関数をReLU関数に変えて勾配爆発を確認する。

与えられたソースを変更して実行したのですが、オーバーフローやエラーが発生しなかなかうまくいきません。後でしっくり調査することとし学習を先に進めたいと思います。
今のところ以下の３つのパターンのグラフが得られています。上の２つは計算がきちんとできていないように思います。

なおRNNは、前の時刻から引き継いだデータに繰り返し同じ重みを掛け合わせるので、勾配損失／爆発が通常のニューラルネットワーク以上に起こりやすいとのこと。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/13085420-9aa7-5c30-0bcd-07bb2c09712d.png)

(5) 活性化関数をハイパボリックタンジェント（$tanh$）にする。

$tanh$の導関数が必要ですが以下のように求められる。

```math
\begin{align}
tanh(x) &= \frac{e^{x}-e^{-x}}{e^{x}+e^{-x}}\\
\frac{d}{dx}tanh(x) &= \frac{(e^{x}-e^{-x})'(e^{x}+e^{-x})-(e^{x}-e^{-x})(e^{x}+e^{-x})'}{(e^{x}+e^{-x})^{2}}\\
&= \frac{(e^{x}+e^{-x})^{2}-(e^{x}-e^{-x})^{2}}{(e^{x}+e^{-x})^{2}}\\
&= \frac{4e^{x}e^{-x}}{(e^{x}+e^{-x})^{2}}\\
&= \frac{4}{(e^{x}+e^{-x})^{2}}\\
&= \frac{1}{cosh^{2}(x)} \quad\quad\quad\quad
\Biggl(cosh(x) = \frac {e^{x}+e^{-x}}{2} より\Biggr)\\
\end{align}
```

ReLUよりは動いたものの、パラメータを変えてもにたようなギザギザしたグラフになって収束しきれていない感じでした。特に特徴がなかったので、ひとつだけグラフを載せておきます。こちらも後でよく確認してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/326e45ea-5d47-f375-05e1-75167adb31d2.png)

####BPTT（Backpropagation Through Time）

RNNにおけるパラメータ調整方法の一種（誤差逆伝播の一種）

####数式

＜順伝播＞

```math
\begin{align}
u^{t} &= W_{(in)}x^{t}+Wz^{t-1}+b\\
z^{t}&=f(W_{(in)}x^{t}+Wz^{t-1}+b)\\
v^{t} &= W_{(out)}z^{t}+c\\
y^{t} &= g(W_{(out)}z^{t}+c)\\
\end{align}
```


＜逆伝播＞

偏微分

```math
\begin{align}
\frac{\partial E}{\partial W_{(in)}} &= \delta^{t}[x^{t}]^{T}\\
\frac{\partial E}{\partial W_{(out)}} &= \delta^{out,t}[z^{t}]^{T}\\
\frac{\partial E}{\partial W} &= \delta^{t}[z^{t-1}]^{T}\\
\frac{\partial E}{\partial b} &= \delta ^{t}\\
\frac{\partial E}{\partial c} &= \delta ^{out,t}\\
\delta^{t} &= \frac{\delta E}{\delta u^{t}}\\
\delta^{t-z-1} &= \delta^{t-z} \Bigl\{ Wf'(u^{t-z-1}) \Bigr\}
\\
\end{align}
```

パラメータ更新

```math
\begin{align}
W_{(in)}^{t+1} &= W_{(in)}^{t} - \epsilon \frac{\delta E}{\delta W(in)}
= W_{(in)}^{t}-\epsilon\sum_{z=0}^{T_{t}}\delta^{t-z}[x^{t-z}]^T\\
\\
W_{(out)}^{t+1} &= W_{(out)}^{t} - \epsilon \frac{\delta E}{\delta W(out)}
= W_{(in)}^{t}-\epsilon\delta^{out,t}[z^{t}]^T\\
\\
W^{t+1} &= W^{t}-\epsilon\frac{\delta E}{\delta W}
=W_{(in)}^{t}-\epsilon \sum_{z=0}^{T_{i}}\delta^{t-z}[z^{t-z-1}]^{T}\\
b^{t+1} &= b^{t}-\epsilon\frac{\delta E}{\delta b} = b^{t}-\epsilon\sum_{z=0}^{T_{t}}\delta^{t-z}\\
c^{t+1}&=c^{t}-\epsilon\frac{\delta E}{\delta b}
=c^{t}-\epsilon \delta^{out,t}
\end{align}
```

＊基本は普通のニューラルネットワークと同じ
＊$\delta^{t}$がポイント
＊$\delta ^{out,t}$のところは$\sum$がないが、総和をとった結果そこだけ残っている。

#Section2：LSTM（Long short-term memory）

RNNには勾配損失の問題があり，長い時系列の学習が困難であった。構造を変えることにより解決したものがLSTM。

####勾配爆発

勾配が逆伝播するごとに指数関数的に増大すること。

勾配爆発を抑制する方法としてクリッピングという手法がある。勾配のノルムがしきい値を超えたときは勾配のノルムをしきい値に正規化する。つまり

**（新しい勾配）＝（閾値）／（勾配のノルム）**

となる。

####CEC（Constant Error Carousel）

過去データを保存するためのユニット。
勾配が１であれば勾配損失／爆発は起こらない。

以下のページなども参照しました。
[http://sagantaf.hatenablog.com/entry/2019/06/04/225239](http://sagantaf.hatenablog.com/entry/2019/06/04/225239)
[https://qiita.com/t_Signull/items/21b82be280b46f467d1b]
(https://qiita.com/t_Signull/items/21b82be280b46f467d1b)
などを読んでみました。

＜課題＞

時間依存度に関係なく重みが一律なことから、ニューラルネットワークの学習特性がなくなり、

- 入力重み衝突
- 出力重み衝突

という問題が発生した。

#####入力・出力ゲート

入力値の重みを、重み行列$W$、$U$で可変可能とすることで、CECの課題を解決。

####忘却ゲート

CECは過去の情報をすべて保管している。忘却ゲートはCECから不要なものを削除する。

####覗き穴結合

CECの値を重み行列を介して入力／出力ゲートに伝播可能にした構造。

#Section3：GRU（Gated Recurrent Unit）

LSTMはパラメータが多く計算負荷が高い。構造を変えることによりパラメータを大幅に削減し計算負荷を減らした。タスクによっては性能も向上。

#Section4：双方向RNN

過去の情報だけでなく未来の情報も加味したモデル。

実用例：文章の推敲、機械翻訳など

ベースとしてはSimple RNN、LSTM、GRUのどれでも使える。

#Section5：Seq2Seq

Encoder-Decoderモデルの一種。
発話から応答を生成するモデル。発話を日本語、応答を英語で学習させれば、日英翻訳になる。
Google翻訳の精度向上（2016/11）にも使われた。
[https://qiita.com/halhorn/items/646d323ac457715866d4](https://qiita.com/halhorn/items/646d323ac457715866d4)

用途：機械対話、機械翻訳など

##1. Encoder RNN

- Taking: 文章をトークン（トークンID）に分割
- Embedding: IDから分散ベクトルに変換
- Encoder RNN: ベクトルを順番にRNNに入力
- この出力（hidden state）と次の入力から、次の出力（hidden state）が作られる。
- トークン分繰り返し最後の出力（final state）をtought vectorと呼ぶ。

参考：[なぜ自然言語処理にとって単語の分散表現は重要なのか？](https://qiita.com/Hironsan/items/a58636f946dd51f670b0)

##2. Decorder RNN
Encoder RNNの逆で発話に対する応答を生成するモデル。

- Encoder RNNの出力（though vector）を入力。
- 各トークンの生成確率を出力。
- sampling: 生成確率に基づいてトークンをランダムに選択。
- Embedding: このトークンを次の入力とする。
- これを繰り返して文章を生成する。

##3. HRED

Seq2Seqは一問一答しかできない。文脈無視。
HREDでは前の$n-1$個の発話から、次の発話を生成する。

例）
システム：インコかわいいよね 。
ユーザー：うん
システム：インコかわいいのわかる 。

Seq2Seqだったら「うん」だけ見て発話を決めることになる。

構造：Seq2Seq+Context RNN

**Context RNN**

Context RNN: 各文章をまとめて、コンテキスト全体をベクトルに変換 。

＜課題＞
- 同じ文脈には似たような回答しかしない。
- 短い回答が多い。

##4. VHRED

- HREDの課題を解決。
- VAE（後述）の潜在変数の概念を追加

##5. VAE（Variational Auto Encoder）

###オートエンコーダ

- 教師なし学習
- 入力と同じ内容を出力

[Encoder] → [z（潜在変数）] → [Decoder]
zの次元が入力より減らせれば次元削減できたことになる。

###VAE

オートエンコーダーの潜在変数zに確率分布$z～N(0,1)$を仮定したもの。

#Section6：Word2Vec

RNNでは単語のような可変長のデータであっても固定長のデータとして扱うしかなかった。

**one-hotベクトル**で表すとボキャブラリー数分の次元からなるベクトルが出来る。
例えば、applesを表すには、以下のようにapplesに対応する箇所だけ1、他は全て0からなるベクトルが出来る。

1…apples
0…eat
0…I
0…like
0…to
︙

**重み行列**のサイズ

従来：ボキャブラリ数×ボキャブラリ数
Word2Vec：ボキャブラリ数×任意の単語ベクトル次元⇒計算量とメモリの大幅な削減

#Section7：Attention Mechanism

Seq2Seqは固定次元ベクトルに入力しなければならないので、長い文章は難しい。

**Attention Mechanism**
- 入力と出力のどの単語が関連しているのかを学習する。
- これにより文章の長さに応じて内部表現の次元を上げていく。
---

#確認テスト

#####Q1. サイズ 5 × 5の入力画像を、サイズ 3 × 3 のフィルタで畳み込んだ時の出力画像のサイズを答えよ。なおストライドは 2 、パディングは 1 とする。

#####A1. 3 x 3
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/93d55673-5d36-3f98-9d01-093afe2eb225.png)
画像の幅：$w$
フィルタの幅：$x$
パディング：$p$
ストライド：$s$
フィルタの枚数：$n$
（全体の幅） = （フィルタ１枚の幅） ＋（残りのフィルタ枚数）× （ストライド）
なので、

```math
\begin{align}
w + 2p &= x + (n-1)s\\
n &= \frac{w + 2p - x}{s}+1\\
&=\frac{5 + 2 - 3}{2}+1\\
&= 3
\end{align}
```
---
#####Q2. RNNのネットワークには大きくわけて 3 つの重みがある。1 つは入力から現在の中間層を定義する際にかけられる重み、1 つは中間から出力を定義する際にかけられる重みである。残り1 つの重みについて説明せよ。

#####A2. 中間層から次の中間層に伝えられる値に掛けられる重み。

#####Q3. 連鎖律の原理を使い、dz/dx を求めよ。

```math
\begin{align}
z = t^2\\
t = x +y\\
\end{align}
```

#####A3. 以下のとおり。

```math
\begin{align}
\frac{dz}{dx} &= \frac{dz}{dt}\frac{dt}{dx}\\
&=  2t\cdot 1\\
&= 2t\\
&= 2(x+y)
\end{align}
```

#####Q4. 下図のy 1 を x ・ s 0 ・ s 1 ・ w in ・ w ・ w out を用いて数式で表せ。
※バイアスは任意の文字で定義せよ。
※また中間層の出力にシグモイド関数 g(x)を作用させよ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318589/2d41e6d7-6b19-e7e0-351a-e56b627c07d8.png)

#####A5. 

$S_{1}$への入力$u_{1}$は、バイアスを$b$として、

```math
u_{1} = x_{1}W_{(in)} + s_{0}W + b
```

活性化関数を掛けると、

```math
z_{1} = g(u_{1}) = g(x_{1}W_{(in)} + s_{0}W + b)\\
```

となり、バイアスを$c$とすると、$y_{1}$は、

```math
\begin{align}
y_{1} &= g(W_{(out)}z_{1}+c)\\
\end{align}
```

#####Q6. シグモイド関数を微分した時、入力値が0 の時に最大値をとる。その値として正しいものを選択肢から選べ。

（1）0.15　（2）0.25　　（3）0.35　　（4）0.45

#####A6. (2)

シグモイド関数の微分は、$(1-sigmoid(u))sigmoid(u)$なので、0の時の値は、

```math
\begin{align}
(1-sigmoid(0))sigmoid(0) &= \Bigl(1-\frac{1}{1+e^{-0}}\Bigr)\frac{1}{1+e^{-0}}\\
&= \Bigl(1-\frac{1}{1+1}\Bigr)\frac{1}{1+1}\\
&=\frac{1}{4}
\end{align}
```
となる。
#####Q7. 以下の文章をLSTM に入力し空欄に当てはまる単語を予測したいとする。文中の「とても」という言葉は空欄の予測においてなくなっても影響を及ぼさないと考えられる。このような場合、どのゲートが作用すると考えられるか。

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

#####A07. 忘却ゲート

不要な情報をCECから消去するのが忘却ゲートの役割なので。

#####Q08. LSTMと CEC が抱える課題について、それぞれ簡潔に述べよ。

#####A08. 
LSTM : 計算負荷が高い。
　⇒解決策としてGRUが考案された。GRUでは構造を変更しパラメータを削減。
CEC : パラメータ更新が出来ない（学習ができない）
　⇒入力／出力ゲートでパラメータを可変可能にした。

#####Q9.LSTMと GRU の違いを簡潔に述べよ 。
 
#####A9. GRUはLSTMがパラメータが多く計算負荷が高い、という問題を構造を変えることにより解決したもの。

#####Q10. 下記の選択肢から、seq2seq について説明しているものを選べ。

（1）時刻に関して順方向と逆方向の RNN を構成し、それら 2 つの中間層表現を特徴量として利用するものである。
（2) RNN を用いた Encoder Decoder モデルの一種であり、機械翻訳などのモデルに使われる。
（3）構文木などの木構造に対して、隣接単語から表現ベクトル（フレーズ）を作るという演算を再帰的に行い（重みは共通）、文全体の表現ベクトルを得るニューラルネットワークである。
（4）RNN の一種であり、単純な RNN において問題となる勾配消失問題を CEC とゲートの概念を導入することで解決したものである。

#####A10. (2)

(1)は双方向RNN
(3)は調べたところ、Recurrent Neural Networkを木構造に用いたRecursive Neural Networkのことのようです。自然言語処理以外にも使われるとのこと。
(4)はLSTMモデル。CEC、入力ゲート、出力ゲート、忘却ゲート、覗き穴結合といった概念が出てきました。

#####Q11. seq2seqと HRED 、 HRED と VHRED の違いを簡潔に述べよ。

#####A11.
seq2seqは直前の文から発話を作成するもので、一問一答なら得意だが、文脈は無視している。HREDを$n-1$個の文のコンテキストから発話を作成するので、文脈に合った回答が出来る。

しかし、HREDは同じ文脈にはいつも似たような回答しかできなかったり、短すぎる不自然な回答が多かったりする。VHREDはVAEの潜在変数を用いてこれらの課題を解決したもの。特に同じ文脈でも異なった回答が出来るようになった。

#####Q12. VAEに関する下記の説明文中の空欄に当てはまる言葉を答えよ。
自己符号化器の潜在変数に＿＿＿を導入したもの。

#####A12. 確率分布 z～N(0,1)

これによってHREDの課題を解決したことは上記の通り。

#####Q13. RNNとword2vec 、seq2seq と Attention の違いを簡潔に述べよ。

#####A13. RNNとword2vec：RNNは重み行列がボキャブラリ×ボキャブラリになるのに対し、word2vecではボキャブラリ×任意の次元なので現実的な計算量に抑えられる。seq2seqとseq2seq+Attention：seq2seqは固定長しか入力できないため長文の扱いが難しいが、seq2seq+Attentionでは可変長が取り扱える。