
【斯坦福CS231n 学习笔记2】神经网络与反向传播
CS231n Lecture 4的笔记
神经网路架构
从线性到非线性
之前提到的线性分类器 虽然简单,但是其无法解决非线性可分问题,而通过一个非线性特征变换,例如将 映射到 这样的空间,原本线性不可分的点可能变得线性可分。
神经网络要做的事情就是“学习这类可用的中间表示”,而不是手工设计特征变换。以两层网络为例:
双层神经网络的数学表达为:
- :输入向量。
- :第一层权重,将输入变换到隐藏层空间。
- :非线性激活函数(此处为 ReLU)。
- :第二层权重,负责将隐藏层映射到输出类别分数。
如果去掉了中间的非线性函数,网络就将退化到线性分类器:
这意味着无论叠加多少层线性变化,其表达能力上都等同于单层的线性变换,即无法学习复杂的曲线边界,永远都只能画出一条“直线”。所以非线性激活函数是深度神经网络有效性的关键,在每一层线性变换后,通过强行插入一个非线性函数来引入非线性因素,使得深层网络能够逼近任意复杂的函数。
此处的神经网络更准确地只是全连接网络/MLP,而所谓的"2-layer net"通常是 1个隐藏层,"3-layer net"是 2 个隐藏层。
激活函数
理解激活函数的关键在于理解其导数(梯度)性质。
Sigmoid 函数
早期神经网络最常用的函数,模拟生物神经元的“全有或全无”特性。
其图像为:
作用是将输入压缩到 区间。
但是也有其缺陷:当输入的 非常大或非常小时,曲线变得极其平缓,近乎水平,在数学上这意味这局部梯度 ,在反向传播中,梯度是相乘的,如果每一层都乘以一个接近 0 的数,传递到浅层的梯度就会变成 0,网络前端的权重得不到更新从而导致训练停止,即梯度消失问题。并且由于 Sigmoid 的输出恒为正数,这意味着下一层神经元的输入恒为正数,会导致关于权重 的梯度要么全为正,要么全为负,这限制了参数更新的方向,使得收敛的路线呈现“之”字形,效率低下。此外, 是指数运算,比简单的加/乘运算消耗更多的 CPU/GPU 周期。
ReLU函数
最常用的深度学习激活函数。其公式为
图像为:
其优点是不饱和(在 的区域,梯度恒为 1。这意味着无论输入有多大,梯度都不会消失,极大地加速了随机梯度下降的收敛速度),计算极简(只需要计算 ,无任何指数运算)。
但是也存在 Dead ReLU 问题:在 的区域,梯度恒为 0, 如果某个神经元在一次权重更新后,使得对于所有训练数据其输入都小于 0,那么这个神经元就彻底“死”了。梯度永远是 0,权重永远不会再更新。为此也出现了很多 ReLU 的变种来解决这个问题:
Tanh函数
解决了零中心问题,但是依然存在梯度消失。
神经科学启发
虽然神经网络受到生物神经元启发,但是也不要过分依赖这种类比。人工神经元是非常粗糙的数学抽象,真正的生物神经元具有更加复杂的时序脉冲特性和不同的非线性机制。
反向传播
反向传播是计算梯度的递归算法,为了计算任意复杂函数的梯度,将函数分解为一系列基本操作,形成有向无环图:
- 前向传播:计算并存储每个节点的输出值。
- 反向传播:从最后的目标函数开始,递归计算每个节点关于输入的梯度。
链式法则
对于图中的任意节点 ,主要关注三个量:
- 上游梯度 :从网络后端传回的,表示最终 Loss 对该节点输出的敏感度。
- 局部梯度 ,:表示该节点当前的运算对输入的敏感度。
- 下游梯度 :需要的计算结果。
反向传播本质上就是链式法则的递归调用,假设 是最终的 Loss,要计算其对某个中间变量 的梯度:
常见门单元梯度行为
- 加法门:梯度分发器,将上游梯度原封不动地赋值给所有输入分支。
- 乘法门:梯度交换器, 的梯度会被放大 倍,这揭示了需要进行数据预处理的原因,输入数据量级过大会导致梯度爆炸。
- 最大值门:梯度路由器,梯度只流向值较大的那个输入,另一个输入的梯度为 0。
向量化反向传播
当输入的 是向量或矩阵时,梯度计算涉及到雅可比矩阵,如果 , 则 是一个 的雅可比矩阵。现实是从不会显式计算并存储雅可比矩阵,而是直接推导矩阵形式的梯度公式。
设 ,其中 为标量损失函数,已知上游梯度 ,则有
这是实现神经网络层的核心数学依据:权重的梯度等于“上游梯度”与“层输入转置”的矩阵乘积。
参考如下:
https://cs231n.stanford.edu/index.html
