讲解式阅读笔记:Krotov & Hopfield, Dense Associative Memory for Pattern Recognition(以下简称 DAM)。
1. 这篇论文想解决什么问题?
经典 Hopfield 网络(1982)是一个能量下降的联想记忆(associative memory)模型:你给它一个“残缺/带噪的提示”,它会收敛到某个存储过的记忆模式,从而“补全”输入。
但经典 Hopfield 的痛点也很明确:
- 容量低:随机二值记忆的可可靠存储数 $K$ 只有 $O(N)$,典型常数级上限大约是 $0.14N$($N$ 是神经元数)。
- 混淆与伪吸引子(spurious states):当你存得太多,多个记忆对能量的贡献“同量级”,低能量谷会融合,系统会落入并非任何记忆的混合态。
论文的核心主张是:把 Hopfield 的能量从“二次相互作用(quadratic)”推广到“更高阶/更陡峭的相互作用”,就能显著提升容量,并把这类稠密联想记忆(Dense Associative Memory, DAM)与深度学习里的一类一隐层前馈网络建立一个非常直接的对偶(duality)。
论文特别强调:通过改变能量函数的“阶数/形状”,模型会在两种识别模式之间平滑切换:
- 特征匹配(feature-matching):更像“检测局部特征并组合”
- 原型(prototype):更像“与某个模板/原型做整体匹配”
1.1 记号说明(符号表)
为了避免“看见公式但不知道每个符号是什么意思”,这里把本文后续会用到的记号统一说明(基本都沿用论文/经典 Hopfield 记法):
- $N$:网络中的神经元(可见层单元)数量。
- $i,j$:神经元索引,$i,j\in\{1,\dots,N\}$。
- $\sigma_i$:第 $i$ 个神经元当前状态(经典 Hopfield 常取二值),典型取值 $\sigma_i\in\{+1,-1\}$。
- $\boldsymbol{\sigma}$:所有神经元状态组成的向量 $(\sigma_1,\dots,\sigma_N)$。
- $K$:存储的记忆(patterns / memories)数量。
- $\mu$:记忆索引,$\mu\in\{1,\dots,K\}$。
- $\xi_i^\mu$:第 $\mu$ 个记忆在第 $i$ 个维度上的分量(在经典设置里也常为二值 $\pm1$)。
你可以把 $\boldsymbol{\xi}^\mu=(\xi_1^\mu,\dots,\xi_N^\mu)$ 理解为“第 $\mu$ 条记忆向量”。 - $T_{ij}$:Hopfield 的权重(耦合)矩阵元素,决定神经元 $i$ 与 $j$ 的相互作用强度。经典 Hebb 形式为 $T_{ij}=\sum_{\mu=1}^K\xi_i^\mu\xi_j^\mu$(有时还会设 $T_{ii}=0$)。
- $E(\boldsymbol{\sigma})$:能量函数。网络动力学(异步更新等)会让 $E$ 单调不增,最终收敛到局部极小点(吸引子)。
- $m_\mu(\boldsymbol{\sigma})$:与第 $\mu$ 条记忆的重叠(overlap),表示当前状态与该记忆有多相似: $$ m_\mu(\boldsymbol{\sigma})=\sum_{i=1}^N \xi_i^\mu \sigma_i $$
- $F(\cdot)$:DAM 中对 overlap 做的“非线性奖励函数”(能量里对 $m_\mu$ 的作用形状)。不同 $F$ 对应不同模型/激活族。
- $[x]_+$:rectifier,表示 $[x]_+=\max(x,0)$。
- $\propto$:比例号。这里表示我们有意忽略一些对动力学/最小值位置不重要的常数因子或常数偏移(例如整体乘上常数、或加上与 $\boldsymbol{\sigma}$ 无关的常数)。
2. 先复习:标准 Hopfield 的形式与瓶颈
标准 Hopfield(以 $\sigma_i\in\{\pm1\}$ 为例)通常写成:
$$ E(\boldsymbol{\sigma})=-\frac{1}{2}\sum_{i,j}\sigma_i T_{ij}\sigma_j,\qquad T_{ij}=\sum_{\mu=1}^K \xi_i^\mu \xi_j^\mu $$
其中 $\xi^\mu$ 是第 $\mu$ 个记忆模式。更新规则会选择能保证能量不增(例如异步更新 + 符号阈值),从而最终收敛到某个局部极小点(吸引子)。
2.1 为什么 $E$ 等价于 $\sum_\mu m_\mu^2$?(逐步推导)
你问的这句:
“在标准 Hopfield 中,能量可以改写为与 $\sum_\mu m_\mu^2$ 相关……”
其实可以直接从定义代入得到一个很干净的等式(不仅仅是“相关”):
从能量定义出发:
$$ E(\boldsymbol{\sigma}) =-\frac{1}{2}\sum_{i,j}\sigma_i T_{ij}\sigma_j $$
把 $T_{ij}=\sum_{\mu=1}^K \xi_i^\mu \xi_j^\mu$ 代入:
$$ \begin{aligned} E(\boldsymbol{\sigma}) &=-\frac{1}{2}\sum_{i,j}\sigma_i\left(\sum_{\mu=1}^K \xi_i^\mu \xi_j^\mu\right)\sigma_j \\ &=-\frac{1}{2}\sum_{\mu=1}^K \sum_{i,j}\left(\xi_i^\mu\sigma_i\right)\left(\xi_j^\mu\sigma_j\right) \\ &=-\frac{1}{2}\sum_{\mu=1}^K \left(\sum_i \xi_i^\mu\sigma_i\right)\left(\sum_j \xi_j^\mu\sigma_j\right) \\ &=-\frac{1}{2}\sum_{\mu=1}^K \left(\sum_i \xi_i^\mu\sigma_i\right)^2 \\ &=-\frac{1}{2}\sum_{\mu=1}^K m_\mu(\boldsymbol{\sigma})^2 \end{aligned} $$
这就解释了“平方项从哪里来”:因为 $T_{ij}$ 本身是一个“按记忆求和的外积”,代入后自然出现 $(\sum_i\xi_i^\mu\sigma_i)^2$。
补充一个你可能会担心的细节:很多教材会额外规定 $T_{ii}=0$(去掉自连接)。如果不去掉,那么 $i=j$ 的项会贡献
$$ -\frac12\sum_{\mu}\sum_i (\xi_i^\mu)^2(\sigma_i)^2 $$
在二值 $\pm1$ 情况下 $(\xi_i^\mu)^2=(\sigma_i)^2=1$,这只是一个与 $\boldsymbol{\sigma}$ 无关的常数偏移,不影响“哪个状态更低能/动力学往哪收敛”。
为什么容量会卡在 $O(N)$ 且常数很小?直觉上:
- 每个记忆 $\xi^\mu$ 都在能量地形上挖一个“谷”。
- 当 $K$ 很大时,不止一个记忆会对当前状态产生同量级的“牵引”,这些牵引相互干扰,谷会变浅、互相连通,出现混合态/伪记忆。
DAM 的策略就是:让“正确记忆”的能量优势增长得更快,让干扰项相对变弱。
3. DAM:把能量做“更陡峭”,让赢家更容易“赢”
3.1 用“更高阶”改变能量地形
论文提出一族更一般的能量函数,核心思想是:把对“匹配程度”的奖励从线性/二次,改成更高阶(或近似更高阶)的函数。
一个关键量是当前状态与记忆 $\mu$ 的重叠(overlap):
$$ m_\mu(\boldsymbol{\sigma})=\sum_{i=1}^N \xi_i^\mu \sigma_i $$
在标准 Hopfield 中,能量可以改写为与 $\sum_\mu m_\mu^2$ 相关(因为二次相互作用导致平方项)。
DAM 的基本思路是让能量更像:
$$ E(\boldsymbol{\sigma})\ \propto\ -\sum_{\mu=1}^K F\!\left(m_\mu(\boldsymbol{\sigma})\right) $$
其中 $F(\cdot)$ 是增长更快、更“尖”的函数(例如幂函数 $x^n$、或只取正半轴的 rectified polynomial)。
3.1.1 你问的 (61-64) 到底“是什么”?怎么落到可计算的能量?
你说得对:$E=-\frac12\sum_{i,j}\sigma_iT_{ij}\sigma_j$ 形式直观;而 (61-64) 看起来像“抽象表述”。它的含义是:
- 先把“与每条记忆的相似度”统一写成 overlap:$m_\mu(\boldsymbol{\sigma})=\sum_i\xi_i^\mu\sigma_i$;
- 然后规定能量是“每条记忆的 overlap 经过同一个标量函数 $F$ 后求和”的负值: $$ E(\boldsymbol{\sigma}) = -\sum_{\mu=1}^K F(m_\mu(\boldsymbol{\sigma})) $$ 文中写 $\propto$ 是因为不同论文/实现会在右侧再乘上常数(例如 $1/2$、$1/N$、$1/n$),或者加上常数偏移;这些不会改变“谁是极小点/更新方向”,所以用比例号统一概括。
最关键的是:只要你给定一个具体的 $F$,(61-64) 就立刻变成一个可计算的显式能量函数。
举三个最重要的例子(把“抽象”变“具体”):
- 标准 Hopfield 就是一个特例:取 $$ F(x)=\frac12 x^2 $$ 那么 $$ E(\boldsymbol{\sigma})=-\sum_\mu \frac12 m_\mu(\boldsymbol{\sigma})^2 $$ 与上面第 2.1 节推导的 $E=-\frac12\sum_\mu m_\mu^2$ 完全一致。
- Power model(高阶/幂能量):取 $F(x)=x^n$(或带归一化的 $F(x)=\frac{1}{n}x^n$),能量就是 $$ E(\boldsymbol{\sigma}) = -\sum_\mu m_\mu(\boldsymbol{\sigma})^n $$ 这会把“最大的 overlap”放大得更厉害,更接近“赢家通吃/原型”。
- Rectified polynomial(ReLU 风格):取 $F(x)=[x]_+^n$,能量就是 $$ E(\boldsymbol{\sigma}) = -\sum_\mu [m_\mu(\boldsymbol{\sigma})]_+^n $$ 只有当与某条记忆正相关时才给奖励,更像“特征检测/稀疏激活”。
3.1.2 “怎么实现更新”?(从能量得到可执行的更新规则)
无论是标准 Hopfield 还是 (61-64) 的一般形式,实践里你需要的是:给定当前 $\boldsymbol{\sigma}$,怎么更新每个 $\sigma_i$ 让能量下降。
一个统一的做法是先写出“局部场”(local field):
$$ h_i(\boldsymbol{\sigma}) \;\triangleq\; -\frac{\partial E}{\partial \sigma_i} $$
对一般形式 $E(\boldsymbol{\sigma})=-\sum_\mu F(m_\mu(\boldsymbol{\sigma}))$,
$$ \begin{aligned} \frac{\partial E}{\partial \sigma_i} &= -\sum_\mu F'(m_\mu)\cdot \frac{\partial m_\mu}{\partial \sigma_i} \\ &= -\sum_\mu F'(m_\mu)\cdot \xi_i^\mu \end{aligned} $$
因此
$$ h_i(\boldsymbol{\sigma})=\sum_{\mu=1}^K \xi_i^\mu\, F'(m_\mu(\boldsymbol{\sigma})) $$
然后用异步更新(逐个 $i$ 更新):
$$ \sigma_i \leftarrow \operatorname{sign}\!\left(h_i(\boldsymbol{\sigma})\right) $$
这就回答了“(61-64) 如何实现”:实现时你只需要算出所有 $m_\mu$,再算 $F'(m_\mu)$,最后把它们按 $\xi_i^\mu$ 加权求和得到 $h_i$。
对不同 $F$,$F'$ 很简单:
- Hopfield:$F(x)=\frac12x^2 \Rightarrow F'(x)=x$,所以 $$ h_i=\sum_\mu \xi_i^\mu m_\mu $$ 这与 $h_i=\sum_j T_{ij}\sigma_j$ 等价(代入 $T_{ij}$ 可验证)。
- Power:$F(x)=x^n \Rightarrow F'(x)=n x^{n-1}$(常数 $n$ 可并入学习率/尺度)。
- Rectified:$F(x)=[x]_+^n \Rightarrow F'(x)=n[x]_+^{n-1}\cdot \mathbf{1}_{x>0}$。
直觉:如果某个记忆与当前状态的重叠略大于其他记忆,那么经过高阶变换后它的贡献会被“放大”,从而更容易在动力学上成为赢家,减少混合态。
3.1.3 你真正关心的“更新到底怎么做”?用“突触/神经元”语言说清楚
你提到“原始的是用生物的突触,现在呢?”——这里的关键是:
- 标准 Hopfield:显式有一张“可见层两两连接”的突触矩阵 $T_{ij}$(每个神经元对每个神经元)。
- DAM:把“高阶相互作用”换成“可见层 $\leftrightarrow$ 隐层”的突触 $\xi_i^\mu$ + 隐层非线性 $F'$,形成一个两段式回路。
也就是说:突触仍然是权重,只是从 $T_{ij}$ 变成了 $\xi_i^\mu$(可见↔隐层的连接)。
把一次更新拆成最直观的三步(每一步都是“突触加权求和 + 非线性”):
-
第 1 步:可见层 → 隐层(前向投票)
对每个隐单元/记忆索引 $\mu$,计算它收到的输入(就是 overlap): $$ m_\mu=\sum_{i=1}^N \xi_i^\mu \sigma_i $$ 这里 $\xi_i^\mu$ 就是“从可见神经元 $i$ 到隐单元 $\mu$ 的突触强度”。 -
第 2 步:隐层做非线性(决定谁的票更大)
把 $m_\mu$ 通过非线性变成隐层活动: $$ a_\mu = F'(m_\mu) $$ - 在 Hopfield 特例里 $F(x)=\frac12x^2$,所以 $a_\mu=m_\mu$(线性)。
-
在 DAM 里 $F$ 更尖(例如幂次、rectified 多项式),所以“更相似的记忆”会被更强放大。
-
第 3 步:隐层 → 可见层(反馈回写)
每个可见神经元 $i$ 收到来自所有隐单元的加权反馈,形成局部场: $$ h_i=\sum_{\mu=1}^K \xi_i^\mu\, a_\mu=\sum_{\mu=1}^K \xi_i^\mu F'(m_\mu) $$ 然后用阈值(符号函数)更新: $$ \sigma_i \leftarrow \operatorname{sign}(h_i) $$
如果你愿意把它“生物化”地想象:
隐层像一群“记忆细胞/特征细胞”,它们先读入当前模式(第 1 步),再根据相似度兴奋(第 2 步),最后把兴奋程度回写到可见层,推动可见层把不一致的位翻转成一致(第 3 步)。
一个最小手算例子:你会看到它真的在“算”并“翻转”
为了让计算尽量简单,我们取:
- $N=3$(3 个可见神经元)
- $K=2$(2 条记忆/2 个隐单元)
- 记忆向量(也就是突触 $\xi_i^\mu$): $$ \boldsymbol{\xi}^{1}=(+1,+1,+1),\qquad \boldsymbol{\xi}^{2}=(+1,-1,+1) $$
- 当前状态: $$ \boldsymbol{\sigma}=(+1,-1,-1) $$
- 选一个简单的 DAM 非线性:$F(x)=\frac14 x^4$(这样 $F'(x)=x^3$;系数不重要)
(1) 先算 overlap:
$$ \begin{aligned} m_1 &= (+1)(+1)+(+1)(-1)+(+1)(-1)= -1\\ m_2 &= (+1)(+1)+(-1)(-1)+(+1)(-1)= +1 \end{aligned} $$
(2) 隐层非线性:
$$ a_1=F'(m_1)=(-1)^3=-1,\qquad a_2=F'(m_2)=(+1)^3=+1 $$
(3) 回写得到局部场 $h_i$:
对每个 $i$,$h_i=\sum_\mu \xi_i^\mu a_\mu$:
$$ \begin{aligned} h_1 &= \xi_1^1 a_1 + \xi_1^2 a_2 = (+1)(-1)+(+1)(+1)=0\\ h_2 &= \xi_2^1 a_1 + \xi_2^2 a_2 = (+1)(-1)+(-1)(+1)=-2\\ h_3 &= \xi_3^1 a_1 + \xi_3^2 a_2 = (+1)(-1)+(+1)(+1)=0 \end{aligned} $$
然后阈值更新(遇到 $0$ 你可以规定“保持不变”以避免抖动):
- $\sigma_2 \leftarrow \operatorname{sign}(-2)=-1$(本来就是 -1,不变)
- $\sigma_1,\sigma_3$ 因为 $h=0$,保持不变
这个例子展示了一次更新的全部计算路径:$\sigma \to m_\mu \to a_\mu \to h_i \to \sigma$。
当你把 $F$ 换得更尖、把 $N,K$ 变大、并做多轮异步更新时,网络就会把 $\boldsymbol{\sigma}$ 推向某个稳定吸引子(记忆/原型/或其组合,取决于容量与参数)。
实现伪代码(对应上面的三步)
repeat until convergence:
# 1) visible -> hidden
for mu in 1..K:
m[mu] = sum_i xi[i,mu] * sigma[i]
# 2) hidden nonlinearity
for mu in 1..K:
a[mu] = F_prime(m[mu])
# 3) hidden -> visible and update (async or sync)
for i in 1..N: # async: pick one i each time
h = sum_mu xi[i,mu] * a[mu]
sigma[i] = sign(h) # define sign(0) as "keep old"
备注:标准 Hopfield 也可以写成完全相同的“三步”结构,只是它的 $F'(x)=x$ 是线性的,所以隐层不“放大赢家”;而 DAM 的关键就在于用更陡的 $F'$ 改造了这个放大机制。
3.2 两类常见选择:幂函数 vs. 纠正多项式(rectified polynomial)
论文重点比较两类:
- Power energy / power model:$F(x)=x^n$(或与其等价的形式)
- Rectified polynomial:$F(x)=[x]_+^n$,其中 $[x]_+=\max(x,0)$
rectified 版本的意义很像 ReLU:只在“匹配到位”(正半轴)时给奖励,在“反相关/不匹配”时不给奖励或较弱,从而更接近分类/特征检测的直觉。
4. 最重要的桥梁:DAM $\leftrightarrow$ 一隐层前馈网络
论文最漂亮的点是这个对偶:把每个记忆 $\xi^\mu$ 看成一隐层网络中的一个“隐单元权重向量”,然后:
- 输入层:$\sigma_i$(或把图像像素 + label 拼在一起形成可记忆向量)
- 隐层第 $\mu$ 个单元的预激活: $$ u_\mu=\sum_i \xi_i^\mu \sigma_i $$ 这就是 overlap $m_\mu$(差一个缩放)。
- 隐层激活:取决于你选的能量函数 $F$ 的导数/相关形式;因此 logistic / ReLU / 更高阶 rectified polynomial 都可以落在同一个族里。
从能量视角看,更新 $\sigma$ 的动力学等价于做“能量下降”;从前馈网络视角看,隐层在做“特征响应”,输出(或回写到可见层)在被这些响应驱动去修正输入。
一句话总结:DAM 像是把“存储的记忆”当作隐层字典,通过非线性把“最相似的记忆/特征”放大,再把可见层推回到一致的记忆吸引子。
5. “特征匹配”与“原型”两种识别模式
论文强调:调节 $F$ 的形状(尤其是阶数 $n$ 或 rectification 的方式)会改变网络的工作方式。
5.1 特征匹配(feature-matching)
当非线性更“像 ReLU/分段”,并且阶数不至于让单一赢家极端主导时:
- 多个隐单元可以同时有中等激活
- 可见层更新更像在叠加多个“局部证据”
- 对应深度学习里熟悉的“特征检测器 + 组合”
5.2 原型(prototype)
当 $F$ 非常尖(例如较大的 $n$),系统趋向于“赢家通吃”:
- 只有与输入最相似的那一个(或极少数)记忆贡献显著
- 更新更像把输入直接拉向某个模板
- 行为上更像最近邻/模板匹配,但用能量下降来实现“鲁棒补全”
对联想记忆而言,这通常是好事:你希望最终收敛到一个具体记忆,而不是一堆记忆的混合。
6. 容量(capacity):为什么能超过 $N$?
经典 Hopfield 的容量是 $O(N)$ 且常数小。DAM 通过更陡峭的能量形状,显著提升“无错回忆(no-error recall)”的可存储数量。
非常粗的直觉是:
- 干扰项来自很多无关记忆的随机重叠,它们的统计波动增长较慢(类似中心极限定律的尺度)。
- 正确信号项(目标记忆)经过高阶/rectified 变换后增长更快。
- 因此可以允许 $K$ 随 $N$ 以更快的速度增长(对某些 $n$,可以远大于 $N$)。
论文还在附录里用数值实验验证 power 与 rectified polynomial 的容量行为非常接近,并给出一个直观现象:当阶数提高到某个程度后,overlap 的分布会从“分散、回忆失败”为主,转变为“在完美恢复处尖锐集中”。
你可以把这理解成:$n$ 越大,系统越不容易被“很多小干扰”合起来误导。
7. 训练与实现:怎么“学”出这些记忆/权重?
论文既讨论“存储给定记忆”的联想记忆视角,也讨论“用于模式识别”的学习视角。一个典型做法是:
- 把输入(例如图像像素)和标签拼成一个更长的向量当作“记忆”
- 训练/存储后,推理时把标签部分留空或置为未知,通过能量下降让系统补全标签
在神经网络对偶下,对应于训练一个一隐层网络,只不过隐层激活可能是高阶 rectified polynomial 之类的“非主流激活”。论文的一个实用贡献是:给出了这种激活族下可用于 mini-batch 的梯度表达式,工程实现上与 ReLU 网络很接近,只是把线性变成幂次形式(并保持 rectification)。
8. 两个演示任务:XOR 与 MNIST
8.1 XOR:展示“能量 + 非线性”如何表达非线性可分
XOR 的意义在于:单层线性模型做不到,必须要非线性/隐层。
DAM 通过合适的能量/激活选择,可以形成对 XOR 的正确分类边界,直观对应:
- 隐层记忆向量起到“特征探测器”的作用
- 能量下降把输入推向满足约束的吸引子
8.2 MNIST:展示容量与识别行为在真实数据上的变化
在 MNIST 上,论文用 DAM 框架做手写数字识别(例如把像素与标签拼接为记忆,或用隐层作为字典),重点不是刷新 SOTA,而是展示:
- 激活/能量形状改变时,“特征匹配 vs 原型”模式会改变
- 高阶 rectified polynomial 激活是可行的,并且能用能量直觉理解其行为
你可以把它看作一种“能量模型视角下的一隐层网络”,在训练与推理上都更容易用物理直觉解释。
9. 这篇论文带来的思维方式(建议你抓住的 3 个点)
9.1 把“激活函数”当作“能量形状”的影子
在这套对偶里,激活函数不是随便拍脑袋选的;它对应着能量函数对重叠的奖励形状。选 ReLU、选更高阶 rectified polynomial,本质上是在选“谁能赢、怎么赢、赢得多彻底”。
9.2 更高阶 ≠ 只是更强非线性,而是更强的“赢家放大器”
提高阶数 $n$ 的作用可以理解为:把“最相似的记忆”从众多相近候选里更坚决地分离出来,从而提升回忆容量并降低混合态概率。
9.3 特征 vs 原型不是二选一,而是一条连续谱
通过调节 $n$ 或是否 rectified,你能在“许多特征共同解释输入”和“一个原型统治解释”之间平滑移动。这对理解模型在不同数据分布下的偏好非常有用:有的数据更适合模板式,有的更适合特征组合式。
10. 建议的复现/练习路线(如果你想把它吃透)
- 最小复现(XOR):实现一个“记忆向量 = 隐层权重”的一隐层网络,分别用 ReLU 与 $[x]_+^n$ 做激活,观察决策边界如何变化。
- 联想记忆实验:随机生成二值记忆,固定 $N$,逐步提高 $K$ 与 $n$,统计收敛到真记忆的比例(用 overlap 直方图衡量)。
- MNIST 小实验:把“像素 + one-hot 标签”拼向量,用能量下降补全标签,观察不同 $n$ 下是更像“原型拉回”还是“特征组合”。
11. 一句话总结
DAM 用更高阶(或 rectified)的能量奖励函数显著提升联想记忆容量,并与一隐层网络的激活函数族形成对偶:调节能量形状等价于调节激活,从而在“特征匹配”与“原型匹配”之间连续切换。