P5-3.1 激活函数(activation function)¶
Section ID:
P5-3.1Version:v2026.07.20
在 P5-2.2 里,我们已经看到:隐藏层(hidden layer)能够把输入改写成更有用的内部表征(representation)。接下来就会立刻出现一个问题。
神经网络并不只是反复做加权和,那么真正让这种变化发生的东西到底是什么?
承担这个角色的,就是激活函数(activation function)。
激活函数会接收某个节点形成的加权和分数 \(z\),把它转换成传给下一层的值 \(a\)。
也就是说,在一个节点内部,通常会发生下面这条顺序:输入值 -> 加权和分数 z -> 激活函数 f -> 传给下一层的值 a。激活函数不是一个单独负责学习的模型,而是一条变换规则:它决定算出来的分数是原样传过去、弱弱地保留,还是强烈地保留。
如果只把这个位置关系单独画出来,就是下面这样。
flowchart TD
A["输入值"]
B["加权和<br/>分数 z"]
C["激活函数<br/>f"]
D["传给下一层的值 a"]
A --> B
B --> C
C --> D
一旦这条变换规则不再只是简单的比例关系,非线性(nonlinearity)就出现了,神经网络也才能表达更复杂的模式。
如果后面需要重新快速固定激活与非线性的基线,可以回到英文概念词汇表里的 activation function 条目。
需要激活函数的问题¶
- 为什么需要激活函数?
- 如果只反复做线性组合,为什么表达能力会受限?
- 说“加入非线性(nonlinearity)”到底是什么意思?
- 激活函数与隐藏层表征之间是什么关系?
代表性激活函数之间的差异会在 P5-3.2 到 P5-3.5 继续。输出层激活与损失函数的连接会在 P5-3.6、P5-4.1、P5-4.2 再回来看。关于 gradient flow 的更细背景,则会在 P5-5.1 与 P5-7.1 重新接上。也就是说,这一节先要闭合的是:为什么激活函数能把只重复线性计算的结构真正变成有表达力的结构。
非线性与表达能力的判断标准¶
- 能把激活函数解释成
给分数施加非线性变换的规则。 - 能理解如果只重复线性组合,整个网络仍然容易重新折叠成一个线性映射。
- 能说明为什么激活函数是多层神经网络真正获得表达力的关键原因。
- 能通过比较激活前后的数值,解释哪些信号被切断、哪些信号得以保留。
为什么需要激活函数¶
在第 1 章与第 2 章里看过的神经网络计算,基本都有下面这个结构。
接收输入
-> 形成加权和(weighted sum)
-> 把输出传给下一层
问题在于:如果这些中间步骤全部都只是线性(linear)计算,那么即使把层数堆得很多,整体也未必会真正复杂起来。
这里可以先用下面这句话把它固定下来。
如果只重复线性计算,神经网络就很难真正学到更复杂的形状与规则。
也就是说,仅仅增加层数还不够。层与层之间还需要一种把直线关系折弯的变换。这个变换,就是激活函数。
非线性(nonlinearity)到底是什么意思¶
非线性是读者最容易觉得抽象的词之一。这里先把它理解成下面这句话就够了。
即使输入只变动了一点,输出也不再总是按一条直线那样等比例变化的性质。
例如:
- 在某个值以下几乎不反应,
- 从某个区间开始反应突然变大,
- 或者低于标准的信号几乎不传,只把高于标准的信号更明显地保留下来,
一旦出现这些规则,模型就已经不再只是一个简单的直线判断器,而能够表达更复杂的模式。
为什么只靠线性组合不够¶
假设我们把线性组合重复很多层。
- 第一层把输入变成加权和。
- 第二层又把这个输出重新变成另一个加权和。
但如果中间没有任何非线性变换,那么这一连串计算最终还是很容易被重新合并成一个更大的线性变换。
也就是说:
线性组合
-> 线性组合
-> 线性组合
如果只不断重复这个过程,模型虽然变深了,但表达力不一定会如预期那样显著增加。
正因为如此,在深度学习里,激活函数不是某种附加功能,而是让深度真正有意义的关键装置。
把这个意思画得最简单,就是下面这样。
flowchart TD
A["线性层 1"]
B["线性层 2"]
C["整体仍像一个更大的线性映射"]
A --> B
B --> C
这张图要确认的结论是:就算线性层堆了很多次,只要中间没有非线性变换,整个结构最终仍然会折回成某种更大的线性计算,因此表达力不会自动显著变强。
相反,只要中间插入激活函数,流程就会变成另一种样子。
flowchart TD
A["线性层"]
B["激活<br/>非线性变换"]
C["线性层"]
D["更丰富的表征"]
A --> B
B --> C
C --> D
这张图要确认的结论是:激活函数在两个线性计算之间插入了非线性变换,于是下一层就能形成更复杂的表征,深度也才能真正连到表达力的提升上。
激活函数到底对分数做了什么¶
把前面的式子再读一遍。
- \(z\):线性组合形成的分数
- \(f\):激活函数
- \(a\):传给下一层的新值
这一节里重要的,不是去背某个具体函数名,而是要先理解:激活函数不会把算出来的分数原样传过去,而是把它改写成下一层更适合使用的形式。
所谓非线性变换,就是它不再遵守那条z 每增加 1,a 也总按同样比例增加 1的直线规则。比如可以先考虑下面这个教学用规则。
这个式子并不是为了让你去记某个代表性激活函数的名字,而只是为了说明:同样是分数 \(z\),在不同区间里,它被变成 \(a\) 的方式可以完全不同。负数区间里信号会变弱;中间区间里则比较直接地被传过去;而在较大正数区间,增长又会被重新压住。于是整条曲线就不再是一条直线,而会在中间拐弯。
上图里的灰色虚线是像 a = z 这样把分数原样传过去的线性通过。蓝色曲线则是会按区间改变反应的非线性变换。说激活函数带来了非线性变换,意思就是:下一层拿到的值 \(a\) 不再只是 \(z\) 的复制品,而是像这样会随着区间变化而拥有不同含义的值。
隐藏层与激活是怎样连在一起的¶
在 P5-2.2 里,我们说过隐藏层会形成内部表征。激活函数正是那个让这种表征不至于停留在线性复制上的装置。
也就是说:
- 加权和负责把输入信号组合起来,
- 激活负责对这种组合施加非线性变换,
- 于是下一层才有可能形成更复杂的内部表征。
正因为有这条连接,激活函数不应该只被看成某种简单的输出规则,而应该被看成让 representation learning 成立的装置。
案例与例子¶
案例 1. 设备视觉信号分类¶
假设设备摄像头的画面需要区分正常的管线区段、警示灯亮起的阀门区段、压力表指针进入危险区的面板。人很容易觉得,只要把警示灯轮廓、管线边缘、仪表盘外框这些类似边线(edge)的信号多加一点,应该就足够了。
这里首先该看的是:激活函数到底插在什么位置。 可以想成某个中间节点接收了警示灯轮廓、指针位置、圆形仪表盘边框这些视觉线索,先形成一个线性分数 \(z\),再由激活函数把这个 \(z\) 变成传给下一层的值 \(a\)。
也就是说,在这个案例里,激活函数不是直接读取图像的装置,而是把中间节点形成的线性分数 z 转成下一层要读的值 a 的规则。
例如,这个案例可以按下面顺序来读。
- 如果某个画面里虽然能看到管线边缘,但警示灯与危险指针的组合很弱,那么线性分数 \(z\) 很容易停留在接近阈值以下的位置。
- 再继续看激活之后的值时,就会发现阈值以下的部分几乎被削弱,因此下一层不太会把它读成强危险信号。
- 相反,如果某个画面里警示灯轮廓与危险指针位置同时都很强,那么线性分数 \(z\) 就会明显升高。
- 这个画面在经过激活后,也会作为较大的值活下来,于是下一层更容易把它读成一种
危险组合。
如果所有计算都保持线性,那么就算堆很多层,最后仍可能只像一个更大的线性滤波器:这个特征多一点,分数就多一点。 但一旦中间插入激活,就会出现有些分数几乎被切掉、有些分数被保留下来的情况,于是像只有警示灯和指针位置同时出现时才强烈反应这样的复杂条件才会成为可能。这也会让一些共享相似线条的画面,例如管线弯曲与圆形仪表边框等,能够被表达成更不同的状态。
所以在这个案例里,要确认的结果是:即使不同画面共享相似的线条信号,激活函数仍然不会把线性分数 \(z\) 原样复制下去,而是会把它过滤成只对某些组合更强烈反应的中间表征,从而让这些画面更清楚地分到不同的运行状态上。
人很容易把这里理解成“多看到了几条线,分数就稍微更高一点”。但如果用激活视角重新来读,真正的关键并不在于线索数量,而在于哪些组合跨过了标准、哪些组合在中间几乎被切掉了。所以即使管线弯曲与仪表盘边框都带有相似的线条信号,也仍可能形成一种只在特定组合下才更强烈地活下来的表征。
这个案例的核心是:同样都是视觉线索组合,它们会因为弱 -> 边界 -> 强而分裂成不同的 \(z\) 与不同的激活结果。下面的公共图,会把这条流程和运行表格数据案例一起重新捆起来。
案例 2. 运行表格数据¶
再假设我们一起看一张设备状态表中的最近报警次数、压力恢复延迟时间、重启失败次数。人很容易觉得,只要把这些数字一点点加起来,就足够读出当前是否危险。
但在这个场景里,激活函数同样不能只被读成“有它会更复杂”这种泛泛必要性说明,而必须被读成:把线性分数 z 改写成下一层要接收的值 a 的规则。某个中间节点会先接收报警次数、恢复延迟与失败次数,先形成线性分数 \(z\),然后再由激活函数把它改写成 \(a\)。
也就是说,在运行表格数据里,激活函数不是直接读取表格的规则,而是决定这个合成后的风险分数会不会被下一层忽略、弱弱保留、还是强烈保留的规则。
这个案例也可以按同样顺序来读。
- 像
1 次报警、恢复延迟很短、失败 0 次这样的状态,如果只看线性分数 \(z\),很容易停留在阈值以下。 - 再把这个值继续跟到激活之后,就会发现它几乎被削弱掉,因此不太会继续形成下一层里的强危险表征。
- 像
2 次报警、恢复延迟中等、失败 1 次这样的状态,只看线性分数时,可能看起来只是略高一点的连续分数。 - 但如果继续看激活后的值,它更像是一种刚刚高于边界、勉强活下来的弱信号。
- 像
4 次报警、恢复延迟很长、失败 2 次这种多个信号叠加的状态,不仅线性分数会很高,激活之后也会留下很大的值,形成下一层应该继续关注的强危险组合信号。
现实里,真正需要的往往是某种带拐点的规则,例如:只有当报警次数多、而且压力恢复也慢时,才强烈地把它看成危险。 如果只重复线性组合,那么所有值都容易停留在“每个量都只是稍微多加一点”的简单关系里。但只要加入激活,就能形成:只有越过某个区间才会明显放大、在较低区间则几乎不反应的表征。
即便是同一台设备,如果把状态按三个区间重新来看,也能更快看出为什么表征到底有没有真正活下来比把值一点点加起来的总和更重要。只有微弱异常信号的状态,如果仍停在阈值以下,那么它几乎会被削弱掉,不会在下一层里继续显著存在。看起来有些暧昧、但稍微更危险一点的状态,则会作为一种刚好高于边界的弱信号活下来。反过来,任何人都能看出已经明显危险的状态,则会以强信号形式被保留下来,供下一层继续使用。
如果把同样输入拆成只看线性分数与继续看激活后的值来对比,差异就更明显了。只看线性分数时,报警次数、恢复延迟、失败次数会像一个每项都稍微加一点的连续和,因此容易让人感觉所有信号都只是在连续分数上平滑地反映。可一旦继续看激活后的值,就会发现阈值以下的部分实际上几乎被削弱掉,最后真正留下的只是一部分组合。也正是在这个时候,只有当这组条件一起出现时,危险表征才真正点亮这样的规则才会变得更直接。
在这个案例里,运行信号组合同样会随着弱 -> 边界 -> 强而变成不同的 \(z\) 与不同的激活结果。每个案例自己的过程由正文句子来读,而图只压缩两类案例共同留下来的“信号如何活下来”的公共流程。
换句话说,激活函数可以被理解成一种跨越不同数据领域的共同装置:它让更复杂的规则表达成为可能。 所以这个案例真正要确认的结果,不是那种每个值都一点点相加的简单总分,而是某些条件组合是否真的会让危险信号更强烈地被保留下来。
如果再把这两个案例压成一个场景,读者真正要抓住的共同流程就是下面这样。
flowchart TD
A[较弱的组合信号] --> B[线性分数 z 仍然偏低]
B --> C[激活几乎把它切掉]
C --> D[几乎没有信号到达下一层]
E[边界附近的组合信号] --> F[线性分数 z 刚刚抬起]
F --> G[激活留下一个小正值]
G --> H[弱信号勉强存活]
I[强组合信号] --> J[线性分数 z 明显升高]
J --> K[激活让它继续保持活跃]
K --> L[强信号到达下一层]
这张图并不是为了把案例 1 的视觉信号和案例 2 的运行表格数据再各画一遍,而是为了让读者一次重新读到两者共同显示出来的那条激活流程:弱 -> 几乎被切掉、边界 -> 弱弱存活、强 -> 强烈存活。
如果把这条流程落回练习里使用的数值,那么激活前分数 \(z\) 与激活后数值 \(a\) 的差异,大致会像下面这样。
在这张图里,原本是负数的两个状态在激活后都会贴近 0,边界刚上的信号只会弱弱保留,而强警告信号则会以较大的值活下来。也就是说,就算原始运行信号相同,下一层真正收到的值在激活前后也已经不再相同。
把两个案例并排看时,就会发现激活函数的作用并不只是把阈值以下的信号削弱一点。在设备视觉信号分类里,看起来像一个大分数的线条相加画面,会在激活后变成只对警示灯 + 指针这类特定轮廓组合才更强烈反应的中间表征。在运行表格数据里,看起来像报警次数、恢复延迟、失败次数不断相加的输入,也会在激活后变成:阈值以下部分几乎被削弱,而报警反复 + 恢复延迟这类条件组合会更强烈地活下来。
读者这里首先要抓住的结果是:激活函数不只是一个改数字的装置,而是一个会改变下一层到底重新把什么看成重要信号的装置。
练习与例题¶
这次练习的目标,是通过对比案例,确认激活函数如何把线性组合分数改成传给下一层的值。这次不会只看一个输入,而是把多个运行状态并排放在一起,看哪些信号会活下来,哪些会几乎消失。
输入:
- 最近报警次数
- 压力恢复延迟分数
- 重启失败次数
- 三个信号对应的权重
- 偏置
- 四个不同的运行状态案例
输出:
- 线性组合结果
z - 激活之后的结果
a - 哪些输入会活下来、哪些输入几乎消失的对比
- 刚好在边界附近的弱信号,与明显存活下来的强信号的对比
问题场景:
- 我们需要直接确认:激活函数不会把线性分数原样复制,而是会如何改变真正留给下一层的信号
要确认的概念:
- 激活函数不会原样保留线性组合结果,而会改写下一层要接收的值
- 把激活前后并排来看,最容易看出哪些信号真正会被传递下去
输入(input):
沿用上面的运行表案例,假设某个中间节点会接收最近报警次数、压力恢复延迟分数、重启失败次数,并据此先形成线性分数 \(z\)。这里所谓的压力恢复延迟分数并不是直接拿真实分钟数,而是为了练习而做的简化输入:恢复越慢,分数越大,大致落在 0 到 3 左右。
这次练习使用下面这条计算规则。
激活之后的值 \(a\) 则按下面这条规则读取。
这条规则并不是要开始比较代表性激活函数,而只是为了实验一种简单感觉:阈值以下的信号几乎不会继续留给下一层,阈值以上的信号则会带着大小差异继续保留下来。
先看输入值。
| 案例 | 最近报警次数 | 压力恢复延迟分数 | 重启失败次数 | 人最容易先读出的状态 |
|---|---|---|---|---|
brief_alarm_recovered | 1 | 0.5 | 0 | 报警短暂出现过,但很快恢复的状态 |
recovery_dominant_signal | 0 | 0.5 | 0 | 恢复趋势占优,危险信号较弱的状态 |
borderline_warning_signal | 2 | 2.3 | 0 | 报警与延迟叠在一起、刚好卡在边界附近的状态 |
strong_warning_signal | 4 | 3.0 | 2 | 报警反复、恢复延迟、重启失败一起叠加的状态 |
在看表之前,最好先猜一猜激活之后它们会怎样。
| 案例 | 先猜什么结果 | 直觉原因 |
|---|---|---|
brief_alarm_recovered | z 应在阈值下方,a 几乎不会留下 | 虽然短暂报警过,但恢复很快、也没有失败,应该更容易停在阈值以下 |
recovery_dominant_signal | z 应在阈值下方,a 几乎不会留下 | 恢复延迟分数低,失败又没有,因此下一层几乎看不到它 |
borderline_warning_signal | z 和 a 都会成为一个刚过边界的弱信号 | 报警与延迟叠加,但还不够形成明显强信号 |
strong_warning_signal | z 和 a 都会是很强的信号 | 报警反复、恢复延迟、重启失败一起叠加,足以明显越过边界 |
这张预测表的目的,并不是要求精确猜中小数点,而是让你先固定两件事:激活函数不会原样复制线性分数,以及边界刚上方的弱信号和明显超出的强信号必须被分开阅读。
把这四个状态用一种更简单的激活视角重新整理,就会得到下面这张表。这里使用的数值不是为了重新精确复现前面那个教学用分段函数,而只是为了观察一种简单规则:阈值以下的信号会几乎消失,阈值以上的信号则会保留下来。目标不是去背函数名字,而是看清:激活前分数 z 与下一层真正接收到的值 a,并不是同一回事。
| 案例 | z 计算 | z | 激活后的值 | 从下一层视角看见的状态 |
|---|---|---|---|---|
brief_alarm_recovered | 0.5*1 + 0.4*0.5 + 1.2*0 - 1.5 | -0.8 | 0.0 | 虽然短暂晃动,但几乎不会继续传到下一层 |
recovery_dominant_signal | 0.5*0 + 0.4*0.5 + 1.2*0 - 1.5 | -1.3 | 0.0 | 几乎不会被继续传递的信号 |
borderline_warning_signal | 0.5*2 + 0.4*2.3 + 1.2*0 - 1.5 | 0.42 | 0.42 | 刚刚活下来的弱信号 |
strong_warning_signal | 0.5*4 + 0.4*3.0 + 1.2*2 - 1.5 | 4.1 | 4.1 | 下一层可以继续强烈使用的信号 |
再把这张表与前面的图重新连起来,就更容易看出差别。z 是线性组合形成的原始位置,而 a 则是激活之后下一层真正收到的位置。
如果把它重新连回只看线性分数这一视角,差异会更清楚。只看线性分数时,阈值以下的值也不过像一种比较小的连续分数;但一旦看激活之后的值,就会发现 brief_alarm_recovered 与 recovery_dominant_signal 实际上已经被压到几乎 0,因此对下一层来说几乎等于不存在。相反,borderline_warning_signal 与 strong_warning_signal 虽然都在边界以上,但意思完全不同。一个只是刚刚活下来的弱信号,另一个则是下一层可以继续强烈使用的强信号。激活之所以让深度真正有意义,也正是在这里:它不只是让你比较线性分数的大小,而是真正改变了下一层输入的组成。
如果继续把这些输出重新接回真实运行判断,就会更清楚地看到:为什么把边界以上都当成一样的警告会有问题。
如果把 borderline_warning_signal 与 strong_warning_signal 都当成“强警告”,就可能把本来只需要跟踪的弱信号也推成过度停机。它们都活了下来,但一个只是弱追踪信号,另一个才是强警告。反过来,如果把 brief_alarm_recovered 与 borderline_warning_signal 都当成“有点模糊”,又会忽略它们本质上已经不同:前者几乎被切掉,后者则还勉强留下了继续追踪的价值。若把刚越过边界的信号也读成和 0 一样,就会漏掉弱异常的早期痕迹。
所以,这一节真正该看的,不是某个代表性函数的名字,而是激活函数怎样决定:哪些信号会几乎消失,哪些信号会弱弱活下去,哪些信号会强烈保留下来。
如果再从学习视角重新压缩一次,这个练习的重点就不是背答案表,而是自己能够解释:边界到底在哪里、为什么刚好高于边界的信号与明显更大的信号不能读成同一种东西、为什么几乎被切掉的信号对下一层来说几乎已经不可见。
最后,再亲手改几个值试试看。下面这张表就是几个可以手算的小实验。
| 可以改的值 | 重新计算哪个案例 | z 怎样变化 | 激活后怎样变化 | 现在要问的解释问题 |
|---|---|---|---|---|
把偏置从 -1.5 降到 -2.0 | borderline_warning_signal | 0.42 -> -0.08 | 0.42 -> 0.0 | 如果边界往后移,会漏掉多少弱异常信号? |
把重启失败次数的权重从 1.2 提高到 1.6 | strong_warning_signal | 4.1 -> 4.9 | 4.1 -> 4.9 | 如果中间表征对失败信号更敏感,哪些案例会被进一步放大? |
把 borderline_warning_signal 的恢复延迟分数从 2.3 降到 1.0 | borderline_warning_signal | 0.42 -> -0.1 | 0.42 -> 0.0 | 如果恢复变快,弱警告与正常恢复该在哪里被重新分开? |
只看激活后的值,这三种调整会像下面这样发生变化。
降低偏置或减少恢复延迟,都会把原本边界上的信号压回 0;而提高失败权重,则会让已经很强的信号进一步被放大。
把这个实验做完之后,就能确认:即使输入相同,只要权重与偏置改变,边界就会移动;边界一旦移动,真正留给下一层的信号也会跟着改变。
如果没有激活函数,为什么深度学习会变弱¶
如果没有激活函数:
- 看起来层数很多,
- 但中间表征并没有真正被折弯,
- 整体仍可能重新折回成一个更大的线性计算。
相反,只要有激活函数:
- 某些信号会被保留,
- 某些信号会被切掉,
- 下一层也才有可能形成更复杂的组合。
正因为如此,深度学习的深度(depth)必须和激活函数一起读,才会真正有意义。
从深度学习历史上看,感知机与多层神经网络之所以会重新受到重视,其中一个关键也正和这里相连。单个感知机的局限其实很早就已经被看见,但当多层结构、非线性激活,以及足以训练它们的计算资源和算法重新合到一起之后,神经网络才真正开始拥有强大的表征能力。
从课程结构上看,激活函数也必须在前半段就被明确拿出来讲,原因很直接。
- 看感知机时,会理解线性组合;
- 看多层神经网络时,会理解中间表征;
- 看激活函数时,才会理解为什么这些中间表征不只是线性复制。
也就是说,激活函数正是 Part 5 前半段最关键的连接件之一。
什么时候应该先拿激活函数视角来读¶
需要把激活函数这一节拿出来的时候,通常是你已经理解了“为什么要堆层”,但为什么这个深度不只是单纯重复线性计算还没有完全闭合的时候。
| 先遇到的问题场景 | 为什么先用激活函数视角更有用 | 下一步马上要接的问题 |
|---|---|---|
| 明明堆了很多线性层,却还是说不清为什么会更复杂 | 它能说明:真正把深度变成表达力的是中间的非线性变换 | 接着就要看代表性激活函数到底有哪些不同反应 |
| 需要更清楚地说明:隐藏层表征为什么不是简单复制 | 它能接上“加权和之后,有些值会被保留,有些值会被折断”这条规则 | 接下来要过渡到各个代表性激活函数的差异 |
| 对多层结构的说明有沦为结构名称介绍的风险 | 只有把激活函数补上,结构才会开始被读成真正的计算过程 | 后面还要区分它与输出层解读有什么不同 |
| “非线性”这个词仍然显得太抽象 | 因为这里正是用来把“只重复线性还不够”这件事真正闭合的地方 | 接下来必须立刻接具体函数例子来比较 |
检查清单¶
- 能否解释为什么激活函数是引入非线性(nonlinearity)的装置?
- 能否说明如果没有激活函数,深度为什么难以真正转化成表达力?
- 能否解释激活函数是一条会对加权和分数施加非线性变换的规则?
- 能否说明:只重复线性组合时,即使层数增加,表达力也未必足够提高?
- 能否说明激活函数为什么是隐藏层形成更有用内部表征的关键装置?
- 能否解释为什么只增加层数还不够,必须同时有激活函数?
- 至少能否用“让输出不再只遵守直线比例关系”来解释非线性?
- 在还没开始比较函数名字之前,如果需要重新固定“为什么激活是必要的”,能否把这一节当作基准线?
出处与参考资料¶
- Ian Goodfellow, Yoshua Bengio, Aaron Courville,
Deep Learning, MIT Press, 2016, 确认日期:2026-06-29. https://www.deeplearningbook.org/ - Yann LeCun, Yoshua Bengio, Geoffrey Hinton,
Deep learning, Nature, 2015, 确认日期:2026-06-29. https://www.nature.com/articles/nature14539