トランスフォーマーごっこ(Attention + Context Vector 編)
😃 GPTー!
😃 トランスフォーマーごっこしよー!
🐹 いいよー!
😃 学習データは「鬼に金棒。猫に小判。」だけで、層は3層だけね
🐹 超ミニトランスフォーマーね、おっけー!
トークンの作成
😃 まず、[鬼,金棒,猫,小判]にトークン分解するよ!
😃 最初はランダムなベクトルになるんだよね?
🐹 そう!
鬼 = [0.9, 0.2, 0.1]
金棒 = [0.8, 0.6, 0.1]
猫 = [0.3, 0.9, 0.1]
小判 = [0.4, 0.8, 0.7]
にしよう!
QKVを作ろう
😃 んで、それぞれのトークンに層固有のWq、Wk、WvをかけたQKV(クエリ、キー、バリュー)を出すんだよね!
🐹 ひとまず、
Wq = [[0.1, 0.2],
[0.3, 0.4],
[0.5, 0.6]]
Wk = [[0.2, -0.1],
[0.0, 0.3],
[0.4, 0.5]]
Wv = [[0.3, 0.7],
[0.5, 0.2],
[0.6, 0.1]]
にしよう!
それぞれのQKVは、
トークン 入力ベクトル x Q (x·Wq) K (x·Wk) V (x·Wv)
鬼 [0.9, 0.2, 0.1] [0.20, 0.32] [0.22, 0.02] [0.43, 0.68]
金棒 [0.8, 0.6, 0.1] [0.31, 0.46] [0.20, 0.15] [0.60, 0.69]
猫 [0.3, 0.9, 0.1] [0.35, 0.48] [0.10, 0.29] [0.60, 0.40]
小判 [0.4, 0.8, 0.7] [0.63, 0.82] [0.36, 0.55] [0.94, 0.51]
になるよ!
Attention Weightを作ろう
QVを掛け合わせよう
😃 つぎは、それぞれのQと他のトークンのKを掛け合わせるんだよね!
🐹 そうだよ!Qが鬼、Kも鬼のときはこんな感じになるよ!
鬼→鬼:
0.20×0.22+0.32×0.02=0.0504
🐹 全部やったらこんな感じ!
鬼(K) 金棒(K) 猫(K) 小判(K)
鬼(Q) 0.0504 0.088 0.1128 0.248
金棒(Q) 0.0764 0.1271 0.1654 0.3991
猫(Q) 0.0866 0.134 0.1787 0.4572
小判(Q) 0.1552 0.2536 0.3591 0.7586
😃 このQKの掛け合わせが、Attention weight(あるトークンが別のトークンにどれだけ注目してるか)になるんだよね!
🐹 そうだよ!でも使える値にするには工夫が必要なんだ!
スケーリング
🐹 まず、スケーリングといって、Kの次元数の平方根で全部のQKを割るよ!
🐹 これは次元が多いときにQKの値の差が大きくなりすぎて次の工程でソフトマックスを取ったときに0か1になっちゃうのを防ぐために必要なんだ!
😃 オッケー!スケーリングしたらどんな値になる?
🐹 今回はKの次元数は2だから、2の平方根で割るよ!
Qが鬼、Kも鬼のときはこんな感じ!
鬼→鬼:
0.0504/1.4142≈0.0356
全部のトークンに対して同じことをすると、こんな感じ!
鬼(K) 金棒(K) 猫(K) 小判(K)
鬼(Q) 0.0356 0.0623 0.0798 0.1755
金棒(Q) 0.0540 0.0899 0.1170 0.2823
猫(Q) 0.0613 0.0948 0.1264 0.3234
小判(Q) 0.1098 0.1794 0.2540 0.5363
SoftMax
😃 この値をソフトマックスすると、Attention weightになるんだね
🐹 そうソフトマックスすると生の値から確率(0から1、しかも合計1)になるんだ
😃 ソフトマックスのやり方は?
🐹 簡単3ステップでできるよ!
さっきのスケーリングスコアを、 自然数を底とした指数に変換するよ。そうすることで負の数も正になるんだ
鬼→鬼:
exp(0.0356) = 1.0362
鬼→金棒:
exp(0.0623) = 1.0642
鬼→猫:
exp(0.0798) = 1.0830
鬼→小判:
exp(0.1755) = 1.1918
一個のQに対する全部の値の合計を出して、
1.0362 + 1.0642 + 1.0830 + 1.1918 = 4.3752
それぞれの指数を割る!
鬼→鬼:
1.0362 / 4.3752 ≈ 0.2368
鬼→金棒:
1.0704 / 4.3752 ≈ 0.2432
鬼→猫:
1.0779 / 4.3752 ≈ 0.2475
鬼→小判:
1.2105 / 4.3752 ≈ 0.2724
😃 ふぉぉぉぉぉ合計が1の確率分布になった
😃 これがQが鬼の場合のAttention Weightだね
🐹 そう!全体に同じことをするとこんな感じ
鬼(K) 金棒(K) 猫(K) 小判(K)
鬼(Q) 0.2368 0.2432 0.2475 0.2724
金棒(Q) 0.2295 0.2378 0.2444 0.2883
猫(Q) 0.2272 0.2350 0.2425 0.2953
小判(Q) 0.2101 0.2253 0.2427 0.3219
😃 今はまだ学習してないから、全部のトークンが他のトークンをほとんど同じ量だけ注意してるね
Context Vectorをつくろう
😃 このAttention Weightから各トークンのVを更新するんだね
🐹 そう、それが文脈ベクトル(Context Vector)
😃 文脈ベクトルの作り方は?
🐹 他のトークンのVにAttention Weightを掛け合わせたものを合計するよ
🐹 それぞれのVと、鬼から見たそれぞれのAttention Weightはこんな感じだから、
参照先 Attention Weight(a) Value (V) 重み付きV (a×V)
鬼 0.2368 [0.43, 0.68] [0.102, 0.161]
金棒 0.2432 [0.60, 0.69] [0.146, 0.168]
猫 0.2475 [0.60, 0.40] [0.149, 0.099]
小判 0.2724 [0.94, 0.51] [0.256, 0.139]
🐹 鬼の文脈ベクトルは、全部の重みつきVの合計で、
[0.102, 0.161] + [0.146, 0.168] + [0.149, 0.099] + [0.256, 0.139]
≈ [0.65, 0.57]
になる!
🐹 それぞれの最終ベクトルはこんな感じ!
鬼 [0.67, 0.66]
金棒 [0.68, 0.66]
猫 [0.68, 0.65]
小判 [0.69, 0.66]
😃 これってさぁ...仲間(他のトークン)を取り込んで新しい自分(V')を作る感じがしてめっちゃエモいよね
😃 しかも特に近い(Attention weightが高い)仲間の影響が強くなるっていう
🐹 まさにそれ!
🐹 Attentionが強い = よく見てる/影響を受けてる
🐹 だから「仲良しさん同士」はお互いをいっぱい参照して、最終的に 文脈ベクトル(性格・雰囲気)まで似てくる
🐹 最初はバラバラの性格(ランダム埋め込み)でも、学習を通して「お前といると落ち着くわ」みたいに似通っていく
🐹 結果として、「に」は名詞に寄り添うし、「猫」と「小判」みたいなセットは「空気感までシンクロ」する
🐹 だからTransformerの世界って、孤立した存在がなくて、全部が全部、関係性で形作られるんだよね
😃 ひぃぃ...エモすぎ...
😃 今はまだContext Vectorは似てるけど、学習が進めば鬼と金棒が近づいたり、猫に小判が近づいたりする?
🐹 そう!学習をするとAttentionが調整されてContext Vectorも似てるもの同士は近くなっていくんだ
😃 早く学習したい!はぁはぁっ
🐹 落ち着け!あと一手間必要だ!
🐹 このあと、Feed Forward Network (FFN)っていう関数に通して、層を積んで、出力層(Linear + Softmax)っていうものに通す必要がある
🐹 でも長くなりすぎたから、次回にしよう
😃 おっけー!じゃぁまた明日集合ね!
🐹 ばいばーい!