跳到主要内容

价值这条线 — DQN 的两个补丁与后来的六个

这一章讲三件事: 把表直接换成网络会怎样;两个补丁各治什么病、有多要命; 以及后来那六个补丁各补的是哪个洞。

它在全书链条里的位置:第一次真的跑起来。 第 06 章诊断出「三样凑齐会发散」,这一章是第一张药方而这一章末尾你会发现:这条线天生接不了连续动作 —— 那就是第 08 章的起点。

顶层全景:Breakout 的一帧,走到一次参数更新

这一章从头到尾跟着一条链:雅达利打砖块游戏(Breakout)的一帧画面,一路走到网络里某个参数被改了一下。

① 游戏原始画面 210×160,彩色
② 同一个动作重复 4 帧,并把相邻两帧逐点取最大 ← 第 10 节:降噪与提速
③ 转成 84×84 的灰度图 ← 第 10 节
④ 把最近 4 张这样的图叠起来 = 一个「局面」 ← 第 10 节(补第 01 章那个「单帧看不出球速」)
⑤ 网络吃进去,吐出每个动作的分数(4 个动作各一个) ← 第 05 章那套卷积
⑥ 大多数时候挑分最高的,偶尔随便挑一个 ← ε-贪心(第 02 章)
⑦ 把这条经验(局面、动作、拿到的分、下一个局面)写进一个大池子 ← 第 2 节:回放缓存
⑧ 从池子里随机抽一小批(比如 32 条) ← 第 2 节
⑨ 用**另一个隔一阵才同步的网络**算出目标值 ← 第 3 节:目标网络
⑩ 目标值减去当前估计,算出损失,反向传播,改参数 ← 第 10 节:Huber 损失

图说:这就是本章的主走查。
第 4 节把消融的四个数挂在「拆掉 ⑦ 或 ⑨ 会怎样」上;
第 5 到第 9 节的六个补丁,每一个都只改这条链上的某一段,我们会逐个定位。
(画面尺寸、4 帧、84×84、四个消融数字都是书里的;
抽样批次里的具体数值是**为演示编的**。)

1. 直接换,不收敛

这一节回答:为什么不是「把 Q 表换成网络」这么简单?

先看现象

第 04 章的 Q-Learning 在小问题上跑得很好。把那张表换成一个神经网络,它就不动了 —— 甚至越跑越离谱。

书里说得很直接:用神经网络这类非线性函数来逼近 Q 值时,强化学习是不稳定的、甚至会发散1

为什么

第 06 章已经把病因写全了,这里只回指:

第 06 章哪一节
连着采的样本几乎一模一样,不满足「彼此独立」第 2 节
目标值自己也在动(策略一变,数据分布就变)第 2 节
函数逼近 + 自举 + 学别人走过的路,三样凑齐可以发散第 3 节

而 Q-Learning 恰好把三样全占了: 它用网络(函数逼近)、它的目标里有下一个局面的估计(自举)、 它的目标取最大而实际行动带 ε 随机(学的不是自己现在走的路)。

DQN 的贡献,就是两个把它按住的补丁

书里的说法是:DQN 通过两个关键技术把 Q-Learning 和深度学习结合起来, 解决了不稳定性问题,并在雅达利游戏上取得了显著进展2

★ 注意这里的措辞:是「解决不稳定性」,不是「证明它会收敛」。★ 这两个补丁没有任何收敛证明 —— 它们是工程上把病按住的手段。 全书那条「打补丁史」的主线,从这里正式开始。

2. 补丁一:把经验存下来,再随机抽

这一节走主走查的 ⑦⑧ 步。

先看现象

按最朴素的写法,智能体每走一步就拿这一步的经验去更新一次网络。

问题是:连着的四帧几乎一模一样。 你等于连着四次拿同一张图去训练, 而且用完就扔 —— 打了几百万帧,每一帧只被看了一眼。

做法:先存进池子,再随机抽

书里的做法:每一步先把这条经验(当前局面、动作、拿到的分、下一个局面)存进一个池子, 再从池子里均匀随机地抽一小批出来做更新3

这个池子书里叫回放缓存**(缓存就是一块临时存东西的地方,存满了就把最老的挤出去)。**

书里还说明了这个点子的来历:它是一种被称为「经验重演」的生物学启发机制3

它一次治了三个毛病

书里把好处列了三条,而它们正好对应三个不同的病3:

好处治的是什么
每一步的经验可以重复使用来学 Q 函数数据用得太浪费 —— 一帧只看一眼太亏
不这么做的话,一个批次里的样本是连续采集的、高度相关,这会增加更新的方差样本不独立(第 06 章第 2 节那条)
防止用于训练的样本只来自上一个策略,能平滑学习过程、减少参数的震荡或发散分布一直在动(同上)

工程上还有一条:书里说为了省内存,往往只保留最近的 N 条经验,新的进来就把最老的挤出去3

走查 ⑦⑧ 步

⑦ 这一步产生的经验写进池子:
(最近 4 帧叠成的局面, 动作「右」, 这一步得分 0, 下一帧叠成的新局面)
池子里现在有 100 万条,最老的那条被挤掉

⑧ 从这 100 万条里随机抽 32 条 —— **它们可能来自几十万步之前的几十局不同的游戏**
★ 这 32 条彼此几乎没有关系,而这正是要的效果。★

(100 万与 32 这两个数是**为演示编的**;做法是书里的。)

★ 这里有一个后面会反复用到的结论:回放缓存只对离线策略的算法可用。★ 因为池子里存的是旧策略走出来的路。第 04 章那个 max 让 Q-Learning 成为离线策略的 —— 所以它能用这个补丁,而第 08 章那条线不能。这是第 10 章要合流的原因之一。

3. 补丁二:给目标钉一个不动的靶子

这一节走主走查的 ⑨ 步,而这个补丁的道理最漂亮。

先看现象

更新时,目标值是「这一步的分 + 折扣 × 下一个局面的最大 Q 值」。 而下一个局面的 Q 值,是用同一个网络算的。

于是:你改这个网络去逼近一个目标,而这个目标本身就由这个网络算出来 —— 你一改它就跟着动。

书里那个具体的例子

书里给了一条很具体的因果链,值得原样走一遍4:

你在 (这个局面, 这个动作) 上做了一次更新,使它的 Q 值增加
↓ 而这个局面和下一个局面长得很像(相邻两帧嘛)
↓ 网络会牵连(第 06 章第 1 节那条)
⟹ 下一个局面所有动作的 Q 值也跟着增加
↓ 而目标值里正有「下一个局面的最大 Q 值」
⟹ ★ 目标值被推高了 —— 你刚才那次更新,把自己的目标也抬高了。★

书里的原话是:这会使得由 Q 网络产生的训练目标值被**过估计**;
而如果使用目标网络产生训练目标,就能避免这个问题。[^4]

做法:再养一个网络,隔一阵才同步

做法很简单:另开一个结构一模一样的网络,专门用来算目标值。 它的参数不跟着每一步更新,而是每 C 步才和主网络同步一次4

书里给了两种同步方式4:

方式做法
硬更新每 C 步,把主网络的参数整个复制过去
软更新每一步都朝主网络挪一点点(指数衰减平均)

为什么有效? 书里的说法是:目标网络用的是旧参数,所以目标值的产生不受最新参数的影响, 从而大大减少发散和震荡4

用一句话说:靶子在你射击的这段时间里是钉住的。

走查 ⑨ 步

抽出来的 32 条里,拿第 1 条:(局面, 动作「右」, 得分 0, 新局面)

用**目标网络**看新局面,它给四个动作打分:0.12 / 0.35 / 0.08 / 0.21
取最大 → 0.35
目标值 = 0 + 0.99 × 0.35 = **0.3465**

用**主网络**看当前局面、当前动作「右」,它现在的估计是 0.50
差 = 0.3465 − 0.50 = **−0.1535** ← 主网络这一格该往下调

★ 关键:那四个 0.12 / 0.35 / 0.08 / 0.21,在接下来的 C 步里不会变。★
(这几个数是**为演示编的**;做法是书里的。)

4. 这两个补丁有多要命:四个数

这一节是全章的证据,而它是一次消融实验 —— 把零件一个个拆掉,看成绩掉多少。

书里给了五个游戏的表,我们只看第一行(Breakout)5:

两个都用只用回放缓存只用目标网络都不用
316.8240.710.23.2

先说这些数怎么来的:书里写明了实验口径 —— 训练 1000 万步,每 25 万步评估一次, 每次评估 13.5 万帧,记录最高的片段平均分5

★ 这张表要横着读,一行三个对照:★

两个都用 316.8
拿掉目标网络 240.7 ← 掉 24%,伤但没死
拿掉回放缓存 10.2 ← ★ 掉到 3% ★ —— 掉了一个半数量级
两个都拿掉 3.2 ← 掉到 1%

图说:参照物就是同一行的其他三个数。
★ 这不是「调参能补回来」的差距,是「跑得起来」和「跑不起来」的差距。★

这张表还给了一个反直觉的次序:在 Breakout 上,回放缓存比目标网络重要得多。 拿掉目标网络还剩 240.7,拿掉回放缓存只剩 10.2 —— 相差 23 倍。

但这个次序不是铁律,书里那五行自己就打了一次架。 Enduro(831.4 对 141.9)、River Raid(4102.8 对 2867.7)、Space Invaders(826.3 对 373.2) 都和 Breakout 同序:只留回放缓存的那一格高。 唯独 Seaquest 反过来 —— 只留回放缓存 822.6,只留目标网络 1003.05

所以准确的说法是「五个游戏里四个如此」,不是「一律如此」。 五行里真正一致的只有另一件事:两个都用的那一格永远最高,两个都不用的那一格永远最低。

判断(我们的,不是书里的): 我们把这一节单列出来,是因为这四个数是全书最有说服力的一处证据: 它不是「某个改进带来了 5% 的提升」,而是**「缺一个零件,整件事根本不成立」**。 后面十三章会出现大量「某某算法比某某算法好」的比较, 它们的说服力都远不如这四个数 —— 因为它们比的是名次,而这四个数比的是能不能跑。 如果错,会错在: 我们拿 Breakout 那一行当了典型,而它恰恰是五行里落差最大的一行。 同一张表里就有现成的反例:Seaquest 上只留回放缓存(822.6)反而不如只留目标网络(1003.0)。 也就是说,「哪个零件更要命」在同一份实验里就已经翻过一次; 五行里立得住的只有「两个都用最高、两个都不用最低」。 判据是:换一类任务(比如连续控制),次序会不会像 Seaquest 那样再翻一次。

5. 补丁三:对一堆带噪的数取最大,结果会系统性偏高

这一节讲六个补丁里的第一个,它治的是第 06 章点过的那个副作用。

先看现象

Q-Learning 的目标里有一个「取最大」。而每个 Q 值都带噪 —— 环境有随机、函数逼近有误差。

书里给了那句关键的不等式:一堆带噪的数「取最大之后再求平均」, 不会小于「先各自求平均再取最大」6

说人话:

三个动作的真实价值都是 0。但你的估计带噪:
这一次估出来 +0.3 / −0.2 / −0.1 → 取最大得 **+0.3**
下一次估出来 −0.4 / +0.5 / −0.2 → 取最大得 **+0.5**
再下一次 −0.1 / −0.3 / +0.2 → 取最大得 **+0.2**
────────────────────────────────────────────────
三次取最大的平均 = +0.33,而真值是 **0**

★ 取最大这个动作,专挑那些「这次运气好、估高了」的。★
**噪声本身没有偏,而「取最大」把它变成了系统性偏高。**
(这几个数是**为演示编的**;那句不等式是书里的。)

这个毛病书里叫过估计,并说文献里有进一步的理论分析和实验结果6

病根在哪:一个网络干了两件事

书里把标准 DQN 的目标式子重写了一遍,然后点出问题: 同一套参数既用来估 Q 值,又用来选下一个动作7

「选谁」和「它值多少」由同一个带噪的估计说了算 —— 于是选出来的必然是被高估的那个。

做法:让两个网络分工

Double DQN 的核心思想:这两件事用两个不同的网络做,以去除选择和评价中噪声的相关性7

而 DQN 本来就有两个网络 —— 书里说这是「一个很自然能想到的选择」7:

谁来**选**动作? → 主网络
谁来**评**这个动作值多少? → 目标网络

★ 主网络选出来的那个「它以为最好」的动作,交给目标网络去打分。★
如果主网络是被噪声骗了,目标网络多半不会跟着骗——两边的噪声不相关。

在主走查上的位置:只改第 ⑨ 步里「取最大」那一下,别的一个字不动。

6. 补丁四:有些局面,做什么都一样

这一节讲第二个补丁,它改的是网络的结构。

先看现象:书里那个例子很好

书里说:假想我们在山上看日出,美丽的景色令人陶醉,这是一个很高的奖励。 此时你即使在这里继续做不同的动作,也不会对 Q 值产生影响8

换句话说:这个局面本身值多少,和你此刻做什么,是两件事。 可标准的网络把它们混在一个数里学,每个动作都要单独学一遍「这个局面值多少」。

做法:把 Q 拆成两半

书里的拆法:一个局面-动作的价值 = 这个局面本身值多少 + 这个动作比平均好多少9

后面那一项书里叫优势 —— 它就是第 08 章要用一整节讲的那个量,这里先见一面。

网络的结构改成两个头:
一个头输出「这个局面值多少」 —— 只有一个数
另一个头输出「每个动作比平均好多少」—— 每个动作一个数
两个加起来,才是每个动作的 Q 值

图说:书里说这样做「可以获得更加鲁棒的学习效果」,
因为**动作无关的那部分只需要学一次,不必在每个动作上重复学**。[^8]

一个必须处理的技术细节

光这么加会出问题:同一个 Q 值有无数种拆法(前一项加 5、后一项各减 5,结果一样)。

书里的处理:给后面那一项做一次归一化 —— 减去它自己的最大值, 书里说这确保了 Q 值能唯一地对应到两部分;否则训练会忽略状态值项9而书里又说,后来提出用减去平均值代替减去最大值,可以获得更好的稳定性9

书里的结论:训练这个结构和训练标准 DQN 一样,只是多了几层; 实验表明它「在许多价值相似的动作中,能获得更好的策略评估效果」9

在主走查上的位置:只改第 ⑤ 步网络的输出结构,别的不动。

7. 补丁五:经验不该一视同仁

这一节讲第三个补丁,它改的是从池子里怎么抽。

先看现象

第 2 节那个池子是均匀随机抽的 —— 每条经验被抽中的机会一样大。

可有些经验明显更值得学:那些「网络算得离谱」的。

做法:按「差多少」定优先级

书里的核心思想:用时间差分误差(目标值和当前估计之间的差)来衡量不同经验的重要性10; 书里还给了一句很到位的形容:这个误差是「一个令人惊喜的衡量标准」10 —— 差得越多,说明这条经验里有越多你还没学会的东西。

但直接按误差排序不行,书里给了三条理由

书里列的三个问题10:

问题说明
扫描整个回放缓存空间非常低效一百万条经验,每次都排一遍序?
对近似误差和随机回报的噪声十分敏感某条经验碰巧误差大,不代表它真的重要
这种贪心的方法会使误差收敛缓慢刚开始训练时误差高的那些经验,会被反复回放,其余的永远轮不上

做法是改成按概率抽:优先级高的机会大,但别的也有机会。 书里给了这个概率的算法,其中一个指数参数控制「偏心到什么程度」—— 这个参数取 0 就退回均匀采样10

优先级本身书里给了两种算法10:

  • 按比例: 直接用误差的绝对值,再加一个很小的正数防止它变成 0;
  • 按名次: 用「它在所有经验里排第几」的倒数。

偏心了就得纠偏

书里点破了一处矛盾:回放缓存之所以有用,正是因为随机采样能消除样本之间的相关性; 而优先采样又放弃了纯随机11

所以要配一个纠偏的系数:被抽得多的那些,训练时的分量要相应调小。11

这个纠偏的做法有一个正式的名字:重要性采样。 它这里只是就地用一下;它的完整讲法(为什么这个系数长这样、它跟「拿旧数据估新东西」有什么关系) 留到第 09 章第 4 节。

书里还给了一个工程口径:那个纠偏系数的强度是一个超参数, 它在训练过程中会逐渐加满到 1 —— 理由是「随着训练增加,更新会趋近于无偏」11

在主走查上的位置:只改第 ⑧ 步「怎么抽」,别的不动。

8. 补丁六:把随机放进参数里

这一节讲第四个补丁,它治的是探索。

先看现象

第 ⑥ 步的 ε-贪心是这样的:大多数时候挑分最高的,有 ε 的机会完全随机挑一个。

第 02 章第 4 节说过它的毛病:它把所有非最优动作一视同仁。 在雅达利上还有更狠的问题:随机挑单步动作,几乎不可能凑出「连贯的几十步」。

书里点名了一个游戏:《蒙特祖玛的复仇》—— 这类需要大量探索的游戏12(为什么它这么难,第 11 章会给出具体的数:一个房间要几十个连贯动作,全游戏 23 个房间。)

做法:把噪声加到网络的参数上,而且让噪声的大小自己学

做法是给网络的一层加一条额外的「噪声流」12

关键在于:噪声的幅度本身是可以被学出来的参数。

ε-贪心: 探索的幅度由你手动设一个 ε,而且对所有局面一视同仁
噪声网络: ★ 每个参数上掺多少噪声,由训练自己决定 ★
→ 学到后期,该确定的地方噪声自动收小,该探索的地方还留着

图说:书里说实验表明,它相比许多基线算法,让众多雅达利游戏的得分有了大幅提升。[^12]

在主走查上的位置:只改第 ⑥ 步「怎么选动作」,别的不动。

9. 补丁七:别只估一个平均值,估整条分布 —— 以及 Rainbow

这一节讲最后两个补丁,并把六个合起来。

补丁:多步

书里的第一个扩展是多步学习13:目标值不只用一步的分数, 而是用接下来若干步的实际分数,再接上第 n 步的估计

这就是第 04 章第 7 节那根轴上往蒙特卡罗那头挪了几格。 挪过去偏差小了、方差大了。

书里在这里很坦率地留了一处麻烦: 多步的目标和实际执行的策略之间会有错配 (你用的是旧策略走出来的那几步),书里说有系统性的研究方法可以纠正这类问题, 但 Rainbow 直接使用了不加修正的多步回报13这是一处「知道有问题、但就这么用了」的坦白。

补丁:估整条分布,而不是一个平均值

先看现象。 Q 值是一个平均值:「从这里出发,平均能拿多少」。 可「平均 5 分」可能是「每次都 5 分」,也可能是「一半 0 分、一半 10 分」——这两件事很不一样。

书里的做法:为值估计提供一个新的视角 —— 估计整条回报分布14

具体怎么估?书里给的第一种做法是把分布切成一串离散的点(书里叫「原子」), 在一个事先定好的范围里均匀排开,网络输出每个点上的机会14

★ 书里给了那个数:实践中这些点通常取 51 个,所以这个算法有时也被叫作 C51。★14

这里有一处必须处理的技术麻烦: 更新之后的分布会「错位」到那串固定的点之外, 所以要把它投影回去;而且时间差分误差本身没法衡量两条分布之间的差别, 所以损失换成了别的东西15

书里也给了它的主要缺点:它只能在一个固定的离散集合上估计值。 后来的另一种做法反过来 —— 固定「机会」的刻度,让位置可以动(书里叫分位数回归)16

Rainbow = 六件合体

书里说得很清楚:Rainbow 在 Double、Dueling 结构和优先经验回放之外, 还包含另外三个扩展 —— 多步学习、噪声网络、值分布13

把这六件挂回主走查那条链上,每一件只动一段:

补丁改的是主走查的哪一步治什么
Double⑨ 里「取最大」那一下估出来的值系统性偏高
Dueling⑤ 网络的输出结构动作无关的那部分被重复学了很多遍
优先经验回放⑧ 怎么从池子里抽有信息量的经验被埋没
多步⑨ 目标值用几步分数往回传得太慢
噪声网络⑥ 怎么选动作探索太笨
值分布⑤ 网络输出什么 + ⑩ 用什么损失只估平均值丢掉了分布的信息

★ 看这张表最右边一列:六个补丁,六个不同的病。这就是「打补丁史」的具体样子。★

10. 让它真的跑起来:预处理每一层在补什么

这一节走主走查的 ②③④ 和 ⑩ 步,而这些细节论文正文里往往一笔带过。

书里列了八个「装饰器」,它们一层层套在环境外面。我们逐个说明它在补什么17:

装饰器做什么补的是什么
重置游戏时随机走几步空动作(默认最多 30 步)每局开头都一样,智能体会背下开局。随机化起点,让初始局面更多样
每个动作重复 4 帧;返回的画面是相邻 2 帧逐点取最大重复 4 帧是省计算;取最大是降噪(雅达利有些物体隔帧才画)
记录原始的分数因为下面会改奖励,评估时要用没被改过的分
一条命结束就当一个片段结束不必等所有命耗完 —— 书里说这对价值估计很有帮助
重置时先按一下开火键很多游戏要按开火才开始。这是塞进去的先验知识
转成 84×84 的灰度图省计算(彩色 210×160 变灰度 84×84)
奖励只取符号,变成 −1 / 0 / +1防止某一个批次的更新大幅改变参数,提高稳定性
堆叠最近 4 帧★ 补第 01 章那个「单帧看不出球速」★ —— 和上一条一起实现了「一个局面」的定义

书里还提了一个省内存的实现技巧:相邻两个局面之间有三帧是公用的,只存一份17

最后一步:损失为什么不用均方误差

书里的理由是防止梯度爆炸:DQN 对平方误差做了裁剪, 这等同于把均方误差换成了 Huber 损失18

它的形状是:

差得小的时候(绝对值 ≤ 1):照旧用平方
差得大的时候: 改成正比于绝对值(不再平方)

★ 为什么:平方在差很大时会给出一个极大的梯度,一步就把参数推飞。★
改成正比之后,再离谱的一条样本,它能推动的幅度也有上限。
(这个「1」是书里给的取法;形状是书里的。)

书里还给了两个工程口径:ε 在前 10% 的训练步里从 1.0 线性降到 0.0119; 而 Breakout 那个实验跑了 1000 万步(相当于 4000 万帧)、用了 3 个随机种子20「3 个随机种子」这件事到第 11 章会变成一条很刺眼的实测结论 —— 那里会说 5 个可能都不够。

作者的判断与证据

书里给了实验数据或推导的:

  • 消融实验的四个数(316.8 / 240.7 / 10.2 / 3.2),而且给了完整的实验口径5;
  • 过估计的那句不等式(一堆带噪的数取最大之后求平均,不小于先求平均再取最大), 书里还指了一篇 1993 年的理论分析文献6;
  • 目标网络为什么有效的因果链(更新推高相邻局面 → 目标被推高)4;
  • Dueling 结构里那个归一化为什么必须有(否则训练会忽略状态值项)9;
  • 优先经验回放不能直接按误差排序的三条理由10

作者的判断或未解决的问题:

  • 「解决不稳定性问题」这个说法2 —— 没有任何收敛证明。 这两个补丁是工程手段,第 11 章会回来说「药也没治好」;
  • 多步学习和实际策略之间的错配,书里承认有问题、指了一个纠正方法, 但明说 Rainbow 直接用了不加修正的版本13;
  • Dueling 用「减平均」代替「减最大」,书里说是为了「更好的稳定性」,没有给对照实验9;
  • 优先经验回放里那个纠偏系数为什么要退火到 1,书里给的理由是 「随着训练增加,更新会趋近于无偏」11 —— 这是一句解释,不是一个证明。

判断(我们的,不是书里的): 这一章的六个补丁里,只有前两个(回放缓存与目标网络) 有「不加就跑不起来」级别的证据;后面六个全部是「加了更好一点」。 两者的证据强度差了一个数量级,而书里是并排讲的。 读这一章要有意识地把它们分开:前两个是地基,后六个是装修。 如果错,会错在: 如果在某类任务上某个「装修」也成了地基 (比如极难探索的游戏上,噪声网络可能是必需品),这条分法就要打折扣。 判据是:去掉它之后,成绩是掉几成,还是掉一个数量级。

边界与局限

  • 这一整条线接不了连续动作。 因为最后一步永远是「对每个动作算一遍 Q 再取最大」, 而方向盘的角度有无穷多个。这就是第 08 章存在的全部理由;
  • 两个补丁都没有收敛证明。 第 06 章那三样一个都没被真正拿掉 —— 回放缓存让「学别人走的路」这一条更严重了,只是把它变得没那么容易炸;
  • 所有实验都在雅达利上。 书里给的五行游戏结论一致,但那是同一类任务 (离散动作、画面输入、有明确分数);
  • 六个补丁之间的相互作用,书里没有讨论。 Rainbow 把它们合在一起有效, 但哪一个贡献最大、有没有互相抵消,这一章一个字都没有;
  • 书里的实验只跑了 3 个随机种子20,而第 11 章会引一条实测说 5 个可能都不够 —— 这本书自己前后就有这个张力。

可带走的

全章那条走查,一行写完: 210×160 的彩色帧 → 动作重复 4 帧、相邻两帧取最大 → 转 84×84 灰度 → 堆最近 4 帧当一个局面 → 网络吐出每个动作的分 → ε-贪心选一个 → 经验写进百万条的池子 → 随机抽 32 条 → 用隔一阵才同步的目标网络算出目标 0.3465 → 和当前估计 0.50 相减,用 Huber 损失反向传播。 (尺寸、帧数、四个消融数是书里的;0.3465 与 0.50 是为演示编的。)

  1. 把 Q 表直接换成网络会不稳定甚至发散 —— 因为它把死亡三件套一次占全了;
  2. DQN 的贡献是两个补丁,不是一个收敛证明。 全书的「打补丁史」从这里开始;
  3. 回放缓存一次治三个病:数据用得省、样本被打散、分布不再只来自上一个策略;
  4. 回放缓存只对离线策略的算法可用 —— 这是第 10 章要合流的原因之一;
  5. 目标网络把靶子钉住:目标值用旧参数算,不受这一步更新的影响;
  6. ★ 四个数要背下来:316.8 / 240.7 / 10.2 / 3.2。★ 在 Breakout 上拿掉回放缓存掉 23 倍,拿掉目标网络只掉 24%; 但这个次序五个游戏里只有四个成立,Seaquest 那一行反过来 —— 五行里一律成立的 是「两个都用最高、两个都不用最低」;
  7. 对一堆带噪的数取最大,会把「这次运气好」系统性地当成「它真的好」 —— Double 的解法是让「选谁」和「值多少」由两个网络分工;
  8. 有些局面做什么都一样(山上看日出),所以把 Q 拆成「局面本身值多少 + 这个动作比平均好多少」;
  9. 按误差偏心抽样能学得快,但偏心会让统计偏掉,所以要配一个纠偏系数(第 09 章讲透);
  10. 把噪声放进参数里,探索的幅度本身就能被学出来 —— 对需要连贯几十步的游戏才见效;
  11. 只估一个平均值会丢掉分布的信息(「平均 5 分」可能是每次 5 分,也可能一半 0 一半 10);
  12. Rainbow = 六个补丁合体,而六个补丁治的是六个不同的病;
  13. 雅达利那套预处理的每一层都在补一个具体的洞 —— 其中堆 4 帧补的正是第 01 章那个「单帧看不出球速」;
  14. 损失用 Huber 不用均方误差,是为了让一条离谱的样本推不飞参数。

原文地图

主题原书章原文位置
直接换成网络会不稳定第4章 深度Q网络text/08-ch04-4-q.txt:145(搜「端到端决策」)
两个关键技术的定位第4章 深度Q网络text/08-ch04-4-q.txt:146(搜「显著进展」)
回放缓存与它的三条好处第4章 深度Q网络text/08-ch04-4-q.txt:147(搜「回放缓存」) · text/08-ch04-4-q.txt:151(搜「重用每个时间步的经验」) · text/08-ch04-4-q.txt:153(搜「增加更新的方差」) · text/08-ch04-4-q.txt:155(搜「FIFO」)
目标网络、硬更新与软更新、那条因果链第4章 深度Q网络text/08-ch04-4-q.txt:157(搜「硬」) · text/08-ch04-4-q.txt:159(搜「不受最新参数的影响」) · text/08-ch04-4-q.txt:161(搜「被过估计」)
消融实验的四个数与实验口径第4章 深度Q网络text/08-ch04-4-q.txt:163(搜「效果提升效果」) · text/08-ch04-4-q.txt:172(搜「316.8」)
过估计的不等式第4章 深度Q网络text/08-ch04-4-q.txt:210(搜「最大化算子」) · text/08-ch04-4-q.txt:211(搜「最大噪声的期望值」)
Double 的核心思想第4章 深度Q网络text/08-ch04-4-q.txt:220(搜「既用于估计」) · text/08-ch04-4-q.txt:221(搜「两个不同的网络」)
看日出的例子第4章 深度Q网络text/08-ch04-4-q.txt:351(搜「山上看日出」) · text/08-ch04-4-q.txt:352(搜「解耦」)
Q 拆成两部分与归一化第4章 深度Q网络text/08-ch04-4-q.txt:355(搜「状态值和动作优势」) · text/08-ch04-4-q.txt:365(搜「唯一地对应」) · text/08-ch04-4-q.txt:366(搜「取平均代替取最大值」) · text/08-ch04-4-q.txt:375(搜「更多的网络层」)
优先经验回放的思想与三个问题第4章 深度Q网络text/08-ch04-4-q.txt:387(搜「令人惊喜」) · text/08-ch04-4-q.txt:391(搜「扫描整个回放缓存」) · text/08-ch04-4-q.txt:150(搜「均匀采样」) · text/08-ch04-4-q.txt:403(搜「基于顺序的优先」)
纠偏权重与退火第4章 深度Q网络text/08-ch04-4-q.txt:405(搜「放弃了纯随机采样」) · text/08-ch04-4-q.txt:411(搜「趋近于无偏」)
多步学习与它的错配第4章 深度Q网络text/08-ch04-4-q.txt:425(搜「另外 3 个」) · text/08-ch04-4-q.txt:432(搜「纠正此类错配」)
噪声网络与蒙特祖玛的复仇第4章 深度Q网络text/08-ch04-4-q.txt:448(搜「蒙」) · text/08-ch04-4-q.txt:456(搜「大幅提升」)
值分布、51 个原子第4章 深度Q网络text/08-ch04-4-q.txt:457(搜「值分布」) · text/08-ch04-4-q.txt:469(搜「原子」) · text/08-ch04-4-q.txt:473(搜「C51」)
投影与换损失第4章 深度Q网络text/08-ch04-4-q.txt:477(搜「脱节」) · text/08-ch04-4-q.txt:488(搜「无法度量」)
分位数回归那一版第4章 深度Q网络text/08-ch04-4-q.txt:504(搜「固定的离散集」) · text/08-ch04-4-q.txt:505(搜「分位数回归」)
八个装饰器第4章 深度Q网络text/08-ch04-4-q.txt:645(搜「空动作」) · text/08-ch04-4-q.txt:648(搜「重复每个动作 4 次」) · text/08-ch04-4-q.txt:652(搜「本条命结束」) · text/08-ch04-4-q.txt:657(搜「符号」) · text/08-ch04-4-q.txt:659(搜「堆叠最后 4 帧」)
Huber 损失防梯度爆炸第4章 深度Q网络text/08-ch04-4-q.txt:663(搜「梯度爆炸」)
ε 的退火与实验规模第4章 深度Q网络text/08-ch04-4-q.txt:737(搜「线性地从」) · text/08-ch04-4-q.txt:802(搜「3 个随机种子」)

Footnotes

  1. 出处:「第4章 深度Q网络」第 145 段(text/08-ch04-4-q.txt:145,搜「端到端决策」)。原书在本章开头就引了一篇文献指出用非线性函数逼近 Q 值时的不稳定甚至发散。

  2. 出处:「第4章 深度Q网络」第 146 段(text/08-ch04-4-q.txt:146,搜「显著进展」)。 2

  3. 出处:「第4章 深度Q网络」第 147 段(text/08-ch04-4-q.txt:147,搜「回放缓存」)、第 151 段(text/08-ch04-4-q.txt:151,搜「重用每个时间步的经验」)、第 153 段(text/08-ch04-4-q.txt:153,搜「增加更新的方差」)与第 155 段(text/08-ch04-4-q.txt:155,搜「FIFO」)。原文写明存进去的是四元组、抽出来的是均匀采样的小批量。 2 3 4

  4. 出处:「第4章 深度Q网络」第 157 段(text/08-ch04-4-q.txt:157,搜「硬」)、第 159 段(text/08-ch04-4-q.txt:159,搜「不受最新参数的影响」)与第 161 段(text/08-ch04-4-q.txt:161,搜「被过估计」)。 2 3 4 5

  5. 出处:「第4章 深度Q网络」第 163 段(text/08-ch04-4-q.txt:163,搜「效果提升效果」)与第 172 段(text/08-ch04-4-q.txt:172,搜「316.8」)。表 4.1 一共五行游戏,数据来自 2015 年那篇论文。另外四行是 Enduro(1006.3 / 831.4 / 141.9 / 29.1)、River Raid(7446.6 / 4102.8 / 2867.7 / 1453.0)、Seaquest(2894.4 / 822.6 / 1003.0 / 275.8)、Space Invaders(1088.9 / 826.3 / 373.2 / 302.0),四个数的次序与表头同。五行都是「两个都用最高、两个都不用最低」;但中间两格谁高谁低不一律 —— Seaquest 那一行是只用回放缓存 822.6、只用目标网络 1003.0,与 Breakout 相反。 2 3 4

  6. 出处:「第4章 深度Q网络」第 210 段(text/08-ch04-4-q.txt:210,搜「最大化算子」)与第 211 段(text/08-ch04-4-q.txt:211,搜「最大噪声的期望值」)。原书还列出了 Q 值带噪的几个来源:环境、非稳态、函数近似。 2 3

  7. 出处:「第4章 深度Q网络」第 220 段(text/08-ch04-4-q.txt:220,搜「既用于估计」)与第 221 段(text/08-ch04-4-q.txt:221,搜「两个不同的网络」)。原文的措辞是「去除选择和评价中噪声的相关性」。 2 3

  8. 出处:「第4章 深度Q网络」第 351 段(text/08-ch04-4-q.txt:351,搜「山上看日出」)与第 352 段(text/08-ch04-4-q.txt:352,搜「解耦」)。

  9. 出处:「第4章 深度Q网络」第 355 段(text/08-ch04-4-q.txt:355,搜「状态值和动作优势」)、第 365 段(text/08-ch04-4-q.txt:365,搜「唯一地对应」)、第 366 段(text/08-ch04-4-q.txt:366,搜「取平均代替取最大值」)与第 375 段(text/08-ch04-4-q.txt:375,搜「更多的网络层」)。 2 3 4 5 6

  10. 出处:「第4章 深度Q网络」第 387 段(text/08-ch04-4-q.txt:387,搜「令人惊喜」)、第 391 段(text/08-ch04-4-q.txt:391,搜「扫描整个回放缓存」)、第 150 段(text/08-ch04-4-q.txt:150,搜「均匀采样」)与第 403 段(text/08-ch04-4-q.txt:403,搜「基于顺序的优先」)。 2 3 4 5 6

  11. 出处:「第4章 深度Q网络」第 405 段(text/08-ch04-4-q.txt:405,搜「放弃了纯随机采样」)与第 411 段(text/08-ch04-4-q.txt:411,搜「趋近于无偏」)。原书在这里直接用了「重要性采样权重」这个名字,但没有展开它的来历——那要到策略梯度那一章。 2 3 4

  12. 出处:「第4章 深度Q网络」第 448 段(text/08-ch04-4-q.txt:448,搜「蒙」)与第 456 段(text/08-ch04-4-q.txt:456,搜「大幅提升」)。原书把噪声网络称为「另一种 ε 贪心的探索算法」。 2

  13. 出处:「第4章 深度Q网络」第 425 段(text/08-ch04-4-q.txt:425,搜「另外 3 个」)与第 432 段(text/08-ch04-4-q.txt:432,搜「纠正此类错配」)。原书写明 Rainbow 直接使用了从给定状态起算的多步回报,没有做离线策略修正。 2 3 4

  14. 出处:「第4章 深度Q网络」第 457 段(text/08-ch04-4-q.txt:457,搜「值分布」)、第 469 段(text/08-ch04-4-q.txt:469,搜「原子」)与第 473 段(text/08-ch04-4-q.txt:473,搜「C51」)。 2 3

  15. 出处:「第4章 深度Q网络」第 477 段(text/08-ch04-4-q.txt:477,搜「脱节」)与第 488 段(text/08-ch04-4-q.txt:488,搜「无法度量」)。

  16. 出处:「第4章 深度Q网络」第 504 段(text/08-ch04-4-q.txt:504,搜「固定的离散集」)与第 505 段(text/08-ch04-4-q.txt:505,搜「分位数回归」)。

  17. 出处:「第4章 深度Q网络」第 645 段(text/08-ch04-4-q.txt:645,搜「空动作」)、第 648 段(text/08-ch04-4-q.txt:648,搜「重复每个动作 4 次」)、第 652 段(text/08-ch04-4-q.txt:652,搜「本条命结束」)、第 657 段(text/08-ch04-4-q.txt:657,搜「符号」)与第 659 段(text/08-ch04-4-q.txt:659,搜「堆叠最后 4 帧」)。省内存那条书里叫「延迟帧技术」。 2

  18. 出处:「第4章 深度Q网络」第 663 段(text/08-ch04-4-q.txt:663,搜「梯度爆炸」)。原文写明这等同于把均方误差换成参数取 1 的 Huber 损失。

  19. 出处:「第4章 深度Q网络」第 737 段(text/08-ch04-4-q.txt:737,搜「线性地从」)。

  20. 出处:「第4章 深度Q网络」第 802 段(text/08-ch04-4-q.txt:802,搜「3 个随机种子」)。原文同时给了训练规模:1000 万个时间步、相当于 4000 万帧。 2