## 吴恩达深度学习——改善深层神经网络——第一周深度学习实用层面
一、训练/测试/开发集
这里我直接简单介绍一下三者的区别
训练集(train set)——顾名思义,当然来做训练模型用的,主要用来获取参数, 如W(权重矩阵)和b等
开发集(dev set)——这个主要是用来调整超参数的,比如α(学习率),lambda(振则化参数)等超参数
测试集(test set)——测试集主要是用来评价模型的优劣,泛化能力。
在不同大小的数据集上,我们取的训练集(train),开发集(dev),测试集(test)的比例不一样,如在我们的训练数据较小,如1000时,我们的分别的比例可以是6:2:2,,而当我们的数据集较大时,如100000时,我们的比例可以是98:1:1,所以具体三个测试集的比例要怎么确定,具体还要看我们的数据集的大小,不唯一,或者说,哪种比例使我们的模型泛化能力更好,那就用那种比例。
二、偏差与方差
他这里是通过训练集和开发集的正确率来反映方差和偏差的情况。
注意这里没有用正确率来表示,而是用错误率。
总结一下,高方差的表现是训练集的正确率很高,但是开发集正确率并不高,即使是相差百分之几**,高偏差**表现在对训练集和开发集的的正确率都不高,并且两者正确率相差不大,高方差和高偏差表现在训练集和开发集正确率都不高,但是训练集和开发集的正确率相差较大(这是和高偏差的区别)。低偏差和低方差,训练集和开发集的正确率都很高,一般都在99%左右。
三、机器学习基础
这一小节,其实主要就是介绍解决高方差和低方差的一些思路。
这里总结一下这张图想表达的东西:
当出现高偏差时,我们应该去评价一下训练集的的数据性能,当我们的偏差过大时,我们应该考虑更好的神经网络,比如更深的神经网络。当我们的偏差降到可接受的大小的时候,我们利用开发集(dev) 来评价 方差,如果方差过高我们尝试增加数据,或者利用正则化,当然如果幸运的话,当天的神经网路刚好能让偏差和方差较低。
四、正则化
使用正则化后改变cost function(代价函数)的计算公式和对dW的求导公式,间接影响更新W的计算公式。
上面是正则化前和正则化后cost function的改变,其实只是在之前的基础上把权重矩阵的里的所有参数的平方都加起来而已。这样的正则化方式叫做L2正则化。
下面是dW的变化
这是原来的dW公式
变化后的dW公式如下:
变化后的W公式如下:
可以看出当我们的λ增大时我们的W会减少更多。当我们的λ到达适当的数值时我们的W会靠近零,相当于等于零。以此来实现减少过拟合的程度。
五、为什么正则化可以减少过拟合
首先从左至右我们可以看到越来越扭曲,当然第二种情况是较好的。
直接影响我们过拟合的因素肯定就是我们每轮的更新参数过程。我们先来看一下其中一种情况:
当我们的λ为一个适合的值时,使得每一层只剩一个参数是有效的,其他的都相当于为零,实际上可能是一个非常接近零的数,换句话来说,就是从第一层(隐藏层第一层)到第二层,第二层到第三层,第三层到第三层,我们的计算过程都只是相当与y=ax+b,就相当是一个简单的逻辑回归,最后呈现出来的就是类似一条直线的决策边界。
证明
这幅图我们可以看出当我们的θ数越多我们的曲线就有可能越曲,即出现过拟合的可能性越大。我们可以这么理解,神经网络中的每个神经元就是我们上图中的一个θ,结合上面的神经网络图大部分的神经元失效,即我们的大部分θ接近于0,当我们的θ减少时是不是离我们中间这幅图的决策边界更近呢。换句话来说,假如我们现在出现了过拟合的情况我们,我们通过L2正则化使得部分θ为零或接近零,使θ失效后更靠近第二幅图的情况。
六、Dropout正则化
我通过两个动态图来解释Dropout正则化的过程,简单来说就是每一层中都会有一些神经元失效,即该神经元对在该次该轮遍历中权重全为零。
下面是两个很短的视频可以很好的解释Dropout的过程(下载0C币):
链接: https://download.youkuaiyun.com/download/weixin_46089779/13071087.
链接https://download.youkuaiyun.com/download/weixin_46089779/13071073.
其实不难看出,L2正则化与Dropout(随机失活)的区别,L2正则化是对权重矩阵中的某个W为0或接近零,而Dropout是直接使某个神经元失活。它们之间说更好用,只能说放进我们的神经网络试一下对比一下谁的效果好吧。答案不是绝对的。
七、理解Dropout
我们首先理解一下Dropout是如何让神经网络减少过拟合的
我们一起结合以下两张图来理解:
在前面我们已经说过决策函数中的参数越多导致曲线越曲从而导致过拟合,结合第二张图,我们可以将神经网络中的三层神经元当作第一张图中的θ,在我么进行训练时,我们可以随机让某些神经元失效,换句话说就是让第一张图中的某些θ失效从而达到靠近第一张图中的中间的图的效果,即减少过拟合。
其实换个说法,随机让某些神经元失效的过程就是让神经网络不要学的太像。
——————————————————————————
下面是实现Dropout的一些操作。
假设神经网络的第一层有四个神经元,有五个样本,那么我们这里就有一个四行五列的矩阵A1
可以发现我们的矩阵都是在0到1之间的。
我们对该矩阵进行进一步的操作,这里的代码不难理解,小于keep_prob的数就为True,大于则为False,所以最后D1矩阵是由bool类型组成的。
最后将我们该层的A1矩阵与D1相乘则为第一层第一次Dropout后的新的A1矩阵,然后利用这个新的A1矩阵去除以keep_prob作为下一层的输入,后面第二层,第三层等需要Dropout的神经元与此操作相同。
注意:对输出的A1矩阵除以keep_prob,即A1 /= keep_prob,这一步是最关键的。将A1除以keep_prob的目的是保证A1的期望值(均值)不变,从而保证第一层的输出不变
八、其他正则化方法
吴恩达这里非常浅显的提到了其他两种可以减少过拟合的方法
第一种是通过增加数据去减少,但是我们重新去寻找新的数据的代价比较大,我们可以通过对原来的图片进行处理后作为我们的新数据。
第二种就是early stopping。
early stopping 的缺点就是提早停止了梯度下降,也就是提早停止优化代价函数,相当于用一种方法去解决两个问题,这时我们考虑的东西更加复杂。
九、正则化输入
其实就是标准化
具体标准化后会有什么不同,
从这一张图片来看,我们的数据被放在了坐标轴的中心,各个点之间的距离都被拉开了,原本拥挤的数据集在标准化后变分散了。
经过处理的数据符合标准正态分布,即均值为0,标准差为1,其转化函数为:x* = (x - μ ) / σ
其中μ为所有样本数据的均值,σ为所有样本数据的标准差。
需要注意的是,我们可以用同一个μ和σ来标准化测试集,而不是在测试集上重新一个新的μ和σ来标准化测试集。
我们归一化后作用:
这里最主要的一个作用就是加快了梯度下降的速度。
当然还有一些其他的作用就是使得预处理的数据被限定在一定的范围内(比如[0,1]或者[-1,1]),从而消除奇异样本数据导致的不良影响…。
十、梯度消失和梯度爆炸
梯度爆炸消失激活函数侧面解释
1、吴恩达课程中是以前向传播来观察梯度爆炸和消失。
以上图的神经网络为例,其实我们可以将该神经网络想象成一个很深的网络,但是为了方便期起见,就先以上面的神经网络为例。
其中的计算过程如下,要知道我们每一层神经元的W都是2x2的矩阵,当各层W之间相互相乘自然不会出现什么问题,所以不用考虑这方面的问题。
需要注意的是我们这里的激活函数是线性激活函数即g(z) = z。
吴恩达这里只是讨论了激活函数的值会呈指数级增长。
当我们初始化我们的权重矩阵W是每一层都一样,都比1稍大一点。
像这样:
如果我们按上面的式子计算随后的出来的W矩阵会是这样:
我们用的出来的2x2的矩阵来与x相乘,最后的出来的yhat必然很大,因为1.5按指数增长,我们都知道指数函数为爆炸函数,所以说激活函数的值会很大。
同理假如我们将以上的1.5换成一个比1稍微小一点的数,比如0.9,我们最后也会因为爆炸函数的作用从而得出一个非常小的激活函数的值。
吴恩达这里并没有具体以梯度下降为例子来解释梯度下降的问题,而是通过激活函数的爆炸式增长和减小来侧面解释梯段消失和梯度爆炸出现的原因。
梯度爆炸和消失,梯度下降式子解释
2、下面是结合梯度下降的式子来理解梯度爆炸和梯度消失:
首先我们回顾我们每一轮更新参数的过程:
很明显新的W是用旧的W减去一个数,即αdW,这里的α是不变的,变的是dW,而我们这里提到的梯度爆炸和梯度消失就是dW因为随层数呈指数增加或减小进而导致dW非常大(梯度爆炸)或非常小,接近0(梯度消失)。
下面我们给予证明:
下面是一个三隐藏层的网络:
有些人可能不知道为什么会得出最后这个式子,我这里做一个简单证明:
我们要知道f3*W3代表的是第四层的输入,那么就有
我们现结合两张图:
现在我们只看这一项(双划线):
根据这个式子我们知道f(x)求导的次方数与神经网络的层数相关,并且会随着层数的增加次方数会增加,即上图中的2变成一个更大的数,就是一个指数函数,我们都知道指数函数是爆炸函数,当我们的f(x)求导后的数如果大于1,经过指数增长后,会非常大,即dW非常大,,反之如果小于1,经过指数增长后,会非常小,即dW非常小或接近零。这两种情况就是对应着我们的梯度爆炸和梯度消失情况。
十一、神经网络权重初始化
先上课程幻灯片:
他这里主要是以梯度爆炸消失激活函数侧面解释为基础来讲的。
以上面的这个逻辑回归为例子,实际上我们的输入层为n,Z会随着输入层的特征数而增加,当我们的输入层的特证书很大时,我们的Z会很大,这时为了控制Z尽量小些,我们能做的就是让W尽量小些,其实就是让W不要离1太远。
而让W尽量小些的方法是除以sqrt(1/前一层的神经元数),但是如果我们的激活函数为Relu激活函数时,我们应该是让W除以sqrt(2/前一层的神经元数),如果是tanh的话,上图也有提到。
这样做的目的就是减轻梯度消失或者梯度爆炸的情况,让梯度不要爆炸的这么快或者或者消失的这么块。
十二、梯度的数值逼近
他这里主要想表达的是这个式子:
证明也不难,只要学过高数的同学对这个都不陌生。
但这里吴恩达也给予了证明:
当我们ε趋近于零时应该是等于在θ出的导数的:
我们会利用这个式子来做梯度检验。
十三、梯度检验
为什么要进行梯度检验
神经网络算法使用反向传播计算目标函数关于每个参数的梯度,可以看做解析梯度。由于计算过程中涉及到的参数很多,反向传播计算的梯度很容易出现误差,导致最后迭代得到效果很差的参数值。
为了确认代码中反向传播计算的梯度是否正确,可以采用梯度检验(gradient check)的方法。通过计算数值梯度,得到梯度的近似值,然后和反向传播得到的梯度进行比较,若两者相差很小的话则证明反向传播的代码是正确无误的。
进行梯度检验
假如我们神经网络中有n个θ我们用J对每个θ进行梯度的数值逼近,而且对每一个θ进行加减ε时其他的θ要保持原始值。
最后进行以下计算:
具体计算的时逼近数值矩阵dθapprox与dθ相减后的L2范数再除以(dθapprox矩阵的L2范数+dθ矩阵的L2范数)
L2范数的计算公式:
如果最后的值为10的-7次方则为较好的结果,如果为10的-3次方或以上,则我们的神经网络应该有问题。
十四、关于梯度检验实现的注记
1、不要在训练的时候使用,只在debug的时候使用。
2、如果算法梯度检验失败了,尝试去找到bug。
3、记得正则化。
4、不要使用在Dropout正则化的神经网络上。
5、在随机初始化上运行,进行一些训练后再尝试。