数学 時系列分析 機械学習/AI 自然言語処理

Transformerとは?世界を変えた深層学習モデルの仕組みをわかりやすく徹底解説

2023年12月9日

近年のAI技術の急激な発展には「Transformer」という深層学習モデルの存在が大きく関わっている。

この記事では、そのTrasformerについてその仕組みとそれがなぜ組み込まれているか画像をふんだんに使用して徹底的に解説している。

この記事の要点

  • Transformerってなに?
  • Transformer登場の背景
  • Transformerの仕組み

必要な知識はなんと高校数学行列の足し算、掛け算のみ!

今後のAI社会において理解しておいて絶対に損はないので、ぜひ読んでほしい。

 

Transformerってなに??

Transformerは、もともと機械翻訳の深層学習モデルとして2017年にGoogleが"Attention is all you need"という論文で発表された。

 

Transformerは、系列データ→ベクトル→系列データという経路で情報を処理するEncoder-DecoderモデルというジャンルのAIである。
機械翻訳では、Encoderに入力された文章を特徴量ベクトル化し、Decoderにその特徴量ベクトルを与えることで目的言語の文章を生成できるのである。

Transformer概略図

transformer概略図

  1. Encoderで入力系列をベクトル列に変換する
  2. その得られたベクトル列をDecoderに与える
  3. Decoderで次の出力系列の確率を計算する
  4. BEAM Searchなどの探索アルゴリズムで出力を生成する

なので、本来の機械翻訳、日本語(原言語)から英語(目的言語)への翻訳を考えると下図のようになる。

まず、Encoderは「こたつでみかんを食べる」という文章を受け取り、原言語の単語(トークン)ごとのベクトルの埋め込みを出力する。

次にDecoderは、すでに生成した目的言語の単語(トークン)列「I eat a mandarin at the 」と原言語の単語(トークン)ごとのベクトルの埋め込みから、次に生成するべき単語(トークン)「kotatsu」を予測する。

 

Transformerの凄さ!

LLM(大規模言語モデル)への発展

皆さんお馴染みのChat-GPTの内部で使用されているGPTシリーズで使われているのがTransformerである。

そもそも、「GPT」とは「Generative Pre-Trained Transformer」の略で「生成に使える事前学習されたTransformer」という意味である。つまりTransformerなくしてGPTはない。

2019年にOpenAIはTransformerを活用した大規模言語モデル「GPT2」を開発。そして2020年にGPT3を開発した。

GPT2のパラメータ数が約15億個だったのに対し、GPT3はその100倍以上の1750億のパラメータ数になった。

 

Chat-GPTなどのGPTがいかに優れているかはここで語るまでもない。

 

他分野への応用

そもそもTransformerにおける"翻訳"の意味を考えてみる。

翻訳とは抽象的に考えると、ある並びの記号の集合から別の並びへの写像(マッピング)と考えることができる。

 

つまり、Transformerにおいて言語に限らずそのメディアを表現する方法を見つけることができれば、それを言語として翻訳することができるのである。

それが機械学習の様々な分野で同時多発的に起こり、TransformerはAI界全体に伝播し脅威的な性能を叩き出しまくったのである。

例えば「画像」分野では、ViTなどの「画像認識」、DALL-EやStable Diffusionなどの「画像生成」

「音声」分野では、Conformerなどの「音声認識」、Voice Transformer Networkなどの「合成音声」などが開発された。

このようにTransoformerは機械翻訳に限らず、自然言語処理、時系列データ、画像認識、音声合成、何に適用しても本当に軒並み最高性能を叩き出すことから、Transformerは深層学習界に革命をもたらしたと言え、昨今の急速なAIの発展はTransformerが火付け役と言っていい。

 

図の黒いノードの「Vanilla Transformer」から進むにつれて、モデルの発展と派生を示している。

この家系図は、トランスフォーマーモデルがどのように進化し、派生してきたかを一目で理解するのに役立つ。

 

Transformer登場の背景

Transformerの登場以前は、ニューラルネットワークの一種であるRNN(Recurrent Neural Network:回帰型ニューラルネットワーク)CNN(Convolutional Neural Network:畳み込みニューラルネットワーク)が用いられて来た。

自然言語処理では単語や単語を分割したサブワード、文字といったトークンを並べた系列データとして扱うことができる。

Transformerとの比較のために、まずはRNNとCNNの仕組みとその問題点についてザックリ理解しておこう。

RNN(Recurrent Neural Network)

系列データの処理には、RNN(Recurrent Neural Network)がよく用いられる。RNNは前の時刻から得られた中間出力を隠れ状態として次の時刻の処理に使われる。これによって、過去の入力を考慮したデータの処理が可能になる。

冒頭の単語から1トークンずつニューラルネットワークに入力して、ニューロンを逐一更新する。これにより原理的に言えば単語をいくらでも入力&出力できる。

日英翻訳の例をとると、

「吾輩は猫である」という文章を英語に翻訳するタスクを考えて、Encoderブロックは「吾輩」「は」「猫」「である」という単語を順に受け取り、その後Decoderブロックは順にその情報とこれまでに出力した情報を受け取り、その段階で出力するに尤もらしい単語を出力する。

RNNの問題点

RNNの課題

  • ニューロンが固定長(ユニットの数と層数)なので、長文になるとすべての情報を覚えきれない。結局、単語の長距離依存性の把握が困難。
  • ネットワークが単語方向に深くなるため、学習が不安定(勾配消失、勾配爆発)&学習が遅い。
  • 入力となる系列データを逐次的に処理する必要がある。
長距離依存性の把握が困難

ニューロンのユニット数や層数が固定なので、これまでのすべての入力を抱えることができずに、長くなればなるほどすべての情報を覚えきれずに、序盤の入力された単語を忘れてしまう。

学習が不安定

訓練時に誤差逆伝播を使用して学習させる際に、文章が長くなればなるほど層が深くなるので、勾配情報を最初の方まで伝えるのが大変。

 

RNNの発展版であるLSTM(Long Short Term Memory)は、この上記二つの問題点をある程度解決しているが、最後の「分散学習が困難」という問題がまだ残っている。

分散学習が困難

RNNやその発展版のLSTMはその性質上、データを逐次的に処理する必要があり、大規模になればなるほど計算リソースと処理速度が重要な要因である場合に使えなくなってしまう。

なので、大規模言語モデルのような膨大なデータを大量のリソースを使ってスケールしたい場合にネックになることがある。

 

CNN(Convolutional Neural Network)

NLPにおけるCNNの簡略図

 

画像データの処理でおなじみのCNNも、自然言語処理(NLP)で使うことができる。CNNは、RNNのように前の時刻から得られた隠れ状態を入力する必要がないため、計算を並列化できる。

 

先ほどの日英翻訳の自然言語処理を考えると

CNNによる日英翻訳の処理の一例

  1. 最初はImput Embeddingでword2vecなどで、入力された文章をベクトルの形に変更したもので、各単語はベクトルとして表現され(上の図では各単語それぞれ5次元)、これを縦に積み上げることで文章全体のベクトルができる。
  2. 異なるサイズのフィルター(2×5、3×5)を使用して、文章行列に対して畳み込みを行う。この畳み込みによって、局所的な特徴が捉えられる。例えば2単語の組み合わせや3単語の組み合わせの情報が捉えられる。
  3. 畳み込みを通した結果を活性化関数を用いて非線形化する。例えばReLU関数などが使われる。
  4. 各フィルターでの出力から、最も大きな値のみを選択する操作を行う。これにより、各フィルターが捉えた特徴の中で最も顕著な特徴だけが次の層に伝えられる。
  5. 異なるサイズのフィルターから得られた特徴ベクトルを結合し、一つの大きな特徴ベクトルを形成する。
  6. そこからさらに、これまでの逆の動きに相当する操作をすることで英語の出力を生成する。

CNNの問題点

CNNの課題

  • CNNは固定サイズのフィルターでテキストを走査するので離れた単語同士の関係を捉えることが難しい。
  • フィルターのサイズ、層の数、活性化関数など、ハイパーパラメータの調整が煩雑である。
  • テキストが長い場合計算コストが多くなる。

CNNには上記のような問題があるが、この中で最も大きい問題は「離れた単語同士の関係を捉えるのが難しい」である。

離れた単語同士の関係を捉えるのが難しい

この問題は先ほどのCNNの翻訳の例を考えれば当たり前な問題なのだが、

CNNは固定サイズのフィルターでテキストを走査する。これが意味するのは、文脈の範囲が限定されるということである。この特性は、文脈が広範であるような自然言語処理タスクには不利になる。

さらには、基本的なCNNは順序情報を保持しない。言い換えれば単語のフレーズ出現順序が重要な場合、CNNだけでは十分な性能を発揮しきれない

CNNは局所的な特徴しか捉えられないため、単語のフレーズの多義性と曖昧性の解消が難しい。このような問題には、文全体の文脈を考慮する能力が求められるが、CNNはその点で限界がある。

 

そこでTransformerは、RNNやCNNを用いずにSelf-Attention(自己注意機構)という機構を活用している。これにより、離れたトークン同士の関係を捉えつつ計算を並列化できるようになった。

それではいよいよ、Transformerのモデルの中身について話していくことにする。

Transformerの全体像

この図は、Encoder,Decoder構成のTransformerを用いて日本語(原言語)から英語(目的言語)への機械翻訳を行うモデルである。

図左側がEncoder、右側がDecoderに対応している。

 

Encoderは、原言語の文を受け取り、原言語の文脈化トークン埋め込み(DecoderとEncoderをつなぐ矢印)を出力する。

Decoderは、すでに生成した目的言語のトークン列と原言語の文脈化トークン埋め込みから、次に生成すべきトークンを予測する。

 

このように、Encoder,Decoderモデルの場合には、EncoderとDecoderで二種類の異なる入力を扱うことができる。Encoderのみで扱う場合は入力に対する文脈化トークン埋め込みを出力するモデル、Decoderのみの場合は入力から次のトークンを予測するモデルとして使われる。

EncoderモデルDecoderモデルEncoder-Decoderモデル
認識系(クラス分類)テキスト生成系テキスト生成系
BERT,RoBERTaなどGPT,PaLMなどBERT,T5など

 

改めて、全体像を眺め少し内部のパーツを見てみると

まだそれぞれの要素を理解できなくても全く問題ない。現時点で理解してほしいのは、EncoderとDecoderで使われている要素が似ているというところである。

Encoderで使われているパーツが同様にDecoderでも使われている。

なので、Encoderのパーツを理解できたら、Decoderの理解は早い。

 

現段階ではまだこのモデル全体を見ても何がどうなっているのかわからない人が多いと思う。Transformerシリーズを読み終わる頃にはこのモデルを遍く理解し、Transformerとお友達になってもらう。

 

Transformerの中心的な役割を果たすのはMulti-Head Attentionという部分であり、これを使い倒すのがTransformerの大きな特徴なのだが、この記事ではあえて一旦その中身をブラックボックスとして扱い、それ以外の部分にフォーカスすることでまずは全体像を掴んでいこうと思う。

 

Encoderの流れ

まずは、Encoder部分について解説する。

Encoderは入力トークン列に対応する文脈化トークン埋め込みを出力することが目的となる。

 

この黄色い枠で囲まれた部分をEncoder Blockとして何層にも重ねることになる。

Encoderでは、後述するInput Embeddingで作成した入力トークン埋め込みに対して、黄色い枠に囲まれたブロックをN個を順に適応して、多段的に情報を付与する。論文中では\(N=6\)が用いられている。

 

この多段的な処理によって低い位置にある層では表層的、中間にある層では文法的、高い位置にある層では意味的というように、より複雑で抽象的な文脈を捉えられるようになると考えられている。[BERT Rediscovers the Classical NLP Pipeline,Ian Tenney et al,2019]

 

ここからは、Encoderに含まれる要素について順に解説していく。

Input Embedding

Transformerでは、語彙Vに含まれるすべてのトークンに対して、入力トークン埋め込みを付与する。つまり、入力単語列を\( d_{\text {model }} =512\)次元のベクトルに変換する。

まず入力されるテキストを受け取り、それをトークナイザーと言われる文章をトークンに分割し、入力できる形に変換するアルゴリズムを使って入力トークン列を対応するIDの列に変換する。

例えばBERTの日本語のモデルの場合のトークナイザーの場合だと

  1. MeCabを用いて単語に分割する
  2. WordPieceを用いて単語をトークンに分割する

そして、あらかじめ用意されたIDと単語が一対一対応された辞書を使用してトークンをIDに変更する。そしてそのIDの数字の順番のところだけ1でそれ以外は0になっているOne-Hotベクトルにする。

そのOne-Hotベクトルをword2vecを使用してベクトルに変換する。

 

word2vecとは

word2vecとは単語をベクトルに変換する、単語分散表現を学習する分析モデルで、単語に対して、一つの単語埋め込み(ベクトル)を割り当てる。

word2vecの強みは大きく二つ

  • 単語同士の位置関係を構築できること
  • 単語同士の演算ができること

「王」ー「男」+「女」=「女王」
「長い」ー「熱い」+「暑さ」=「長さ」
「ロンドン」ー「イギリス」+「日本」=「東京」

というような計算ができるのである。このように、数値の加減算と意味的な加減算が一致するような性質を加法構成性と呼ぶ。

一般的に、学習完了後のWord2Vecを次元圧縮して可視化すると、以下のように、単語間の関係性を見ることができる。

 

位置符号(Positional Encoding)

 

先ほどのInput Embeddingで得た入力トークン埋め込みは、トークンの順序や位置に関する情報を含んでいない。またTransformerのブロックは入力の順序を考慮しないので

このままだと「吾輩は猫である。」という文章と、例えば「である。猫は吾輩」という文章は同じものとして扱われてしまう。

 

これを解決するために、入力トークン埋め込みに対して位置符号(position encoding)を付加する。
位置符号は正弦関数を使ってトークン列の中でトークンの位置をベクトルで表現する方法で、トークン列中の\(pos\)番目に対応する512次元の位置符号\(PE\)は\(PE\)の\(j\)番目の要素を\(P E(pos , j)\)とすると、\(i \in \{0,1,2,\dots,\frac{d_{\text{model}}}{2}-1\}\)に対して、次のように計算される。

$$
\begin{gathered}
P E(pos , 2 i)=\sin \left(\frac{ pos }{10000^{2 i / d_{\text {model }}}}\right) \\
P E(pos , 2 i+1)=\cos \left(\frac{ pos }{10000^{2 i / d_{\text {model }}}}\right)
\end{gathered}
$$

\(PE(pos)\)をベクトルで表現すると次のようになる。

これを先ほど得た入力トークン埋め込みに加えることで、各単語の位置やほかのベクトルとの相対的な位置関係をモデルに把握してもらうのが目的である。

単語埋め込みが\(\sqrt{d_{model}}\)倍されているのは、位置符号のL2ノルムが\(\sqrt{\frac{d_{model}}{2}}\)となるので、スケールを揃えるために入力トークン埋め込みを\(\sqrt{d_{model}}\)倍している。

 

この部分はTransformerにおいてとても大事な部分であり、考察の余地を残す要素なのでこちらの記事で詳しく解説しているので、ぜひこちらも併せて読んでほしい。

Positional Encoding徹底解説:Sinusoidal(絶対位置)から相対位置エンコーディング

Transformerで使われているPositional EncodingであるSinusoidal Positional Encodingについて徹底的に解説して さらに、そこから相対位置エンコーデ ...

続きを見る

自己注意機構(self-attention)

ココがTransformerの要である自己注意機構(self-attention)という部分なのだが、ここでは先に全体の流れを掴みたいのでこの解説を別記事に譲ることにする。

なぜならば、れほどまでに重要な機構なので詳細に解説しなければならないからである。ここでそれをやるとこの記事が長くなりすぎる。

Multi-Head AttentionとScaled Dot-Product Attentionの全て:Transformerの核心を徹底解説

この記事では、Transformerの中心的な役割を果たすMulti-Head Attentionについて解説する。   Transformerのほかの機構の詳細な解説はせず、完全にMult ...

続きを見る

 

なのでここでは、行列のサイズが入力と出力で変化せずに、出力される行列には文脈の情報が付加された状態で出てくるということ覚えておこう。

加算&層正規化(Add&Norm)

ここでは、二つの操作が行われる。

一つ目が加算で、ResNetなどで行われる残差結合(residual connection)を用いて、自己注意機構の出力を足す操作を行う。

その後、二つ目の操作として層正規(Layer Normalization)という処理で、各ベクトルの成分の総和を0に、長さを1に正規化する。

これを行うことで、学習を安定化&高速化させる。ついでにTransformerで使われるドロップアウトも紹介しておく。

残差結合(residual connection)

残差結合(residual connection)は、Transformerの訓練を安定させる仕組みで、エンコーダ部分には各ブロックに二つの残差結合を適用した層(自己注意機構とフィードフォワード層)がある。

このため、N個のブロックを含んだモデルには2N個の残差結合を適用した層を通って出力が計算される。

ここで、\(k \in \{1,2,\dots,2N\}\)に対して、k番目の残差結合を適用する前の元々の層の処理を\(\mathcal{F}^{(k)}(\mathbf{X})\)、層への入力ベクトル列を行列表記して\(\mathbf{X}^{(k)}=\left[\mathbf{x}_1^{(k)}, \mathbf{x}_2^{(k)}, \ldots, \mathbf{x}_N^{(k)}\right]\)とする。残差結合を適用した層の出力(\(k+1\)番目の層の入力)\(\mathbf{X}^{(k+1)}\)は、もともとの層の出力\(\mathcal{F}^{(k)}\left(\mathbf{X}^{(k)}\right)\)に入力\(\mathbf{X}^{(k)}\)を加算して計算される。つまり、

$$
\mathbf{X}^{(k+1)}=\mathcal{F}^{(k)}\left(\mathbf{X}^{(k)}\right)+\mathbf{X}^{(k)}
$$

このように表される。さらにこの式を変形すると次のようになる。

$$
\mathcal{F}^{(k)}\left(\mathbf{X}^{(k)}\right)=\mathbf{X}^{(k+1)}-\mathbf{X}^{(k)}
$$

上式より、\(\mathcal{F}^{(k)}\left(\mathbf{X}^{(k)}\right)\)は出力\(\mathbf{X}^{(k+1)}\)と\(\mathbf{X}^{(k)}\)の残差のみを捉えればよくなることがわかる。これが残差結合の名前の由来である。

エンコーダー構成のTransformerの出力\(\mathbf{X}^{(2 N+1)}\)を展開すると次の式のようになる。

$$
\mathbf{X}^{(2 N+1)}=\mathbf{X}^{(1)}+\mathcal{F}^{(1)}\left(\mathbf{X}^{(1)}\right)+\mathcal{F}^{(2)}\left(\mathbf{X}^{(2)}\right)+\cdots+\mathcal{F}^{(2 N)}\left(\mathbf{X}^{(2 N)}\right)
$$

Transformerの出力は、最初の入力埋め込みと2N個の層の出力を足し合わせたもので、入力埋め込み\(\mathbf{X}^{(1)}\)に対して、マルチヘッド注意機構とフィードフォワード層を通じて、静的な埋め込みでは捉えられない文脈を順に付与していくことで、文脈の情報を持った文脈化トークンが計算される。

 

デグレーションと恒等写像

深層学習モデルは層が深ければ深いほどいいというわけではない。実際に、層を深くすれば深くするほど精度が落ちるという現象、デグレーション(劣化)が発生することがあった。これは過学習とは異なり、訓練データに対しても精度が落ちていくのである。

訓練データに対する誤差が56層の深層学習モデルの方が20層のものよりも大きくなってしまっている。

深層学習モデルを層の数だけの合成関数とみる、\( y=f^{(k)}\left(f^{(k-1)}\left(\cdots f^{(2)}\left(f^{(x)}(x)\right)\cdots\right)\right) \)

このとき、もし仮にある層が恒等写像\( X=f^{(i)}(X) \)を表現できるとすると、どれだけ深くなっても浅い層で表現できることは深い層になっても表現できるということになるので、学習上問題ないはずである。

しかし、実際には恒等写像を畳み込み層の繰り返しで学習することは現実的には不可能であり、恒等写像に近い写像を学習することも不可能なのであり

仮に浅い層でいい感じの精度が出ていたとしても、その後の層で精度を悪化させてしまうのである。

しかし、この残差結合を利用すれば話が一気に変わる。\(f(x)\)を直接学習するのではなく

$$
y=f(x)=x+g(x)
$$

この式を使って、出力\(y\)と入力\(x\)の差\(g(x)\)を学習するという手法をとると、\(g(x)=0\)という風になれば恒等写像を簡単に表現することができる。

どんな入力に対しても0を出力する関数\(g\)は容易に作ることができて、すべてのパラメータを0にすればよい。このとき

$$
y=f(x)=x+g(x)=x
$$

なので、つまり恒等写像を学習できるということになり、入力が理想的なものであればそのまま出力することができる。たったこれだけのことで、深層学習モデルは層を深くすることに成功したのである。この残差結合という対策がシンプルかつ完璧なものなのかがわかる。

これはTransformerという深層学習モデルにおいても同様であり、「注意機構」「フィードフォワード層」のすべての層にこの残差結合を利用することでこれだけ層を深くしても、学習ができるのである。

層正規化(Layer Normalization)

層正規化は過剰に大きい値によって訓練が不安定になることを防ぐために、ベクトルの値を正規化(平均0、分散1に)する仕組みである。

直感的にも、シグモイド関数などの活性化関数は入力が0周辺の時に非線形性をもつため、入力が0周辺に集中するように入力を調整することで、ニューラルネットワークが学習によって複雑な関数を表現しやすくなることが想像できる。

まず、層正規化への512(\(=d_{model}\))次元の入力ベクトルを\(\mathbf{x}\)とおき、ベクトルの要素の平均を\(\mu_{\mathbf{x}}\)と標準偏差を\(\sigma_{\mathbf{x}}\)と置く。

$$
\begin{gathered}\mu_{\mathrm{x}}=\frac{1}{d_{model}} \sum_{i=1}^{d_{model}} x_i \\ \sigma_{\mathrm{x}}=\sqrt{\frac{1}{d_{model}} \sum_{i=1}^{d_{model}}\left(x_i-\mu_{\mathrm{x}}\right)^2}\end{gathered}
$$

これを使用して、層正規化関数\(layernorm(\mathbf{x})\)のk番目の要素は

$$
\text { layernorm }(\mathbf{x})_k=g_k \frac{x_k-\mu_{\mathbf{x}}}{\sigma_{\mathbf{x}}+\epsilon}+b_k
$$

で求めることができる。\(g_k\)と\(h_k\)は、学習可能なゲインベクトル\(\mathbf{g}\)とバイアスベクトル\(\mathbf{b}\)のk番目の要素である。この二つのベクトルは層正規化の表現力向上のために導入されている。これを\(\mathbf{g}=1\),\(\mathbf{b}=0\)のようにすることで無効にすることもできる。また\(\epsilon\)には\(\epsilon=0.000001\)などの非常に小さい値が用いられる。

 

フィードフォワード層(Feed-Forward Network)

フィードフォーワード層(feed-forward layer)は、2層の順伝播型ニューラルネットワーク(feed-forward network)と同じ構造をしている。

フィードフォワード層への入力ベクトルを\(\mathbf{u}_i\)とすると、出力ベクトル\(\mathbf{z}_i\)は下の式で求められる。

フィードフォワード層

$$
\mathbf{z}_i = \mathbf{W}_2 f(\mathbf{W}_1 \mathbf{u}_i + \mathbf{b}_1) + \mathbf{b}_2
$$

\(\mathbf{W}_1\),\(\mathbf{W}_2\)は、それぞれ\(4d_{model} \times d_{model}\)次元、\(d_{model} \times 4d_{model}\)次元の行列、\(\mathbf{b}_1\),\(\mathbf{b}_2\)はそれぞれ\(4d_{model}\)、\(d_{model}\)次元のベクトルで、\(f\)は活性化関数である。

活性化関数は提案当初のものはRelu関数であったが、その後開発された大規模言語モデルでは、Relu関数よりも滑らかであり、経験的に早く収束するGELU関数が用いられる。

ReluとGELUのグラフ

標準正規分布\(\mathcal{N}(0,1)\)の累積分布関数を\(\Phi(x)\)と置くと、GELU関数は次のように表せる。

$$
\operatorname{GELU}(x)=x \Phi(x)
$$

この活性化関数の非線形性は、ニューラルネットワークの表現力を高くするのに必要不可欠な要素であり、もしTransformerにフィードフォワード層がなかったとすると、単に入力を線形変換して重み付きで足し合わせているだけなので、表現力が著しく低下してしまう。

 

Transformerでは、入力次元\(d_{model}=512\)に対して、中間層の次元は\(4 d_{model}=2048\)が使われている。この結果、フィードフォワード層に含まれるパラメータ数は全体のパラメータ数の2/3を占めている。

つまり、それだけフィードフォワードがTransformerにとって重要な要素なのである。そしてこれだけ大量のパラメータは知識を保持する部分だと考えられている。実際、トランスフォーマーモデルのフィードフォワード層がキー・バリューのメモリとして機能する。つまり、非明示的で辞書的な対応関係が重み\(W_1\)と\(W_2\)に埋め込まれていると解釈できる。

例えばGPT-3の場合

  • 入力層/出力層の次元数:12,288
  • 中間層の次元数:12,288×4=49,152
  • 総ブロック数:96

つまり、フィードフォワードのパラメータ数は\(12288 \times 49152 \times 2 \times 96 = 116B\)

GPT3の総パラメータ数:175B

加算&層正規化(Add&Norm)

先ほどの自己注意機構の直後に行った加算&層正規化と同じ処理を行う。

ここまでの処理をN回行う(「Attention is all you need」の論文だと\(N=6\)ととなっている)、エンコーダーの処理を終えデコーダーに移る。

Encoderまとめ

これで、Encoderのすべての要素は解説し終わった。いろいろ紹介したが、重要な要素は二つ。Multi-head Attentionによる「自己注意機構」と「フィードフォワード層」である。

改めて押さえておきたいのが、自己注意機構」が系列データの単語間(トークン間)で処理を行っているのに対し、「フィードフォワード層」が単語内で処理を行っているということである。

これを残差結合によって自己注意機構で単語間の関係性、つまり文脈に相当するものを付加し、フィードフォワード層で表現力を向上させる。

 

Decoderの流れ

 

まずは、Decoderの入出力を確認すると、Decoderの出力は\( P\left(y_i \mid x_1, x_2, \cdots, x_M, y_0,\cdots, y_{i-1}\right) \)で、、これは、入力文\(x_1,x_2,\cdots,x_M\)と、\(i-1\)番目までの出力\(y_1,y_2,\cdots,y_{i-1}\)を入力として与えたときに、次の\(i\)番目の単語\(y_i\)に何を選ぶべきかを表す確率となる。Decoderの入力は、文の開始記号\(y_0 = <BOS>\)と既に出力された\(y_1,y_2,\cdots,y_{i-1}\)の\(i\)個の単語列である。

つまり、Decoderの目的は、Encoderで処理された原言語の入力の情報を受け取りながら、次の単語が何であるかの確率分布を出力し、次の単語をBEAM SEARCHなどのアルゴリズムに従って、次の単語を予測することである。

そして、その単語とこれまでの出力単語を再度Decoderの入力として使用し、さらに次の単語を予測する。

 

DecoderにはEncoderと比較してブロックにマルチヘッド注意機構が二つ含まれている。それが「マスク付き自己注意機構」と「交差注意機構」というもの。

Encoder部分との違いとしてはこれだけで、ほかの「Input Embedding」や「位置符号」、「加算&層正規化」、「フィードフォワード層」などの機構、性質は同じである。なので後は、Encoderとの違いの部分と、既知の機構の組み合わせの順番だけ意識して見てもらえれば大丈夫というわけだ。

 

Decoderブロックの順番

Decoderブロックはこの図のように、Encoder層でのフィードフォワード層と自己注意機構の間にもう一つの注意機構として「交差注意機構」が挟み込まれるような形で入っただけである。

後はEncoder部分と同じくそれぞれの機構に残差結合を用いて「加算&層正規化」を行い、それをN回行う。これも論文中では\(N=6\)が用いられている。Encoderからの出力は同じ結果がすべてのDecoderブロックに対しての入力となる。

 

Decoderの二つの注意機構

Decoderブロックには二つの注意機構が含まれていて

  • 交差注意機構(Crossed Multi-Head Attention)
  • マスク付き事故注意機構(Masked Multi-Head Attention)

である。これについてもこちらの記事を参考にしていただきたい。ここでもDecoderを流れる行列のサイズは変わらない。

 

Multi-Head AttentionとScaled Dot-Product Attentionの全て:Transformerの核心を徹底解説

この記事では、Transformerの中心的な役割を果たすMulti-Head Attentionについて解説する。   Transformerのほかの機構の詳細な解説はせず、完全にMult ...

続きを見る

 

確率分布の計算

Decoderのブロックが出力する\(d_{model}\)次元のベクトルは、最終的な単語の予測のためにさらに線形変換を受ける。

この線形変換は、Decoderの出力ベクトルとモデルの語彙サイズ(ボキャブラリのサイズ)と同じ次元を持つ重み行列を掛け合わせることで行われる。この語彙サイズは、モデルが知っている単語の総数であり、数千から数十万に及ぶこともある。と問えば語彙サイズが10万であれば、線形変換後のベクトルは10万次元になる。

この10万次元のベクトルには、モデルの語彙に含まれる各単語に対するスコアが含まれていて、これをsoftmaxに通してあげることで、それぞれのスコアが0から1までの確率に変換され、全体としての確率の和が1になるように調整(正規化)される。こうして得られたものが予測確率分布である。

要するに、デコーダーからの各ステップの出力は、線形変換によってモデルの語彙サイズに拡張された後、softmax関数を通して次の単語の予測に使用される。この過程を数式で表すと以下のようになる。

Decoderの(\( i-1 \times d_{model}\))次元の出力行列を\(\mathbf{Y}\)とし、語彙サイズを\(\mathbf{V}\)、線形変換の重み行列を\(\mathbf{W}\)とする。このときの\(W\)は目的言語のWord2Vecの際に使用したものを使う。各単語のスコア行列\(\mathbf{Z}\)は次のように計算される。

$$
\mathbf{Z} = \mathbf{Y} \mathbf{W}
$$

\(\mathbf{W}\)のサイズは\(d_{model} \times V\)になる。そして、\(i\)番目の単語の確率分布\(\mathbf{p}\)はsoftmax関数を用いて次のように計算される。

$$
\mathbf{p}=\operatorname{softmax}(\mathbf{z_{i-1}})=\frac{\exp (\mathbf{z_{i-1}})}{\sum_{j=1}^V \exp \left(\mathbf{z}_{(i-1)j}\right)}
$$

この\(\mathbf{p}\)が最終的な単語の予測確率分布となる。

確率分布のイメージ

この予測分布を得ることができたのであれば、後はBeam Searchを使って文章を生成するのだ

Beam Search

Beam Searchでは、単語ごとの確率に基づき候補になる単語を複数選ぶ。

この候補数をビームサイズという。

 

ここでは、具体例を示すため、モデルの持っている語彙数を5、ビームサイズを3として図示することにする。

一つ目の単語の候補を、先ほど得た出力確率分布から上から三つ選ぶ

そして、その三つが選ばれたとしてTransformerの演算を行い、そしてその三つそれぞれから次の単語の予測確率分布が出力される。この具体例の場合、15種類の語彙から同じく上位確率三つを選ぶ。

これを文章の終了を表す<EOS>が現れ選ばれるまで、これを繰り返すことによって文章を生成する。

これがBeam Searchのアルゴリズムである。

 

これで文章を生成できた。これでTransformernの流れの解説は終了した。

ここからの部分は興味があれば読んでほしい。しかし、この以下の部分よりもMulti-Head Attentionの部分の理解の方が重要だと僕は考えるので、この記事でTranformerの流れ、概要が理解できたらぜひ続いてこちらの記事を読んでほしい。

Multi-Head AttentionとScaled Dot-Product Attentionの全て:Transformerの核心を徹底解説

この記事では、Transformerの中心的な役割を果たすMulti-Head Attentionについて解説する。   Transformerのほかの機構の詳細な解説はせず、完全にMult ...

続きを見る

その他の要素

最適化(Optimizer)

Optimizer(最適化アルゴリズムのこと)にはAdamを使っている。Optimizerとは学習の過程で用いられる誤差逆伝播で得た勾配情報を使って最適化する手法である。

Adamの更新則

$$
\begin{aligned}
& v^{(\tau+1)}=\beta v^{(\tau)}+(1-\beta) \nabla E\left(w^{(\tau)}\right) \\
& r^{(\tau+1)}=\gamma r^{(\tau)}+(1-\gamma) \nabla E\left(w^{(\tau)}\right)^2 \\
& w^{(\tau+1)}=w^{(\tau)}-\frac{\alpha}{\sqrt{r / 1-\gamma^\tau}+\varepsilon} \frac{v}{1-\beta^\tau}
\end{aligned}
$$

そして、Transformerでは("Attention is all you need"では)

$$
\begin{gathered}
\beta=0.9 \\
\gamma=0.98 \\
\varepsilon=10^{-9}
\end{gathered}
$$

ニューラルネットワーク1

                  ニューラルネットワークとは ニューラルネットワークは脳の神経細胞(ニューロ ...

続きを見る

ドロップアウト(Dropout)

ドロップアウトは、訓練データセットに対してモデルが過適合する、つまり過学習を防ぐための正則化の仕組みのことであり、

ドロップアウトは、訓練中にモデルが特定の特徴に依存しすぎないようにするために、確率\(1-p_{\text {keep }}\)で入力された要素を欠落(0に設定)させる。こうすることによって一定割合のニューロンを使わないようにする。

ミニバッチごとに毎回違うニューロンが使われないので、ミニバッチごとに違うモデルが学習されていることになる。

これはある意味アンサンブル学習とも言え、複数のモデルを構築し各モデルの予測を平均することで精度を上げることを狙っている。

ドロップアウトの挙動は訓練時と推論時で異なり、512次元の入力ベクトル\(\mathbf{x}\)に対してドロップアウトを適用することを考える。

学習時はドロップアウト確率\(p\)で選ばれたニューロンのウェイトを0にする。

ドロップアウト確率ではなく、ドロップしない確率を\(q (=1-p)\)とすると、確率が\(q\)の二項分布に従う乱数を生成する。

$$
r_i^{(l)} \sim \operatorname{Bernoulli}(q)
$$

\(l\)は\(l\)番目の層を表し、\(i\)は\(i\)番目の出力(ニューロン)であることを表す。

\(r_i^{(l)} \)は0か1を取る。

この\(r_i^{(l)} \)をベクトルにしたものを\(\mathbf{r}^{(l)}\)とする。

これを\(l\)番目の層のインプットベクトル\(\mathbf{y}^{(l)}\)に掛ける。

$$
\widetilde{\mathbf{y}}^{(l)}=\mathbf{r}^{(l)} * \mathbf{y}^{(l)}
$$

*は要素ごとの積を表している。これによって選ばれたニューロンのウェイトはゼロとして使われないようになる

推論時はドロップアウトせずにすべてのニューロンを使用するのだが、学習時は\(q\)の割合で計算していたのを、推論時はすべてを使用して計算していくと、アウトプットが\(\frac{1}{q}\)倍だけ大きくなってしまう。

なので、ドロップアウトを使った場合、推論時には各ニューロンの重みに\(q\)を掛けてあげる。

$$
W_{\text {test }}^{(l)}=q W^{(l)}
$$

例えば、ベクトル\([1.0,2.0,3.0,4.0,5.0]\)に対して、\(q=0.8\)でドロップアウトを適用すると、訓練時の出力は各要素が20%の確率で0に設定されて、\([1.0,0,3.0,4.0,5.0]\)のようになり、推論時は入力ベクトルが0.8倍されて\([0.8,1.6,2.4,3.2,4.0]\)になる。

Transformerでドロップアウトが使われている場所

  • 入力埋め込み
  • マルチヘッド注意機構の重み
  • 残差結合による加算を適用する前のマルチヘッド注意機構の出力
  • 残差結合による加算を適用する前のフィードフォワード層の出力

まとめ

この記事ではTransformerの流れについて徹底的に解説を行った。

この記事が皆さんの学習の一助となれば幸いである。

※この記事には多分に僕の考察も含まれているので間違っている部分があればコメント等で教えてほしいです。

 

参考先

-数学, 時系列分析, 機械学習/AI, 自然言語処理