1. 引言:从诺贝尔奖到深度学习的新基础
John Hopfield于1982年提出的Hopfield网络是神经网络领域的奠基性工作之一。2024年诺贝尔物理学奖授予John Hopfield和Geoffrey Hinton,“for foundational discoveries and inventions that enable machine learning with artificial neural networks”,标志着联想记忆理论的复兴。1
2020年,Ramsauer等人发表《Hopfield Networks is All You Need》,证明现代Hopfield网络的更新规则就是Transformer的自注意力机制——这建立了联想记忆与深度学习最强大架构之间的桥梁。2 2024-2026年,该领域经历了新一轮理论突破:球面码视角的最优容量证明、Fenchel-Young统一框架、Titans/MIRAS测试时记忆等。
本文档系统阐述现代Hopfield网络的基础理论,从经典模型出发,推导到现代版本,建立完整的数学框架。
1.1 内容框架
┌─────────────────────────────────────────────────────────────────────┐
│ 现代Hopfield网络知识体系 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ 经典Hopfield │ │ 现代Hopfield │ │ 注意力等价 │ │
│ │ (1982) │ │ (Ramsauer 2020) │ │ Transformer │ │
│ │ 二元状态 │ │ 连续状态 │ │ QKV检索 │ │
│ │ 局部更新 │ │ 全局更新 │ │ 多头 │ │
│ │ O(d)容量 │ │ 2^(d/2)容量 │ │ β=1/√d │ │
│ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │ │
│ └────────────────────┼────────────────────┘ │
│ │ │
│ ┌─────────────────────────────┴─────────────────────────────┐ │
│ │ 能量函数统一视角 │ │
│ │ E(ξ) = -lse(β, X^⊤ξ)/β + ||ξ||²/2 │ │
│ │ ↑ ↑ │ │
│ │ 现代 凸分析框架 │ │
│ └───────────────────────────────────────────────────────────┘ │
│ │
│ 应用层:表格、时序、药物、免疫、医学影像、扩散模型 │
└─────────────────────────────────────────────────────────────────────┘
1.2 与现有wiki文档的关系
- 能量基模型与深度学习 — 能量函数基础、Langevin采样
- Markov随机场与EBM — 概率图视角
- Transformer数学基础 — 注意力机制的矩阵视角
- 注意力机制现代理论 — 注意力的共识、OT等新视角
- 架构收敛模式 — 现代Transformer的统一栈
- 能量Transformer — Hopfield视角的Transformer
2. 经典Hopfield网络(1982)
2.1 网络结构
经典Hopfield网络由个二元(或连续)神经元构成,神经元之间的连接权重为(对称、零自连接 )。
状态空间:
能量函数:
更简洁的矩阵形式(对称):
2.2 Hebbian学习
给定个要存储的记忆模式,权重通过外积规则(outer product rule)学习:
矩阵形式:
其中。
2.3 异步更新规则
神经元的状态更新(异步方式,依次更新):
或带阈值的形式:
2.4 能量单调下降
关键定理:每次更新不增加能量。
证明:设神经元状态从变为,其他不变。能量变化为:
若更新规则,则与同号,故。等号成立当且仅当不变。
Lyapunov函数:是网络的Lyapunov函数,保证网络收敛到不动点(局部能量极小)。
2.5 存储容量限制
经典Hopfield容量(Amit 1985):
即在个神经元中可以可靠存储约个记忆模式。超过此容量,虚假态(spurious states)大量涌现,模式检索失败。
为什么会有限制:存储的模式之间存在串扰(crosstalk)。当过大时,Hebbian权重矩阵近似于随机,记忆模式的”信号”被噪声淹没。
2.6 模式检索的生物学隐喻
经典Hopfield网络与大脑海马体的联想记忆功能有深刻联系:
- 每个记忆对应能量景观的一个吸引子
- 回忆对应从初始状态沿能量梯度下落到吸引子
- 部分线索可以完整恢复(模式完成,pattern completion)
- 抗噪声输入(模式分离失败时)仍可找到正确吸引子
2.7 PyTorch实现:经典Hopfield
import torch
import torch.nn as nn
class ClassicalHopfield(nn.Module):
"""经典Hopfield网络(二元,Hebbian学习)"""
def __init__(self, num_neurons: int):
super().__init__()
self.num_neurons = num_neurons
# 权重矩阵(初始化为零)
self.weight = nn.Parameter(torch.zeros(num_neurons, num_neurons))
def store_patterns(self, patterns: torch.Tensor):
"""
Hebbian学习存储模式。
参数:
patterns: (M, N) 形状的二元模式张量,元素为±1
"""
M, N = patterns.shape
assert N == self.num_neurons
# 外积和
self.weight.data = (patterns.T @ patterns) / N
# 零对角
self.weight.data.fill_diagonal_(0.0)
def energy(self, state: torch.Tensor) -> torch.Tensor:
"""计算能量 E(s) = -1/2 * s^T W s"""
return -0.5 * torch.einsum('bi,ij,bj->b', state, self.weight, state)
@torch.no_grad()
def recall(self, query: torch.Tensor, max_steps: int = 100) -> torch.Tensor:
"""异步更新检索"""
state = query.clone()
for step in range(max_steps):
prev_state = state.clone()
# 计算局部场
local_field = state @ self.weight
# 异步更新(这里用同步更新近似)
state = torch.sign(local_field)
# 防止零状态
state[state == 0] = 1
# 检查收敛
if torch.all(state == prev_state):
break
return state
# 测试
if __name__ == "__main__":
torch.manual_seed(42)
N = 100 # 神经元数
M = 12 # 存储模式数(远小于容量 0.14*N ≈ 14)
# 生成随机二元模式
patterns = torch.sign(torch.randn(M, N))
net = ClassicalHopfield(N)
net.store_patterns(patterns)
# 测试检索:给受损模式,期望恢复到原模式
query = patterns[0].clone()
query[:20] = -query[:20] # 翻转前20个
retrieved = net.recall(query.unsqueeze(0)).squeeze(0)
accuracy = (retrieved == patterns[0]).float().mean()
print(f"检索准确率: {accuracy:.3f}")
# 验证能量下降
initial_energy = net.energy(query.unsqueeze(0)).item()
final_energy = net.energy(retrieved.unsqueeze(0)).item()
print(f"初始能量: {initial_energy:.2f} → 最终能量: {final_energy:.2f}")
assert final_energy <= initial_energy, "能量未下降!"3. 连续Hopfield网络与密集联想记忆
3.1 连续Hopfield网络(1984)
将离散状态推广为连续状态,神经元动力学由微分方程描述:
能量函数:
连续版本保留了联想记忆能力,但容量仍受限于。
3.2 密集联想记忆(Krotov-Hopfield 2016)
Krotov和Hopfield在2016年提出多项式能量的密集联想记忆(Dense Associative Memory, DAM)。3
一般能量形式:
其中是单调递增函数,是存储的模式。
多项式:
- :退化为经典Hopfield
- :,容量
- :容量
- 一般:容量
3.3 Demircigil指数能量(2017)
选择指数函数:
这实现了指数级容量:
其中是模式维度(假设模式位于的球面上)。
直觉:指数函数使能量景观极为陡峭,每个存储模式都是一个深且窄的能量井。模式之间的”分隔墙”呈指数高,因而可以容纳指数多个模式。
容量证明概要:设模式位于的球面上,且任意两个模式的内积有界。当时,能量。当在两个模式中间时,能量。因此信噪比指数大。
4. 现代Hopfield网络(Ramsauer 2020)
4.1 核心论文
Ramsauer, Schäfl, Lehner, Seidl, Widrich, Adler, Gruber, Holzleitner, Pavlović, Sandve, Greiff, Kreil, Kopp, Klambauer, Brandstetter, Hochreiter. “Hopfield Networks is All You Need.” ICLR 2021.2
4.2 数学定义
存储模式:,堆叠成矩阵。
查询模式:(待检索的查询)。
现代Hopfield能量函数:
其中:
- 是对数和指数(log-sum-exp)
- 是逆温度参数
能量函数直觉:
- 第一项 :鼓励与某个存储模式接近
- 第二项 :正则化项,防止无限增长
4.3 CCCP推导更新规则
定理(Ramsauer 2020):现代Hopfield能量可以用凹-凸过程(CCCP,Yuille & Rangarajan 2003)优化。
推导:
能量可以写成两个函数之差:
其中是凸函数,是凹函数。CCCP迭代步骤为:
对应用CCCP:
这是凹函数(log-sum-exp是凸的,前面有负号)。
这是凸函数。
CCCP步骤:
计算梯度:
代入并求解(最小化的二次型):
这就是现代Hopfield网络的更新规则——也是Transformer自注意力的核心。
4.4 三类不动点
现代Hopfield网络有三种类型的不动点:
- 单模式固定点:(恢复某个存储模式)
- 亚稳态:,是某些模式的凸组合
- 全局态:(所有模式的平均)
检索模式时,我们希望找到单模式固定点;亚稳态是虚假态(spurious states)的根源。
4.5 模式分离条件
存储模式是单模式固定点的充分条件是模式分离:
即模式与自身的内积大于它与其他模式的最大内积。
检索误差:从查询出发,更新后状态与的偏差指数小:
越大,模式分离越强,检索越精确。
4.6 存储容量
Ramsauer 2020证明:
对维模式、存储在球面上、模式分离条件下:
指数级容量:以模式维度的指数增长。
与经典Hopfield对比:
| 模型 | 容量 | 增长 | 检索精度 |
|---|---|---|---|
| 经典Hopfield | 线性 | 近似 | |
| Krotov多项式 | 多项式 | 近似 | |
| Demircigil指数 | 指数 | 近似 | |
| 现代Hopfield | 指数 | 近似(指数小误差) |
4.7 PyTorch实现:现代Hopfield
import torch
import torch.nn as nn
import torch.nn.functional as F
class ModernHopfield(nn.Module):
"""现代Hopfield网络(Ramsauer 2020)"""
def __init__(self, beta: float = 1.0):
super().__init__()
self.beta = beta # 逆温度
def energy(self, query: torch.Tensor, patterns: torch.Tensor) -> torch.Tensor:
"""
计算现代Hopfield能量。
参数:
query: (B, d) 查询模式
patterns: (N, d) 存储的模式
返回:
energy: (B,) 每个查询的能量
"""
# X^T ξ: (B, N)
scores = torch.einsum('bd,nd->bn', query, patterns)
# lse(β, scores)
lse = torch.logsumexp(self.beta * scores, dim=-1) / self.beta
# E = -lse + ||ξ||²/2
energy = -lse + 0.5 * torch.sum(query ** 2, dim=-1)
return energy
def retrieve(self, query: torch.Tensor, patterns: torch.Tensor) -> torch.Tensor:
"""
单步检索(=注意力)。
参数:
query: (B, d) 查询
patterns: (N, d) 模式(= keys)
返回:
retrieved: (B, d) 检索结果(= attention output)
"""
# X softmax(β X^T ξ)
scores = torch.einsum('bd,nd->bn', query, patterns)
attn = F.softmax(self.beta * scores, dim=-1)
retrieved = torch.einsum('bn,nd->bd', attn, patterns)
return retrieved
def retrieve_iterative(
self, query: torch.Tensor, patterns: torch.Tensor, max_steps: int = 10
) -> torch.Tensor:
"""迭代检索(多次CCCP步骤)"""
state = query
for _ in range(max_steps):
new_state = self.retrieve(state, patterns)
# 收敛检查
if torch.allclose(new_state, state, atol=1e-5):
break
state = new_state
return state
# 测试:模式检索
if __name__ == "__main__":
torch.manual_seed(0)
d = 64
N = 100
beta = 5.0 # 较大的β→更尖锐的检索
# 随机正交化模式
patterns_raw = torch.randn(N, d)
patterns, _ = torch.linalg.qr(patterns_raw.T) # 正交化
patterns = patterns.T # (N, d)
# 缩放到 √d 球面
patterns = patterns * (d ** 0.5)
net = ModernHopfield(beta=beta)
# 测试检索
query = patterns[0] + 0.1 * torch.randn(d) # 模式0 + 噪声
retrieved = net.retrieve_iterative(
query.unsqueeze(0), patterns, max_steps=20
).squeeze(0)
# 计算检索误差
error = torch.norm(retrieved - patterns[0]).item()
print(f"检索误差: {error:.6f}")
# 测试能量下降
E_initial = net.energy(query.unsqueeze(0), patterns).item()
E_final = net.energy(retrieved.unsqueeze(0), patterns).item()
print(f"能量: {E_initial:.3f} → {E_final:.3f}(差={E_final-E_initial:.3f})")4.8 与Transformer注意力的精确等价
核心定理:当、(键矩阵)、query 、值时:
对应关系:
| Hopfield变量 | Transformer变量 |
|---|---|
| 存储模式 | 键向量 |
| 查询模式 | 查询向量 |
| 检索输出 | 值向量的加权和 |
| 逆温度 | |
| 更新规则 | 注意力 |
注意力的Hopfield解释:
- 注意力分数 = 模式分离度
- 注意力权重 = 后验概率(给定查询下模式的后验)
- 注意力输出 = 期望值(给定查询下的模式期望)
5. CCCP:现代Hopfield的优化方法
5.1 凹-凸过程(CCCP)
Yuille & Rangarajan (2003) 提出的优化方法,用于优化目标函数是两个凸函数之差的形式:
迭代规则:从开始,交替求解:
收敛性:在一定条件下,CCCP收敛到的局部极小或鞍点。能量单调下降:
5.2 应用于现代Hopfield
能量分解:
注意:这里是凹函数(lse是凸函数,前面有负号)。
CCCP迭代(取梯度):
求解:
但我们希望的方向与一致。在Ramsauer 2020中:
等价性:两边差一个符号,可以重新定义能量使其一致。
5.3 单步vs多步
单步检索(一次CCCP迭代):等价于Transformer的一次注意力计算。
多步检索:迭代多次可获得更精确的固定点,但实践中单步通常足够(因为Transformer通常堆叠多层,每层都是一次Hopfield检索)。
5.4 与梯度下降的关系
现代Hopfield更新也可以看作梯度下降:
但需要投影到特定范数上(球面投影),所以是投影梯度下降。
6. Hopfield作为深度学习模块
6.1 三种角色(Ramsauer 2020)
现代Hopfield层可以作为:
- 联想记忆:输入键值对,查询,输出检索结果
- 池化层(HopfieldPooling):学习一个查询原型,从输入集合中检索代表性向量
- 注意力替代:替代Transformer中的注意力层
6.2 Hopfield层的PyTorch实现
import torch
import torch.nn as nn
import torch.nn.functional as F
class HopfieldLayer(nn.Module):
"""
通用Hopfield层(Ramsauer 2020风格)。
支持:
- 静态模式(训练前固定)
- 联想记忆模式(输入即模式)
- 池化模式
"""
def __init__(
self,
input_dim: int,
hidden_dim: int,
num_heads: int = 1,
beta: float = 1.0,
):
super().__init__()
self.input_dim = input_dim
self.hidden_dim = hidden_dim
self.num_heads = num_heads
self.head_dim = hidden_dim // num_heads
self.beta = beta
# 投影矩阵
self.W_q = nn.Linear(input_dim, hidden_dim)
self.W_k = nn.Linear(input_dim, hidden_dim)
self.W_v = nn.Linear(input_dim, hidden_dim)
self.W_o = nn.Linear(hidden_dim, input_dim)
def forward(
self,
query: torch.Tensor, # (B, L_q, d_in)
key: torch.Tensor, # (B, L_k, d_in)
value: torch.Tensor = None, # (B, L_v, d_in)
mask: torch.Tensor = None, # (B, L_q, L_k)
) -> torch.Tensor:
if value is None:
value = key
B, L_q, _ = query.shape
_, L_k, _ = key.shape
# 投影
Q = self.W_q(query).view(B, L_q, self.num_heads, self.head_dim).transpose(1, 2)
K = self.W_k(key).view(B, L_k, self.num_heads, self.head_dim).transpose(1, 2)
V = self.W_v(value).view(B, L_k, self.num_heads, self.head_dim).transpose(1, 2)
# Q, K, V: (B, H, L, head_dim)
# Hopfield检索 = 注意力
scale = self.beta / (self.head_dim ** 0.5)
attn_scores = torch.matmul(Q, K.transpose(-2, -1)) * scale
if mask is not None:
attn_scores = attn_scores.masked_fill(mask == 0, float('-inf'))
attn_weights = F.softmax(attn_scores, dim=-1)
# 检索结果
out = torch.matmul(attn_weights, V) # (B, H, L_q, head_dim)
out = out.transpose(1, 2).contiguous().view(B, L_q, self.hidden_dim)
out = self.W_o(out)
return out
class HopfieldPooling(nn.Module):
"""Hopfield池化:学习一个查询原型"""
def __init__(self, input_dim: int, num_heads: int = 1):
super().__init__()
self.input_dim = input_dim
self.num_heads = num_heads
# 可学习的状态原型
self.state = nn.Parameter(torch.randn(1, 1, input_dim) * 0.02)
def forward(self, x: torch.Tensor) -> torch.Tensor:
"""
参数:
x: (B, L, d) 输入序列
返回:
pooled: (B, d) 池化结果
"""
B = x.shape[0]
state = self.state.expand(B, -1, -1) # (B, 1, d)
# 多次Hopfield检索迭代
for _ in range(3):
scores = torch.einsum('bld,bnd->bln', state, x) / (self.input_dim ** 0.5)
attn = F.softmax(scores, dim=-1)
state = torch.einsum('bln,bld->bnd', attn, x)
return state.squeeze(1)6.3 训练动力学分析
梯度流:Hopfield层的梯度可以通过自动微分计算。关键观察:
通过链式法则可以推导,但实践中使用PyTorch自动微分即可。
PyTorch官方实现:ml-jku/hopfield-layers(≈1.9k stars)提供了完整的实现和文档。
6.4 在深度架构中的位置
现代Hopfield层可以作为:
- Transformer层的注意力替代
- 池化层(替代mean/max pooling)
- 记忆模块(键值存储)
- 多示例学习的聚合器
典型架构:
输入 → [Hopfield Layer] → [Hopfield Layer] → ... → [Hopfield Pooling] → 输出
(self-attention) (cross-attention) (sequence-level)
7. 历史与生物学背景
7.1 神经元模型到Hopfield
McCulloch-Pitts神经元(1943):二元阈值神经元。
Hebbian学习(1949):“同步激活,连接增强”——“neurons that fire together, wire together”。
Rosenblatt感知器(1958):监督学习的第一个模型。
Hopfield网络(1982):将统计物理引入神经网络,建立能量函数。
7.2 Hopfield与统计物理
Ising模型(1925):铁磁性的简化模型,。
Sherrington-Kirkpatrick模型(1975):自旋玻璃,,随机。
Hopfield网络:Hebbian权重是Ising/SK模型的一个特例——具有结构化的耦合。
关键概念:温度(逆温度)
- ():系统处于基态(最低能量态)
- ():热噪声主导,访问所有状态
- 临界温度:检索-混淆相变
7.3 神经科学关联
| Hopfield概念 | 神经科学对应 |
|---|---|
| 能量函数 | 大脑状态空间的Lyapunov函数 |
| 吸引子 | 海马体中的记忆印记(engram) |
| 模式完成 | 线索触发的回忆 |
| 模式分离 | 齿状回的差异化编码 |
| 虚假态 | 错误记忆、记忆混淆 |
| CCCP更新 | 神经群体动力学 |
2024年诺贝尔物理学奖授予Hopfield与Hinton的理由正是这种”统计物理与人工智能的深度联系”。
7.4 Hopfield-Hinton 2024 Nobel Prize
颁奖词:表彰”为通过人工神经网络实现机器学习做出的奠基性发现和发明”。
Hopfield的贡献:联想记忆网络的物理基础。
Hinton的贡献:玻尔兹曼机、深度信念网络、AlexNet。
这一奖项反映了统计物理、神经科学和深度学习的融合趋势。
8. 完整PyTorch实践
8.1 实现一:从零实现现代Hopfield
import torch
import torch.nn as nn
import torch.nn.functional as F
from typing import Optional
class ModernHopfieldFromScratch(nn.Module):
"""
从零实现现代Hopfield网络(Ramsauer 2020)。
展示注意力机制的Hopfield本质。
"""
def __init__(
self,
pattern_dim: int, # 模式维度 d
num_patterns: int = 0, # 存储的模式数(0表示输入动态)
beta: float = 1.0, # 逆温度
learn_beta: bool = False,
):
super().__init__()
self.pattern_dim = pattern_dim
self.num_patterns = num_patterns
if learn_beta:
self.beta = nn.Parameter(torch.tensor(float(beta)))
else:
self.register_buffer('beta', torch.tensor(float(beta)))
if num_patterns > 0:
# 静态模式(可在训练中更新)
self.patterns = nn.Parameter(torch.randn(num_patterns, pattern_dim))
else:
self.patterns = None
def energy(
self,
query: torch.Tensor,
patterns: Optional[torch.Tensor] = None
) -> torch.Tensor:
"""计算能量 E(ξ) = -lse(β, X^T ξ)/β + ||ξ||²/2"""
if patterns is None:
patterns = self.patterns
assert patterns is not None
scores = torch.einsum('bd,nd->bn', query, patterns)
lse = torch.logsumexp(self.beta * scores, dim=-1) / self.beta
energy = -lse + 0.5 * (query ** 2).sum(dim=-1)
return energy
def forward(
self,
query: torch.Tensor,
patterns: Optional[torch.Tensor] = None
) -> torch.Tensor:
"""单步Hopfield检索 = 注意力"""
if patterns is None:
patterns = self.patterns
assert patterns is not None
# 计算注意力分数
scores = torch.einsum('bd,nd->bn', query, patterns) # (B, N)
attn = F.softmax(self.beta * scores, dim=-1)
# 加权求和
out = torch.einsum('bn,nd->bd', attn, patterns)
return out
def iterative_retrieve(
self,
query: torch.Tensor,
patterns: Optional[torch.Tensor] = None,
max_steps: int = 10,
tol: float = 1e-5,
) -> torch.Tensor:
"""迭代检索(多次CCCP)"""
state = query
for step in range(max_steps):
new_state = self.forward(state, patterns)
diff = (new_state - state).norm(dim=-1).max().item()
if diff < tol:
break
state = new_state
return state
# 演示:模式检索能力
def demonstrate_retrieval():
torch.manual_seed(42)
d = 128
N = 200
beta = 8.0
# 生成正交化模式
patterns_raw = torch.randn(N, d)
patterns, _ = torch.linalg.qr(patterns_raw.T)
patterns = patterns.T # (N, d)
net = ModernHopfieldFromScratch(
pattern_dim=d,
num_patterns=N,
beta=beta
)
net.patterns.data = patterns.clone()
# 测试检索不同模式
for idx in [0, 50, 100]:
# 加噪声
query = patterns[idx] + 0.5 * torch.randn(d)
retrieved = net(query.unsqueeze(0)).squeeze(0)
error = (retrieved - patterns[idx]).norm().item()
rel_error = error / patterns[idx].norm().item()
print(f"模式 {idx}: 相对误差 = {rel_error:.4f}")
# 容量测试
print("\n容量测试(不同模式数):")
for N_test in [10, 50, 100, 200, 500]:
if N_test > d:
continue
net_test = ModernHopfieldFromScratch(d, N_test, beta=beta)
net_test.patterns.data = torch.randn(N_test, d)
net_test.patterns.data = F.normalize(net_test.patterns.data, dim=-1) * (d ** 0.5)
errors = []
for i in range(min(10, N_test)):
query = net_test.patterns.data[i] + 0.3 * torch.randn(d)
retrieved = net_test(query.unsqueeze(0)).squeeze(0)
errors.append((retrieved - net_test.patterns.data[i]).norm().item())
print(f" N={N_test}: 平均误差={sum(errors)/len(errors):.4f}")
if __name__ == "__main__":
demonstrate_retrieval()8.2 实现二:Hopfield作为Transformer Block
class HopfieldBlock(nn.Module):
"""完整的Hopfield Transformer Block"""
def __init__(
self,
d_model: int,
n_heads: int = 8,
d_ff: int = None,
dropout: float = 0.1,
beta_init: float = 1.0,
learn_beta: bool = True,
norm_type: str = 'rmsnorm',
):
super().__init__()
if d_ff is None:
d_ff = 4 * d_model
# Hopfield自注意力
self.attn = MultiHeadHopfieldAttention(
d_model=d_model,
n_heads=n_heads,
beta_init=beta_init,
learn_beta=learn_beta,
)
# 前馈
self.ff = nn.Sequential(
nn.Linear(d_model, d_ff),
nn.GELU(),
nn.Linear(d_ff, d_model),
nn.Dropout(dropout),
)
# 归一化(pre-norm风格)
if norm_type == 'rmsnorm':
self.norm1 = RMSNorm(d_model)
self.norm2 = RMSNorm(d_model)
else:
self.norm1 = nn.LayerNorm(d_model)
self.norm2 = nn.LayerNorm(d_model)
self.dropout = nn.Dropout(dropout)
def forward(self, x: torch.Tensor, mask: torch.Tensor = None) -> torch.Tensor:
# Pre-norm + Hopfield attention + 残差
attn_out = self.attn(self.norm1(x), mask=mask)
x = x + self.dropout(attn_out)
# Pre-norm + FFN + 残差
ff_out = self.ff(self.norm2(x))
x = x + self.dropout(ff_out)
return x
class RMSNorm(nn.Module):
"""RMSNorm(更高效的归一化)"""
def __init__(self, dim: int, eps: float = 1e-6):
super().__init__()
self.eps = eps
self.weight = nn.Parameter(torch.ones(dim))
def forward(self, x: torch.Tensor) -> torch.Tensor:
rms = x.norm(dim=-1, keepdim=True) * (x.shape[-1] ** -0.5)
return x / (rms + self.eps) * self.weight
class MultiHeadHopfieldAttention(nn.Module):
"""多头Hopfield注意力(=标准多头注意力的Hopfield视角)"""
def __init__(
self,
d_model: int,
n_heads: int = 8,
beta_init: float = 1.0,
learn_beta: bool = True,
):
super().__init__()
assert d_model % n_heads == 0
self.d_model = d_model
self.n_heads = n_heads
self.head_dim = d_model // n_heads
self.W_qkv = nn.Linear(d_model, 3 * d_model, bias=False)
self.W_o = nn.Linear(d_model, d_model, bias=False)
if learn_beta:
self.beta = nn.Parameter(torch.tensor(float(beta_init)))
else:
self.register_buffer('beta', torch.tensor(float(beta_init)))
def forward(self, x: torch.Tensor, mask: torch.Tensor = None) -> torch.Tensor:
B, L, _ = x.shape
# 投影到QKV
qkv = self.W_qkv(x).reshape(B, L, 3, self.n_heads, self.head_dim)
q, k, v = qkv.permute(2, 0, 3, 1, 4) # (3, B, H, L, head_dim)
# Hopfield注意力
scale = self.beta / (self.head_dim ** 0.5)
attn = torch.einsum('bhld,bhkd->bhlk', q, k) * scale
if mask is not None:
attn = attn.masked_fill(mask == 0, float('-inf'))
attn = F.softmax(attn, dim=-1)
# 输出
out = torch.einsum('bhlk,bhkd->bhld', attn, v)
out = out.transpose(1, 2).reshape(B, L, self.d_model)
return self.W_o(out)8.3 实现三:Hopfield池化与MIL
class HopfieldMIL(nn.Module):
"""
多示例学习(MIL)with Hopfield层。
用于医学影像、全切片图像、表格数据等场景。
"""
def __init__(
self,
instance_dim: int,
hidden_dim: int,
num_classes: int,
beta: float = 1.0,
):
super().__init__()
# 实例编码器
self.instance_encoder = nn.Sequential(
nn.Linear(instance_dim, hidden_dim),
nn.GELU(),
nn.Linear(hidden_dim, hidden_dim),
)
# Hopfield池化:学习一个查询原型
self.prototype = nn.Parameter(torch.randn(1, 1, hidden_dim) * 0.02)
self.beta = beta
# 输出分类器
self.classifier = nn.Sequential(
nn.Linear(hidden_dim, hidden_dim),
nn.GELU(),
nn.Linear(hidden_dim, num_classes),
)
def forward(self, instances: torch.Tensor) -> torch.Tensor:
"""
参数:
instances: (B, K, d) K个实例的特征
返回:
logits: (B, num_classes)
"""
B, K, _ = instances.shape
# 编码所有实例
encoded = self.instance_encoder(instances) # (B, K, h)
# Hopfield池化:迭代检索原型
state = self.prototype.expand(B, -1, -1)
for _ in range(3):
scores = torch.einsum('bhd,bkd->bhk', state, encoded) * self.beta
attn = F.softmax(scores, dim=-1)
state = torch.einsum('bhk,bkd->bhd', attn, encoded)
pooled = state.squeeze(1) # (B, h)
# 分类
logits = self.classifier(pooled)
return logits9. 现代Hopfield的实践注意事项
9.1 温度参数的选择
温度影响:
- 大 → 检索更尖锐,倾向于单模式固定点,但可能错过相关模式
- 小 → 检索更平滑,更多模式被混合
经验选择:
- Transformer注意力:
- 联想记忆:(需要实验调优)
- 池化:
可学习:将作为可学习参数,让模型自动调节。
9.2 模式标准化
存储模式应该归一化(通常到单位范数或范数),以确保:
- 数值稳定性
- 模式分离条件更容易满足
- 的选择更一致
9.3 数值稳定性
log-sum-exp在数值上可能不稳定(极大/极小值),使用:
# 稳定的log-sum-exp
def logsumexp_stable(x, dim=-1):
max_x, _ = x.max(dim=dim, keepdim=True)
return max_x.squeeze(dim) + torch.log((x - max_x).exp().sum(dim=dim))PyTorch的torch.logsumexp已自动处理数值稳定性。
9.4 与其他架构的对比
| 架构 | 检索机制 | 复杂度 | 容量 |
|---|---|---|---|
| Hopfield (1982) | 局部异步更新 | ||
| Hopfield (Ramsauer 2020) | 全局softmax | ||
| Transformer Attention | 全局softmax | ||
| Linear Attention | 核近似 | 依赖核 | |
| Performer | FAVOR+ | 近似 |
10. 与其他深度学习主题的关联
10.1 与注意力机制
等价关系:现代Hopfield更新 = Transformer注意力(时)。
差异:
- Hopfield有显式的能量函数和Lyapunov保证
- Transformer有残差连接和层归一化
- Transformer堆叠多层(深度检索)
详细见 Hopfield与注意力的等价性。
10.2 与能量基模型
现代Hopfield网络是能量基模型(EBM)的特例,其中:
- 能量函数
- 通过CCCP迭代优化
- 状态空间的局部极小对应存储模式
详细见 能量基模型与深度学习。
10.3 与扩散模型
关键洞察(Pham et al. 2025):扩散模型的训练过程=在DAM中编码记忆,生成过程=检索记忆。
详细见 Hopfield最新进展。
10.4 与状态空间模型(SSM)
SSM可以被视为Hopfield记忆的线性版本(具体见Mamba文档)。两者结合形成MIRAS框架的统一理论。
11. 小结
核心要点
- 经典Hopfield(1982):二元神经元、Hebbian学习、容量
- 密集联想记忆(Krotov 2016, Demircigil 2017):多项式/指数能量,指数容量
- 现代Hopfield(Ramsauer 2020):连续状态、softmax更新、容量,等价于Transformer注意力
- CCCP优化:保证能量单调下降,收敛到不动点
- 三种角色:联想记忆、池化、注意力替代
- 2024 Nobel:Hopfield与Hinton因神经网络奠基性工作获诺贝尔物理学奖
学习路径
- 入门:经典Hopfield → 能量函数 → 模式检索
- 进阶:现代Hopfield → CCCP → 与Transformer等价
- 研究:稀疏Hopfield → 容量理论 → 最新进展
后续文档
- Hopfield与注意力的等价性 — 深入理论连接
- Hopfield存储容量理论 — 严格数学推导
- 稀疏与结构化Hopfield — 稀疏化扩展
- Hopfield最新进展 — 容量、Titans、MIRAS等
- Hopfield应用综述 — 表格、时序、医学等
脚注
Footnotes
-
McClelland, J. L. (2025). Profile of John Hopfield and Geoffrey Hinton: 2024 Nobel laureates in Physics. PNAS 122(15):e2423094122. ↩
-
Ramsauer, H. et al. (2020/2021). Hopfield Networks is All You Need. ICLR 2021. arXiv:2008.02217. ↩ ↩2
-
Krotov, D. & Hopfield, J. J. (2016). Dense associative memory for pattern recognition. NeurIPS 2016. arXiv:1606.01164. ↩