首页 / 模块 2 · 概率统计、信息论与最优化 / 第 4 课(共 10 课)

从数据到损失——MLE 与 MAP

从零到前沿 ML 自学课程 · 阶段0:数学与工具基础 · 能力点:MLE/MAP——把"数据怎么生成"翻译成"该最小化什么损失"(本模块枢纽)

上一课我们建立了贝叶斯三件套:先验(动手前对参数的信念)、似然(参数对数据的解释力)、后验(看完数据后更新的信念)。这一课我们把它们起来,回答一个训练神经网络时天天遇到、却很少被讲清的问题:损失函数到底是从哪儿冒出来的?为什么回归用 MSE、分类用交叉熵,而不是别的式子?答案出奇地干净——你只要写下"数据是怎么生成的"这一个假设,损失函数就被唯一地推导出来了,不是凑的。

读完这一课,你将能够

  • 把"数据生成假设"翻译成似然函数,再用"取对数 + 加负号"机械地得到对应的损失函数(NLL)。
  • 亲手推出:高斯噪声假设 → MSE;伯努利/类别假设 → 交叉熵
  • 解释 MAP 与 MLE 的区别,并把 L2 正则 = 高斯先验L1 正则 = 拉普拉斯先验 这件事讲给别人听,包括 L1 为什么会"逼出 0"。
  • 说清小样本下 MLE 为什么会"自信地犯错"(某类计数为 0),以及拉普拉斯平滑如何补救。
  • 用 numpy 验证 \(\hat p=k/n\)、\(\hat\mu=\) 样本均值,以及"MLE 闭式解 = 最小二乘正规方程解"。

一、似然:把"参数"当成"对数据的解释力"

先建立一个最基本的视角转换。在贝叶斯那一课,\(p(x\mid\theta)\) 我们读作"给定参数 \(\theta\),数据 \(x\) 的取值情况"——这时 \(x\) 是变量,\(\theta\) 固定。现在反过来:数据 \(x\) 已经摆在桌上(已经观测到了,是常数),我们让 \(\theta\) 变化,问"哪个 \(\theta\) 让这批数据显得最不意外?"

同一个表达式 \(p(x\mid\theta)\),盯着 \(x\) 看叫概率(密度)(probability / density),盯着 \(\theta\) 看叫似然(likelihood)。似然不是 \(\theta\) 的概率分布(它对 \(\theta\) 积分不一定等于 1),它衡量的是"这个参数把已观测数据解释得多好"。一句话:似然是参数的"考试成绩",数据是考卷。

真正让似然好用的,是一个朴素到容易被忽略的建模假设——i.i.d.(独立同分布,independent and identically distributed):我们假设 \(n\) 个样本 \(x_1,\dots,x_n\) 是从同一个分布里各自独立抽出来的。独立 ⇒ 联合概率等于各自概率连乘;同分布 ⇒ 每个 \(p\) 用同一个 \(\theta\)。于是整批数据的似然就是一长串乘积:

\[ L(\theta)\;=\;p(x_1,\dots,x_n\mid\theta)\;\overset{\text{i.i.d.}}{=}\;\prod_{i=1}^{n} p(x_i\mid\theta). \]

把它当成 \(\theta\) 的函数画出来,通常是一条有单峰的曲线:某个 \(\theta\) 处似然最大,那就是最能解释数据的参数。

似然函数单峰曲线,峰顶即最大似然估计 MLEθ参数L(θ)似然峰顶 = 最大似然θ*MLE哪个参数让这批数据最不意外?峰顶就是答案。
似然函数曲线:横轴是参数 θ,纵轴是似然 L(θ)。曲线呈单峰,峰顶用圆点标出,并向横轴投下虚线指向 θ*(MLE)。直观传达"MLE = 站到似然曲线的峰顶"。

二、MLE:站到似然曲线的峰顶

最大似然估计(Maximum Likelihood Estimation, MLE)就是字面意思——挑出让似然最大的那个参数:

\[ \theta^{*}\;=\;\arg\max_{\theta}\;L(\theta)\;=\;\arg\max_{\theta}\;\prod_{i=1}^{n} p(x_i\mid\theta). \]

但这个连乘很难直接优化:成百上千个介于 0 和 1 之间的小数相乘,结果会小到计算机直接下溢成 0(比如 \(0.1^{400}\) 在浮点里就是 0,连数值本身都存不下来,更别说在它上面做优化)。解决办法是取对数

这里说的"下溢"指似然数值本身归零,和后面深层网络里"梯度消失"(vanishing gradient,反向传播时梯度逐层变小)是两件不同的事,别被它们都带"消失"色彩的描述混淆——一个是数值表示问题,一个是优化信号问题。

为什么取对数是"免费的好处"

对数 \(\ln\) 有两个性质,恰好治好连乘的所有毛病:

取 log 前后对比:原始似然几乎被压平易下溢,对数似然舒展且峰位置不变θ*θ*原始似然 L(θ)=∏p1e-3000L(θ)θ微弱尖峰数值极小,易下溢对数似然 ln L(θ)=∑ ln p-50-120-200ln L(θ)θ峰清晰舒展的下凹曲线取 log:连乘→连加、避免下溢、峰位置不变(θ* 相同)。
取 log 前后对比:左图是原始似然(连乘),纵轴数值极小(贴近 0、几乎被压平到看不出峰,标注"易下溢");右图是对数似然,曲线舒展、峰清晰。两图峰的横坐标 θ* 用同一条竖直虚线对齐,强调"log 不改变峰的位置,只让它更好优化"。

于是定义对数似然 \(\ell(\theta)=\ln L(\theta)=\sum_i\ln p(x_i\mid\theta)\)。优化里习惯"最小化"而非"最大化",再加个负号,得到本课的主角——负对数似然(Negative Log-Likelihood, NLL):

\[ \boxed{\;\mathrm{NLL}(\theta)\;=\;-\sum_{i=1}^{n}\ln p(x_i\mid\theta)\;} \qquad\Longrightarrow\qquad \theta^{*}=\arg\min_{\theta}\;\mathrm{NLL}(\theta). \]

关键结论:最大化似然 ⟺ 最小化负对数似然。NLL 就是损失函数的本体。你平时写的 loss,几乎都是某个数据生成假设下的 NLL。接下来两节,我们换两种 \(p(x_i\mid\theta)\) 的假设,分别"变"出 MSE 和交叉熵。

为什么对数和 \(\exp\) 这么搭?很多常见分布(高斯、伯努利、泊松……)的密度都能写成 \(p(x)\propto \exp(\text{某个关于 }\theta\text{ 的式子})\) 这一类形状。取 \(\ln\) 正好把 \(\exp\) 抵消,指数里的东西变成了关于参数的简单(常是二次或线性)函数——优化瞬间变容易。这不是巧合,是对数和指数互为反函数的红利。(这一大类分布有个正式名字,下一阶段再正式学,这里不必记。)

三、高斯噪声假设 → MSE(最小二乘)

现在做一个回归任务。假设标签由某个函数 \(f(x)\)(比如线性模型 \(f(x)=w^\top x\))加上高斯噪声生成:

\[ y_i\;\sim\;\mathcal{N}\!\big(f(x_i),\,\sigma^2\big) \qquad\Longleftrightarrow\qquad p(y_i\mid x_i,\theta)=\frac{1}{\sqrt{2\pi\sigma^2}}\exp\!\left(-\frac{(y_i-f(x_i))^2}{2\sigma^2}\right). \]

这里有个该说清的细节:密度不是概率。前面伯努利/类别那种离散标签里,\(p(y\mid\theta)\) 是货真价实的概率(取值在 0 和 1 之间)。但这里 \(y\) 是连续的,\(p(y_i\mid x_i,\theta)\) 是概率密度(PDF):它有量纲、数值可以大于 1,而且任何单个连续观测点的概率严格等于 0。似然在连续情形下比较的不是"概率高低",而是"密度值高低"——哪个 \(\theta\) 让观测点落在密度更高的地方。顺带一提,这也正是下面 MSE 能把 \(1/\sqrt{2\pi\sigma^2}\) 这种纯归一化因子丢掉的原因:它只是把密度积分归一的常数,不影响哪个 \(\theta\) 让密度更高。

这句假设的现实含义是:模型的预测 \(f(x_i)\) 是"真值",实际观测在它周围呈钟形抖动,离得越远越罕见。把它代进 NLL(先只看权重 \(\theta\) 这个参数,把 \(\sigma\) 当成已知常数;为什么能这样,下面立刻交代):

\[ \mathrm{NLL}(\theta)=-\sum_i\ln p(y_i\mid x_i,\theta) =\sum_i\left[\frac{(y_i-f(x_i))^2}{2\sigma^2}+\underbrace{\tfrac12\ln(2\pi\sigma^2)}_{\text{与}\,\theta\,\text{无关,常数}}\right]. \]

常数项不影响 \(\arg\min\),\(1/(2\sigma^2)\) 是正的缩放因子也不影响最优 \(\theta\) 的位置,全部丢掉:

\[ \boxed{\;\theta^{*}=\arg\min_{\theta}\sum_{i=1}^{n}\big(y_i-f(x_i)\big)^2\;} \]

"为什么能把 \(\sigma\) 当常数丢掉?"高斯其实有两个参数:均值侧的 \(\theta\)(即 \(\mu\) 或权重 \(w\))和噪声方差 \(\sigma^2\)。关键事实是:对 \(\theta\) 求 \(\arg\min\) 时,\(\sigma\) 只以"正缩放因子 + 加常数"的形式出现,不影响 \(\theta\) 的最优位置——所以求 \(w\) 时可以把它当常数。\(\sigma\) 自己当然也能估,它的 MLE 就是样本残差的方差 \(\hat\sigma^2=\frac1n\sum_i(y_i-f(x_i))^2\)(解出 \(\hat\theta\) 后回代即可,先解 \(\theta\) 不依赖 \(\sigma\))。本课主线只关心 \(\theta\),\(\sigma\) 的细节放进文末 skip。

高斯噪声假设直接给出 MSE。你每次用均方误差,背后都在悄悄假设"标签噪声是高斯的、方差恒定的"。MSE 不是天经地义的"距离",它是一个具体概率假设的产物。

例题:高斯 MLE 的 \(\hat\mu\) 就是样本均值

取最简单的 \(f(x)\equiv\mu\)(常数模型,无输入),即 \(y_i\sim\mathcal{N}(\mu,\sigma^2)\)。NLL 去掉常数后要最小化 \(g(\mu)=\sum_i(y_i-\mu)^2\)。求导置零:

\[ g'(\mu)=\sum_i 2(y_i-\mu)(-1)=-2\sum_i(y_i-\mu)=0 \;\Longrightarrow\;\sum_i y_i=n\mu \;\Longrightarrow\;\boxed{\hat\mu=\tfrac1n\sum_i y_i.} \]

"高斯 MLE 的均值 = 样本均值",并且这等价于最小化 \(\sum(y-\mu)^2\)——这就是 MSE 在一维上的样子。二阶导 \(g''=2n>0\),确认是极小值。

ML 和 ML 的联系

把 \(f(x_i)=w^\top x_i\) 代入,最小化 \(\sum_i(y_i-w^\top x_i)^2\) 就是线性回归。对 \(w\) 求导置零得到正规方程 \(X^\top X\,w=X^\top y\)(你在模块1 矩阵求导那课推过 \(\nabla_w\|y-Xw\|^2=-2X^\top(y-Xw)\))。所以"最小二乘的闭式解"和"高斯线性模型的 MLE"是同一个解——本课代码会让它们逐位对齐。

四、伯努利 / 类别假设 → 交叉熵

换成二分类。每个标签 \(y_i\in\{0,1\}\),模型吐出"预测为 1 的概率" \(\hat y_i=\hat y_i(\theta)\in(0,1)\)。这等于假设 \(y_i\) 服从伯努利分布 \(\mathrm{Bernoulli}(\hat y_i)\)(这里 \(y\) 离散,\(p\) 是真概率,不是密度)。伯努利的概率可以写成一个紧凑的式子(指数当开关):

\[ p(y_i\mid\theta)=\hat y_i^{\,y_i}\,(1-\hat y_i)^{\,1-y_i} =\begin{cases}\hat y_i,& y_i=1\\[2pt] 1-\hat y_i,& y_i=0.\end{cases} \]

取负对数并对样本求和:

\[ \mathrm{NLL}=-\sum_i\Big[y_i\ln\hat y_i+(1-y_i)\ln(1-\hat y_i)\Big]. \]

这正是二元交叉熵(binary cross-entropy)。推广到 \(K\) 类(Categorical 分布),把真实标签写成 one-hot 向量 \(y_i\)(只有正确类是 1),预测为概率向量 \(\hat y_i\),得到逐点交叉熵

\[ \boxed{\;\mathrm{NLL}=-\sum_i\sum_{c=1}^{K} y_{i,c}\,\ln\hat y_{i,c}\;=\;-\sum_i\ln\hat y_{i,\text{正确类}}\;} \]

因为 \(y_i\) 是 one-hot,内层求和只剩"正确那一类的预测概率的对数"这一项。所以分类的交叉熵损失 = −ln(模型给正确答案的概率):模型对正确答案越自信,loss 越小;给正确答案分配的概率趋于 0 时,loss 趋于 \(+\infty\)(被狠狠惩罚)。下一课会用信息论给"交叉熵"这个名字一个更深的解释。

例题:伯努利 MLE 推出 \(\hat p=\) 正例比例

抛硬币 \(n\) 次,正面 \(k\) 次(每次 \(\mathrm{Bernoulli}(p)\),没有输入特征,模型就是单个参数 \(p\))。对数似然为

\[ \ell(p)=\sum_i\big[y_i\ln p+(1-y_i)\ln(1-p)\big]=k\ln p+(n-k)\ln(1-p). \]

求导置零:

\[ \ell'(p)=\frac{k}{p}-\frac{n-k}{1-p}=0 \;\Longrightarrow\;k(1-p)=(n-k)p \;\Longrightarrow\;\boxed{\hat p=\frac{k}{n}.} \]

最大似然给出的最优 \(p\) 就是样本里正面的比例——和直觉完全一致。注意这和上面高斯例题的结构一模一样:写似然 → 取对数 → 求导置零 → 得到一个"样本统计量"。MLE 的套路是统一的。

五、MAP:给似然配上先验

MLE 只听数据的,这在数据少时很危险。极端例子:投 3 次硬币全是正面,MLE 笃定地宣布 \(\hat p=3/3=1\)("这枚硬币永远不会出反面")。这显然过拟合了——它把"恰好没观测到"当成了"不可能"。我们需要把"先验信念"(硬币大概接近公平)加回来。

这就是上一课的后验似然 × 先验最大后验估计(Maximum A Posteriori, MAP)取的是后验的峰,而不是似然的峰:

\[ \theta_{\mathrm{MAP}}=\arg\max_{\theta}\;\underbrace{p(\theta\mid \text{data})}_{\text{后验}} =\arg\max_{\theta}\;\underbrace{p(\text{data}\mid\theta)}_{\text{似然}}\,\underbrace{p(\theta)}_{\text{先验}}. \]

分母 \(p(\text{data})\) 不含 \(\theta\),求 \(\arg\max\) 时可丢弃。照例取对数把乘积拆成加法:

\[ \boxed{\;\theta_{\mathrm{MAP}}=\arg\max_{\theta}\;\big[\,\underbrace{\ln L(\theta)}_{\text{数据项}}+\underbrace{\ln p(\theta)}_{\text{先验项}}\,\big] =\arg\min_{\theta}\;\big[\,\mathrm{NLL}(\theta)-\ln p(\theta)\,\big].\;} \]

看右边这个式子:它就是 "原损失 + 一个只跟参数有关的额外项"。先验把后验的峰从似然峰往先验中心了一点——数据越少,似然越"软",先验拉得越动;数据越多,似然越尖,先验几乎拉不动(数据淹没先验)。这正是我们想要的行为。

把"3 投全正"的悬念闭环

回到开头那枚硬币:\(n=3\)、\(k=3\)。给 \(p\) 配一个温和的对称先验("事先各假装看到 1 正 1 反",即 Beta(1,1) 加 add-one 平滑),MAP 解是

\[ \hat p_{\mathrm{MAP}}=\frac{k+1}{n+2}=\frac{3+1}{3+2}=\frac{4}{5}=0.8. \]

于是先验把 MLE 的"硬 1"拉回到了合理的 0.8——既承认"目前都是正面",又拒绝断言"反面绝不可能"。记住这个动作:第七节会看到同一个先验把另一头的"硬 0"也抬离零点。先验做的事前后呼应:既不让概率冲到 1,也不让它塌到 0。

MAP = 似然 × 先验:先验把后验峰从似然峰往中心拉MAP = 似然 × 先验θ密度中心(0/公平)先验把后验峰往中心拉prior 先验(宽,峰在中央)likelihood 似然(窄,峰偏右)posterior 后验(落在两者之间)数据越少似然越胖,先验拉得越动;数据越多似然越尖,先验几乎拉不动。
MAP = 似然 × 先验:同一张图画三条曲线——似然(峰在数据偏好处,偏右)、先验(峰在中心,较宽,体现"权重应靠近 0/公平"的信念)、后验(峰被先验从似然峰往中心拉,落在两者之间)。三个峰用竖直虚线标出,箭头从似然峰指向后验峰,标注"先验把峰往中间拉"。

六、先验 = 正则项:把"权重衰减"看穿

现在揭开一个让很多人恍然大悟的等价关系。回到高斯线性回归,给权重 \(w\) 加一个零均值高斯先验 \(w_j\sim\mathcal{N}(0,\tau^2)\),意思是"我事先相信权重应该小、应该靠近 0"。它的负对数为

\[ -\ln p(w)=\sum_j\frac{w_j^2}{2\tau^2}+\text{const}=\frac{1}{2\tau^2}\|w\|_2^2+\text{const}. \]

代入 MAP 目标(NLL 是高斯的 \(\tfrac{1}{2\sigma^2}\sum(y_i-w^\top x_i)^2\)),整理出

\[ \theta_{\mathrm{MAP}}=\arg\min_{w}\;\sum_i(y_i-w^\top x_i)^2+\lambda\|w\|_2^2, \qquad \lambda=\frac{\sigma^2}{\tau^2}. \]

加 L2 正则(权重衰减 / Ridge / weight decay)= 假设权重服从零均值高斯先验。正则强度 \(\lambda\) 就是"噪声方差 / 先验方差"之比:先验越强(\(\tau\) 越小,越坚信权重该小)⇒ \(\lambda\) 越大 ⇒ 那个把权重往 0 拉的"二次碗"越陡。

高斯先验等价于 L2 正则:先验越强(τ 越小,λ 越大),二次惩罚碗越陡,权重被压得越靠近 0高斯先验 = L2 正则:碗底在 w=0wλ·w²0碗底(先验把 w 往这里拉)同一 w,惩罚差弱先验:λ 小,τ 大(碗浅而宽)强先验:λ 大,τ 小(碗陡而窄)零均值高斯先验 w∼N(0, τ²) 的负对数 = (1/2τ²)‖w‖²,正是 L2 正则。先验越强(τ 越小 → λ 越大)碗越陡,权重被压得越靠近 0;λ = σ²/τ²。
高斯先验 = L2 正则:以权重 w 为横轴、正则项 λ‖w‖² 为纵轴画一个二次"碗",碗底在 w=0(先验把权重往 0 拉)。叠画两条碗:先验弱(λ 小,碗浅而宽)与先验强(λ 大,碗陡而窄),标注"先验越强(τ 越小,λ 越大)碗越陡,权重被压得越靠近 0"。

换个先验就换个正则。拉普拉斯先验 \(p(w_j)\propto\exp(-|w_j|/b)\)(形状是0 处一个尖顶、两侧重尾)的负对数是 \(\frac1b\sum_j|w_j|\),于是

\[ \text{拉普拉斯先验}\;\Longrightarrow\;\lambda\|w\|_1\;=\;\textbf{L1 正则(Lasso)}. \]

为什么 L1 会"逼出 0"(稀疏),L2 只会"压小"?看惩罚项在 \(w_j\) 接近 0 时的梯度
· L2 的惩罚是 \(w_j^2\),梯度 \(2w_j\) 在 \(w_j\to 0\) 时自己也趋于 0——越靠近 0,往 0 推的力气越小,所以只能把权重压得很小却不会真正归零
· L1 的惩罚是 \(|w_j|\),梯度是 \(\pm1\)(绝对值在 0 处尖、不可导),大小不随 \(w_j\) 减小而衰减——只要这个权重对拟合的贡献撑不过这股恒定的"往 0 推"的力,它就会被推到正好等于 0
几何上:拉普拉斯先验的尖顶把最优点"钉"在坐标轴上,于是一堆不重要的权重直接变成 0,得到稀疏解。这就是 L1 做特征选择的来历。

高斯先验对应 L2 正则、拉普拉斯先验在 0 处尖角对应 L1 稀疏0w先验密度尖角 (cusp)稀疏的来源圆顶高斯先验 ∝ exp(−w²/2)L2 正则:平滑收缩,少为 0拉普拉斯先验 ∝ exp(−|w|)L1 正则:尖峰鼓励恰好为 0
拉普拉斯先验(L1,0 处尖角 → 鼓励权重恰好为 0、稀疏)vs 高斯先验(L2,圆顶 → 把权重平滑往 0 收缩)
数据生成 / 先验假设等价的损失 / 正则
高斯噪声 \(y\sim\mathcal N(f(x),\sigma^2)\)MSE / 最小二乘
伯努利 / Categorical交叉熵
权重零均值高斯先验L2 正则(权重衰减)
权重拉普拉斯先验L1 正则(稀疏)

ML 和 ML 的联系

这张表是深度学习损失函数的"户口本":你在 PyTorch 里写的 MSELossCrossEntropyLossweight_decay,没有一个是凭空规定的,全都是"某个生成假设/先验"下的 MAP 目标。理解了这层,你以后看到新损失(如泊松回归的 loss、带 L1 的稀疏模型)就能反推它在假设什么——这是设计损失函数的钥匙。

七、小样本的陷阱与拉普拉斯平滑

MLE 在小样本下会"自信地犯错"。设想用词频估计一个 3 类分布,观测计数为 \([8,0,2]\):第 2 类恰好没出现。MLE 给出概率 \([0.8,\,0,\,0.2]\)——它断言第 2 类概率为 0,永远不可能出现。一旦测试集真的来了一个第 2 类样本,交叉熵 \(-\ln 0=+\infty\),模型彻底崩溃。

救法就是 MAP:给类别分布配一个对称的狄利克雷先验(相当于"假装每类先各看到 \(\alpha\) 个样本"),MAP 解变成

\[ \hat p_c=\frac{n_c+\alpha}{N+\alpha K},\qquad K=\text{类别数}. \]

这就是拉普拉斯平滑(Laplace / add-one smoothing,\(\alpha=1\))。对上面的例子:\([8,0,2]\to[\tfrac{9}{13},\tfrac{1}{13},\tfrac{3}{13}]\approx[0.69,0.08,0.23]\)——那个危险的 0 被先验抬离了零点,模型不再"把没见过当成不可能"。注意这和第五节"3 投全正→拉回 0.8"是同一件事的两面:先验既不让概率冲到 1,也不让它塌到 0。

易错点:(1) 对数似然不是似然——只在比较 \(\arg\max\) 时能随意丢常数/正缩放因子;如果你要的是似然本身的数值(如做模型比较算证据),就不能乱丢。(2) MAP 给的是后验的众数(峰),不是后验均值,二者在偏斜分布下不同(完整贝叶斯要对后验积分,那是更贵的事)。(3) MLE/MAP 都依赖 i.i.d. 假设——数据有时间相关、有分布漂移时,直接套连乘的似然是错的。

调一调,观察现象

下面每个小实验都只改一个量,先猜结果,再运行验证。所有代码只用 numpy + print,几秒跑完。

调一调①:样本量如何"锁定"似然峰

改什么:把伯努利样本量 n 从 20 调到 2000(真值 0.3)。预期现象:对数似然曲线的峰会越来越尖——用 seed=0 实跑,峰宽(格数)大致是 29 → 9 → 3,也就是对参数的不确定性越来越小。峰的位置则始终等于 k/n,并在真值 0.3 附近抖动、抖动幅度随 n 减小:小 n 时受抽样波动影响可能偏离 0.3(方向随机,本种子下 n=20 给约 0.35),单次随机不保证逐 n 单调逼近,但 n 越大估计越可靠。为什么:样本越多,似然对参数越"挑剔",等价于后验越集中、先验越来越拉不动它。

import numpy as np
rng = np.random.default_rng(0)
for n in [20, 200, 2000]:
    data = (rng.random(n) < 0.3).astype(float)
    p = np.linspace(0.01, 0.99, 99)
    ll = np.array([(data*np.log(pi)+(1-data)*np.log(1-pi)).sum() for pi in p])
    pk = p[ll.argmax()]
    # 用"峰附近高出 1 个单位的宽度"粗略量峰的尖锐度(越小越尖、越确定)
    width = (ll >= ll.max()-1.0).sum()
    print(f"n={n:5d}  argmax p={pk:.3f}  k/n={data.mean():.3f}  峰宽(格数)={width}")

调一调②:正则强度 λ 就是"先验有多强"

改什么:把岭回归里的 lam 从 0 增大到 100。预期现象:\(\lambda=0\) 时解就是普通最小二乘解;\(\lambda\) 越大,权重范数 \(\|w\|\) 越小、越被压向 0(本种子下 \(\|w\|\) 单调下降,约 0.92 → 0.90 → 0.73 → 0.30)。为什么:\(\lambda=\sigma^2/\tau^2\),调大 \(\lambda\) 等于把高斯先验调窄(\(\tau\) 变小),先验把权重往 0 拉得更狠。

import numpy as np
rng = np.random.default_rng(1)
N, d = 60, 5
X = rng.normal(size=(N, d)); w_true = rng.normal(size=d)
y = X @ w_true + rng.normal(0, 0.5, size=N)
for lam in [0.0, 1.0, 10.0, 100.0]:
    w = np.linalg.solve(X.T@X + lam*np.eye(d), X.T@y)
    print(f"lam={lam:6.1f}  ||w||={np.linalg.norm(w):.3f}")

调一调③:零计数如何让交叉熵爆炸,平滑如何救场

改什么:对比 MLE 概率与拉普拉斯平滑概率在"遇到未见类别"时的交叉熵。预期现象:MLE 对第 2 类给 0 概率,一旦测试样本属于第 2 类,-log(0)=inf;平滑后给出有限的、合理的损失(这里 \(-\ln(1/13)\approx2.565\))。为什么:先验把概率从硬 0 抬起来,避免了"把没见过当成不可能"。

import numpy as np
counts = np.array([8, 0, 2]); K = len(counts); N = counts.sum()
p_mle = counts / N
p_smooth = (counts + 1) / (N + K)          # 拉普拉斯平滑 alpha=1
print("MLE   :", np.round(p_mle, 3))
print("smooth:", np.round(p_smooth, 3))
# 测试样本恰好属于第 2 类(索引1)
with np.errstate(divide='ignore'):
    print("CE(MLE, 第2类)   =", -np.log(p_mle[1]))     # inf
print("CE(smooth, 第2类)=", round(-np.log(p_smooth[1]), 3))

动手练习

  1. 网格验证伯努利 MLE。合成 n=300 的伯努利数据(真值 0.3),在 0.01–0.99 上扫描对数似然,print 出网格 argmax 与 k/n,确认两者一致(到网格精度)。
    import numpy as np
    rng = np.random.default_rng(0)
    data = (rng.random(300) < 0.3).astype(float)
    p = np.linspace(0.01, 0.99, 99)
    ll = np.array([(data*np.log(pi)+(1-data)*np.log(1-pi)).sum() for pi in p])
    print("grid argmax =", round(p[ll.argmax()],3), "  k/n =", round(data.mean(),3))
    
  2. 验证高斯 MLE \(\hat\mu=\) 样本均值。合成 n=300 的 \(\mathcal N(\mu=2,\sigma^2)\) 数据,在 \(\mu\) 网格上扫描对数似然,确认网格 argmax 与 data.mean() 一致(到网格精度)。这就是 goals 里承诺的"\(\hat\mu=\) 样本均值"的可跑验证。
    import numpy as np
    rng = np.random.default_rng(7)
    data = rng.normal(2.0, 1.0, size=300)
    mu = np.linspace(0.0, 4.0, 401)
    # 高斯对数似然去掉与 mu 无关的常数后 ∝ -Σ(y-mu)^2
    ll = np.array([-((data - m)**2).sum() for m in mu])
    print("grid argmax =", round(mu[ll.argmax()],3), "  mean =", round(data.mean(),3))
    
  3. MLE 闭式解 vs 正规方程解。合成线性回归数据,分别用 np.linalg.solve(X.T@X, X.T@y)(正规方程)和 np.linalg.lstsq(X, y)(最小二乘/MLE),print 两组权重并用 np.allclose 验证它们数值一致。
    import numpy as np
    rng = np.random.default_rng(2)
    N = 100
    X = np.column_stack([np.ones(N), rng.normal(size=N), rng.normal(size=N)])
    y = X @ np.array([1.0,-2.0,0.5]) + rng.normal(0,0.5,size=N)
    w_ols = np.linalg.solve(X.T@X, X.T@y)
    w_mle = np.linalg.lstsq(X, y, rcond=None)[0]
    print("OLS:", np.round(w_ols,4))
    print("MLE:", np.round(w_mle,4))
    print("一致?", np.allclose(w_ols, w_mle))
    
  4. 把 L2 正则拼出来。在上一题基础上加入 lam*I,实现岭回归闭式解 solve(X.T@X+lam*I, X.T@y)。验证 lam=0 时回到 OLS,lam 增大时 ||w|| 单调减小。
  5. (推导题)泊松 MLE。设 \(x_i\sim\mathrm{Poisson}(\lambda)\),\(p(x\mid\lambda)=e^{-\lambda}\lambda^{x}/x!\)。写出对数似然,对 \(\lambda\) 求导置零,证明 \(\hat\lambda=\) 样本均值。(提示:\(\ell(\lambda)=-n\lambda+(\sum_i x_i)\ln\lambda-\sum_i\ln(x_i!)\),与本课的高斯/伯努利例题同套路。)
  6. (思考题)如果你把回归的 MSE 换成平均绝对误差(MAE,\(\sum|y_i-f(x_i)|\)),这对应假设标签噪声服从哪种分布?(提示:哪种分布的负对数密度长成 \(|y-\mu|\)?回看第六节拉普拉斯先验那个"0 处尖顶"的形状。)

掌握自检

下一课预告:我们已经看到 NLL 神奇地"长成"了各种损失。下一课用信息论(熵、交叉熵、KL 散度)从根上解释"损失为什么长这样",并把这一课的"最小化 NLL"、信息论的"最小化交叉熵"、以及"让模型分布逼近数据分布(最小化 KL)"三条线汇合证明成同一件事;那里会专门讲清 KL 散度不对称(forward 与 reverse KL 不是一回事)这个关键直觉。