P5-4.1 损失函数(loss function)¶
Section ID:
P5-4.1Version:v2026.07.20
在 P5-3 章里,我们已经看到:激活函数(activation function)会把非线性(nonlinearity)加入神经网络,并提升表达能力。接下来立刻会跟上的问题就是:
那么,神经网络到底靠什么判断自己当前的输出错了多少?
回答这个问题的标准,就是损失函数(loss function)。
损失函数,就是把模型当前输出与目标之间偏离了多少,压成一个数字的规则。
不过,在教材或框架文档里,loss 与 objective 或 cost 有时也会被分得更细一些。通常,loss 指的是样本级偏差或其平均值,而真正被最小化的整体对象,则会被解释为同时包含 batch 平均值与正则化(regularization)的 objective/cost。这一节为了照顾初学者的阅读流程,会先统一用“损失”来讲;但等到后面把梯度(gradient)与优化器(optimizer)连起来时,还会再回头确认:真正被最小化的到底是什么?
如果后面又需要快速回看损失的角色,更适合回到英文概念词汇表里的 loss function 条目。
这里先固定下面三句话就够了。
- 只看到输出,学习还没有真正开始。
- 必须先把“错得多严重”变成数字,后面的计算才能继续。
- 这个数字,就是损失(loss)。
需要损失函数的问题¶
- 损失(loss)到底把什么变成数字?
- 为什么在深度学习里,损失函数会成为核心标准?
- 损失函数与评估指标(metric)有什么不同?
- 损失值变小,在学习过程中到底意味着什么?
具体有哪些损失函数,以及它们在不同问题类型上的差异,会在 P5-4.2 继续;微分与梯度计算怎样真正接到反向传播(backpropagation),则会在 P5-5.1、P5-5.2 再回来展开。也就是说,这一节首先要抓住的,是损失如何把预测与目标之间的偏差变成学习可以使用的数字。
把误差读成数字的判断标准¶
- 能把损失函数解释成
把当前预测错误变成数字的标准。 - 能区分损失函数与评估指标。
- 能说明“在学习里让损失变小”到底是什么意思。
- 能解释:预测值与目标值的差异,会让模型优先更强地修正哪一类错误。
为什么需要损失函数¶
神经网络会产生输出,但只有输出本身,还不会自动变成学习。模型必须能够对自己提出这个问题:
当前这个结果到底有多糟?
如果这个问题不能被转成数字,下一步就无法展开。
- 它不知道权重(weight)该往哪个方向改。
- 它不知道当前模型是否比前一个状态更好。
- 它也很难比较多个输出候选里到底哪一个更糟。
也就是说,损失函数就是神经网络检查自己结果时所依赖的基准点。
把这个场景换一句话来说,就是:
没有损失,模型就无法自己比较现在是变好了还是变坏了。
损失(loss)在测什么¶
损失(loss)通常比较的是下面这两个对象:
- 模型当前给出的输出(prediction)
- 我们期望的目标(target)
先这样理解就够了:
损失,就是把预测与目标之间的偏差压缩成一个数字。
例如:
- 正确答案是 10,而预测是 9,损失可能相对较小;
- 正确答案是 10,而预测是 2,损失可能就更大。
也就是说,损失并不只停在“对 / 错”这种离散判断上,它会进一步把偏离了多少读成一个更连续的数字。
这里读者最容易抓住的关键感觉通常是:
- 无论是分类还是回归,损失都在处理
错的程度; - 损失往往会给出比
0 或 1更平滑的数字; - 也正因为如此,后面才有办法去计算梯度。
把这个流程再压成很短的一张图,就是下面这样:
flowchart TD
A["模型预测"]
B["目标值"]
C["比较偏差"]
D["损失值"]
E["梯度信号"]
F["参数更新"]
A --> C
B --> C
C --> D
D --> E
E --> F
这张图最先要确认的结果是:损失并不只是一个“难看分数”,而是把预测与目标之间的偏差继续传给下一次更新的连接点。
它和 Part 4 里的 metric 有什么不同¶
在 Part 4 里,我们已经看过 accuracy、precision、recall、F1、RMSE 这类评估指标(metric)。走到这里时,很容易把损失函数和评估指标理解成同一件事。
但它们的角色并不一样。
| 区分 | 损失函数(loss function) | 评估指标(metric) |
|---|---|---|
| 主要角色 | 为学习服务的内部标准 | 为评估与选择服务的标准 |
| 使用时点 | 在学习过程中持续使用 | 用于中途检查、early stopping、最终评估 |
| 它回答的问题 | 现在到底错了多少? | 实际上表现得有多好? |
所以,先把这两件事分开来看会更稳妥:损失函数是模型用来学习的标准,而 metric 是人用来评估和选择模型的标准。
当然,两者也不是完全无关。一个设计得好的损失,通常还是应该和我们真正关心的性能方向有一定对应关系。但它们并不是同一种角色。
为什么损失最后会聚成一个数字¶
神经网络有很多参数(parameter)。想要修改这些参数,就必须把当前状态先收束成一个可以比较的统一标准。
例如,对多个样本来说:
- 有些预测只错了一点;
- 有些预测错得很多;
- 有些预测几乎已经是对的。
如果把这些状态原样摆着,就很难决定更新方向。因此,损失函数会把多个偏差聚成一个数字。在真实训练代码里,这个数字通常会被整理成 batch 的平均值或总和;有时还会再加上正则化项,变成真正被优化的整体目标函数(objective/cost)。
也就是说,损失函数在学习流程里,承担的是指南针数字的角色。
如果再压成读者可以直接记住的一句话,就是:
损失,是把模型当前走偏的方向压缩成一个数字的信号。
损失变小意味着什么¶
这里可以先用下面这句话来解释:
损失变小,表示当前模型至少在训练数据上,制造出的预测与目标偏差变少了。
但这里也有一个必须一起记住的提醒:
- 训练损失(training loss)变小,
- 并不等于可以立刻断定泛化(generalization)也变好了。
这一点和 Part 4 里关于过拟合(overfitting)与泛化的说明是直接连着的。也就是说,损失非常重要,但不能只靠损失一个数字就判断整个模型。
案例与示例¶
案例 1. 批次能耗预测¶
假设我们在预测一个混合批次的总能耗。真实用电量是 5.0kWh,模型预测 A 是 4.8kWh,模型预测 B 是 2.0kWh。人最先会看的是:哪一个更接近真实用量? 只靠这个标准,也能立刻看出预测 A 比预测 B 错得少。但学习必须把这种判断在所有样本上用同一套规则重复下去,所以偏一点和偏很多必须被转成一致的数字。损失函数正是把这种差异变成适合学习使用的数字,让模型能够比较:哪个预测更糟,哪个预测相对没那么糟。也就是说,在回归问题里,先要做的不是只问“错没错”,而是把离得有多远变成数字。
| 比较项 | 预测 A | 预测 B | 现在要读到的核心 |
|---|---|---|---|
| 与真实用量的差距 | 5.0 - 4.8 = 0.2 | 5.0 - 2.0 = 3.0 | 两者都是错的,但偏离程度完全不同。 |
| 人最容易先做的判断 | 几乎正确 | 错得很多 | 直觉上能分开,但学习必须把这种差别固定成可重复使用的数字。 |
| 从损失视角来看 | 较小惩罚 | 较大惩罚 | 损失函数会把没那么糟的错答和更糟得多的错答在数字上拉开。 |
如果把同样的差距用最简单的规则,例如平方误差(squared error)来读,为什么损失会被拉开也就会更直接。
| 损失计算示例 | 预测 A | 预测 B | 现在要确认的结果 |
|---|---|---|---|
| 误差(error) | 4.8 - 5.0 = -0.2 | 2.0 - 5.0 = -3.0 | 两者方向都一样,都是低估了真实值,但大小差很多。 |
| 平方误差 | (-0.2)^2 = 0.04 | (-3.0)^2 = 9.0 | B 的损失会比 A 大得多。 |
| 更新信号解释 | 只需要小幅修正的状态 | 需要大幅纠正的状态 | 损失数字越大,就越能看清应该优先强烈修正哪一个预测。 |
| 人最容易先看的标准 | 用损失重新阅读后的标准 |
|---|---|
| 只看到两者都不是正确答案 | 即便都是错答,也要把偏得更远的那个在数字上拉得更开 |
| 只保留“A 比 B 好”的直觉 | 这种直觉必须被变成能在所有样本上重复应用的损失数字 |
| 在回归里容易觉得“大致接近就行” | 学习必须把到底有多接近读成连续值,更新方向才会出现 |
这个案例里最后要确认的结果很明确:即便两个预测都错,损失也不会停在“两者都错了”这一层,而会给像 B 这样偏得更远的预测更大的数字,让它更早、更强地被修正。
案例 2. 检测状态分类¶
分类问题也类似。假设正确答案是细微划痕,而模型输出 A 是 正常 0.51,细微划痕 0.49,模型输出 B 是 正常 0.99,细微划痕 0.01。
人很容易说“两者都错了”就直接跳过去。但从学习的角度看,这两个错答的权重不应该一样。A 几乎就快答对了,而 B 却以很高的把握往相反方向判断。因此,损失函数还会把它错得有多自信一起纳入,让模型能够区分:虽然都是错答,但有些错答需要被更强地修正。也就是说,在分类问题里,重要的不只是“对还是错”,还包括模型带着什么样的置信度错了。所以,这个案例要确认的结果是:即便两者都错,像 B 这样几乎不给正确类别概率、而且非常自信地答错的预测,是否会得到更大的损失惩罚。
| 比较项 | 输出 A | 输出 B | 现在要读到的核心 |
|---|---|---|---|
| 预测标签 | 正常 | 正常 | 如果只看最终标签,两者是同一种错答。 |
给正确答案细微划痕的概率 | 0.49 | 0.01 | A 几乎答对了,但 B 几乎没有给正确答案任何机会。 |
| 人最容易先做的判断 | 错了 | 错了 | 如果只看对错,这两者之间的差别会消失。 |
| 从损失视角来看 | 更接近小惩罚的错答 | 惩罚会大得多的错答 | 即便是同样的错答,损失也会把正确类别概率的差距拉开。 |
即便不去详细推导 cross-entropy,也能立刻确认这个例子:给正确答案的概率越低,损失就越大。
| 损失计算示例 | 输出 A | 输出 B | 现在要确认的结果 |
|---|---|---|---|
给正确答案细微划痕的概率 | 0.49 | 0.01 | 损失会直接看正确类别到底拿到了多少概率。 |
cross-entropy 示例 -log(p) | -log(0.49) ≈ 0.713 | -log(0.01) ≈ 4.605 | B 的损失远大于 A。 |
| 更新信号解释 | 可能只需稍微调整边界的状态 | 必须往正确方向大幅拉回的状态 | 越是很自信地答错,修正信号就越强。 |
把这两个案例再画成图形来读,会更容易看出:回归损失会随着离目标值越来越远而变大,而分类损失会随着给正确类别的概率越来越低而变大。
这两张图的目的并不是让读者背公式,而是看清:损失是沿着哪条轴变大的? 对回归来说,关键轴是与目标值之间的距离;对分类来说,关键轴是给正确类别的概率。
| 人最容易先看的标准 | 用损失重新阅读后的标准 |
|---|---|
| 把两者都看成同样的错答 | 同时去看它离正确答案多远,以及它错得有多自信 |
| 把 0.51 和 0.99 都只读成“都预测为正常” | 把 A 读成“差一点就对的错答”,把 B 读成“强烈朝错误方向确信的错答” |
| 容易觉得两格的对 / 错判断就够了 | 损失会把错答的程度更细致地分成数字 |
这个案例里最后也要确认同样明确的结果:在分类里,即便是同一种错答,像 B 这样几乎不给正确类别概率的预测,也会得到更大的损失,并被更早、更强地修正。
这两个案例合在一起所展示的核心是一致的:在回归里,更重要的是偏离了多远;在分类里,更重要的是错得有多自信。这些差异必须更强地反映在损失数字里,下一次更新才会更准确。
把这两个案例收成一句话,损失函数的共同角色其实就是:
把模型当前的偏差变成学习可以使用的数字。
而这一节还必须再往前走一步:在案例层面真正闭合为什么损失需要和 metric 分开存在。
| 问题类型 | 人最容易先看到的结果 | 如果只看 metric 或最终对错 | 损失额外揭示了什么 | 应该优先修正哪个预测 |
|---|---|---|---|---|
| 批次能耗预测 | A 比 B 更接近真实用量 | 如果只知道两者都错,修正优先级还不够清楚 | B 比 A 偏离得远得多,因此损失会被拉开很多 | 预测 B |
| 检测状态分类 | A 和 B 都预测成正常,所以都错了 | 只看 accuracy,它们都可能只是同一个 0 | B 几乎没给正确答案细微划痕任何概率,因此损失大得多 | 输出 B |
这张表的核心很简单:即使在 metric 或最终对错层面看起来像同一种错答,损失仍然会更细致地区分:到底哪一种错答更危险、更该优先大幅修正。
flowchart TD
A["看起来像同一种错误的结果"]
B["人或评估指标(metric)视角"]
C["两者都只是错了或分数较低"]
D["损失视角"]
E["区分偏差大小与置信度差异"]
F["更大的损失得到更高的修正优先级"]
A --> B
B --> C
A --> D
D --> E
E --> F
在这条流程里,读者最后要抓住的结果是:损失不是贴在“对 / 错”后面的辅助分数,而是决定更新优先级的数字。
为什么机器学习与深度学习的教材总会在前面尽早讲损失函数,一个重要原因就是:学习不是简单地反复套规则,而是一个优化(optimization)问题。
深度学习的核心流程,通常可以先读成下面这样:
放入输入
-> 产生输出
-> 计算损失
-> 沿着让损失下降的方向修改参数
也就是说,损失函数不是加在输出后面的可选附件,而是整个学习计算真正被启动的标准。
从课程结构来看,也只有先理解了损失函数,后面这些问题才会变得自然:
- 为什么需要反向传播(backpropagation);
- 优化器(optimizer)到底在试图减小什么;
- 学习率(learning rate)又是在追着什么数字走。
练习与示例¶
这次练习的目标,是读懂:预测值与目标值之间的差异,怎样以最简单的方式变成损失数字。这里不只看平均损失,还要一起看样本级误差,确认到底是哪个项目把损失拉高了。
输入:
- 3 个目标值
- 3 个预测值
输出:
- 每个样本的平方误差
- 错得最厉害的样本
- 平均损失
问题场景:
- 不能只看最终平均值;还必须一起看每个样本的误差是怎样累积起来的
要确认的概念:
- 平均损失是由各个样本误差聚合出来的数字;
- 找出最严重的样本,更容易解释为什么整体损失会变大。
输入(input):
使用上面整理过的样本目标值与预测值。
在看表之前,也可以先自己猜一猜:哪个样本最可能把平均损失拉高。
| 样本 | 可以先猜测的损失大小 | 这样猜的原因 |
|---|---|---|
night_shift_batch | 中等 | 目标 3.0 与预测 2.5 的差是 0.5,并不算特别小。 |
stabilized_batch | 最小 | 目标 1.0 与预测 1.4 的差是 0.4,在三个样本里最小。 |
restart_delay_batch | 最大 | 目标 2.0 与预测 1.2 的差是 0.8,是三者里拉得最开的。 |
这张表的目的并不是要求先把平方误差精确算出来,而是先抓住:平均损失不是每个样本都同样贡献,而是会被那些错得更厉害的样本更强地拉动。
如果把这三个 batch 按损失视角整理,就会读成下面这样:
| 样本 | target | prediction | squared error | 现在要读到的结果 |
|---|---|---|---|---|
night_shift_batch | 3.0 | 2.5 | 0.25 | 需要修正,但还不是最优先的 worst case。 |
stabilized_batch | 1.0 | 1.4 | 0.16 | 三个 batch 里错得最轻,损失贡献最小。 |
restart_delay_batch | 2.0 | 1.2 | 0.64 | 它是把平均损失抬得最高的关键错答。 |
把这三个值再取平均,就得到 mean_loss = 0.35;而错得最严重的 batch,会被读成 restart_delay_batch。
这个练习真正重要的是:0.35 这个平均损失数字到底是怎样形成的。
- 第一个样本错了一些;
- 第二个样本也错了一些;
- 第三个样本错得更多。
损失函数会把这些偏差聚成一个数字,让模型能够读出自己当前有多糟。同时,透过样本级误差,也能看出到底是哪个案例把平均损失拉高得最多。
在这个例子里,读者必须真正读到的是:
- 每个样本错的程度并不一样;
- 损失函数不会丢掉这种差别,而会把它保留成数字;
- 多个样本的错答,可以被聚成一个统一的平均标准。
但如果只停在这里,还只是“看到了平均损失数字”。损失示例还应该继续读出:到底应该先更强地修正哪个样本。
| 输出信号 | 不那么差的读法 | 更危险的读法 | 现在更好的下一步判断 |
|---|---|---|---|
mean_loss = 0.35 | 把它读成三个样本当前平均偏差大约在这个程度 | 只看 0.35 就以为已经知道该修哪个样本 | 平均值只是整体摘要,还要一起看样本分解,才能看到更新优先级 |
worst_sample = restart_delay_batch | 读成:三个样本里它把平均损失拉得最高 | 以为把它当异常点扔掉就好 | 更好的读法是:它代表了模型当前特别脆弱的一段输入区间,需要优先回看它为什么会偏这么大 |
night_shift_batch=0.25, stabilized_batch=0.16, restart_delay_batch=0.64 | 知道三者都有误差,但大小不同 | 觉得既然都错了,就差不多一起改就行 | 读出:像 restart_delay_batch 这种更大的错答,会更强地牵动平均损失与后续更新 |
把这张表也读完后,损失函数就不再只是“算出一个平均数字的过程”,而会更明确地变成筛出哪种错答应该优先被大幅修正的标准。
从学习的角度,还要再向前一步。读者最后应该能自己说出这样一句话:重要的不只是平均损失有没有下降,还包括哪一个 batch 还在持续充当 worst case,以及它是否代表了某种输入区间的系统性弱点。因为损失函数一方面是数字聚合规则,另一方面也是修正优先级规则。
| 换值后重新阅读的轴 | 会一起变化的损失解释 | 现在可以继续追问的问题 |
|---|---|---|
把 restart_delay_batch 的 prediction 从 1.2 提高到 1.7 | worst case 会被缓和,平均损失也会一起下降 | 模型当前最大的弱点是否真的被减轻了? |
只降低 night_shift_batch 与 stabilized_batch 的误差 | 平均值可能下降一些,但 worst case 可能原封不动 | 平均改善是否真的意味着核心错误区间也改善了? |
| 样本数量继续增加 | 光看平均损失一个数字,更容易看不出到底哪段输入持续有问题 | 什么时候必须把平均值与样本级分解一起看? |
如果把同样的场景用 Python 做一个小实验,就能直接改动看看:修哪个预测时,平均损失和 worst case 会一起下降? 下面的例子把“重点修正 restart_delay_batch”和“只修正原本误差较小的 night_shift_batch”分开比较。
运行后会得到下面这样的输出。
这里真正被操作的值,是 replace_prediction(...) 里的最后一个数字。修正 restart_delay_batch 时,平均损失会明显下降,worst case 也会改变;而只修 night_shift_batch 时,平均值虽然也会下降一些,但最大的弱点依然没变。因此,这段代码帮助读者确认:损失不是一个单纯的平均数,而是会把哪一类错误该优先被大幅修正显露出来的信号。
从图里看,会更容易发现:修正 restart_delay_batch 时,平均损失和 worst 损失会一起下降。相反,只修正 night_shift_batch 时,平均损失会减少,但红色柱子,也就是最大的损失,仍然留在原地。所以,这个图额外强化的重点是:要把平均有没有下降与最大的弱点有没有缩小分开来看。
如果把同样的输出重新译回运营判断,会更直接。
| 示例场景 | 只急着看结果时容易做出的解释 | 更好的解释 |
|---|---|---|
night_shift_batch 与 stabilized_batch | 两者都只错一点,因此优先级差别不大 | 两者都只是轻微修正候选,但仍可读出 night_shift_batch 比 stabilized_batch 更早需要处理 |
restart_delay_batch | 反正它也被平均进去了,整体调整自然会顺便解决 | 它是把损失拉得最高的关键样本,因此更像模型特别脆弱输入区间的代表信号 |
只看 mean_loss 这一个数字 | 只要整体损失下降就足够了 | 即便平均下降,也要一起看哪个样本还在持续充当 worst case,修正方向才会更清楚 |
损失小,就一定是好模型吗¶
读者很容易觉得:只要损失数字变小,一切问题就都解决了。但还要一起记住下面几点:
- 看损失时,不只要看数字本身有没有变小,还要一起看它是在训练数据上变小,还是在验证数据上也保持住了;
- 即便是同样小的损失,如果不区分它来自哪个数据区间,就很容易漏掉过拟合;
- 只看训练损失去相信模型,很可能会忽略过拟合。
也就是说,损失是学习过程中的核心标准,但它仍然必须和 Part 4 里看过的 validation、test、metric 一起阅读。
正因为如此,深度学习也会直接继承 Part 4 的机器学习共通原则。
什么时候要先用损失函数视角来读¶
当你发现“模型已经输出了结果”这一句还不足以说明学习到底发生了什么时,就应该先把损失函数这一节拿出来。
| 先出现的问题场景 | 为什么应先切到损失函数视角 | 紧接着该问的下一个问题 |
|---|---|---|
| 已经有输出,但还无法用数字比较哪里错了 | 可以先建立起:预测与目标之间的偏差怎样被转成可学习的信号 | 接下来要继续看,不同问题类型为什么会用不同的损失 |
| metric 与学习标准混在一起 | 可以把“人用来读的指标”和“模型内部用来学的标准”拆开 | 接下来要看回归与分类各自最自然的损失是什么 |
| 反向传播或优化器的说明看起来很突兀 | 因为只有先有损失,才能闭合“到底在减小什么” | 接下来要看损失如何被传回到各层 |
| 同样是错答,但错的程度差异很重要 | 可以说明:为什么不能只停在对 / 错,而要保留偏差大小 | 接下来要看不同损失怎样解释这些偏差差异 |
检查清单¶
- 能说明损失函数(loss function)到底是把什么变成数字的标准吗?
- 能区分损失与评估指标(metric)的角色差异吗?
- 能说明损失函数是把预测与目标之间的偏差变成一个数字的规则吗?
- 能解释为什么只有输出还不算学习开始,还必须再加上损失这个数字吗?
- 能说明损失是模型学习时的内部标准,而 metric 是人用来读与选择模型的外部标准吗?
- 能把“学习会沿着让损失下降的方向调整参数”这件事说清楚吗?
- 能说明损失下降并不自动保证泛化也变好吗?
- 当你看到“模型已经输出了结果”,但仍然说不清它靠什么标准在学时,能先想到损失函数视角吗?
- 能掌握:问题类型差异会在下一节继续,而损失如何传回前面各层会在下一章继续吗?
出处与参考资料¶
- Ian Goodfellow, Yoshua Bengio, Aaron Courville,
Deep Learning, MIT Press, 2016, 确认日期:2026-06-29. https://www.deeplearningbook.org/ - Christopher M. Bishop,
Pattern Recognition and Machine Learning, Springer, 2006, 确认日期: 2026-07-19. https://link.springer.com/book/9780387310732