【深度学习基础】系列博客为学习Coursera上吴恩达深度学习课程所做的课程笔记。
本文为原创文章,未经本人允许,禁止转载。转载请注明出处。
1.神经网络的梯度下降法
在【深度学习基础】第四课:正向传播与反向传播一文中我们了解了反向传播的原理,学习了梯度下降法在logistic回归中的应用。其实,logistic回归模型就可以看作是一个没有隐藏层的神经网络结构。那么,梯度下降法在一个带有隐藏层的浅层神经网络中是怎么应用的呢?这便是本文所要讨论的内容。
我们以【深度学习基础】第六课:浅层神经网络中所用的双层神经网络为例:
假设所有激活函数均为sigmoid函数,所要解决的问题为二分类问题。loss function和cost function依然采用交叉熵损失函数。
1.1.单样本的情况
首先,我们先考虑只有一个样本的情况。
在反向传播之前,我们先复习下正向传播的过程。假设样本的维数为m,即有m个特征。则我们的输入为:
x=a[0]=[x1x2⋮xm]m×1第一层(即隐藏层)的参数w[1]和b[1]分别为:
w[1]=[⋯w[1]1T⋯⋯w[1]2T⋯⋯w[1]3T⋯⋯w[1]4T⋯]4×m据此可得到第一层的输出a[1]为:
a[1]=[a[1]1a[1]2a[1]3a[1]4]4×1=σ(z[1])=σ([z[1]1z[1]2z[1]3z[1]4]4×1)第二层的参数w[2]和b[2]为:
w[2]=[⋯w[2]1T⋯]1×4第二层的输出a[2]为:
a[2]=[a[2]1]1×1=σ(z[2])=σ([z[2]1]1×1)借用【深度学习基础】第四课:正向传播与反向传播中计算的导数的结果,我们通过反向传播可以很快得到:
- da[2]=−ya[2]+1−y1−a[2];维数为1×1。
- dz[2]=a[2]−y;维数为1×1。
- dw[2]=dz[2]a[1]T;维数为1×4=(1×1)(1×4)。
- db[2]=dz[2];维数为1×1。
- da[1]=dz[2]w[2]T;维数为4×1。
- dz[1]=da[1]∗g[1]′(z[1]);维数为4×1。
*
表示da[1]中的每个元素都乘上g[1]′(z[1])。其中,g[1]′(z[1])=a[1](1−a[1])。 - dw[1]=dz[1]a[0]T;维度为4×m=(4×1)(1×m)。
- db[1]=dz[1];维度为4×1。
1.2.多个样本的情况
n个样本的情况和单样本基本类似:
- dZ[2]=A[2]−Y;维度为1×n。
- dw[2]=1ndZ[2]A[1]T;维数为1×4=(1×n)(n×4)。
- db[2]=1nnp.sum(dZ[2],axis=1,keepdims=True);维度为1×1。
- dZ[1]=dA[1]∗g[1]′(Z[1]);维数为4×n。
- dw[1]=1ndZ[1]A[0]T;维数为4×m=(4×n)(n×m)。
- db[1]=1nnp.sum(dZ[1],axis=1,keepdims=True);维数为4×1。
2.网络参数的随机初始化
‼️如果将神经网络的各参数数组全部初始化为0,会使得梯度下降算法完全无效。
👉但是如果只是逻辑回归的话,可以将所有参数都初始化为0。
假设我们有如下的逻辑回归模型:
正向传播:
- a1=sigmoid(w11x1+w21x2+b)
- L=−ylog(a1)−(1−y)log(1−a1)
反向传播:
- da1=−ya1+1−y1−a1
- dw11=(a1−y)x1
- dw21=(a1−y)x2
- db=(a1−y)
当w11=w21=0时,dw11和dw21会因为x1和x2的不同而不同,梯度下降法可以正常进行。即使b也等于0,梯度下降法依旧可以正常进行。
👉现在考虑神经网络中的所有参数被初始化为0的情况。
正向传播:
- a1=g(w11x1+w21x2+b1)
- a2=g(w12x1+w22x2+b2)
- a3=sigmoid(w13a1+w23a2+b3)
- L=−yloga3−(1−y)log(1−a3)
反向传播:
- da3=−ya3+1−y1−a3
- dw13=(a3−y)a1
- dw23=(a3−y)a2
- db3=(a3−y)
- da1=(a3−y)w13
- da2=(a3−y)w23
- dw12=da2∗a′2∗x1
- dw22=da2∗a′2∗x2
- db2=da2∗a′2
- dw11=da1∗a′1∗x1
- dw21=da1∗a′1∗x2
- db1=da1∗a′1
我们考虑以下两种情况:
✓情况一:模型所有权重w初始化为0,所有偏置b初始化为0。
始终有a1=a2=g(0),所以始终有dw13=dw23,每次迭代更新权重时,w13总是等于w23,出现权重的对称性。
在第一次迭代时,因为w13=w23=0,所以da1=da2=0,所以dw12=dw22=dw11=dw21=0,因此在第一次梯度下降法运行时,除了w13和w23能够及时得到更新,其余权重均得不到更新。在之后的迭代中,因为w13和w23总是相等,所以始终有dw12=dw11;dw22=dw21,即始终有w12=w11;w22=w21,也呈现出权重的对称性。
这样使得同一隐藏层内的多个神经元完全在运行相同的操作(一样的输入和输出),没有任何意义。
✓情况二:模型所有权重w初始化为0,所有偏置b随机初始化。
因为b的随机初始化,所以a1≠a2,所以w13和w23可以正常更新。
w11,w12,w21,w22除了第一次迭代无法更新,后续迭代也可以正常更新。
并且均不存在权重对称性。
但是这种方式存在更新较慢,梯度消失,梯度爆炸等问题,在实践中,通常不会选择此方式。
因此,我们常用的解决办法就是:随机初始化网络参数。例如产生高斯分布随机变量:
w[1]=np.random.randn((2,2))∗0.01一般还会在末尾乘上一个很小的数字,例如0.01, 将权重初始化成很小的随机数。
因为如果权重初始值很大,对于sigmoid和tanh函数,计算得到的z值就会很大或很小,这样就会使梯度变得很小,梯度下降法的收敛速度会非常慢。 但是如果我们的神经网络中没有sigmoid或tanh函数,那么可能影响就不会很大。
在训练浅层神经网络时,0.01通常是一个比较合适的值。但是当训练深层神经网络时,一般会选择一个其他的常数,这个在今后的博客中会有介绍。
但是参数b可以初始化为0,这个是没有影响的:
b[1]=np.zero((2,1))