はじめに
ディープラーニングの実装をしているとベクトル微分とかを頻繁に目にしますが、具体的な演算の定義を改めて確認したいなと思い、まとめてみました。
- 数式の定義(微分の一般形)
- 微分演算と次元の整理
- 微分以外の演算(加算・乗算・除算)のルール
形状(Rank)の定義
| 用語 | 次元数 (Rank) | データのイメージ |
|---|---|---|
| スカラー y | 0 | 単一の数値(例:損失関数の値) |
| ベクトル y | 1 | 数値の列(例:1つのデータ点、特徴ベクトル) |
| 行列 Y | 2 | 数値の表(例:画像、重みパラメータ) |
| テンソル 𝒴 | 3以上 | 多次元配列(例:RGB画像バッチ、動画) |
3階のテンソルのイメージは以下のサイトなどで確認
微分の次元数(Rank)一覧表
結論、微分演算後の次元数は
微分後の次元数(Rank) = 分子の次元数 + 分母の次元数
となります。
これは微分が
「微分するもの(分母)を微小変化させた場合に対する関連する分子の変化量」
を定義しないといけないため、分子の次元数に対して変化分の次元数が足されるためです。
| 分子 \ 分母 | スカラー | ベクトル | 行列 | テンソル (k階) |
|---|---|---|---|---|
| スカラー y | 0 | 1 | 2 | k |
| ベクトル y | 1 | 2 | 3 | 1+k |
| 行列 Y | 2 | 3 | 4 | 2+k |
| テンソル 𝒴 (m階) | m | m+1 | m+2 | m+k |
分母の階数ごとの具体例
スカラー・ベクトル・行列・テンソル(m階)に対してそれぞれスカラー・ベクトル・行列・テンソル(k階)で微分演算を行った場合、どのような定義・数式になるのかをまとめます。
掲載の数式が見づらい場合には「ベクトルをベクトルで微分」のパターンで結果のイメージをつかんでいただければと思います。
分母がスカラー(0階)
分子がスカラー
\begin{aligned}
y &: \frac{dy}{dx} \
\mathbf{y}
\end{aligned}
分子がベクトル
\begin{aligned}
\frac{\partial
\mathbf{y}}{\partial x} = \left[\frac{\partial y_i}{\partial x}\right]_{i} \
\end{aligned}
分子が行列
\begin{aligned}
\frac{\partial Y}{\partial x} = \left[\frac{\partial y_{ij}}{\partial x}\right]_{i,j} \
\end{aligned}
分子がテンソル(k階)
\begin{aligned}
\frac{\partial \mathcal{Y}}{\partial x} = \left[\frac{\partial y_{i_1\dots i_m}}{\partial x}\right]_{i_1,\dots,i_m}
\end{aligned}
分母がベクトル(1階)
\begin{aligned}
y &: \frac{\partial y}{\partial \mathbf{x}} = \left[\frac{\partial y}{\partial x_1}, \dots, \frac{\partial y}{\partial x_n}\right] \
\end{aligned}
\begin{aligned}
\mathbf{y} &: \frac{\partial \mathbf{y}}{\partial \mathbf{x}} = \left[\frac{\partial y_i}{\partial x_j}\right]_{i,j} \
\end{aligned}
\begin{aligned}
Y &: \frac{\partial Y}{\partial \mathbf{x}} = \left[\frac{\partial y_{ij}}{\partial x_k}\right]_{i,j,k} \
\end{aligned}
\begin{aligned}
\mathcal{Y} &: \frac{\partial \mathcal{Y}}{\partial \mathbf{x}} = \left[\frac{\partial y_{i_1\dots i_m}}{\partial x_j}\right]_{i_1,\dots,i_m,j}
\end{aligned}
分母が行列(2階)
\begin{aligned}
y &: \frac{\partial y}{\partial X} = \left[\frac{\partial y}{\partial x_{ij}}\right]_{i,j} \
\end{aligned}
\begin{aligned}
\mathbf{y} &: \frac{\partial \mathbf{y}}{\partial X} = \left[\frac{\partial y_i}{\partial x_{jk}}\right]_{i,j,k} \
\end{aligned}
\begin{aligned}
Y &: \frac{\partial Y}{\partial X} = \left[\frac{\partial y_{ij}}{\partial x_{kl}}\right]_{i,j,k,l} \
\end{aligned}
\begin{aligned}
\mathcal{Y} &: \frac{\partial \mathcal{Y}}{\partial X} = \left[\frac{\partial y_{i_1\dots i_m}}{\partial x_{jk}}\right]_{i_1,\dots,i_m,j,k}
\end{aligned}
分母がテンソル(k階)
\begin{aligned}
y &: \frac{\partial y}{\partial \mathcal{X}} = \left[\frac{\partial y}{\partial x_{j_1\dots j_k}}\right]_{j_1,\dots,j_k} \
\end{aligned}
\begin{aligned}
\mathbf{y} &: \frac{\partial \mathbf{y}}{\partial \mathcal{X}} = \left[\frac{\partial y_i}{\partial x_{j_1\dots j_k}}\right]_{i,j_1,\dots,j_k} \
\end{aligned}
\begin{aligned}
Y &: \frac{\partial Y}{\partial \mathcal{X}} = \left[\frac{\partial y_{i_1 i_2}}{\partial x_{j_1\dots j_k}}\right]_{i_1,i_2,j_1,\dots,j_k} \
\end{aligned}
\begin{aligned}
\mathcal{Y} &: \frac{\partial \mathcal{Y}}{\partial \mathcal{X}} = \left[\frac{\partial y_{i_1\dots i_m}}{\partial x_{j_1\dots j_k}}\right]_{i_1,\dots,i_m,j_1,\dots,j_k}
\end{aligned}
テンソルを用いた微分の一般定義
テンソルとしてスカラー・ベクトル・行列を一般化します。以下のサイトが非常にわかりやすいです。(必読)
任意のテンソル (A)(階数 (m))を任意のテンソル (B)(階数 (n))で微分した結果:
[
C = \frac{\partial A}{\partial B}, \quad C \text{の階数 } = m+n
]
要素は以下で定義
[
C_{i_1, \dots, i_m, j_1, \dots, j_n} = \frac{\partial A_{i_1, \dots, i_m}}{\partial B_{j_1, \dots, j_n}}
]
なおテンソルの軸について、機械学習では (batch, height, width, features) の4階テンソルを使うことが多いようです。
微分時の転置について
演算時に転置が起こる場合があります。
実装上の観点
微分後のレイアウトについて
-
分子レイアウト:微分結果の形状を分子の形状に合わせる書き方。例:スカラーをベクトルで微分すると「行ベクトル」になる
-
分母レイアウト:微分結果の形状を分母の形状に合わせる書き方。例:スカラーをベクトルで微分すると「列ベクトル(分母と同じ)」になる
誤差逆伝搬法などでは重みの微分値を用いて重みパラメータの更新を行うため実装上でも必須となる。
W=W-\eta \nabla W
数学上の観点
ここはChatGPTでも調査しました。
| 分子 (y)\分母 (x) | スカラー (0) | ベクトル (1) | 行列 (2) | テンソル (k) |
|---|---|---|---|---|
| スカラー (0) | 不要 | 不要 | マスト (A) | マスト (A) |
| ベクトル (1) | 不要 | マスト (B) | マスト (C) | マスト (C) |
| 行列 (2) | 不要 | マスト (C) | マスト (C) | マスト (C) |
| テンソル (m) | 不要 | マスト (C) | マスト (C) | マスト (C) |
以下のパターンに分かれます
(A) スカラー ÷ 行列(またはテンソル)
理由:双対性(Dual)の維持行列微分において、例えば
y=\text{Tr}(AX)\
をXで微分した結果を「行列」として表現する場合、結果は
A^{T}
になります。これは、線形代数における内積の定義
\langle A^{T},dX\rangle
と整合性を取るために、数学的に転置が必須となるためです。転置をしないと、行列の積の順序が壊れ、微分形式としての意味をなしません。
(B) ベクトル ÷ ベクトル(ヤコビ行列)
理由:微分同相写像と連鎖律の整合性ベクトル関数
\mathbf{f}:\mathbb{R}^{n}\rightarrow \mathbb{R}^{m}
の微分において、連鎖律
\frac{\partial \mathbf{z}}{\partial \mathbf{x}}=\frac{\partial \mathbf{z}}{\partial \mathbf{y}}\frac{\partial \mathbf{y}}{\partial \mathbf{x}}
を行列積として成立させるためには、成分
J_{ij}=\frac{\partial y_{i}}{\partial x_{j}}
という特定の並び順(ヤコビ行列)が数学的に強制されます。この「行に分子、列に分母」という配置ルールそのものが、一種の転置操作(方向の固定)を含んでいます。
(C) 2階(行列)以上が関わる微分
理由:テンソル縮約(Tensor Contraction)の要請行列やテンソルが微分に絡む場合、結果は3階や4階のテンソルになります。これらを数式の中で「行列」として扱う(あるいは行列積を行う)ためには、多次元の軸を2次元に押し込める必要があり、その過程で軸の入れ替え(転置の拡張概念)が数学的に不可避となります。これを行わないと、演算の次元(次元の不一致)により数式が成立しません。
微分以外の演算ルール
加算・減算
形状が同じ場合、要素ごとに計算可能
結合法則(Associativity)
[
(\mathcal{A} + \mathcal{B}) + \mathcal{C} = \mathcal{A} + (\mathcal{B} + \mathcal{C})
]
交換法則(Commutativity)
[
\mathcal{A} + \mathcal{B} = \mathcal{B} + \mathcal{A}
]
単位元(Identity)
[
\mathcal{A} + 0 = \mathcal{A}, \quad 0\text{は同階のゼロテンソル}
]
逆元(Inverse)
[
\mathcal{A} + (-\mathcal{A}) = 0
]
乗算
テンソル積について全要素を掛け合わせて新しい
テンソル (A) の要素数が (N) 個、テンソル (B) の要素数が (M) 個ある場合、それらのテンソル積
u\otimes v
の全要素数は必ず
N\times M
個になります。これは、数学で言うところの「直積(デカルト積)」の全パターンに対して掛け算を行っている状態です。
「どの要素とどの要素を掛けた結果が、新しいテンソルのどこに配置されるか」については A の位置 (i,j,k) にある値、B の位置 (l,m,n) にある値 これらを掛け合わせた値は、新しいテンソルの (i,j,k,l,m,n) という位置に格納されます。
この前提で、次元を落とした場合の演算についてもまとめます。一部特殊な演算定義があるため、そこはよく知られている名前でまとめます。
| 演算 | 記号 | 対象 | 結果 | 説明 | テンソル積との対応 |
|---|---|---|---|---|---|
| スカラー倍 | cX | スカラー/ベクトル/行列/テンソル | 元と同じ形状 | 全要素をc倍する | テンソル積 |
| 要素ごとの積 (Hadamard) | X⊙Y | 同じ形状 | 元と同じ形状 | 対応する要素同士を掛ける(0でマスキングなどに便利) | 関係性なし |
| 内積 | a⊤b | ベクトル×ベクトル | スカラー | 類似度計算など | テンソル積 + 対角成分の和 |
| 外積(ベクトル積) | a×b | ベクトル×ベクトル | ベクトル | rot(∇ × A) | テンソル積 + 反対称化→同型写像(ベクトル空間への写像) |
| 行列積 | AB | 行列×行列 | 行列 | ニューラルネット結合層で使用 | テンソル積 + 縮約操作 |
テンソル積の普遍性「多重線形写像(内積や行列積など)は、一度テンソル積を経由して記述できる」により、
- テンソル積で「全通りの掛け合わせ」を作る
- 必要な成分を足し合わせたり取り出したりする(縮約・射影)
で記述できることをさします。
行列積の縮約とは:特定のインデックス((A) の列と (B) の行)を一致させて和をとる(足し合わせる)ことで、階数を減らす(4階→2階)
テンソル積 → ベクトル積(外積)について
u×v=⋆(u∧v)
ただし⋆:Hodge双対
u∧v∈Λ2R3
① スカラー倍
結合法則
(\alpha \beta) \mathcal{A} = \alpha (\beta \mathcal{A})
単位元
1 \cdot \mathcal{A} = \mathcal{A}
分配法則
\alpha (\mathcal{A} + \mathcal{B}) = \alpha \mathcal{A} + \alpha \mathcal{B}
② 要素ごとの積(Hadamard積)
結合法則
(\mathcal{A} \odot \mathcal{B}) \odot \mathcal{C} = \mathcal{A} \odot (\mathcal{B} \odot \mathcal{C})
交換法則
\mathcal{A} \odot \mathcal{B} = \mathcal{B} \odot \mathcal{A}
分配法則
\mathcal{A} \odot (\mathcal{B} + \mathcal{C}) = \mathcal{A}\odot \mathcal{B} + \mathcal{A}\odot \mathcal{C}
③ 行列積・テンソル積(縮約積)
結合法則
(AB)C = A(BC)
単位元
I A = A I = A(行列の場合)
非可換
AB \neq BA(行列・テンソル一般)
除算
- 基本的に要素ごとの除算
- 行列の「割り算」は逆行列を掛ける形で代用
要素ごとの除算は可逆性のみ
\mathcal{A} / \mathcal{B} = \mathcal{A} \odot \mathcal{B}^{-1}
分配法則は通常成立しない
\mathcal{A}/(\mathcal{B} + \mathcal{C}) \neq \mathcal{A}/\mathcal{B} + \mathcal{A}/\mathcal{C}
行列の場合は逆行列を掛ける
X / Y = X Y^{-1}, \quad XY^{-1} \neq Y^{-1}X
おわりに
微積とその結果の次元についてはディープラーニングの学習でよく使うので、まとめてみました。誤差逆伝搬をベクトル表記で眺めてみたいと思います。特に重要な計算としては以下です。
スカラーをベクトル微分(グラディエント・勾配)
地形の高さ(損失)を最小にするために、最も急な下り坂の方向(勾配)を探す作業
ベクトルをベクトル微分(ヤコビ行列)
中間層の出力ベクトル h が活性化関数などを通って次のベクトル u に変換されるとき、
\frac{\partial \mathbf{u}}{\partial \mathbf{h}}
を計算
スカラーの行列微分
損失Lを全結合層の重み行列Wで微分し、
\frac{\partial L}{\partial W}
を求める場合
関連
テンソルの演算については以下がわかりやすいです
線形代数の基礎は以下のサイトがお薦めです。特に行列積などを振り返るのに使えます