くますきIT日記

IT系資格、競技プログラミングの情報を書いていきます。

E資格の勉強⑤深層学習day3

目次

本投稿の目的

深層学習(day3)に関する学習のまとめ

Section1:再帰ニューラルネットワークの概念

【要点】

再帰ニューラルネットワーク

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

 時系列データ=データに前後関係がある。例えばボードゲーム

 今の盤面は「直前(一手前)の盤面」の延長。さらに「直前(一手前)の盤面」は「直前(二手前)の盤面」の延長・・。

 この時系列を考慮するために、3つの重みを使用する。

 ①入力→中間層の重み。

 ②入力→出力層の重み。

 ③ひとつ前の中間層→中間層の重み。(ここがRNNの特徴)

 この3つの重みを時系列データの開始時点→終了時点まで再帰的に処理する。

 ※技術者的には「recursive neural network = RNN」と覚えるとよさげ。

 

BPTT:

 時間をさかのぼる誤差逆伝搬。

 といっても特殊な事ではなく、微分の連鎖率を使用して、

 「最後の時間の誤差」→「最後-1の時間の誤差」・・→「最初の時間の誤差」

 を何度も求めることなく少ない計算で求めること。

 

【確認テスト】

RNNのネットワークには大きくわけて3つの重みがある。

1つは入力から現在の中間層を定義する際にかけられる重み、

1つは中間層から出力を定義する際にかけられる重みである。

残り1つの重みについて説明せよ。

(回答)

 【要点】に記載した③の部分。ひとつ前の中間層→中間層の重み。

 

【演習チャレンジ:再帰ニューラルネットワーク

以下は再帰ニューラルネットワークにおいて構文木を入力として再帰的に文全体の表現ベクトルを得るプログラムである。ただし、ニューラルネットワークの重みパラメータはグローバル変数として定義してあるものとし、_activation関数はなんらかの活性化関数であるとする。木構造再帰的な辞書で定義してあり、rootが最も外側の辞書であると仮定する。(く)にあてはまるのはどれか。

(1)W.dot(left + right)

(2)W.dot(np.concatenate([left, right]))

(3)W.dot(left * right)

(4)W.dot(np.maximum(left, right))

 →答え:(2)。木構造のルートの右側と左側の一覧を全て抜き出し、結合したリストを活性化関数に使う。※「+」や「*」をしてしまうと、単語間の前後の繋がりを失ってしまう。

 

【演習チャレンジ:BPTT】

左の図はBPTTを行うプログラムである。

なお簡単化のため活性化関数は恒等関数であるとする。

また、calculate_dout関数は損失関数を出力に関して偏微分した値を返す関数であるとする。(お)にあてはまるのはどれか。

(1)delta_t.dot(W)

(2)delta_t.dot(U)

(3)delta_t.dot(V)

(4)delta_t* V

 →答え:(2)。過去にさかのぼるたびにUを掛ける必要がある。

 

【実装演習】

サンプルプログラムの実行結果。

①サンプルプログラムをそのまま実行。(中間層の活性化関数=シグモイド関数)

iters:0
Loss:1.4592344781314095
Pred:[1 1 1 1 1 1 1 1]
True:[0 1 1 0 1 1 1 0]
59 + 51 = 255
------------
iters:100
Loss:1.0581959125913671
Pred:[0 1 1 0 0 0 0 0]
True:[1 0 1 0 0 0 1 1]
47 + 116 = 96
------------
iters:200
Loss:0.8673602168782221
Pred:[0 1 1 0 0 0 1 0]
True:[0 1 0 0 0 0 1 1]
12 + 55 = 98
------------



------------
iters:9800
Loss:0.0012348486845701505
Pred:[1 1 0 0 0 1 0 1]
True:[1 1 0 0 0 1 0 1]
116 + 81 = 197
------------
iters:9900
Loss:0.0011690369308675372
Pred:[1 0 1 0 0 0 0 1]
True:[1 0 1 0 0 0 0 1]
120 + 41 = 161

→最終的に、誤差が0.001近くまで減少している。そして予測[Pred]と答え「True」が全て一致している(=正しく学習できている)。

 

②中間層の活性化関数をシグモイド関数 → ReLuに変更してみた。

iters:0
Loss:1.877133925079352
Pred:[0 0 0 0 0 0 0 0]
True:[1 0 0 1 0 0 1 1]
83 + 64 = 0
------------
iters:100
Loss:1.4036311687506768
Pred:[1 1 0 1 1 0 0 0]
True:[1 0 0 1 0 0 0 0]
104 + 40 = 216
------------
iters:200
Loss:1.0
Pred:[1 1 1 1 1 1 1 1]
True:[0 1 1 1 1 0 1 1]
6 + 117 = 255
------------



------------
iters:9800
Loss:2.0
Pred:[1 1 1 1 1 1 0 1]
True:[1 0 1 0 1 0 1 1]
117 + 54 = 253
------------
iters:9900
Loss:2.25
Pred:[1 1 1 1 1 1 0 0]
True:[0 1 1 0 0 0 0 0]
92 + 4 = 252
------------

→誤差が減っていない。最終的な精度も良くない。

 (=勾配の消失か発散が発生している?)

 誤差の推移を見た結果、大きな上下を繰り返している。

 勾配の消失?おそらく違う。消失なら、誤差が概ね一定になるはず。

 勾配が発散?おそらく当たっている。勾配爆発が発生していると考えられる。

(誤差の推移)
――――――――――――――――――――――――――

f:id:you_it_blog:20211107212139p:plain

――――――――――――――――――――――――――

 

Section2:LSTM

【要点】

RNNの課題:

 時系列が多い → 中間層が多い、という状態と同じ。

 →時系列が長いほど、初めの部分が出力層から遠くなる。

  →勾配消失問題が発生する。

   →活性化関数の変更や正則化などの対応と異なり、構造自体の変更で対応したものがLSTM。

 

LSTM:

 以下の部品を使用する。

  ・CEC勾配を1とした自己ループを行うゲート(勾配が1なら勾配は消失も発散もしない)

  ・入力ゲート、出力ゲート:CECの欠点(学習が行えない)に対応するため、設けられた層。

  ・忘却ゲート:CECが保持している情報の内、不要となった情報を削除するための層。

 

【確認テスト:RNNの課題】

シグモイド関数微分した時、入力値が0の時に最大値をとる。

その値として正しいものを選択肢から選べ。

(1)0.15

(2)0.25

(3)0.35

(4)0.45

 →答え:(2)。最大でも0.25なので、例えば3回さかのぼる場合、勾配は最大でも0.25^2≒0.0015まで小さくなる。

  中間層(RNNの場合時系列)が多いほど勾配が消えることが分かる。

 

【確認テスト:LSTM】

以下の文章をLSTMに入力し空欄に当てはまる単語を予測したいとする。

文中の「とても」という言葉は空欄の予測においてなくなっても影響を及ぼさないと

考えられる。このような場合、どのゲートが作用すると考えられるか。

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

 →答え:忘却ゲート。

 

【演習チャレンジ:RNNの課題】

RNNや深いモデルでは勾配の消失または爆発が起こる傾向がある。

勾配爆発を防ぐために勾配のクリッピングを行うという手法がある。

具体的には勾配のノルムがしきい値を超えたら、勾配のノルムをしきい値に正規化するというものである。

以下は勾配のクリッピングを行う関数である。(さ)にあてはまるのはどれか。

(1)gradient * rate

(2)gradient / norm

(3)gradient / threshold

(4)np.maximum(gradient, threshold)

 →答え:(1)。値が大きすぎる(ノルムを超える)場合、正規化されるという内容から推測できる。

 

【演習チャレンジ:LSTM】

以下のプログラムはLSTMの順伝播を行うプログラムである。

ただし_sigmoid関数は要素ごとにシグモイド関数を作用させる関数である。

(け)にあてはまるのはどれか。

(1)output_gate* a + forget_gate* c

(2)forget_gate* a + output_gate* c

(3)input_gate* a + forget_gate* c

(4)forget_gate* a + input_gate* c

 →答え:(3)。

 

Section3:GRU

【要点】

LSTMの課題:

 パラメータ数が多く、計算の負荷が高い。この課題に対応するための構造がGRU。

GRU:

 ゲート付き回帰ユニット。リセットゲート、更新ゲートと呼ばれる2つのゲートを持つ。(LSTMより1つゲートが少ない)

 LSTMと同等以上の精度、かつパラメータ(重み)の数を減らした構造。

 

【確認テスト:LSTMの課題】

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

 →答え:

   LSTM:パラメータ数が多く、計算の負荷が高い。

   CEC:学習ができない。(結果、入力、出力ゲートが必要になる)

 

【確認テスト:GRU】

LSTMとGRUの違いを簡潔に述べよ。

 →答え:ゲート数が異なる。(LSTM:3ゲート、GRU:2ゲート)

     また、GRUの方が軽量である。

 

【演習チャレンジ】

GRU(Gated Recurrent Unit)もLSTMと同様にRNNの一種であり、

単純なRNNにおいて問題となる勾配消失問題を解決し、長期的な依存関係を学習することができる。

LSTMに比べ変数の数やゲートの数が少なく、より単純なモデルであるが、

タスクによってはLSTMより良い性能を発揮する。以下のプログラムはGRUの順伝播を行うプログラムである。

ただし_sigmoid関数は要素ごとにシグモイド関数を作用させる関数である。

(こ)にあてはまるのはどれか。

(1)z * h_bar

(2)(1-z) * h_bar

(3)z * h * h_bar

(4)(1-z) * h + z * h_bar

 →答え:4。新しい中間状態は、1ステップ前の中間表現と計算された中間表現の線形和で表現される。つまり更新ゲートzを用いて、(1-z) * h + z * h_barと書ける。

 

Section4:双方向RNN

【要点】

双方向RNN:

 双方向、つまり過去だけでなく未来の情報も考慮することで精度を向上させるモデル。文章の翻訳などに使用される。(文章の場合で説明すると、翻訳に「直前の文脈」だけでなく、「直後の文脈」も使用しよう、というモデル)

 

 

【演習チャレンジ】

以下は双方向RNNの順伝播を行うプログラムである。

順方向については、入力から中間層への重みW_f, 一ステップ前の中間層出力から中間層への重みをU_f、逆方向に関しては同様にパラメータW_b, U_bを持ち、両者の中間層表現を合わせた特徴から出力層への重みはVである。

_rnn関数はRNNの順伝播を表し中間層の系列を返す関数であるとする。

(か)にあてはまるのはどれか

(1)h_f + h_b[::-1]

(2)h_f * h_b[::-1]

(3)np.concatenate([h_f, h_b[::-1]], axis=0)

(4)np.concatenate([h_f, h_b[::-1]], axis=1)

 →答え:4。まず、「+」や「*」では前後の特徴が混ざってしまう。=concatenateを使用するべき。次に、「h_f(過去→未来)」のデータと「h_b[-1](未来→過去の反転)」のデータを結合するため、axis=1とする。これにより、例えば1,2,3というデータの場合、以下のような行列を作成できる。

 [1(過去→未来方向)、1(未来→過去方向)],

 [2(過去→未来方向)、2(未来→過去方向)],

 [3(過去→未来方向)、3(未来→過去方向)]

 

【参考】

引数(axis)のイメージ:

deepage.net

 

Section5:seq2seq

【要点】

seq2seq:

 Encoder-Decoderモデルの一種。以下2つの深層学習モデルで構成される。

  ・入力を中間表現(圧縮したベクトル)に変換(encode)するモデル(Encoder-RNN)。

  ・中間表現(圧縮したベクトル)を変換(decode) して出力を作成するモデル(Decoder-RNN)。

 

Encoder-RNN:

 入力(例えば、テキストデータ)を、単語等のトークンに区切って渡す。

 Taking:文章を単語等のトークン毎に分割し、トークンごとのIDに分割する。

 Embedding:上記のIDから、そのトークンを表す分散表現ベクトルに変換する。

Decoder-RNN:

 Encoder-RNNの個々の出力を受け取り、出力するデータを生成する。

 

seq2seqの課題:

 最終の入力に対する一問一答しかできない。それまでの文脈などが考慮できない。

 →HRED、VHRED、VAE等の会話モデルがある。

 

HRED:

 過去n-1の入力から次の出力を生成できる。

 →最終の入力が「はい」や「いいえ」でも、直前の入力から適切な出力が行える可能性がある。(seq2seqより人間らしいやり取りができる)

 →課題。同じ流れの会話には同じ回答しかできない。短い回答(Yes、No)などを選びがち。

 

VHRED:

 HREDに、VAEの潜在変数の概念を追加して、HREDの課題に対応したもの。

 

VAE:

 Variational Autoencoder(変動オートエンコーダー) 。

 データを潜在変数zの確率分布という構造に押し込めることができる。

 (以下のリンクを読むと分かる) 

qiita.com

 

【確認テスト:seq2seq】

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

(1)時刻に関して順方向と逆方向のRNNを構成し、それら2つの中間層表現を特徴量として利用するものである。

(2)RNNを用いたEncoder-Decoderモデルの一種であり、機械翻訳などのモデルに使われる。

(3)構文木などの木構造に対して、隣接単語から表現ベクトル(フレーズ)を作るという演算を再帰的に行い(重みは共通)、文全体の表現ベクトルを得るニューラルネットワークである。

(4)RNNの一種であり、単純なRNNにおいて問題となる勾配消失問題をCECとゲートの概念を導入することで解決したものである。

 →答え:2。(1は双方向RNN。3は純粋なRNN。4はLSTM)

 

【確認テスト:VHRED】

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

 →答え:

  seq2seqとHRED:seq2seqは一問一答。HREDは直前の入力を使用した出力が可能。

  HREDとVHRED:HREDは短い回答が多い。また、同じ流れの場合同じ回答。VHREDはVAEにてHREDの課題に対応する。

 

【演習チャレンジ:seq2seq】

演習チャレンジ機械翻訳タスクにおいて、入力は複数の単語から成る文(文章)であり、それぞれの単語はone-hotベクトルで表現されている。

Encoderにおいて、それらの単語は単語埋め込みにより特徴量に変換され、そこからRNNによって(一般にはLSTMを使うことが多い)時系列の情報をもつ特徴へとエンコードされる。

以下は、入力である文(文章)を時系列の情報をもつ特徴量へとエンコードする関数である。ただし_activation関数はなんらかの活性化関数を表すとする。

(き)にあてはまるのはどれか。

(1)E.dot(w)

(2)E.T.dot(w)

(3)w.dot(E.T)

(4)E * w

 →答え:1。Eは単語の埋め込みの一覧表(word embedding matrix)。単語ごとの特徴ベクトルが書かれた表のイメージ。この特徴ベクトルと重みを掛けた値を返せばよい。

 

【確認テスト:VAE】

VAEに関する下記の説明文中の空欄に当てはまる言葉を答えよ。

自己符号化器の潜在変数に____を導入したもの。

 →答え:確率分布z∼N(0,1)

 

Section6:Word2vec

【要点】

word2vec:

 文字は人間が作成した単なる記号であり、金額や色(RGBA)、物のサイズのような大小関係や連続性が無い = 文字のままではNNに使用できない。

 各単語をone-hotベクトル※に変換する必要がある。が、世界中の全単語をone-hotベクトルする事は物理的に不可能、かつ、one-hotベクトルでは単語の類似度などを把握できない。

 ※one-hot ベクトル:1つの成分が1、残りの成分は全て0のベクトル。

 word2vecは「単語の確率分布は、周辺の単語によって決定される」という分布の仮説に基づいて、単語をone-hotベクトルでないベクトルに変換する方法。

 

Section7:Attention Mechanism

【要点】

Attention Mechanism:

 sec2secは中間表現(圧縮したベクトル)を使用して出力を作成する。

 →中間表現(圧縮したベクトル)はサイズが決まっているので、入力が短い文章でも、長い文章でも使用できるベクトルの次元数は同じ。

  →長文に弱い。(表現を持ちきれない)

   →中間表現(圧縮したベクトル)を使用して出力を作成するタイミングで、元々の入力を参照できるようにする方法。

 

【確認テスト】

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

 →答え:

  RNNは時系列データに対応可能なニューラルネットワーク。処理対象だけでなく、処理対象の前のデータ(中間層の出力)も用いて、処理に使用する。

  ※直前~現在の流れを考慮した処理を行える。

  word2vecは文章(単なる人が作成した記号であり、NNで利用するにはベクトルに直す必要がある)をone-hot-ベクトルでなく、単語ごとの関連性を持たせたベクトルに変換する手法。

  seq2seq:Encoder-Decoderモデルの一種。2つのNNを持ち、文字に対する一問一答が可能である。

  Attention:seq2seqの課題(長文に弱い)に対応するために、seq2seqのDecoderへの入力として、「Encoderの成果物」に加えて、「入力」も使用して、入力データに柔軟なを可能とする