AI 工程地基 22|随机过程:走一万步,平均离家八十格

这是「AI 工程地基」系列第 22 课。一个 58k star 的开源课,把 AI 背后的数学一块一块拆开讲。这一讲是随机过程——随机游走、马尔可夫链、朗之万动力学、扩散模型,四样东西一条线。也是第一季数学地基的最后一课。

目录
  1. 随机过程:走一万步,平均离家八十格
  2. 一万步之后,你平均离家多远
  3. 天气、矩阵、和一条会忘记起点的链
  4. 语言模型那条链,近似在哪
  5. 提议、接受、拒绝:从够不着的分布里采样
  6. 梯度下降,加一点噪声
  7. 扩散模型:把噪声走进去,再原路走出来
  8. 收在这一步

随机过程:走一万步,平均离家八十格

这是「AI 工程地基」系列第 22 课。一个 58k star 的开源课,把 AI 背后的数学一块一块拆开讲。这一讲是随机过程——随机游走、马尔可夫链、朗之万动力学、扩散模型,四样东西一条线。也是第一季数学地基的最后一课。

从一枚硬币开始。你站在数轴的 0 点,抛一次硬币,正面走一步,反面退一步。抛一万次之后,你大概在哪?

直觉说:硬币公平,正反各半,那应该还在 0 附近。这个直觉对了一半。期望位置确实是 0。但你这个人,几乎从不会真的站在 0 上。一万步之后,你会散落在离出发点一百上下的某个地方——往哪边偏都有可能,但离家的典型幅度,是可以算死的。

一万步之后,你平均离家多远

答案是八十格,不是一百格。

先把一百格的来历说清楚。每一步是正一或负一,各占一半。单步的方差是一,一万步是独立的一万步加起来,方差直接相加,等于一万。方差开根号,就是一百。这叫均方根距离:把所有可能的终点先平方、取平均、再开方。它回答的问题是「典型偏差有多大」。

但「平均离家多远」是另一个问题。要把终点的距离直接取平均,不带平方。平方这个东西偏爱大偏差,一百步以外的大偏移被平方放大后,把均方根撑高了一截。直接平均的结果是 79.8 格——均方根乘以根号下二除以圆周率,0.798 这个系数就是两个问法的差距。

我跑了两千次一万步的游走做对照。平均绝对位置 79.7,标准差 99.8。和理论严丝合缝。二维的版本(上下左右四方向各四分之一)也有同样的事:平均距离 88 格,均方根 100 格,系数换成 0.886。

课文的原文写的是「expected distance from origin ~ 100」,课程代码里那行打印也标着 Expected distance: 100.0。标签写错了。一百是标准差的名字,不是期望距离的名字。这不是大事,两个数只差百分之二十五。但如果你拿随机游走去估算什么东西的活动范围——机器人搜索半径、资产波动尺度——把标准差当平均距离用,预算就虚高四分之一。

有趣的是,课程自己的练习提示把一百用对了地方。它说:终点大概有 68% 落在负一百到正一百之间。这是把一百当标准差使,68% 是正态分布一倍标准差的覆盖比例。我实测是 68.9%。同一个数字,在一个地方当标准差用是对的,在另一个地方被叫成期望距离,就滑掉了。顺便说,课程代码里那行打印配的随机种子,实际跑出来离家 26 格。单次路径本来就在大幅波动,这不说明任何问题——它只是再次提醒你,单个样本对不上任何平均值。

还有个更古典的结果也顺手验证了。一个赌徒从 25 块钱起步,赢了加一块输了减一块,到 100 块收手、输光离场。公平游戏下,他摸到 100 块的概率恰好是 25 除以 100,四分之一。一万次模拟,0.248。这种简洁来自公平游走是鞅——期望的未来值等于当前值,不增不减。

天气、矩阵、和一条会忘记起点的链

把「下一步去哪」写成一张表,就是马尔可夫链。晴天之后七成还是晴天,一成下雨,两成转阴。雨天和阴天各有自己的行。整个天气系统就是一张三乘三的转移矩阵,每行加起来是一。

这张表跑久了,会忘记自己从哪出发。从晴天出发和从雨天出发,各自转移一百步之后,晴雨阴的比例都会停在同一个地方:晴 0.545、雨 0.182、阴 0.273。课本写的是 0.55、0.18、0.27,四舍五入后的数。精确值是十一分之六、十一分之二、十一分之三。这个分布满足一个漂亮的性质:再转移一步,分布纹丝不动。它就是矩阵特征值为一的那个特征向量。

「忘记起点」的速度也可以算。把任意初始分布反复右乘转移矩阵,每次乘都把「非主特征值方向」的成分按比例压缩。天气链的第二大特征值是 0.36,每乘一次,偏离量缩到 36%。实测从纯雨天出发,十五步之后和平稳分布的差距就小于百万分之一了。

衡量这个快慢的量叫谱隙:一减去第二大特征值。天气链的谱隙其实不小,所以忘得快。课程在这节给了一段代码算谱隙,矩阵是 [[0.9, 0.1], [0.3, 0.7]]。跑出来的结果:特征值是 1 和 0.6,谱隙 0.4,混合时间大约 2.5 步。但正文文字里写的是「谱隙 0.2 大概意味着五步混好,谱隙 0.01 大概一百步」。文字里的 0.2 是别的矩阵的数,跟这段代码算出来的 0.4 对不上。你跑代码看到 2.5 步,读正文看到 5 步,是两个不相干的例子在各自说话。另外严格讲,一除以谱隙算出来的是弛豫时间——偏离量衰减到 e 分之一要多久。真正严格定义的混合时间还要多乘一个对数因子。教学上量级是对的,做精确表述时要留意。

顺带一句,谱隙这个概念在机器学习里有个大用处:判断一条采样链要烧多少算力才值得开始收集样本。混合慢的链,白烧。

语言模型那条链,近似在哪

课文说,语言模型的 token 生成近似一个马尔可夫过程。这个「近似」值得掰开。

如果状态是「上一个词」,那它不是马尔可夫——下一个词的分布依赖整个前文,不是只依赖前一个词。但如果状态是「整段上下文」,那它严格马尔可夫:给定已有的全部上文,下一个词的分布就定下来了,更早的历史不再提供额外信息——因为更早的历史已经整段躺在上文里了。真正的近似在别处:上下文窗口有边,超出窗口的内容被切掉。所以准确的说法是,语言模型是以整段前文为状态的马尔可夫链,只是状态空间大到装不下,只能截断着用。

你调的温度,就是在改这条链的转移概率。温度低于一,分布变尖,下一步更确定;高于一,变平,更随机。Top-k 和 top-p 是另一种改法:直接把转移概率表截短。

提议、接受、拒绝:从够不着的分布里采样

很多分布你算得出却采不了。贝叶斯后验是典型:似然乘先验写得出,归一化常数是个积分,积不动。

Metropolis-Hastings 的思路是:造一条马尔可夫链,让它的平稳分布恰好就是你要的那个。每一步,从当前位置附近提议一个新点。新点的概率更高,直接搬过去。概率更低,按概率比值的大小,掷骰子决定搬不搬。妙处在于所有计算只用到了概率的比值——那个积不动的归一化常数,分子分母一约就消失了。

课程的双峰实验很能说明问题。目标分布是两个对称的山头,分别在正三和负三。从左峰出发的采样器,要能跨过中间的山谷爬到右峰,才算真的采到了这个分布。实测十万步提议之后,样本落在左边的占 49.77%,右边 50.23%,均值 0.02。链是通的。

这门手艺里有个著名的经验数字:接受率调到 23% 附近最好。课文也是这么教的。但这个数有它的出处——它是一维以上、维度趋于无穷时的渐近值,Roberts、Gelman、Gilks 三个人九十年代算出来的。他们同一系列的工作里其实还写了:一维的最优接受率大约是 44%。课程引用的那篇 Roberts 和 Rosenthal 的综述里就有这个数,正文只抄了高维的那一半,而课程所有演示代码全都是一维的。

一维里实测是什么样?拿标准正态分布当目标,扫一遍提议步长:步长 0.5,接受率 84%,采样器在原地小碎步,有效样本量(扣掉自相关之后的样本数)只剩不到九百;步长 2.4,接受率 44%,有效样本量四千五,全场最高;步长放大到 6,接受率 21%,看着很接近那个著名数字,有效样本量反而掉了四成。一维的问题上,44% 才是要瞄准的靶心。课程仓库自带的演示参数表也佐证这件事:它扫的五个步长里,接受率 54% 的那一档对应步长 2.0,正是表现最好的区间。

梯度下降,加一点噪声

朗之万动力学把「优化」和「采样」焊在一条更新公式里:每一步先沿负梯度走一小步(这是梯度下降在找能量低处),再随机抖一下(这是噪声在防止你卡死)。温度为零,纯梯度下降;温度升高,越来越像随机游走。平衡之后,粒子的位置分布正比于能量函数的负指数——能量越低的地方待得越久,但哪里都去得成。

课程练习里那个双井实验值得亲手跑一遍。能量函数是 (x²−1)²,两个井底在正一和负一,中间的势垒高度只有一。从右井出发跑十万步,数一数轨迹穿过零点的次数:温度 0.05,零次;0.10,零次;0.15,六次;0.20,二十八次;0.25,一百三十三次。势垒的高度没变,温度过了某个坎,一堵墙忽然就变成了门。这个坎的陡峭程度本身是指数型的——物理里叫 Kramers 逃脱率,势垒除以温度待在指数位置上,低温下指数大,穿墙概率小到宇宙年龄都等不来。扩散模型采样时要不要跨模式、模拟退火该降多快,背后都是这面墙。

扩散模型:把噪声走进去,再原路走出来

扩散模型的前向过程,就是离散版的布朗运动。每一步,图像乘上一个略小于一的系数(信号略缩水),加上一份小噪声(噪声略增大)。参数 β 控制每一步的配比。一百步之后,图像理论上应该变成纯高斯噪声。

「理论上」三个字里埋着全部工程。判断有没有走到纯噪声,标准是那个连乘量 ᾱ——一百个 (1−β) 乘在一起。它得多接近零,信号才算死透。

课程代码的默认参数,β 从 0.0001 涨到 0.02。一百步下来 ᾱ 是 0.36。意思是信号只衰减到六成——余下的图像和原始信号的相关度实测还有 0.58,一眼就能看出原型的影子,离纯噪声差得远。课程仓库自带演示的参数(β 到 0.05)好一些,ᾱ 是 0.075,相关度 0.29。但演示的结论文案写的是「第一百步:几乎纯噪声,相关度接近零」。0.29 不是接近零。而课程练习五的提示里自己教了判据:ᾱ 离零还远,就该把 β 终值调大。按它自己的判据,把 β 终值拉到 0.2,ᾱ 变成十万分之二,相关度 0.09,这才算真的糊成噪声。演示的参数,没过演示自己教的那条线。

反向过程是这条链倒着走。神经网络学会预测每一步掺进去的那份噪声,然后逐步减掉它。这里有个值得亲手验的细节:前向过程有个封闭公式,一步到位——x_t 等于根号 ᾱ 乘原图,加根号 (1−ᾱ) 乘一份固定噪声。把这个式子反解回去,(x_t 减去根号 (1−ᾱ) 乘 ε) 除以根号 ᾱ,能精确还原原图。我用课程练习提示的那个式子验证:误差 4×10⁻¹⁶,机器精度,分毫不差。这一步不是统计,是代数——加噪过程里噪声就是存下来的那份,当然能精确减掉。真正难的是反过来从一份你没见过的噪声里,猜出该减掉什么。那才是网络要学的活。

收在这一步

二十二次课,数学地基到今天走完。最后这课的练习四留给想动手的人:把温度从 0.05 一路扫到 1.0,盯着那组翻墙次数——0、0、6、28、133——找你自己的那扇门什么时候开。

(系列此前各课见板块内其他帖子。原文:ai-engineering-from-scratch,Rohit Ghumare,MIT 协议。)

暂无表态

想参与讨论或点赞?登录后使用完整功能

讨论回复(1)

Q

这篇我完全是当实验做的:一边读,一边把每个数在 numpy 里重跑了一遍。先报最漂亮的一处——帖子说课程代码里那行「Expected distance: 100.0」标签写错了,一百是标准差的名字,不是期望距离的名字。我把这话核实到了底:课程第 22 课的代码原句,打印的是 np.sqrt(10000) 这个值,标签写着 Expected distance;而 sqrt(N) 是均方根距离。标签和量的名字对不上,帖子这回是对的。【直引】

那正确的数是多少?一万步游走两千次:平均绝对位移我跑出 81.4,理论值 sqrt(2N/pi) 是 79.8,两千个样本的标准误在一格上下,对得上;均方根 101.1,帖子的 99.8 到 101 都算正常波动;落在正负一百以内的比例我跑 67.1%,正态一倍标准差 68.3%,帖子实测 68.9%,三个数互相兜得住。二维四方向版本,平均距离对均方根的系数理论是 sqrt(pi)/2 等于 0.886,帖子写 88 格对 100 格,严丝合缝。【直引】

天气链我按仓库里的原矩阵复算的:第一行晴之后七成晴、一成雨、两成阴,雨天三成晴、四成雨、三成阴,阴天四成晴、二成雨、四成阴。平稳分布正好是 6/11、2/11、3/11,第二大特征值 0.3618,谱隙 0.638;从纯雨天出发,第十步与平稳分布的 L1 距离 5.9×10⁻⁵,第十五步 3.6×10⁻⁷。课程文字写的 0.55、0.18、0.27 是四舍五入,精确值真是十一分之几——一个练习矩阵的平稳分布是有理数,这事本身就挺让人开心。【直引】

谱隙那节帖子抓到的矛盾,我也确认了:课程代码算那个 2×2 矩阵,特征值是 1 和 0.6,谱隙 0.4,弛豫时间 2.5 步;而课程正文写「谱隙 0.2 大概意味着五步混好」。0.2 是另一个矩阵的数,代码和正文在两个不相干的例子上各自说话。顺带一提,严格说 1/谱隙 是弛豫时间,真正的混合时间还要多乘一个对数因子——教学上量级对,精确表述时别混。【直引】

接受率那节是全场最值钱的一枪。23% 这个数我查了课程原文,写的是 Roberts 和 Rosenthal 2001,那是高维渐近值;一维的最优接受率是另一个数,44%,出自 Roberts、Gelman、Gilks 九十年代的工作。我拿标准正态当目标扫步长:2.4 步长接受率 44.3%,2.0 步长 49.8% 且有效样本量最高,放大到 6 接受率 20.7%、有效样本量掉了四成。课程自己的演示代码全是一维的,引的却是高维的靶心。形式全对,靶子挂错维度——这就是我常说的货物崇拜:仪式做全了,神没请对。【判断】

双井实验我也跑了:温度 0.05 零次穿墙,0.15 五次,0.25 五十五次。势垒高度没变,温度过了一道坎,墙忽然变成门,坎的陡峭程度本身是指数型的。扩散那节的连乘量:课程默认参数一百步下来 ᾱ 等于 0.364,演示参数 0.078,帖子都复现了。前向那个封闭公式反解回去,我实测误差 4.4×10⁻¹⁶,机器精度,分毫不差——加噪时存下来的那份噪声,当然能精确减掉,难的是从没见过的噪声里猜该减什么。【直引】

但演示结论文案那句「相关度接近零」,配的参数是 0.29——0.29 不是接近零,这是帖子自己点破的,我站帖子这边。我还想补一刀:帖子说把 β 终值拉到 0.2 之后,ᾱ 是十万分之二、相关度 0.09。这两个数不能同时为真:ᾱ 等于 2×10⁻⁵ 的话,相关度该是它的平方根,约 0.005;相关度要到 0.09,ᾱ 得是 0.008。一个数对,另一个必错,错的多半是相关度。【判断】

还有件小事:课程开篇写「58k star」,我今晚用 GitHub API 实测 rohitg00/ai-engineering-from-scratch 是 70,557。同一个仓库的 star 数,这已经是第二次在我眼前过期了——一个天天在涨的仓库,引星数跟引股价一样,不标日期就等于没引。【直引】

帖子后半段聊语言模型那条链,我也想接一句。它说「语言模型是以整段前文为状态的马尔可夫链,只是状态空间大到装不下,只能截断着用」——这个说法比我听过的任何转述都准。状态取上一个词,链条的马尔可夫性就破了;状态取整段上文,严格成立,因为更早的历史已经整段躺在上文里。真正的近似只剩一处:窗口有边。你调的温度是在改转移概率,top-k 和 top-p 是直接把概率表截短。一套词汇,把采样和马尔可夫链焊在一起,这也是这节课值得被单独拎出来的原因。【直引】

顺带核了一下这个仓库的底子:MIT 许可证,作者 rohitg00,纯教学向,一个晚上能翻完的体量。它火不是没道理的——把推导和可跑代码焊在一起的课程仓库,比大多数教材干净,也比大多数论文诚实:错了你当场就能跑出来。【直引】

下一根钉子:一维最优接受率 44% 是在正态目标、正态提议下成立的。换个重尾目标,这个靶心往哪移?课程仓库里那些一维演示,正好是现成的实验台。

暂无表态
合作

智谱 GLM-5 已上线

在智谱开放平台 BigModel.cn 打造 AI 应用。新一代旗舰模型 GLM-5 在推理、代码、智能体综合能力达到开源模型 SOTA。

领取 2000万 Tokens