Attentionの式を初めて読むと、多くの人が同じ場所で立ち止まります。
$$ \text{Attention}(Q, K, V) = \mathrm{softmax}\!\left(\frac{QK^\top}{\sqrt{d_k}}\right) V $$
self-attention では、この $Q$(クエリ)・$K$(キー)・$V$(バリュー)をすべて同じ入力 $X$ から作ります。具体的には、$Q = XW_Q$、$K = XW_K$、$V = XW_V$ と、3枚の別々の重み行列で $X$ を射影します。
ここで素朴な疑問が湧きます。どうせ同じ $X$ から作るなら、なぜ3つに分けるのか? いっそ $Q = K = V = X$ とそのまま使えば、重み行列が3枚も要らず、パラメータも節約できそうです。実際、Attention の説明では「$Q$ と $K$ の内積で類似度を測る」と言われるので、「同じものの内積なら、自分自身との類似度を測るだけでは?」と感じても不思議ではありません。
結論を先に言えば、この射影こそが Attention を「使いものになる仕組み」にしている急所です。$X$ をそのまま使うと、スコア行列が数学的に対称になり、しかも自分自身への注目が支配的になってしまいます。「私はりんごを食べた」という文で「食べた」が「りんご」に注目する度合いと、「りんご」が「食べた」に注目する度合いが、常に強制的に等しくなるのです。言語の関係は本来、向きを持つ非対称なものなのに、です。
この「なぜ3つに射影するのか」を理解すると、次のような場面で役に立ちます。
- モデル設計: なぜ $W_Q W_K^\top$ が本質で、それが $d\times d$ 行列の低ランク(rank $\le d_k$)分解になっているのか。パラメータ効率の設計判断が腹落ちする
- Multi-Head の意味: ヘッドごとに違う射影を持つことが、なぜ「違う部分空間で違う関係を見る」ことになるのかが分かる
本記事の内容
- $Q$・$K$・$V$ の3役を「図書館検索」のアナロジーで直感的に理解する
- $Q=K=V=X$ にすると、スコア行列が対称かつ対角支配になることを実測で確認する
- $W_Q, W_K$ を挟むと $QK^\top = X(W_Q W_K^\top)X^\top$ という学習可能な双線形形式になり、非対称な関係を表現できること
- $M = W_Q W_K^\top$ が rank $\le d_k$ の低ランク分解であること(パラメータ効率)
- $K$ と $V$ を分ける理由(辞書のキーと値)と Multi-Head との関係
- PyTorch のトイタスクで、射影なしが非対称な関係を学習できず精度が落ちることの実測
前提知識
この記事を読む前に、以下の記事を読んでおくと理解が深まります。
- self-attentionとは?Transformerの核心をわかりやすく解説 — Q・K・V と内積スコアの全体像
- アテンションを直感で理解する — 検索アナロジーによる QKV の直感
- Attentionの数式を行列の形で完全に理解する — QK^T・softmax・重み付き和を行列の形で追う

上の図が、この記事で追いかける中心的なイメージです。1冊の本(入力トークン $x_i$)から、「探すときの言葉(クエリ)」「本を見分ける背表紙(キー)」「実際に読む中身(バリュー)」という3つの異なる役割の表現を、それぞれ別の行列 $W_Q, W_K, W_V$ で作り分けます。同じ本でも、探すときに使う言葉と、棚で見分ける背表紙と、開いて読む中身はまったくの別物です。なぜ別物である必要があるのか、を数式と実測で解き明かしていきます。
Q・K・V の3役 — 図書館検索のアナロジー
まず、$Q$・$K$・$V$ が何をする役なのかを、図書館で本を探す場面で捉えましょう。
あなたが「甘い果物について知りたい」と思って図書館に来たとします。このとき起きることは3段階です。
- クエリ($Q$): あなたの頭の中にある「甘い果物」という探すための言葉。何を探しているかを表します。
- キー($K$): 各本の背表紙やタイトルという照合される目印。あなたの探す言葉と本の目印を突き合わせて、どの本が関係ありそうかを判断します。
- バリュー($V$): 実際に本を開いて読む中身の情報。関係ありそうな本から、実際に取り出す内容です。
Attention はこの3段階をそのまま数式にしたものです。クエリとキーの内積 $QK^\top$ で「探す言葉」と「目印」の一致度(=どの本に注目すべきか)を測り、softmax で重みにして、その重みでバリュー(中身)を混ぜて取り出します。

図のように、$N$ 個のトークンからなる入力系列 $X$(形は $N\times d$)に、3枚の重み $W_Q, W_K, W_V$ を掛けて $Q, K, V$ を作ります。ここで大事なのは、3枚の重みはすべて学習で決まる別々の行列だということです。初期値はランダムで、学習を通じて「探す言葉に最適な表現」「照合に最適な表現」「取り出すのに最適な表現」へと、それぞれ独立に育っていきます。
ここで先ほどの疑問に戻ります。図書館の例なら「探す言葉」「背表紙」「中身」が別物なのは当たり前です。でも self-attention では、これらを全部同じ本 $x_i$から作ります。同じ本から作るのに、なぜ3役に分ける必要があるのでしょうか。この問いに答えるには、「もし分けなかったら何が起きるか」を具体的に見るのが一番です。
もし Q=K=V=X だったら — スコア行列が対称になる
一番シンプルな設計、つまり射影をやめて $Q = K = V = X$ とそのまま使う場合を考えます。このときスコア行列(softmax に入る前の $QK^\top$)は
$$ S = XX^\top $$
になります。この $XX^\top$ は線形代数でグラム行列と呼ばれ、$(i, j)$ 成分は $x_i \cdot x_j$(トークン $i$ とトークン $j$ の内積)です。ここに決定的な性質があります。内積は順番を入れ替えても同じ、つまり $x_i \cdot x_j = x_j \cdot x_i$ です。したがって、
$$ S_{ij} = x_i \cdot x_j = x_j \cdot x_i = S_{ji} $$
スコア行列 $S$ は必ず対称になります。$S = S^\top$ です。これが何を意味するか、言葉に直すと重大です。「トークン $i$ がトークン $j$ に注目する生スコア」と「トークン $j$ がトークン $i$ に注目する生スコア」が、構造的に、学習しようがしまいが、常に等しいのです。
実際に確かめてみましょう。ランダムな入力 $X$ でスコア行列 $S = XX^\top/\sqrt{d}$ を作り、その非対称性 $\max|S – S^\top|$ を測ります。
import numpy as np
rng = np.random.default_rng(7)
N, d = 8, 32
X = rng.standard_normal((N, d)) # 8トークン、各32次元
S = X @ X.T / np.sqrt(d) # 射影なしスコア = グラム行列
asym = np.abs(S - S.T).max()
print(f"射影なしスコアの非対称性 max|S - S^T| = {asym:.2e}")
このコードの出力は次の通りです。
射影なしスコアの非対称性 max|S - S^T| = 0.00e+00
非対称性は厳密にゼロです。数値誤差すら出ません(対称行列を作る計算がそのまま対称だから)。ヒートマップで見ても一目瞭然です。

左がスコア行列 $S$、右が $S – S^\top$ です。右がべた塗りのゼロ(完全に無地)になっていることが、対称性の動かぬ証拠です。言語では「形容詞は名詞を修飾する」「動詞は目的語を取る」といった向きのある関係が本質なのに、射影なしではこの向きを一切表現できません。$i \to j$ と $j \to i$ が常にセットで同じ強さになってしまうのです。
対称性はスコアの段階の話でした。次に、softmax を通したあとの注意重みを見ると、もう一つの弊害が現れます。
射影なしのもう一つの弊害 — 自己注目が支配的になる
スコア $S = XX^\top$ の対角成分は $S_{ii} = x_i \cdot x_i = \|x_i\|^2$、つまりベクトルのノルムの2乗です。これは常に非負で、しかも「自分自身との内積」なので、他のトークンとの内積 $x_i \cdot x_j$ よりも大きくなりやすいという性質があります。ランダムな高次元ベクトルどうしはほぼ直交する(内積が0に近い)一方、自分自身との内積はノルム2乗でしっかり正の値を持つからです。
その結果、softmax を通すと対角成分(自分自身への注目)に重みが集中します。実測で確認しましょう。
import numpy as np
def softmax_rows(S):
S = S - S.max(axis=-1, keepdims=True)
e = np.exp(S)
return e / e.sum(axis=-1, keepdims=True)
rng = np.random.default_rng(11)
N, d = 8, 32
X = rng.standard_normal((N, d))
S = X @ X.T / np.sqrt(d)
A = softmax_rows(S) # 注意重み
diag_mean = np.mean(np.diag(A)) # 対角(自己注目)の平均
off_mean = (A.sum() - np.trace(A)) / (N * (N - 1)) # 非対角の平均
print(f"対角(自己注目)の平均重み = {diag_mean:.3f}")
print(f"非対角(他への注目)の平均重み = {off_mean:.3f}")
出力は次の通りです。
対角(自己注目)の平均重み = 0.923
非対角(他への注目)の平均重み = 0.011
結果は極端です。各トークンは注意の重みの約92%を自分自身に向けています。他のトークンへの注目は平均1.1%しかありません。これでは Attention が「文脈の中の他のトークンから情報を集める」という本来の役割をほとんど果たせません。ほぼ「自分を見ているだけ」の層になってしまいます。

左のヒートマップでは、赤枠で囲った対角線だけが明るく(重みが大きく)、それ以外は暗いままです。右の棒グラフが示す通り、自己注目0.923に対して他への注目は0.011。文脈を混ぜるどころか、自分に閉じこもった注意になっています。
ここまでで、射影なし($Q=K=V=X$)には2つの致命的な問題があると分かりました。(1) スコアが強制的に対称になり、向きのある関係を表現できない。(2) 自己注目が支配的で、他トークンから情報を集められない。 では、$W_Q$ と $W_K$ を挟むと、この2つがどう解決されるのでしょうか。
W_Q・W_K を挟むと「学習可能な双線形形式」になる
$Q = XW_Q$、$K = XW_K$ と射影してからスコアを作ると、どうなるかを式で追います。ゴールは、$QK^\top$ が $X$ に関する双線形形式の形になることを示すことです。
まず定義を代入します。
$$ QK^\top = (XW_Q)(XW_K)^\top $$
転置の性質 $(AB)^\top = B^\top A^\top$ を右側に使うと、$(XW_K)^\top = W_K^\top X^\top$ です。これを代入して、
$$ QK^\top = X W_Q W_K^\top X^\top $$
ここで、真ん中の2枚の重みをひとまとめにして $M = W_Q W_K^\top$ と置きます。$W_Q$ が $d\times d_k$、$W_K$ が $d\times d_k$ なので、$M = W_Q W_K^\top$ は $d\times d$ の正方行列です。すると、
$$ QK^\top = X M X^\top, \qquad \text{成分で書くと}\quad (QK^\top)_{ij} = x_i^\top M\, x_j $$
この $x_i^\top M x_j$ という形を双線形形式と呼びます。$M$ という「間に挟まった行列」が、2つのベクトル $x_i, x_j$ の関係を測る学習可能な物差しになっているのです。

図のように、$QK^\top$ は「$X$ を左から、$X^\top$ を右から、真ん中の $M$ で挟んだ」構造をしています。ここが射影なしとの決定的な違いです。射影なしのスコアは $XX^\top = X\,I\,X^\top$、つまり真ん中が単位行列 $I$に固定されていました。単位行列は対称なので、スコアも対称になるしかありませんでした。射影を入れると、真ん中を任意の(非対称でもよい)行列 $M$ に置き換えられます。
$M$ が非対称、つまり $M \ne M^\top$ なら、
$$ (QK^\top)_{ij} = x_i^\top M x_j \ne x_j^\top M x_i = (QK^\top)_{ji} $$
となり、スコアを非対称にできます。これで「$i \to j$ と $j \to i$ を別々の強さにする」ことが可能になり、向きのある関係を表現できます。実際に、ランダムな $W_Q, W_K$ でスコアの非対称性を測ってみます。
import numpy as np
rng = np.random.default_rng(3)
N, d, dk = 8, 32, 16
X = rng.standard_normal((N, d))
WQ = rng.standard_normal((d, dk)) / np.sqrt(d)
WK = rng.standard_normal((d, dk)) / np.sqrt(d)
Q = X @ WQ
K = X @ WK
S = Q @ K.T / np.sqrt(dk) # 射影ありスコア
asym = np.abs(S - S.T).max()
print(f"射影ありスコアの非対称性 max|S - S^T| = {asym:.3f}")
出力は次の通りです。
射影ありスコアの非対称性 max|S - S^T| = 3.881
射影なしでは厳密に0だった非対称性が、射影を入れるだけで3.881まで立ち上がりました。ランダムな重みですらこれだけ非対称になり、学習でこの非対称性を「意味のある向き」に育てられます。

右の $S – S^\top$ が、射影なしのときの無地(ゼロ)とは打って変わって、正負のはっきりしたパターンを持っています。これが「$i$ から $j$ への注目」と「$j$ から $i$ への注目」を別々に設定できるようになった証拠です。$W_Q$ と $W_K$ を別の行列にすること自体が、非対称性を生む源泉になっています。
$M = W_Q W_K^\top$ という見方をすると、もう一つ設計上の重要な事実が見えてきます。この $M$ は「$d\times d$ の行列を rank $d_k$ で分解したもの」だという事実です。
M = W_Q W_K^T は低ランク分解 — パラメータ効率の設計
「向きのある関係を表したいなら、$d\times d$ の行列 $M$ を1枚学習すればいいのでは?」と思うかもしれません。実際、$QK^\top = XMX^\top$ なので、本質的に効いているのは $M$ という1枚の $d\times d$ 行列です。ならばなぜ、わざわざ $W_Q$ と $W_K$ の2枚に分けるのでしょうか。
理由はパラメータ効率です。$M$ を直接持つと $d^2$ 個のパラメータが必要です。一方 $W_Q, W_K$ はそれぞれ $d\times d_k$ なので、合わせて $2 d d_k$ 個。実際の Transformer では $d_k$ は $d$ よりずっと小さく(例えば $d=512$ をヘッド数8で割って $d_k=64$)、$2 d d_k = 2 \times 512 \times 64$ は $d^2 = 512^2$ の4分の1です。
しかも $M = W_Q W_K^\top$ は、$d\times d_k$ と $d_k\times d$ の積なので、線形代数の基本性質から
$$ \mathrm{rank}(M) \le d_k $$
を満たします。つまり $M$ は「$d\times d$ の見た目だが、実質 $d_k$ 次元ぶんの情報しか持たない低ランク行列」です。これは制約ではありますが、「関係の物差しは低ランクで十分」という設計判断でもあります。実測してみましょう。
import numpy as np
rng = np.random.default_rng(3)
d, dk = 32, 16
WQ = rng.standard_normal((d, dk)) / np.sqrt(d)
WK = rng.standard_normal((d, dk)) / np.sqrt(d)
M = WQ @ WK.T # d×d だが rank ≤ dk
sv = np.linalg.svd(M, compute_uv=False) # 特異値
n_nonzero = int(np.sum(sv > 1e-9))
print(f"M の形 = {M.shape}, d_k = {dk}")
print(f"非ゼロ特異値の数(実効ランク) = {n_nonzero}")
print(f"上位 {dk} 個の特異値が全体に占める割合 = {sv[:dk].sum()/sv.sum():.3f}")
出力は次の通りです。
M の形 = (32, 32), d_k = 16
非ゼロ特異値の数(実効ランク) = 16
上位 16 個の特異値が全体に占める割合 = 1.000
$M$ は $32\times 32$ の行列ですが、非ゼロの特異値はちょうど 16個($= d_k$) しかありません。17番目以降は厳密にゼロで、上位16個で情報の100%を占めています。$32\times 32 = 1024$ 個のパラメータ空間のうち、実際に使われているのは rank 16 のぶんだけ、というわけです。

左の棒グラフを見ると、特異値が16番目(赤い破線=$d_k$ の壁)でぷつりと途切れ、それ以降はゼロです。$W_Q, W_K$ の2枚に分ける設計は、「$d\times d$ のフル行列は要らない、rank $d_k$ で十分」という判断を、パラメータ数の節約と同時に実現しているのです。$d_k$ を選ぶことは、この関係の物差しの「表現力の上限」を選ぶことでもあります。
ここまでで $Q$ と $K$ を分ける理由(非対称・低ランク)が分かりました。残るは $V$ です。なぜ $K$ と $V$ をさらに別の行列で作るのでしょうか。
K と V を分ける理由 — 照合用と取り出す中身は別物
$K$(キー)と $V$(バリュー)の役割の違いに戻りましょう。$K$ は「クエリと照合して、どこに注目すべきかを決める」ために使われます。$V$ は「注目が決まったあと、実際に取り出して混ぜる中身」です。この2つは Attention の式の中でまったく違う場所に現れます。
$$ \text{Attention} = \underbrace{\mathrm{softmax}\!\left(\frac{QK^\top}{\sqrt{d_k}}\right)}_{K \text{ は「どこを見るか」を決める}} \underbrace{V}_{V \text{ は「何を取り出すか」}} $$
$K$ は softmax の中(重みの計算)に、$V$ は softmax の外(重み付き和の対象)に入ります。役割が違えば、最適な表現も違います。辞書に例えると分かりやすいです。

辞書では、見出し語(キー)は「引くときに探しやすい形」、語義の説明(バリュー)は「引いたあとに役立つ中身」です。”bank” という見出し語は照合のための短い目印ですが、その中身は「土手/銀行…」という豊かな情報です。もし $K = V$ に縛ると、1つのベクトルが「照合しやすさ」と「取り出す中身の豊かさ」を同時に兼ねる制約を負います。照合に最適な向きと、中身として運びたい情報は別物なので、両立させると両方が中途半端になります。$W_K$ と $W_V$ を分けることで、キーは照合に専念し、バリューは中身の運搬に専念できます。
さらに、$V$ の次元 $d_v$ は $K$ の次元 $d_k$ と独立に選べます。照合のための物差しはコンパクト(小さい $d_k$)でよくても、運ぶ中身はもっと豊かにしたい、といった設計が可能になります。3つを別々の行列で射影する設計は、こうした自由度をすべて開いておくためのものです。
役割ごとに表現を分けることの利点が見えてきました。では、この「役割を分ける」発想を、実際のタスクで検証してみましょう。射影なしが本当に非対称な関係を学習できないのかを、小さな実験で確かめます。
トイタスクで検証 — 射影なしは非対称な関係を学べない
「射影なしは向きのある関係を表現できない」という主張を、実際に学習させて確かめます。次のようなトイタスクを設計します。
- 各位置に、系列内で相異なるトークンと、ランダムなペイロード(数値ラベル)を置く
- 各位置 $i$ の正解は、「自分のトークンより1つ小さいトークン $t_i – 1$ を持つ位置のペイロード」
この「$t$ が $t-1$ を指す」という関係は本質的に非対称です。$t$ から $t-1$ への矢印はあっても、$t-1$ から $t$ への矢印とは別物だからです。射影なし($Q=K=V=X$)ではスコアが対称になるので、この向きのある参照を学べないはずです。1ヘッドの Attention で、射影あり/なしを比べます。
import numpy as np
import torch
import torch.nn as nn
def build_task(rng, n, L, V, P):
toks = np.stack([rng.permutation(V)[:L] for _ in range(n)]) # 系列内で相異なる
pays = rng.integers(0, P, size=(n, L))
tgt = np.zeros((n, L), dtype=np.int64)
for s in range(n):
pos_of = {t: j for j, t in enumerate(toks[s])}
for i in range(L):
want = (toks[s, i] - 1) % V # 1つ前のトークン
tgt[s, i] = pays[s, pos_of.get(want, i)]
return torch.tensor(toks), torch.tensor(pays), torch.tensor(tgt)
class AttnModel(nn.Module):
def __init__(self, V, P, d, dk, project=True):
super().__init__()
self.project = project
self.tok = nn.Embedding(V, d); self.pay = nn.Embedding(P, d); self.dk = dk
if project:
self.Wq = nn.Linear(d, dk, bias=False); self.Wk = nn.Linear(d, dk, bias=False)
self.Wv = nn.Linear(d, dk, bias=False); self.head = nn.Linear(dk, P, bias=False)
else:
self.head = nn.Linear(d, P, bias=False)
def forward(self, tok, pay):
h = self.tok(tok) + self.pay(pay)
if self.project:
Q, K, Vv = self.Wq(h), self.Wk(h), self.Wv(h); scale = self.dk ** 0.5
else:
Q = K = Vv = h; scale = h.shape[-1] ** 0.5
A = torch.softmax(torch.matmul(Q, K.transpose(1, 2)) / scale, dim=-1)
return self.head(torch.matmul(A, Vv))
def train(project, seed=0, epochs=600):
torch.manual_seed(seed); rng = np.random.default_rng(seed)
V, P, L, d, dk = 8, 8, 8, 32, 16
tk, pa, tg = build_task(rng, 800, L, V, P)
tkT, paT, tgT = build_task(rng, 400, L, V, P)
model = AttnModel(V, P, d, dk, project=project)
opt = torch.optim.Adam(model.parameters(), lr=5e-3); lossf = nn.CrossEntropyLoss()
for _ in range(epochs):
opt.zero_grad()
loss = lossf(model(tk, pa).reshape(-1, P), tg.reshape(-1))
loss.backward(); opt.step()
with torch.no_grad():
acc = (model(tkT, paT).argmax(-1) == tgT).float().mean().item()
return acc
acc_p = train(project=True, seed=0)
acc_u = train(project=False, seed=0)
print(f"射影あり (Q,K,V別射影) の精度 = {acc_p:.3f}")
print(f"射影なし (Q=K=V=X) の精度 = {acc_u:.3f}")
print(f"ランダム推測の精度 = {1/8:.3f}")
出力は次の通りです。
射影あり (Q,K,V別射影) の精度 = 1.000
射影なし (Q=K=V=X) の精度 = 0.161
差は決定的です。射影ありは精度1.000(完璧)で「1つ前のトークンを引く」という非対称な参照を学習しきったのに対し、射影なしは0.161、ランダム推測の0.125をわずかに上回るだけで、ほとんど何も学べていません。同じデータ・同じ学習設定で、射影の有無だけがこの差を生みます。
学習後の注意行列を見ると、何が起きているかがはっきりします。

位置をトークンの昇順に並べ替えると、理想の注意は「$t \to t-1$」を表す副対角線(対角の1つ隣)になります。左(射影あり)はまさにこの副対角にきれいに集中していて、各クエリが「1つ前のトークン」を正確に指しています。右(射影なし)はパターンがぼやけ、狙った位置を指せていません。対称性の制約が、向きのある参照の学習を妨げているのです。
学習曲線でも同じ傾向が確認できます。

左の損失は射影あり(赤)がぐんぐん下がるのに対し、射影なし(灰破線)は高止まりします。右の精度も、射影ありが1.0へ駆け上がる一方、射影なしはランダム水準に張り付いたままです。「3つに射影する」ことが、非対称な関係を扱うために本質的だと分かります。
トイタスクで射影の効果が確認できました。最後に、この射影を「ヘッドごとに複数持つ」とどうなるか、Multi-Head との関係を見ておきましょう。
Multi-Head との関係 — 違う射影で違う関係を見る
ここまでは1組の $W_Q, W_K, W_V$ を考えてきました。実際の Transformer は、この射影をヘッドごとに複数持ちます。ヘッド $h$ はそれぞれ独自の $W_Q^h, W_K^h, W_V^h$ を学習します。射影が「$X$ を特定の部分空間に落とす操作」であることを思い出すと、ヘッドごとに違う射影を持つことの意味が見えてきます。各ヘッドは、$X$ を違う部分空間に落として、違う種類の関係を見るのです。

図は3つのヘッドがそれぞれ違う注意パターンを持つ様子です。あるヘッドは近くのトークンに注目し、別のヘッドは文頭に注目し、また別のヘッドは広く分散して注目します。もし射影が1組しかなければ、こうした複数の関係を1枚のスコア行列に押し込めることになり、表現力が足りません。ヘッドごとに $W_Q^h, W_K^h$ を分けることで、「近傍関係を見る物差し $M_1 = W_Q^1 (W_K^1)^\top$」「文頭関係を見る物差し $M_2$」…と、関係ごとに専用の低ランクな物差しを用意できます。
3つに射影する設計は、Multi-Head と組み合わさって初めて本領を発揮します。1トークンから3役を作り、それをヘッドの数だけ並列に用意する。この二段構えが、Transformer の柔軟な注意を支えています。
ここまでの流れを、原論文のブロック図で確認しておきましょう。

出典: Vaswani et al., “Attention Is All You Need”, NeurIPS 2017, Fig.2
論文の Figure 2 右側(Multi-Head Attention)を見ると、入力の $V, K, Q$ がそれぞれ Linear(=線形射影、本記事の $W_V, W_K, W_Q$) を通ってから Scaled Dot-Product Attention に入り、それが $h$ 個並列に並んでいます。左側の Scaled Dot-Product Attention は、本記事で見た $\mathrm{softmax}(QK^\top/\sqrt{d_k})V$ の中身(MatMul → Scale → SoftMax → MatMul)です。図の一番下で $Q, K, V$ が別々の入力口として描かれ、それぞれ独立に Linear を通ることが、「3つに射影する」設計そのものを表しています。
まとめ
本記事では、self-attention がなぜ同じ入力 $X$ から $Q$・$K$・$V$ の3つを別々に射影して作るのかを、直感・数式・実測の3面から解説しました。
- $Q$・$K$・$V$ は「探す言葉」「照合する目印」「取り出す中身」という別々の役割。図書館検索で言えば、クエリ・背表紙・本文にあたる
- $Q=K=V=X$ とそのまま使うと、スコア行列は $XX^\top$(グラム行列)になり必ず対称(実測で $\max|S-S^\top|=0$)。向きのある関係を表現できない。さらに対角成分がノルム2乗で大きく、自己注目が支配的(実測で対角0.923・非対角0.011)
- $W_Q, W_K$ を挟むと $QK^\top = X(W_Q W_K^\top)X^\top = XMX^\top$ という学習可能な双線形形式になり、真ん中の $M$ を非対称にできるので向きのある関係を表せる(実測で非対称性3.881)
- $M = W_Q W_K^\top$ は $d\times d$ 行列の rank $\le d_k$ の低ランク分解。フルの $M$ を持つより省パラメータで、「関係の物差しは低ランクで十分」という設計判断(実測で $32\times32$ の $M$ が実効ランク16)
- $K$ と $V$ を分けるのは「照合に最適な表現」と「取り出す中身に最適な表現」が別物だから。次元 $d_k, d_v$ も独立に選べる
- トイタスクでは、非対称な参照($t \to t-1$)を射影ありは精度1.000で学習、射影なしは0.161(ほぼランダム)と学習できなかった
- Multi-Head は、この射影をヘッドごとに複数持ち、違う部分空間で違う関係を見る仕組み
「どうせ同じ $X$ から作るなら1つでいいのでは」という素朴な疑問への答えは、「1つにすると対称・自己注目・単一関係の3重の制約に縛られるから」でした。3つに射影することは、Attention に非対称性・柔軟な役割分担・複数の関係という自由度を与える、必然の設計だったのです。
次のステップとして、以下の記事も参考にしてください。
- なぜAttentionはスケールドドット積なのか — √d_kで割る理由 — 射影のあとの $\sqrt{d_k}$ スケーリングの意味
- Multi-Head Attentionの理論と実装を完全解説 — ヘッド分割の幾何学的意味とスクラッチ実装
- self-attentionとは?Transformerの核心をわかりやすく解説 — Q・K・V とアテンション機構の全体像
- Attentionの数式を行列の形で完全に理解する — QK^T・softmax・重み付き和を行列の形で追う