Attention ¶ Attentionでは、入力の埋込x i \boldsymbol{x}_i x i に対して文脈の情報を追加したベクトルx i ′ \boldsymbol{x}_i' x i ′ を再構築していく。
このベクトルx i ′ \boldsymbol{x}_i' x i ′ は、各トークンの埋め込みから計算されたバリューベクトルたちv 1 , v 2 , … , v d \boldsymbol{v}_1, \boldsymbol{v}_2, \dots, \boldsymbol{v}_d v 1 , v 2 , … , v d に対して、どのトークンのバリューに注意を払うべきかの重みa 1 , a 2 , … , a d a_1, a_2, \dots, a_d a 1 , a 2 , … , a d を用いて重み付け和にしたものである。
x i ′ = a 1 v 1 + a 2 v 2 + ⋯ + a d v d \boldsymbol{x}_i' = a_1 \boldsymbol{v}_1 + a_2 \boldsymbol{v}_2 + \cdots + a_d \boldsymbol{v}_d x i ′ = a 1 v 1 + a 2 v 2 + ⋯ + a d v d 重みa 1 , a 2 , … , a d a_1, a_2, \dots, a_d a 1 , a 2 , … , a d はキーk k k とクエリq q q から計算された類似度のスコアs s s をsoftmaxにかけて合計1がになるように正規化したもの
s i j = q i T k j d s_{ij} = \frac{\boldsymbol{q}^T_i \boldsymbol{k}_j}{\sqrt{d}} s ij = d q i T k j ( a 1 , a 2 , … , a d ) = softmax ( s i ) = ( exp ( s i 1 ) ∑ j = 1 p exp ( s i j ) , … , exp ( s i p ) ∑ j = 1 p exp ( s i j ) ) \begin{align}
(a_1, a_2, \dots, a_d)
&= \text{softmax}( \boldsymbol{s}_i ) \\
&= \left(
\frac{ \exp(s_{i1}) }{ \sum^p_{j = 1} \exp(s_{ij}) }, \dots, \frac{ \exp(s_{ip}) }{ \sum^p_{j = 1} \exp(s_{ij}) }
\right)
\end{align} ( a 1 , a 2 , … , a d ) = softmax ( s i ) = ( ∑ j = 1 p exp ( s ij ) exp ( s i 1 ) , … , ∑ j = 1 p exp ( s ij ) exp ( s i p ) ) 単語埋め込み(word embedding)が入力となる。この分散表現も他のパラメータと同時に学習される
Positional Encoding ¶ 例えば翻訳を行うとき、入力と出力の系列のどのトークンがどの位置で入力されたのかを示す情報を付与する必要がある。
特に、Attentionは順番の変化に頑健(x 1 x_1 x 1 とx 2 x_2 x 2 を入れ替えても、y 1 y_1 y 1 とy 2 y_2 y 2 が元のそれと入れ替えた状態になり、入出力を集合とみなせば等価である)であるが、言語処理では系列性を評価したいため、位置情報を含める。
具体的には三角関数により位置をエンコーディングする
特徴要素の位置が偶数(2 i 2i 2 i )のときはsin \sin sin 、奇数(2 i + 1 2i+1 2 i + 1 )のときはcos \cos cos を使う。d e m b e d d_{embed} d e mb e d は埋め込みの次元数である
P E ( p o s , 2 i ) = sin ( p o s 1000 0 2 i d e m b e d ) P E ( p o s , 2 i + 1 ) = cos ( p o s 1000 0 2 i d e m b e d ) PE(pos, 2i) = \sin \left( \frac{pos}{ 10000^{ \frac{2i}{d_{embed}}} } \right)\\
PE(pos, 2i+1) = \cos \left( \frac{pos}{ 10000^{ \frac{2i}{d_{embed}}} } \right) PE ( p os , 2 i ) = sin ( 1000 0 d e mb e d 2 i p os ) PE ( p os , 2 i + 1 ) = cos ( 1000 0 d e mb e d 2 i p os ) Positional Embedding ¶ GPTではこちらを利用
Scaled Dot-Product Attention ¶ 入力埋込に文脈の情報を付与していく。
Q, K, Vはいずれも入力X ∈ R n m a x × d e m b e d \boldsymbol{X} \in \mathbb{R}^{n_{max} \times d_{embed}} X ∈ R n ma x × d e mb e d から変換されたもの。n m a x n_{max} n ma x はトークンの最大長、d e m b e d d_{embed} d e mb e d は埋め込み次元数
Q = X W Q K = X W K V = X W V Q = X W^Q\\
K = X W^K\\
V = X W^V Q = X W Q K = X W K V = X W V 重みW Q , W K , W V W^Q, W^K, W^V W Q , W K , W V は学習して推定していく。self-attentionだとsource = targetなので入力のベクトルを再現するように重みを推定するっぽい?
Q , K , V ∈ R n m a x × d e m b e d Q, K, V \in \mathbb{R}^{n_{max} \times d_{embed}} Q , K , V ∈ R n ma x × d e mb e d s i j = q i ⊤ k j = ∑ l = 1 d e m b e d q i l k j l s_{ij} = \boldsymbol{q}_i ^\top \boldsymbol{k}_j
= \sum^{d_{embed}}_{l = 1} q_{il} k_{jl} s ij = q i ⊤ k j = l = 1 ∑ d e mb e d q i l k j l a j = softmax ( s i j d e m b e d ) = 1 d e m b e d exp ( s i j ) ∑ j = 1 n exp ( s i j ) a_j = \text{softmax}\left( \frac{ s_{ij} }{ \sqrt{ d_{embed} } } \right)
= \frac{1}{ \sqrt{ d_{embed} } } \frac{ \exp(s_{ij}) }{ \sum^n_{j=1} \exp(s_{ij}) } a j = softmax ( d e mb e d s ij ) = d e mb e d 1 ∑ j = 1 n exp ( s ij ) exp ( s ij ) 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)
Aarray([[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 @ Varray([[-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 ( Q K T d k ) V \text{Attention}(Q, K, V)
= \text{softmax}
\left(
\frac
{ Q K^T }
{ \sqrt{d_k} }
\right)
V Attention ( Q , K , V ) = softmax ( d k Q K T ) V 単純化のためQ, Kの行列からベクトルをとってきて示すことにする。qとkの内積
内積は類似度に使われる(cf. コサイン類似度)
softmax ( q ⋅ k d ) \newcommand{\b}[1]{\boldsymbol{#1}}
\text{softmax}
\left(
\frac{\b{q} \cdot \b{k}}
{\sqrt{d}}
\right) softmax ( d q ⋅ k ) これは
クエリ \b{q} とキー \b{k} の内積(=類似度)を計算する
次元数d d d によって正規化する(内積は次元数が多いほど値も大きくなるので)
softmaxによって確率値へと値の範囲を整える
という処理になる。いわば確率ベクトルを返すようなものになる。
例えばi i i 番目のトークンだけこの出力値が1だとして、ほかが0だとすると、V V V のi i i 番目のベクトルだけが出力となる
v i = ( v 1 , ⋯ , v d ) V = ( v 1 v 2 ⋮ v n ) p = ( p 1 , ⋯ , p n ) = softmax ( q ⋅ k d ) \newcommand{\b}[1]{\boldsymbol{#1}}
\b{v}_i = (v_1, \cdots, v_d)
\\
\b{V} =
\begin{pmatrix}
\b{v}_1\\
\b{v}_2\\
\vdots\\
\b{v}_n
\end{pmatrix}
\\
\b{p} = (p_1, \cdots, p_n) =
\text{softmax}
\left(
\frac{\b{q} \cdot \b{k}}
{\sqrt{d}}
\right) v i = ( v 1 , ⋯ , v d ) V = ⎝ ⎛ v 1 v 2 ⋮ v n ⎠ ⎞ p = ( p 1 , ⋯ , p n ) = softmax ( d q ⋅ k ) とする
Undefined control sequence: \b at position 15: \begin{align}
\̲b̲{p} \b{V}
&= (…
\begin{align}
\b{p} \b{V}
&= (p_1, \cdots, p_n)
\begin{pmatrix}
v_{11} & \cdots & v_{1d}\\
\vdots & \ddots & \vdots\\
v_{n1} & \cdots & v_{nd}\\
\end{pmatrix}
\\
&=
\begin{pmatrix}
p_1 v_{11} + \cdots + p_n v_{n1},\
\cdots, \
p_1 v_{1d} + \cdots + p_n v_{nd}
\end{pmatrix}
\\
&= p_1 (v_{11}, \cdots, v_{1d}) + \cdots + p_n (v_{n1}, \cdots, v_{nd})
\\
&= \sum_i^n p_i \b{v}_i
\end{align}Multi-head attention ¶ 元のベクトルを等分割して複数のattentionに通す。
multiにするメリットは
並列計算可能になる
ソフトマックスはexpが入っていて極端な値になりやすい → 単一のattentionではなく複数使うことで、複数の観点から評価する(アンサンブル的な?
参考文献 ¶ Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A. N., ... & Polosukhin, I. (2017). Attention is all you need. Advances in neural information processing systems, 30.
30分で完全理解するTransformerの世界
The Illustrated Transformer
Encoder-Decoder ネットワーク [ディープラーニングの文脈で] | CVMLエキスパートガイド
【深層学習】Transformer - Multi-Head Attentionを理解してやろうじゃないの【ディープラーニングの世界vol.28】#106 #VRアカデミア #DeepLearning - YouTube
BERT以降の事前学習済みモデルのトレンドと主要モデルを紹介! Part 1 学習方法編 - ELYZA Tech Blog
[2106.04554] A Survey of Transformers