Transformer を学ぼうとして、この式の前で固まった経験はありませんか。
$$ \mathrm{Attention}(Q, K, V) = \mathrm{softmax}\!\left(\frac{QK^{\top}}{\sqrt{d_k}}\right)V $$
$Q$ に $K$ の転置を掛けて、$\sqrt{d_k}$ で割って、softmax して、$V$ を掛ける……記号は追えても、「結局この式は何をしているのか」がつかめない。多くの人がつまずくのはここです。
つまずきの原因は、たいてい行列の「形(shape)」を追っていないことにあります。$Q$ はどんな形の行列で、$QK^{\top}$ で何行何列の行列ができて、その各マスは何を意味するのか——これを1ステップずつ絵にして追いかけると、Attention は驚くほど単純な操作に見えてきます。やっていることは、たった3つ。①全トークンの間で「似ている度」を測り、②それを正規化して、③その重みで混ぜ合わせる。それだけです。
この「行列の形を追う」という見方が身につくと、いいことがたくさんあります。
- Transformer の理解が一気に進む:BERT も GPT も、心臓部はこの1つの式の繰り返しです
- 自分で実装できる:どこで何次元になるかを把握できれば、
shape mismatchのエラーで悩まなくなります - Multi-Head や Cross-Attention も怖くない:形の分割・組み替えとして見通せます
本記事では、具体的な小さな行列(5トークン)を使い、$X$ から出力までのすべての行列を形と意味つきで可視化します。数式が苦手な人こそ、絵で腹落ちさせましょう。

上の図が全体の地図です。恐ろしげな式も、分解すれば「①類似度($QK^{\top}$)→②正規化(softmax)→③加重和($\times V$)」の3手にすぎません。この3つを、行列の形を見ながら順にたどっていきます。
本記事の内容
- 入力 $X$・$Q$・$K$・$V$ がそれぞれどんな形の行列か
- $QK^{\top}$ が作る「スコア行列」の形と、各マスの意味
- なぜ $\sqrt{d_k}$ で割るのか(softmax の飽和を防ぐ)
- softmax を「行ごと」にかける意味と、重み行列 $A$
- $A \times V$ の加重和が「新しい表現」を作る仕組み
前提知識
以下を先に読むと、本記事がスムーズです。
行列の積の計算ルール($(n\times d)$ と $(d\times m)$ を掛けると $(n\times m)$)と、softmax(ベクトルを合計1の確率に変換)を知っていれば十分です。
登場人物:入力 X は「行がトークン」の行列
まず、Attention に入ってくるデータの形を確認します。文は「トークン(単語や部分文字列)」の列です。各トークンは、埋め込みによって長さ $d$ のベクトルになっています。それを縦に積んだのが入力行列 $X$ です。

図のとおり、$X$ は $(n \times d)$ の行列です。$n$ はトークンの数(この記事の例では「私・は・犬・を・見た」の5個)、$d$ は各トークンの埋め込み次元です。1行が1トークンに対応する——この対応を最後まで握っておくことが、Attention 理解の一番の鍵です。これから行列がいくつも登場しますが、「行 = トークン」はずっと変わりません。
さて、この $X$ から、Attention はまず3つの別バージョンを作ります。$Q$(query)、$K$(key)、$V$(value)です。次はその形を見ましょう。
Q・K・V:同じ入力を3つの役割に変換する
Attention は、各トークンに3つの役割を持たせます。「自分は何を探しているか(query)」「自分はどんな目印を持つか(key)」「自分はどんな中身を渡すか(value)」の3つです。この3つは、入力 $X$ に別々の重み行列を掛けて作ります:
$$ Q = X W_Q, \qquad K = X W_K, \qquad V = X W_V $$

図で形を追いましょう。$X$ は $(n \times d)$、重み行列 $W_Q$ は $(d \times d_k)$。行列積のルールで、$Q = X W_Q$ は $(n \times d_k)$ になります。$K$、$V$ も同じで、すべて $(n \times d_k)$ の形です(厳密には $V$ の列数は $d_v$ と別にできますが、簡単のため同じにします)。ここでも行はトークンのままです。$Q$ の第1行は「私」の query ベクトル、$K$ の第3行は「犬」の key ベクトル、という具合です。
重み行列 $W_Q, W_K, W_V$ は学習で決まるパラメータです。同じトークンでも、query として見るか key として見るかで別のベクトルになる——この「役割の分離」が Attention の柔軟さを生みます。
なぜ、わざわざ同じ $X$ から3つも作るのでしょうか。図書館での本探しにたとえると分かりやすいでしょう。query は「探している内容」、key は各本の「背表紙の見出し」、value は本の「中身」です。あなたの探し物(query)と各本の見出し(key)を照らし合わせて、合致した本の中身(value)を取り出す——Attention はこれを全トークン間でやっています。探す側の表現(query)と探される側の目印(key)を別々に学習できるからこそ、「主語は述語を探す」「代名詞は指示先を探す」といった多様な関係を、それぞれに適した向きで捉えられるのです。もし1種類のベクトルで済ませたら、この非対称な「探す・探される」の関係を表せません。
3つの行列がそろったので、いよいよ本題の $QK^{\top}$ に進みます。
ステップ①:QK^T で「全トークン対の類似度」を測る
Attention の第一歩は、「どのトークンがどのトークンに注目すべきか」を数値化することです。それには、query と key の内積を使います。
なぜ内積が「似ている度」になるのか、少しだけ確認しておきましょう。2つのベクトル $q$ と $k$ の内積は、幾何的には $q \cdot k = |q|\,|k|\cos\theta$ と書けます($\theta$ は2つのベクトルの間の角度)。向きがそろっている($\theta$ が小さい)ほど $\cos\theta$ は1に近づき、内積は大きくなります。逆に向きが直交すれば0、反対を向けば負。つまり内積は「2つのベクトルがどれだけ同じ方向を向いているか=どれだけ似ているか」を1つの数にまとめた量なのです。query と key が「似た向き」に学習されたトークン同士は、大きなスコアで結ばれます。
すべての query と、すべての key の組で内積を取れば、全トークン対の類似度が一気に求まります。これがちょうど $Q K^{\top}$ です。行列の積は「左の行と右の列の内積を並べる」演算なので、$Q$ の各行(query)と $K^{\top}$ の各列(= $K$ の各行 = key)の内積が、そのまま全部のマスに詰まります。

形を追います。$Q$ は $(n \times d_k)$、$K^{\top}$ は $K$ を転置した $(d_k \times n)$。掛けると $(n \times n)$ の正方行列になります。これをスコア行列 $S$ と呼びましょう。$d_k$ という次元は内積で「潰れて」消え、代わりにトークン数 $n$ が両側に並ぶことに注目してください。
このスコア行列の各マス $S_{ij}$ は、$q_i \cdot k_j$——「トークン $i$ の query」と「トークン $j$ の key」の内積です。意味は「トークン $i$ が、トークン $j$ にどれだけ注目するか」。つまり第 $i$ 行を横に読むと、「トークン $i$ が他のすべてのトークンに向ける関心の強さ」が並んでいます。実際の数値で見てみましょう。

これは例のデータで実際に $QK^{\top}/\sqrt{d_k}$ を計算したヒートマップです(スケーリングは次節で説明します)。縦軸が「注目する側(query)」、横軸が「注目される側(key)」。赤いマスほどスコアが高く、青いほど低い。たとえば「犬」の行を見ると「を」のマスが濃い赤(3.0)で、「犬」が「を」に強く注目していることが読み取れます。この時点ではまだ生のスコアで、大きさもバラバラです。これを「注目度の配分」に変えるのが、次のスケーリングと softmax です。
ステップ①.5:なぜ √d_k で割るのか
softmax に入る前に、スコアを $\sqrt{d_k}$ で割る「スケーリング」が入ります。地味な操作ですが、これには明確な理由があります。
内積 $q_i \cdot k_j$ は $d_k$ 個の積の和です。各成分が独立でだいたい分散1くらいだとすると、その和である内積の分散は $d_k$ に比例して大きくなります。つまり次元 $d_k$ が大きいほど、スコアは極端な値(大きな正・負)を取りやすくなるのです。

左の図は、$d_k=64$ のときの内積の分布です。標準偏差が8前後まで広がっています。この大きなスコアをそのまま softmax に入れると何が起きるか——右の図が答えです。スケーリングなし(赤)だと、softmax はたった1つのトークンにほぼ確率1を集中させ、他はほぼ0。これでは「その1つしか見ない」硬直した注目になり、しかも softmax の勾配がほぼ消えて学習が進まなくなります。$\sqrt{d_k}$ で割ってスコアの大きさを抑える(緑)と、なだらかで学習しやすい注目度になります。標準偏差が $\sqrt{d_k}$ 倍に膨らむのを、ちょうど打ち消す割り算なのです。
スコアの大きさが整ったので、これを確率に変換します。それが softmax です。
ステップ②:softmax を「行ごと」にかける
softmax は、実数のベクトルを「すべて正で、合計が1」の確率分布に変換します。Attention では、これをスコア行列の各行に独立にかけます。なぜ行ごとかというと、第 $i$ 行は「トークン $i$ が各トークンに向ける関心」でした。それを合計1に正規化すれば、「トークン $i$ の注目度の配分(どこにどれだけ注意を割くか)」になるからです。
$$ A_{ij} = \frac{\exp(S_{ij})}{\sum_{j’} \exp(S_{ij’})} $$
行ごとに正規化するので、$A$ の各行は横に足すと必ず1になります。この $A$ をアテンション重み行列と呼びます。

実データの重み行列 $A$ です。先ほどの生スコアが、行ごとにきれいな確率分布に変わりました。「は」の行を見ると「は」自身に0.78が集中し、「犬」の行は「を」に0.64が向いています。各行を横に足すと、どの行も1.00になっているのを確かめてください。形は $(n \times n)$ のまま、中身が「関心の強さ」から「注目度の割合」に変わったわけです。
この重み $A$ が決まれば、あとは仕上げです。この割合で value を混ぜ合わせます。
ステップ③:A×V で value を加重平均する
最後のステップは、注目度 $A$ を重みにして、value ベクトル $V$ を混ぜ合わせることです。式では $O = A V$ とシンプルに書けます。

形を追います。$A$ は $(n \times n)$、$V$ は $(n \times d_v)$。掛けると $(n \times d_v)$ の出力 $O$ になります。ここで $n$ が1つ潰れて、また「行=トークン、列=次元」の形に戻るのが美しいところです。入力 $X$ と同じ「$n$ 行」の形で出てくるので、この操作を何層も積み重ねられるのです。
出力の第 $i$ 行 $o_i$ は、次の加重和です:
$$ o_i = \sum_{j=1}^{n} A_{ij}\, v_j $$
「トークン $i$ の注目度 $A_{ij}$ を重みにして、全トークンの value $v_j$ を平均したもの」。注目度が高いトークンの value ほど強く反映されます。1つの出力行を、実際に分解してみましょう。

左は「犬」が各トークンに向ける注目度($A$ の該当行)です。「を」に0.64、「犬」自身に0.20が向いています。右がその加重和の中身です。$o_{\text{犬}} = 0.07\,v_{私} + 0.01\,v_{は} + 0.20\,v_{犬} + 0.64\,v_{を} + 0.08\,v_{見た}$。つまり「犬」の新しい表現は、強く注目した「を」の value を主成分に、自分自身の value を少し混ぜた合成ベクトルになります。これが「文脈を取り込む」ということの正体です。周りのどのトークンをどれだけ見るかを $A$ が決め、その配合で新しい意味ベクトルを作っているのです。
これで3ステップがすべて出そろいました。最後に、行列の形の流れを1枚にまとめて俯瞰しましょう。
全体を1枚で俯瞰する

この図が、Attention の行列変形の全景です。形の流れはこうです:
$$ \underbrace{X}_{n\times d} \;\to\; \underbrace{Q,K,V}_{n\times d_k} \;\xrightarrow{QK^{\top}}\; \underbrace{S}_{n\times n} \;\xrightarrow{\text{softmax}}\; \underbrace{A}_{n\times n} \;\xrightarrow{\times V}\; \underbrace{O}_{n\times d_v} $$
注目すべきは、トークン数 $n$ が最初から最後まで保たれ、次元だけが $d \to d_k \to (n) \to d_v$ と移り変わることです。$QK^{\top}$ でいったん $(n \times n)$ という「トークン対の関係」の世界に移り、$\times V$ でまた「トークン×次元」の世界に戻ってくる。この往復が Attention の骨格です。入力と同じ $(n \times \cdot)$ の形で出てくるからこそ、Transformer はこのブロックを何十層も積み重ねられます。
行列の形さえ追えれば、この式はもう怖くありません。仕上げに、実装での確認と、Multi-Head への一歩を見ておきましょう。
Pythonで確かめる
これまで図で見た計算を、そのままコードで再現します。図と同じ5トークンの例です。
import numpy as np
tokens = ["私", "は", "犬", "を", "見た"]
n, d, dk = len(tokens), 6, 4
rng = np.random.default_rng(7)
X = rng.normal(0, 1, (n, d)) # 入力 (n×d)
WQ = rng.normal(0, 0.6, (d, dk)) # 重み (d×dk)
WK = rng.normal(0, 0.6, (d, dk))
WV = rng.normal(0, 0.6, (d, dk))
Q, K, V = X @ WQ, X @ WK, X @ WV # すべて (n×dk)
print("Q, K, V の形:", Q.shape, K.shape, V.shape)
S = (Q @ K.T) / np.sqrt(dk) # スコア (n×n)
print("スコア S の形:", S.shape)
def softmax_rows(M): # 行ごとに softmax
M = M - M.max(axis=1, keepdims=True)
e = np.exp(M)
return e / e.sum(axis=1, keepdims=True)
A = softmax_rows(S) # 重み (n×n)
O = A @ V # 出力 (n×dv)
print("重み A の形:", A.shape, " 出力 O の形:", O.shape)
print("A の各行の合計:", A.sum(axis=1)) # すべて 1
このコードを実行すると、次のように出力されます。
Q, K, V の形: (5, 4) (5, 4) (5, 4)
スコア S の形: (5, 5)
重み A の形: (5, 5) 出力 O の形: (5, 4)
A の各行の合計: [1. 1. 1. 1. 1.]
形の流れ $(5,4) \to (5,5) \to (5,4)$ が、図で見たとおりに再現できました。重み行列 $A$ の各行の合計がぴったり1になっているのも、softmax を行ごとにかけた証拠です。数式・図・コードの3つが、同じ1つの操作を指していることが確認できます。コードで A や S を print してヒートマップにすれば、本記事の図がそのまま得られます。
最後に、実際の Transformer で使われる Multi-Head Attention に一歩だけ踏み込みます。
一歩先へ:Multi-Head も「形の分割」で見える
実際の Transformer は、1つの Attention を単独で使うのではなく、複数のヘッド(head)に分けて並列に行います。これが Multi-Head Attention です。難しそうに聞こえますが、行列の形で見れば「次元 $d$ を分割するだけ」です。

図のように、次元 $d$ をヘッド数 $h$ で割り、$(n \times d_k)$ の小さな $Q,K,V$ を $h$ 組作ります。各ヘッドで独立に本記事の3ステップ($QK^{\top}$ → softmax → $\times V$)を行い、最後に出力を横に連結して元の次元に戻します。ヘッドごとに違う重み行列を持つので、「あるヘッドは文法的な係り受けに、別のヘッドは意味的な関連に注目する」といった役割分担が生まれます。1ヘッドの計算さえ形で追えていれば、Multi-Head は「それを $h$ 回並べて連結する」だけだとわかります。
まとめ
本記事では、Attention の数式を行列の形を追いながら可視化しました。要点を整理します。
- 行 = トークン:入力 $X$ から出力 $O$ まで、行がトークンに対応する関係は保たれる
- ステップ①($QK^{\top}$):query と key の内積で、全トークン対の類似度スコア $(n\times n)$ を作る。$S_{ij}$ は「$i$ が $j$ にどれだけ注目するか」
- スケーリング($/\sqrt{d_k}$):内積の分散が $d_k$ に比例して膨らむのを抑え、softmax の飽和と勾配消失を防ぐ
- ステップ②(softmax):スコア行列を行ごとに確率へ。各行が合計1の注目度分布 $A$ になる
- ステップ③($\times V$):注目度を重みに value を加重平均。$o_i = \sum_j A_{ij} v_j$ が新しい文脈表現
- 形の流れ:$n\times d \to n\times d_k \to n\times n \to n\times d_v$。$n$ は保たれ、次元だけが移り変わる
「難しい式」に見えても、行列の形と各マスの意味を追えば、Attention は「似てる度を測る→正規化する→混ぜる」の3手にすぎません。この見方は、Multi-Head・Cross-Attention・Transformer 全体を理解する土台になります。
次のステップとして、以下の記事も参考にしてください。