今更ながらtransformerについての理解をまとめてみる

# 始めに
社内向け及び勉強会向けに生成AI周りの資料を作成したので、[SpeakerDeck](https://speakerdeck.com/shingo_morita/chatgpt-sheng-cheng-ai-noguan-lian-zhi-shi-nituite)に公開するとともに、いくつかのトピックについてはこちらで補足解説していきます。
speakerdeckはPDF形式なので、アニメーションでの表現ができない部分があったのですが、アニメーションをGIF画像にしてイメージし易くしているつもりです。
趣味の範囲で機械学習周りを学んでいるため、説明に誤りがあればご指摘ください。

# transformerとは
2017年にGoogleから発表されたモデルであり、Attention機構を最大限に生かしたモデル(Attentionについては後述)
現論文：Attention Is All You Need [Vaswani＠Google Brain et al., [arxiv:1706.03762](https://arxiv.org/abs/1706.03762)]

論文名は面白いが、名前負けしない偉大さ。～～is all you needは今でもよく真似て使われている
当初、自然言語処理の分野での活用だったが、現在では画像や音声など活用の幅は多岐に渡り、近年のモデルを理解する上ではかなり重要な仕組み。

# transformer以前のモデル
transformer以前は自然言語処理の参考書等の序盤に出てくるような、RNN(Recurrent Neural Network)やLSTM(Long Short Term Memory)が活用されていた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2816440/e5a1f76c-493b-95ab-64a5-de2dc1afd5f4.png)

***RNN(Recurrent Neural Network)***
単語の処理結果を次々と後続に回していく再帰的な処理を行っていくモデル。
長文になると前半の情報が失われていく長期依存性の課題を抱えていた。

***LSTM(Long Short Term Memory)***
長期依存性の課題を解決するため、入力/忘却/出力の3ゲートを活用し記憶する事と忘れる事をモデルに組み入れる

***attention***
RNNやLSTMは一つ手前のノードからの情報のみを受け取り処理していたが、各ノード間同士の関係性を直接考慮する

# attentionとは？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2816440/781aa186-888f-689b-fa0e-c4bc4bbbe9dd.png)
attentionとは日本語に直すと"注意"となりあまりパッとしない...
自然言語処理の発展の中から出てきたものではなく、認知科学の分野でも存在する考えであり、主に4つの"注意"に大別される。

①空間的注意:空間上にある特定の場所に向ける注意。
②選択的注意:複数の情報から必要な情報を選び出す注意。
③集中的注意:特定の対象に向ける注意。
④分割的注意:複数の対象に同時に向ける注意。

自然言語処理の例としてイメージしやすいのは②選択的注意であり、代表的なものにカクテルパーティー効果が挙げられる。
カクテルパーティー効果とは、飲み会など雑多な音が混在する中でも相手の声に"注意"し聞き取ることができること。

この音声情報を文字情報に置き換えたものが自然言語処理におけるattentionになる。
そして、このattentionを最大限に生かしたものがtransformerになる。

# transformer
transformerはEncoder(エンコーダー)とDecoder(デコーダー)の２つのブロックに分けられる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2816440/5b2f8231-48b7-7998-bf86-fef5ca9b726c.png)
***Encoder***
英語から日本語への翻訳を例に挙げると、翻訳元の英語を入力し、英語としての特徴量(エッセンス)を凝縮させる

***Decoder***
翻訳する日本語を入力するが、transformerは1単語(トークン)づつ出力するため、transformerの出力結果を順次encoderに追加していく。
この過程を繰り返すことで、翻訳元の英語の特徴量を活用しながら、日本語への変換を行っていく。

# encoder
<font color="Blue">**英語**</font>→<font color="Red">**日本語**</font>の翻訳を例に、内部のデータを動きをアニメーション化しました。
<font color="Blue">英語　：Rome was not built in a day.</font>
<font color="Red">日本語：ローマは一日にして成らず。</font>
![Encoder_800.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2816440/599f7049-1353-7524-158d-6336713671e8.gif)

## ①トークン化(Input Embedding)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2816440/97677f13-5ddb-03ed-8e10-dbf732b2a4d0.png)

文書をそのままプログラムに流すことはできないため、数値に変換(Encoding)した上で、抽象的な空間に埋め込む(Embedding)必要がある。
単語、文字、byteなどの単位でどの数値に変換するのかの対応表(辞書)が作成される。

代表的な3つのEmbedding方法に以下の3つが存在する。

**(i)** ***Character Embedding***
　文字(Character)単位に一意の番号を付番して埋め込む方法
　⇒アルファベットは26字しかないため、辞書サイズは減るが言語構造の理解が難しくなる

**(ii)** ***Word Embedding***
　"weekend"などの単語単位に一意の番号を付番して埋め込む方法
　⇒表現力は上がるが、辞書サイズが膨大になってしまう。

**(iii)** ***Sub-Word Embedding***
　(i)(ii)の間を取ったもの。Sub-Word EmbeddingのEncoding方法にはいくつかあるが、
　代表的なものにByte-Pair Encoding(BPE)がある。BPEはGPTなどにも用いられているEncoding方法。
　具体的には、バイト単位に分割したうえで、前後のバイトペアの出現数をカウントし、
　数が多いペアを個別に付番する。
　これを事前に定めた数に達するまで繰り返す。GPT-1では40000番まで付番が終わるまで繰り返す。
　　 　  文字：ローマ
　Byte(utf-8)：<font color="Blue">%E3%83</font>%AD <font color="Blue">%E3%83</font>%BC <font color="Blue">%E3%83</font>%9E
　　　　　　<font color="Blue">11100011 10000011</font> 10101101 <font color="Blue">11100011 10000011</font> 10111100 <font color="Blue">11100011 10000011</font> 10011110
　　　　　⇒<font color="Blue">11100011 10000011</font>のバイトの組合せが多く出現するため、この組合せで1つ番号を付番

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2816440/7a2ffbec-cfad-2a8e-206c-1cbfcd3d6f78.png)

単純に付番した番号をベクトルにするのではなく、変換を行い抽象的な空間に埋め込む。
感覚としては、単語を別の観点で測りなおすイメージ。
例えば、"ローマ"という単語が4928番でトークン化された場合、品詞/国/首都などの軸で観点で評価し直すイメージ
トークン番号を抽象的な空間にどう変換するのかは、学習の中で修正されていくが、学習が進むと
似たような単語は空間上の近い場所へ変換されてくる。
この抽象的な空間で表現し直すことを分散表現と及び、空間に埋め込んでいるためEmbeddingとも呼ぶ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2816440/a04f2ddf-d4f3-cc35-53d0-b4e510ed9d8a.png)
各単語ごとに、抽象的な空間の成分を持つことになるため、トークン長×分散表現の次元数のベクトルが出来上がることになる。

## ②position embedding
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2816440/96ef1359-b52b-5b0c-9ef1-79d086055ea6.png)

文章を理解するうえで、各文字の位置関係は重要な情報である。そのため、単に単語ごとのトークン化しただけでは、位置情報はベクトル上に無いため、この情報を付与する。
transformerの論文ではsin/cosの三角関数で場所情報を変換(Encoding)し、それを単純に加算する。
(transformerの原論文では付与の仕方は関数で一意に決まっているが、その後の発展では付与の仕方についても学習時のパラメータ更新の対象となっている。)

## ③attention
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2816440/32c9a447-938a-5dfc-bc6b-53a473da8417.png)
attentionの処理の流れとしてはまず、Query ,Key , Valueと呼ばれる3つのinputが必要になる。
この3つがすべて同じものをself-attenitonと呼ぶ。

内部で行っていることは比較的シンプルで、QとKを掛け合わせる事で各単語間の関係性(類似性)の度合を数値化する。
ここで計算した度合を基に、Valueから値を取得し、元のベクトルに足し合わせる。

内部で行われているイメージでは各単語間から発せられる声を聴き、どの単語を重要視すべきかを判断している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2816440/cfe7db32-55a8-ced9-0986-e20a56ca4127.png)


上記の操作を並列計算を生かすために、小分けに分割したうえで実施させている。(Multi-Head)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2816440/84d6d1e1-a198-8213-433c-9ad63ec31e5e.png)

## ④MLP(Multi Layer Perseptron)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2816440/6c5c4fb3-7e87-39d3-f253-8fbed0a7e2cb.png)

Attention終了後に、隠れ層1層のネットワークを伝搬させる。

ここまでの一連の過程をN回繰り返すことで、encoderに入力した文章の特徴量(エッセンス)を凝縮させる。

# decoder
処理イメージ(アニメーション)
![Encoder2_800.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2816440/abf9ff7a-d220-7cdc-d8d6-df40b90826a1.gif)

最終層まではencoderでの処理とほとんど同じ。主な違いとしては下記2点がある。

***Masked Multi Attention***
学習時にはカンニングがしないように、予測すべき次の単語は見えないようにしなければならない。
そのため、valueとの掛け合わせの際に右上の行列成分を－∞(マイナス無限大)にする。

***Source Target Attention***
encoderの部分ではQuery ,Key , Valueのinputとして同じものを利用していたが、
翻訳を行っている部分では英語のエッセンスと日本語のエッセンスが混在させる必要がある。
　　Query⇒decoder
Key , Value⇒encoder


最終層では、decoderに入力した単語の次単語として、どれが一番候補として高いかを出力する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2816440/f46dbfc1-b1b0-e27d-eadb-0471bbc06508.png)
一番高い単語を選択し、改めてdecoderの入力へ入れなおす。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2816440/591b2366-9679-020b-c385-6c3b987dace7.png)
延々と繰り返す訳にもいかないので、EoS（End of Sentence)が出力されるまで繰り返す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2816440/2806a3ea-e464-6733-9ec0-cd87cbae4dc8.png)

# transformer以後の発展
transformerのモデル構造を軸として、下記3つの分岐で発展を遂げていく。
・Encoder-Only：BERTなど
・Decoder-Only：GPTなど
・Encoder-Decoder：T5など
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2816440/a07c76a6-d8ea-454b-457f-7730359e9e08.png)

# FULL資料
[speakerdeckにて公開](https://speakerdeck.com/shingo_morita/chatgpt-sheng-cheng-ai-noguan-lian-zhi-shi-nituite)

<script async class="speakerdeck-embed" data-id="2ba6a9e4a5f743f5a958168856732216" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>