理解深度学习基石:前向传播与反向传播详解
深度学习基础 - 前向传播和反向传播
flyfish
有一个故事:
一位外地人闯进小镇,到镇里的旅店,取出100元钱准备住店,然后便随服务员去看房。旅店老板拿着这100元钱到街对面的肉铺还赊账买肉的钱;肉铺老板赶紧跑去一公里外的养猪场还了买猪钱;养猪场场主开开心心地将还没捂热的100元钱又还给前来催债的邻镇饲料厂厂长;厂长正惦记着前几天住旅店欠下的100元钱,飞奔到旅店将钱还上。外地人向旅店老板反映房间环境不好,要退掉100元房钱,老板便将饲料厂厂长付给自己的钱给了这个外地人。这下子,小镇上的人债务都解除了,大家都很开心。
从一个简单的数学表达式开始
1
+
2
=
3
1+2=3
1+2=3
把常量换成变量,如下
x
+
y
=
z
x+y=z
x+y=z
这是数学表达式的方式
我们再换种计算图的方式,如下
前向传播
反向传播
这是加法,左边是前向传播,右边是反向传播
这是乘法,左边是前向传播,右边是反向传播
从左向右进行计算是一种正方向上的传播,简称为正向传播 (forward propagation)。从右向左的传播称为反向传播 (backward propagation)。
计算图的反向传播
计算图的反向传播:沿着与正方向相反的方向,乘上局部导数。
反向传播的计算顺序是:
将信号 E 乘以节点的局部导数(
∂
y
∂
x
\frac{\partial y}{\partial x}
∂x∂y),然后将结果传递给下一个节点。这里所说的局部导数是指正向传播中
y
=
f
(
x
)
y = f (x)
y=f(x) 的导数,也就是 y 关于 x 的导数(
∂
y
∂
x
\frac{\partial y}{\partial x}
∂x∂y )。比如,假设
y
=
f
(
x
)
=
x
2
y = f(x) = x 2
y=f(x)=x2 ,则局部导数为
∂
y
∂
x
\frac{\partial y}{\partial x}
∂x∂y = 2x。把这个局部导数乘以 E,然后传递给前面的节点。这就是反向传播的计算顺序。通过这样的计算,可以高效地求出导数的值,这是反向传播的要点。
z
=
f
(
x
,
y
)
z=f(x,y)
z=f(x,y) 求偏导数
加法的偏导数
f
(
x
,
y
)
=
x
+
y
∂
f
∂
x
=
1
,
∂
f
∂
y
=
1
\begin{array}{l} f(x, y)=x+y \\\\ \frac{\partial f}{\partial x}=1, \\\\ \frac{\partial f}{\partial y}=1 \end{array}
f(x,y)=x+y∂x∂f=1,∂y∂f=1
乘法的偏导数
f ( x , y ) = x y ∂ f ∂ x = y , ∂ f ∂ y = x \begin{array}{l} f(x, y)=x y \\\\ \frac{\partial f}{\partial x}=y, \\\\ \frac{\partial f}{\partial y}=x \end{array} f(x,y)=xy∂x∂f=y,∂y∂f=x
我们把加法和乘法联合起来,以应用题的方式说明正向传播和反向传播
完整代码
物品a的单价是3,数量是7
物品b的单价是4,数量是8
物品的总价是多少?
3×7 + 4×8 = 53
代码实现
class multiplication_layer:
def __init__(self):
self.x = None
self.y = None
def forward(self, x, y):
self.x = x
self.y = y
out = x * y
return out
def backward(self, d_out):
d_x = d_out * self.y
d_y = d_out * self.x
return d_x, d_y
class addition_layer:
def __init__(self):
pass
def forward(self, x, y):
out = x + y
return out
def backward(self, d_out):
d_x = d_out * 1
d_y = d_out * 1
return d_x, d_y
a_price = 3
a_num = 7
b_price = 4
b_num = 8
# layer
a_layer = multiplication_layer()
b_layer = multiplication_layer()
c_layer = addition_layer()
# forward
a_price = a_layer.forward(a_price, a_num) # (1)
b_price = b_layer.forward(b_price, b_num) # (2)
totoal_price = c_layer.forward(a_price, b_price) # (3)
# backward
d_price = 1
d_a_price, d_b_price = c_layer.backward(d_price) # (3)
d_b, d_b_num = b_layer.backward(d_b_price) # (2)
d_a, d_a_num = a_layer.backward(d_a_price) # (1)
print("totoal_price:", (totoal_price))
print("d_a:", d_a)
print("d_a_num:", (d_a_num))
print("d_b:", d_b)
print("d_b_num:", (d_b_num))
# totoal_price: 53
# d_a: 7
# d_a_num: 3
# d_b: 8
# d_b_num: 4
局部计算 - 各人自扫门前雪,莫管他人瓦上霜
计算图的特征是可以通过传递“局部计算”获得最终结果。通过一个乘号看局部计算是指,无论全局发生了什么,这个乘号只根据与自己相关两个连接的信息计算与其他点和线无关。
在计算图中表示链式法则
z
=
(
x
+
y
)
2
z = {(x + y)}^2
z=(x+y)2是由两个式子构成的。
1
、
z
=
t
2
2
、
t
=
x
+
y
1、z = t^2 2、t = x + y
1、z=t22、t=x+y
简单实现一个全连接层的前向传播和反向传播
全连接层是fully connected layer,类似的名词是affine或者linear
Y = W X + B Y=WX+B Y=WX+B
import numpy as np
N=1
X= np.random.random((N,2))
W= np.random.random((2,3))
B= np.random.random((3,))
Y = np.dot(X, W) + B
print(Y)
以矩阵为对象的反向传播
∂
L
∂
X
=
∂
L
∂
Y
⋅
W
T
∂
L
∂
W
=
X
T
⋅
∂
L
∂
Y
\begin{array}{l} \frac{\partial L}{\partial \boldsymbol{X}}=\frac{\partial L}{\partial \boldsymbol{Y}} \cdot \boldsymbol{W}^{\mathrm{T}} \\ \\ \frac{\partial L}{\partial \boldsymbol{W}}=\boldsymbol{X}^{\mathrm{T}} \cdot \frac{\partial L}{\partial \boldsymbol{Y}} \end{array}
∂X∂L=∂Y∂L⋅WT∂W∂L=XT⋅∂Y∂L
X 和
∂
L
∂
X
\frac{\partial L}{\partial X}
∂X∂L形状相同,W 和
∂
L
∂
W
\frac{\partial L}{\partial W}
∂W∂L形状相同
X
=
(
x
0
,
x
1
,
⋯
,
x
n
)
∂
L
∂
X
=
(
∂
L
∂
x
0
,
∂
L
∂
x
1
,
⋯
,
∂
L
∂
x
n
)
\begin{array}{l} \boldsymbol{X}=\left(x_{0}, x_{1}, \cdots, x_{n}\right) \\ \frac{\partial L}{\partial \boldsymbol{X}}=\left(\frac{\partial L}{\partial x_{0}}, \frac{\partial L}{\partial x_{1}}, \cdots, \frac{\partial L}{\partial x_{n}}\right) \end{array}
X=(x0,x1,⋯,xn)∂X∂L=(∂x0∂L,∂x
推荐阅读
-
入门深度学习1:理解深度前馈神经网络与反向传播机制
-
理解深度学习:向前推进 - 前馈神经网络与反向误差传播机制
-
理解神经网络:向前推进(前向传播)与向后修正(BP反向传播)算法详解及计算原理
-
理解BP神经网络:前向计算与反向传播的实际应用示例
-
详解神经网络的前向传播与反向传播计算公式步骤
-
深度学习探索(第二部分):从前向计算到反向传播详解
-
用一个实例深入理解神经网络的前向传播与反向传播机制
-
理解深度学习基石:前向传播与反向传播详解
-
理解深度学习基础:从神经网络构造到实践 - 1.评分函数介绍 2.SVM损失函数解析 3.正规化惩罚项说明 4.Softmax与交叉熵损失函数详解 5.前向传播中的最优化挑战 6.批量大小(batch_size)实操指南...
-
深度学习探索(2):从头到尾理解前向传播与反向传播算法 - 序章