はじめに
ディープラーニングE資格(JDLA主催)のオンライン講座(ラビットチャレンジ)を受講したときの学習記録になります。
E資格の一通りの科目をカバーしています。学習の参考にしてください。
科目一覧
- 応用数学
- 機械学習
- 深層学習(day1)
- 深層学習(day2)
- 深層学習(day3) ←ココ
- 深層学習(day4)
Section1: 再帰型ニューラルネットワークの概念
1-1RNN全体像
1-1-1RNNとは
・前の中間層からの重みがある。
・中間層は1層である。
xからzの活性化関数に入る前のもの
f,gは活性化関数。関数f:u→z。関数g:v→y
zからyの活性化関数に入る前のもの
zからyの活性化関数から出てきたもの
Python
u[:,t+1] = np.dot(X, W_in) + np.dot(z[:,t].reshape(1, -1), W)
z[:,t+1] = functions.sigmoid(u[:,t+1])
np.dot(z[:,t+1].reshape(1, -1), W_out)
y[:,t] = functions.sigmoid(np.dot(z[:,t+1].reshape(1, -1), W_out))
Code language: Python (python)
Python u[:,t+1] = np.dot(X, W_in) + np.dot(z[:,t].reshape(1, -1), W) z[:,t+1] = functions.sigmoid(u[:,t+1]) np.dot(z[:,t+1].reshape(1, -1), W_out) y[:,t] = functions.sigmoid(np.dot(z[:,t+1].reshape(1, -1), W_out))
Python
u[:,t+1] = np.dot(X, W_in) + np.dot(z[:,t].reshape(1, -1), W)
z[:,t+1] = functions.sigmoid(u[:,t+1])
np.dot(z[:,t+1].reshape(1, -1), W_out)
y[:,t] = functions.sigmoid(np.dot(z[:,t+1].reshape(1, -1), W_out))
1-1-2時系列データ
・RNNの特徴
時系列モデルを扱うには、初期の状態と過去の時間t-1の状態を保持し、そこから次の時間でのtを再帰的に求める再帰構造が必要になる。
・simpleRNN
右側から左側へ増える2進数の加算を行う。過去の数と新しい数とその和がある。右側(=過去)から数が増えていって未来(=左側)の方向につながる。和を求めさせて未来へつながるように学習させるイメージ。
例では8単位時間分、学習を進めていく。
1-1-3RNNについて
演習問題
・再帰型ニューラルネットワークにおいて構文木を入力として再帰的に文全体の表現ベクトルを得るプログラムがある。ノード同士を結合するときには、文字列の連結を使用する。
例. W.dot(np.concatenate([left, right]))
文字列の文字数が増えすぎるのではないか?>重みを適用して、入力と出力側で同じ数に整えることで対処する。
1-2BPTT
BackPropagationThroughTimeの略。
RNNにおけるパラメータ調整の一例。
RNNの逆伝播
1-2-1BPTTとは誤差逆伝播法の復習
1-2-2BPTTの数学的記述
np.dot(X.T, delta[:,t].reshape(1,-1))
np.dot(z[:,t+1].reshape(-1,1), delta_out[:,t].reshape(-1,1))
np.dot(z[:,t].reshape(-1,1), delta[:,t].reshape(1,-1))
※はEを一気に微分したという意味である。
※Tは時間的に遡ることを意味する。転置のT(ブロック体で書く)とは違う意味である。
1-2-3BPTTの全体像
コードの考察
・simple RNNのコードについて
#入力層が2,中間層が16,出力層が1である。本編の解説と構成が違うから最初、紛らわしい。 #中間層に対する重みWの初期化。配列は(hidden_layer_size, hidden_layer_size)。つまり、中間層の数*中間層の数。 W = weight_init_std * np.random.randn(hidden_layer_size, hidden_layer_size) #微分した関数の省略表現のための初期化。配列の縦・横の数を数式と照合してチェックする。 delta_out = np.zeros((output_layer_size, binary_dim)) delta = np.zeros((hidden_layer_size, binary_dim + 1)) #reshapeの例 (行,列)の数値にてどちらかに-1を指定可能。指定するとその次元は自由になる。 z.reshape(-1) array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) z.reshape(-1, 2) array([[ 1, 2], [ 3, 4], [ 5, 6], [ 7, 8], [ 9, 10], [11, 12]]) #.Tの用例。二次元配列(行列)の転置 X.T #np.unit8の用例。格納するのに必要なメモリをビット数で明示的に指定する。 np.unit8:8ビットの符号なし整数で 0,…,255 の値np.float
32:32bit,いわゆる単精度の浮動小数点数を表す #unpackbitsの用例。特定の長さの整数配列をバイナリ配列に変換する。 binary = np.unpackbits(np.array([range(largest_number)],dtype=np.uint8).T,axis=1) #この例では、largest_number(ここではの10進数の整数)までのrangeの配列を(長さ8のビット配列)に変換する。 #後でbinaryに対してa_intをインデックスとして値を呼び出している。 a_int = np.random.randint(largest_number/2) a_bin = binary[a_int] # binary encoding #zeros_likeの例。元の配列と同じ形状の0で構成された配列を生成する。ここではW_inと同じshapeの配列。 np.zeros_like(W_in) #[:,1]の意味。2列目の配列を縦に取る。 data = np.array([[1,2,3], [4,5,6],[7,8,9]]) print(data[:,1]) array([[2,5,8]) #for文の省略の例 for x in Y[start:stop:step]: start番目からstopまで。stepだけ飛ばす。for c in P[1::2]:
print(c)
#Pythonのfor文でインデックスを同時に参照する:enumerate() #逆順(reverse)でリストをトラバースする例 for index,x in enumerate(reversed(out_bin)): out_int += x * pow(2, index) print(index,x) >>2 78
>>1 99
>> 0 16
#こういう具合にindexも逆順になる
確認テストの考察
・問題
サイズ5×5の入力画像を、サイズ3×3のフィルタで畳み込んだ時の出力画像のサイズを答えよ。なおストライドは2、パディングは1とする。(3分)
・問題
RNNのネットワークには大きくわけて3つの重みがある。1つは入力から現在の中間層を定義する際にかけられる重み、1つは中間層から出力を定義する際にかけられる重みである。残り1つの重みについて説明せよ。(3分)
・問題
連鎖律の原理を使い、dz/dxを求めよ。(5分)連鎖律の原理を使い、dz/dxを求めよ。
・問題
下図のy1をx・s0・s1・win・w・woutを用いて数式で表せ。※バイアスは任意の文字で定義せよ。※また中間層の出力にシグモイド関数g(x)を作用させよ。(7分
Section2: LSTM
・RNNの課題
時系列を遡れば遡るほど、勾配が消失していく。長い時系列の学習が困難。
前回の授業で触れた勾配消失の解決方法とは、別で、構造自体を変えて解決したものがLSTM。LSTMもRNNの一つである。
・演習チャレンジ
勾配のクリッピング。勾配爆発を防ぐもの。勾配のノルムがしきい値を超えたら、勾配のノルムをしきい値に正規化するもの。
コードの考察
#threshold = しきい値
#勾配のノルムを計算する
np.linalg.norm(grad)
#ノルムのほうがしきい値より大きい場合を判定する
rate = threshold/ norm
if rate < 1:
#勾配を正規化する
grad = grad*(threshold/ norm)
2-1 CEC
※CECとは。Constant Error Carousel(定誤差カルーセル、CEC)
考えることと記憶することを分離して、記憶することだけをCECが担う。RNNでは考えることも記憶することも一緒にしていた。結果、 勾配消失問題が起こった。
勾配が1であれば、勾配消失も勾配爆発も起きない。CECは勾配を1にする。
2-2 入力ゲートと出力ゲート
・入力ゲートはCECに対して、どんなふうに記憶してもらうか、決める。
赤(入力値と重みWi)と青(前回の中間層からの出力値と重みUi)の矢印が入力ゲートへ入る。重みで調整される。CECにどれくらい(=Vi)覚えてもらうかを決定する。
・出力ゲートはCECの記憶に対して、どんなふうにCECの記憶を使うか、決める。
赤(入力値と重みW0)と青(前回の中間層からの出力値と重みU0)の矢印が入力ゲートへ入る。重みで調整される。
2-3 忘却ゲート
CECは過去の記憶は保持し続ける。削除できない。忘却ゲートで解決。
数式
c(t)=i(t)*a(t)+f(t)*c(t-1)
CECの出力c(t)は今回の情報
i(t)はどの程度覚えるか。a(t)は入力。
f(t)はどの程度忘れるか。
c(t-1)は前の情報
2-4 覗き穴結合
CEC自身の値に、重み行列を介して伝播可能にした構造。
実際に効果はあまりない。
演習チャレンジの考察
・新しいセルの状態は、計算されたセルへの入力と1ステップ前のセルの状態に入力ゲート、忘却ゲートを掛けて足し合わせたものと表現される。つまり、input_gate* a + forget_gate* cである。
・numpy.hsplit()
: 横に分割
※(疑問): 下記がわからない。セルへの入力やゲートをまとめて計算し分離とある。
lstm_in = _activation(x.dot(W.T)+ prev_h.dot(U.T) + b)
a,i,f,o = np.hsplit(lstm_in,4)
確認テストの考察
・問題
シグモイド関数を微分した時、入力値が0の時に最大値をとる。その値として正しいものを選択肢から選べ。(1分)
(1)0.15(2)0.25(3)0.35(4)0.45
・答え
(2)
・考察
シグモイド関数のかわりに使われるものとして、Relu関数がある。
・問題
以下の文章をLSTMに入力し空欄に当てはまる単語を予測したいとする。文中の「とても」という言葉は空欄の予測においてなくなっても影響を及ぼさないと考えられる。このような場合、どのゲートが作用すると考えられるか。「映画おもしろかったね。ところで、とてもお腹が空いたから何か____。」(3分
・答え
忘却ゲート
・考察
不要な情報を削除するから、忘却ゲート。
Section3: GRU
LSTMの問題点は、パラメータが多すぎて複雑すぎた。
GRUのコンセプト:
パラメータを減らす。
精度をなるべく落とさない。
・隠れ層の状態を保存しておく。
h(t)=f(Wrx(t)+Ur*(r(t)*h(t-1))bh(t)))
リセットゲート
前回の情報と重みと今回の情報と重みと、バイアスを和算して出力する。
それをシグモイド関数に代入して出力する。
更新ゲート
前回の情報と重みと今回の情報と重みと、バイアスを和算してztとして出力する。
zt*h(t-1)と(1-zt)(t-1)を求めて、和を出力する。
確認テストの考察
・問題
LSTMとCECが抱える課題について、それぞれ簡潔に述べよ。(3分)
・答え
複雑で計算量が多くなった。
・考察
機械学習の分野では、複雑で計算量が多いモデルをよりコストが低いモデルに改良するプロセスがよく行われてきた。
・問題
LSTMとGRUの違いを簡潔に述べよ。(5分)
・答え
GRUは以下の点が違う。
CECがなくなった。忘却ゲートがなくなった。入力ゲート・出力ゲートはなくなり、更新ゲート・リセットゲートがある。
パラメータが少ない。計算コストが減った。
Section4: 双方向RNN
過去の情報だけでなく、未来の情報も持たせて精度を向上させるモデル。
例: 機械翻訳。過去も未来も情報を使う。
演習チャレンジの考察
・問題
以下は双方向RNNの順伝播を行うプログラムである。順方向については、入力から中間層への重みW_f, 一ステップ前の中間層出力から中間層への重みをU_f、逆方向に関しては同様にパラメータW_b, U_bを持ち、両者の中間層表現を合わせた特徴から出力層への重みはVである。_rnn関数はRNNの順伝播を表し中間層の系列を返す関数であるとする。(か)にあてはまるのはどれか
・答え
双方向RNNでは、順方向と逆方向に伝播したときの中間層表現をあわせたものが特徴量となるので、np.concatenate([h_f, h_b[::-1]], axis=1)である。
(4)np.concatenate([h_f, h_b[::-1]], axis=1)
※np.concatenate axis=0の場合は2つの配列([a,b,c,d]と[x,y,z,v])を一つにする。[a,b,c,d,x,y,z,v]。axis=1の場合は、[[a,x],[b,y],[c,z],[d,v]]
※[::-1]は後ろからステップ1のスライスを行う
確認テストの考察
Section5: Seq2Seq
・Seq2Seqについて
2つのネットワークがドッキング。その間に”C 文脈”がある。自然言語処理に使う。機械翻訳など。
Encoder RNN:
単語を入力すると中間層に入る。順次、行う。
それまでに入力された情報が蓄積される。
文脈:
意味が保持される。Decorderに渡される。
Decorder RNN:
逆に、意味を解釈する。
5-1 Encoder RNN
ユーザーが入力したテキストデータを単語等のトークンに区切って渡す構造。
Taking:
単語ごと、トークンごとにIDを割り振る。
one-hot Encodingをして上記をベクトル化する。0 > [00000] , 1> [00001] , 2> [00011] ※ベクトルの大きさは10000くらいなど。単語が1万くらいあるから。
Embedding:配列の省略をする(Embedding表現をする)。[1,0,0, … 0] > [0.2 0.4 0.6 … 0.1] ※ベクトルの大きさは数百に収める。上記ベクトルに関連した内容でベクトルを作り直す。機械学習を使うことがある。
Encorder RNN:
vec1をRNNに入力し、hidden_stateを出力。このhidden_stateと次の入力vec2をまたRNNに入力してきたhidden stateを出力という流れを繰り返す。
最後のvecを入れたときのhiddenstateをfinalstateとしてとっておく。このfinalstateがthoughtvectorと呼ばれ、入力した文の意味を表すベクトルとなる。
>文脈ベクトルができる。
・最近では、Googleのbert
MLM: Masked Language Modelが使われる。
例:
私 は 昨日 ラーメン を 食べ ました
[✕]
ここでは、”昨日”を消す。前後文脈から、そこに何が入るかを学習させる。単語の意味がベクトルに持たせられる。
教師なし学習ができる。そのメリットは、人間の手をかけずに、データの量を増やして精度を上げる事ができる。
5-2 Decoder RNN
アウトプットデータを単語等のトークンごとに生成する構造。
あるシーケンスから別のシーケンスを作り出すこと。
昨日の刺し身大丈夫でしたか?と聞く。
刺し身を食べたがお腹が痛いという出力を返す。
手順
1.Decoder RNN: Encoder RNN のfinal state (thought vector) から、各token の生成確率を出力していきます。
final state をDecoder RNN のinitial state ととして設定し、Embedding を入力。
※与えられたembedding表現のベクトルを元に、対応する単語を取る。元に戻っていく。
2.Sampling:生成確率にもとづいてtoken をランダムに選びます。
3.Embedding:2で選ばれたtoken をEmbedding してDecoder RNN への次の入力とします。
4.Detokenize:1 -3 を繰り返し、2で得られたtoken を文字列に直します。
5-3 HRED
・Seq2Seqは一問一答しかできない。過去の文脈を取りたい。
・HREDは文脈自体を単位として扱う。Context RNNである。
文を入力>文の意味ベクトルが生成される。>次の状態にその意味ベクトルを引き継ぐ。
・問題点
確率的な多様性が字面にしかなく、会話の流れのような多様性がない。
・VHREDは、HREDにVAEを付加。Context RNNとSeq2Seqを合体。
5-4 VHRED
5-5 VAE
5-5-1 オートエンコーダ―
教師なし学習の一つ。MNIST(0-9の画像を予測する)
オートエンコーダ構造。
入力データ(例:画像)から潜在変数z(小さいベクトル)に変換する>元のデータ(画像)に戻す
Encorder:28*28(=784) -(小さく)-> 10*10(=100)※次元削減。復元するために、重要な情報だけ残す。
Decorder:10*10(=100) -(戻す)-> 28*28(=784)
5-5-2 VAE
・Variable Auto Encorder
上記のAEでは、潜在変数zに10*10の重要な情報を作成した。中身の情報がよくわからない。
VAEでは正則化(平均0,分散1)することで、類似度が近いものは近いベクトルになるように揃えることができる。
演習チャレンジの考察
・回答
(1)E.dot(w)
【解説】単語wはone-hotベクトルであり、それを単語埋め込みにより別の特徴量に変換する。これは埋め込み行列Eを用いて、E.dot(w)と書ける。
確認テストの考察
・問題
下記の選択肢から、seq2seqについて説明しているものを選べ。(1)時刻に関して順方向と逆方向のRNNを構成し、それら2つの中間層表現を特徴量として利用するものである。(2)RNNを用いたEncoder-Decoderモデルの一種であり、機械翻訳などのモデルに使われる。(3)構文木などの木構造に対して、隣接単語から表現ベクトル(フレーズ)を作るという演算を再帰的に行い(重みは共通)、文全体の表現ベクトルを得るニューラルネットワークである。(4)RNNの一種であり、単純なRNNにおいて問題となる勾配消失問題をCECとゲートの概念を導入することで解決したものである。(3分)
・答え
(2)RNNを用いたEncoder-Decoderモデルの一種であり、機械翻訳などのモデルに使われる。
・考察
・最近では、GoogleのbertにてMLM: Masked Language Modelが使われる。
文脈の一部を削って、他の文脈からそこに当てはまる単語を推測させることができる。教師なし学習を用いて大量なデータを用いられるので手間がかからず、精度が上がる。
・問題
seq2seqとHRED、HREDとVHREDの違いを簡潔に述べよ。(5分)
・答え
Seq2Seqは一問一答に対応できる、ある時系列データからある時系列データを作る手法。
HREDは文脈の意味を汲み取った変換ができるもの。
VHREDはHREDが当たり障りのない会話しか作れなくなった点をVAEを取り込んで解消したモデル。
・問題
VAEに関する下記の説明文中の空欄に当てはまる言葉を答えよ。自己符号化器の潜在変数に____を導入したもの。(1分)
・答え
確率分布
Section6: Word2vec
・課題:RNNでは、単語のような可変長の文字列をNNに与えることはできない。固定長で表現する必要がある。
・単語をベクトル表現する手法
embedding表現を得ることが可能。
一つ一つのベクトルで単語の意味同士が近くなるようなものを生成。
手順:
単語をリストアップし、IDを割り振り、行列を作成。embedding表現に変換する。
変換するときの変換表を作るときに機械学習を用いる。
Section7: Attension Mechanism
Seq2Seqは長い文章に対応できない。
seq2seq の問題は長い文章への対応が難しいです。seq2seq では、2単語でも、100単語でも、固定次元ベクトルの中に入力しなければならない。
文章が長くなるほどそのシーケンスの内部表現の次元も大きくなっていく、仕組みが必要になります。
Attension Mechanism:入力と出力のどの単語が関連しているのか」の関連度を学習する仕組み。
重要な単語を自分で見分ける。
確認テストの考察
・問題
RNNとword2vec、seq2seqとAttentionの違いを簡潔に述べよ。(5分)
・答え
RNNは時系列データを処理するのに適している。
Word2vecは単語の分散表現ベクトルを得る手法。
Seq2Seqに比べてAttentionは、長い文章でも対応できる。
Appendix: 実装演習
キャプチャ
ご紹介: E資格対策講座 ラビットチャレンジについて
E資格を受けるには、対象の講座の修了が必要です。
ラビットチャレンジは「現場で潰しが効くディープラーニング講座」の通学講座録画ビデオを編集した教材を活用したコースです。
質問等のサポートはありませんが、E資格受験のための最安(2020年5月時点)の講座の一つです。
詳細は以下のリンクからご確認ください。