Transformerの紹介を兼ねた備忘録

:::note
本記事は[SLP KBIT AdventCalendar 2023](https://adventar.org/calendars/9222)の6日目の記事になります
:::

https://adventar.org/calendars/9222

4日遅れとなり申し訳ないです。6日目担当のふせんです。
この記事では近年話題のTransformerという深層学習モデルについて、自分の備忘録を兼ねて紹介していきます。
Transformerなんぞ知らんと思っている方、ご安心ください。Chat-GPTで文章を生成するために使用されているモデル内部にもTransformerの仕組みが利用されていますので、身近な存在です。
対象読者として機械学習の基礎を身に着けてる人を想定していますが、無くても雰囲気が掴めるよう補足を挟んでいます。

# そもそもTransformerとは
Transformerは2017年に発表された論文「Attention Is All You Need」で導入された深層学習モデルの一つです。Transformerは日本語から英語のように文章を入力すると別の文章を予測してくれる機械翻訳のモデルとして提案されました。今では自然言語処理(NLP)の文章生成、質問応答etc...など様々なタスクにも利用されています。また、音声認識や画像処理などの分野でも用いられ、他分野からも注目されているモデルです。(有名なモデルとしてBERT, GPT, ViT, DALL-Eとか)
色々省略して言うと「Transformerを使えばめっちゃ性能良いAIが作れるよ！他分野にも応用効いてすごい！」です。

以下がモデルの模式図です。
例として機械翻訳のタスクで和文->英文を行う場合を考えます。すると左のEncoderでは日本語の文章を意味にして、右のDecoderではその意味を英語の文章に変換するというイメージです。以降は機械翻訳(和文->英文)の例を挙げながら、Transformerの内部の構成要素について説明していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249811/439c2c06-23e1-5d99-b854-1d721d4a467f.png)

# Input Embedding
ここでは翻訳したい文章(inputs)をベクトルの列に変換します。順番としては以下の通りです。

1. 翻訳したい文章を単語に分ける
2. 単語をそれぞれベクトルにする

まず、文章は単語が結合して成り立っています。ここでは、コンピュータが処理をしやすいように文章を単語に分割します(形態素解析)。その後、分割した単語はそのままでは扱いにくいため、ベクトルに変換しています。
つまり、"私は犬が好き" = "私" + "は" + "犬"　+ "が"　+ "好き"という感じに分割して、その後5つのベクトル列に変換します。(詳しくは単語でなくサブワード)

# Positional Encoding
ここでは単語の位置情報を加えています。後に説明するMulti-Head Attentionにベクトルの列をそのまま入れてしまうと、単語の位置情報が忘れられてしまいます。そうならないように、ここでPositional Encodingという位置の情報を含むベクトルを用意し、後にInput Embeddingで作成したベクトルに加えます。


# Multi-Head Attention
Multi-Head Attentionは多角的にどの情報に注目するべきかを判断し、どこに注目するかを制御して出力を決めるという事をします。文章生成ではこの単語とこの単語があるから、次はこの単語を生成したほうがいいんじゃない？という感じで、それぞれの単語に注目度合いを割り振って処理をしています。
このMulti-Head Attentionの中身を知るためにはScaled Dot-Product Attentionについて知る必要があります。以下に式を示します。
$$ Attention(Q,K,V) = softmax\Biggl(\frac{Q\ ^t\hspace{-1.0pt}K}{\sqrt{d}}\Biggr)V $$

このAttention(注意機構)はクエリ($Q$)・キー($K$)・バリュー($V$)で構成されています。キー・バリュー方式のデータベースがあり、それに対してクエリで問い合わせをする処理です。ただし、このクエリ・キー・バリューはすべてベクトルであることに注意が必要です。それぞれのベクトルは$Q = (\vec{q_1},...,\vec{q_n})$, $K = (\vec{k_1},...,\vec{k_m})$, $V = (\vec{v_1},...,\vec{v_m})$と表すことができる。前提として、$Q$, $K$, $V$は縦ベクトルであると考えてください。その上で、$Q$, $K$, $V$の各要素は列ベクトルです。Qの要素はそれぞれが一つのクエリ、つまり入力であると考えると$Q$は$n$個の入力であるとわかります。このことから、Scaled Dot-Product Attentionは$n$個分のデータのバッチ処理であると考えることができます。$K$, $V$はセットの関係であるため、キー・バリューのペア$(\vec{k_i},\vec{v_i})$が$m$個あると考えることができます。先ほど、Qの要素$\vec{q}$が一つのクエリであると述べたことから、以下ではある一つのクエリ$\vec{q}$に注目して式を見ていきます。
$$ Attention(\vec{q},K,V) = softmax\Biggl(\frac{\vec{q}\ ^t\hspace{-1.0pt}K}{\sqrt{d}}\Biggr)V $$

右辺の$\vec{q}\ ^t\hspace{-1.0pt}K$に注目するとこれは以下のようにできます。
```math
\begin{align}
\vec{q}\ ^t\hspace{-1.0pt}K &= \vec{q}(^t\hspace{-1.0pt}\vec{k_1} \cdots ^t\hspace{-1.0pt}\vec{k_m})\\
&=(\vec{q} \cdot ^t\hspace{-1.0pt}\vec{k_1}\cdots\vec{q} \cdot^t\hspace{-1.0pt}\vec{k_m})
\end{align}
```
内積はベクトルの類似度を指すため、上記の式では入力されたベクトルであるクエリとキーの類似度を計算しています。
元の式に戻ると、$softmax$の分母$\sqrt{d}$にある$d$はクエリやキーの次元を指します。次元の高いベクトルは長いため、勾配消失を軽減するためにも$\sqrt{d}$で割っています。
その後$softmax$を取ります。先ほど計算した類似度に関するベクトルの合計が1になるように正規化します。つまり、確率分布を出力します。この確率分布(重みともいう)を$\vec{p} = (p_1...p_m)$とすると、以下のように変換できます。
$$ softmax\Biggl(\frac{\vec{q}\ ^t\hspace{-1.0pt}K}{\sqrt{d}}\Biggr)V = \vec{p}V = \sum{p_i}\vec{v_i} $$

よって、毎回クエリとキーの類似度を比較し、その確率分布(重み)でバリューを選び取っています。$\vec{q}$と$\vec{k_i}$が似ている際は$p_i\fallingdotseq1$、その他の$p_j\fallingdotseq0$に近くなります$(j\ne i)$。これにより出力は$\vec{v_i}$に近くなります。
因みに、上記では$\vec{q}$という一つのクエリに注目しましたが、$Q$の全ての要素についても同様に以下のように書けます。
```math
\begin{align}
Attention(Q,K,V) &= softmax\Biggl(\frac{Q\ ^t\hspace{-1.0pt}K}{\sqrt{d}}\Biggr)V \\
&=\begin{pmatrix}
  p_{11}\vec{v_1}+ \cdots +p_{1m}\vec{v_m} \\
  \vdots \\
  p_{n1}\vec{v_1}+ \cdots + p_{nm}\vec{v_m}\\
  
  \end{pmatrix}
\end{align}
```

さて、上記の式ではクエリに対してキーの類似度を求め、バリューを返すようにしていました。しかし、そもそもこの時に利用する$K$,$V$のペアは適切なペアでなければそもそも類似度を求めても意味がありません。以下では、このペアの学習の重要性を踏まえた上で、Multi-Head Attentionについて説明をします。
Multi-Head Attentionの模式図と式は以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249811/7f548cae-ad53-218b-99e4-082a94eb75f7.png)


```math
\begin{align}
MultiHead(Q,K,V) &= concat(head_i)W^o \\
head_i &= Attention(QW^Q_i, KW^K_i, VW^V_i)
\end{align}
```

Attentionの内部では$Q$,$K$,$V$に対してそれぞれ$W^Q_i$,$W^K_i$,$W^V_i$の行列をかけています。
ここでMulti-Head Attentionの入力$X = (\vec{x_1},\cdots,\vec{x_n})$を考えます。Transformerの模式図を見てもらうとわかるように、入力が3つに分裂していることがわかります。これが$Q$,$K$,$V$であり、それぞれに$X$が入ってます。しかし、すべてのベクトルが同じ内容のまま計算してもAttentionが正常に動作しません。そのため、$QW^Q_i$,$KW^K_i$,$VW^V_i$のようにそれぞれに異なる行列をかけることで、それぞれを異なるベクトルにしています。より具体的には、$W^Q_i$,$W^K_i$,$W^V_i$は入力されたベクトル$X$のどの部分を処理するか、$X$の注目の仕方、出力の調整などそれぞれの役割があります。

また、Malti-Headという名前の通り$head$は複数作成します。これは$softmax$には一つの要素は1に近い値、それ以外の要素は0に近い値を取るという性質があるためです。$Attention$が一つの場合は複数の観点で情報を取り出すことが難しいですが、複数の$head$を用いることで情報をうまく混ぜることが期待できます。
concatは行列を縦方向に連結する処理を表しています。

# Add & Norm
Addは残差結合(residual connection)、Normは層正規化を指します。
残差結合は一つ前の層の結果を現在の層の出力結果に足し合わせる処理です。
層正規化は学習を行う際に、過剰に値が大きくならないようにベクトルの各要素を正規化するという操作を行います。これによって、勾配爆発を抑制する効果を期待できます。

# Feed Forward
二層のニューラルネットワーク(NN)があります。原論文では以下のようにNNが定義されています。
$$FFN(x) = ReLU(xW_1+b)W_2+b_2$$
この通り、古典的な2層の順伝播型のNNと同じですが、中間層に位置するベクトルサイズが入出力層よりも大きくなるという特色を持っています。

# Outputs
ここで入力するのはそれまでに生成した英単語です。理由として、次に生成される英単語を予測するために、それまでに生成した英単語を参考にする必要があるためです。以下に詳細を示します。
入力する和文を$X = (x_1,\cdots,x_N)$、出力する英文を$Y = (y_1,\cdots,y_i)$とします。$N$は入力する単語の総数で、$x_N$は入力する最後の単語を示します。$y_i$は$i$番目に予測する単語を示します。
この場合、出力$yi$を予測する確率は$P(y_i | x1,\cdots,xi, y_1,\cdots,y_{i-1})$となります。つまり、Encoderで入力した和文$X$のすべての要素と$i-1$番目までの$y$を入力することで$y_i$を予測することができます。

# Linear と Softmax
Linearではそれまで圧縮して計算していたベクトルを単語次元のベクトル列に戻す処理を行います。
Softmaxでは確率の列に変換します。Softmaxによって、次に予測されうる単語が確率で表現され、最も確率の高い単語が次に生成される単語となります。

# おわりに
いかがでしょうか。数式っぽい部分もありましたが、Transformerの雰囲気を感じ取ってくれたなら嬉しいです。書いている自分も怪しい部分が多々あったので、間違いなどありましたら指摘してくださると有難いです。記事を書いていく中で、自分のTransformerに対する理解が深まったことを実感したので、やはりアウトプットは大切なことだと再認識しました。今回のAdventCalendar以外にも、重要だと思ったものは積極的にアウトプットできたらなと思います。
# 参考にしたもの
動画
[AIcia SolidさんのTransformer解説動画(とても分かりやすく楽しい)](https://www.youtube.com/watch?v=50XvMaWhiTY)

論文、記事
[Attention Is All You Need](https://arxiv.org/pdf/1706.03762.pdf)
[論文解説 Attention Is All You Need (Transformer)](https://deeplearning.hatenablog.com/entry/transformer)
[作って理解するTransformer/Attention](https://qiita.com/halhorn/items/c91497522be27bde17ce#transformer-%E3%82%92%E7%9F%A5%E3%82%8B)
[ざっくり理解する分散表現, Attention, Self Attention, Transformer](https://qiita.com/norihitoishida/items/2fead107792b504eaccf#scaled-dot-product-attention)

書籍
IT Text 自然言語処理の基礎
ゼロから作るDeepLearning2 自然言語処理編