Transformer Encoderの処理の流れとBERTの基本
Contents
はじめに
今回はAttention Is All You Needで発表されたTransformerモデルのEncoder部分(下図左側部分)について具体的な式の流れを雑に書いていきたいと思います。
またBERTにおけるTransformer Encoderの利用方法(〜入力と出力の利用方法)についても雑に書いていきたいと思います。
本記事は以下の書籍を参考にしています。興味のある方は参考ににして下さい:
特に本記事では各論文の詳細は説明しません。各論文の詳細に興味のある方は以下のリンクなどを参考にして下さい:
自然言語処理の必須知識 Transformer を徹底解説!
流れ
本記事で紹介するTransformer Encoderの処理は以下の通りです:
- 文章
- ↓ (1) 形態素解析
- 形態素
- ↓ (2) ベクトル化(語彙ベクトル\(e^T\), 文位置ベクトル\(e^S\), 文内位置ベクトル\(e^P\)の和)
- \(X = (x_1, x_2, \cdots, x_n) \)
- ↓ (3) Multihead Attention
- \(Y = (y_1, y_2, \cdots, y_n) = \left( \mathrm{Softmax}\left( \frac{Q_1 \cdot K_1}{\sqrt{d}}\right) V_1 \cdots \mathrm{Softmax}\left( \frac{Q_m \cdot K_m}{\sqrt{d}}\right) V_m \right) W^0 \)
- ↓ (4) Residual Connection
- \(Z = X + Y\)
- ↓ (5) Layer Normalization
- \(X' = \frac{\gamma}{\sigma} \odot \left( Z - \mu \right) + \beta\)
- ↓ (6) Feed Forward Network
- \(Y' = \mathrm{GERU}(X'W_1+b_1)W_2 +b_2 \)
- ↓ (7)Residual Connection
- \(Z' = X' + Y' \)
- ↓ (8) Layer Normalization
- \(Z''=\frac{\gamma'}{\sigma'} \odot \left( Z' - \mu' \right) + \beta'\)
(1)~(2)はBERTを想定した入力データの前処理、(3)~(8)はTransformer Encoderを表しています。以降、これらの処理について雑に紹介していきたいと思います:
(1) 形態素解析
入力:文章 S
出力:Sを形態素に分解した形態素(index)リスト [t_1, t_2, ..., t_n]
ここでは入力文章を形態素へ分解します。形態素、形態素解析についてはこちらなどを参照して下さい。ここでは単純に"文章を意味の確定する最小単位に分解する"程度の意味で用いることにします。
例:
入力:S = "明日は自然言語処理の勉強をしよう。"
出力':['明日', 'は', '自然', '言語', '処理', 'の', '勉強', 'を', 'しよ', 'う', '。']
更に、文頭には[CLS], 文末 or 文を分ける位置には[SEP], 未知単語には[UNK]など、"特殊トークン"と呼ばれるものを挿入し、かつ、各形態素を語彙の定義に従ってindexに変換します:
出力'':['[CLS]', '明日', 'は', '自然', '言語', '処理', 'の', '勉強', 'を', 'しよ', 'う', '。', '[SEP]']
出力:[2, 11475, 9, 1757, 1882, 2762, 5, 8192, 11, 2132, 205, 8, 3]
(2) ベクトル化
入力:(1)の出力リスト [t_1, t_2, ..., t_n]
出力:d次元ベクトルのリスト [x_1, x_2, ..., x_n], 但し \(x_i = e_i^T + e_i^S + e_i^P \)
ここでは各形態素(index)をベクトル化します。その為にサイズそれぞれ(語彙数, ベクトルの次元 = d), (2, d), (入力文章の最大形態素数, d)となる3つの行列\(E^T\), \(E^S\), \(E^P\)を用意します。
\(E^T\) : 語彙情報
まず\(E^T\)は語彙の数だけ行ベクトルを持つ行列で各行に各語彙のベクトル表現を持ちます。
\(E^S\) : 文位置情報
次に\(E^S\)は文の位置の数(文章は2文まで入力可能)だけ行ベクトルを持つ行列で各行に文の位置を表すベクトル表現を持ちます。
\(E^P\) : 文内位置情報
最後に\(E^P\)は入力文章の最大形態素数だけ行ベクトルを持つ行列で各行に形態素の位置を表すベクトル表現を持ちます。
これらを合わせて"形態素に対応する\(E^T\)の行ベクトル\(e^T\)"、"文の位置に対応する\(E^S\)の行ベクトル\(e^S\)"、そして"文章内の位置に対応する\(E^P\)の行ベクトル\(e^P\)"の総和をある形態素のベクトル\(x=e^T+e^S+e^P\)と定義します。
ここで\(E^T, E^S, E^P\)は学習パラメータになります。
(3) Multihead Attention
入力:(2)の出力リスト [x_1, x_2, ..., x_n]
出力:特徴量ベクトルのリスト[y_1, y_2, ..., y_n]
ここでは各形態素の特徴量を抽出します。特徴量の抽出にはAttentionを用います。ここではAttentionについて簡単に述べます。ある形態素ベクトル\(x\)に対し、線形変換\(W^Q, W^K, W^V\)を用いて、
- クエリ : \(q(x)=xW^Q\)
- キー : \(k(x)=xW^K\)
- バリュー : \(v(x)=xW^V\)
の三つの\(D\)次元ベクトルを生成し、\(x_i\)の特徴量\(y_i\)を
$$y_i = \sum_{j} \alpha_{ij} v(x_j)$$
で定義します。即ち\(x_i\)の特徴量を抽出する為に形態素ベクトル\(x_i\)自身(のバリュー\(v(x_i)\))だけでなく全ての形態素ベクトル(のバリュー)を用いることを表しています。
(メモ)\(v(x)\)は線形なので上記の\(y_i\)は\(v(\sum_{j} \alpha_{ij} x_i) \)とも書くことが出来、形態素ベクトルの重み付きの和が表す形態素ベクトルが、文章内でのこの形態素のベクトル表現である、と解釈できそう?
重み\(\alpha_{ij}\)は、形態素ベクトル\(x_i\)のクエリ\(q(x_i)\)と、他の形態素ベクトル\(x_j\)のキー\(k(x_j)\)を用いて
$$\tilde{(\alpha)}_{ij} = \frac{q(x_i)\cdot k(x_j)}{\sqrt{D}}$$
の様に定義します(分母は"ベクトルの次元で均している"程度にご理解ください)。即ち形態素\(x_i\)と他の形態素\(x_j\)との"関連度"をクエリ\(q(x_i)\)と\(k(x_j)\)の内積によって定義することを意味します。但し"重み"はその総和(\(\sum_{j}\alpha_{ij}\))が1であることを要求する為この\(\tilde{\alpha}_{ij}\)にSoftmax関数を作用させ正規化します:
$$\tilde{y}_i = \sum_{j}\mathrm{Softmax}\left( \frac{q(x_i)\cdot k(x_j)}{\sqrt{D}} \right) v(x_j)$$
この一連の操作は行列で表現し
$$\tilde{Y} = \mathrm{Softmax}\left( \frac{Q(X)\cdot K(X)}{\sqrt{D}} \right) V(X)$$
とまとめることが出来ます。この操作はAttention層と呼ばれ
$$\tilde{Y} = \mathrm{Attention}(Q(X), K(X), V(X))$$
と書かれます。
ここで\(W^Q, W^K, W^V\)は学習パラメータになります。
そしてMultiheadとは、このAttention層を\(k\)個並列で並べ(勿論パラメータ\(W^Q, W^K, W^V\)もAttention層の数分だけ用意し)て、\(k\)個の出力\(\tilde{Y}\)を最後に線形変換\(W^0\)で結合するものを指します:
$$Y = (\tilde{Y}_1, \tilde{Y}_2, \cdots, \tilde{Y}_k)W^0$$
ここで\(W^0\)は学習パラメータになります。
Multihead_Attntionは画像分野の畳み込みニューラルネットワークの様に文章の特徴量を複数のフィルター(ここではクエリとバリューの内積)で抽出するイメージです。
(4) Residual Connection
入力:(2)の出力リスト [x_1, x_2, ..., x_n]と(3)の出力リスト[y_1, y_2, ..., y_n]
出力:(1)と(2)の和のリスト[z_1, z_2, ..., z_n]
ここでは抽出した特徴量に元の形態素のベクトル情報を足すことで抽出された特徴量に元の情報を保持できる様にしたものです。
Residual Connectionは画像でイメージすると特徴量(画像)を元画像に重ねて元画像を強調する形で特徴量を保持するイメージです。
(5) Layer Normalization
入力:(4)の出力リスト[z_1, z_2, ..., z_n]
出力:標準化されたリスト[x'_1, x'_2, ..., x'_n]
ここでは入力リストの変数を標準化(平均0, 標準偏差1)する処理を行います。但し以下の様にスケール変換\(\gamma\)と並行移動\(\beta\)のパラメータを与えておきます:
$$X'=\frac{\gamma}{\sigma}\odot (Z-\mu) + \beta$$
ここで\(\beta, \gamma\)は学習パラメータになります。
(6) Feed Forward Network
入力:(5)の出力リスト[x'_1, x'_2, ..., x'_n]
出力:FFNの出力リスト[y'_1, y'_2, ..., y'_n]
ここでは全結合層を2層、1層目には活性化関数GELU(ReLUをなめらかにした様な活性化関数。詳しくはこちらを参照して下さい)を作用、2層目には活性化関数を作用しない、と計算するものです:
$$Y'=\mathrm{GELU}(X'W_1+b_1)W_2+b2$$
ここで\(W_1, W_2, b_1, b_2\)は学習パラメータになります。
(7) Residual Connection
入力:(5)の出力リスト[x'_1, x'_2, ..., x'_n]と(6)の出力リスト[y'_1, y'_2, ..., y'_n]
出力:(5)と(6)の和のリスト[z'_1, z'_2, ..., z'_n]
(4)と同様です。
(8) Layer Normalization
入力:和のリスト[z'_1, z'_2, ..., z'_n]
出力:標準化されたリスト[x''_1, x''_2, ..., x''_n]
(5)と同様です。
以上が処理の流れになります。
BERTの基本タスクと出力の使い方
BERTは2つの基本タスクを持ちます。1つはMasked Language Model(MLM)、もう一つはNext Sentence Prediction(NSP)です。
BERTでは与えられた文章のデータセットに対し、その一部をランダムに[MASK]に置き換え[MASK]予測するタスク(MLM)、また、連続する2つの文章をランダムに入れ替え2つの文章が連続しているかを予測するタスク(NSP)、の2つのタスクを(同時に)達成できるように学習します。
この方法によって人間が文章の意味やラベルを付与しなくてもモデルは各形態素が持つべきベクトルや特徴量を学習することができます(自身の情報を変形し学習用データとラベルが作れる=自己教師学習)。
このとき、BERTで用いたTransformer Encoderで出てきた特徴量として(出力層は若干追加がありますが詳細はまた別記事で)、
- [MASK]の特徴量は[MASK]に入るべき形態素の情報
- [CLS]の特徴量は2つの文章が連続しているかを表す情報
が得られます。
特にBERTはTransformer Encoderによって言語(形態素)の持つ特徴を取り出すことに主眼を置いているので、得られた特徴量を用いてその他のタスクにチューニングすることが出来ます。これをファインチューニングと呼びます。BERTが優れている点はオリジナルのモデルをファインチューニングすれば様々な自然言語処理タスクを精度良くこなすことが出来るところにあります。
これらの具体的な内容や実装についてはまた別な機会に。