Coursera deeplearning.ai 深度学习笔记1-3-Shallow Neural Networks-浅层神经网络原理推导与代码实现

时间:2022-12-14 18:07:49

在掌握了逻辑回归算法后,先来学习浅层神经网络,之后再对深度神经网络进行学习。

1. 原理推导

1.1 神经网络表示

神经网络由输入层、隐含层和输出层构成。L层神经网络,隐含层为第1 ~ (L - 1)层,输出层为第L层。为了方便,将输入层写成第0层。
定义:上标[l]表示第l层,下标j表示第j个节点。
例如,下图为2层神经网络,包含1个隐藏层:

Coursera deeplearning.ai 深度学习笔记1-3-Shallow Neural Networks-浅层神经网络原理推导与代码实现

输入层和隐含层可以写成:
a[0]=x=x1x2x3,a[1]=a[1]1a[1]2a[1]3a[1]4(1)

1.2 正向传播(Forward Propagation)

计算过程与逻辑回归类似,只是多了隐含层,如下:
z[1]1=w[1]T1x+b[1]1,a[1]1=g(z[1]1)z[1]2=w[1]T2x+b[1]2,a[1]2=g(z[1]2)z[1]3=w[1]T3x+b[1]3,a[1]3=g(z[1]3)z[1]4=w[1]T4x+b[1]4,a[1]4=g(z[1]4)(2)
式中,g(z)为激活函数。可将上式向量化为:
z[1]1z[1]2z[1]3z[1]4=w[1]T1w[1]T2w[1]T3w[1]T4x1x2x3+b[1]1b[1]2b[1]3b[1]4,a[1]1a[1]2a[1]3a[1]4=gz[1]1z[1]2z[1]3z[1]4(3)
即:
z[1]=W[1]x+b[1],a[1]=g(z[1])(4)
式中,
z[1]=z[1]1z[1]2z[1]3z[1]4,W[1]=w[1]T1w[1]T2w[1]T3w[1]T4,b[1]=b[1]1b[1]2b[1]3b[1]4,a[1]=a[1]1a[1]2a[1]3a[1]4(5)
因此,对于该2层神经网络的每个样本,给定a[0] = x,正向传播计算流程如下:
z[1]=W[1]a[0]+b[1]a[1]=g(z[1])z[2]=W[2]a[1]+b[2]a[2]=g(z[2])(6)
各矩阵维度如下表:

矩阵
a [0]
W [1]
b [1]
z [1]
a [1]
W [2]
b [2]
z [2]
a [2]
维度
(3, 1)
(4, 3)
(4, 1)
(4, 1)
(4, 1)
(1, 4)
(1, 1)
(1, 1)
(1, 1)

以上推导仅仅针对单个样本,对于m个样本,以上标(m)表示第m个样本。则可以将公式改写为:
|z[1](1)||z[1](2)||||z[1](m)|=w[1]1Tw[1]2Tw[1]3Tw[1]4T|x(1)||x(2)||||x(m)|+b[1](7)
|a[1](1)||a[1](2)||||a[1](m)|=g|z[1](1)||z[1](2)||||z[1](m)|(8)
即:
Z[1]=W[1]X+b[1],A[1]=g(Z[1])(9)
式中,
Z[1]=|z[1](1)||z[1](2)||||z[1](m)|,A[1]=|a[1](1)||a[1](2)||||a[1](m)|(10)
因此,对于以上2层神经网络,针对m个样本,给定A[0] = X,正向传播计算流程如下:
Z[1]=W[1]A[0]+b[1]A[1]=g(Z[1])Z[2]=W[2]A[1]+b[2]A[2]=g(Z[2])(11)
各矩阵维度如下表:

矩阵
A [0]
W [1]
b [1]
Z [1]
A [1]
W [2]
b [2]
Z [2]
A [2]
维度
(3, m)
(4, 3)
(4, 1)
(4, m)
(4, m)
(1, 4)
(1, 1)
(1, m)
(1, m)

从式中可以看出,矩阵ZA在计算过程中,水平索引遍历所有样本集,垂直索引遍历神经网络每一层的各个节点。

1.3 激活函数(Activation Function)

常见的4种激活函数如下:

Coursera deeplearning.ai 深度学习笔记1-3-Shallow Neural Networks-浅层神经网络原理推导与代码实现

sigmoid函数:在0 ~ 1之间,很少用到,仅仅用于二分类问题。
tanh函数,在-1 ~ 1之间,均值为0,使得数据更集中。
sigmoid和tanh函数的一个共同缺点:当z很大或者很小时,函数的斜率都很小且接近0,从而使得梯度下降法的速度较慢。
ReLU(Rectified Linear Units)函数:通常比sigmoid和tanh函数效果好,是最常用的激活函数。缺点在于,当很大的梯度经过一个ReLU神经元,更新过参数后,这个神经元再也不会对任何数据有激活现象。对于较大的学习因子,经常会发生这个问题。因此,需要设置合适的、较小的学习因子。
Leaky ReLU函数:相比ReLU函数,设置了一个很小的常数α,保留了一些负轴的值,使得负轴信息不会全部丢失。

1.4 为什么激活函数使用非线性函数?

假如使用线性函数g(z) = z
则正向传播化简为:
z[1]=W[1]a[0]+b[1]a[1]=g(z[1])=z[1]z[2]=W[2]a[1]+b[2]=W[2]z[1]+b[2]a[2]=g(z[2])=z[2]=W[2](W[1]a[0]+b[1])+b[2]=(W[2]W[1])a[0]+(W[2]b[1]+b[2])=Wa[0]+b(12)
可以看出,a[2]z[1]等效,如果使用线性激活函数,就无法发挥隐含层的作用。在深度神经网络中,使用线性激活函数,多个隐含层与没有隐含层的效果相同。
因此,必须使用非线性激活函数。

1.5 梯度下降(Gradient Descent)

n[l]表示第l层的节点数,对于以上的2层神经网络:
n[0]=nx=3,n[1]=4,n[2]=1(13)
代价函数:
J(w,b)=1mi=1mL(a(i),y(i))=1mi=1m[y(i)loga(i)+(1y(i))log(1a(i))](14)
梯度下降法流程如下:
Computeactivationa(i),i=1,,mComputecostfunctionJdW[1]=dJdW[1],db[1]=dJdb[1],W[1]=W[1]αdW[1],b[1]=b[1]αdb[1],(15)
式中,α为学习因子。为了更新参数Wb,关键在于求解导数dWdb,可以通过反向传播来求解。

1.6 反向传播(Backward Propagation)

在正向传播中,已经计算得到了Z[1]A[1]Z[2]A[2]。此处使用sigmoid函数来推导。对于2层神经网络,针对单个样本,正向传播为:
z[1]=W[1]a[0]+b[1]a[1]=g(z[1])z[2]=W[2]a[1]+b[2]a[2]=g(z[2])(16)
与逻辑回归类似,反向传播计算如下:
dz[2]=a[2]ydW[2]=dz[2]a[1]Tdb[2]=dz[2]dz[1]=dJdz[2]dz[2]da[1]da[1]dz[1]=W[2]Tdz[2]g[1](z[1])dW[1]=dz[1]a[0]Tdb[1]=dz[1](17)
拓展到m个样本得到:
dZ[2]=A[2]YdW[2]=1mdZ[2]A[1]Tdb[2]=1mnp.sum(dZ[2],axis=1,keepdims=True)dz[1]=W[2]TdZ[2]g[1](Z[1])dW[1]=1mdZ[1]A[0]Tdb[1]=1mnp.sum(dZ[1],axis=1,keepdims=True)(18)
式中,“*”表示元素点乘。通过上式求出梯度dWdb,并代入梯度下降法中,即可对参数Wb进行更新。

1.7 随机初始化

对于如下的2层神经网络。

Coursera deeplearning.ai 深度学习笔记1-3-Shallow Neural Networks-浅层神经网络原理推导与代码实现

如果将参数全部初始化为0:
W[1]=[0000],b[1]=[00](19)
那么,无论采用什么样本来训练,都会得到:
a[1]1=a[1]2,dz[1]1=dz[1]2(20)
在更新参数的过程中,W始终保持如下的对称形式:
W=[uuvv](21)
这样, a[1]1 a[1]2 具体相同的功能,实际上只需要一个就够了。
所以,在初始化神经网络参数时,应当避免以上情况,将参数W随机初始化,为了方便,可以将b全部初始化为0。
另外,根据sigmoid或者tanh函数的特点,当输入较大时,函数的导数较大,会导致学习速度较慢。因此,通常将参数随机初始化为较小的参数:
W=np.random.randn(l,l1)0.01b=np.zeros((l,1))(22)

2. 代码实现

案例:采用2层神经网络实现色点的二分类。

Coursera deeplearning.ai 深度学习笔记1-3-Shallow Neural Networks-浅层神经网络原理推导与代码实现

计算流程如下:
Coursera deeplearning.ai 深度学习笔记1-3-Shallow Neural Networks-浅层神经网络原理推导与代码实现

2.1 初始化initialize

对参数W进行随机初始化,将参数b初始化为0。核心代码如下:
Coursera deeplearning.ai 深度学习笔记1-3-Shallow Neural Networks-浅层神经网络原理推导与代码实现

2.2 正向传播forward

按照下式计算各个节点的ZA
Z[1]=W[1]A[0]+b[1]A[1]=g(Z[1])Z[2]=W[2]A[1]+b[2]A[2]=g(Z[2])(23)
核心代码如下:
Coursera deeplearning.ai 深度学习笔记1-3-Shallow Neural Networks-浅层神经网络原理推导与代码实现

2.3 计算代价函数compute_cost

采用下式计算代价函数:
J(w,b)=1mi=1mL(a(i),y(i))=1mi=1m[y(i)loga(i)+(1y(i))log(1a(i))](24)
核心代码如下:
Coursera deeplearning.ai 深度学习笔记1-3-Shallow Neural Networks-浅层神经网络原理推导与代码实现

2.4 反向传播backward

按照下式计算参数的梯度dWdb
dZ[2]=A[2]YdW[2]=1mdZ[2]A[1]Tdb[2]=1mnp.sum(dZ[2],axis=1,keepdims=True)dz[1]=W[2]TdZ[2]g[1](Z[1])dW[1]=1mdZ[1]A[0]Tdb[1]=1mnp.sum(dZ[1],axis=1,keepdims=True)(25)
核心代码如下:
Coursera deeplearning.ai 深度学习笔记1-3-Shallow Neural Networks-浅层神经网络原理推导与代码实现

2.5 参数更新update_parameters

按照下式对参数Wb进行更新:
W[1]=W[1]αdW[1],b[1]=b[1]αdb[1]W[2]=W[2]αdW[2],b[2]=b[2]αdb[2](26)
核心代码如下:
Coursera deeplearning.ai 深度学习笔记1-3-Shallow Neural Networks-浅层神经网络原理推导与代码实现

2.6 模型构建nn_model

将以上几个模块进行整合,输入训练样本,得到最优参数Wb。关键代码如下:
Coursera deeplearning.ai 深度学习笔记1-3-Shallow Neural Networks-浅层神经网络原理推导与代码实现

2.7 预测predict

根据优化得到的参数Wb,输入样本x,得到预测值,如果预测概率大于0.5,则预测值为1,否则为0。关键代码如下:
Coursera deeplearning.ai 深度学习笔记1-3-Shallow Neural Networks-浅层神经网络原理推导与代码实现

2.8 样本测试

代码如下:
Coursera deeplearning.ai 深度学习笔记1-3-Shallow Neural Networks-浅层神经网络原理推导与代码实现
可得到如下输出,分类准确率为90.50%。

Coursera deeplearning.ai 深度学习笔记1-3-Shallow Neural Networks-浅层神经网络原理推导与代码实现

此外,对隐含层节点数量的影响作了分析,核心代码如下:
Coursera deeplearning.ai 深度学习笔记1-3-Shallow Neural Networks-浅层神经网络原理推导与代码实现
得到如下结果。可以看出,较多的隐含层节点无法提升分类准确率,甚至存在过拟合现象,5个隐含层节点是比较理想的结果。
Coursera deeplearning.ai 深度学习笔记1-3-Shallow Neural Networks-浅层神经网络原理推导与代码实现

代码下载地址:https://gitee.com/tuzhen301/Coursera-deeplearning.ai1-3