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.8 激活函数的导数 Derivatives of activation functions
在神经网络中使用反向传播的时候,就需要计算激活函数的斜率或者导数。本节会介绍如何计算激活函数的斜率。
1。sigmod函数
g(x)函数在z处的斜率,求导过程如下:
d d z g ( z ) = 1 1 + e − z ( 1 − 1 1 + e − z ) = g ( z ) ( 1 − g ( z ) ) \frac {d}{dz}g(z)=\frac 1{1+e^{-z}}(1 - \frac1{1+e^{-z}})=g(z)(1-g(z)) dzdg(z)=1+e−z1(1−1+e−z1)=g(z)(1−g(z))
我们代入z值,来看看这个结果是否合理。
- 如果z比较大,例如z=10, g ( z ) ≈ 1 g(z) \approx 1 g(z)≈1,所以斜率 d d z g ( z ) ≈ 0 \frac {d}{dz}g(z) \approx 0 dzdg(z)≈0
- 同理如果z比较小,例如z=-10, g ( z ) ≈ 0 g(z) \approx 0 g(z)≈0,所以斜率 d d z g ( z ) ≈ 0 \frac {d}{dz}g(z) \approx 0 dzdg(z)≈0
- 如果z=0,那么 g ( z ) = 1 2 g(z)=\frac 12 g(z)=21,所以斜率 d d z g ( z ) = 1 4 \frac {d}{dz}g(z) = \frac 14 dzdg(z)=41
从曲线图中可以得知,上面的结果是正确的。
符号约定
导数用
g
′
(
z
)
g'(z)
g′(z)表示,所以
g
′
(
z
)
=
d
d
z
g
(
z
)
g'(z)=\frac {d}{dz}g(z)
g′(z)=dzdg(z)
结论,sigmod函数的导数公式为:
在NN中,
a
=
g
(
z
)
a=g(z)
a=g(z),
g
′
(
z
)
=
a
(
1
−
a
)
g'(z)=a(1-a)
g′(z)=a(1−a)
这个公式的优点是,如果你已经计算出a,那你就能很快计算出导数(斜率) g ′ ( z ) g'(z) g′(z)。
2。tanh函数
tanh函数导数为
g ′ ( z ) = d d z g ( z ) = 1 − ( t a n h ( z ) ) 2 g'(z)=\frac {d}{dz}g(z)=1-(tanh(z))^2 g′(z)=dzdg(z)=1−(tanh(z))2
证明
- z比较大,如z=10, t a n h ( z ) ≈ 1 tanh(z) \approx 1 tanh(z)≈1,所以斜率 g ′ ( z ) ≈ 0 g'(z)\approx0 g′(z)≈0
- z比较小,如z=-10, t a n h ( z ) ≈ − 1 tanh(z) \approx -1 tanh(z)≈−1,所以斜率 g ′ ( z ) ≈ 0 g'(z)\approx0 g′(z)≈0
- z=0, t a n h ( z ) = 0 tanh(z) =0 tanh(z)=0,所以斜率 g ′ ( z ) = 1 g'(z)=1 g′(z)=1
与tanh函数曲线图相符合。
结论,tanh函数的导数公式为:
a
=
g
(
z
)
a=g(z)
a=g(z),
g
′
(
z
)
=
1
−
a
2
g'(z)=1-a^2
g′(z)=1−a2
3。Relu函数
Relu函数导数为
显然,公式也是与图像中的斜率相符合的。
在软件中实现Relu算法,如果z正好为0,可以令其导数为1或者为0,对于下降算法而言,这无关紧要。
4。带泄漏的Relu函数Leaky Relu
Leaky Relu函数的导数为
在软件中实现Relu算法,如果z正好为0,可以令其导数为1或者为0.01。
掌握好以上的公式,你就可以计算出这些激活函数的斜率(导数)。
3.9 神经网络的梯度下降法 Gradient descent for neural networks
本节将介绍NN梯度下降法或者说反向传播的具体实现。
对于单隐藏层的NN4个 正向计算公式 如下
Z
[
1
]
=
W
[
1
]
A
[
0
]
+
b
[
1
]
Z^{[1]}=W^{[1]}A^{[0]}+b^{[1]}
Z[1]=W[1]A[0]+b[1]
A
[
1
]
=
g
[
1
]
(
Z
[
1
]
)
A^{[1]}=g^{[1]}(Z^{[1]})
A[1]=g[1](Z[1])
Z
[
2
]
=
W
[
2
]
A
[
1
]
+
b
[
2
]
Z^{[2]}=W^{[2]}A^{[1]}+b^{[2]}
Z[2]=W[2]A[1]+b[2]
A
[
2
]
=
g
[
2
]
(
Z
[
2
]
)
A^{[2]}=g^{[2]}(Z^{[2]})
A[2]=g[2](Z[2])
g [ 1 ] g^{[1]} g[1]选用tanh函数, g [ 2 ] g^{[2]} g[2]选用 σ \sigma σ函数。
公式中包含了
W
[
1
]
W^{[1]}
W[1],
W
[
2
]
W^{[2]}
W[2],
b
[
1
]
b^{[1]}
b[1],
b
[
2
]
b^{[2]}
b[2]这些参数。
我们用n[0]表示输入特征个数,n[1]表示隐藏层单元个数,n[2]表示输出层单元个数,而本例中n[2]=1。
所以
- 矩阵 W [ 1 ] W^{[1]} W[1]的维度是(n[1],n[0])。
- 矩阵 b [ 1 ] b^{[1]} b[1]的维度是(n[1],1),它是个列向量。
- 矩阵 W [ 2 ] W^{[2]} W[2]的维度是(n[2],n[1])。
- 矩阵 b [ 2 ] b^{[2]} b[2]的维度是(n[2],1)。
二分类NN网络的 成本函数公式 如下,它是损失函数的平均值
J ( W [ 1 ] , b [ 1 ] , W [ 2 ] , b [ 2 ] ) = 1 m ∑ i = 1 m L ( y ^ , y ) J(W^{[1]},b^{[1]},W^{[2]},b^{[2]})=\frac 1m \sum_{i=1}^mL(\hat y,y) J(W[1],b[1],W[2],b[2])=m1∑i=1mL(y^,y)
这里的损失函数和之前逻辑回归完全一样。
如果要训练参数,你的算法需要梯度下降。在训练NN时候,初始化参数不是为零,而是随机初始化参数很重要。
当你参数初始化成某些值后,每次梯度下降循环都会计算预测值 y ^ ( i ) \hat y^{(i)} y^(i),i=1…m。
然后再计算成本函数对参数的导数: d W [ 1 ] = d J d W [ 1 ] dW^{[1]}=\frac{dJ}{dW^{[1]}} dW[1]=dW[1]dJ, d b [ 1 ] = d J d b [ 1 ] db^{[1]}=\frac{dJ}{db^{[1]}} db[1]=db[1]dJ, d W [ 2 ] = d J d W [ 2 ] dW^{[2]}=\frac{dJ}{dW^{[2]}} dW[2]=dW[2]dJ, d b [ 2 ] = d J d b [ 2 ] db^{[2]}=\frac{dJ}{db^{[2]}} db[2]=db[2]dJ
最后,参数会更新为
W
[
1
]
=
W
[
1
]
−
α
d
W
[
1
]
W^{[1]}=W^{[1]}-\alpha dW^{[1]}
W[1]=W[1]−αdW[1]
b
[
1
]
=
b
[
1
]
−
α
d
b
[
1
]
b^{[1]}=b^{[1]}-\alpha db^{[1]}
b[1]=b[1]−αdb[1]
W
[
2
]
=
W
[
2
]
−
α
d
W
[
2
]
W^{[2]}=W^{[2]}-\alpha dW^{[2]}
W[2]=W[2]−αdW[2]
b
[
2
]
=
b
[
2
]
−
α
d
b
[
2
]
b^{[2]}=b^{[2]}-\alpha db^{[2]}
b[2]=b[2]−αdb[2]
α \alpha α是学习率。
以上就是梯度下降算法的一次迭代计算过程。你会重复很多次这样的过程,直到参数看上去在收敛。
前面几节已经详细介绍过如何通过向量化计算预测值 y ^ \hat y y^。现在来看看如何计算偏导 d W [ 1 ] dW^{[1]} dW[1], d b [ 1 ] db^{[1]} db[1], d W [ 2 ] dW^{[2]} dW[2], d b [ 2 ] db^{[2]} db[2]。
按照反向传播过程,6个计算公式如下
(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),这是对矩阵的一个维度求和。axis=1表示水平求和;keepdims=True防止输入秩为1的数组,确保输出维度是(n[2],1),其实本例中这里是一个实数,因为n[2]=1,二分类输出预测值只可能是1个,非0即1。
(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]),
g
[
1
]
′
g^{[1]'}
g[1]′是隐藏层激活函数的导数;符号*表示逐个元素乘积。
W
[
2
]
T
d
Z
[
2
]
W^{[2]T}dZ^{[2]}
W[2]TdZ[2]是n[1] x m矩阵;逐个元素导数
g
[
1
]
′
(
Z
[
1
]
)
g^{[1]'}(Z^{[1]})
g[1]′(Z[1])也是n[1] x m矩阵。
(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),这里输出的是(n[1],1)维度的向量。
矩阵Y是1 x m维度,所有样本标签值横向堆叠起来。
Y
=
[
y
(
1
)
y
(
2
)
.
.
.
.
.
.
y
(
m
)
]
Y=[y^{(1)}y^{(2)}......y^{(m)}]
Y=[y(1)y(2)......y(m)]。
我们也可以用reshape替代keepdims=True,这个在前面已经介绍过。
这里只是直接给出了反向传播的公式,在下一节中会介绍如何推导出这6个公式。