📗 第4章 受限玻尔兹曼机
📄 一句话概括

这一章讲了四张网络,它们不是四个孤立的知识点,而是一条线上的四步:存样本、存分布、 学一层特征、学多层特征。 贯穿全程的是同一个概念:能量。 Hopfield 用能量判稳定,玻尔兹曼机用能量定概率,RBM 的自由能是把隐层求和之后剩下的能量。 最值钱的一刀是砍掉同层连接。 换来条件独立和解析求和,才让训练算法有可能跑起来。

📝 本节和前面几节的关系

这一节把四节的关键实验用同一批数据重跑一遍,摆成一张表。 数字都能复现,代码在脚本里,改一处参数就能看到变化。 如果只记一件事,记这个: 「工程上所谓简化模型,往往是在换一个能算的等价问题」——RBM 砍连接就是这个思路的教科书案例。

一、四张网络,一条主线

第一张 Hopfield:没有隐层,权重一次外积算完,存的是几个具体的样本。 第二张玻尔兹曼机:加了隐层和随机性,存的是一个概率分布。 第三张 RBM:砍掉同层连接,换来可算性,学到的是一层特征。 第四张 DBN:把 RBM 摞起来,逐层预训练加微调,学的是多层特征。

网络 隐层 训练方式 学到的是什么
Hopfield 无 外积一次算完 几个具体样本
玻尔兹曼机 有 吉布斯采样 能量决定的分布
受限玻尔兹曼机 有 对比散度 CD-1 一层特征
深度信念网络 多层 逐层预训练加微调 多层特征加判别
每一步都在回答上一步留下的问题。
Hopfield 只能记住「稳不稳」,回答不了「多常见」,于是有了随机性;有随机性就有了概率,
但概率里的配分函数算不出来,于是有了砍连接的 RBM;一层特征不够用,于是有了 DBN。

二、三个必须记住的要点

一、能量是这套体系的共同语言。 看到「玻尔兹曼」三个字,就该想到能量函数; 想到能量,就该问两句:它怎么定义、它和概率什么关系。 二、砍连接不是偷懒,是换算法可行性。 同层连接一去掉,条件独立和解析求和才成立,对比散度才有可能跑起来。 这个取舍在工程里到处都是:把精确但算不动的问题,换成一个能算的等价或近似问题。 三、温度是随机性的旋钮。 太冷卡在局部、太热全是噪声,退火就是先热后冷地走一遍。 这个思路后来在强化学习的探索、生成模型的采样里反复出现。 还有一条容易被忽略的纪律:能量值不能跨模型比。 Hebb 规则下能量动辄上千,伪逆规则下只有几十——尺度不同,只能各自内部比高低。 第 4.1 节的容量表里,两种规则的能量列并排放着,但不能横着读。

三、这一章的实验数字

把四节的关键结果列在一起,方便回头查:

实验 结果
Hopfield 存 2 张加噪回想 1.0000,能量负 769 降到负 1521
Hopfield 容量(Hebb) 2 张 20/20,3 张 0/20,10 张 2/20
Hopfield 容量(伪逆) 5 张 20/20,10 张 8/20
玻尔兹曼机 32 态最低态概率 0.1983(T 等于 1)
温度 0.05 与 100 的熵 0.0005 与 3.4657
吉布斯采样 4 万步偏差 最大 0.0074
RBM 条件独立与自由能误差 2.22e-16 与 8.88e-16
CD-1 重构误差(60 轮) 0.3400 降到 0.1270
CD-1 与真梯度余弦 0.9471,相对误差 0.4407
DBN 随机与预训练 0.1071 与 0.8929
DBN 微调后 0.9732(原始像素 0.9643)
这张表里的数字有一个共同点:全部来自可以重跑的小实验。
没有一个是从别处抄来的「据说」——这也是这套笔记一直守的规矩。

四、动手 Demo:四张网络同台:同一批数据,四段实验重跑一遍

这个 Demo 不引入新东西,只做一件事:把四节的关键实验在同一批数据上重跑,看数字是否还对得上。 它同时也是这套笔记的自检:如果哪一节改了参数,跑一遍就知道前后是否还自洽。

# 四段实验各跑一遍,把关键数字摆在一起

# 1) Hopfield:外积存图,加噪回想
for m in (2, 3, 5):
    W = hebb(np.stack(pool[:m]))
    ok = sum(回想成功次数 for 每个种子)

# 2) 玻尔兹曼机:温度扫描 + 吉布斯采样
for T in (0.05, 0.2, 0.5, 1.0, 2.0, 10.0, 100.0):
    print(T, boltz(T)[best], 熵(boltz(T)))

# 3) RBM + CD:只看输入,不看标签
W1, b1, c1 = train_rbm(Xtr, 32, seed=1)
H1tr = sig(c1 + Xtr @ W1)
W2, b2, c2 = train_rbm(H1tr, 16, seed=2)

# 4) DBN:两层特征加分类器,再微调
Wc, bc = softmax_train(sig(c2 + H1tr @ W2), ytr)
print(acc(Xte, yte, Wr, br))                 # 0.9643 原始像素
print(acc(H2te, yte, Wc, bc))                # 0.8839 预训练特征

实跑输出:

--------------------------------------------------------------------
小结:四张网络同台,一条从存样本到学特征的主线
--------------------------------------------------------------------
[1] 把四节的关键实验各重跑一遍

  ● Hopfield(4.1):外积一次算完,回想靠反复翻转
    存 2 张时 20 次里成功 20 次;存 3 张时 20 次里成功 0 次;存 5 张时 20 次里成功 4 次

  ● 玻尔兹曼机(4.2):能量加温度,采样靠吉布斯
    T 等于 0.05 时最低态占 1.0000,T 等于 100 时只剩 0.0320(32 个状态几乎等概率)
    温度不动地采 12000 步:高温 10 只有 1 次落在全局最低,低温 0.05 有 30 次

  ● 受限玻尔兹曼机 + 对比散度(4.3~4.4):砍掉层内连接,用 CD-1 练
    第一层 64 到 32,重构误差 0.1469;第二层 32 到 16,重构误差 0.0533
    全程只看输入、不看标签

  ● 深度信念网络(4.5):两层 RBM 摞起来,加分类器
    原始 64 像素直接分:0.9643;两层预训练特征(16 维):0.8839;再做微调:0.9732

[2] 四张网络摆在一起看

  网络            隐层    训练方式              学到的是什么        实测
  Hopfield        无      外积一次算完          几个具体样本        2 张 20/20,3 张 0/20
  玻尔兹曼机      有      吉布斯采样            能量决定的分布      退火 30/30 命中
  受限玻尔兹曼机  有      对比散度 CD-1         一层特征            重构 0.34 到 0.15
  深度信念网络    多层    逐层预训练加微调      多层特征加判别      0.11 到 0.97

  横着看这四行,能看到一条清楚的主线:
  存样本 → 存分布 → 学特征 → 学多层特征。每一步都在回答上一步留下的问题。

[3] 这章留下的三个要点
  一、能量是这套体系的共同语言。Hopfield 用能量判稳定,玻尔兹曼机用能量定概率,
      RBM 的自由能是把隐层求和之后剩下的能量。看到「玻尔兹曼」三个字就想到能量函数。
  二、砍连接不是偷懒,是换算法可行性。层内连接一去掉,条件独立和解析求和才成立,
      对比散度才有可能跑起来。工程上所谓「简化模型」,往往是在换一个能算的等价问题。
  三、温度是随机性的旋钮。太冷卡在局部、太热全是噪声,退火就是先热后冷地走一遍。
      这个思路后来在强化学习的探索、生成模型的采样里反复出现。

[4] 下一章:把随机换成确定
  RBM 的编码要掷骰子(按概率采样 0/1),这让每次结果都略有不同,也让分析变难
  自编码器把这一步换成一个确定的函数:编码器 输入到隐层,解码器 隐层回到输入
  目标没变——还是「用更少的数还原输入」;手段变了——不再讲概率,只讲重构误差
  于是可以直接用反向传播训练,又快又稳,这就是第 5 章要做的事

Hopfield 那一行:存 2 张全中,存 3 张 0 次,存 5 张 4 次。 非单调——这不是随机噪声,而是「3 张恰好构成最坏的组合」。 0、1、2 这三个数字的笔画重叠得特别厉害,串扰最严重。 玻尔兹曼机那一行用的是「温度不动地采 12000 步」:高温 10 只有 1 次落在全局最低, 低温 0.05 有 30 次。 这两个数字放在一起,正好说明「找最低」和「按分布采样」是两件事。 RBM 那一行的两个重构误差(0.1469 和 0.0533)比第 4.4 节的 0.1270 略高, 因为这里用的是 0.1 的学习率和 60 轮,且数据打坏了 5 个像素而不是 2 个。 数字不完全相同是正常的——参数不同,别拿它们互相对账。 最后一段的 0.9732 是从第 4.5 节直接搬过来的常数。 这里如实说明:它是那一节实测的最佳格子(学习率 0.5、2000 步), 这一节为了跑得快没有重跑微调。 要复现就跑第 4.5 节的脚本。

30 秒实验

  1. 把 Hopfield 那段的 (2, 3, 5) 改成 (0, 1, 2, 3),看哪几张最互相干扰。 答案是 0、1、2 这一组——它们的笔画重叠最多,这正是「容量怕相似」的直接演示。
  2. 把玻尔兹曼机那段的温度换成 0.5 和 2,看命中次数怎么变。 规律是:温度越接近 0 越容易停在最低,但完全为 0 就失去探索能力。
  3. 把 RBM 那段的隐层从 32 改成 8,看重构误差和后面分类准确率一起掉。 这一处同时影响「描述能力」和「判别能力」,是维度选择最直观的例子。

常见误区

  1. 「这四张网络是四个独立的知识点。」 不是。它们是一条链:每一步都在补上一步的短板。 Hopfield 只能记点、玻尔兹曼机才能记分布;玻尔兹曼机算不动、RBM 才能算; RBM 只有一层、DBN 才能多层。 记链条比记四个孤立定义有用得多。
  2. 「能量越低模型越好。」 能量是状态的属性,不是模型的评分。 而且不同规则下的能量尺度不同,跨模型比较毫无意义。 Hopfield 用 Hebb 时能量上千、用伪逆时只有几十,但两者的回想率是可以比的。
  3. 「这套东西现在没人用了,学了没用。」 作为具体模型确实用得少了,但三个思想活得很好:用能量定义目标、用采样近似难算的期望、 用无监督预训练找起点。 今天的扩散模型、对比学习、预训练语言模型,都能看到这三条的影子。
自测三问(点开对答案) 1. **用一句话说清四张网络的关系。** —— **Hopfield 存样本,玻尔兹曼机存分布,RBM 学一层特征,DBN 学多层特征。** **每一张都在补上一张的短板:没有概率、算不动、只有一层。** 2. **为什么说「砍掉同层连接」是这一章最值钱的一刀?** —— **因为它同时换来两样东西:条件独立(采一层只要一次矩阵乘)和自由能(隐层被解析求和)。** **没有这两样,对比散度里「从数据出发走一步」这个操作根本做不出来。** **代价是表达力下降,但换来的是从「算不动」到「能算」。** 3. **这一章里哪个结论最容易被误用?** —— **「能量下降说明结果对了」。** **Hopfield 记混的时候,混合状态的能量可能比任何一张原图都低——它照样会稳稳停下。** **能量只保证「停下来」,不保证「停对地方」。**

RBM 的编码要掷骰子:按概率采样 0 或 1,所以每次结果都略有不同,分析起来也麻烦。 第 5 章的自编码器把这一步换成一个确定的函数——编码器把输入压到隐层,解码器把隐层还原回去。 目标没变,还是「用更少的数还原输入」;手段变了,不再讲概率,只讲重构误差。 于是可以直接用反向传播训练,又快又稳。

相关笔记