行列積とアダマール積の使い分け ミキサーとふるいで教える

こんにちは。ゆうせいです。

ディープラーニングの研修で、必ず質問が出る場面があります。

「なぜここは掛け算の記号が違うのですか」

コードを見ると、@ と * が混在しています。どちらも掛け算に見えますが、まったく別の演算です。そして、この違いを理解しているかどうかで、モデルの構造の読み方が変わります。

この記事では、講師がこの区別をどう教えるかを、例え、数式、演習まで含めて整理します。

結論

二つの演算は、次のように役割が分かれています。

演算記号役割例え
行列の積@情報をすべて混ぜ合わせて新しい特徴を作るミキサー
アダマール積*情報を残すか消すか通すかを決めるふるい

この例えは、単なる語呂合わせではありません。計算の構造そのものから導かれます。

ミキサーは、入れたものが混ざり合って別のものになります。行列の積では、和を取る操作が入るため、複数の入力が一つの出力に混ざります。

ふるいは、通すか通さないかを決めるだけで、粒そのものは変えません。アダマール積では、位置ごとに独立して掛け算するため、情報が混ざりません。

研修では、この構造の違いを先に示してから、AIのどこで使われるかに進んでください。順序を逆にすると、暗記になります。

定義と記号

行列の積

A m \times n B n \times p のとき、積 C = AB の各要素は次のように計算されます。

C_{ij} = \sum_{k=1}^{n} A_{ik} B_{kj}

総和の記号があることが要点です。k について足し合わせるため、複数の値が一つにまとまります。

アダマール積

A B が同じ形のとき、アダマール積 C = A \odot B の各要素は次のように計算されます。

C_{ij} = A_{ij} B_{ij}

総和がありません。同じ位置どうしを掛けるだけです。

記号は \odot で表します。要素ごとの積、要素積、element-wise productとも呼ばれます。

記号の対応

数式Python別名
AB または A \cdot B @ または matmul行列積、内積型の積
A \odot B * または mulアダマール積、要素積

なお、数学の教科書では A \cdot B が行列積を意味しますが、プログラムでは * が要素ごとの積になります。この不一致が、混乱の原因になります。研修では最初に指摘しておいてください。

数値で違いを確認する

同じ二つの行列で、両方を計算してみます。

A = \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix}, \quad B = \begin{pmatrix} 5 & 6 \\ 7 & 8 \end{pmatrix}

行列の積

各要素を、定義に従って計算します。

1行1列目です。

1 \times 5 + 2 \times 7 = 5 + 14 = 19

1行2列目です。

1 \times 6 + 2 \times 8 = 6 + 16 = 22

2行1列目です。

3 \times 5 + 4 \times 7 = 15 + 28 = 43

2行2列目です。

3 \times 6 + 4 \times 8 = 18 + 32 = 50

まとめると次のようになります。

AB = \begin{pmatrix} 19 & 22 \\ 43 & 50 \end{pmatrix}

アダマール積

同じ位置どうしを掛けるだけです。

A \odot B = \begin{pmatrix} 1 \times 5 & 2 \times 6 \\ 3 \times 7 & 4 \times 8 \end{pmatrix} = \begin{pmatrix} 5 & 12 \\ 21 & 32 \end{pmatrix}

何が違ったか

結果を並べます。

位置行列の積アダマール積
1行1列195
1行2列2212
2行1列4321
2行2列5032

行列の積の19という値には、A の1行目の全要素と、B の1列目の全要素が関与しています。四つの数字が混ざって19になりました。

アダマール積の5という値には、A_{11} B_{11} しか関与していません。他の要素は一切影響しません。

ここが、ミキサーとふるいの違いです。

形の規則という決定的な差

計算そのものより、形の規則を先に押さえたほうが理解が速い場合があります。

演算入力の形出力の形
行列の積(m, n) (n, p) (m, p)
アダマール積(m, n) (m, n) (m, n)

行列の積は、内側の次元が一致していれば計算でき、出力の形が変わります。次元を変換する操作です。

アダマール積は、形が同じでなければ計算できず、出力の形も変わりません。次元を変えない操作です。

この違いだけで、役割が説明できます。

特徴を作り出すには、次元の変換が必要です。だから行列の積を使います。

情報を選別するには、形を保ったまま各位置の値を調整すればよい。だからアダマール積を使います。

AIのどこで使われるか

行列の積が使われる場所

場面数式何をしているか
全結合層y = Wx + b 入力の全要素を混ぜて新しい特徴を作る
Q、K、Vの生成Q = XW^{Q} 埋め込みを三つの役割に変換する
注意スコアの計算QK^{T} 単語どうしの関連度を測る
情報の集約\text{softmax}(\cdot) V 重みに応じて情報を混ぜ合わせる
出力層z = hW_e^{T} 隠れ状態を語彙数の得点に変換する

いずれも、次元が変わっています。そして、複数の入力が一つの出力に寄与しています。

アダマール積が使われる場所

場面数式何をしているか
LSTMのゲートc_t = f_t \odot c_{t-1} + i_t \odot \tilde{c}_t 記憶を残すか消すかを決める
GRUの更新h_t = (1 - z_t) \odot h_{t-1} + z_t \odot \tilde{h}_t 前の状態と新しい状態を混ぜる比率を決める
ドロップアウトy = x \odot m ランダムに一部を0にする
レイヤー正規化y = \gamma \odot \hat{x} + \beta 正規化後の尺度を次元ごとに調整する
SwiGLUなどのゲート機構y = \text{Swish}(xW) \odot (xV) 片方が他方の通過量を制御する
誤差逆伝播\delta = (W^{T}\delta') \odot \sigma'(z) 活性化関数の微分を各位置に掛ける

いずれも、形が変わっていません。そして、各位置が独立して処理されています。

LSTMで両方が並ぶ例

最も教えやすいのが、LSTMの忘却ゲートです。

まず、ゲートの値を作ります。

f_t = \sigma(W_f [h_{t-1}, x_t] + b_f)

ここは行列の積です。前の状態と今の入力を混ぜ合わせ、シグモイド関数で0から1の値にします。

次に、そのゲートを適用します。

c_t = f_t \odot c_{t-1} + i_t \odot \tilde{c}_t

ここはアダマール積です。作ったゲートの値を、記憶の各次元に掛けます。

流れを整理すると、次のようになります。

段階演算目的
ゲートを作る行列の積どこを通すべきかを判断する
ゲートを適用するアダマール積判断に従って通す量を決める

判断はミキサーで作り、実行はふるいで行う。この対比が、両者の役割を最もよく表しています。

ゲートの値の意味

シグモイド関数の出力は、0から1の範囲に収まります。

\sigma(x) = \frac{1}{1 + e^{-x}}

具体的に確認します。

\sigma(0) = \frac{1}{1 + e^{0}} = \frac{1}{2} = 0.5

\sigma(2) = \frac{1}{1 + e^{-2}} \approx \frac{1}{1 + 0.135} \approx 0.881

\sigma(-2) = \frac{1}{1 + e^{2}} \approx \frac{1}{1 + 7.389} \approx 0.119

この値をアダマール積で掛けると、次のような意味になります。

ゲートの値効果
1に近いほぼそのまま通す
0.5前後半分程度に弱める
0に近いほぼ消す

ふるいの目の粗さを、次元ごとに0から1で調整している、と説明できます。

数値例で確認します。記憶の状態とゲートが次のようになっているとします。

c_{t-1} = (2.0, ; -1.0, ; 3.0, ; 0.5)

f_t = (0.9, ; 0.1, ; 0.5, ; 0.99)

アダマール積を計算します。

f_t \odot c_{t-1} = (1.8, ; -0.1, ; 1.5, ; 0.495)

1番目と4番目はほぼ保持され、2番目はほぼ消え、3番目は半減しました。次元ごとに独立して扱われていることが確認できます。

誤差逆伝播で両方が現れる

もう一つ、両者が同時に出てくる重要な場面があります。

全結合層の誤差逆伝播では、次の式が現れます。

\delta^{(l)} = \left( (W^{(l+1)})^{T} \delta^{(l+1)} \right) \odot \sigma'(z^{(l)})

括弧の中は行列の積です。次の層から来た誤差を、重みの転置を使って前の層の次元へ戻しています。

括弧の外はアダマール積です。活性化関数の微分を、各位置に掛けています。

なぜここでアダマール積なのか。活性化関数は、各要素に独立して適用されるためです。

a_i = \sigma(z_i)

i 番目の出力は i 番目の入力にしか依存しません。したがって微分も位置ごとに独立し、掛け算も位置ごとになります。

この点は、連鎖律から導けます。研修で扱う際は、なぜ和が現れないのかを問いかけると、理解が定着します。

計算量の違い

実務上の感覚として、押さえておくべき差があります。

n \times n の行列どうしの場合を比較します。

行列の積では、出力の各要素に n 回の乗算と加算が必要です。要素は n^2 個あります。

n^2 \times n = n^3

計算量は O(n^3) です。

アダマール積では、各要素に1回の乗算だけです。

n^2 \times 1 = n^2

計算量は O(n^2) です。

具体的な数値で確認します。n = 1000 の場合を比べます。

1000^3 = 10^9

1000^2 = 10^6

千倍の差があります。アダマール積は、行列の積に比べて圧倒的に軽い演算です。

ゲート機構が多用される理由の一つが、ここにあります。制御のために大きな計算コストを払わずに済みます。

つまずきやすい点

研修で必ず補足すべき三点を挙げます。

1 ブロードキャストによる無言の失敗

最も危険な落とし穴です。

アダマール積は形が一致していなければ計算できない、と説明しました。しかし実際のライブラリでは、形が違っても自動的に拡張されて計算が通ってしまう場合があります。これをブロードキャストといいます。

たとえば、(3, 1) の配列と (1, 4) の配列を掛けると、(3, 4) の結果が返ります。エラーは出ません。

意図した計算と違っていても、プログラムは動き続けます。学習が進まない原因を探して、何日も費やすことになりかねません。

対策は、計算の前後で形を確認する習慣です。研修では、実際に形を出力させる演習を必ず入れてください。

2 数学とプログラムで記号の意味が違う

数学の教科書では、A \cdot B は行列の積を指します。しかしプログラムでは、* は要素ごとの積です。

論文の数式をコードに書き写すとき、この不一致が誤りを生みます。論文中に \odot があればアダマール積、なければ行列の積、という読み方を伝えてください。

3 交換法則が成り立つかどうか

アダマール積は、順序を入れ替えても結果が変わりません。

A \odot B = B \odot A

一方、行列の積は一般に順序を入れ替えられません。

AB \neq BA

先ほどの数値例で確認します。

BA = \begin{pmatrix} 5 \times 1 + 6 \times 3 & 5 \times 2 + 6 \times 4 \\ 7 \times 1 + 8 \times 3 & 7 \times 2 + 8 \times 4 \end{pmatrix} = \begin{pmatrix} 23 & 34 \\ 31 & 46 \end{pmatrix}

先ほどの AB とは、まったく違う結果になりました。

この違いも、混ぜるか選別するかという性質から説明できます。混ぜる順序は結果を変えますが、選別は順序に依存しません。

講師向けの進め方

推奨する順序

段階内容時間
1ミキサーとふるいの例えを提示する5分
22行2列の数値で両方を手計算させる15分
3形の規則を表で整理する5分
4なぜ役割が分かれるかを、総和の有無から説明する10分
5LSTMのゲートで両方が並ぶ例を示す10分
6ブロードキャストの落とし穴を実演する10分
7演習と解説15分

合計70分程度です。

山場は2番

手計算を省略しないでください。定義を読むだけでは、総和の有無が体感されません。

2行2列であれば、全員が数分で計算できます。同じ二つの行列から違う結果が出ることを、自分の手で確認させることが重要です。

6番は必ず実演する

ブロードキャストは、口頭で説明しても危機感が伝わりません。実際に形の違う配列を掛けて、エラーが出ずに違う形の結果が返る様子を見せてください。

「これは動きます。しかし、あなたが意図した計算ではありません」

この一言が、後の実務での事故を防ぎます。

想定質問と回答例

質問。なぜ行列の積のほうがよく使われるのですか。

回答。新しい特徴を作り出せるからです。アダマール積は形を変えられないため、単独では表現力が上がりません。ただし、制御の役割ではアダマール積のほうが適しています。役割が違うため、どちらが優れているという話ではありません。

質問。アダマール積は学習するパラメータを持ちますか。

回答。持つ場合と持たない場合があります。レイヤー正規化のスケールパラメータは学習されます。ドロップアウトのマスクは、学習ではなくランダムに生成されます。LSTMのゲートは、その値を作る行列の積の側にパラメータがあります。

質問。ゲートの値はなぜ0から1なのですか。

回答。通過量を表すためです。0で遮断、1で全通過という直感的な意味を持たせるために、シグモイド関数が使われます。もし負の値を許すと、符号が反転してしまい、ふるいという解釈が成り立たなくなります。

質問。行列の積で情報が混ざると、元の情報は失われますか。

回答。一般には失われます。ただし、残差接続を併用すると、元の情報を別経路で保持できます。トランスフォーマーが深い層を積めるのは、この仕組みがあるためです。

演習問題

問題1

次の二つの行列について、行列の積とアダマール積をそれぞれ求めてください。

A = \begin{pmatrix} 2 & 0 \\ 1 & 3 \end{pmatrix}, \quad B = \begin{pmatrix} 4 & 5 \\ 2 & 1 \end{pmatrix}

解答を示します。

行列の積を計算します。

1行1列目です。

2 \times 4 + 0 \times 2 = 8

1行2列目です。

2 \times 5 + 0 \times 1 = 10

2行1列目です。

1 \times 4 + 3 \times 2 = 4 + 6 = 10

2行2列目です。

1 \times 5 + 3 \times 1 = 5 + 3 = 8

AB = \begin{pmatrix} 8 & 10 \\ 10 & 8 \end{pmatrix}

アダマール積を計算します。

A \odot B = \begin{pmatrix} 8 & 0 \\ 2 & 3 \end{pmatrix}

注目すべきは、A_{12} = 0 の扱いです。アダマール積では1行2列目が0になりますが、行列の積では10になりました。0であっても、他の要素の寄与によって出力は0になりません。混ぜる操作と選別する操作の違いが、はっきり現れています。

問題2

(4, 6) の行列と (6, 3) の行列について、次の問いに答えてください。

(1) 行列の積は計算できますか。できる場合、出力の形は何ですか。 (2) アダマール積は計算できますか。

解答を示します。

(1) 計算できます。内側の次元が6で一致しているためです。出力の形は (4, 3) です。

(2) 計算できません。アダマール積は形が完全に一致している必要があります。

補足します。ブロードキャストが働く条件は、各次元が一致しているか、どちらかが1であることです。この例では4と6、6と3が対応し、いずれも条件を満たさないため、エラーになります。

問題3

次の式のうち、下線部にあたる演算がアダマール積であるものをすべて選んでください。

y = Wx + b における Wx c_t = f_t \odot c_{t-1} における f_t \odot c_{t-1} \text{softmax}(QK^{T}/\sqrt{d}) V における \text{softmax}(\cdot) V \delta = (W^{T}\delta') \odot \sigma'(z) における \odot \sigma'(z)

解答はイとエです。

解説します。イはLSTMのゲート適用であり、記憶の各次元に通過量を掛けています。エは活性化関数の微分を各位置に掛ける操作で、位置ごとに独立しています。

アは全結合層の変換です。入力の全要素を混ぜて出力を作るため、行列の積です。ウは注意の重みに従ってバリューを集約する操作で、複数の位置の情報を足し合わせるため、行列の積です。

ウを誤って選ぶ受講者が多く出ます。重みを掛けるという表現から、要素ごとの積を連想するためです。「足し合わせているか」を判断基準にするよう指導してください。

問題4

n \times n の行列どうしについて、行列の積とアダマール積の計算量の比を求めてください。n = 512 の場合の具体的な値も示してください。

解答を示します。

行列の積は O(n^3) 、アダマール積は O(n^2) です。比は次のようになります。

\frac{n^3}{n^2} = n

n = 512 の場合、512倍になります。

補足します。この差があるため、ゲート機構を追加しても計算コストの増加は限定的です。一方、行列の積を一つ追加すると、影響は大きくなります。モデルの設計で、どこにパラメータを置くかを考える際の判断材料になります。

振り返り

受講者に、次の問いで締めてください。

  • 二つの演算のうち、次元を変えられるのはどちらですか
  • 総和が現れるのはどちらですか
  • 交換法則が成り立つのはどちらですか
  • LSTMで、ゲートの値を作るのはどちらの演算ですか
  • 形が違ってもエラーが出ない場合があるのは、どちらですか

すべて答えられれば、この単元は理解できています。

まとめと次の学習ステップ

行列の積は、総和を伴うため情報が混ざります。次元を変換し、新しい特徴を作り出します。ミキサーの役割です。

アダマール積は、位置ごとに独立して掛け算します。形を変えず、通過量を調整します。ふるいの役割です。

そして、この二つはしばしば連携します。ゲートの値をミキサーで作り、それをふるいとして適用する。LSTMもGRUも、現代のゲート付き活性化関数も、この組み合わせでできています。

次の学習ステップとしては、テンソルの形の追跡に進むとよいでしょう。実際のモデルでは、バッチ次元や系列長の次元が加わり、形が複雑になります。どの演算でどう形が変わるかを追えるようになれば、論文の実装を読む力が大きく伸びます。

あわせて、ブロードキャストの規則を体系的に押さえておくことをおすすめします。便利な仕組みですが、意図しない計算を許してしまう側面もあります。規則を知ったうえで使うか、明示的に形を揃えるかを、方針として決めておいてください。

セイ・コンサルティング・グループでは新人エンジニア研修のアシスタント講師を募集しています。

投稿者プロフィール

山崎講師
山崎講師代表取締役
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
海外放浪の末、2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。

学生時代は趣味と実益を兼ねてリゾートバイトにいそしむ。長野県白馬村に始まり、志賀高原でのスキーインストラクター、沖縄石垣島、北海道トマム。高じてオーストラリアのゴールドコーストでツアーガイドなど。現在は野菜作りにはまっている。