ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

方差损失函数、MSE与高斯噪声:从极大似然推导到工程避坑

方差损失函数、MSE与高斯噪声:从极大似然推导到工程避坑 1. 从一次loss 死活降不下去的排查说起去年帮一个做设备寿命预测的朋友看模型他的任务是拿传感器时序特征回归剩余使用寿命网络不复杂三层全连接损失用的就是最朴素的平方误差。问题在于训练曲线特别难看前几十个 epoch 掉得飞快之后就贴着一条水平线不动了把学习率从 0.01 一路降到 1e-4结果只是从震荡变成了更慢的震荡。我让他把训练集标签的分布打出来一眼就看到了问题绝大多数样本的寿命在 300 到 800 之间但有三条记录的值是 99999——那是设备离线时代码填的默认值没做清洗。这三条样本贡献的平方误差是(99999 - 400)² ≈ 9.9e9而其余几万条样本的误差平方加起来也就 1e5 量级。整个损失函数被三条脏数据彻底绑架了梯度方向全被它们带着走模型学到的不是怎么预测寿命而是怎么把这三条往中间拽一点。这个案例把方差损失函数的性格暴露得非常彻底。所谓方差损失最常见的形态就是均方误差Mean Squared ErrorMSE也叫 L2 损失它用预测值和真实值之差的平方来衡量这次预测偏了多少。在人工智能基础这套知识体系里它出现的频率高到几乎每个入门者第一周就会写loss ((y - y_hat) ** 2).mean()但真正理解它为什么长这样、什么时候会咬人的人并不多。这篇文章适合三类人看刚学完线性回归、正在纠结为什么损失函数要用平方的入门者跑通了模型但对梯度尺度、离群点敏感这些现象只有模糊感觉的实践者以及准备面试、需要把从极大似然推导 MSE讲清楚的人。我会从统计学出身讲到代码实现中间穿插几个我在真实项目里踩过的坑尽量把它讲成一件能上手用的事而不是一段公式背诵。1.1 平方这个选择不是拍脑袋定的新手最容易问的一句话是既然只是衡量偏差为什么不用绝对值|y - y_hat|看起来更直观量纲也和原始标签一致多好。绝对值损失L1也叫 MAE确实有它的优点但有两个硬伤。第一个是在零点不可导。绝对值函数在 0 处是一个尖角导数从 -1 突跳到 1没有定义。深度学习靠梯度反传吃饭损失函数在最优点附近不可导意味着优化器在那个区域会抖收敛精度受影响。工程上大家用次梯度或者平滑近似绕过去但那是额外的心智负担。第二个是梯度是常数。L1 的梯度恒为 ±1跟误差大小无关。误差是 0.001 还是 100梯度一样大。这带来一个反直觉的后果当预测已经相当准的时候L1 还在用同样大的力气推参数容易在最优点附近来回横跳训练后期 loss 曲线毛刺明显。而平方损失在小误差区域梯度也小天然有自动收油门的效果。第三个理由更本质也是这篇要重点说的平方损失不是我们发明的是从概率模型里推出来的。假设观测噪声服从高斯分布那么最大化似然函数等价于最小化平方误差。这条推导链是理解方差损失的钥匙下一节细讲。1.2 方差损失和均方误差到底是不是一回事很多人看到方差损失函数这个名字会犯嘀咕方差不是统计里衡量数据离散程度的量吗Var(x) E[(x - μ)²]跟损失有什么关系把两个公式并排写出来就清楚了名称公式中心是什么方差$\frac{1}{N}\sum_{i}(x_i - \bar{x})^2$样本均值 $\bar{x}$均方误差$\frac{1}{N}\sum_{i}(y_i - \hat{y}_i)^2$模型预测 $\hat{y}_i$方差损失在线学习视角$\frac{1}{N}\sum_{i}(\hat{y}_i - \bar{y})^2$全量标签均值 $\bar{y}$结构完全一样都是先算偏离量再平方再平均。差别只在偏离的参照点是什么。均方误差的参照点是模型自己给出的预测衡量的是模型偏了多少方差的参照点是均值衡量的是数据自身散得有多开。所以狭义的方差损失其实指的是一种更朴素的基线如果你什么特征都不用只拿训练集标签的均值去预测所有样本那么你在测试集上得到的 MSE就等于测试集标签的方差严格说是以训练均值为中心的那种偏离程度。这就引出一个非常实用的判断技巧——任何回归模型在上线前都该和猜均值这个基线比一比。如果你的深度网络在测试集上的 MSE 跟标签方差是同一个量级那说明模型什么都没学到特征工程和网络结构都得推倒重来。注意这里的方差是通俗叫法严格统计意义上样本方差分母是 $N-1$无偏估计机器学习里的 MSE 分母默认是 $N$。数据量大时差别可以忽略但如果你在做小样本实验、且需要把损失值当作统计量去解释这个 $N$ 和 $N-1$ 的差异就会被放大别把两个数直接混着比。2. 从高斯噪声假设把平方项推出来把平方损失当成约定俗成来记是入门阶段最常见的偷懒。但只要花十分钟走一遍极大似然估计的推导你会突然明白很多设计细节为什么长那样为什么是平方而不是立方、为什么常常带一个 1/2 系数、为什么噪声方差 σ² 在推导完就消失了、以及为什么有的论文会给每个样本配一个可学习的方差。2.1 观测 真实规律 噪声先建模。假设真实世界存在一个确定性规律 $f(x)$我们观测到的标签 $y$ 是它加上一点随机扰动$$y f(x) \varepsilon, \quad \varepsilon \sim \mathcal{N}(0, \sigma^2)$$这句话翻译成人话是同一个输入 x你重复测十次会得到十个略有差别结果这些结果围在真实值附近误差呈钟形分布。这个假设在很多场景是站得住的——传感器有本底噪声、人工标注有主观偏差、被测量本身存在微小波动这些因素叠加起来按中心极限定理天然趋近正态。在这个假设下给定输入 x标签 y 的条件概率密度是$$p(y \mid x) \frac{1}{\sqrt{2\pi}\sigma}\exp\left(-\frac{(y - f(x))^2}{2\sigma^2}\right)$$注意指数上的那一项分子就是平方误差。这就是平方项的出处——它不是人为规定的惩罚方式而是高斯分布自带的结构。2.2 取负对数平方项自然落下来现在有 N 个独立同分布的样本整个数据集的似然函数是各样本概率的连乘。连乘容易数值下溢取对数变成连加$$\log L \sum_{i1}^{N}\left[-\log(\sqrt{2\pi}\sigma) - \frac{(y_i - f(x_i))^2}{2\sigma^2}\right]$$我们想最大化似然等价于最小化负对数似然。把与参数无关的常数项拎出去$$-\log L \underbrace{N\log(\sqrt{2\pi}\sigma)}{\text{常数}} \frac{1}{2\sigma^2}\sum{i1}^{N}(y_i - f(x_i))^2$$第一项对模型参数没有梯度优化时可以扔掉。剩下第二项就是带缩放系数的平方误差和。这里有两个细节值得停下来看一眼。第一σ² 在最优解里消失了。因为它是正的常数缩放最小化 $\frac{1}{2\sigma^2}\sum(\cdot)^2$ 和最小化 $\sum(\cdot)^2$得到的最优参数完全一样。这解释了为什么实践中大家直接扔掉 1/2 和 σ²省事又不影响结果。第二σ² 虽然不影响最优解但影响损失值的绝对大小和学习率的合适尺度。如果你的标签噪声方差很大损失量级会偏大梯度也偏大学习率就得相应调小。这解释了为什么换个数据集同样的网络和超参经常要重新调学习率——不是玄学是损失的尺度变了。2.3 异方差给每个样本配一个自己的 σ上面假设所有样本的噪声方差都是同一个 σ²。但现实里经常不是这样。比如做深度估计近处的像素预测误差可能只有几厘米远处的误差可能好几米做股票波动预测行情剧烈时的不确定性远高于平稳期。这时候模型应该写成 $y f(x) \varepsilon$其中 $\varepsilon \sim \mathcal{N}(0, \sigma^2(x))$即噪声方差随输入变化。重走一遍负对数似然$$-\log L \sum_{i1}^{N}\left[\log \sigma(x_i) \frac{(y_i - f(x_i))^2}{2\sigma^2(x_i)}\right] C$$这个形式非常有意思误差平方那一项被自己的方差除了。翻译过来就是模型对某个样本心里没底的时候σ 大这个样本的误差惩罚会被自动调低反之模型说自己很确定σ 小那误差就要被严厉追责。这就是异方差不确定性加权回归的核心思想实践中非常实用让网络多输出一个log_var头损失写成0.5 * (exp(-log_var) * (y - y_hat)**2 log_var)。用 log 形式是为了保证 σ² 恒正同时避免除零。这套写法在处理多任务联合训练时特别香——不同任务的损失量级往往差好几个数量级靠手调权重系数很难调平让网络自己学方差能省掉大量调参时间。提示exp(-log_var) * err² log_var里的log_var项起到的作用是防止模型摆烂——如果它把 σ 无限放大来逃避所有误差惩罚log_var这一项就会变大反过来惩罚它。两项是一对平衡缺一个都会退化。3. 手工推一遍前向与梯度理解了出身接下来动手算一遍。这一步千万别跳因为后面所有的调参直觉都从这里来。3.1 一个最小例子的完整计算设单个样本输入 $x 2$真实标签 $y 5$模型 $\hat{y} wx b$当前 $w 1.5$$b 0.5$。前向$\hat{y} 1.5 \times 2 0.5 3.5$误差 $e \hat{y} - y -1.5$损失 $L e^2 2.25$。梯度$$\frac{\partial L}{\partial \hat{y}} 2(\hat{y} - y) -3$$ $$\frac{\partial L}{\partial w} \frac{\partial L}{\partial \hat{y}} \cdot x -3 \times 2 -6$$ $$\frac{\partial L}{\partial b} \frac{\partial L}{\partial \hat{y}} \cdot 1 -3$$梯度是负的说明沿正方向更新 w 和 b 能降低损失。取学习率 0.1更新后 $w 1.5 0.6 2.1$$b 0.5 0.3 0.8$新预测 $\hat{y} 2.1 \times 2 0.8 5.0$一步命中。这个例子里藏着 MSE 梯度的通用结构每个参数的梯度 残差项 × 该参数对输出的敏感度。对 w 来说敏感度是输入 x对 b 来说是 1。这就是为什么特征尺度会影响训练——输入 x 大 100 倍w 的梯度就大 100 倍学习率不跟着调就会炸。3.2 批量形式与矩阵写法把 N 个样本堆成矩阵设 $X \in \mathbb{R}^{N \times d}$$y \in \mathbb{R}^{N}$预测 $\hat{y} Xw b\mathbf{1}$损失$$L \frac{1}{N}|Xw b\mathbf{1} - y|_2^2$$对 w 求梯度$$\nabla_w L \frac{2}{N}X^\top(Xw b\mathbf{1} - y)$$这个式子值得记。$X^\top r$ 的物理含义是把每个样本的残差按该样本的特征值加权累加。如果某个特征在所有样本上都是正数那它对 w 的梯度就是所有残差的和——这就是多重共线性为什么有害两个高度相关的特征它们的梯度方向几乎一样优化器在两者之间来回分配权重训练极不稳定。顺带说一件事很多人第一次看到正规方程 $w^* (X^\top X)^{-1}X^\top y$ 会疑惑它怎么来的。令梯度为零$\frac{2}{N}X^\top(Xw - y) 0$两边乘 $\frac{N}{2}$ 并移项得到 $X^\top X w X^\top y$两边左乘 $(X^\top X)^{-1}$ 就出来了。方差损失的凸性保证了这个解是全局最优也是线性回归能被一步解开的原因——换成神经网络的非线性结构这个好性质就没了。3.3 那个 1/2 系数是怎么来的几乎所有教程在定义 MSE 时都会写成$$L \frac{1}{2N}\sum_{i}(y_i - \hat{y}_i)^2$$多了个 1/2。原因很朴素求导的时候平方会掉下来一个 2跟 1/2 抵消梯度写成 $\frac{1}{N}(\hat{y} - y)$干净。它不影响最优解位置纯粹是为了纸面好看。代码里要不要加我个人的习惯是不加直接用F.mse_loss因为框架默认实现不带 1/2。如果你自己手写又加了 1/2记得学习率要调大约 2 倍否则收敛速度会对不上别人的实验报告。这种细节在复现论文结果时能坑掉好几天。4. 方差损失的脾气什么时候好用什么时候该换MSE 不是万金油。它在什么场景下稳、什么场景下会翻车背后都有明确的数学原因搞清楚之后选损失函数就不用凭感觉了。4.1 一个离群点能顶一万个正常样本回到开头那个寿命预测的例子。假设一批样本的误差都在 1 附近突然来一个误差 1000 的脏数据。它对损失的贡献是 $1000^2 10^6$对梯度的贡献是 $2 \times 1000 2000$而每个正常样本的梯度贡献只有 2。一个脏样本的梯度是正常样本的一千倍参数会直接被它拽走。换成 L1 损失会怎样同样那个脏样本梯度贡献是 1和正常样本的 1 完全一样。它当然还是会把参数往错误方向推但因为权重没有放大只要正常样本数量占绝对优势整体梯度方向不会被带偏。这就是 L1 更鲁棒robust的量化解释。下面这张表是我自己在选损失函数时的参考直接抄作业即可场景特征推荐损失理由标签干净噪声近似高斯MSE / L2与噪声模型匹配估计效率最高标签有少量异常值无法清洗L1 / MAE对离群点梯度不放大大部分样本干净但允许小部分偏离Huber / Smooth L1小误差区用平方保精度大误差区用线性抗噪目标是大误差必须被重罚MSE 加权平方放大正好是想要的效果分类任务交叉熵MSE 配 sigmoid 会梯度消失见下节Huber 的切换阈值 δ 怎么定是个经验活。常见的做法是先跑一遍 MSE把残差画成直方图取 95% 分位数作为 δ也可以用标签标准差的 1.0 到 1.5 倍作为起点。别一上来就精细调这个参数不敏感。4.2 梯度尺度随误差线性增长带来的连锁反应MSE 的梯度是 $2(\hat{y} - y)$误差多大梯度就多大线性关系。这带来两个连锁反应。训练初期参数随机初始化预测离目标很远误差可能是几百上千。这时候梯度极大如果学习率沿用后期调好的值一步更新就能把参数甩到火星去损失曲线出现那种第一个 epoch 掉到 0.001第二个 epoch 跳到 10的诡异形态。解决办法有三个用较小的初始学习率配合 warmup、对输入标签做标准化、或者换用自适应优化器让它自己缩放。我自己最常用的组合是标签标准化 AdamW 前 5% 步数线性 warmup基本能覆盖八成回归任务。训练后期误差缩小到 0.01 量级梯度也只有 0.02参数更新几乎停滞。这就是很多人疑惑为什么 loss 降到最后就不动了、但明明还没收敛的原因——不是模型学不动是梯度太小在浮点精度下更新量被稀释了。这时候把学习率降下来反而没用应该考虑换损失比如后期切到 L1 保精度或者用学习率重启策略跳出平台。注意如果你的网络最后一层是 Sigmoid 或 Tanh配 MSE 用会出现另一个更严重的病——梯度消失。Sigmoid 导数最大只有 0.25当输出饱和接近 0 或 1时导数趋近 0MSE 的梯度再乘上这个趋零的项反传到前面几层就基本归零了。这也是分类任务现在清一色用交叉熵的原因交叉熵配 Softmax 的梯度恰好是 $(\hat{y} - y)$没有额外的饱和因子稳定得多。4.3 判断该不该换损失的一个土办法说了这么多理论实操时怎么快速判断我有个偷懒但有效的流程。第一步先把训练集的残差分布画出来y - y_hat的直方图。如果是对称的钟形且尾部没有异常长的拖尾MSE 就是对的别折腾。如果看到明显的重尾或者孤立的一小撮远离中心的点先别急着换损失去查数据——大概率是脏数据或者特征泄漏清洗掉比换损失更治本。第二步算一下残差的绝对值和平方看看两者量级是不是差了几个数量级。如果平均残差是 1但均方残差是 100说明有少数样本主导了损失这时候换 Huber 会有立竿见影的效果。第三步看验证集指标和训练损失的排序是否一致。如果训练损失降了但验证集 MAE 没降甚至涨了说明模型在拟合那些大误差样本而这些样本往往是噪声。这是换 L1 的强信号。5. 几个挂着方差名字但不是一回事的概念这个坑我必须单独说因为我在读论文时被它绕过一次。机器学习里方差这个词出现在至少三个完全不同的语境里混起来会把知识体系搅乱。5.1 风格迁移里的方差损失匹配的是二阶统计量在神经风格迁移这一类任务里有一个术语叫 variance loss或去风格化里的 variance regularizationTotal Variation 则是另一回事。它做的事情是把风格图经过卷积网络提取出的特征图计算通道间的协方差矩阵实践中常直接算 Gram 矩阵然后最小化内容图特征和风格图特征在协方差上的差异。为什么有效因为卷积特征的每个通道可以看作一种纹理模式的响应强度通道之间的协方差描述了哪些纹理模式倾向于一起出现。协方差的平方根相关量本质上和方差是同一族的东西——都在刻画分布的散布结构。所以这类损失确实和方差有关但它的对象是特征分布不是预测误差。和 MSE 的区别在哪MSE 作用在标量输出上衡量单点预测偏差Gram 矩阵损失作用在特征张量上衡量的是分布级别的相似度。两者数学形式差得远但因为都挂了方差两个字读文献时极容易串。我的辨认方法是看它作用在网络的哪一层。作用在输出层的标量、目的是让预测逼近标签那就是 MSE作用在中间层特征、目的是对齐分布统计量那就是风格类的损失。5.2 偏差-方差分解里的方差是模型的稳定性另一个高频出现的概念是泛化误差分解$$\mathbb{E}[(y - \hat{f}(x))^2] \text{Bias}^2 \text{Variance} \sigma^2_{\text{noise}}$$这里的 Variance 指的是如果你换一份训练数据重新训练得到的模型 $\hat{f}$ 会有多大变化。它是模型对训练集扰动的敏感程度衡量的是稳定性不是某个损失函数。这和 MSE 的关系是MSE 是你实际算出来的那个数而这个分解是对 MSE 期望值的理论拆解。前者是你能打印到屏幕上的标量后者是用来解释为什么模型在验证集上表现不好的分析框架Bias 高说明模型太简单欠拟合Variance 高说明模型太敏感过拟合后面那项是数据本身的不可约噪声谁也没法消掉。我在给团队做调参培训时经常强调一句话方差损失是你手里的尺子偏差-方差分解是解释这把尺子读数为什么是这么大的理论。把两者混为一谈讨论要不要降低损失函数的方差这种问题就会变成鸡同鸭讲。5.3 分布输出层的方差参数在做什么第三类是 VAE、不确定性量化这类模型里的方差。VAE 的损失是重构项加 KL 散度KL 里有 $\sigma^2$ 和 $\mu$ 两个参数深度不确定性估计里网络会额外输出一个log_var。以 VAE 为例编码器不是把输入映射成一个点而是映射成一个高斯分布 $q(z|x) \mathcal{N}(\mu(x), \sigma^2(x))$然后从里面采样。KL 散度那一项$$D_{KL} -\frac{1}{2}\sum_j\left(1 \log\sigma_j^2 - \mu_j^2 - \sigma_j^2\right)$$这里出现了 $\log\sigma^2$ 和 $\sigma^2$它们的作用是约束这个分布不要偏离标准正态太远。整个损失可以理解成重构要准和隐空间要规整之间的拉扯。如果重构项用的是 MSE那这个模型里就同时存在两种方差一个是重构误差的平方MSE 里的一个是隐空间分布的方差KL 里的。写代码时变量命名一定要区分开我见过有人把recon_loss和kld_loss写成mse_loss和var_loss过两周自己都读不懂了。6. 上手实操从 NumPy 到 PyTorch 的完整复现前面都是纸上谈兵这一节直接上代码。我建议你打开一个 notebook 跟着敲一遍尤其是梯度检验那段跑通一次之后你对反向传播的理解会踏实很多。6.1 纯 NumPy 实现加数值梯度校验数值梯度检验是个好东西它不依赖任何框架的自动微分纯粹用给参数加一点点扰动看损失变多少的方式估算导数用来验证你手写的解析梯度对不对。import numpy as np def mse_loss(w, b, X, y): 全量 MSE不做任何工程优化只为看清公式 y_hat X w b return np.mean((y_hat - y) ** 2) def mse_grad(w, b, X, y): 解析梯度 N X.shape[0] y_hat X w b r y_hat - y # 残差 grad_w 2.0 / N * (X.T r) # 对 w 的梯度 grad_b 2.0 / N * np.sum(r) # 对 b 的梯度 return grad_w, grad_b def numeric_grad(f, w, b, X, y, eps1e-5): 中心差分法数值梯度 gw np.zeros_like(w) for i in range(len(w)): w_plus, w_minus w.copy(), w.copy() w_plus[i] eps w_minus[i] - eps gw[i] (f(w_plus, b, X, y) - f(w_minus, b, X, y)) / (2 * eps) gb (f(w, b eps, X, y) - f(w, b - eps, X, y)) / (2 * eps) return gw, gb np.random.seed(0) X np.random.randn(50, 3) y X np.array([1.0, -2.0, 0.5]) 0.3 np.random.randn(50) * 0.1 w np.random.randn(3) b 0.0 gw_ana, gb_ana mse_grad(w, b, X, y) gw_num, gb_num numeric_grad(mse_loss, w, b, X, y) print(解析梯度 w:, gw_ana) print(数值梯度 w:, gw_num) print(最大相对误差:, np.max(np.abs(gw_ana - gw_num) / (np.abs(gw_ana) np.abs(gw_num) 1e-12)))跑出来相对误差应该在 1e-7 量级。如果超过 1e-4说明梯度推导或者实现有 bug。做数值梯度检验时eps 别取太小浮点误差会淹没信号也别太大一阶近似不成立1e-5 到 1e-6 是经验甜区。另外一定要用中心差分而不是前向差分精度差一个数量级。6.2 PyTorch 的 reduction 参数到底改了什么PyTorch 里nn.MSELoss有个reduction参数三个取值行为完全不同这是新手最容易踩的坑之一reduction返回形状数值含义什么时候用mean默认标量全部元素平均常规训练梯度尺度不随 batch 变sum标量全部元素求和batch 变化时需要补偿学习率none同输入形状逐元素损失需要自己加权、掩码、做难例挖掘mean和sum的区别在于如果 batch size 从 32 改成 256用sum的话损失会变成原来的 8 倍梯度也大 8 倍学习率必须相应调小否则直接发散。用mean就没这个问题。我几乎所有项目都用默认的mean只有在做多任务加权、需要人为控制每个任务贡献时才会切到none自己算。import torch import torch.nn as nn pred torch.tensor([[1.0, 2.0], [3.0, 4.0]]) target torch.tensor([[1.5, 2.5], [2.0, 5.0]]) loss_mean nn.MSELoss(reductionmean)(pred, target) loss_sum nn.MSELoss(reductionsum)(pred, target) loss_none nn.MSELoss(reductionnone)(pred, target) print(loss_mean.item()) # 0.4375 print(loss_sum.item()) # 1.75 print(loss_none) # 逐元素的值 # none 的典型用法给困难样本更高权重 weights torch.tensor([[1.0, 1.0], [5.0, 5.0]]) # 第二行样本加权 weighted (loss_none * weights).mean()还有一个历史包袱老版本的size_average和reduce参数已经废弃但在一些老代码库里还能看到。如果同时传了新旧参数PyTorch 会报警告甚至报错。看到size_averageFalse就直接等价于reductionsum可以放心替换。6.3 我在项目里踩过的三个真实坑第一个坑是标签没标准化导致损失爆炸。做房价预测时标签单位是元数值在 1e6 量级MSE 损失一上来就是 1e12。float32 的有效精度大概在小数点后 7 位这种量级下梯度信息基本被浮点误差吃干净了训练出来是一堆 NaN。解决办法是训练前对标签做标准化推理后再反变换回来。这条经验适用于所有回归任务无论用什么损失函数。第二个坑是用 MSE 做二分类导致训练卡死。当时为了图省事最后一层是 Sigmoid损失用 MSE。前几个 epoch 损失从 0.25 慢慢降然后就再也不动了。原因就是前面说的梯度消失当预测接近 0 或 1 时 Sigmoid 饱和导数趋零MSE 的梯度乘上去趋近于零。换成BCEWithLogitsLoss数值稳定的交叉熵之后收敛速度肉眼可见地快了十倍以上。第三个坑是多任务训练里损失量级失衡。模型同时预测一个 0 到 1 之间的概率和一个 1000 到 10000 之间的数值两个损失直接相加结果大的那个一个顶一千个小任务完全学不到东西。我试过手调权重调了半天还是此消彼长。后面改成前面 2.3 节讲的异方差加权让网络自己学log_var两个任务才真正一起收敛。这也算是方差这个概念最实用的一次出场——它不只是拿来衡量误差的尺子还能变成调节任务平衡的旋钮。如果你正在做入门练习我建议先在一维数据上把 MSE 的梯度手推一遍再用数值梯度验证最后在 PyTorch 里跑通线性回归。这三步走完你对损失函数、梯度、学习率之间关系的理解会比看十篇文章都扎实。等遇到真正复杂的场景再回来读异方差加权和鲁棒损失那部分会发现前面的每一步都没白走。
返回列表