吴恩达-DeepLearning.ai-Course2-Week1笔记

本周主要学习了如何设置训练、开发、测试集,如何分析高偏差高方差的情况以及面对高偏差或者高方差应该如何做,以及如何运用不同形式的正则化, 比如L2正则化还有对你的神经网络进行随机失活(dropout),即一些加速神经网络训练的技巧,最后是梯度检验的内容,个人觉得本周课程还是蛮重要的,笔记如下方便日后查看

1.我们一般把数据集分为训练集,开发集,还有测试集(当然也可以仅仅存在训练集和开发集),如果数据集比较小,也许可以采用传统的分割比例70/30.但如果数据集大了很多,那也可以使开发集和测试集远小于总数据的20%,甚至远小于10%,注意,开发集和测试集中的数据分布最好相同(比如数据来源一致)

2.Bias/Variance:偏差(偏离度)/方差(集中度)

                                                                       图1

图1从左到右,分别为:欠拟合,正确,过拟合

注意图2:理解偏差和方差的两个关键数据  是训练集误差和开发集误差(下图中的百分号就是误差)(另外下边的误差是基于人眼识别0%的误差分析的,也叫贝叶斯误差接近0%,以及数据都是来源于同一分布)

                                                                                           图2

比如图片非常模糊,甚至人眼都识别不了,那么贝叶斯误差会很高;

在如下图3所示,该分类算法同时具有高偏差(几乎一条直线分类,左下角数据被忽略了)以及高方差(过拟合了两个孤立样本)

                                                                                   图3

3.Basic”recipe” formachine learning,

机器学习的基本准则能让我们在改进算法性能时更有条理

1>.当训练一个神经网络的时候,andrew会首先问“这个算法是否有高偏差?”,如果存在该问题,那么我们需要挑选一个新的网络,比如带有更多隐藏层或跟多隐藏单元的或者延长训练时间

2>.当通过1>把偏差降到可以接受的范围后,就再问”这个算法是否有高方差?”要判断这一点,会看模型在开发集上的表现,看模型是否具备一般化的能力,就是如果在训练集上性能良好,当一般化到开发集上时仍然良好。如果有较高的方差,那么解决高方差问题最好的方法是取得更多的数据(当然前提是你能获取得到),如果不能获取更多数据还可以尝试正则化( 正则化是一个减小方差的一个很有用的方法

4.Logistic regression

如果你怀疑你的神经网络在数据上发生了过拟合,也就是存在高方差的问题,你也许需要首先尝试使用正则化。

1>.我们以逻辑回归为例进行阐述,在逻辑回归中,你会尝试最小化代价函数J,图4中公式成为L2正则化,这里使用的是参数矢量w的。欧几里得范数也称L2范数

                                                                                    图4

为什么只对w进行正则化呢?,因为w是一个可以具有非常高维度的矢量,几乎所有的参数都集中在w中,而不是b中

2>.在神经网络中的L2范数

                                                                                           图5

如上图5中,L1正则化后,w最后会变得很稀疏,意味着w矢量中有很多0,有些人认为这有助于压缩模型,因为有一部分是参数0,只需要较少的内存来存储模型,而在实践中发现,通过L1正则化让模型变得稀疏带来的收益甚微,所以至少再压缩模型的目标上L1的作用不大

在训练中,L2正则化使用的频繁的多,λ成为正则化参数(是需要调优的另一个超参数)

在以上描述中式逻辑回归的例子,那么在神经网络中请看以下图6介绍:(L是神经网络的层数)

                                                                                      图6

以上矩阵的范数称为矩阵的”弗罗贝尼乌斯范数”,用脚标F表示,它表示矩阵中元素的平方和,那么有了它如何实现梯度下降呢?如下图7中,注意第四行,对某一层的范数求导后得到紫色的那个公式,

                                                                                      图7

这样L2范数正则化又被称为权重衰减(只是让权重乘以了一个略小于1的数字,展开wl的公式就能看得出)

5.为什么正则化能防止过拟合?

                                                                                               图8

如上图8所示,一个直观的解释是当λ很大的时候WL约等于0因此这个直观理解就是把很多隐藏单元的权重设置的太接近0了而导致这些隐藏单元的影响被消除了,如果是这种情况,那么会大大简化的神经网络变成一个很小的神经网络,事实上这种情况和逻辑回归单元很像,那么这个过拟合网络带到更加接近左边高偏差的状态,但λ存在一个中间值能够得到一个更加接近中间这个刚刚好的状态

再举一个直观的例子:

                                                                                                  图9

以tanh激活函数来看,如上图9所示,中间圆圈部分函数是趋于线性的,当λ很大的时候,W会很小,进而导致Z很小,所以会处在线性部分的区域中,那么我们知道线性激活函数不能处理复杂问题

注意:在程序中增加正则项的时候,我们根据代价函数J的定义加入如下紫色额外的惩罚项来防止权重过大

如果使用梯度下降方法。调试程序的一个步骤就是画出代价函数J梯度下降的迭代次数的图像,可以看到的是每次迭代后代价函数J都会单调递减的,如果你实现了正则化部分,那么请记住J现在有了新的定义

6.Dropout regularization

除了L2正则化,另一种非常强大的正则化技术是,随机失活正则化(丢弃法droput)

使用随机失活技术,我们要遍历这个网络的每一层,且为丢弃(drop)网络中的某个节点置一个概率值,即对网络中的每一层,我们将对立每一个节点做一次公平投币,使这个节点有50%的几率被保留,50%的几率被丢弃,抛完这些硬币我们会决定消除哪些节点如下图10所示,然后清除那些节点上所有正在进行的运算(如图11所示):


                                                                                          图10

                                                                                         图11

然后我们会得到一个小的被简化了很多的网络11,然后再做反向传播训练

这个方法只是按照随机的编码决定这些节点的去留,但这个技术是有效的,因为对于每一个训练样例你都在训练一个小的多的网络,这样或许能让你理解为什么你能正则化整个网络,因为被训练的是一个小的多的网络。

让我们看下如何实现随机失活算法:

我们介绍常用的一种—反向随机失活(inverted dropout) 我们将在l=3层上介绍这个算法:

一共三步:

1>设置一个向量d3 d3表示第三层的失活向量

Keep.prob是一个数值,是给定隐藏单元将被保留的概率值,比如Keep.prob=0.8 那么这个隐藏单元会有20%的几率被丢弃

2>.

a3是激活矩阵,a3和d3逐元素相乘,这样的作用是 对于d3中值为0的元素,每个元素中有20%的几率取值为0,通过点乘将a3中0值对应位置的元素一一清零,如果使用Python,技术上来说d3是一个值为True或False的布尔值数组,而不是1或者0

最后我们要放大a3:

3>.

a3/=keep.prob 实际上是除以keep.prob参数;原因是:方便起见假设层3有50个单元或者说有50个神经元,所以a3的维度是50xm 如果keep.prob等于0.8  那么将有50*0.2=10个神经元失活或者被清零

为了不减小z4的期望值,所以我们需要除以0.8,因为它能提供你所需要的大约20%的的校正值,这样a3的期望就不会被改变

以上三点就是所谓的反向随机失活技术,它的作用在于你可以将 keep.Prob设为任意值

7.Understanding Dropout

随机失活(dropout)这种从网络中随机敲除神经元的做法看起来有些疯狂

如果你觉得某一层比其他层更容易发生过拟合,你可以给这一层设置更低的存留率(缺点是会有更多的超参数,运行时会更费时)另一个选择是对一些层使用dropout(存留率相同)

注意:dropout是一种正则化技术,如果没有过拟合问题,不需要考虑使用dropout(不过计算机视觉领取非常依赖dropout)dropout的另一个缺点是让代价函数J变的不那么明确,因为每一次迭代,都有一些神经元随机失活,所以你去检验梯度下降算法表现的时候,你会很难确定代价函数是否已经定义的足够好

8.其他正则化技术



                                      (该方法缺点是没有正交化,不能同时解决优化和过拟合的问题)

#注意一个概念:正交化,即同一时间只考虑一个任务

9.Setting up youroptimization

1>归一化

对输入进行归一化包含2个步骤,第一步是将减去均值或说将均值归0(中间的图),第二步是将方差进行归一化(下图最右边的)

一个提示,如果你用这种方法对数据进行缩放,那么务必对测试集和训练集都使用同样的u和,具体来说就是不应该用不同的方式去归一化训练集和测试集

为什么要对输入进行归一化呢?

如果不做归一化,那么按照下图中右侧的代价函数,根据输入数据可能如下图

但若这是因为你的特征的尺度不一样,例如说x1的范围是1到1000,而x2的范围只有0到1,这回导致神经网络参数w1和w2的比率或者w1和w2的范围会有很大的不同

但使用归一化后:

归一化后会使代价函数J优化起来更容易也更快

所以只要对输入数据进行归一化,使均值均为0,方差均为1,就能保证所有的特征尺度都相近,这通常也能让帮助学习算法运行的更快

2>.梯度的消失和爆炸

意思是当你训练一个深度神经网络的时候,损失函数的导数(或者说是斜率)有时候变得非常大或者变得非常小甚至是呈指数级增长,这使训练变得很困难

举例如下:

在一个非常深的神经网络中,当权重W大于一个单位矩阵的时候,激活函数就会爆炸(呈现指数增长) 如果W比单位矩阵小一点点,而你有个很深的网络,激活函数就会指数级减小

3>.权重系数W的选择

举例如下,对于单个神经元,比如采用relu激活函数的话,初始化W的时候,乘以2/(当前层的输入) 的开方是很有效的

4>.近似计算梯度

如上图所示,计算结果会是3.0001(比单侧计算差值的误差要低),这和其导数值非常接近,所以利用这个取双侧差值的方法来近似导数,你会发现非常接近3,当把这个方法用于梯度检验和逆传播时,它运行起来很可能比用单侧差值要慢2倍

5>.Gradient Checking

梯度检查可以帮助找出反向传播代码中的错误,那么如何用梯度检查来调试代码呢?

你刚刚写的神经网络里有一些参数,从W1,B1一直到WL BL,要实现梯度检查算法,首先要把你的所有参数重新拼成一个巨大的参数向量,

同样:


现在的问题是是否是代价函数J的梯度或者说是斜率?

接下来就是如何编写梯度检查算法,梯度检查(Gradient Checking)通常写为(GradCheck)

实现梯度检查算法时,我们首先要写一个循环:

如上图所示,如果最后一行的Check算出的值约等于10的﹣7次方说明梯度求的很正确,说明算法是正确的

6>.关于梯度检查的一些注意事项:

(1)    首先不能在训练中使用梯度检查,而仅仅在调试时使用

(2)    如果一个算法没有通过梯度检测,你需要检查它的组成,检查每一个组成部分,尝试找出漏洞

(3)    当你在进行梯度检验时,如果你使用了正则化,别忘了你的正则化项

(4).梯度检验不能与随机失活(Dropout)一起使用,因为在每一次的迭代中随机失活将随机消除隐藏单元的不同子集,在使用随机失活进行梯度下降的过程中,并不存在一个容易计算的代价函数J。随机失活可以看作对于代价函数的优化,但这个代价函数的定义是在每一次迭代中对所有非常大的可消除节点集进行求和,所以这个代价函数是很难计算的,你只需对代价函数进行抽样,在那些使用随机失活的集合中,每次消除不同随机集合,所以很困难。

(5).在随机初始化的时候运行梯度检验(很少用);你对于梯度下降的使用是正确的同时,w和b在随机初始化的时候是很接近0的数,但随着梯度下降的进行,w和b有所增大,也许你的反向传播算法在w和b接近0的时候是正确的,但当w和b变大的时候算法精准度有所下降

猜你喜欢

转载自blog.csdn.net/zgx123666/article/details/79350730