DNN_後編1 (要点)

#Section1：再帰型ニューラルネットワーク（RNN）の概念
RNNは、自然言語処理と一緒に成長してきた。

###Section1-1：RNN全体像
####Section1-1-1：RNNとは
RNN：時系列データに対応可能なニューラルネットワーク。

####Section1-1-2：時系列データ
時系列データ：時間的順序を追って、一定間隔ごとに観察され、しかも相互に統計的依存関係が認められるようなデータの系列

例）　音声データ、テキストデータ、株価のデータ

####Section1-1-3：RNNについて
中間層が重要な意味を持っている。

中間層は、入力Xに対してSが出力されるとする。
この出力されたSが、次のデータXの中間層を計算する際に用いられる。

つまり、$x_{n}$の中間層での出力値Sが、次のデータ$x_{n+1}$の中間層の計算の際に、使われる事になる。


RNNの特徴：
時系列モデルを扱うには、初期の状態と過去の時間t-1の状態を保持し、そこから次の時間でのtを再帰的に求める再帰構造が必要になる。
これまで講義で扱った通常のNNやCNNは、あくまでデータ1つ1つに対してのネットワークになっていたので、
データ同士は独立したものになっていたが、
RNNは、直前のデータの影響も受けるようなネットワーク構造になっている。


###Section1-2：BPTT
####Section1-2-1：BPTTとは
BPTT：backpropgation through time	
誤差伝播法の一種。RNNにおいてのパラメータ調整方法の一種。

####Section1-2-2：BPTTの数学的記述
基本的なところは、勾配降下法と同じ考え方。
但し、重みが、$w_{in}$, w, $w_{out}$と、バイアスが、$w_{in}$, $w_{out}$に対して、それぞれあるので（バイアスは合計2つ）、それぞれに対して計算する必要がある。


####Section1-2-3：BPTTの全体像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435761/f25ef255-086d-a93d-cb0c-8241ed58875c.png)
数式を確認すれば分かる通り、基本的なところは勾配降下法と同じ考え方。
総和Zの値を求める時に、BPTT特有の計算がある事が分かる($W*z^{t-1}$)。


#Section2：LSTM
RNNの課題：
時系列を遡れば遡るほど、勾配が消失していく。つまり、長い時系列の学習が困難。

これまでの講義でやったように、勾配消失問題の解決として、活性化関数(ReLU)や初期値の設定（Xavier,He）、バッチ正規化などでは、RNNの勾配消失は解決が難しい。そこで考えられたのがLSTM。

LSTMは活性化関数の工夫や、初期値の設定など、各処理の内容を工夫するのではなく、構造自体を変えてしまって、RNNの勾配消失問題を解決した。

勾配爆発：
勾配が、層を逆伝播するごとに指数関数的に大きくなっていく現象（勾配消失問題の逆パターン）。

###Section2-1：CEC
CEC：
勾配消失、勾配爆発の解決方法として導入された方法。
考え方は単純で、勾配が1であり続ければ、勾配消失、勾配爆発が防げるという考え方。

課題：
入力データについて時間の依存度に関係なく、重みが一律。
つまり、NNの学習特性が無いという事になる。
これらの課題を解決するために、次の入力ゲート、出力ゲートが考えられた。

###Section2-2：入力ゲートと出力ゲート
入力・出力ゲートの役割：
入力ゲート・出力ゲートを追加する事で、
それぞれのゲートへの入力値の重みを
重み行列W,Uで可変可能とする。

これにより、重みが一律ではなくなるので、CECの課題は解決される。

###Section2-3：忘却ゲート
LSTMの現状：
CECは、過去の情報全てが保管されている。

課題：
過去の情報が不要になった場合に、削除する事が出来ず、保管され続ける。

解決策：
過去の情報が不要になった場合に、そのタイミングで情報を忘れる機能が必要。
そこで考えられたのが、忘却ゲート。

###Section2-4：覗き穴結合
課題：
　CECの保存されている過去の情報を、任意のタイミングで、他のノードに伝播させたり、
　あるいは任意のタイミングで忘却させたい。
　CEC自身の値は、入力ゲートや忘却ゲート、出力ゲートに影響を与えている訳ではない。
→解決策として覗き穴結合がある。

覗き穴結合：
　CEC自身の値に、重み行列を介して伝播可能にした構造で、入力ゲートや忘却ゲート、出力ゲートに間接的に影響を与える事が出来る。

#Section3：GRU
LSTMの課題：
　パラメータ数が多く、計算負荷が高くなる。
→解決策として、GRUがある。

GRU：
LSTMの構造自体を変えたもの。
LSTMに比べて、パラメータを大幅に削減し、かつ、精度はLSTMと同等またはそれ以上が望めるようになった構造。
LSTMに比べると計算負荷が低い。


#Section4：双方向RNN
通常のRNNでは、現在の情報に加えて、過去の情報を加味するような構造になっていたが、
双方向RNNでは、それに加えて、未来の情報も加味して、精度を向上させるためのモデル。
未来の情報も加味するため、オンラインで推定を行う場合は使えない。

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


#Section5：Seq2Seq
Encoder-Decoderモデルの一種を指す。

具体的な用途：
機械対話、機械翻訳など。

###Section5-1：Encoder RNN
ユーザがインプットしたテキストデータを、単語などのトークンに区切って渡す構造。

Taking：文章を単語などのトークン毎に分割し、トークンごとのIDに分割する。
Embadding：IDから、そのトークンを表す分散表現ベクトルに変換（文字を数値に変換）。
Encoder RNN：ベクトルを順番にRNNに入力していく。

処理手順：
分散表現ベクトルにしたvec1をRNNに入力し、hidden stateを出力
→このhidden stateと次の入力である分散表現ベクトルvec2をRNNに入力、hidden stateを出力
→このhidden stateと次の入力である分散表現ベクトルvec3を....
→（繰り返し）
→最後の入力vec(n)をRNNに入力し、出力されたhidden stateをfinal stateとして取っておく。
　このfinal stateがthought vectorと呼ばれ、入力した文章の意味を表すベクトルになる。
→このthought vectorがdecoder側に渡される。


###Section5-2：Decoder RNN
システムがアウトプットデータを、単語などのトークンごとに生成する構造。

処理：
1
Encoder RNNの最後の値(final state[thought vector])から、各トークンの生成確率を出力していき、
Encoder RNNのfinal stateをDecoder RNNのinitial stateととして設定し、Embaddingを入力。
→
2
Smapling：生成確率に基づいてトークンをランダムに選ぶ。
→
3
Embedding：2(Sampling)で選ばれたトークンを、EmbaddingしてDecoder RNNへの、次の入力とする。
→
4
Detokenize：1～3を繰り返し、2で得られたトークンを文字列に直す。


###Section5-3：HRED
Seq2Seqの課題：
一問一答しか出来ない。
問に対して、文脈も何もなく、ただ応答が行われ続ける。
→
クイズやFAQのような、ある質問に対して答えるタスクについては使えるが、人間ぽい感じや、文脈に即した対応などは出来ない。

HRED：
過去(n-1)個の発話から、次の発話を生成する。
Seq2Seqでは、過去の会話の文脈を無視して応答がなされたが、
HREDでは、前の単語の流れに即して応答される。
→
より人間らしい文章が生成される（会話ぽい事が成り立つ）。


HREDの構造：
Seq2Seq + Context RNN

Context RNN：
Encoderのまとめた各文章の系列をまとめて、
これまでの会話コンテキスト全体を表すベクトルに変換する構造。
そうする事で、過去の発話の履歴を加味した応答が出来る。


HREDの課題：
HREDは確率的な多様性が字面にしかなく、
会話の「流れ」のような多様性がない。
→
同じコンテキスト（発話リスト）を与えられても、
毎回毎回同じ質問をすると、いつも同じ回答が返ってくる。
答えの内容が毎回会話の流れとしては同じものしか出せない。

HREDは短く情報量に乏しい答えをしがち。
例）　うん、そうだね、なるほど など。

###Section5-4：VHRED
VHRED：
HREDに、VAEの潜在変数の概念を追加したもの。
これにより、HREDの課題を、VAEの潜在変数の概念を追加する事で解決した構造。

VHREDでは、HREDの課題の中でも、毎回同じコンテキストを与えられた時に、毎回同じ回答をする。
というところが改善された。

VAE、潜在変数については、このあと説明する。


###Section5-5：VAE
####Section5-5-1：オートエンコーダー（自己符号化器）
オートエンコーダ：
教師なし学習の１つ。
教師なしなので、訓練データのみで学習を行う。
入力値に対して、ニューラルネットワークから出力される値は、入力値と同じ値。

例）
28x28の画像を入力として、入力したものと同じ画像を出力するニューラルネットワーク。
但し、入力画像は内部で一度圧縮されている（入力画像よりも情報が少ない状態）。


オートエンコーダの構造：
入力データから潜在変数zに変換するニューラルネットワークをEncoder（圧縮）。
逆に潜在変数zをインプットとして、元の画像を復元するニューラルネットワークをDecoder（解凍）。

オートエンコーダのメリット：
潜在変数zに変換する事で、次元削減が行える。


####Section5-5-2：VAE（変分自己符号化器）
VAE：
学習による近似推論を行い、勾配に基づく方法で訓練出来るモデル。


通常のオートエンコーダの場合、
何かしら潜在変数zにデータを押し込めているものの、
その構造がどのような状態か分からない。
→
VAEは、この潜在変数zに確率分布z～N(0,1)を仮定したもの。
→
VAEは、データを潜在変数zの確率分布という構造に押し込める事を可能にする。
それにより、オートエンコーダに比べて、多少構造が分かりやすくはなった。

#Section6：Word2vec
課題：
RNNでは、単語のような可変長の文字列をニューラルネットワークに与える事は出来ない。
→固定長形式で単語を表す必要がある。
→word2vecでは、可変長形式で単語を表す事が出来る。

word2vec：
・学習データからボキャブラリを作成。
例） I want to eat apples. I like apples.
という文章があった場合
{apples, eat, I, like, to, want}
という6語の辞書を作成する。

・one-hotベクトルを用いて、単語をベクトル化する（分散表現）。
該当する単語が「1」で、それ以外のベクトルは「0」になったベクトルで表現する。
例）上記の6語の単語の中で、applesを表現する場合は、

$\begin{pmatrix} apples \\\ eat \\\ I \\\ like \\\ to \\\ want \end{pmatrix} = \begin{pmatrix} 1 \\\ 0 \\\ 0 \\\ 0 \\\ 0 \\\ 0 \end{pmatrix}$

という表現になる。

メリット：
大規模データの分散表現の学習が
現実的な計算速度とメモリ量で実現可能になった。
→
これまでは（word2vec以前）、(ボキャブラリ)x(ボキャブラリ)の数だけの重み行列が誕生していた。
それに対しword2vecでは、(ボキャブラリ)x(任意の単語)のベクトル次元で重み行列が誕生する。

word2vecでは、次元が圧倒的に削減されたにも関わらず、その単語自体には意味を持った値を算出出来るところが大きなメリット。


#Section7：Attention Mechanism
課題：
seq2seqの問題は、長い文章への対応が困難。
seq2seqでは、2単語でも、100単語でも、
固定ベクトルの中に入力しなければならない。

解決策：
文章が長くなるほど、そのシーケンスの内部表現の次元も大きくなっていく仕組みが必要。

Attention Mechanism：
「入力と出力のどの単語が関連しているのか」
の関連度を学習する仕組み。
単語同士の関連度を学習するので、文章が長くなっても、少ない計算量で対応する事が出来る。