1.视频网站:mooc慕课https://mooc.study.163.com/university/deeplearning_ai#/c
2.详细笔记网站(中文):http://www.ai-start.com/dl2017/
3.github课件+作业+答案:https://github.com/stormstone/deeplearning.ai
3.10 (选修)直观理解反向传播 Backpropagation intuition
本节我们要了解如何通过计算图推导出反向传播公式。
回忆一下逻辑回归的正向传播计算步骤
x
w
b
}
⇒
z
=
w
T
x
+
b
⇒
a
=
σ
(
z
)
⇒
L
(
a
,
y
)
\left. \begin{array}{l} x\\ w\\ b \end{array} \right\} \Rightarrow z=w^Tx+b\Rightarrow a=\sigma(z)\Rightarrow L(a,y)
xwb⎭⎬⎫⇒z=wTx+b⇒a=σ(z)⇒L(a,y)
先计算z,再计算a,最后损失函数L
接下来是反向传播求导过程
x
w
b
⏟
d
w
=
d
z
⋅
x
,
d
b
=
d
z
}
⇐
z
=
w
T
x
+
b
⏟
d
z
=
d
a
⋅
g
′
(
z
)
=
(
−
y
a
+
1
−
y
1
−
a
)
(
a
(
1
−
a
)
)
=
a
−
y
⇐
a
=
σ
(
z
)
⇐
L
(
a
,
y
)
⏟
d
a
=
d
d
z
L
(
a
,
y
)
=
(
−
y
l
o
g
a
−
(
1
−
y
)
l
o
g
(
1
−
a
)
)
′
=
−
y
a
+
1
−
y
1
−
a
\left. \underbrace{\begin{array}{l} x\\ w\\ b \end{array}}_{dw=dz\cdot x,db=dz} \right\} \Leftarrow \underbrace{z=w^Tx+b}_{dz=da\cdot g'(z)=(-\frac ya+\frac {1-y}{1-a})(a(1-a))=a-y} \Leftarrow \underbrace{a=\sigma(z)\Leftarrow L(a,y)} _{da=\frac d{dz}L(a,y)=(-yloga-(1-y)log(1-a))'=-\frac ya+\frac {1-y}{1-a}}
dw=dz⋅x,db=dz
xwb⎭⎪⎪⎪⎪⎪⎬⎪⎪⎪⎪⎪⎫⇐dz=da⋅g′(z)=(−ay+1−a1−y)(a(1−a))=a−y
z=wTx+b⇐da=dzdL(a,y)=(−yloga−(1−y)log(1−a))′=−ay+1−a1−y
a=σ(z)⇐L(a,y)
先计算da,再计算dz,最后计算dw和db
关于dz的计算说明如下
- 利用微分链式法则 d z = d L d z = d L d a d a d z = d a d d z g ( z ) = d a ⋅ g ′ ( z ) dz=\frac {dL}{dz}=\frac{dL}{da}\frac {da}{dz}=da\frac {d}{dz}g(z)=da\cdot g'(z) dz=dzdL=dadLdzda=dadzdg(z)=da⋅g′(z)
- 在这里g(z)使用sigmoid激活函数
- 在3.8节中介绍过,sigmoid函数的导数 g ′ ( z ) = a ( 1 − a ) g'(z)=a(1-a) g′(z)=a(1−a)
单隐藏层NN网络反向传播的计算和上面逻辑回归计算很类似,只是需要计算2次,输入x先到隐藏层,再到输出单元,并不是直接到输出单元。这一点和逻辑回归计算不相同。
双层NN网络的正向传播计算过程如上图。
所以,它的反向传播计算过程就是依次计算
d
a
[
2
]
⇒
d
z
[
2
]
⇒
d
W
[
2
]
和
d
b
[
2
]
⇒
d
a
[
1
]
⇒
d
z
[
1
]
⇒
d
W
[
1
]
和
d
b
[
1
]
da^{[2]} \Rightarrow dz^{[2]} \Rightarrow dW{[2]}和db{[2]} \Rightarrow da^{[1]} \Rightarrow dz{[1]} \Rightarrow dW{[1]}和db{[1]}
da[2]⇒dz[2]⇒dW[2]和db[2]⇒da[1]⇒dz[1]⇒dW[1]和db[1]
注意:我们不需要对x求导,因为监督学习的输入x是固定的,我们也不是想优化x。至少对于监督学习,不需要对x求导。
按照上面的计算过程,我们可以很容易得到前3个公式
- d z [ 2 ] = d a [ 2 ] − y dz^{[2]}=da^{[2]}-y dz[2]=da[2]−y
-
d
W
[
2
]
=
d
z
[
2
]
⋅
a
[
1
]
T
dW^{[2]}=dz^{[2]}\cdot a^{[1]T}
dW[2]=dz[2]⋅a[1]T。这里类似逻辑回归的
d
w
=
d
z
⋅
x
dw=dz\cdot x
dw=dz⋅x,只是 a[1]相对于x多了一个转置T。这是因为NN的矩阵W和逻辑回归的参数w是转置关系。
- 上一节已经介绍过W[2]的维度是(n[2],n[1]),n[2]=1,所以W是行向量。
- 2.11和2.12节中都介绍过,w是一个列向量。
- d b [ 2 ] = d z [ 2 ] db^{[2]}=dz^{[2]} db[2]=dz[2]
到这里为止,已经完成了反向传播的一半。
下面一个公式,也是第4个公式
d z [ 1 ] = W [ 2 ] T d z [ 2 ] ∗ g [ 1 ] ′ ( z [ 1 ] ) dz^{[1]}=W^{[2]T}dz^{[2]}\ast g^{[1]'}(z^{[1]}) dz[1]=W[2]Tdz[2]∗g[1]′(z[1])
其中
- W [ 2 ] W^{[2]} W[2]的维度已经说过是(n[2],n[1]),n[2]=1。 W [ 2 ] T W^{[2]T} W[2]T维度是(n[1],n[2])
- z [ 2 ] z^{[2]} z[2]和 d z [ 2 ] dz^{[2]} dz[2]的维度是(n[2],1),n[2]=1。 W [ 2 ] T d z [ 2 ] W^{[2]T}dz^{[2]} W[2]Tdz[2]的维度是(n[1],1)
- z [ 1 ] z^{[1]} z[1]和 d z [ 1 ] dz^{[1]} dz[1]的维度是(n[1],1)
注意:对于任意变量x和导数dx的维度都是一样的。例如,W和dW,b和db,z和dz,a和da等等。
符号 ∗ \ast ∗表示前后矩阵逐个元素相乘,所以计算结果维度也是(n[1],1),和 d z [ 1 ] dz^{[1]} dz[1]的维度匹配。
实现后向传播有个技巧,就是要保证矩阵的维度相互匹配。多多考虑维度,很多时候你就可以消除很多反向传播的bug了。
最后2个公式是
- d W [ 1 ] = d z [ 1 ] ⋅ X T dW^{[1]}=dz^{[1]}\cdot X^T dW[1]=dz[1]⋅XT
- d b [ 1 ] = d z [ 1 ] db^{[1]}=dz^{[1]} db[1]=dz[1]
这里你会发现,公式之间是有相似性的。
令
X
=
a
[
0
]
X=a^{[0]}
X=a[0],这样
d
W
[
1
]
=
d
z
[
1
]
⋅
a
[
0
]
T
dW^{[1]}=dz^{[1]}\cdot a^{[0]T}
dW[1]=dz[1]⋅a[0]T,与
d
W
[
2
]
dW^{[2]}
dW[2]类似
现在我们说明了6个反向传播的公式,汇总如下
最后把它们转化为向量化方程。
把z列向量横向堆叠起来定义为Z。其余的矩阵A,Y也是类似的。
其次,注意成本函数是损失函数求和后的平均值
结果如下
(1)
d
Z
[
2
]
=
A
[
2
]
−
Y
dZ^{[2]}=A^{[2]}-Y
dZ[2]=A[2]−Y
(2)
d
W
[
2
]
=
1
m
d
Z
[
2
]
A
[
1
]
T
dW^{[2]}=\frac 1mdZ^{[2]}A^{[1]T}
dW[2]=m1dZ[2]A[1]T
(3)
d
b
[
2
]
=
1
m
n
p
.
s
u
m
(
d
Z
[
2
]
,
a
x
i
s
=
1
,
k
e
e
p
d
i
m
s
=
T
r
u
e
)
db^{[2]}=\frac 1mnp.sum(dZ^{[2]},axis=1,keepdims=True)
db[2]=m1np.sum(dZ[2],axis=1,keepdims=True)
(4)
d
Z
[
1
]
=
W
[
2
]
T
d
Z
[
2
]
∗
g
[
1
]
′
(
Z
[
1
]
)
dZ^{[1]}=W^{[2]T}dZ^{[2]}*g^{[1]'}(Z^{[1]})
dZ[1]=W[2]TdZ[2]∗g[1]′(Z[1])
(5)
d
W
[
1
]
=
1
m
d
Z
[
1
]
A
[
0
]
T
dW^{[1]}=\frac 1mdZ^{[1]}A^{[0]T}
dW[1]=m1dZ[1]A[0]T
(6)
d
b
[
1
]
=
1
m
n
p
.
s
u
m
(
d
Z
[
1
]
,
a
x
i
s
=
1
,
k
e
e
p
d
i
m
s
=
T
r
u
e
)
db^{[1]}=\frac 1mnp.sum(dZ^{[1]},axis=1,keepdims=True)
db[1]=m1np.sum(dZ[1],axis=1,keepdims=True)
反向传播的推导是机器学习领域最难的数学推导之一。它需要了解线性代数,矩阵的导数,链式法则