深層学習Day3　ラビットチャレンジ

Section 0 CNNの復習
サイズ5x5の入力画像を3x3のサイズのフィルタで畳み込んだときの出力画像サイズ、パディングは1、ストライド2
地道に数えれば3x3。公式的には
{(高さ(幅)＋パディング*2-フィルタ高さ(幅))/ストライド}+1　なので
{(5+1*2-3)/2}+1=3 なので3x3行列で出力される。

Section１：再帰型ニューラルネットワークの概念 14:00
・RNN (recurrent neural network)　時系列データに対応可能なニューラルネットワーク。時系列データとは、時間的順序を追って一定間隔ごとに観察され、しかも相互に統計的依存関係が認められるようなデータの系列。音声データやテキストデータなど。24:48
・時間的つながりをうまく勉強させるために中間層に当たるところに、ループをおいて、入力層からの情報を中間層で処理し、出力したものを、再度入力して、前の時間の中間層からの出力を用いる。中間層はその１つ前の時間での中間層の出力を用いるが、実際にはt-1の中間層がt-2の情報も得ている。33:26
・前の中間層の出力をどれくらい使うのか、という重みが出現する。
・RNNの数学的記述
順伝播：
ut = W(in)*xt + W zt-1 + bias (活性化関数fを通る前のもの)
zt = f(W(in)*xt + X zt-1  + bias)　= f(ut)　(活性化関数fを通ったあとのもの)
vt = W(out) * zt + c　(活性化関数gを通る前のもの)
yt = g(W(out)*zt + c) =g(vt)　(活性化関数gを通ったもの)
f,gは活性化関数
確認テスト 43:04　3つの重み。①入力から現在の中間層を定義する際にかけられる重み W(in) ②中間層から出力を定義する際にかけられる重みW(out ③ 中間層zt-1から次の時点の中間層ztへの重み。
・RNNの特徴
時系列モデルを扱うには、初期の状態と過去の時間t-1の状態を保持し、そこから次の時間でのtを再帰的に求める再帰構造(中間層が数珠つながりになっている)が必要になる。49:43
逆伝播もその時点数分やらなくてはならない。
・BPTT 1:18:46
Bach propagatino through time RNNにおける逆伝播　1:23:42 確認テスト1:33:32
・BPTTの数学的記述：RNNは3つ重みがあるので、3つの微分が必要。
入力層：dE/dW(in) = dE/du *  [dut/dW(in)]時間的にさかのぼって微分のT　＝ dt*[xt]時間的にさかのぼって微分のT　Eをuまで微分したところをdt deltaで表現しておく。[　]TはRNNで時間をさかのぼってすべて微分する、という意味。
出力層：dE/dW(out) = dE/dvt * [dvt/dW(out)]時間的にさかのぼって微分のT = δout,t * [Zt]時間的にさかのぼって微分のT
前の中間層：dE/dW(前の中間層からの重み) = dE/dut * [dut/dW]さかのぼって微分のT = dt｢ztｰ1]時間的にさかのぼって微分のT 1:57:59
確認テスト 2:08:00
先程の右辺のδtとまとめた微分の式は、dE/du(t) = dE/dv(t) * dv(t)/du(t) = dE/dv(t) * d{W(out) * f(u(t)) + c}/du(t)　＝f'(うt)＊WT (out) * δ out,t = δtとする。
・BPTTの全体像
BPTTの誤差関数にはt番目の出力およびt-1番目の出力どちらも含まれており、t-1番目とt番目の関係性があることが数式からも見て取れる。　そしてt-1番目の出力はさらにt-2番目の出力が出てきており、術つながりになっていることが確認できる。2:36:30
コード演習問題2:46:30　

RNNハンズオン
https://github.com/MasahitoKatsuki/RabbitChallenge/blob/main/handson3_1_simple_RNN.ipynb

RNN確認テスト
https://github.com/MasahitoKatsuki/RabbitChallenge/blob/main/20210708NNDay3RNN%E3%83%86%E3%82%B9%E3%83%88.ipynb

Section 2 LSTM 2:57:54
・RNNの課題：時系列を遡れば遡るほど、勾配が消失していく。長い時系列の学習が困難である。その解決として、tanh等の勾配消失問題に強い活性化関数を用いる、あるいは正則化を用いる等があるが、今回はネットワークの構造自体を勾配消失がおきづらい構造にする。その1つがLSTMがある。
・復習：sigmoid関数の微分値の最大値は0.25しかないので、それをかけていけば行くほどに勾配が消失していってしまう。
・勾配消失問題の逆として、勾配爆発があり、収束しなくなってしまう。勾配爆発を防ぐために、勾配クリッピングを行い、しきい値を超えたら勾配のノルムをしきい値に正規化する、ということもある。クリッピングした勾配は、勾配 * (しきい値/勾配ノルム)となる。 3:17:00
・LSTMの全体図  中間層にあるCEC(constant error carousel)が重要。RNNの問題点は、中間層に記憶を溜め込むわけだが、そのときに中間層が増えれば増えるほどに学習の過程で勾配が小さくなっていき勾配消失が起きてしまう。CECでは記憶することだけをもたせて、学習は分離する。そうすることで勾配がどんどん小さくなることを防ぐ。3:34:20
・勾配消失および勾配爆発の解決方法として、勾配が1であれば解決することができる。
・CECの課題：入力データについて、時間依存に関係なく一律である（ニューラルネットワークの学習特性が無いという事）。そのため、CECの周囲に学習機能を配置する。3:44:13
・入力ゲートと出力ゲートを追加する事で、それぞれのゲートへの入力値の重みを、重み行列で可変とする（CECの課題を解決）
・入力ゲートからの情報と、入力からの情報を混ぜでCECに入力する。イメージとしては、入力された情報を、「こんな感じで覚えてね」とCECに教える役割。
・出力ゲート　CECが出力した情報をどのように用いるかを決めるフィルター。3:47:40
・入力値と出力値をもとに、入力ゲートと出力ゲートに調整がかかる。Wは今回の入力からどれくらいゲートを調整するかに用いる重み、Uは今回の出力からゲートをどのように調整するかの重み。3:53:45
・忘却ゲート；LSTMブロックの課題を解決する。
LSTMの現状；CECはすべての過去の情報を記憶している。　課題；過去の情報が要らなくなった場合、削除することはできず、保管され続ける。　解決策；過去の情報が要らなくなった場合、そのタイミングで情報を忘却する機能が必要。3:58:00
・忘却ゲートも、入力値と出力力重みWUを用いて調整する。
・覗き穴結合：CEC自身の値に重み行列を介して伝播可能にした構造（実際にはあまり大きな効果の改善は見られない。）4:12:45

LSTMハンズオン
https://github.com/MasahitoKatsuki/RabbitChallenge/blob/main/3_1_simple_RNN_after.ipynb

LSTM確認テスト
https://github.com/MasahitoKatsuki/RabbitChallenge/blob/main/20210708NNDay3LSTM%E3%83%86%E3%82%B9%E3%83%88.ipynb

Section３：GRU 4:25:00
・LSTMはパラメータが多く、計算が大変。そこでGRU。パラメータを大幅に削減して、精度は同等またはそれ以上望めるようになった。
・リセットゲートや更新ゲートがあり、隠れ層の状態をどのような状態で保持するのかを決めるゲート。
・確認テスト4:31:30 LSTMが抱える課題：入力ゲート、出力ゲート、忘却ゲート、CECの４つの部品があり、計算量が多い。　CECが抱える課題：記憶のみで学習ができない。
・確認テストLSTMとGRUの違い：入力ゲート、出力ゲート、忘却ゲート＋CEC。GRUは更新ゲート、リセットゲートの２つ。パラメータの数はLSTMよりGRUのほうが少ないので、計算量が少なくて良い。　4:42:8

GRUハンズオン
https://github.com/MasahitoKatsuki/RabbitChallenge/blob/main/handson_predict_word.ipynb

GRU確認テスト
https://github.com/MasahitoKatsuki/RabbitChallenge/blob/main/20210708NNDay3GRU%E3%83%86%E3%82%B9%E3%83%88.ipynb

Section４：双方向RNN 4:48:12
・Bidirectional RNN 過去の情報だけでなく、未来の情報を加味することで、精度を向上させるためのモデル。実用例として文章の推敲や機械翻訳など。
・過去の流れだけでなく、将来の流れからも現時点での予測ができるため、文章の推定などで良い結果が出やすい。
ハンズオン該当なし、確認テスト該当なし

Section５：Seq2Seq 4:57:02
・Sequence to sequenceは自然言語処理用のネットワークで、自然言語処理(機械対話や翻訳)に用いられる。
・Seq2SeqはEndocder-decoderモデルの1種。（時系列データを入力に取って時系列のデータを出力するモデル）
・入力された文章を隠れ層を通して、意味を理解する。(文脈Cとする)この文脈をもとに、新たな隠れそうで他の言語で出力する。文脈を読み取るのをエンコーダー、出力するのはデコーダー。
5-1　Encoder RNN 5:01:04
・文の意味を集約する。ユーザーがインプットしたテキストデータを単語のトークンに区切って渡す構造。
・Taking；文章を単語などのトークンごとに分割し、トークンごとのIDに分割する。
・Embedding；辞書配列に番号を振る(通常数万から数十万)ことで、もじそれぞれをワンホットベクトル(大きさは辞書の数だけの列数)で表現し、それをembeddingで数百単位に落とし込む。単語の意味が似ているものを似通ったembedding layerとして抽出する。すなわち、IDからそのトークンを表す分散表現ベクトルに変換する。
・この2つの仮定は特徴量抽出。
・Encoder RNN; vec1をRNNに入力し、hidden stateを出力する。このhidden stateと次の入力vec2をまたRNNに入力してきたhiddenstateを出力、という内容を繰り返す。
・最後のvecを入れたときのhidden stateをfinal stateとしてとっておく。このfinal stateがthought vectorと呼ばれ、入力した文の意味を表すベクトルとなる。5:09:04
・BERTなどの最近の自然言語処理モデルはMLM(masked language model)による。
　私　は　昨日　ラーメン　を　たべ　ました　という文のうち、1つを隠し、前後の単語からそこに何が入るのかを予測させる。これにより単語ごとの意味ベクトルが同じ様になっていく。特に、人間がラベリングしなくてもある程度教師なし学習が一気に進むことができrる。
5-2 Decoder RNN 5:17:08
・システムがアウトプットデータを単語のトークンごとに生成する構造。
・1Decoder RNNではEncoder RNNの final state(thought vector)から、各tokenの生成確率を出力していく。　Final stateをdecoder RNNのinitial stateとして設定し、embeddingを入力。
・2Sampling：生成確率にもとづいてtokenをランダムに選ぶ。
・3Embedding：2で選ばれたtokenをembeddingしてdecoder RNNへの次の入力とする。
・4 detokenize：1-3を繰り返し、2で得られたtokenを文字列に直します。5:20:49
5-3 HRED 5:27:10
・seq2seqの課題は　1問1答しかできない。問に対して文脈もなく、ただ応答が行われ続ける。
・HREDでは、過去n-1個の発話から次の発話を生成する。seq2seqは会話の文脈を無視して応答がなされたが、HREDでは前の単語の流れに即して応答されるため、より人間らしい文章が生成される。
・全体のイメージとしては、seq2seqのthought vectorをRNNのようにしてつないでいく。なので、seq2seq+context RNN。
・Context RNN: Encoderのまとめた各文章の系列をまとめて、これまでの会話コンテキスト全体を表すベクトルに変換する構造。これにより、過去の発話の履歴を加味した返答をすることができる。
・課題：HREDではは確率的な多様性が字面にしかなく、会話の流れのような多様性が無い。→おなじコンテキストを与えられても、答えの内容が毎回会話の流れとしては同じものしか出せない。
・課題；HREDは短く情報量に乏しい答えをしがちである。→短いよくある答えを学ぶ傾向がある　うん、そうだね　など。5:30:03
5-4 VHRED HREDの課題を克服したく、HREDにVAEの潜在変数の概念を追加したもの。
・オートエンコードは教師なし学習の一つ。訓練データのみで教師データは利用しない。
・オートエンコーダ構造はEndocer、decoderを介す潜在変数zがある。zはデータ数が小さく次元削減ができている。
・VAE variational autoencorder、通常のオートエンコーダでは何かしら潜在変数ｚに情報を押し込めているものの、その構造がどのような常態化はわからない。VAEはこの潜在変数zに正規確率分布z~N(0,1)を仮定したもの。
→VAE はデータを潜在変数zの確率分布という構造に押し込めることを可能にする。これにより汎用性があがる。

確認テスト
https://github.com/MasahitoKatsuki/RabbitChallenge/blob/main/20210708NNDay3seq2seq%E3%83%86%E3%82%B9%E3%83%88.ipynb

Section６：Word2vec 5:45:07
・RNNでは単語のような可変長の文字列をNNに与えることはできない。→固定長形式で単語を表現する必要がある。
・メリット；大規模データの分散表現の学習が、現実的な計算速度とメモリ量で実現可能となった。
・ボキャブラリx任意の単語のベクトル表現（単語の変換表）を機械学習で学習しかけることで、計算速度を向上できる。

Section７：Attention Mechanism 1:51
・seq2seq の問題は長い文章への対応が難しい→seq2seqでは2単語でも、100単語でも、固定次元ベクトルの中に入力しなければならない。
・解決策：文章が長くなるほどそのシーケンスの内部表現の次元も大きくなっていく仕組みが必要
→Attention Mechanism：「入力と出力のどの単語が関連しているのか」の関連度を学習する仕組み。重要なところと重要でないところを自動で見つける。
・近年特に性能が上がっている自然言語処理のモデルは全部attention mechanismである程強力。

確認テスト　RNNとword2vec、seq2seqとAttentionの違いを簡潔に述べよ。
RNNとWord2vec：RNNは時系列データを処理するのに適したNN
Word2vec:単語の分散表現ベクトルを得る手法
Seq2Seq:一つの時系列データから別の時系列データを得るネットワーク
Attention:時系列の中身に対して、関連性に重みをつける手法