P5-3.6 输出层(output layer)与激活的选择¶
Section ID:
P5-3.6Version:v2026.07.20
在 P5-3.1 里,我们已经看过为什么需要激活函数;而从 P5-3.2 到 P5-3.5,则分别看了 sigmoid、tanh、ReLU 与代表性函数的公式比较。走到这里之后,下一个问题就会自然出现。
既然隐藏层里经常会用 ReLU 这类函数,那么最后的输出层到底该用什么样的激活?
这个问题会立刻连到损失函数(loss function)。所以这一节既是激活函数这一章的收束,也是通向下一章的桥。
输出层的激活会随着模型到底在预测什么而改变,它必须被选成一种能够匹配“输出值应该具有什么意义”的形式。
如果后面又开始混淆输出解读与激活选择的标准,更适合一起回看英文概念词汇表里的 output 条目与activation function 条目。
选择输出层激活的问题¶
- 为什么隐藏层激活与输出层激活不能被当成同一个问题?
- 在回归(regression)、二元分类(binary classification)、多分类(multiclass classification)里,输出层分别该怎样阅读?
- 为什么输出层激活必须和损失函数一起考虑?
看起来像概率的输出与分数(score)应该怎样区分?
损失函数本身的设计会在 P5-4.1 与 P5-4.2 继续;而 calibration 的基本阅读与类概率输出的解释,则会在 P4-6.4 再接回去。也就是说,这一节先要闭合的是:输出层激活到底会把最后那个数字固定成什么样的解读单位。
预测目标与损失连接的判断标准¶
- 能说明:输出层激活的选择,和
模型到底在预测什么直接相关。 - 能在回归、二元分类、多分类里,用不同方式阅读输出层。
- 能理解输出层激活与损失函数并不是彼此分开的两件事。
- 能按输出形式,区分最后那个数字到底应该按什么单位来读。
为什么隐藏层与输出层必须分开看¶
隐藏层(hidden layer)里的激活,主要和让表征变得更丰富的非线性有关。相反,输出层(output layer)里的激活,则更直接地连到最后那个值到底应该具有什么意义。
也就是说:
- 隐藏层激活更接近于“如何形成内部表征”的问题,
- 输出层激活更接近于“如何解释最终输出”的问题。
这里可以先用下面这条区分来理解。
隐藏层改变数值,是为了形成更复杂的模式;输出层改变数值,则是为了让这些值能够以某种预测结果的形式被正确读取。
这个区分之所以重要,是因为它们都叫“激活函数”,很容易让角色混在一起。对于隐藏层,中心问题是它能不能形成更复杂的表征?;而对于输出层,中心问题则是最后这个数字到底应该怎样当作答案候选来读? 因此,输出层的选择并不是先从内部计算方便出发,而是更直接地绑定在预测对象的意义与损失解释上。
输出层要按预测目标来选¶
如果模型要预测的对象不同,那么最后所需要的输出形式也会不同。
例如:
- 如果预测的是混合批次的总能耗这类连续值,就可以直接输出一个数字;
- 如果要判断一个新警报到底该“立即停机”还是“继续监控”,就可能需要一个可以被读成 0 到 1 之间的值;
- 如果要在“正常 / 细微划痕 / 污染”这些候选里做选择,就需要一种能比较多个候选的输出结构。
也就是说,输出层并不只是最后一个节点,而是问题定义决定最后输出长什么样子的地方。
在回归(regression)里该怎样读¶
在回归问题里,预测的是连续数值。比如:
- 下一批的预期能耗,
- 压力稳定完成时间,
- 某时段的冷却水需求量。
在这种情况下,输出层常常不会再额外套一个特殊的非线性激活,而是保留线性输出(linear output)。原因很简单:如果本来就要预测一个真实数值,却把它硬压到 0 到 1 或 -1 到 1 之间,反而会把表达范围限制住。
如果要直接预测连续值,那么让输出尽可能保持数字本身,会更自然。
在二元分类(binary classification)里该怎样读¶
二元分类就是在两个选择里做判断。
- 立即停机 / 继续监控
- 需要复测 / 自动通过
- 过热风险 / 正常状态
在这种问题里,sigmoid 很常出现。因为 sigmoid 会把输出压成 0 到 1 之间,所以读者很容易把它读成某种像概率的值。
但这里必须小心一件事。
sigmoid 输出是一个很容易按概率那样去读的值,但它并不会在所有情境里自动保证那就是严格意义上的概率。
在真实系统里,它后面往往还会跟着 threshold(阈值)策略。比如:
- 大于等于 0.5 就判为阳性,
- 大于等于 0.9 就直接阻断,
- 介于 0.6 到 0.9 之间则送人工复核。
所以,输出层里的数字,与服务里的最终决策,必须分开来看。
在多分类(multiclass classification)里该怎样读¶
多分类就是候选不止两个,而是三个以上。
- 正常 / 细微划痕 / 污染
- 压力恢复 / 冷却不稳 / 传感器异常
- 初级警报 / 现场检查 / 生产中断
在这种问题里,常见做法是先给每个类别(class)形成一个自己的分数,再通过 softmax 把这些分数变成可以互相比较的相对比例。
这里先用下面这种直觉来理解就够了。
- 每个类别先都有自己的分数;
- softmax 会把这些分数放在一起比较,显示出
哪一个相对更大。
也就是说,多分类不应该被读成每个输出各自独立解释,而应该被读成一种候选之间相互竞争的结构。
把它画得最简单,就是下面这样。
flowchart TD
A["隐藏表征"]
B["类别分数<br/>正常、划痕、污染"]
C["softmax 比较"]
D["类似类别概率的输出"]
A --> B
B --> C
C --> D
这张图会帮助你把多分类输出层读成先形成各类分数,再把这些分数放在一起比较的结构。softmax 不是只是把数字“变好看”,而是那个真正让多个类别候选的相对强弱显出来的步骤。
分数(score)、logit、像概率的值是同一回事吗¶
这里最容易让读者混淆的,有三个表达。
- 分数(score)
- logit
- 像概率一样的输出
在这一节里,先做到下面这种区分就够了。
| 表达 | 给读者的解释 |
|---|---|
| 分数(score) | 模型内部为了比较而形成的值 |
| logit | 送进 softmax 或 sigmoid 之前的最后一组分数 |
| 像概率一样的输出 | 经过 sigmoid 或 softmax 后,更容易被人解释的值 |
这个区分很重要,因为它会直接连到下一章的损失函数。有些损失函数会被设计成直接接收 logits,而有些则默认你传进来的是已经激活后的输出。
这里可以先固定这样一点:logit 还是解释前的分数,而激活后的值才是更容易被人读取的形式。 如果这个区分没有立住,那么即便是同一个数字,也很容易被混淆成:它到底是模型内部拿来比较的分数,还是人可以像概率一样去读的值。
为什么输出层激活和损失函数必须一起看¶
如果只单独决定输出层激活,解释会只完成一半。因为损失函数负责的,是去读取输出到底和正确答案差了多少。
例如:
- 在回归里,连续值输出与均方误差(mean squared error)通常会自然连在一起;
- 在二元分类里,sigmoid 与 binary cross-entropy 常常一起被提起;
- 在多分类里,softmax 与 cross-entropy 常常会配对出现。
输出层激活负责对齐输出的意义,而损失函数则会按照这种意义去读取它与正确答案的差距。
也就是说,输出层与损失函数更适合被看成一对设计,而不是两件彼此分离、各自去背的东西。
案例与例子¶
案例 1. 能耗预测¶
假设我们要预测一批混合工艺的最终能耗。人在这个场景里首先想知道的是这一批大概会用多少 kWh?,而不是它属于哪个能耗区间的概率。也就是说,输出必须保留成像 12.5kWh 这样的连续值,才能直接拿来和真实能耗比较到底差了多少。
在这类问题里,人通常想要先知道是多少,而不是先在一堆概率类别中挑一个。因此,与其把输出压成 0 到 1 之间,不如直接让能耗数字本身保留下来更自然。比如说,重要的是它到底更接近 12.0kWh 还是 15.0kWh,而像高能耗批次概率 0.8这种绕一层的值并不方便直接使用。这里真正重要的标准不是它属于哪个类别,而是它离正确数字到底有多远。因此在这个例子里,要确认的结果是:输出有没有作为一个连续值被保留下来,让你能直接比较与真实使用量之间的距离,而不是被压成某种像概率的东西。
| 人最容易先做的误读 | 为什么更差 | 更好的读法 |
|---|---|---|
看到 12.7 后,只判断它大概算高还是算低 | 它错过了回归输出的核心:离正确答案有多远 | 先比较真实答案是 12.4 还是 16.0,以及误差到底有多大 |
把 12.7 读成某个区间的概率 | 它会把连续值预测问题错误地改读成分类问题 | 把这个数字本身当成预测值,并结合允许误差一起判断 |
案例 2. 警报阻断过滤器¶
再想一个场景:线路控制系统需要决定,新出现的警报到底应该立即停机,还是继续监控。在这种情况下,操作员首先关心的不是某个精确数字,而是到底该拦还是该放? 所以像 0.91 这样的输出,不应该只被看成一个小数,而应该被看成一个明显偏向“立即停机”一侧的分数。也就是说,这类问题更接近于去读它在两个选择里偏向哪一边、有多强,而不是像回归那样直接预测一个连续数值。比如 0.91 可能触发自动停机,而 0.55 可能只会送去现场确认,因此这个输出值后面很容易立刻接上一条运行策略。关键点在于:sigmoid 输出本身并不等于最终策略。
但真实运行不会停在这里。比如说,0.91 可能触发自动停机,0.65 可能送去现场确认,而 0.30 则可能只是被记录下来。因此这个案例真正要确认的结果是:即使面对同一个 sigmoid 输出,分数的解释与实际控制规则,仍然是两个不同阶段。
如果把 0.91 立刻读成停机决定,那就会把模型输出与运行策略揉成一团。在输出层解读里,更合理的做法是:先把 0.91 看成模型输出,再在下一步通过政策规则决定是否停机。即使是同样的小数,不同设备也可能使用不同阈值,所以 sigmoid 分数的解读与 threshold 政策必须分开。
即便是同样的 sigmoid 输出,也有一些误读相对没那么糟,而有些则更危险。
| 输出场景 | 相对没那么糟的误读 | 更危险的误读 | 更好的读法 |
|---|---|---|---|
0.55 | 读成偏向阳性,但仍然模糊 | 直接决定自动停机 | 把模型输出与运行阈值拆开,优先看是否落在现场确认这样的中间策略区间 |
0.91 | 只把它读成强警告,细化策略稍后再看 | 把 0.91 本身当作策略,忽略不同设备阈值会不同 | 把它先读成强阳性分数,再确认自动停机标准究竟设在什么位置 |
案例 3. 质量状态分类¶
假设我们有一个模型,会自动把表面检测画面分成正常、细微划痕、污染。人往往会先想直接看到一个名字,像是这到底是什么状态? 但模型实际上会先形成一组相互竞争的分数,比如 normal、scratch、contamination。这时重要的,不只是第一名叫什么,而是它到底领先了多少。
例如,如果输出是 normal 0.70, scratch 0.20, contamination 0.10,人可以读成它最明显地偏向正常。但如果输出变成 normal 0.38, scratch 0.34, contamination 0.28,那即使系统仍会选出一个答案,也很难说模型真的有很高把握。人一开始很容易觉得只看第一名名字就够了,可在实际使用里,它与其他候选到底拉开了多大距离也同样重要。比如自动分类能不能直接确认,还是应该交给人复核,就会强烈依赖这个差距。因此在这个例子里,需要确认的结果就是:输出里不只保留第一名的类别名字,还保留了它与其他候选之间的差距,从而把自动处理和人工复核分开。
| 输出场景 | 人最容易先下的判断 | 为什么这还不够 | 更好的读法 |
|---|---|---|---|
normal 0.70, scratch 0.20, contamination 0.10 | normal 第一名,所以直接确定 | 在这个例子里问题也许不大,但它没有留下“为什么可以自动确认”的标准 | 同时检查第一名与其他候选之间的分数差距是否足够大 |
normal 0.38, scratch 0.34, contamination 0.28 | normal 第一名,所以仍然直接判正常 | 候选差距太小,模型把握不高,却仍可能被自动确认 | 比起第一名名字,更先看差距不足,并转到人工复核流程 |
把这三个案例并排看时,就会发现:输出层的选择并不是先决定最后到底挂哪个函数,而是先决定最后那个数字到底应该被读成什么。
如果把这些案例里的数字重新固定成图,差异会更明显。回归里,最先看到的是预测值离真实值有多远。
二元分类里,则能更清楚地看出:像 0.91 这样的分数并不是策略本身,而是落在某个阈值区间里的模型输出。
多分类里,不能只盯着第一名的类别名字,还必须一起看第一名与第二名之间的差距到底大不大。
因此,在这些图里首先该看的不是曲线或柱子的样子,而是三种不同的解读单位:回归看距离、二元分类看阈值位置、多分类看候选差距。
| 问题类型 | 人最容易先看的结果 | 输出层实际应当留下的解释 | 与损失自然连在一起的输出感觉 |
|---|---|---|---|
| 回归 | 像“多少”这样的连续数字 | 可以直接和真实数值比较大小的连续值 | 与正确数字之间的距离 |
| 二元分类 | 像“拦还是放”这样的两选一 | 0~1 之间的分数,以及其后分离的政策 | 朝阳性类别倾斜了多少 |
| 多分类 | 第一名到底叫什么 | 候选之间的相对比较与分数差距 | 正确类别在多个候选中领先了多少 |
读者在这张表里首先要抓住的结果是:输出层激活的选择,不是选择一个函数名字,而是先固定最后那个将被拿来和正确答案比较的输出,究竟意味着什么。
练习与例题¶
即使看起来都像数字,输出层也必须按问题类型不同来不同地阅读。把下面三个场景放在一起看,这个差异会更明显。
| 问题类型 | 模型最后输出 | 首先该读的单位 | 损失函数首先会比较什么 |
|---|---|---|---|
| 回归 | 预测能耗 = 12.7kWh,正确答案 12.4kWh | 与正确数字的距离 | 预测值与真实值之间的误差 |
| 二元分类 | sigmoid output = 0.881,正确答案 阳性 | 阈值区间与政策分离 | 它朝正确的阳性类倾斜了多少 |
| 多分类 | normal 0.214, scratch 0.713, contamination 0.072,正确答案 scratch | 第一名候选与其他候选之间的差距 | 正确类别比其他候选领先了多少 |
这张表里首先必须看清的一点是:输出值的形状与它会怎样被拿去和正确答案比较是一起确定下来的。回归会保留数字本身,并直接看它离正确答案有多远。二元分类则把输出读成 0 到 1 之间的分数,再去看这个分数到底朝正确类别倾了多少。多分类不仅要看第一名是谁,还要看正确类别是否真的明显领先于其他候选。
如果把同一个场景再稍微改一下,也能更清楚看见“接下来到底该先重新看什么”。
| 改变后的输出场景 | 应该先重新看的标准 | 立刻该想到的问题 |
|---|---|---|
回归输出从 12.7 变成 13.2 | 与正确答案的距离,而不是数字本身的大小 | 它是不是离正确答案 12.4 更远了? |
二元分类输出从 0.881 降到 0.61 | 阈值策略与分数倾向 | 它是不是从“自动阻断”掉进了“现场确认”区间? |
多分类输出变成 0.38, 0.34, 0.28 这种彼此接近的结构 | 候选之间的差距,而不是第一名名字 | 这时人工复核会不会比自动确认更安全? |
在这个练习里,下面三个问题必须自己真正闭合。
- 为什么像
12.7这样的回归输出,应该先按它离正确答案12.4的距离来读,而不是像 sigmoid 或 softmax 那样去压缩后再读? - 为什么像
0.881这样的二元分类输出,应该先被看成一个落在阈值以上的模型输出,而不是策略本身? - 为什么在多分类里,光看到
scratch排第一还不够,还必须一起看它到底领先了其他候选多少?
答案方向是明确的。回归里,最后那个数字本身就是预测值,所以损失首先会比较它到底离真实答案差了多少。二元分类里,sigmoid 输出展示的是朝阳性类别倾斜的方向与强度,所以损失会结合真实标签是阳性还是阴性来读它。多分类里,多个候选本来就在一起竞争,因此损失也会自然地连到:正确类别到底有没有明显领先其他候选。
所以,这一节练习真正想让读者留下来的,不是用了哪个激活函数,而是最后那个数字到底该按什么单位来读,以及损失究竟会比较这个数字的哪一部分。
在早期神经网络与统计分类模型的教学传统里,最后的输出到底应该怎样读一直都是个核心问题。逻辑回归(logistic regression)与 sigmoid 的连接、多分类概率解释、以及损失函数如何与之配套,这些都不是深度学习出现以后才突然冒出来的问题。
这也是为什么在深度学习课程里,这一节必须存在。
- 如果把激活函数只当成隐藏层里的非线性,
- 就很容易漏掉:为什么最后那个输出会随着问题而改变,
- 等到下一章损失函数出现时,就会只剩下突然冒出来的一堆公式。
因此,这一节其实是在为下一章做准备:它要说明,损失函数并不是凭空出现的规则,而是和输出解读绑在一起的设计。
什么时候应该先把输出层解读单独分出来看¶
一旦隐藏层激活解释完,接下来就必须把最后那个数字到底该意味着什么单独分出来看。这一节正是负责这个转折点。
第一步,先问问题类型是什么。如果是连续值,就把最后的数字直接当预测值来读;如果是在两个选择之间做判断,就把 0 到 1 之间的分数与阈值策略一起读;如果是多个类别在竞争,就不要只看第一名名字,还要一起看候选分数与它们之间的差距。只有先把这个解读固定下来,损失函数“该怎样去读它与正确答案的差距”这一标准才会真正固定下来。
flowchart TD
A["预测目标是什么?"]
B["连续数值"]
C["二选一"]
D["多个类别中的一个"]
E["把数字当作数值保留"]
F["读取 0~1 分数<br/>并附上阈值策略"]
G["比较类别分数<br/>以及领先差距"]
H["连接到匹配的损失"]
A --> B
A --> C
A --> D
B --> E
C --> F
D --> G
E --> H
F --> H
G --> H
在这条流程里,尤其要小心的一点,是把服务里的策略与模型里的分数直接读成一回事。模型输出是拿来和正确答案比较的最后一个值,而自动阻断、现场确认、人工复核这些运行决策,属于它之后的下一步。只有先把输出层解读拆开,P5-4 里的损失函数与评估标准才会继续沿着同一个单位接下去。
检查清单¶
- 能否说明输出层激活的选择为什么会直接连到预测对象的意义?
- 能否解释为什么隐藏层激活与输出层激活不应该被当成同一个问题?
- 能否说明隐藏层激活与输出层激活承担的是不同角色?
- 能否说明输出层激活必须按问题类型与输出解读来选?
- 能否解释在回归、二元分类、多分类里,输出值应该怎样各自被阅读?
- 能否说明输出层激活与损失函数更适合被当成一对设计?
- 当自己因为它们都叫激活函数,就开始用同一种方式解释隐藏层与输出层时,能否主动把“输出解读问题”单独拆出来?
- 当很容易把 sigmoid 或 softmax 输出误读成服务策略本身时,能否主动区分模型分数与运行决策?
出处与参考资料¶
- 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 - Kevin P. Murphy,
Probabilistic Machine Learning: An Introduction, MIT Press, 2022, 确认日期: 2026-07-19. https://probml.github.io/pml-book/book1.html