前言:一个被忽略的“灵魂”组件
在搭建一个简单的全连接网络时,初学者往往会把“线性层(Linear)”和“激活函数(Activation)”视为两个割裂的模块。甚至有人会问:“反向传播不是对损失函数求导来更新权重吗?这里面有激活函数什么事?”
这个问题直击神经网络设计的核心。如果回答不清,我们对反向传播的理解就停留在“背公式”的层面。本文将带你从为什么必须要有激活函数开始,一步一步推导出它在反向传播(复合函数求导)中扮演的关键角色,并最终解释为什么ReLU能成为工业界默认首选。
第一章:前因——如果没有激活函数,神经网络会怎样?
1.1 线性叠加的“塌缩”危机
假设我们构建一个3层网络,每层只有线性变换(即没有激活函数,或激活函数为 f(x)=x):
将第1层代入第2层,再代入第3层:
你会发现,无论网络堆叠多少层,最终输出的 z3 依然是输入 x 的一次线性函数(即)。这意味着多层网络退化成了单层网络,网络的深度完全没有意义,根本无法拟合复杂的非线性数据(如识别图像、理解语言)。
1.2 全零初始化的“对称性”僵局
退一步说,即使不加激活函数,如果我们把权重全部初始化为0,情况会更糟。反向传播时,同一层的所有神经元接收到的误差信号完全相同,计算出的梯度也完全相同。因此,所有神经元在训练过程中永远保持同步更新,网络有效宽度退化为1,彻底丧失学习能力。
结论:为了打破线性塌缩和对称性,必须在线性层之间插入非线性函数(激活函数)。这是它存在的第一层“前因”。
第二章:前向传播——激活函数在计算图中的位置
有了激活函数,前向传播的计算链条就不再是简单的乘加,而是分成了明确的几步(以单隐层为例):
线性求和:z=w⋅x+b
非线性映射(激活函数):a=f(z),这里的 f 可以是 Sigmoid、Tanh 或 ReLU。
损失计算:L=Loss(a,y),如 MSE 或交叉熵。
为什么要把它单独拎出来?
因为线性层只负责“空间投影”,而激活函数负责“幅度限制”和“非线性扭曲”。例如,Sigmoid 将 z 压缩到 (0,1) 区间,使其具有概率意义;ReLU 则将负数直接置零,引入稀疏性。两者分工明确,缺一不可。
第三章:核心硬核——反向传播中“激活函数被强塞进来”的数学必然
这是本文最核心的部分。我们抛开抽象的链式法则缩写,直接用复合函数逐层求导的方式,看激活函数是如何“无处可逃”地出现在梯度中的。
3.1 简单复合(一层网络)
设网络为:
这里 f 是激活函数。
我们要算。根据复合函数求导的“剥洋葱”法则:
最外层(平方):设
,则
,导数为
。
中间层(减法):
(因为 y 是常数)。
最内层(激活与乘法):令
,则
。导数为
。
拼回完整结果:
肉眼可见:最终更新权重 w 的梯度公式中,硬生生乘了一个(激活函数的导数)。如果没有它,梯度方向和大小就全错了。
3.2 深度复合(三层网络,看连乘效应)
现在堆叠3层,只保留第一个权重 w1 作为变量,其余视为常数。前向传播代入后:
依葫芦画瓢,从外往里逐层求导,最终得到的梯度为:
这里揭示了两个极其重要的真相:
误差传递的“必经关卡”:来自损失函数的误差信号
要传到第一层权重 w1,必须连续闯过 3 道激活函数的导数关卡
。这就是反向传播时,激活函数必须参与计算的物理意义——它决定了误差信号能否顺利“穿透”该层。
连乘的灾难性后果(梯度消失/爆炸):
如果使用Sigmoid,其导数
,最大值仅为0.25。
3层相乘:0.253=0.01560.253=0.0156,信号迅速衰减。
100层相乘:0.25100≈00.25100≈0,浅层梯度直接消失,网络无法训练。
第四章:后果——为什么工业界首选 ReLU 作为隐藏层默认激活?
正是因为上述“连乘效应”,Sigmoid 和 Tanh 在深层网络中逐渐淡出隐藏层。ReLU(修正线性单元)异军突起,源于它对上述数学特性的完美规避:
计算效率极高(应对关卡①):ReLU 的公式为
。前向传播只比大小,反向传播的导数 f′(x) 只需判断输入是否大于0(即
)。没有 Sigmoid 的指数运算,也没有 Tanh 的平方运算,极大地提升了训练和推理速度。
硬性阻断梯度消失(应对关卡②):在正区间 (x>0),ReLU 的导数恒等于1。这意味着在反向传播的连乘中,只要该神经元处于激活状态,误差信号通过它时模长完全不衰减(乘以1)。这保证了深层网络的误差能无损地传回浅层,使得训练上百层的网络成为可能。
稀疏性带来的泛化收益(应对关卡③):ReLU 在负区间输出严格为0。这导致网络中的神经元呈现出稀疏激活的特性(约50%的神经元输出为0)。这种机制减少了神经元间的复杂共适应关系,起到了类似于天然正则化的效果,有效缓解了过拟合。
第五章:工程视角的升华(Autograd 在做什么?)
你可能会好奇,既然推导这么复杂,为什么我们在 PyTorch 或 TensorFlow 中写代码时,只需要调用loss.backward()就完事了?
原因在于自动微分(Autograd)机制。框架预先为每一个张量操作(包括加法、乘法、Sigmoid、ReLU)构建了计算图(Computational Graph)。当执行反向传播时:
框架从损失节点出发。
遍历计算图的逆序。
每遇到一个节点(比如 ReLU 节点),就调用其预置的局部导数(阈值判断),乘以从后方传回的梯度。
直到到达权重节点,计算出最终梯度。
所以,我们推导的公式,正是 Autograd 在后端默默执行的全部数学过程。理解它,才能理解为什么模型会收敛,抑或为什么会梯度消失。
总结
| 环节 | 激活函数的角色 | 关键数学特征 |
|---|---|---|
| 前因(必要性) | 打破线性塌缩,赋予网络非线性拟合能力 | 非线性函数 |
| 前向传播 | 将线性空间映射到非线性空间(如概率、稀疏特征) | |
| 反向传播 | 作为误差传递的必经过的乘法因子,决定信号衰减程度 | 导数 |
| 深度网络挑战 | 多个 | 连乘结构 |
| 工程最优解(ReLU) | 正区间导数为1,阻断衰减;计算简单 |
激活函数并非简单的“非线性装饰”,而是深度学习中信号传递的控制阀门。只有深刻理解它在复合函数求导中留下的“数学痕迹”,才能真正驾驭深层网络的训练艺术。