文章目录
![公众号](https://i-blog.csdnimg.cn/blog_migrate/650c0d1606d560f73f2775e6d7e75d82.jpeg)
欢迎关注《汽车软件技术》公众号,回复关键字获取资料。
1. 关键词
梯度下降
,链式法则
,反向传播
2. 导读
本文介绍了反向传播的数学基础,及其过程。
3. 数学基础
3.1 梯度下降
神经网络求解的目的,是使输出值更接近于真实值,这就转化成一个求最优解或最小值的过程,最常用的就是梯度下降法。从山顶沿负梯度方向(导数的反方向),一步步走到山底。
上图也演示了梯度下降受到起点的影响,得到的是局部最优解,并不一定是全局最优解。
3.2 链式法则
求解梯度就是求导数,但复杂的函数,不能一次性求出。因此需要引入链式法则。
∂
z
∂
x
=
∂
z
∂
y
∂
y
∂
x
∂
(
z
+
y
)
∂
x
=
∂
z
∂
x
+
∂
y
∂
x
\frac{\partial z}{\partial x}=\frac{\partial z}{\partial y}\frac{\partial y}{\partial x}\\ \frac{\partial(z+y)}{\partial x}=\frac{\partial z}{\partial x}+\frac{\partial y}{\partial x}
∂x∂z=∂y∂z∂x∂y∂x∂(z+y)=∂x∂z+∂x∂y
3.3 学习率
在得到梯度后,需要选择合适的步长,称作学习率。学习率不是越大,收敛的越快。如下图,左边的学习率大,反而不收敛;右边的学习率小,反而收敛。
学习率一般取一个小的数,或者多尝试几个,选择结果最好的。
4. 代价函数
在机器学习中,寻找最优解的目标函数,通常成为代价函数,表示输出值和真实值的误差。神经网络代价函数很复杂,公式如下:
J
(
Θ
)
=
−
1
m
[
∑
i
=
1
m
∑
k
=
1
K
y
k
(
i
)
log
(
h
Θ
(
x
(
i
)
)
)
k
+
(
1
−
y
k
(
i
)
)
log
(
1
−
(
h
Θ
(
x
(
i
)
)
)
k
)
]
J(\Theta)=-\frac1{m}\left[\sum\limits_{i=1}^{m}\sum\limits_{k=1}^{K}y_k^{(i)}\log\left(h_{\Theta}(x^{(i)})\right)_k+(1-y_k^{(i)})\log\left(1-\left(h_{\Theta}(x^{(i)})\right)_k\right)\right]
J(Θ)=−m1[i=1∑mk=1∑Kyk(i)log(hΘ(x(i)))k+(1−yk(i))log(1−(hΘ(x(i)))k)]
其中:
- m m m,输入数据的数量;
- i i i,第 i i i 次输入, i ∈ [ 1 , m ] i\in[1,m] i∈[1,m];
- k k k,第 k k k 个输出单元, k ∈ [ 1 , K ] k\in[1,K] k∈[1,K];
- K K K,输出单元数量;
- j j j,第 L + 1 L+1 L+1 层第 j j j 个神经元
- l l l,第 l l l 层, l ∈ [ 1 , L ] l\in[1,L] l∈[1,L];
- L L L,总层数;
- s l s_l sl,第 l l l 层神经元数量。
因为逻辑回归也使用了 sigmod 函数,所以代价函数有相似之处,注意区分:
J
(
θ
)
=
−
1
m
[
∑
i
=
1
m
y
(
i
)
log
(
h
θ
(
x
(
i
)
)
)
+
(
1
−
y
(
i
)
)
log
(
1
−
(
h
θ
(
x
(
i
)
)
)
)
]
J(\theta)=-\frac1{m}\left[\sum\limits_{i=1}^{m}y^{(i)}\log\left(h_{\theta}(x^{(i)})\right)+(1-y^{(i)})\log\left(1-\left(h_{\theta}(x^{(i)})\right)\right)\right]
J(θ)=−m1[i=1∑my(i)log(hθ(x(i)))+(1−y(i))log(1−(hθ(x(i))))]
每个权重的迭代步骤:
Θ
j
i
(
l
)
=
Θ
j
i
(
l
)
−
α
∂
∂
Θ
j
i
(
l
)
J
(
Θ
)
{\Theta}_{ji}^{(l)}={\Theta}_{ji}^{(l)}-\alpha\frac{\partial}{\partial{\Theta}_{ji}^{(l)}}{J}(\Theta)
Θji(l)=Θji(l)−α∂Θji(l)∂J(Θ)
其中:
- l l l,第 l l l 层;
- i i i, l l l 下一层第 i i i 个神经元;
- j j j, l l l 层第 j j j 个神经元;
- α \alpha α,学习率。
对代价函数直接求导不现实,因此要用数值计算的方法。
5. 反向传播
5.1 算法步骤
- 通过前向传播,得到对应的输出;
- 输出与真实值比较,得到误差;
- 将误差从输出层,反向传播到输入层,得到每个权重的梯度;
- 计算新的权重,使用下一组输入,继续迭代。
5.2 公式推导
5.2.1 输出层
假设一个4层网络,用欧式距离表示输出层总误差:
E
=
∑
k
=
1
K
1
2
(
y
k
−
a
k
(
4
)
)
2
E=\sum_{k=1}^{K}\frac{1}{2}(y_k-a_k^{(4)})^2
E=k=1∑K21(yk−ak(4))2
则:
∂
E
∂
a
k
(
4
)
=
−
(
y
k
−
a
k
(
4
)
)
\frac{\partial E}{\partial a_k^{(4)}}=-(y_k-a_k^{(4)})
∂ak(4)∂E=−(yk−ak(4))
5.2.2 隐含层到输出层
z
(
4
)
=
Θ
(
3
)
a
(
3
)
z^{(4)}=\Theta^{(3)}a^{(3)}
z(4)=Θ(3)a(3),
a
(
4
)
=
g
(
z
(
4
)
)
a^{(4)}=g(z^{(4)})
a(4)=g(z(4)),基于链式法则,
Θ
(
3
)
\Theta^{(3)}
Θ(3) 梯度:
∂
E
∂
Θ
(
3
)
=
∂
E
∂
a
(
4
)
∂
a
(
4
)
∂
z
(
4
)
a
(
3
)
\frac{\partial E}{\partial \Theta^{(3)}}=\frac{\partial E}{\partial a^{(4)}}\frac{\partial a^{(4)}}{\partial z^{(4)}}a^{(3)}
∂Θ(3)∂E=∂a(4)∂E∂z(4)∂a(4)a(3)
其中:
∂
a
(
4
)
∂
z
(
4
)
=
∂
(
1
+
e
−
z
(
4
)
)
−
1
∂
z
(
4
)
=
e
−
z
(
4
)
(
1
+
e
−
z
(
4
)
)
2
=
1
1
+
e
−
z
(
4
)
(
1
−
1
1
+
e
−
z
(
4
)
)
=
a
(
4
)
(
1
−
a
(
4
)
)
\begin{aligned} \frac{\partial a^{(4)}}{\partial z^{(4)}}=&\frac{\partial (1+e^{-z^{(4)}})^{-1}}{\partial z^{(4)}}=\frac{e^{-z^{(4)}}}{(1+e^{-z^{(4)}})^2}\\ =&\frac{1}{1+e^{-z^{(4)}}}(1-\frac{1}{1+e^{-z^{(4)}}})=a^{(4)}(1-a^{(4)}) \end{aligned}
∂z(4)∂a(4)==∂z(4)∂(1+e−z(4))−1=(1+e−z(4))2e−z(4)1+e−z(4)1(1−1+e−z(4)1)=a(4)(1−a(4))
带入之前的等式,得到:
∂
∂
Θ
k
j
(
3
)
J
(
Θ
)
=
∂
E
∂
Θ
k
j
(
3
)
=
−
(
y
k
−
a
k
(
4
)
)
a
k
(
4
)
(
1
−
a
k
(
4
)
)
a
j
(
3
)
\frac{\partial}{\partial{\Theta}_{kj}^{(3)}}{J}(\Theta)=\frac{\partial E}{\partial \Theta^{(3)}_{kj}}=-(y_k-a^{(4)}_k)a^{(4)}_k(1-a^{(4)}_k)a^{(3)}_j
∂Θkj(3)∂J(Θ)=∂Θkj(3)∂E=−(yk−ak(4))ak(4)(1−ak(4))aj(3)
其中:
- k k k,输出层第 k k k 个单元
- j j j,隐含层第 j j j 个单元
5.2.3 隐含层之间
z
(
3
)
=
Θ
(
2
)
a
(
2
)
z^{(3)}=\Theta^{(2)}a^{(2)}
z(3)=Θ(2)a(2),
a
(
3
)
=
g
(
z
(
3
)
)
a^{(3)}=g(z^{(3)})
a(3)=g(z(3)),基于链式法则,
Θ
(
2
)
\Theta^{(2)}
Θ(2) 梯度:
∂
E
∂
Θ
(
2
)
=
∂
E
∂
z
(
4
)
∂
z
(
4
)
∂
a
(
3
)
∂
a
(
3
)
∂
z
(
3
)
a
(
2
)
\frac{\partial E}{\partial \Theta^{(2)}}=\frac{\partial E}{\partial z^{(4)}}\frac{\partial z^{(4)}}{\partial a^{(3)}}\frac{\partial a^{(3)}}{\partial z^{(3)}}a^{(2)}
∂Θ(2)∂E=∂z(4)∂E∂a(3)∂z(4)∂z(3)∂a(3)a(2)
因为
z
(
4
)
z^{(4)}
z(4) 和
a
(
3
)
a^{(3)}
a(3) 是1对多的关系,因此还有求和的过程:
∂
∂
Θ
j
i
(
2
)
J
(
Θ
)
=
∂
E
∂
Θ
j
i
(
2
)
=
∑
j
=
1
s
3
(
∂
E
∂
z
j
(
4
)
∂
z
j
(
4
)
∂
a
i
(
3
)
)
∂
a
i
(
3
)
∂
z
i
(
3
)
a
i
(
2
)
=
∑
j
=
1
s
3
(
∂
E
∂
z
j
(
4
)
∂
z
j
(
4
)
∂
a
i
(
3
)
)
a
j
(
3
)
(
1
−
a
j
(
3
)
)
a
i
(
2
)
\begin{aligned} \frac{\partial}{\partial{\Theta}_{ji}^{(2)}}{J}(\Theta)&=\frac{\partial E}{\partial \Theta_{ji}^{(2)}}=\sum^{s_3}_{j=1}(\frac{\partial E}{\partial z_j^{(4)}}\frac{\partial z_j^{(4)}}{\partial a_i^{(3)}})\frac{\partial a_i^{(3)}}{\partial z_i^{(3)}}a_i^{(2)}\\ &=\sum^{s_3}_{j=1}(\frac{\partial E}{\partial z_j^{(4)}}\frac{\partial z_j^{(4)}}{\partial a_i^{(3)}})a_j^{(3)}(1-a_j^{(3)})a_i^{(2)} \end{aligned}
∂Θji(2)∂J(Θ)=∂Θji(2)∂E=j=1∑s3(∂zj(4)∂E∂ai(3)∂zj(4))∂zi(3)∂ai(3)ai(2)=j=1∑s3(∂zj(4)∂E∂ai(3)∂zj(4))aj(3)(1−aj(3))ai(2)
同理可以继续推导出上一层。
5.3 例子
继续使用前向传播的例子,实际输出值是[0.01,0.99],图上分别标注了:当前权重、梯度、计算后权重。
使用Python实现:
import numpy as np
# 激活函数 sigmoid
def sigmoid(input):
return 1 / (1 + np.exp(-input))
# 层计算
def layer(input, weight, isInputLayer, bias):
output = input
if weight is not None:
output = np.dot(weight, input)
if bias is not None:
output = output + bias
if not isInputLayer:
output = sigmoid(output)
return output
# 输入
x = np.array([0.05, 0.10])
# 输入层偏置单元
x0 = 0.35
# 输入层到隐含层权重
thelta_1 = np.array([[0.15, 0.20],
[0.25, 0.30]])
# 隐含层偏置单元
a_0_2 = 0.6
# 隐含层到输出层权重
thelta_2 = np.array([[0.40, 0.45],
[0.50, 0.55]])
# 输入层
a_1 = layer(x, None, True, None)
print(a_1)
# 隐含层
a_2 = layer(a_1, thelta_1, False, x0)
print(a_2)
# 输出层
a_3 = layer(a_2, thelta_2, False, a_0_2)
print(a_3)
# 反向传播
learning_rate = 0.5
y = np.array([0.01, 0.99])
delta_a_3 = -(y - a_3)
delta_z_3 = a_3 * (1 - a_3)
delta_thelta_2 = np.outer(delta_a_3 * delta_z_3, a_2)
print(delta_thelta_2)
thelta_2_new = thelta_2 - learning_rate * delta_thelta_2
print(thelta_2_new)
delta_z_2 = a_2 * (1 - a_2)
delta_thelta_1 = np.outer(np.dot(delta_a_3 * delta_z_3, thelta_2) * delta_z_2, a_1)
print(delta_thelta_1)
thelta_1_new = thelta_1 - learning_rate * delta_thelta_1
print(thelta_1_new)
本例参考了扩展阅读中的《A Step by Step Backpropagation Example》。
6. 附录
6.1 中英文对照表
英文 | 中文 | 缩写 | 数学符号 |
---|---|---|---|
Backpropagation | 反向传播 | BP | |
Batch Gradient Descent | 批量梯度下降 | ||
Chain Rule | 链式法则 | ∂ z ∂ x = ∂ z ∂ y ∂ y ∂ x \frac{\partial{z}}{\partial x}=\frac{\partial z}{\partial y}\frac{\partial y}{\partial x} ∂x∂z=∂y∂z∂x∂y | |
Cost Function | 代价函数 | J ( Θ ) J(\Theta) J(Θ) | |
Gradient Descent | 梯度下降 | Δ \Delta Δ | |
Learning Rate | 学习率 | α \alpha α |
6.2 扩展阅读
- A Step by Step Backpropagation Example
- 一文弄懂神经网络中的反向传播法
- 《深度学习》(这是一本必读书籍,强烈推荐,公众号回复“深度学习”获取)
- 3Blue1Brown