JA EN
体系線形代数
·無料·9分で読めます

AIのための線形代数 — ベクトルと行列が何をしているのか

行列式もクラメルの公式も要りません。AIの論文に本当に出てくるのは、ベクトル=意味を置く座標と、行列=その座標を運ぶ変換、この2つだけです。内積がなぜ「意味の近さ」になるのかから、Attentionの式を記号ごとに読み下すところまで。

対象textタスクmath

ゴール: この式を読めるようにする

論文を開くと、早ければ2ページ目にこんな式が現れます。

Attention(Q,K,V)=softmax ⁣(QKdk)V\mathrm{Attention}(Q, K, V) = \mathrm{softmax}\!\left(\frac{QK^{\top}}{\sqrt{d_k}}\right)V
(1)

この式が言っているのは要するに、どの単語をどれだけ見るかを内積で決めて、その配分で情報を混ぜるということです。いま意味が取れなくても構いません。記事の最後にもう一度ここへ戻り、記号を1つずつ言葉にします。

使っている道具は2つだけです。ベクトル=意味を置く座標と、行列=座標を別の座標へ運ぶ変換。行列式の手計算もクラメルの公式も、AIの論文にはまず出てきません。

ベクトル: 意味を座標にする

ベクトルは数を一列に並べたものです。v=[0.3,1.2,0.8]\mathbf{v} = [0.3, -1.2, 0.8] なら数が3つ、これを「3次元空間の1点を指す矢印」と読みます。太字は「これはベクトルだ」という印にすぎません。

AIでこれが効くのは、意味をベクトルに置けるからです。「犬」に数百個の数の並びを割り当て、「猫」にも割り当てる。うまくできていれば犬と猫は空間の近くに、犬と「経理」は遠くに来ます。この割り当てが埋め込み(embedding)です。

注意すべきは、個々の軸に「1本目は足の本数」のような意味が付いているわけではないこと。意味は軸ではなくベクトル同士の位置関係に宿ります。だから次に要るのが、2本がどれだけ近いかを測る道具です。

内積: 「同じ向きか」を1つの数にする

ab=i=1daibi=abcosθ\mathbf{a}\cdot\mathbf{b} = \sum_{i=1}^{d} a_i b_i = \|\mathbf{a}\|\,\|\mathbf{b}\|\cos\theta
(2)

記号を1つずつ。dd は次元の数(並んでいる数の個数)、aia_ia\mathbf{a}ii 番目の成分、\sum は「全部足す」、a\|\mathbf{a}\| は矢印の長さθ\theta(シータ)は2本の矢印がなす角です。

この式が言っているのは要するに、同じ位置の数どうしを掛けて全部足すという素朴な計算が、実は「長さ×長さ×向きの一致度」になっているということ。左辺は機械が数え上げるだけの作業、右辺は幾何の意味。この2つが同じものだという事実が、線形代数がAIで効く理由のほぼすべてです。

長さの影響を消して向きだけを見たいときは、両方の長さで割ります。

sim(a,b)=abab=cosθ\mathrm{sim}(\mathbf{a},\mathbf{b}) = \frac{\mathbf{a}\cdot\mathbf{b}}{\|\mathbf{a}\|\,\|\mathbf{b}\|} = \cos\theta

この式が言っているのは要するに、2本の矢印の向きだけを比べるということ。同じ向きなら1、直角なら0、逆向きなら−1です。これがコサイン類似度で、RAGの基礎で「近い文書を引く」と呼んでいる操作の正体です。ベクトル検索とは、質問ベクトルとの内積が大きい順に並べているだけです。

FIG 12本のベクトルを回してみてください。向きが揃うほど内積は大きく、直角で0、逆向きで負になります。この数字がそのまま「意味の近さ」として使われます

行列: ベクトルを別の空間へ運ぶ

行列は数を格子状に並べたものですが、大事なのは見た目ではなく働きです。行列はベクトルを受け取って別のベクトルを返す装置、つまり変換です。

y=Wx,yi=j=1dinWijxj\mathbf{y} = W\mathbf{x}, \qquad y_i = \sum_{j=1}^{d_{\text{in}}} W_{ij}\,x_j
(3)

x\mathbf{x} は入力ベクトル(長さ dind_{\text{in}})、y\mathbf{y} は出力ベクトル(長さ doutd_{\text{out}})、WijW_{ij}WWiijj 列目の数です。

この式が言っているのは要するに、出力の ii 番目の成分は、入力全体と「WWii 行目」との内積だということ。WW の各行が1つずつ「質問」を持っていて、入力にその質問を投げ、答えを縦に並べたものが出力になります。全結合層はこれそのもので、WW の行数がその層のニューロンの数です(ニューラルネットワークの基礎)。

形(shape)も押さえます。WWdout×dind_{\text{out}} \times d_{\text{in}}x\mathbf{x}dind_{\text{in}} 次元なら結果は doutd_{\text{out}} 次元。内側の数が一致しないと計算できません。実装のエラーはほとんどここで起きます。

行列積は、内積の総当たり表

(AB)ij=kAikBkj(AB)_{ij} = \sum_{k} A_{ik}B_{kj}

この式が言っているのは要するに、AAii 行目と BBjj 列目の内積を、(i,j)(i,j) の位置に書き込むということ。行列積は「式(2)の内積を全組み合わせぶん並べた表」以上のものではありません。

これが分かると冒頭の QKQK^{\top} が読めます。QQ が質問ベクトルを積み上げたもの、KK がキーのベクトルを積み上げたものなら、QKQK^{\top}すべての質問とすべてのキーの内積を一度に並べた表iijj 列は「ii 番目の単語が jj 番目の単語をどれだけ見るか」の生スコアです。

計算量の感覚も持っておきます。m×km \times kk×nk \times n の積は、掛け算と足し算あわせておよそ 2mkn2mkn 回の演算。学習も推論も、時間のほとんどはこの積に消えます。GPUという専用ハードが要るのは、この総当たり表を作る作業が桁違いに重いからです。

次元とは何か

次元は軸の本数、1つのベクトルに並んでいる数の個数です。埋め込みが768次元なら、単語1つを768個の数で表しているということ。

高次元では直感が効きません。押さえるべき性質を1つ挙げるなら、次元が高いほど、無関係に取った2本のベクトルはほぼ直角になること。内積がほぼ0、つまり「無関係」が既定値になるので、何十万語ぶんの埋め込みを詰め込んでも互いに干渉しません。次元を増やすとは、意味がすれ違える余地を増やすことです。もちろん増やせば重くなるので、次元数は表現力と計算コストのトレードオフとして選ばれます。

固有値と特異値: 行列の性格を要約する数

行列は変換でした。では「この変換はどういう性格か」を短く言えないか。それが固有値・特異値です。

Av=λvA\mathbf{v} = \lambda \mathbf{v}
(4)

λ\lambda(ラムダ)は数、v\mathbf{v} はゼロでないベクトルです。この式が言っているのは要するに、この変換に通しても向きが変わらず、長さが λ\lambda 倍になるだけの特別な方向があるということ。その方向が固有ベクトル、倍率が固有値で、変換の骨格にあたります。

固有値は正方行列にしか使えません。縦横の違う行列まで含めて同じことをやるのが特異値分解(SVD)です。

A=UΣVA = U\Sigma V^{\top}

Σ\Sigma(シグマ)は対角線上にだけ数が並んだ行列で、その数が特異値UUVV は向きを回す役です。この式が言っているのは要するに、どんな行列も「回す → 軸ごとに伸ばす/縮める → もう一度回す」の3段階に分解できるということ。特異値はその伸ばし方の強さを、大きい順に並べたものです。

使いどころは1つ。大きい特異値がほんの数個しかないなら、その行列の情報はごく少数の方向に集中している——このとき行列は「ランクが低い」といいます。巨大な行列を小さな2つの積で置き換えられる、という節約がここから出ます。LoRAが賭けているのは、ファインチューニングでの重みの更新量が低ランクで足りるという仮説です。

冒頭の式に戻る

式(1)をもう一度置きます。

Attention(Q,K,V)=softmax ⁣(QKdk)V\mathrm{Attention}(Q, K, V) = \mathrm{softmax}\!\left(\frac{QK^{\top}}{\sqrt{d_k}}\right)V

いま読めるはずです。QQKKVV は、入力の埋め込みにそれぞれ別の行列を掛けて作った、質問・キー・中身のベクトルの束。QKQK^{\top} は全ペアの内積表、つまり「誰が誰をどれだけ見るか」の生スコア。dk\sqrt{d_k}dkd_k はキーの次元)で割るのは、次元が大きいほど内積が大きくなりがちで、そのまま softmax に入れると分布が1点に潰れるからです。softmax は各行を合計1の配分に直し、VV を掛けてその配分で中身を混ぜ合わせます。

この式が言っているのは要するに、内積で注目の配分を決め、その配分で情報を平均するということ。使っているのは内積と行列積だけです。仕組みそのものはAttention機構で扱います。

実務で効く3つのポイント

1. 形を追えば式は読める 式に詰まったら、各記号の形を書き出します。dmodeld_{\text{model}}dkd_k、系列長、バッチ数。形が合う読み方はたいてい1通りで、それが正しい解釈です。

2. 内積を類似度に使うなら、長さを揃える 正規化しないと、ベクトルが長いというだけで無関係な文書が上位に来ます。ベクトル検索が妙な結果を返すときの定番の原因です。

3. 「低ランク」と出てきたら、節約の話だと読む LoRA、埋め込みの圧縮、キャッシュの削減。言葉は違っても、大きい行列を小さい2つの積で近似するという同じ発想です。

まとめ

次は、この座標の上で「どちらへ動けば良くなるか」を教えてくれる矢印——AIのための微分へ進んでください。実際に動かす手続きは損失関数と最適化にあります。

コメント

コメントにはログインが必要です