Modern Hopfield NetworksとAttentionの等価性 — 連想記憶の更新則がTransformerと一致する

ぼやけた写真の一部を見ただけで、誰の顔かを思い出す。歌詞の冒頭を聞いただけで、続きが口をついて出る——人間の記憶は「部分的な手がかりから完全なパターンを取り出す」操作が得意です。この仕組みを数理モデルにしたものを連想記憶(associative memory)と呼び、その代表が1982年の Hopfieldネットワーク です。

一方、時代を40年近く下ったTransformerの心臓部 attention は、「query で key を照合して value を取り出す」検索の機械です。この2つ、出自も時代もまったく違うのに——数式がぴったり一致します。連想記憶を現代化した Modern Hopfield Network の「思い出す」操作は

$$ \xi^{\mathrm{new}} = X\,\mathrm{softmax}(\beta X^\top \xi) $$

で、記号を読み替えるとこれは attention の式そのものです。この驚くべき対応を示したのが Ramsauer らの論文 “Hopfield Networks is All You Need”(ICLR 2021)で、タイトルからして “Attention Is All You Need” への返歌になっています。

この等価性を知っていると、attention の見え方が変わります。

  • attentionの理論的な性質が使える: 記憶容量(何パターンまで正確に取り出せるか)、収束の速さ(なぜ attention は1回で「読み出し」が済むのか)、$\beta$(=温度)と検索の鋭さの関係など、Hopfield 側で証明された定理が attention の理解に輸入できる
  • 「Hopfield層」という道具が手に入る: 連想記憶を明示的なモジュールとして深層学習に組み込む設計(DeepRC など)が読めるようになる

本記事の内容

  • 古典Hopfieldネットワーク — エネルギー関数・Hebb則・想起のダイナミクスと容量限界(実装つき)
  • Modern Hopfield(連続版)のエネルギーと、更新則 $\xi^{\mathrm{new}} = X\,\mathrm{softmax}(\beta X^\top \xi)$ の導出
  • attention との対応の完全な読み替え表
  • パターン復元実験 — $\beta$ が生む3つの検索モード(単一収束・準安定・大域平均)
  • 記憶容量が線形から指数へ跳ね上がる話

前提知識

この記事を読む前に、以下の記事を読んでおくと理解が深まります。

連想記憶の1ステップ更新とAttentionの対応の概念図

上の図が本記事の全体地図です。左の連想記憶では「ぼやけた手がかり $\xi$」を「保存パターン $X$」と照合し、1ステップの更新で完全なパターンを思い出します。この更新式を attention の言葉に翻訳すると、$\xi$ が query、$X$ が key と value、$\beta$ がスケール $1/\sqrt{d_k}$ に対応します。まずは出発点の古典 Hopfield から見ていきましょう。

古典Hopfieldネットワーク: エネルギーを下る記憶

古典Hopfieldネットワークは、$N$ 個の $\pm 1$ をとるニューロン $s \in \{-1, +1\}^N$ でパターンを表します。覚えたいパターン $x^{(1)}, \dots, x^{(P)}$ があるとき、結合重みを Hebb則 で決めます。

$$ W = \frac{1}{N}\sum_{\mu=1}^{P} x^{(\mu)} (x^{(\mu)})^\top, \qquad W_{ii} = 0 $$

「一緒に発火したニューロン同士は結びつく」という学習則です。想起は、各ニューロンを1個ずつ「周囲の多数決」で更新する操作の繰り返しです。

$$ s_i \leftarrow \mathrm{sign}\left(\sum_j W_{ij} s_j\right) $$

この更新には美しい性質があります。エネルギー関数

$$ E(s) = -\frac{1}{2} s^\top W s $$

を定義すると、非同期更新のたびに $E$ は決して増えません。つまり想起とは「エネルギー地形を転がり落ちて、近くの谷(=覚えたパターン)に落ち着く」プロセスです。実際に、文字パターンを覚えさせてノイズだらけの手がかりから復元してみます。

import numpy as np

def hebb_weights(patterns):
    P, N = patterns.shape
    W = patterns.T @ patterns / N
    np.fill_diagonal(W, 0.0)
    return W

def hopfield_recall(W, s, steps=30, rng=None):
    s = s.copy(); order = np.arange(len(s))
    for _ in range(steps):
        rng.shuffle(order)
        changed = False
        for i in order:
            si = 1 if W[i] @ s >= 0 else -1
            if si != s[i]:
                s[i] = si; changed = True
        if not changed:
            break
    return s

# 10x10の2値画像2枚(縦棒とF)を記憶
side = 10; N = side * side
P0 = -np.ones((side, side)); P0[2:8, 4:6] = 1                       # 縦棒
P1 = -np.ones((side, side)); P1[2, 2:8] = 1; P1[5, 2:8] = 1; P1[2:9, 2] = 1  # F
pats = np.stack([P0.ravel(), P1.ravel()])
W = hebb_weights(pats)

rng = np.random.default_rng(3)
target = pats[1].copy()
corrupt = target.copy()
idx = rng.choice(N, size=int(0.30 * N), replace=False)
corrupt[idx] *= -1                       # 30%のピクセルを反転
recalled = hopfield_recall(W, corrupt, rng=rng)
print(f"想起前一致 = {(corrupt == target).mean():.3f}, 想起後一致 = {(recalled == target).mean():.3f}")
# => 想起前一致 = 0.700, 想起後一致 = 1.000

古典Hopfieldによるパターン想起: 30%ノイズから完全復元

30%のピクセルを反転させた手がかり(一致率 0.70)から、わずか数回の更新で完全なF(一致率 1.00)が蘇りました。「劣化した部分情報 → 完全なパターン」という連想記憶の本領です。エネルギーの推移も確認しておきます。

非同期更新でエネルギーは単調に減少する

エネルギーは初期の -11.2 から -48.6 まで単調に下がり、あとは動かなくなります。谷に落ちたら止まる——想起の終了条件がエネルギーの言葉で書けるわけです。

ただし、古典Hopfieldには致命的な弱点があります。覚えられる量が少ないのです。

記憶パターンが多すぎると干渉で崩壊する

ランダムなパターンを増やしながら「覚えたパターンがそのまま安定に保てるか」を測ると、パターン数がニューロン数の約0.14倍(理論値 $0.138N$)を超えたあたりから急速に壊れます。実測でも $\alpha = P/N = 0.18$ で安定度が0.99を割り、0.35では0.945まで落ちました。パターン同士の「混線(クロストーク)」が原因で、しかも上の文字の例のように似たパターンを覚えさせると、もっと少ない数でも偽の記憶(どのパターンでもない谷)に落ちるようになります。実は先ほどのデモで2文字しか覚えさせなかったのはこのためで、相関の強い文字を3つ覚えさせると30%ノイズからの復元はもう失敗します。

100次元で14パターン——これでは実用になりません。この容量の壁を打ち破ったのが Modern Hopfield です。

Modern Hopfield: エネルギーをlog-sum-expにする

容量の壁の原因は、エネルギーが $s^\top W s$ という2次形式であることにありました。Krotov & Hopfield (2016) は相互作用をより急峻な関数に置き換えると容量が増えることを示し、指数関数まで押し進めると容量が $2^{d/2}$ 級になることが分かりました(Demircigil et al., 2017)。Ramsauer らはこの流れを連続ベクトルへ拡張します。$d$ 次元の連続パターン $X = [x_1, \dots, x_N] \in \mathbb{R}^{d \times N}$ と連続状態 $\xi \in \mathbb{R}^d$ に対して、エネルギーを

$$ E(\xi) = -\mathrm{lse}\left(\beta,\ X^\top \xi\right) + \frac{1}{2}\xi^\top \xi + \mathrm{const} $$

と定義します。ここで $\mathrm{lse}$ は log-sum-exp

$$ \mathrm{lse}(\beta, z) = \beta^{-1} \log \sum_{i=1}^{N} \exp(\beta z_i) $$

です。直感的には、第1項が「どれかの保存パターンと似ているほどエネルギーが低い」($\mathrm{lse}$ は $\max_i x_i^\top \xi$ のソフト版)、第2項が「$\xi$ が勝手に大きくなるのを防ぐ錘」です。

このエネルギーを最小化する更新則を導きます。$E$ は「凹関数($-\mathrm{lse}$)+凸関数($\frac{1}{2}\xi^\top\xi$)」の和なので、Concave-Convex Procedure (CCCP) が使えます。CCCPでは、凸部分の勾配(新しい点で評価)と凹部分の勾配(現在の点で評価)を釣り合わせます。

$$ \nabla_\xi \left(\frac{1}{2}\xi^\top \xi\right)\bigg|_{\xi^{t+1}} = \nabla_\xi\, \mathrm{lse}(\beta, X^\top \xi)\bigg|_{\xi^t} $$

左辺は単純に $\xi^{t+1}$ です。右辺は合成関数の微分で、$\mathrm{lse}$ の勾配が softmax になるという有名な関係($\partial \mathrm{lse}/\partial z_i = \mathrm{softmax}(\beta z)_i$)を使うと

$$ \nabla_\xi\, \mathrm{lse}(\beta, X^\top \xi) = X\,\mathrm{softmax}(\beta X^\top \xi) $$

となります。両辺を等置して、更新則が得られました。

$$ \boxed{\ \xi^{\mathrm{new}} = X\,\mathrm{softmax}(\beta X^\top \xi)\ } $$

意味を読み下すと、「query $\xi$ と各保存パターンの内積を取り、$\beta$ で鋭さを調整して softmax で重みにし、保存パターンの重み付き平均を返す」——もうお気づきでしょう。次節でこの式を attention と突き合わせます。

Modern Hopfieldのエネルギー地形と更新の収束

1次元に射影したエネルギー地形を見ると、各保存パターンの位置に谷ができ、更新のたびに $\xi$ が最寄りの谷へ滑り込む様子が分かります。しかも Ramsauer らは、この更新が大域収束すること、よく分離したパターンなら1ステップで指数的に不動点へ近づくことを証明しています。

読み替え表: Hopfield = Attention

更新則の記号を置き換えます。$\xi \to q$(query)、$X \to K = V$(保存パターン=keyでありvalue)、$\beta \to 1/\sqrt{d_k}$ とすると

$$ \xi^{\mathrm{new}} = X\,\mathrm{softmax}(\beta X^\top \xi) \quad\Longleftrightarrow\quad \mathrm{Attention}(q, K, V) = V\,\mathrm{softmax}\!\left(\frac{K^\top q}{\sqrt{d_k}}\right) $$

完全に同じ形です。attention の1回の計算は、連想記憶の1ステップの「思い出し」にほかなりません。

Modern HopfieldとAttentionの対応表

この対応は原論文の Figure 1 に凝縮されています。

Hopfieldエネルギーの一般化からTransformerのattentionに至る対応(原論文Figure 1)

出典: Ramsauer et al., “Hopfield Networks is All You Need”, ICLR 2021, Fig.1

左から、2値 Modern Hopfield の指数エネルギー → 連続状態への新エネルギー(lse+2乗正則化)→ その CCCP 更新則 → Transformer の attention、という4段の変換チェーンです。「=」記号は「性質(高速収束・大容量)を保ったまま」の意味だと注記されています。つまり attention は、指数容量の連想記憶の読み出し回路として理論的に再解釈できるのです。

理屈が繋がったので、実際に「attention の式でパターンを思い出す」実験をしてみましょう。

実験: attentionの式で文字を思い出す

8×8の文字パターン5枚(A・T・L・O・H)を列に並べた $X$ を「記憶」とし、Aの下半分を消したものを query にして、先ほどの更新則を適用します。

import numpy as np

def softmax(z):
    e = np.exp(z - z.max())
    return e / e.sum()

def modern_update(X, xi, beta):
    """X: (d, N) 保存パターン(列), xi: (d,) query。1ステップ更新"""
    p = softmax(beta * (X.T @ xi))
    return X @ p, p

# 8x8の文字グリフ5枚を記憶 (±1画像, 詳細は省略)
side = 8
def glyph(setup):
    g = -np.ones((side, side)); setup(g); return g.ravel().astype(float)
A = glyph(lambda g: (g.__setitem__((1, slice(2,6)), 1), g.__setitem__((slice(2,7), 1), 1),
                     g.__setitem__((slice(2,7), 6), 1), g.__setitem__((4, slice(2,6)), 1)))
T = glyph(lambda g: (g.__setitem__((1, slice(1,7)), 1), g.__setitem__((slice(1,7), slice(3,5)), 1)))
L = glyph(lambda g: (g.__setitem__((slice(1,7), slice(1,3)), 1), g.__setitem__((6, slice(1,7)), 1)))
O = glyph(lambda g: (g.__setitem__((1, slice(2,6)), 1), g.__setitem__((6, slice(2,6)), 1),
                     g.__setitem__((slice(2,6), 1), 1), g.__setitem__((slice(2,6), 6), 1)))
H = glyph(lambda g: (g.__setitem__((slice(1,7), 1), 1), g.__setitem__((slice(1,7), 6), 1),
                     g.__setitem__((slice(3,5), slice(1,7)), 1)))
X = np.stack([A, T, L, O, H], axis=1)   # (64, 5)

target = A.copy()
masked = target.copy(); masked[side*side//2:] = 0.0   # 下半分を消す
beta = 8.0 / (side * side)

out, p = modern_update(X, masked, beta)
out2, _ = modern_update(X, out, beta)
names = ["A", "T", "L", "O", "H"]
print(f"softmax重み最大 = {p.max():.3f}(パターン{names[p.argmax()]})")
print(f"復元パターンの正解Aとの一致率 = {(np.sign(out2) == target).mean():.3f}")
# => softmax重み最大 = 0.435(パターンA)
# => 復元パターンの正解Aとの一致率 = 0.953

下半分マスクされたAをModern Hopfieldが復元する

上半分だけの手がかりから、Aがほぼ復元されました(一致率 0.953)。右端の棒グラフが softmax の重み——つまり attention weights ——です。Aに最大の重み 0.435 が付き、上半分の形が似ているOにも同程度の重みが付いています。「復元=保存パターンの attention 加重平均」という等価性が、そのまま絵になっています。

では、$\beta$(attention でいう温度の逆数)を動かすと何が起きるでしょうか。

βが検索モードを切り替える: 大域平均・準安定・単一パターン

Ramsauer らが整理した3つの検索モードが現れます。$\beta$ が小さいと softmax はほぼ一様になり、全記憶の平均というぼやけた像に落ちます(重みエントロピー 1.61 ≒ 一様分布の $\log 5$)。中間の $\beta$ では、似たパターン数個の平均——準安定状態(metastable state)——に留まります(エントロピー 1.45)。$\beta$ が大きいと単一パターンへ鋭く収束します(エントロピー 0.73)。attention に翻訳すれば、「広く浅く文脈を混ぜるヘッド」と「1トークンを狙い撃つヘッド」の違いが、$\beta$ ひとつで連続的に繋がっていることになります。

βとattention重みエントロピーの関係

$\beta$ を掃引すると、重みのエントロピーは一様極限($\log 5 = 1.61$)から鋭い検索(0.70)まで単調に下がります。$1/\sqrt{d_k}$ スケーリングが「適度な $\beta$ を選ぶ行為」だという見方もできます。

収束の速さも確認しておきます。

更新1回でほぼ不動点に到達する

不動点(更新を50回繰り返した収束先)までの距離を追うと、最初の1回で距離5.24から2.31へと大きく縮み、以降の更新の寄与はわずかです。理論が言う「典型的には1ステップで読み出しが済む」性質で、だからこそ Transformer は attention を再帰的に反復せず、1回適用して次の層へ渡す設計で成立しているのだと解釈できます。

最後に、Modern Hopfield が古典の容量問題をどう解決したかをまとめます。

記憶容量の比較: 古典の線形 vs Modernの指数

古典Hopfieldの容量はニューロン数に対して線形($\approx 0.14N$)でしたが、Modern Hopfield は次元 $d$ に対して指数的($\propto c^{d}$ 級)です。$d=64$ のヘッド次元でも天文学的な数のパターンを区別して取り出せる——attention が「系列中のどのトークンでも正確に引き当てられる」理論的な裏付けがここにあります。

まとめ

本記事では、連想記憶と attention を繋ぐ等価性を、古典から現代まで通しで解説しました。

  • 古典Hopfieldはエネルギー $-\frac{1}{2}s^\top Ws$ を下る連想記憶。30%ノイズから完全復元できる(実測 0.70→1.00)が、容量は線形($\approx 0.14N$)で、相関パターンには弱い
  • Modern Hopfieldはエネルギーを $-\mathrm{lse}(\beta, X^\top\xi) + \frac{1}{2}\xi^\top\xi$ に一般化。CCCPから導かれる更新則が $\xi^{\mathrm{new}} = X\,\mathrm{softmax}(\beta X^\top \xi)$
  • この更新則は $\xi = q$, $X = K = V$, $\beta = 1/\sqrt{d_k}$ と置くと attention の式と完全一致。attention は指数容量の連想記憶の1ステップ読み出し
  • $\beta$(温度の逆数)が検索モードを決める: 大域平均(エントロピー1.61)→ 準安定(1.45)→ 単一収束(0.73)。attentionヘッドの「広く見る/狙い撃つ」の違いに対応
  • 収束は速く、1回の更新で不動点へ大きく近づく(距離5.24→2.31)。Transformerがattentionを1回ずつ適用する設計と整合する

「Transformerは何をしているのか」への答えがまた1つ増えました——各attention層は、文脈というその場限りの記憶に対する連想記憶の読み出しである。

次のステップとして、以下の記事も参考にしてください。

画像なし
Attentionは『ソフトな辞書引き』— カーネル回帰(Nadaraya-Watson推定)との等価性
attentionを統計学の言葉で言い換えるもう1つの理論的視点
画像なし
なぜAttentionはスケールドドット積なのか — √d_kで割る理由を徹底解説
β=1/√d_kを「温度」として理解する。本記事の等価性の前提
画像なし
softmaxの温度とattentionエントロピー
注意の『集中・分散』をエントロピーで定量化する。検索モードの議論と直結