アダマール積(Hadamard product)は、2つの行列の同じ位置の要素同士を掛け合わせる演算です。element-wise product(要素ごとの積)とも呼ばれ、機械学習や深層学習の論文で頻繁に登場します。
本記事では、アダマール積の定義から性質、通常の行列積との違い、そして深層学習での活用例までを解説します。
本記事の内容
- アダマール積の定義
- 通常の行列積との違い
- アダマール積の数学的性質
- 深層学習での応用
- Pythonでの実装
アダマール積の定義
数学的定義
同じサイズの2つの行列 $\bm{A}, \bm{B} \in \mathbb{R}^{m \times n}$ のアダマール積 $\bm{C} = \bm{A} \odot \bm{B}$ は、各成分の積として定義されます。
$$ (\bm{A} \odot \bm{B})_{ij} = a_{ij} \cdot b_{ij} $$
記号 $\odot$ や $\circ$ が使われますが、論文によっては $\bm{A} \ast \bm{B}$ と書くこともあります。
具体例
$$ \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} \odot \begin{pmatrix} 5 & 6 \\ 7 & 8 \end{pmatrix} = \begin{pmatrix} 1 \times 5 & 2 \times 6 \\ 3 \times 7 & 4 \times 8 \end{pmatrix} = \begin{pmatrix} 5 & 12 \\ 21 & 32 \end{pmatrix} $$
通常の行列積との違い
アダマール積と通常の行列積は全く異なる演算です。
| アダマール積 $\bm{A} \odot \bm{B}$ | 行列積 $\bm{A}\bm{B}$ | |
|---|---|---|
| サイズの条件 | 同じサイズ $m \times n$ | $\bm{A}$: $m \times k$, $\bm{B}$: $k \times n$ |
| 結果のサイズ | $m \times n$ | $m \times n$ |
| 計算 | 対応する要素の積 | 行と列の内積 |
| 可換性 | $\bm{A} \odot \bm{B} = \bm{B} \odot \bm{A}$ | 一般に $\bm{A}\bm{B} \neq \bm{B}\bm{A}$ |
| 計算量 | $O(mn)$ | $O(mkn)$ |
アダマール積の性質
可換律
$$ \bm{A} \odot \bm{B} = \bm{B} \odot \bm{A} $$
通常の行列積とは異なり、アダマール積は可換です。
結合律
$$ (\bm{A} \odot \bm{B}) \odot \bm{C} = \bm{A} \odot (\bm{B} \odot \bm{C}) $$
分配律
$$ \bm{A} \odot (\bm{B} + \bm{C}) = \bm{A} \odot \bm{B} + \bm{A} \odot \bm{C} $$
単位元
全成分が1の行列 $\bm{J}$(ones行列)が単位元です。
$$ \bm{A} \odot \bm{J} = \bm{A} $$
シューアの積定理
$\bm{A}$ と $\bm{B}$ がともに半正定値行列ならば、$\bm{A} \odot \bm{B}$ も半正定値行列です。この定理は、カーネル法でカーネル関数の積が再びカーネル関数になることの根拠となります。
トレースとの関係
アダマール積とトレースには以下の関係があります。
$$ \text{tr}(\bm{A}^\top \bm{B}) = \sum_{i,j} a_{ij} b_{ij} = \bm{1}^\top (\bm{A} \odot \bm{B}) \bm{1} $$
ここで $\bm{1}$ は全成分が1のベクトルです。この関係はフロベニウス内積と呼ばれます。
深層学習での応用
ゲート機構(LSTM, GRU)
LSTMやGRUなどのリカレントニューラルネットワークでは、アダマール積がゲート機構として使われます。
例えばLSTMの忘却ゲートでは、
$$ \bm{c}_t = \bm{f}_t \odot \bm{c}_{t-1} + \bm{i}_t \odot \tilde{\bm{c}}_t $$
ここで $\bm{f}_t$(忘却ゲート)の各要素は $[0, 1]$ の値を取り、前の時刻のセル状態 $\bm{c}_{t-1}$ のどの要素を保持するかを制御します。
Attention機構
Transformer系モデルのマスク付きAttentionでは、マスク行列とのアダマール積が使われます。
残差接続
一部のネットワークアーキテクチャでは、特徴量マップのスケーリングにアダマール積が用いられます。
Pythonでの実装
アダマール積の基本操作と性質の検証を行います。
import numpy as np
import matplotlib.pyplot as plt
# アダマール積の基本
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
# アダマール積(要素ごとの積)
hadamard = A * B # NumPyでは * がアダマール積
matrix_product = A @ B # @ が行列積
print("行列 A:")
print(A)
print("\n行列 B:")
print(B)
print(f"\nアダマール積 A * B:\n{hadamard}")
print(f"\n行列積 A @ B:\n{matrix_product}")
# 性質の検証
C = np.array([[2, 1], [0, 3]])
# 可換律
print(f"\n可換律: A*B == B*A ? {np.allclose(A*B, B*A)}")
# 結合律
print(f"結合律: (A*B)*C == A*(B*C) ? {np.allclose((A*B)*C, A*(B*C))}")
# 分配律
print(f"分配律: A*(B+C) == A*B+A*C ? {np.allclose(A*(B+C), A*B + A*C)}")
# トレースとの関係
trace_val = np.trace(A.T @ B)
hadamard_sum = np.sum(A * B)
print(f"\ntr(A^T B) = {trace_val}")
print(f"sum(A * B) = {hadamard_sum}")
print(f"一致: {trace_val == hadamard_sum}")
# シューアの積定理の検証
np.random.seed(42)
n = 5
# 半正定値行列の生成(A = X^T X で構成)
X1 = np.random.randn(10, n)
X2 = np.random.randn(10, n)
A_psd = X1.T @ X1
B_psd = X2.T @ X2
# アダマール積
C_hadamard = A_psd * B_psd
# 固有値の確認
eig_A = np.linalg.eigvalsh(A_psd)
eig_B = np.linalg.eigvalsh(B_psd)
eig_C = np.linalg.eigvalsh(C_hadamard)
print(f"\nシューアの積定理:")
print(f"A の最小固有値: {eig_A.min():.6f} (>= 0)")
print(f"B の最小固有値: {eig_B.min():.6f} (>= 0)")
print(f"A*B の最小固有値: {eig_C.min():.6f} (>= 0)")
# ゲート機構の可視化(LSTMの忘却ゲートのイメージ)
fig, axes = plt.subplots(1, 4, figsize=(16, 4))
signal = np.random.randn(8, 8)
gate = 1 / (1 + np.exp(-np.random.randn(8, 8) * 3)) # シグモイド
gated_signal = signal * gate
axes[0].imshow(signal, cmap='RdBu', vmin=-2, vmax=2)
axes[0].set_title('Signal')
axes[1].imshow(gate, cmap='gray', vmin=0, vmax=1)
axes[1].set_title('Gate (sigmoid)')
axes[2].set_text(0.5, 0.5, '$\\odot$', fontsize=40, ha='center', va='center',
transform=axes[2].transAxes)
axes[2].axis('off')
axes[3].imshow(gated_signal, cmap='RdBu', vmin=-2, vmax=2)
axes[3].set_title('Gated Signal')
plt.suptitle('Hadamard Product as Gating Mechanism', fontsize=13)
plt.tight_layout()
plt.show()
このコードでは、アダマール積の基本的な性質の検証と、深層学習のゲート機構におけるアダマール積の役割を可視化しています。
まとめ
本記事では、アダマール積について解説しました。
- アダマール積は同じ位置の要素同士を掛け合わせる演算であり、$(\bm{A} \odot \bm{B})_{ij} = a_{ij} b_{ij}$ で定義される
- 通常の行列積とは異なり、可換律が成り立つ
- シューアの積定理により、半正定値行列のアダマール積は半正定値であり、カーネル法の理論的基盤となる
- 深層学習では、LSTMやGRUのゲート機構としてアダマール積が重要な役割を果たす