这部份内容是我在看Andreg Ng深度学习视频,而后又阅读了一些文章整理后记录下来的html
视频链接:http://mooc.study.163.com/smartSpec/detail/1001319001.htmpython
在了解这些内容以前,先推荐看一下下面几篇博客,我仅仅只是对这些内容进行一下总结。算法
1.什么是高/低方差、高/低误差网络
2.验证集、误差与方差、学习曲线app
(1) 先来介绍一下,训练集,校验集,以及测试集函数
训练集:学习样本数据集,经过匹配一些参数来创建一个分类器。创建一种分类的方式,主要是用来训练模型的。工具
验证集:对学习出来的模型,调整分类器的参数,如在神经网络中选择隐藏单元数。验证集还用来肯定网络结构或者控制模型复杂程度的参数。学习
测试集:主要是测试训练好的模型的分辨能力(识别率等)。测试
小数据时代七三分或者六二二分是个不错的选择,在大数据时代各个数据集的比例可能须要变成 98%: 1%: 1%,甚至训练集的比例更大。 有些时候训练集和验证集、测试集的数据有所不一样时,好比训练集的图片高像素、高质量,而验证集和测试集则像素较低,那么有一条经验法则是确保验证集和测试集来自于同一分布;但因为深度学习须要大量的训练数据,为了获取更大规模的训练数据集,可能会进行网页抓取,代价是训练集数据与验证集和测试集数据有可能不是来自于同一分布。
还有一种状况,就算没有测试集也是能够的,测试集的目的是对最终所选定的神经网络系统作出无偏估计,若是不须要无偏估计也能够不设置测试集。
因此搭建训练验证集合测试集可以加速神经网络的集成,也能够更有效地衡量算法的误差和方差,从而帮助咱们更高效地选择合适的方法来优化你的算法。
(2) 接下来介绍一下什么是误差,什么是方差
误差:通常描述的是预测值(估计值)的指望与真实值之间的差距。误差越大,越偏离真实数据集。(对象是单个模型, 指望输出与真实标记的差异)
方差:描述的是预测值的变化范围,离散程度,也就是离其指望值的距离。方差越大,预测结果数据的分布越散。(若是对象是多个模型,表示多个模型差别程度。)
基于误差的偏差:所谓基于误差的偏差是咱们模型预期的预测与咱们将要预测的真实值之间的差值。误差是用来衡量咱们的模型的预测同真实值的差别。
基于方差的偏差:基于方差的偏差描述了一个模型对给定的数据进行预测的可变性。好比,当你屡次重复构建完整模型的进程时,方差是,在预测模型的不一样 关系间变化的多少。
通常来讲,误差、方差和模型的复杂度之间的关系以下图所示:
越复杂的模型误差越小,而方差越大。
咱们用一个参数少的,简单的模型进行预测,会获得低方差,高误差,一般会出现欠拟合。
而咱们用一个参数多的,复杂的模型进行预测,会获得高方差,低误差,一般出现过拟合。
实际中,咱们须要找到误差和方差都较小的点。从上图能够看出在误差和方差都较小的点处,total Error是最少的。
例子
让咱们来看一看咱们在什么状况下应该怎样选择:
针对训练神经网络过程当中误差过大(欠拟合),或者方差过大(过拟合)咱们能够采用哪些方法?
(1) 深度学习在现在大数据时代能够经过构建一个更大的网络即可在不影响方差的同时减小你的误差。
(2)采用更多的数据能够在不过多影响误差的同时减小方差。扩增数据代价比较高,并且有时没法扩增数据,但咱们能够经过水平翻转、随意翻转和裁剪图片来增长训练数据 。
以上两步实际要作的工做是训练网络,选择网络或者准备更多数据,如今咱们有工具能够作到仅仅减小误差或者仅仅减小方差,不对另外一方产生过多不良影响。
(3)正则化是一种很是实用的减小方差的方法,正则化会出现误差方差权衡问题,误差可能会略有增长,但若是网络足够大的话,增幅一般不会太大 。
这里主要讲解如下L2规范化技术。二次代价函数,以及交叉熵代价函数,柔性最大值正则化后的形式以下:
其中C0为原始代价函数。第二项加入的就是全部权重(每一个元素)的平方和,λ成为规范化参数,规范化能够当作一种寻找小的权重和最小原始代价函数之间的折中,λ越小,就越偏向于最小化原始代价函数,反之倾向于小的权重。
经常使用正则化方法来防止过拟合,所以须要思考参数的选择问题。
(4)利用弃权来下降过拟合。(主要应用在计算机视觉,其余领域应用较少)
假设左图存在过拟合,这就是 dropout 所要处理的,咱们复制这个神经网络, dropout 会遍历网络的每一层,并几率性地设置消除神经网络中的节点,假设每一个节点都以抛硬币的方式设置几率,每一个节点得以保留和消除的几率都是 0.5;设置完节点几率,咱们会消除一些节点,而后删掉从该节点进出的连线,最后获得一个节点更少、规模更小的网络,而后用bcakprop 方法进行训练,这是网络节点精简后的一个版本。对于其余样本,照旧以抛硬币的方式设置几率,保留一类节点集合,删除其余类型的节点集合,对于每个训练样本,都将采用一个精简的后的神经网络来训练它。也许你会认为这个方法有点怪,单纯遍历节点,编码也是随机,可它真的有效。
咱们怎么去理解弃权?
启发式的看,当咱们弃掉不一样的神经元集合时,有点像咱们在训练不一样的神经网络。因此,弃权过程就如同大量不一样的神经网络效果的平均那样
弃权如何实现?
对于l层,咱们先向量 向量dl,其维数和al.shape一致(al表示第l层激活函数输出列向量), dl表示 dropout 向量,而后看它是否小于某数,这个数叫作 keep_prob, 是一个具体的数,表示弃权的几率,咱们假设该值为它0.8,它表示保留某个隐藏单元的几率,它的做用就是生成随机矩阵。dl是一个矩阵,每一个样本和每一个隐藏单元其在 dl中的对应值为 1 的几率都是 0.8,其对应值为 0 的几率是 0.2.接下来要作的是从l层获取激活函数 al, al 含有须要计算的激活函数 al*=dl(元素相乘),它的做用就是过滤 dl 中全部等于 0 的元素,若是用python 实现的话, dl 是个布尔型数值, true 或者 false,而不是 0 或 1;乘法运算会把 true 或者 false 翻译为 1 和 0。最后咱们向外扩张 a3,用它除以 keep_prob 参数(why?假设第l层有 50 层神经元,在一维上 al 等于 50,咱们经过因式分解将它拆成 50Xm 维的,保留和删除它们的几率分别为 80%和 20%,这意味着最后被删除或归零的单元平均有 10 个, zˆ[l+1] = wˆ[l]*al+bˆ[l+1], 咱们预期是 al减小 20%,也就是说 al中有 20%的元素被归零,为了避免影响 zˆ[l+1]的指望值,咱们须要用 (wˆ[l+1]*al) / 0.8,它将会修正或弥补咱们所需的 20%,这样 al的指望不会变)。
dl = np.random.rand(al.shape[0],al.shape[1]) < keep_prob #dropout向量 al = np.multply(al,dl) #乘法运算会把 true 或者 false 翻译为 1 和 0。 过滤掉dl中元素为1的神经元
al = al/keep_prob
弃权有什么不稳定的因素?
对于咱们已经训练好的神经网络,咱们只需计算前向输出,因为弃权矩阵dl是随机的,给定一个输入,则网络的输出也会动态变化,有时候输出结果并不会太令咱们满意。
(5)利用提早中止来下降过分拟合
在运行梯度降低时,你能够绘制训练偏差图或者回执代价函数 J 的优化过程图,在训练集上用 0-1 记录分类偏差次数,能够看到它呈单调降低的趋势;由于在训练过程当中,咱们但愿训练偏差、代价函数 J 都在降低,经过 early stopping 不只能够看到上述这些图,还能够绘 制验证集偏差图,你会发现验证集偏差一般会先呈降低趋势,而后在某个节点处开始上升。early stoping 在神经网络中随机初始化w 值,它的值可能都是较小的值,随着迭代增大,而它是在中间点中止迭代过程,获得一个中等大小的 w;与L2 正则化类似,选择参数w范数较小的神经网络,但愿神经网络过分拟合不严重。
early stopping 的学术意思是提前中止训练神经网络,一旦校验数据集上分类准确率已经饱和,就中止训练。但也有一个缺点:不能独立处理如下两个状况,由于提前中止梯度降低,也就中止下降代价函数 J,因此代价函数可能不会比较小,这样作的话你没有采用不一样的方式来解决这个问题,你须要考虑的东西就变得更复杂了。
若是不用 early stopping,另外一种方法是 L2 正则化,训练神经网络的时间就可能很长,将致使参数搜索空间更容易分解,也更容易搜索, 但缺点是你必须尝试不少正则化参数 λ 的值, 也致使搜索大量 λ 值得计算代价过高。 early stopping 的优势是只运行一次梯度降低, 你能够找出 W 的较小值,中间值和较大值, 而无需尝试 L2 正则化超参数 λ 的不少值。
在训练神经网络中,咱们有哪些方法能够加速神经网络的训练速度?
归一化输入(normalized)
假设一个训练集有两个特征x1,x2,输入特征为 2 维, 归一化须要两个步骤: 1.零均值化 2.归一化方差; 咱们但愿不管是训练集和测试集都是经过相同 的 μ 和 σ^2定义的数据转换, 这两个是由训练集得出来的 。
1.首先计算每一个特征的平均值μ,针对每一个样本进行如下计算:xi = xi - μ。
2.针对新获得的样本计算方差方差σ2。而后在进行如下计算:xi = xi/σ。
3.获得的新的样本每个特征则服从标准正态分布μ(0,1).
为何要标准化输入特征 ?
咱们能够把左边的图当作没有归一化的代价函数曲线图,右边为通过归一化的代价曲线图。左图的话,你必须使用一个很是小的学习率,可能须要屡次迭代,直到找到最小值,但函数若是是右图的话,不管从哪里开始,梯度降低法都能更直接地找到最小值,你可使用 较大的步长,这使得函数 J 优化起来更简单快速。实际上 W 是个高维向量,所以二维绘制 W 并不能正确地表达清楚,直观理解能够是代价函数更圆一些,并且更容易优化,前提是特征在类似范围内,而不是从 1 到 1000, 0 到 1的范围,而是早-1 到 1 范围内或类似的方差。因此输入特征处于不一样范围时,那么归一化特征就很重要;若是特征处于类似范围内,归一化就不太须要了,固然也能够执行,一般使用归一化无论它可否提升训练和算法速度。
咱们可使用梯度检验来调试或检验 backprop 的实施是否正确。 假设网络有 以下参数,为了执行梯度检验,首先要把全部参数换成一个巨大的向量数据,你要作的就是把矩阵 W 转换成一个向量,把全部 W 矩阵转化为向量后作链接运算,获得一个巨型向量 θ; 代价函数 J 是全部 W 和 b 的函数,也就是获得了一个 θ 的代价函数 J。求导各个 w,b, 再转换成一个大向量 dθ。
为了实施梯度检验, 你要作的是循环执行, 从而对每一个 i, 也就是每一个 θ 组成元素计算dθ [i](approx)的值,运用双边偏差求得的值应该逼近 dθ[i],目的就是检验 dθ[i](approx)和 dθ[i] 是否相等。 先计算这两个向量的距离, 而后用向量长度进归一化, ε 可能为 10 的-7 次方, 使用这个取值范围内的 ε, 你若是发现方程式获得的值为 10 的-7 次方或者更小, 这就很好, 这意味着导数逼近颇有多是正确的,它的值很是小;若是在 10 的-5 方范围内,要当心,也许这个值没问题,但须要再次检查这个向量的全部项,确保没有一项偏差过大,若是有一项偏差很是大,可能就存在 BUG。
如何应用?
咱们在调试程序的时候能够用以下公式计算:
dθ [i](approx)= (J(θ [1],θ [2],...,θ [i]+ε,...θ [n]) - J(θ [1],θ [2],...,θ [i]-ε,...θ [n])) / ||2ε||
而后与咱们公式推导计算的dθ比较,看结果是否接近。