ベクトルの内積 -- 射影から乗算へ

内積(Dot Product)は、AIで最も頻繁に使われるベクトル演算です。

全結合層の計算、注意力機構の類似度マッチング——その核心はすべて内積です。

内積には2つの等価な視点があります、それらの間の架け橋を理解することが、この章の中心的な学びです。

視点1:代数的計算

対応する位置の要素を掛け合わせて、合計します。

\( \mathbf{a} \cdot \mathbf{b} = \sum a_i b_i \)

例:(2,3) · (4,1) = 2×4 + 3×1 = 11

視点2:幾何的な直感

一方のベクトルをもう一方のベクトルに射影し、その2つの長さを掛け合わせます。

\( \mathbf{a} \cdot \mathbf{b} = \|\mathbf{a}\| \|\mathbf{b}\| \cos\theta \)

なす角 θ が小さいほど、内積は大きくなります。

2つの計算方法は同じ値を導きます——これは数学における極めてエレガントな等式です。

内積の正負は方向の関係を明らかにする

<90°
内積 > 0
方向がほぼ同じ
=90°
内積 = 0
方向が垂直(直交)
>90°
内積 < 0
方向がほぼ反対

生活の例

買い物のレシート:数量 × 単価

あなたはコーラ2本(1本3元)、ポテトチップス3袋(1袋5元)、カップ麺1個(1個4元)を買いました。

数量ベクトル (2, 3, 1) と価格ベクトル (3, 5, 4) の内積が合計金額になります:2×3 + 3×5 + 1×4 = 25元。

買い物カートを押す:力 × 変位

カートを押す力はベクトル(大きさと方向を持つ)であり、カートの変位ももう1つのベクトルです。

物理学では、仕事 = 力の変位方向の成分 × 変位の大きさ = 力ベクトルと変位ベクトルの内積です。

横(垂直方向)に押すと、仕事をまったくしません——内積はゼロです。


数学の定義

代数的定義

\[ \mathbf{a} \cdot \mathbf{b} = \sum_{i=1}^{n} a_i b_i = a_1 b_1 + a_2 b_2 + \cdots + a_n b_n \]

幾何学的定義

\[ \mathbf{a} \cdot \mathbf{b} = \|\mathbf{a}\| \|\mathbf{b}\| \cos\theta \]

2つの定義の架け橋:なす角を求める

\[ \cos\theta = \frac{\mathbf{a} \cdot \mathbf{b}}{\|\mathbf{a}\| \|\mathbf{b}\|} \]

これはつまり:2つのベクトルの座標が与えられれば、分度器なしでそれらのなす角を計算できます。。

演算の性質

性質公式説明
交換法則\( \mathbf{a} \cdot \mathbf{b} = \mathbf{b} \cdot \mathbf{a} \)順序は影響しない
分配法則\( \mathbf{a} \cdot (\mathbf{b} + \mathbf{c}) = \mathbf{a}\cdot\mathbf{b} + \mathbf{a}\cdot\mathbf{c} \)先に加算してから内積を取れる
自分自身との内積\( \mathbf{a} \cdot \mathbf{a} = \|\mathbf{a}\|^2 \)ベクトルと自分自身の内積 = 長さの2乗

Pythonで実際に試す

例

import numpy as np

a_サンプル = np.array([2, 3, 1])
b_サンプル = np.array([4, 1, 2])

# 方法1:np.dot()
dot1 = np.dot(a_サンプル, b_サンプル)
# 方法2:@ 演算子(推奨)
dot2 = a_サンプル @ b_サンプル
# 方法3:手書きで検証
dot3 = sum(a_サンプル[i] * b_サンプル[i] for i in range(len(a_サンプル)))

print("a · b =", dot1)   # 13
print("3つの方法の結果は一致:", dot1 == dot2 == dot3)

# 幾何的定義からなす角を逆算
norm_a = np.linalg.norm(a_サンプル)
norm_b = np.linalg.norm(b_サンプル)
cos_theta = dot1 / (norm_a * norm_b)
theta_deg = np.degrees(np.arccos(cos_theta))
print(f"||a||={norm_a:.2f}, ||b||={norm_b:.2f}, cosθ={cos_theta:.4f}")
print(f"なす角 = {theta_deg:.1f}°")

# 幾何公式を検証
verify = norm_a * norm_b * cos_theta
print(f"||a||·||b||·cosθ = {verify:.4f} (内積と一致)")

# さまざまななす角のデモ
print("\n[1,0] · [0.8,0.6] =", np.array([1,0]) @ np.array([0.8,0.6]), " (鋭角、正)")
print("[1,0] · [0,1] =", np.array([1,0]) @ np.array([0,1]), " (直角、ゼロ)")
print("[1,0] · [-1,0] =", np.array([1,0]) @ np.array([-1,0]), " (鈍角、負)")
a · b = 13
三种方法结果一致: True
||a||=3.74, ||b||=4.58, cosθ=0.7580
夹角 = 40.7°

[1,0] · [0.8,0.6] = 0.8  (锐角,正)
[1,0] · [0,1] = 0  (直角,零)
[1,0] · [-1,0] = -1.0  (钝角,负)

インタラクティブな内積デモ

ベクトル a と b の端点をドラッグして、内積の値となす角がどう変わるかを観察しましょう。内積の正負によって、鋭角/鈍角/直角が決まります:


AIにおける応用シーン

全結合層 = 内積の一括計算

1つのニューロンは \( y = w_1x_1 + w_2x_2 + \cdots + w_nx_n + b \) を計算します。加算部分は、重みベクトル w と入力ベクトル x の内積。

全結合層を見たときnn.Linear(784, 256)、それが数学的に行っていることは:256個のニューロンがあり、各ニューロンが自分の重みベクトル(784次元)と入力ベクトルの内積を取り、バイアスを加えます。256個の内積の並列計算 = 行列乗算です。

注意力機構 = 内積 + Softmax

Transformerの核心的な操作:QueryベクトルとKeyベクトルの内積を取り、結果が大きいほど両者が「関連している」ことを示します。

\[ \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V \]

\( QK^T \) は seq_len × d_k 行列と d_k × seq_len 行列の乗算であり、結果行列の位置 (i, j) の値 = i 番目の Query と j 番目の Key の内積。この値が大きいほど、i 番目の位置の j 番目の位置に対する「注意力」が高いことを示します。

\( \sqrt{d_k} \) で割るのは、内積の値が大きくなりすぎて Softmax の勾配が消失するのを防ぐためです。GPT、BERT、Claude など、現代の大規模言語モデルはすべてこの内積注意力機構に基づいています。

レコメンドシステムにおける類似度計算

ユーザーベクトルとアイテムベクトルの内積を取り、ユーザーのそのアイテムに対する「嗜好スコア」を得ます。これが行列分解レコメンドアルゴリズムの核心です——評価行列 ≈ ユーザー潜在ベクトル行列 × アイテム潜在ベクトル行列の転置。


その他の拡張