ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

深度学习概率基础:从随机变量到极大似然估计核心要点

深度学习概率基础:从随机变量到极大似然估计核心要点

先说我读完这一节的第一感受:第三章第一节是整个深度学习理论体系里少有的、能在半小时内读完、却值得反复咀嚼一整周的内容。如果你手头正好翻到这本书的第三章开头,大概率会在“随机变量”“期望”“方差”“概率分布”这些基础概念上快速扫过去,因为看上去都是老朋友了。但真正做深度学习的人都会有这种体会——后续所有模型推导、损失函数设计、正则化项选择、生成模型的数学表达,全部蜕了一层皮之后,底下站着的还是这一节的底子。

这一节叫《概率与信息论》的开篇,作者用相当浓缩的篇幅快速搭建了理解深度学习的概率语言框架。书里反复强调一句话:机器学习不是直接处理数据,而是在数据分布上做推断。这句话就是你读这一整节应该挂在脑子里的主线。这一篇笔记,我就围绕这个主线,把第一节涉及的核心知识点全部重新梳理一遍,配合我在实际训练模型时踩过的坑和验证过的理解方式,尽量说人话,帮你把这一节从“看懂了”变成“会用了”。

1. 这一节到底在解决什么问题

先把视角拉高一点。第三章的标题是“概率与信息论”,第一节其实承担了一个很重的任务:它要把你从“确定性计算”的思维,切换成“不确定性推理”的思维。为什么深度学习绕不开概率?因为模型最终要面对的真实世界本身就是不确定的——同一个输入可能对应多个合理输出,传感器噪声、标注误差、数据采样的偏差,都会让输入和输出之间的关系带有随机性。如果没有概率语言,我们根本无法描述“模型有多自信”,更别提在训练中量化损失、为不同样本做加权处理了。

书里举的经典场景,是线性回归从“求解方程组”变成“求解条件概率分布”。确定性的视角下,我们想要找到函数 f,让 f(x) 恰好等于 y;概率视角下,我们描述的是 P(y|x)的条件分布,也就是在给定输入时,输出落在各个取值上的可能性有多大。这一转变直接影响损失函数的形式——从最小二乘误差变成了极大似然估计,而这两者在高斯噪声假设下是等价的,但适用范围完全不同。理解这一点,你就明白为什么交叉熵、KL散度这些东西在分类任务里如此常见。

1.1 随机变量:从“变量”到“状态的映射”

书里对随机变量的定义很多初学者会疑惑:随机变量不是一个数值,而是一个从样本空间到数值的映射函数。也就是说,随机变量描述的不是某个具体结果,而是所有可能结果的取值规则。举个例子,抛一枚硬币,正面记为1,反面记为0,这里 X 就是一个随机变量,它的取值取决于试验结果。深度学习中我们更常接触的是连续型随机变量,比如图片像素的强度值、特征向量中某一维的浮点数,这些都是通过某种概率分布来描述的。

实际建模时容易踩的第一个坑,是把随机变量和它的观测值混为一谈。模型输入 x 是一个具体的向量,它是一次采样得到的观测值;但从概率角度,训练集的全体样本应该看成是某个底层分布 P_data 的独立采样。读这一节时,把“观测值”和“随机变量”这两个概念分开理解,后面看损失函数的期望形式时就不会发晕。

1.2 概率分布是模型的核心语言

离散型和连续型变量的分布描述方式不同。离散型用概率质量函数(PMF),直接给每个取值赋一个概率;连续型用概率密度函数(PDF),描述的是取值落在某个无穷小区间内的概率密度,而非概率本身。深度学习里最常见的两个分布,一个是分类任务中的 categorical 分布(离散),另一个是高斯分布(连续)。书中反复强调 PDF 之所以叫密度,是因为它本身可以大于1,只有积分之后才是概率。这个看似废话的点,很多人在做异常检测时计算概率密度值会忘记——密度值低并不意味着“不可能”,只是相对于其他区域更稀疏。

经验上,如果你刚接触生成模型,这个概念尤其重要:用极大似然训练生成模型时,我们优化的目标函数里出现的不是概率而是对数密度,而 PDF 在特定参数下可能数值极大或极小,直接用概率比较不同点之间的“可能性”反而容易出问题。所以书里引入对数运算来缓解数值压力,后面的信息论部分会展开,我在这儿先提个醒。

2. 核心细节拆解:从期望、方差到独立同分布

2.1 期望不是“平均值”那么简单

书里给出期望的定义公式的时候,大多数读者都能看懂,但容易忽略期望作为一个算子的线性性质到底有多少用。期望是概率加权的平均,离散情形下是求和,连续情形下是积分。实际应用中,期望的线性性让我们可以放心地对随机变量的线性组合直接计算期望,而不需要重新推导整个分布。这在训练神经网络时经常用到——比如一个 batch 的损失期望等于每个样本损失的期望的平均,放大了看就是一个线性运算。

一个容易被忽略的细节是:期望的存在性并不总是有保证的。某些分布(比如重尾分布)下,积分可能发散,期望不存在。这种情况在实际业务数据中并不罕见,比如广告点击数据的长尾部分、网络延迟数据的极端峰值。设计损失函数或评估指标时,如果数据中存在极大的离群值,平均值可能会被少数样本“带飞”,这时候用中位数或其他稳健统计量可能比期望更合适。书中用严谨的数学语言描述了这个缺陷,但它的工程含义往往被跳过。

还有一个理解捷径:期望可以看成是在无限多次采样下,算术平均趋近的那个值。大数定律保证了这个收敛性。这正好解释了我们为什么要用 mini-batch 来估计期望——单个样本的梯度可以看成对真实梯度期望的一个噪声估计,batch 越大,估计越准,但计算代价也越高。理解期望和采样估计的关系,基本就能理解深度学习优化为什么能跑得动。

2.2 方差与标准差:模型的稳定性指标

方差度量的是随机变量与其期望的偏离程度,标准差则是方差的平方根,回到与原始数据相同的量纲。书中用公式表达,但实操中的价值是给“不确定性”一个具体的数字。网络权重的初始化方差会影响训练稳定性,噪声方差会影响模型输出置信度,数据增强引入的随机扰动大小本身就是一个方差控制问题。

我在实际项目里最常用的一个地方是贝叶斯神经网络或深度集成:多个模型的预测可以看成是从一个隐含的后验分布中采样,这些样本的方差就代表了认知不确定性。数据本身噪声带来的方差则是偶然不确定性。两者在工程上对应完全不同的处理方式——前者可能需要收集更多数据,后者则需要调整模型容量或损失函数加权。书中把方差的概念推到中心极限定理部分还会再次出现,但那是后话了。

2.3 独立同分布:深度学习不成立却坚持用的假设

独立同分布(i.i.d.)是整个监督学习的基石假设:训练集样本之间相互独立,且都来自同一个分布。书里用严谨的概率语言表述了这个假设,但在真实业务场景里,这个假设几乎总是被打破的。同一个用户的多次点击行为互相之间有强关联,时间序列数据天然不独立,某一段时间采集的数据在分布上也与另一段时间不同。

那为什么我们还要用?因为在工程上,没有 i.i.d. 假设,我们几乎无法从有限样本中推断出可用模型的任何保证。实际做法是在已知分布偏移的场景下做针对性矫正,比如使用领域自适应、重采样、或直接用更鲁棒的损失函数。我第一次做真实业务数据时,天真地按学术数据集那套方式切分训练验证集,结果模型上线一周后效果崩了。后来才意识到:分布偏移才是常态,i.i.d. 只是简化假设,不是事实描述。这一节的价值正是让你分清哪些是假设、哪些是事实,才不会在后面做模型诊断时走弯路。

3. 实操视角:亲手用一个小实验验证这些概念

这一节的数学推导很平易近人,但光学不练很容易变成“假懂”。我有一个自己常用的验证方式,也是我在带新人的时候总让他们做的一个练习:用代码构造两个不同分布的随机变量,计算它们的期望和方差,然后观察样本均值随采样数量的变化如何逼近理论值。做一遍这个实验之后,再看书里的公式会有完全不一样的感觉。

下面是我常用的最小复现实验,用 Python 写,模型结构就是一个简单的采样实验。整个过程不需要 GPU,只需要 numpy、matplotlib 和 Jupyter 就能完成。

3.1 构造实验环境

先准备基础库。这里我用最简洁的方式把环境代码贴出来,方便你直接跟着走一遍。

import numpy as np import matplotlib.pyplot as plt np.random.seed(42)

环境本身不做复杂配置。关键是要让随机种子固定,这样你复现的时候曲线和我这里描述的完全一致。工业级实验里,随机种子管理是容易忽视的一环——这直接关系实验结果的可复现性。如果你在团队协作中共享代码,seed 不设固定,别人跑出来的结果和你不同,很难判断是代码问题还是随机性问题。

3.2 从离散分布验证期望

先从一个简单的离散分布开始,比如取值 1、2、3,概率分别是 0.2、0.3、0.5。这是概率质量函数最直接的例子,我们可以用 numpy 手写采样,计算不同采样数量下的样本均值。

values = np.array([1, 2, 3]) probs = np.array([0.2, 0.3, 0.5]) true_expectation = np.sum(values * probs) print(f"理论期望: {true_expectation:.4f}") sample_sizes = [10, 100, 1000, 10000, 100000] means = [] for size in sample_sizes: samples = np.random.choice(values, size=size, p=probs) means.append(np.mean(samples)) for size, mean in zip(sample_sizes, means): print(f"采样数量 {size:6d}: 样本均值 {mean:.4f}")

跑完这个实验你会发现,随着采样数量增大,样本均值越来越靠近理论期望 2.3。这个过程就是大数定律在起作用。我当时做这个实验时最大的感受是:期望不是“算出来”的,而是在极限意义下“逼近”出来的。实际训练模型时,我们每次迭代只用一个 batch 来估算期望,本质上就是用有限样本近似极限值,所以 loss 曲线波动是正常的,不需要惊慌。

3.3 考察高斯分布的方差估计

对连续型变量,我们用高斯分布做同样的事。这一次观察无偏方差和有偏方差的区别,这个区别在统计里讲究,但在深度学习中也很关键——因为很多损失函数的正则化项其实就是对参数分布的方差做了某种约束。

mu, sigma = 2.0, 3.0 true_variance = sigma ** 2 sample_sizes = [10, 100, 1000, 10000] for size in sample_sizes: samples = np.random.normal(mu, sigma, size=size) sample_var_pop = np.mean((samples - np.mean(samples)) ** 2) # 有偏 sample_var_unbiased = np.var(samples, ddof=1) # 无偏 print(f"采样数量 {size:6d}: 有偏方差 {sample_var_pop:.4f}, 无偏方差 {sample_var_unbiased:.4f}, 理论方差 {true_variance:.4f}")

书里的公式是定义式,但在实际计算中,样本方差是否除以 n-1 会直接影响你对模型预测不确定性的估计。比如在评估集成模型的方差时,我调试过几次发现直接调用 NumPy 的 var 默认是有偏估计,而论文里如果提到“empirical variance”可能用的是另一种定义,对不上就很麻烦。搞懂这个区别,你就拥有了阅读文献公式的第一层解读能力。

3.4 可视化独立同分布的作用

最后一个实验是视觉化的:从同一个分布中采样两组独立样本,平均后计算它们的差异。这可以直观感受到独立采样的价值——如果采样不独立(比如每次在前一次基础上做微小扰动),那么估计的方差会显著不同,这其实就牵扯到自相关和有效样本量问题,在 MCMC 采样方法中是大坑。

def estimate_mean_via_samples(corr_strength=0.0, n_samples=10000): samples = [] prev = np.random.randn() for _ in range(n_samples): if corr_strength == 0: s = np.random.randn() else: s = corr_strength * prev + np.sqrt(1 - corr_strength ** 2) * np.random.randn() samples.append(s) prev = s return np.std(np.mean(samples) for _ in range(10)) # 简化示意运行多次会慢,仅示意

严格来说这个简化代码的效率不高——重复采样生成列表会慢,真实分析时我会改用数组一次性生成。但思路是清楚的:当采样之间存在正相关时,有效样本量变小,均值估计的波动变大。书里讲 i.i.d. 假设时只是数学描述,这里你亲手看到相关性对估计误差的影响,才能理解为什么时间序列建模比独立数据建模难这么多。后面在讲 RNN 或自回归模型的章节里,这个直觉会反复派上用场。

4. 读完这节必须搞懂的三个实操道理

4.1 损失函数是负对数似然的变装

这一节另一个重要铺垫是概率与优化的连接。极大似然估计的出发点,是寻找让观测数据概率最大的模型参数。在连续情形下,计算所有样本概率的乘积会下溢(书中这里提到下溢出问题,是奠基性的工程观察),因此转换为对数求和。而深度学习中大量使用的交叉熵损失,本质上就是在类别分布假设下最大化对数似然的等价形式。

我经常看到初学者在回归任务中纠结“为什么用均方误差、不用平均绝对误差”。如果你从本章的视角看就很简单:均方误差对应高斯噪声假设下的负对数似然,平均绝对误差对应拉普拉斯噪声假设下的负对数似然。两种假设对离群值的容忍度不同,所以并不是 MES 更好或者 MAE 更好,而是取决于你对数据噪声分布的先验判断。这个认知一旦建立,你在设计自定义损失函数时思路会清晰很多。

4.2 常用分布不只是一个公式表

书中这一节会给出伯努利分布、高斯分布等常见分布的表达式。很多读者扫过去就完了,但实操中你应该为每个常见分布记住三件事:它描述什么类型的变量、它的参数控制什么形态、它的期望和方差表达式是什么。伯努利分布对应二分类输出,高斯分布对应连续值回归输出,categorical 分布对应多分类输出。这三组对应关系是你在搭模型时最常用的分布——输出层激活函数的选择,直接由这些分布假设决定。

比如二分类输出的最后一层用 sigmoid,是因为 sigmoid 输出值可以解释为伯努利分布的参数 p;多分类用 softmax,是因为输出向量可以看成 categorical 分布的概率向量。这个联系如果不读概率章节,就容易把激活函数当成纯函数来记,遇到新任务不知道选哪种激活,只能到处试。我遇到过不止一次这样的情况:有人问为什么回归不能直接用 softmax 输出,答案就是把分布假设和输出结构联系起来——回归的目标是一个连续变量,而 softmax 是给离散类别设计的概率分布,连续变量的输出得用带位置和尺度参数的分布来处理。

4.3 边际概率与条件概率是模型设计的分水岭

最后一点是条件概率的视角。监督学习本质上在拟合 P(y|x),生成模型在拟合 P(x),贝叶斯推断要处理 P(θ|x, y)。书中定义的乘法规则和求和规则是贯穿深度学习的两个最基础运算工具。条件概率和联合概率的转换关系,在实际代码里体现在数据生成流程上——比如文本生成模型的每个时间步都在建模给定上文条件下的下一个词分布,这就是一个典型的链式条件概率分解。

看懂条件概率的分解,你就会明白 attention 机制里的 Query 和 Key 在做的事本质上也是条件加权;理解贝叶斯公式的变形,你才能读懂变分自编码器的 ELBO 推导。很多高阶论文啃不动,不是因为后续涉及的知识太深,而是概率基础中的条件概率分解不够熟。这一节就是补这个短板的。

5. 常见问题与避坑实录

5.1 随机变量的符号会混淆怎么办

P(X=x) 这种写法把随机变量和取值混在一个式子里,初读容易绕晕。我的习惯是先把随机变量看成对应某个分布的“名字”,把小写的 x 看成具体的数值。等看到期望公式 E[f(X)],理解为对一个分布下的所有输出进行加权平均,符号的障碍就会迅速消失。书里的公式推导,大多数不是要算出具体数字,而是让你理解变换的逻辑,所以符号上不必过于纠结。

5.2 连续型概率密度大于1是不是写错了

许多读者第一次看到 PDF 值大于1会懵。我在讲这个问题时最常用的类比是:密度的概念就像地球的人口密度——一个城市每平方公里可能有数千人,单位面积上的人数可以很大,但你在某些地区调查时,真正随机落到某一平方米的“概率”极小。PDF 在某个点的值等于“概率集中程度”,不是概率本身。如果你用 PDF 的值去类比概率,当然会觉得大于1不合理。

实操中出现这个误解的典型场景是 outlier detection——不少人直接用 PDF 的绝对数值来判断异常,结果在高密度区域某些值算出来很大、低密度区域的也很“合理”,最后阈值没法定。正确做法是看相对密度或者用累积分布函数区间概率。这个坑我在做异常检测实验时栽过,花了一下午才发现不是模型问题,是我对 PDF 的理解有偏差。

5.3 期望和均值是不是完全等价

从定义上,期望是概率加权平均,均值是等权平均。只有当分布是均匀分布时,两者才一致。当数据分布不均匀时,经验均值是期望的良好估计,但经验均值本身也是一个随机变量。很多人在分析训练集和测试集差异时,错把“均值相同”当成“分布相同”,但均值相同的时候方差、偏度、相关性可能完全不同。书中这一节紧接着引入方差就是为了补足这个缺陷——用期望和方差一起去刻画分布特征。判断数据分布是否变化,至少要同时比较均值、方差和高阶矩,只看均值的对比在实际业务中是极度危险的操作。

我在做数据漂移检测时踩过一个很经典的坑:某模型监控指标显示预测均值稳定,但模型效果明显下滑,后来分析发现是因为feature的方差发生了显著变化,均值却被两头平均了。这就是不动手做实验、光看教科书会觉得“均值变了才叫漂移”的误区。

5.4 信息论部分为什么放在概率章节

这个标题的疑问很多人有。其实你在读完第一节之后再看整章的目录结构就清楚了:概率分布定义清楚之后,信息论研究的是“一个事件携带多少信息”的问题,而信息量就是概率的函数。低概率事件携带高信息量,高概率事件信息量低。这个转换把概率和不确定性量化了起来,为后面整个深度学习中的损失函数设计、正则化、KL散度、交叉熵提供了统一的语言。

读这一节时如果没有建立这个从概率到信息量的桥梁,后面读信息熵时会感觉突兀。实际上这里已经在为交叉熵做铺垫了——分类问题的交叉熵损失,从信息论视角看就是真实分布与预测分布之间的平均编码代价差。这条逻辑链一旦打通,你会觉得整个第三章是一体的。

5.5 要不要把课后题全部做一遍

个人建议是不要上来刷全部习题,但一定要做两类:一类是验证定义的(比如推导高斯分布的归一化条件),另一类是设计分布的采样代码实验。定义验证能逼你把符号搞清楚,代码实验能逼你把公式变成直觉。我当时只挑了这两类题做,但在后面读生成模型章节时,发现这些基础带来的收益远超付出的时间。书读得越往后,对概率的调用越频繁,前面基础打得越早,后面摸索的时间越短。

6. 把这本书当工具书用,而不是教材啃

最后想说的是读这本书的心法。很多人在读深度学习的经典教材时有一个共同的误区,就是试图从第一个字到最后一个字全部精读,看不懂就卡住,结果长时间停留在前几章。我的习惯是把这章的内容当成“查漏补缺的工具”——首次通读时保证理解概率分布的描述方式和期望、方差的定义就足够了,剩下的细节等需要用的场景出现时再回来看。

经验之谈,我每次重读这一节,都会因为当前在做的方向不同而注意到不同的点。第一次做分类任务时注意力全在 categorical 分布上,后来做回归任务时才发现高斯分布的重要性,再后来研究生成模型时才真正理解 log 变换和边际化是怎么回事。阅读经典跟使用开源代码一样,不用一次性吃透全部,而是要按需深入,带着问题反复阅读,效果比一口气硬啃好得多。

这一节内容虽然短,但是整个第三章的支点。概率语言你早就是熟悉的,但它作为工具在深度学习里如何起承转合,却是很多人长期没想明白的。希望这篇笔记能帮你把“看懂了”变成“会用”,在读后面的模型推导时少一点阻涩,多一分从容。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进