吴恩达神经网络与深度学习章节笔记(三)——深层神经网络
视频课程链接:
https://www.bilibili.com/video/BV1FT4y1E74V?
笔记参考链接:
https://blog.csdn.net/weixin_36815313/article/details/105728919
课程作业链接:
https://download.csdn.net/download/baoli8425/19821557?spm=1001.2014.3001.5503
1. 深层神经网络 (Deep L-layer Neural Network)
上图是一个四层的神经网络,有三个隐藏层,隐藏层中的单元数目分别是5、5、3,最后是一个输出单元。
对深层神经网络我们做如下符号约定:
(1)
L
L
L表示神经网络的层数,上图中
L
L
L = 4。
(2)
n
[
l
]
n^{[l]}
n[l]表示在
l
l
l层上节点的数量。以上图为例,
n
[
0
]
n^{[0]}
n[0] =
n
x
n_x
nx = 3,
n
[
1
]
n^{[1]}
n[1] = 5,
n
[
2
]
n^{[2]}
n[2] = 5,
n
[
3
]
n^{[3]}
n[3] = 3,
n
[
4
]
n^{[4]}
n[4] =
n
[
L
]
n^{[L]}
n[L] = 3。
(3)
a
[
l
]
=
g
[
l
]
(
z
[
l
]
)
a^{[l]}=g^{[l]}(z^{[l]})
a[l]=g[l](z[l])表示在
l
l
l层上的激活值,最后一层的输出
a
[
L
]
a^{[L]}
a[L]=
y
^
\hat{y}
y^,表示这个神经网络的预测值。
(4)
W
[
l
]
W^{[l]}
W[l]表示
z
[
l
]
z^{[l]}
z[l]中的权重。
(5)
b
[
l
]
b^{[l]}
b[l]表示
z
[
l
]
z^{[l]}
z[l]中的偏置项。
(6) 输入特征记作
x
x
x,满足
x
=
a
[
0
]
x=a^{[0]}
x=a[0]。
2. 深层网络中的前向传播 (Forward Propagation in a Deep Network)
对其中一个训练样本
x
x
x应用前向传播的过程如下:
(1) 第一层
z
[
1
]
=
w
[
1
]
x
+
b
[
1
]
z^{[1]}=w^{[1]}x+b^{[1]}
z[1]=w[1]x+b[1],
a
[
1
]
=
g
[
1
]
(
z
[
1
]
)
a^{[1]}=g^{[1]}(z^{[1]})
a[1]=g[1](z[1]) (
x
x
x可以看作
a
[
0
]
a^{[0]}
a[0])
(2) 第二层
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])
(3) 第三层
z
[
3
]
=
w
[
3
]
a
[
2
]
+
b
[
3
]
z^{[3]}=w^{[3]}a^{[2]}+b^{[3]}
z[3]=w[3]a[2]+b[3],
a
[
3
]
=
g
[
3
]
(
z
[
3
]
)
a^{[3]}=g^{[3]}(z^{[3]})
a[3]=g[3](z[3])
(4) 第四层
z
[
4
]
=
w
[
4
]
a
[
3
]
+
b
[
4
]
z^{[4]}=w^{[4]}a^{[3]}+b^{[4]}
z[4]=w[4]a[3]+b[4],
a
[
4
]
=
g
[
4
]
(
z
[
4
]
)
=
y
^
a^{[4]}=g^{[4]}(z^{[4]})=\hat{y}
a[4]=g[4](z[4])=y^
前向传播可以归纳为多次迭代
z
[
l
]
=
w
[
l
]
a
[
l
−
1
]
+
b
[
l
]
z^{[l]}=w^{[l]}a^{[l-1]}+b^{[l]}
z[l]=w[l]a[l−1]+b[l],
a
[
l
]
=
g
[
l
]
(
z
[
l
]
)
a^{[l]}=g^{[l]}(z^{[l]})
a[l]=g[l](z[l])。
向量化的实现过程可以写成:
Z
[
l
]
=
W
[
l
]
A
[
l
−
1
]
+
b
[
l
]
,
A
[
l
]
=
g
[
l
]
(
Z
[
l
]
)
(
A
[
0
]
=
X
)
Z^{[l]}=W^{[l]}A^{[l−1]}+b^{[l]},A^{[l]}=g^{[l]}(Z^{[l]}) \quad (A^{[0]}=X)
Z[l]=W[l]A[l−1]+b[l],A[l]=g[l](Z[l])(A[0]=X)这里只能用一个显式for循环,让
l
l
l从1到
L
L
L遍历每一层,一层接着一层去计算前向传播。
3. 核对矩阵的维数 (Getting Your Matrix Dimensions Right)
当实现深度神经网络的时候,其中一个常用的检查代码是否有错的方法就是过一遍算法中矩阵的维数。
一般情况下对于单个训练样本,矩阵的维度有如下规律:
(1)
w
[
l
]
w^{[l]}
w[l]的维度是
(
n
[
l
]
,
n
[
l
−
1
]
)
(n^{[l]},\ n^{[l-1]})
(n[l], n[l−1]) (这里
w
w
w的维度是转置以后的);
(2)
b
[
l
]
b^{[l]}
b[l]的维度是
(
n
[
l
]
,
1
)
(n^{[l]},\ 1)
(n[l], 1);
(3)
d
w
[
l
]
dw^{[l]}
dw[l]和
w
[
l
]
w^{[l]}
w[l]维度相同,
d
b
[
l
]
db^{[l]}
db[l]和
b
[
l
]
b^{[l]}
b[l]维度相同,且
w
w
w和
b
b
b向量化维度不变,但
z
,
a
z,a
z,a以及
x
x
x的维度会向量化后发生变化。
而对于
m
\pmb{m}
mmm个训练样本,向量化之后矩阵的维度有如下规律:
(1)
Z
[
l
]
Z^{[l]}
Z[l]的维度是
(
n
[
l
]
,
m
)
(n^{[l]},\ m)
(n[l], m);
(2)
A
[
l
]
A^{[l]}
A[l]的维度是
(
n
[
l
]
,
m
)
(n^{[l]},\ m)
(n[l], m)。当
l
l
l = 0,
A
[
0
]
=
X
A^{[0]}=X
A[0]=X的维度是
(
n
[
0
]
,
m
)
(n^{[0]},\ m)
(n[0], m);
(3)
d
Z
[
l
]
dZ^{[l]}
dZ[l]和
Z
[
l
]
Z^{[l]}
Z[l]维度相同,
d
A
[
l
]
dA^{[l]}
dA[l]和
A
[
l
]
A^{[l]}
A[l]维度相同;
(4)
W
[
l
]
W^{[l]}
W[l]的维度不变,仍然是
(
n
[
l
]
,
n
[
l
−
1
]
)
(n^{[l]},\ n^{[l-1]})
(n[l], n[l−1]);
(5)
b
[
l
]
b^{[l]}
b[l]的维度是
(
n
[
l
]
,
m
)
(n^{[l]},\ m)
(n[l], m)。
4. 搭建深层神经网络块 (Building Blocks of Deep Neural Networks)
4.1 前向传播
上图是一个实现前向传播的模块:在第
l
l
l层中,输入是前一层
a
[
l
−
1
]
a^{[l-1]}
a[l−1],输出是
a
[
l
]
a^{[l]}
a[l],其中需要参数
W
[
l
]
W^{[l]}
W[l]和
b
[
l
]
b^{[l]}
b[l]来进行计算,并将计算过程中的
z
[
l
]
z^{[l]}
z[l]缓存起来,用于反向传播的计算。
前向传播的步骤可以写成:
(1)
z
[
l
]
=
W
[
l
]
⋅
a
[
l
−
1
]
+
b
[
l
]
z^{[l]}=W^{[l]}\cdot a^{[l-1]} + b^{[l]}
z[l]=W[l]⋅a[l−1]+b[l]
(2)
a
[
l
]
=
g
[
l
]
(
z
[
l
]
)
a^{[l]}=g^{[l]}(z^{[l]})
a[l]=g[l](z[l])
向量化实现过程可以写成:
(1)
Z
[
l
]
=
W
[
l
]
⋅
A
[
l
−
1
]
+
b
[
l
]
Z^{[l]}=W^{[l]}\cdot A^{[l-1]} + b^{[l]}
Z[l]=W[l]⋅A[l−1]+b[l]
(2)
A
[
l
]
=
g
[
l
]
(
Z
[
l
]
)
A^{[l]}=g^{[l]}(Z^{[l]})
A[l]=g[l](Z[l])
4.2 反向传播
上图是一个实现反向传播的模块:在第
l
l
l层中,输入是
d
a
[
l
]
da^{[l]}
da[l]和缓存的
z
[
l
]
z^{[l]}
z[l],输出是
d
a
[
l
−
1
]
da^{[l-1]}
da[l−1],另外还需要输出
d
W
[
l
]
dW^{[l]}
dW[l]和
d
b
[
l
]
db^{[l]}
db[l]。其中需要参数
W
[
l
]
W^{[l]}
W[l]和
b
[
l
]
b^{[l]}
b[l]来进行计算,最后计算出
d
z
[
l
]
dz^{[l]}
dz[l]。
反向传播的步骤可以写成:
(1)
d
z
[
l
]
=
d
a
[
l
]
⋅
g
[
l
]
′
(
z
[
l
]
)
dz^{[l]}=da^{[l]}\cdot g^{[l]^{\prime}}(z^{[l]})
dz[l]=da[l]⋅g[l]′(z[l])
(2)
d
w
[
l
]
=
d
z
[
l
]
⋅
a
[
l
−
1
]
dw^{[l]}=dz^{[l]}\cdot a^{[l-1]}
dw[l]=dz[l]⋅a[l−1]
(3)
d
b
[
l
]
=
d
z
[
l
]
db^{[l]}=dz^{[l]}
db[l]=dz[l]
(4)
d
a
[
l
−
1
]
=
w
[
l
]
T
⋅
d
z
[
l
]
da^{[l-1]}=w^{[l]T}\cdot dz^{[l]}
da[l−1]=w[l]T⋅dz[l]
式子(5)由式子(4)带入式子(1)得到,前四个式子就可实现反向函数。
(5)
d
z
[
l
]
=
w
[
l
+
1
]
T
d
z
[
l
+
1
]
⋅
g
[
l
]
′
(
z
[
l
]
)
dz^{[l]}=w^{[l+1]T}dz^{[l+1]}\cdot g^{[l]^{\prime}}(z^{[l]})
dz[l]=w[l+1]Tdz[l+1]⋅g[l]′(z[l])
向量化实现过程可以写成:
(1)
d
Z
[
l
]
=
d
A
[
l
]
⋅
g
[
l
]
′
(
Z
[
l
]
)
dZ^{[l]}=dA^{[l]}\cdot g^{[l]^{\prime}}(Z^{[l]})
dZ[l]=dA[l]⋅g[l]′(Z[l])
(2)
d
W
[
l
]
=
1
m
d
Z
[
l
]
⋅
A
[
l
−
1
]
T
dW^{[l]}=\frac1mdZ^{[l]}\cdot A^{[l-1]T}
dW[l]=m1dZ[l]⋅A[l−1]T
(3)
d
b
[
l
]
=
1
m
n
p
.
s
u
m
(
d
z
[
l
]
,
a
x
i
s
=
1
,
k
e
e
p
d
i
m
s
=
T
r
u
e
)
db^{[l]}=\frac1mnp.sum(dz^{[l]}, axis=1, keepdims=True)
db[l]=m1np.sum(dz[l],axis=1,keepdims=True)
(4)
d
A
[
l
−
1
]
=
W
[
l
]
T
⋅
d
Z
[
l
]
dA^{[l-1]}=W^{[l]T}\cdot dZ^{[l]}
dA[l−1]=W[l]T⋅dZ[l]
4.3 总结
上图是一个 L L L层神经网络的计算过程。 a [ 0 ] a^{[0]} a[0]即 x x x作为输入,沿着蓝色箭头从左往右逐层进行前向传播的计算,并缓存 z [ l ] z^{[l]} z[l]值,直到最后输出 a [ L ] a^{[L]} a[L]即 y ^ \hat{y} y^,并计算出损失函数 L ( y ^ , y ) L(\hat{y},y) L(y^,y)。接着再根据前向传播的输出值得到导数 d a [ L ] da^{[L]} da[L],以此作为输入,沿着红色箭头从右往左逐层进行反向传播的计算,并输出 d w [ l ] dw^{[l]} dw[l]和 d b [ l ] db^{[l]} db[l],用于梯度下降的参数更新,直到最终得到 d a [ 2 ] da^{[2]} da[2]和 d a [ 1 ] da^{[1]} da[1]。
5. 参数 vs 超参数 (Parameters vs. Hyperparameters)
超参数(hyperparameter):超参数的设置影响参数(parameter) W W W和 b b b的值。
- learning rate α(学习率)
- iterations(梯度下降法循环的数量)
- L L L(隐藏层数目)
- n [ l ] n^{[l]} n[l](隐藏层单元数目)
- choice of activation function(激活函数的选择)
- momentum(动量)
- mini batch size(一次训练所选取的样本数)
- regularization parameters(正则化参数)
以上列举了部分常用的超参数。
当你开始开发新应用时,预先很难确切知道超参数的最优值应该是什么,所以通常必须尝试很多不同的值,并走这个循环,试试各种参数,实现模型并观察是否成功,然后再迭代。
比如你可能大致知道一个学习率 α \alpha α=0.01最好,你可以实际试一下看看效果如何,然后基于尝试的结果你会发现,将学习率提高到0.05可能会更好。如果你不确定什么值最好,你可以先试试一个学习率 α \alpha α,再看看损失函数J的值有没有下降,然后再试试大一些的值,发现损失函数的值增加并发散了。再试试其他数,看结果是否下降的很快或者收敛在更高的位置。你可能需要尝试不同的 α \alpha α并观察损失函数 J J J的变化,然后发现这个 α \alpha α值会加快学习过程,并且收敛在更低的损失函数值上,我就会用这个 α \alpha α值了。