Transformerのアルゴリズム#

概要#

Vaswani, et al. (2017). Attention is all you need. で提案されたDeep Learningの新しいアーキテクチャ。

提案されものはEncoder-Decoder型。

GPTシリーズはDecoderのみでもっとシンプル

処理の流れ#

出所:Attention (machine learning) - Wikipedia

Attention#

Attentionでは、入力の埋込xiに対して文脈の情報を追加したベクトルxiを再構築していく。

このベクトルxiは、各トークンの埋め込みから計算されたバリューベクトルたちv1,v2,,vdに対して、どのトークンのバリューに注意を払うべきかの重みa1,a2,,adを用いて重み付け和にしたものである。

xi=a1v1+a2v2++advd

重みa1,a2,,adはキーkとクエリqから計算された類似度のスコアsをsoftmaxにかけて合計1がになるように正規化したもの

sij=qiTkjd
(a1,a2,,ad)=softmax(si)=(exp(si1)j=1pexp(sij),,exp(sip)j=1pexp(sij))

inputs#

単語埋め込み(word embedding)が入力となる。この分散表現も他のパラメータと同時に学習される

Positional Encoding#

例えば翻訳を行うとき、入力と出力の系列のどのトークンがどの位置で入力されたのかを示す情報を付与する必要がある。

特に、Attentionは順番の変化に頑健(x1x2を入れ替えても、y1y2が元のそれと入れ替えた状態になり、入出力を集合とみなせば等価である)であるが、言語処理では系列性を評価したいため、位置情報を含める。

具体的には三角関数により位置をエンコーディングする

特徴要素の位置が偶数(2i)のときはsin、奇数(2i+1)のときはcosを使う。dembedは埋め込みの次元数である

PE(pos,2i)=sin(pos100002idembed)PE(pos,2i+1)=cos(pos100002idembed)

Positional Embedding#

GPTではこちらを利用

Scaled Dot-Product Attention#

入力埋込に文脈の情報を付与していく。

Q, K, Vはいずれも入力XRnmax×dembedから変換されたもの。nmaxはトークンの最大長、dembedは埋め込み次元数

Q=XWQK=XWKV=XWV

重みWQ,WK,WVは学習して推定していく。self-attentionだとsource = targetなので入力のベクトルを再現するように重みを推定するっぽい?

Q,K,VRnmax×dembed
sij=qikj=l=1dembedqilkjl
aj=softmax(sijdembed)=1dembedexp(sij)j=1nexp(sij)
import numpy as np

n, d = 5, 3
np.random.seed(0)
Q = np.random.normal(size=(n, d))
K = np.random.normal(size=(n, d))

def softmax(x):
    return np.exp(x) / np.exp(x).sum()

S = (Q @ K.T) / d # Sはn*n行列
A = np.apply_along_axis(softmax, 0, S).round(3)
A
array([[0.173, 0.105, 0.163, 0.301, 0.24 ],
       [0.432, 0.384, 0.447, 0.206, 0.189],
       [0.129, 0.284, 0.152, 0.209, 0.112],
       [0.127, 0.065, 0.1  , 0.123, 0.289],
       [0.139, 0.162, 0.138, 0.16 , 0.17 ]])
V = np.random.normal(size=(n, d))
A @ V
array([[-0.48113832,  0.37745091, -0.75004649],
       [-0.52850805,  0.71992637, -0.88546848],
       [-0.60983733,  0.13207693, -0.48285972],
       [-0.5163397 ,  0.58045241, -0.46327048],
       [-0.46800559,  0.32599458, -0.46536853]])

参考#

Attention(Q,K,V)=softmax(QKTdk)V

単純化のためQ, Kの行列からベクトルをとってきて示すことにする。qとkの内積

内積は類似度に使われる(cf. コサイン類似度)

softmax(qkd)

これは

  1. クエリqとキーkの内積(=類似度)を計算する

  2. 次元数dによって正規化する(内積は次元数が多いほど値も大きくなるので)

  3. softmaxによって確率値へと値の範囲を整える

という処理になる。いわば確率ベクトルを返すようなものになる。

例えばi番目のトークンだけこの出力値が1だとして、ほかが0だとすると、Vi番目のベクトルだけが出力となる

vi=(v1,,vd)V=(v1v2vn)p=(p1,,pn)=softmax(qkd)

とする

pV=(p1,,pn)(v11v1dvn1vnd)=(p1v11++pnvn1, , p1v1d++pnvnd)=p1(v11,,v1d)++pn(vn1,,vnd)=inpivi

Multi-head attention#

元のベクトルを等分割して複数のattentionに通す。

multiにするメリットは

  1. 並列計算可能になる

  2. ソフトマックスはexpが入っていて極端な値になりやすい → 単一のattentionではなく複数使うことで、複数の観点から評価する(アンサンブル的な?

#

Attentionの可視化#

トークン間の距離を可視化。

AttentionViz Docs

動かせるデモサイトあり

参考文献#