第三周:浅层神经网络(Shallow neural networks)

3.1 神经网络概述(Neural Network Overview)

3.2 神经网络的表示(Neural Network Representation )

单隐藏层神经网络就是典型的浅层(shallow)神经网络

单隐藏层神经网络也被称为两层神经网络(2 layer NN)

ll层的权重W[l]W^{[l]}维度的行等于ll层神经元的个数,列等于l1l-1层神经元的个数;第ii层常数项b[l]b^{[l]}维度的行等于ll层神经元的个数,列始终为1

3.3 计算一个神经网络的输出(Computing a Neural Network's output )

两层神经网络可以看成是逻辑回归再重复计算一次

逻辑回归的正向计算可以分解成计算z和a的两部分:

z=wTx+bz=w^Tx+b
a=σ(z)a=\sigma(z)

两层神经网络,从输入层到隐藏层对应一次逻辑回归运算;从隐藏层到输出层对应一次逻辑回归运算

z[1]=W[1]x+b[1]z^{[1]}=W^{[1]}x+b^{[1]}
a[1]=σ(z[1])a^{[1]}=\sigma(z^{[1]})
z[2]=W[2]a[1]+b[2]z^{[2]}=W^{[2]}a^{[1]}+b^{[2]}
a[2]=σ(z[2])a^{[2]}=\sigma(z^{[2]})

3.4 多样本向量化(Vectorizing across multiple examples )

for循环来求解其正向输出:

for i = 1 to m:

z[1](i)=W[1]x(i)+b[1]a[1](i)=σ(z[1](i))z[2](i)=W[2]a[1](i)+b[2]a[2](i)=σ(z[2](i))\begin{aligned}&z^{[1](i)}=W^{[1]}x^{(i)}+b^{[1]}\\&a^{[1](i)}=\sigma(z^{[1](i)})\\&z^{[2](i)}=W^{[2]}a^{[1](i)}+b^{[2]} \\&a^{[2](i)}=\sigma(z^{[2](i)})\end{aligned}

矩阵运算的形式:

Z[1]=W[1]X+b[1]Z^{[1]}=W^{[1]}X+b^{[1]}
A[1]=σ(Z[1])A^{[1]}=\sigma(Z^{[1]})
Z[2]=W[2]A[1]+b[2]Z^{[2]}=W^{[2]}A^{[1]}+b^{[2]}
A[2]=σ(Z[2])A^{[2]}=\sigma(Z^{[2]})

行表示神经元个数,列表示样本数目mm

3.5 激活函数(Activation functions)

  • sigmoid函数

  • tanh函数

  • ReLU函数

  • Leaky ReLU函数

对于隐藏层的激活函数,tanhtanh函数要比sigmoidsigmoid函数表现更好一些。因为tanhtanh函数的取值范围在[1,+1][-1,+1]之间,隐藏层的输出被限定在[1,+1]-1,+1]之间,可以看成是在00值附近分布,均值为00。这样从隐藏层到输出层,数据起到了归一化(均值为00)的效果

对于输出层的激活函数,因为二分类问题的输出取值为{0,+1}\{0,+1\},所以一般会选择sigmoidsigmoid作为激活函数

选择ReLUReLU作为激活函数能够保证zz大于零时梯度始终为11,从而提高神经网络梯度下降算法运算速度。但当zz小于零时,存在梯度为00的缺点

LeakyLeaky ReLUReLU激活函数,能够保证zz小于零时梯度不为00

3.6 为什么需要( 非线性激活函数?(why need a nonlinear activation function?)

假设所有的激活函数都是线性的,直接令激活函数g(z)=zg(z)=z,即a=za=z

z[1]=W[1]x+b[1]z^{[1]}=W^{[1]}x+b^{[1]}
a[1]=z[1]a^{[1]}=z^{[1]}
z[2]=W[2]a[1]+b[2]z^{[2]}=W^{[2]}a^{[1]}+b^{[2]}
a[2]=z[2]a^{[2]}=z^{[2]}
a[2]=z[2]=W[2]a[1]+b[2]=W[2](W[1]x+b[1])+b[2]=(W[2]W[1])x+(W[2]b[1]+b[2])=Wx+ba^{[2]}=z^{[2]}=W^{[2]}a^{[1]}+b^{[2]}=W^{[2]}(W^{[1]}x+b^{[1]})+b^{[2]}=(W^{[2]}W^{[1]})x+(W^{[2]}b^{[1]}+b^{[2]})=W'x+b'

多层隐藏层的神经网络,如果使用线性函数作为激活函数,最终的输出仍然是输入xx的线性模型。这样的话神经网络就没有任何作用了。因此,隐藏层的激活函数必须要是非线性的

如果是预测问题而不是分类问题,输出yy是连续的情况下,输出层的激活函数可以使用线性函数。如果输出yy恒为正值,则也可以使用ReLUReLU激活函数

3.7 激活函数的导数(Derivatives of activation functions )

sigmoidsigmoid函数的导数:

g(z)=11+e(z)g(z)=\frac{1}{1+e^{(-z)}}
g(z)=ddzg(z)=g(z)(1g(z))=a(1a)g'(z)=\frac{d}{dz}g(z)=g(z)(1-g(z))=a(1-a)

tanhtanh函数的导数:

g(z)=e(z)e(z)e(z)+e(z)g(z)=\frac{e^{(z)}-e^{(-z)}}{e^{(z)}+e^{(-z)}}
g(z)=ddzg(z)=1(g(z))2=1a2g'(z)=\frac{d}{dz}g(z)=1-(g(z))^2=1-a^2

ReLUReLU函数的导数:

g(z)=max(0,z)g(z)=max(0,z)
x={0if z<01if z0x = \begin{cases} 0 &\text{if } z < 0 \\ 1 &\text{if } z \geq 0 \end{cases}

LeakyReLULeaky ReLU函数:

g(z)=max(0.01z,z)g(z)=max(0.01z,z)
g(z)={0.01if z<01if z0g'(z) = \begin{cases} 0.01 &\text{if } z < 0 \\ 1 &\text{if } z \geq 0 \end{cases}

3.8 神经网络的梯度下降(Gradient descent for neural networks)

dZ[2]=A[2]YdZ^{[2]}=A^{[2]}-Y
dW[2]=1mdZ[2]A[1]TdW^{[2]}=\frac1mdZ^{[2]}A^{[1]T}
db[2]=1mnp.sum(dZ[2],axis=1,keepdim=True)db^{[2]}=\frac1mnp.sum(dZ^{[2]},axis=1,keepdim=True)
dZ[1]=W[2]TdZ[2]g(Z[1])dZ^{[1]}=W^{[2]T}dZ^{[2]}\ast g'(Z^{[1]})
dW[1]=1mdZ[1]XTdW^{[1]}=\frac1mdZ^{[1]}X^T
db[1]=1mnp.sum(dZ[1],axis=1,keepdim=True)db^{[1]}=\frac1mnp.sum(dZ^{[1]},axis=1,keepdim=True)

3.9 (选修)直观理解反向传播(Backpropagation intuition )

单个训练样本反向过程可以根据梯度计算方法逐一推导:

dz[2]=a[2]ydz^{[2]}=a^{[2]}-y
dW[2]=dz[2]z[2]W[2]=dz[2]a[1]TdW^{[2]}=dz^{[2]}\cdot \frac{\partial z^{[2]}}{\partial W^{[2]}}=dz^{[2]}a^{[1]T}
db[2]=dz[2]z[2]b[2]=dz[2]1=dz[2]db^{[2]}=dz^{[2]}\cdot \frac{\partial z^{[2]}}{\partial b^{[2]}}=dz^{[2]}\cdot 1=dz^{[2]}
dz[1]=dz[2]z[2]a[1]a[1]z[1]=W[2]Tdz[2]g[1](z[1])dz^{[1]}=dz^{[2]}\cdot \frac{\partial z^{[2]}}{\partial a^{[1]}}\cdot \frac{\partial a^{[1]}}{\partial z^{[1]}}=W^{[2]T}dz^{[2]}\ast g^{[1]'}(z^{[1]})
dW[1]=dz[1]z[1]W[1]=dz[1]xTdW^{[1]}=dz^{[1]}\cdot \frac{\partial z^{[1]}}{\partial W^{[1]}}=dz^{[1]}x^T
db[1]=dz[1]z[1]b[1]=dz[1]1=dz[1]db^{[1]}=dz^{[1]}\cdot \frac{\partial z^{[1]}}{\partial b^{[1]}}=dz^{[1]}\cdot 1=dz^{[1]}

浅层神经网络(包含一个隐藏层),mm个训练样本的正向传播过程和反向传播过程分别包含了66个表达式,其向量化矩阵形式如下图所示:

3.10 随机初始化(Random Initialization)

神经网络模型中的参数权重WW不能全部初始化为零

如果权重W[1]W^{[1]}W[2]W^{[2]}都初始化为零,即:

W[1]=[0000]W^{[1]}= \left[ \begin{matrix} 0 & 0 \\ 0 & 0 \end{matrix} \right]
W[2]=[00]W^{[2]}= \left[ \begin{matrix} 0 & 0 \end{matrix} \right]

这样使得隐藏层第一个神经元的输出等于第二个神经元的输出,即a1[1]=a2[1]a_1^{[1]}=a_2^{[1]}。经过推导得到dz1[1]=dz2[1]dz_1^{[1]}=dz_2^{[1]}dW1[1]=dW2[1]dW_1^{[1]}=dW_2^{[1]},这样的结果是隐藏层两个神经元对应的权重行向量W1[1]W_1^{[1]}W2[1]W_2^{[1]}每次迭代更新都会得到完全相同的结果,W1[1]W_1^{[1]}始终等于W2[1]W_2^{[1]},完全对称。这样隐藏层设置多个神经元就没有任何意义

权重WW全部初始化为零带来的问题称为symmetry breaking problem

随机初始化:

W_1 = np.random.randn((2,2))*0.01
b_1 = np.zero((2,1))
W_2 = np.random.randn((1,2))*0.01
b_2 = 0

WW比较小,是因为如果使用sigmoidsigmoid函数或者tanhtanh函数作为激活函数的话,WW比较小,得到的z|z|也比较小(靠近零点),而零点区域的梯度比较大,这样能大大提高梯度下降算法的更新速度,尽快找到全局最优解

如果WW较大,得到的z|z|也比较大,附近曲线平缓,梯度较小,训练过程会慢很多

如果激活函数是ReLUReLU或者LeakyLeaky ReLUReLU函数,则不需要考虑这个问题

如果输出层是sigmoidsigmoid函数,则对应的权重WW最好初始化到比较小的值

Last updated