神经网络入门(一)
文章目录
- 神经网络入门(一)
- 1. 神经元
- 2. 网络结构
- 3. 激活函数
- 2.1 激活函数的作用与性质
- 2.2 Sigmoid型函数
- 2.3 Hard-Logistic函数和 Hard-Tanh函数
- 2.4 ReLU函数
- 2.5 常见的激活函数及其导数
- 4. 前馈神经网络
- 4.1 前馈神经网络简介
- 4.2 参数学习
- 5. 反向传播算法
- 5.1 链式法则
- 5.2 计算各项
- 5.3 算法步骤
- 5.4 优化问题
- 6. 自动梯度计算
- 6.1 数值微分
- 6.2 符号微分
- 6.3 自动微分
在学习神经网络之前,你可能需要一点机器学习的基础。其中机器学习的相关内容可以参考:超级简单的机器学习入门
人工神经网络(Artificial Neural Network,ANN)模拟了生物神经网络,构建人工神经元,并按照一定拓扑结构来建立人工神经元之间的连接.
神经网络一般可以看作一个
非线性模型
,其基本组成单元为具有非线性激活函数的神经元
,大量神经元之间相互连接
,神经元之间的连接权重
就是需要学习的参数。误差反向传播
机制大大提高了神经网络的学习能力,基于此可以在机器学习的框架下通过梯度下降方法
来进行学习。
1. 神经元
1)神经元是构成神经网络的基本单元,用来接收一组输入信号并产生输出.
-
其中
MP神经元
是比较原始基础的神经元。 -
特点:MP 神经元中的
激活函数
𝑓为0或1的阶跃函数
,而现代神经元中的激活函数通常要求是连续可导的函数
.
2)假设一个神经元接收𝐷 个输入
𝑥
1
,
𝑥
2
,
⋯
,
𝑥
𝐷
𝑥_1, 𝑥_2, ⋯ , 𝑥_𝐷
x1,x2,⋯,xD,令向量
𝒙
=
[
𝑥
1
;
𝑥
2
;
⋯
;
𝑥
𝐷
]
𝒙 = [𝑥_1; 𝑥_2; ⋯ ; 𝑥_𝐷]
x=[x1;x2;⋯;xD]来表示这组输入,并用净输入
𝑧 ∈ ℝ 表示一个神经元所获得的输入信号𝒙的加权和
。
其计算公式如下:
z
=
∑
d
=
1
D
w
d
x
d
+
b
=
w
⊤
x
+
b
\begin{aligned} z & =\sum_{d=1}^{D} w_{d} x_{d}+b \\ & =\boldsymbol{w}^{\top} \boldsymbol{x}+b \end{aligned}
z=d=1∑Dwdxd+b=w⊤x+b
- 其中
𝒘
=
[
𝑤
1
;
𝑤
2
;
⋯
;
𝑤
𝐷
]
∈
R
𝒘 = [𝑤_1; 𝑤_2; ⋯ ; 𝑤_𝐷] ∈ ℝ
w=[w1;w2;⋯;wD]∈R,𝐷 是𝐷 维的权重向量,𝑏 ∈ ℝ 是偏置.
3)净输入𝑧在经过一个非线性函数𝑓(⋅)后,得到神经元的活性值 𝑎
,
𝑎
=
𝑓
(
𝑧
)
𝑎 = 𝑓(𝑧)
a=f(z)
- 其中非线性函数𝑓(⋅)称为
激活函数
.激活函数的具体介绍可以看下一小节。
4)一个典型的神经元结构示例
2. 网络结构
单一的神经元是远远不够完成复杂的功能,需要通过很多神经元一起协作.这样通过一定的连接方式
或信息传递方式
进行协作的神经元可以看作一个网络,就是神经网络
.
目前常用的神经网络有三种
1)前馈网络
- 前馈网络中各个神经元按接收信息的先后分为不同的组.每一组可以看作一个神经层.每一层中的神经元接收前一层神经元的输出,并输出到下一层神经元.
- 整个网络中的信息是朝一个方向传播,没有反向的信息传播,可以用一个
有向无环路图
表示. - 前馈网络包括
全连接前馈网络
和卷积神经网络
等. - 前馈网络可以看作一个函数,通过简单非线性函数的多次复合,实现输入空间到输出空间的复杂映射.这种网络结构简单,易于实现.
2)记忆网络
记忆网络
,也称为反馈网络,网络中的神经元不但可以接收其他神经元的信息,也可以接收自己的历史信息
- 和前馈网络相比,记忆网络中的神经元具有记忆功能,在不同的时刻具有不同的状态.
- 记忆神经网络中的信息传播可以是单向或双向传递,因此可用一个有向循环图或无向图来表示.
- 记忆网络包括
循环神经网络
、Hopfield 网络
、玻尔兹曼机
、受限玻尔兹曼机
等.
3)图网络
- 前馈网络和记忆网络的输入都可以表示为向量或向量序列.但实际应用中很多数据是图结构的数据,比如
知识图谱
、社交网络
、分子网络
等. - 图网络节点之间的连接可以是有向的,也可以是无向的.每个节点可以收到来自相邻节点或自身的信息.
- 图网络是前馈网络和记忆网络的泛化,包含很多不同的实现方式,比如
图卷积网络
、图注意力网络
、消息传递神经网络
等.
4)三种网络结构的对比
3. 激活函数
2.1 激活函数的作用与性质
1)激活函数在神经元中非常重要的.可以增强网络的表示能力和学习能力
- 如果没有激活函数,那么神经网络只能表达线性映射,此刻即便是有再多的隐藏层,其整个网络和单层的神经网络都是等价的
激活函数需要具备以下几点性质:
连续并可导
(允许少数点上不可导)的非线性函数
.- 激活函数及其导函数要尽可能的
简单
,有利于提高网络计算效率.- 激活函数的导函数的值域要
在一个合适的区间
内,不能太大也不能太小,否则会影响训练的效率和稳定性.
以下是几种常见的激活函数。
2.2 Sigmoid型函数
Sigmoid 型函数
是指一类 S 型曲线函数,为两端饱和函数
.常用的 Sigmoid型函数有Logistic函数
和Tanh函数
.
对于函数 𝑓(𝑥),若 𝑥 → −∞ 时,其导数 𝑓′(𝑥) → 0,则称其为
左饱和
.若𝑥 → +∞时,其导数𝑓′(𝑥) → 0,则称其为右饱和
.当同时满足左、右饱和时,就称为两端饱和
.
Logistic函数
Logistic函数定义为:
σ ( x ) = 1 1 + exp ( − x ) \sigma(x)=\frac{1}{1+\exp (-x)} σ(x)=1+exp(−x)1
- 当输入值在0附近时,Sigmoid型函数近似为
线性函数
;当输入值靠近两端时对输入进行抑制.输入越小,越接近 0;输入越大,越接近 1. - 和感知器使用的
阶跃激活函数
相比,Logistic函数是连续可导
的,其数学性质更好.
Tanh函数
Tanh函数也是一种Sigmoid型函数.其定义为:
tanh ( x ) = exp ( x ) − exp ( − x ) exp ( x ) + exp ( − x ) \tanh (x)=\frac{\exp (x)-\exp (-x)}{\exp (x)+\exp (-x)} tanh(x)=exp(x)+exp(−x)exp(x)−exp(−x)
Tanh函数 可以看作放大并平移的 Logistic函数,其值域是(−1, 1)。以下是 Tanh函数 与 Logistic函数的相互转化公式
tanh ( x ) = 2 σ ( 2 x ) − 1 \tanh (x)=2 \sigma(2 x)-1 tanh(x)=2σ(2x)−1
- 以下是
Tanh函数
和Logistic函数
的对比
Tanh函数
的输出是零中心化
的,而Logistic 函数
的输出恒大于 0
.非零中心化
的输出会使得其后一层的神经元的输入发生偏置偏移
,并进一步使得梯度下降的收敛速度变慢
.
2.3 Hard-Logistic函数和 Hard-Tanh函数
Logistic函数 和 Tanh函数 在中间(0附近)近似线性,两端饱和,计算开销较大。因此,这两个函数可以通过分段函数
来近似.
-
以
Logistic 函数 𝜎(𝑥)
为例,其导数为 𝜎′(𝑥) = 𝜎(𝑥)(1 − 𝜎(𝑥)).Logistic 函数在0附近的一阶泰勒展开
为
g l ( x ) ≈ σ ( 0 ) + x × σ ′ ( 0 ) = 0.25 x + 0.5 \begin{aligned} g_{l}(x) & \approx \sigma(0)+x \times \sigma^{\prime}(0) \\ & =0.25 x+0.5 \end{aligned} gl(x)≈σ(0)+x×σ′(0)=0.25x+0.5 -
这样
Logistic函数
可以用 分段函数hard-logistic(𝑥)
来近似.
hard − logistic ( x ) = { 1 g l ( x ) ≥ 1 g l 0 < g l ( x ) < 1 0 g l ( x ) ≤ 0 = max ( min ( g l ( x ) , 1 ) , 0 ) = max ( min ( 0.25 x + 0.5 , 1 ) , 0 ) \begin{aligned} \operatorname{hard}-\operatorname{logistic}(x) & =\left\{\begin{array}{ll} 1 & g_{l}(x) \geq 1 \\ g_{l} & 0<g_{l}(x)<1 \\ 0 & g_{l}(x) \leq 0 \end{array}\right. \\ & =\max \left(\min \left(g_{l}(x), 1\right), 0\right) \\ & =\max (\min (0.25 x+0.5,1), 0) \end{aligned} hard−logistic(x)=⎩⎨⎧1gl0gl(x)≥10<gl(x)<1gl(x)≤0=max(min(gl(x),1),0)=max(min(0.25x+0.5,1),0) -
同样,
Tanh函数
在0附近的一阶泰勒展开
为
g t ( x ) ≈ tanh ( 0 ) + x × tanh ′ ( 0 ) = x , g_{t}(x) \approx \tanh (0)+x \times \tanh ^{\prime}(0) =x, gt(x)≈tanh(0)+x×tanh′(0)=x, -
这样
Tanh函数
也可以用 分段函数hard-tanh(𝑥)
来近似.
hard − tanh ( x ) = max ( min ( g t ( x ) , 1 ) , − 1 ) = max ( min ( x , 1 ) , − 1 ) \begin{aligned} \operatorname{hard}-\tanh (x) & =\max \left(\min \left(g_{t}(x), 1\right),-1\right) \\ & =\max (\min (x, 1),-1) \end{aligned} hard−tanh(x)=max(min(gt(x),1),−1)=max(min(x,1),−1) -
以下是
Hard-Logistic函数
和Hard-Tanh函数
的形状.
2.4 ReLU函数
ReLU
是目前深度神经网络中经常使用的激活函数,其定义为:
ReLU
(
x
)
=
{
x
x
≥
0
0
x
<
0
=
max
(
0
,
x
)
\begin{aligned} \operatorname{ReLU}(x) & =\left\{\begin{array}{ll} x & x \geq 0 \\ 0 & x<0 \end{array}\right. \\ & =\max (0, x) \end{aligned}
ReLU(x)={x0x≥0x<0=max(0,x)其图像为:
优点
- 采用 ReLU 的神经元只需要进行加、乘和比较的操作,没有指数函数等影响,计算上更加高效.
- 更加有效率的梯度下降以及反向传播,避免了梯度爆炸(梯度接近于无穷)和梯度消失(梯度接近于0)问题;
- ReLU 具有很好的稀疏性,大约50%的神经元会处于激活状态.
缺点:
- 输出不是0对称
- 由于小于0的时候激活函数值为0,梯度为0,所以存在一部分神经元永远不会得到更新
解决方案:
在实际使用中,为了避免上述情况,有几种ReLU的变种也会被广泛使用.
1. 带泄露的ReLU
:在输入 𝑥 < 0时,保持一个很小的梯度
γ
\gamma
γ(往往小于1)
LeakyReLU
(
x
)
=
{
x
if
x
>
0
γ
x
if
x
≤
0
=
max
(
0
,
x
)
+
γ
min
(
0
,
x
)
=
max
(
x
,
γ
x
)
\begin{aligned} \operatorname{LeakyReLU}(x) & =\left\{\begin{array}{ll} x & \text { if } x>0 \\ \gamma x & \text { if } x \leq 0 \end{array}\right. \\ & =\max (0, x)+\gamma \min (0, x)\\ & = \max (x,\gamma x) \end{aligned}
LeakyReLU(x)={xγx if x>0 if x≤0=max(0,x)+γmin(0,x)=max(x,γx)
2.带参数的ReLU
:引入一个可学习的参数,不同神经元可以有不同的参数。对于第 𝑖 个神经元,其 PReLU 的定义为:
PReLU
i
(
x
)
=
{
x
if
x
>
0
γ
i
x
if
x
≤
0
=
max
(
0
,
x
)
+
γ
i
min
(
0
,
x
)
,
\begin{aligned} \operatorname{PReLU}_{i}(x) & =\left\{\begin{array}{ll} x & \text { if } x>0 \\ \gamma_{i} x & \text { if } x \leq 0 \end{array}\right. \\ & =\max (0, x)+\gamma_{i} \min (0, x), \end{aligned}
PReLUi(x)={xγix if x>0 if x≤0=max(0,x)+γimin(0,x),
- 如果 y i = 0 y_i = 0 yi=0,那么PReLU就退化为ReLU.如果 y i y_i yi 为一个很小的常数,则PReLU可以看作带泄露的ReLU。
3.ELU函数
:一个近似的零中心化的非线性函数
ELU
(
x
)
=
{
x
if
x
>
0
γ
(
exp
(
x
)
−
1
)
if
x
≤
0
=
max
(
0
,
x
)
+
min
(
0
,
γ
(
exp
(
x
)
−
1
)
)
\begin{aligned} \operatorname{ELU}(x) & =\left\{\begin{array}{ll} x & \text { if } x>0 \\ \gamma(\exp (x)-1) & \text { if } x \leq 0 \end{array}\right. \\ & =\max (0, x)+\min (0, \gamma(\exp (x)-1)) \end{aligned}
ELU(x)={xγ(exp(x)−1) if x>0 if x≤0=max(0,x)+min(0,γ(exp(x)−1))
4.Softplus 函数
:可以看作 ReLU 函数的平滑版本,其定义为
Softplus ( x ) = log ( 1 + exp ( x ) ) . \text { Softplus }(x)=\log (1+\exp (x)) \text {. } Softplus (x)=log(1+exp(x)).
5.不同ReLU函数的对比
2.5 常见的激活函数及其导数
激活函数 | 函数 | 导数 |
---|---|---|
Logistic 函数 | f ( x ) = 1 1 + exp ( − x ) f(x)=\frac{1}{1+\exp (-x)} f(x)=1+exp(−x)1 | f ′ ( x ) = f ( x ) ( 1 − f ( x ) ) f^{\prime}(x)=f(x)(1-f(x)) f′(x)=f(x)(1−f(x)) |
Tanh 函数 | f ( x ) = exp ( x ) − exp ( − x ) exp ( x ) + exp ( − x ) f(x)=\frac{\exp (x)-\exp (-x)}{\exp (x)+\exp (-x)} f(x)=exp(x)+exp(−x)exp(x)−exp(−x) | f ′ ( x ) = 1 − f ( x ) 2 f^{\prime}(x)=1-f(x)^{2} f′(x)=1−f(x)2 |
ReLU 函数 | f ( x ) = max ( 0 , x ) f(x)=\max (0, x) f(x)=max(0,x) | f ′ ( x ) = I ( x > 0 ) f^{\prime}(x)=I(x>0) f′(x)=I(x>0) |
ELU 函数 | f ( x ) = max ( 0 , x ) + min ( 0 , γ ( exp ( x ) − 1 ) ) f(x)=\max (0, x)+\min (0, \gamma(\exp (x)-1)) f(x)=max(0,x)+min(0,γ(exp(x)−1)) | f ′ ( x ) = I ( x > 0 ) + I ( x ≤ 0 ) ⋅ γ exp ( x ) f^{\prime}(x)=I(x>0)+I(x \leq 0) \cdot \gamma \exp (x) f′(x)=I(x>0)+I(x≤0)⋅γexp(x) |
SoftPlus 函数 | f ( x ) = log ( 1 + exp ( x ) ) f(x)=\log (1+\exp (x)) f(x)=log(1+exp(x)) | f ′ ( x ) = 1 1 + exp ( − x ) f^{\prime}(x)=\frac{1}{1+\exp (-x)} f′(x)=1+exp(−x)1 |
4. 前馈神经网络
4.1 前馈神经网络简介
前馈神经网络
(Feedforward Neural Network,FNN)是最早发明的简单人工神经网络。
- 在前馈神经网络中,各神经元分别属于不同的层.每一层的神经元可以接收前一层神经元的信号,并产生信号输出到下一层.
- 第0层称为
输入层
,最后一层称为输出层
,其他中间层称为隐藏层
. - 整个网络中
无反馈
,信号从输入层向输出层单向传播,可用一个有向无环图
表示.
前馈神经网络的图示
前馈神经网络的记号
记号 | 含义 |
---|---|
L L L | 神经网络的层数 |
M l M_l Ml | 第 𝑙 层神经元的个数 |
𝑓 𝑙 ( ⋅ ) 𝑓_𝑙(⋅) fl(⋅) | 第𝑙 层神经元的激活函数 |
W ( l ) ∈ R M l × M l − 1 \boldsymbol{W}^{(l)} \in \mathbb{R}^{M_{l} \times M_{l-1}} W(l)∈RMl×Ml−1 | 第𝑙 − 1层到第 𝑙 层的权重矩阵 |
b ( l ) ∈ R M l \boldsymbol{b}^{(l)} \in \mathbb{R}^{M_{l}} b(l)∈RMl | 第𝑙 − 1层到第𝑙 层的偏置 |
z ( l ) ∈ R M l \boldsymbol{z}^{(l)} \in \mathbb{R}^{M_{l}} z(l)∈RMl | 第𝑙 层神经元的净输入(净活性值) |
a ( l ) ∈ R M l \boldsymbol{a}^{(l)} \in \mathbb{R}^{M_{l}} a(l)∈RMl | 第𝑙 层神经元的输出(活性值) |
令𝒂(0) = 𝒙,前馈神经网络通过不断迭代下面公式进行信息传播:
z
(
l
)
=
W
(
l
)
a
(
l
−
1
)
+
b
(
l
)
a
(
l
)
=
f
l
(
z
(
l
)
)
\begin{aligned} \boldsymbol{z}^{(l)} & =\boldsymbol{W}^{(l)} \boldsymbol{a}^{(l-1)}+\boldsymbol{b}^{(l)} \\ \boldsymbol{a}^{(l)} & =f_{l}\left(\boldsymbol{z}^{(l)}\right) \end{aligned}
z(l)a(l)=W(l)a(l−1)+b(l)=fl(z(l))
- 首先根据第𝑙−1层神经元的
活性值 𝒂(𝑙−1)
计算出第𝑙层神经元的净活性值 𝒛(𝑙)
,然后经过一个激活函数得到第 𝑙 层神经元的活性值
- 整个网络呈如下迭代:
x = a ( 0 ) → z ( 1 ) → a ( 1 ) → z ( 2 ) → ⋯ → a ( L − 1 ) → z ( L ) → a ( L ) = ϕ ( x ; W , b ) \boldsymbol{x}=\boldsymbol{a}^{(0)} \rightarrow \boldsymbol{z}^{(1)} \rightarrow \boldsymbol{a}^{(1)} \rightarrow \boldsymbol{z}^{(2)} \rightarrow \cdots \rightarrow \boldsymbol{a}^{(L-1)} \rightarrow \boldsymbol{z}^{(L)} \rightarrow \boldsymbol{a}^{(L)}=\phi(\boldsymbol{x} ; \boldsymbol{W}, \boldsymbol{b}) x=a(0)→z(1)→a(1)→z(2)→⋯→a(L−1)→z(L)→a(L)=ϕ(x;W,b)
4.2 参数学习
损失函数:
L
(
y
,
y
^
)
=
−
y
⊤
log
y
^
\mathcal{L}(\boldsymbol{y}, \hat{\boldsymbol{y}})=-\boldsymbol{y}^{\top} \log \hat{\boldsymbol{y}}
L(y,y^)=−y⊤logy^
结构化风险函数:
R
(
W
,
b
)
=
1
N
∑
n
=
1
N
L
(
y
(
n
)
,
y
^
(
n
)
)
+
1
2
λ
∥
W
∥
F
2
\mathcal{R}(\boldsymbol{W}, \boldsymbol{b})=\frac{1}{N} \sum_{n=1}^{N} \mathcal{L}\left(\boldsymbol{y}^{(n)}, \hat{\boldsymbol{y}}^{(n)}\right)+\frac{1}{2} \lambda\|\boldsymbol{W}\|_{F}^{2}
R(W,b)=N1n=1∑NL(y(n),y^(n))+21λ∥W∥F2
在梯度下降方法的每次迭代中,第𝑙 层的参数
𝑾
(
𝑙
)
𝑾^{(𝑙)}
W(l) 和
𝒃
(
𝑙
)
𝒃^{(𝑙)}
b(l) 参数更新方式为:
W
(
l
)
←
W
(
l
)
−
α
∂
R
(
W
,
b
)
∂
W
(
l
)
=
W
(
l
)
−
α
(
1
N
∑
n
=
1
N
(
∂
L
(
y
(
n
)
,
y
^
(
n
)
)
∂
W
(
l
)
)
+
λ
W
(
l
)
)
,
b
(
l
)
←
b
(
l
)
−
α
∂
R
(
W
,
b
)
∂
b
(
l
)
=
b
(
l
)
−
α
(
1
N
∑
n
=
1
N
∂
L
(
y
(
n
)
,
y
^
(
n
)
)
∂
b
(
l
)
)
,
\begin{aligned} \boldsymbol{W}^{(l)} & \leftarrow \boldsymbol{W}^{(l)}-\alpha \frac{\partial \mathcal{R}(\boldsymbol{W}, \boldsymbol{b})}{\partial \boldsymbol{W}^{(l)}} \\ & =\boldsymbol{W}^{(l)}-\alpha\left(\frac{1}{N} \sum_{n=1}^{N}\left(\frac{\partial \mathcal{L}\left(\boldsymbol{y}^{(n)}, \hat{\boldsymbol{y}}^{(n)}\right)}{\partial \boldsymbol{W}^{(l)}}\right)+\lambda \boldsymbol{W}^{(l)}\right), \\\\ \boldsymbol{b}^{(l)} & \leftarrow \boldsymbol{b}^{(l)}-\alpha \frac{\partial \mathcal{R}(\boldsymbol{W}, \boldsymbol{b})}{\partial \boldsymbol{b}^{(l)}} \\ & =\boldsymbol{b}^{(l)}-\alpha\left(\frac{1}{N} \sum_{n=1}^{N} \frac{\partial \mathcal{L}\left(\boldsymbol{y}^{(n)}, \hat{\boldsymbol{y}}^{(n)}\right)}{\partial \boldsymbol{b}^{(l)}}\right), \end{aligned}
W(l)b(l)←W(l)−α∂W(l)∂R(W,b)=W(l)−α⎝⎛N1n=1∑N⎝⎛∂W(l)∂L(y(n),y^(n))⎠⎞+λW(l)⎠⎞,←b(l)−α∂b(l)∂R(W,b)=b(l)−α⎝⎛N1n=1∑N∂b(l)∂L(y(n),y^(n))⎠⎞,
- 梯度下降法需要计算损失函数对参数的
偏导数
,如果通过链式法则逐一对每个参数进行求偏导比较低效. - 在神经网络的训练中经常使用
反向传播算法
来高效地计算梯度
5. 反向传播算法
5.1 链式法则
∂ L ( y , y ^ ) ∂ w i j ( l ) = ∂ z ( l ) ∂ w i j ( l ) ∂ L ( y , y ^ ) ∂ z ( l ) , ∂ L ( y , y ^ ) ∂ b ( l ) = ∂ z ( l ) ∂ b ( l ) ∂ L ( y , y ^ ) ∂ z ( l ) \begin{array}{l} \frac{\partial \mathcal{L}(\boldsymbol{y}, \hat{\boldsymbol{y}})}{\partial w_{i j}^{(l)}}=\frac{\partial \boldsymbol{z}^{(l)}}{\partial w_{i j}^{(l)}} \frac{\partial \mathcal{L}(\boldsymbol{y}, \hat{\boldsymbol{y}})}{\partial \boldsymbol{z}^{(l)}}, \\\\ \frac{\partial \mathcal{L}(\boldsymbol{y}, \hat{\boldsymbol{y}})}{\partial \boldsymbol{b}^{(l)}}=\frac{\partial \boldsymbol{z}^{(l)}}{\partial \boldsymbol{b}^{(l)}} \frac{\partial \mathcal{L}(\boldsymbol{y}, \hat{\boldsymbol{y}})}{\partial \boldsymbol{z}^{(l)}} \end{array} ∂wij(l)∂L(y,y^)=∂wij(l)∂z(l)∂z(l)∂L(y,y^),∂b(l)∂L(y,y^)=∂b(l)∂z(l)∂z(l)∂L(y,y^)
5.2 计算各项
(1)计算偏导数 ∂ z ( l ) ∂ w i j ( l ) \frac{\partial \boldsymbol{z}^{(l)}}{\partial w_{i j}^{(l)}} ∂wij(l)∂z(l),因为 z ( l ) = W ( l ) a ( l − 1 ) + b ( l ) \boldsymbol{z}^{(l)}=\boldsymbol{W}^{(l)} \boldsymbol{a}^{(l-1)}+\boldsymbol{b}^{(l)} z(l)=W(l)a(l−1)+b(l)
∂ z ( l ) ∂ w i j ( l ) = [ ∂ z 1 ( l ) ∂ w i j ( l ) , ⋯ , ∂ z i ( l ) ∂ w i j ( l ) , ⋯ , ∂ z M l ( l ) ∂ w i j ( l ) ] = [ 0 , ⋯ , ∂ ( w i : ( l ) a ( l − 1 ) + b i ( l ) ) ∂ w i j ( l ) , ⋯ , 0 ] = [ 0 , ⋯ , a j ( l − 1 ) , ⋯ , 0 ] ≜ [ ] ( a j ( l − 1 ) ) ∈ R 1 × M l , \begin{aligned} \frac{\partial \boldsymbol{z}^{(l)}}{\partial w_{i j}^{(l)}} & =\left[\frac{\partial z_{1}^{(l)}}{\partial w_{i j}^{(l)}}, \cdots, \frac{\partial z_{i}^{(l)}}{\partial w_{i j}^{(l)}}, \cdots, \frac{\partial z_{M_{l}}^{(l)}}{\partial w_{i j}^{(l)}}\right] \\\\ & =\left[0, \cdots, \frac{\partial\left(\boldsymbol{w}_{i:}^{(l)} \boldsymbol{a}^{(l-1)}+b_{i}^{(l)}\right)}{\partial w_{i j}^{(l)}}, \cdots, 0\right] \\\\ & =\left[0, \cdots, a_{j}^{(l-1)}, \cdots, 0\right] \\\\ & \triangleq []\left(a_{j}^{(l-1)}\right) \quad \in \mathbb{R}^{1 \times M_{l}}, \end{aligned} ∂wij(l)∂z(l)=[∂wij(l)∂z1(l),⋯,∂wij(l)∂zi(l),⋯,∂wij(l)∂zMl(l)]=⎣⎡0,⋯,∂wij(l)∂(wi:(l)a(l−1)+bi(l)),⋯,0⎦⎤=[0,⋯,aj(l−1),⋯,0]≜[](aj(l−1))∈R1×Ml,
- 其中 w i ( l ) w_i^{(l)} wi(l)∶ 为权重矩阵 𝑾 ( 𝑙 ) 𝑾^{(𝑙)} W(l) 的第𝑖 行, [ ] ( a j ( l − 1 ) ) []\left(a_{j}^{(l-1)}\right) [](aj(l−1))表示第𝑖 个元素为 ( a j ( l − 1 ) ) \left(a_{j}^{(l-1)}\right) (aj(l−1)) ,其余为0的行向量.
(2)计算偏导数
∂
z
(
l
)
∂
b
(
l
)
\frac{\partial \boldsymbol{z}^{(l)}}{\partial \boldsymbol{b}^{(l)}}
∂b(l)∂z(l) 因为
𝒛
(
𝑙
)
𝒛^{(𝑙)}
z(l) 和
𝒃
(
𝑙
)
𝒃^{(𝑙)}
b(l) 的函数关系为
z
(
l
)
=
W
(
l
)
a
(
l
−
1
)
+
𝒃
(
𝑙
)
\boldsymbol{z}^{(l)}=\boldsymbol{W}^{(l)} \boldsymbol{a}^{(l-1)}+ 𝒃^{(𝑙)}
z(l)=W(l)a(l−1)+b(l)
∂
z
(
l
)
∂
b
(
l
)
=
I
M
l
∈
R
M
l
×
M
l
\frac{\partial \boldsymbol{z}^{(l)}}{\partial \boldsymbol{b}^{(l)}}=\boldsymbol{I}_{M_{l}} \quad \in \mathbb{R}^{M_{l} \times M_{l}}
∂b(l)∂z(l)=IMl∈RMl×Ml
- 为 𝑀 𝑙 × 𝑀 𝑙 𝑀_𝑙 × 𝑀_𝑙 Ml×Ml 的单位矩阵.
(3)计算偏导数
∂
L
(
y
,
y
^
)
∂
z
(
l
)
\frac{\partial \mathcal{L}(\boldsymbol{y}, \hat{\boldsymbol{y}})}{\partial \boldsymbol{z}^{(l)}}
∂z(l)∂L(y,y^). 偏导数
∂
L
(
y
,
y
^
)
∂
z
(
l
)
\frac{\partial \mathcal{L}(\boldsymbol{y}, \hat{\boldsymbol{y}})}{\partial \boldsymbol{z}^{(l)}}
∂z(l)∂L(y,y^)表示第𝑙层神经元对最终损失的影响,因此一般称为第 𝑙 层神经元的误差项
,用
δ
(
𝑙
)
\delta ^{(𝑙)}
δ(l) 来表示.
-
误差项
δ ( 𝑙 ) \delta ^{(𝑙)} δ(l) 也间接反映了不同神经元对网络能力的贡献程度,从而比较好地解决了贡献度分配问题
-
根据链式法则,第 𝑙 层的误差项为
δ ( l ) ≜ ∂ L ( y , y ^ ) ∂ z ( l ) = ∂ a ( l ) ∂ z ( l ) ⋅ ∂ z ( l + 1 ) ∂ a ( l ) ⋅ ∂ L ( y , y ^ ) ∂ z ( l + 1 ) = diag ( f l ′ ( z ( l ) ) ) ⋅ ( W ( l + 1 ) ) ⊤ ⋅ δ ( l + 1 ) = f l ′ ( z ( l ) ) ⊙ ( ( W ( l + 1 ) ) ⊤ δ ( l + 1 ) ) ∈ R M l , \begin{aligned} \delta^{(l)} & \triangleq \frac{\partial \mathcal{L}(\boldsymbol{y}, \hat{\boldsymbol{y}})}{\partial \boldsymbol{z}^{(l)}} \\ & =\frac{\partial \boldsymbol{a}^{(l)}}{\partial \boldsymbol{z}^{(l)}} \cdot \frac{\partial \boldsymbol{z}^{(l+1)}}{\partial \boldsymbol{a}^{(l)}} \cdot \frac{\partial \mathcal{L}(\boldsymbol{y}, \hat{\boldsymbol{y}})}{\partial \boldsymbol{z}^{(l+1)}} \\ & =\operatorname{diag}\left(f_{l}^{\prime}\left(\boldsymbol{z}^{(l)}\right)\right) \cdot\left(\boldsymbol{W}^{(l+1)}\right)^{\top} \cdot \delta^{(l+1)} \\ & =f_{l}^{\prime}\left(\boldsymbol{z}^{(l)}\right) \odot\left(\left(\boldsymbol{W}^{(l+1)}\right)^{\top} \delta^{(l+1)}\right) \in \mathbb{R}^{M_{l}}, \end{aligned} δ(l)≜∂z(l)∂L(y,y^)=∂z(l)∂a(l)⋅∂a(l)∂z(l+1)⋅∂z(l+1)∂L(y,y^)=diag(fl′(z(l)))⋅(W(l+1))⊤⋅δ(l+1)=fl′(z(l))⊙((W(l+1))⊤δ(l+1))∈RMl, -
其中⊙是向量的点积运算符,表示每个元素相乘.
-
第 𝑙 层的误差项可以通过第𝑙 + 1层的误差项计算得到,这就是误差的
反向传播
. -
第 𝑙 层的一个神经元的误差项是所有与该神经元相连的第 𝑙 + 1 层的神经元的误差项的权重和,再乘上该神经元激活函数的梯度.
因此,
L
(
y
,
y
^
)
\mathcal{L}(\boldsymbol{y}, \hat{\boldsymbol{y}})
L(y,y^) 关于第𝑙 层权重
𝑾
(
𝑙
)
𝑾^{(𝑙)}
W(l) 的梯度为
∂
L
(
y
,
y
^
)
∂
W
(
l
)
=
δ
(
l
)
(
a
(
l
−
1
)
)
⊤
∈
R
M
l
×
M
l
−
1
\frac{\partial \mathcal{L}(\boldsymbol{y}, \hat{\boldsymbol{y}})}{\partial \boldsymbol{W}^{(l)}}=\delta^{(l)}\left(\boldsymbol{a}^{(l-1)}\right)^{\top} \quad \in \mathbb{R}^{M_{l} \times M_{l-1}}
∂W(l)∂L(y,y^)=δ(l)(a(l−1))⊤∈RMl×Ml−1
同理,
L
(
y
,
y
^
)
\mathcal{L}(\boldsymbol{y}, \hat{\boldsymbol{y}})
L(y,y^) 关于第 𝑙 层偏置
𝒃
(
𝑙
)
𝒃^{(𝑙)}
b(l) 的梯度为
∂
L
(
y
,
y
^
)
∂
b
(
l
)
=
δ
(
l
)
∈
R
M
l
\frac{\partial \mathcal{L}(\boldsymbol{y}, \hat{\boldsymbol{y}})}{\partial \boldsymbol{b}^{(l)}}=\delta^{(l)} \quad \in \mathbb{R}^{M_{l}}
∂b(l)∂L(y,y^)=δ(l)∈RMl
5.3 算法步骤
因此,使用误差反向传播算法的前馈神经网络训练过程可以分为以下三步:
(1) 前馈计算每一层的净输入 𝒛 ( 𝑙 ) 𝒛^{(𝑙)} z(l) 和激活值 𝒂 ( 𝑙 ) 𝒂^{(𝑙)} a(l),直到最后一层;
(2) 反向传播计算每一层的误差项 δ ( 𝑙 ) \delta^{(𝑙)} δ(l);
(3) 计算每一层参数的偏导数,并更新参数.
输入: 训练集𝒟,验证集𝒱,学习率𝛼, 正则化系数𝜆,网络层数𝐿,神经元数量 M l M_l Ml, 1 ≤ 𝑙 ≤ 𝐿.
随机初始化 𝑾, 𝒃 ;
repeat
对训练集𝒟 中的样本随机重排序
for 𝑛 = 1 ⋯ 𝑁 do
从训练集𝒟 中选取样本 ( 𝒙 ( 𝑛 ) , 𝑦 ( 𝑛 ) ) (𝒙^{(𝑛)}, 𝑦^{(𝑛)}) (x(n),y(n))
前馈计算每一层的净输入 𝒛 ( 𝑙 ) 𝒛^{(𝑙)} z(l) 和激活值 𝒂 ( 𝑙 ) 𝒂^{(𝑙)} a(l),直到最后一层;
反向传播计算每一层的误差 δ ( 𝑙 ) \delta^{(𝑙)} δ(l);
// 计算每一层参数的导数
∀ l , ∂ L ( y ( n ) , y ^ ( n ) ) ∂ W ( l ) = δ ( l ) ( a ( l − 1 ) ) ⊤ \forall l, \quad \frac{\partial \mathcal{L}\left(\boldsymbol{y}^{(n)}, \hat{\boldsymbol{y}}^{(n)}\right)}{\partial W^{(l)}}=\delta^{(l)}\left(\boldsymbol{a}^{(l-1)}\right)^{\top} ∀l,∂W(l)∂L(y(n),y^(n))=δ(l)(a(l−1))⊤
∀ l , ∂ L ( y ( n ) , y ^ ( n ) ) ∂ b ( l ) = δ ( l ) \forall l, \quad \frac{\partial \mathcal{L}\left(\boldsymbol{y}^{(n)}, \hat{\boldsymbol{y}}^{(n)}\right)}{\partial \boldsymbol{b}^{(l)}}=\delta^{(l)} ∀l,∂b(l)∂L(y(n),y^(n))=δ(l)
// 更新参数
W ( l ) ← W ( l ) − α ( δ ( l ) ( a ( l − 1 ) ) ⊤ + λ W ( l ) ) \boldsymbol{W}^{(l)} \leftarrow \boldsymbol{W}^{(l)}-\alpha\left(\delta^{(l)}\left(\boldsymbol{a}^{(l-1)}\right)^{\top}+\lambda\boldsymbol{W}^{(l)}\right) W(l)←W(l)−α(δ(l)(a(l−1))⊤+λW(l))
b ( l ) ← b ( l ) − α δ ( l ) \boldsymbol{b}^{(l)} \leftarrow \boldsymbol{b}^{(l)}-\alpha \delta^{(l)} b(l)←b(l)−αδ(l)
end
until 神经网络模型在验证集𝒱 上的错误率不再下降;
输出: 𝑾, b b b
5.4 优化问题
神经网络的参数学习比线性模型要更加困难,主要原因有两点:
非凸优化问题
神经网络的优化问题是一个
非凸优化问题
.
- 以一个最简单的1-1-1结构的两层神经网络为例,
y = σ ( w 2 σ ( w 1 x ) ) y=\sigma\left(w_{2} \sigma\left(w_{1} x\right)\right) y=σ(w2σ(w1x))- 其中 𝑤 1 𝑤_1 w1 和 𝑤 2 𝑤_2 w2 为网络参数,𝜎(⋅)为Logistic函数.
- 通过图可以看出,平方误差和交叉熵损失函数都是关于参数的非凸函数
梯度消失问题
梯度消失问题:
Sigmoid 型函数饱和区的导数接近于 0.误差经过每一层传递都会不断衰减.当网络层数很深时,梯度就会不停衰减,甚至消失,使得整个网络很难训练.
6. 自动梯度计算
因为手动用链式法则来计算风险函数对每个参数的梯度非常琐碎并容易出错,导致实现神经网络变得十分低效.实际上,参数的梯度可以让计算机来自动计算.
主流的深度学习框架都包含了自动梯度计算
的功能,自动计算梯度的方法可以分为以下三类:数值微分
、符号微分
和自动微分
.
6.1 数值微分
数值微分
是用数值方法来计算函数𝑓(𝑥)的导数.函数𝑓(𝑥)的点𝑥的导数定义为
f
′
(
x
)
=
lim
Δ
x
→
0
f
(
x
+
Δ
x
)
−
f
(
x
)
Δ
x
f^{\prime}(x)=\lim _{\Delta x \rightarrow 0} \frac{f(x+\Delta x)-f(x)}{\Delta x}
f′(x)=Δx→0limΔxf(x+Δx)−f(x)
数值微分方法非常容易实现,但找到一个合适的扰动 Δ𝑥 却十分困难.
如果 Δ𝑥 过小,会引起数值计算问题,比如舍入误差
;如果Δ𝑥 过大,会增加截断误差
,使得导数计算不准确.
因此,数值微分的实用性比较差.
- 在实际应用,经常使用下面公式来计算梯度,可以减少
截断误差
.
f ′ ( x ) = lim Δ x → 0 f ( x + Δ x ) − f ( x − Δ x ) 2 Δ x . f^{\prime}(x)=\lim _{\Delta x \rightarrow 0} \frac{f(x+\Delta x)-f(x-\Delta x)}{2 \Delta x} . f′(x)=Δx→0lim2Δxf(x+Δx)−f(x−Δx).
数值微分的另外一个问题是
计算复杂度
.假设参数数量为𝑁
,则每个参数都需要单独施加扰动,并计算梯度.
假设每次正向传播的计算复杂度为𝑂(𝑁)
,则计算数值微分的总体时间复杂度为𝑂(𝑁^2)
.
6.2 符号微分
符号微分是一种基于符号计算的自动求导方法.即将数值代入数学表示中进行计算.符号计算也叫代数计算.
这里的变量被看作符号,一般不需要代入具体的值.
符号计算的输入和输出都是数学表达式,一般包括对数学表达式的化简、因式分解、微分、积分、解代数方程、求解常微分方程
等运算.
6.3 自动微分
自动微分是一种可以对一个(程序)函数进行计算导数的方法.
自动微分的基本原理是所有的数值计算可以分解为一些基本操作,包含+, −, ×, / 和一些初等函数 exp, log,sin, cos 等,然后利用链式法则
来自动计算一个复合函数的梯度.
例:令复合函数𝑓(𝑥; 𝑤, 𝑏)为
f ( x ; w , b ) = 1 exp ( − ( w x + b ) ) + 1 f(x ; w, b)=\frac{1}{\exp (-(w x+b))+1} f(x;w,b)=exp(−(wx+b))+11
其计算图为:
前向模式和反向模式可以看作应用链式法则的两种梯度累积方式.
- 对于一般的函数形式 𝑓 ∶ R N → R M \mathbb{R}^{N} \rightarrow \mathbb{R}^{M} RN→RM,前向模式需要对每一个输入变量都进行一遍遍历,共需要 𝑁 遍.
- 而反向模式需要对每一个输出都进行一个遍历,共需要 𝑀 遍.
- 当 𝑁 > 𝑀 时,反向模式更高效.
- 在前馈神经网络的参数学习中,风险函数为𝑓 ∶
R
N
→
R
\mathbb{R}^{N} \rightarrow \mathbb{R}
RN→R,输出为
标量
,因此采用反向模式为最有效的计算方式,只需要一遍计算.