提升深度神经网络:超参数调节,正则化,优化
之前已经学习了如何构建神经网络,本章将继续学习如何有效运行神经网络,内容涉及超参数调优,如何构建数据以及如何确保优化算法快速运行,从而使学习算法在合理时间内完成自我学习。第一周首先说说神经网络机器学习中的问题,然后是正则化,还会学习一些确保神经网络正确运行的技巧。
1 训练-验证-测试集
在配置训练集验证集和测试集的过程中做出正确决策会在很大程度上帮助大家创建高效的神经网络。训练神经网络时我们需要做出许多决策,例如:神经网络分多少层,每层含有多少个隐藏单元,学习速率是多少,各层采用哪些激活函数。创建新应用的过程中我们不可能一开始就准确预测出这些信息和其他超参数,实际上应用机器学习是一个高度迭代的过程。通常项目开始时我们有一个初步想法比如构建一个含有特定层数隐藏单元数量的网络,然后编码运行,得到结果,然后根据结果重新完善自己的想法改变策略。
就像之前说过的构建一个神经网络需要不断的实践,即使是经验丰富的深度学习专家也不太可能一开始就预设出最匹配的超参数,所以说应用深度学习是一个典型的迭代过程。
因此循环该过程的效率是决定项目进展速度的一个关键因素,而创建高质量的训练 验证 测试集也有助于提高循环效率。
我们对训练集执行训练算法,通过验证集(开发集)选择最好的模型,应该充分验证我们决定了最终模型然后就可以在测试集上进行评估了,为了无偏评估算法的运行状况。
在机器学习发展的小数据量时代常见的做法是将所有数据7:3分(没有验证集)或者6:2:2(训练集:验证集:测试集)这是机器学习领域普遍认可的最好的实践方法,但是在大数据时代我们的数据量可能是百万级别,那么验证集和测试集的比列会趋于变得更小。因为验证集的目的就是验证不同的算法,验证那种算法能有效,因此验证集需要足够大才能评估比如2个或者10个不同的算法并迅速判断哪种算法更有效,我们可能不需要拿出20%的数据作为验证集,比如我们有一百万条数据,验证集1万条数据就足够了,同样测试集的主要目的是正确评估分类器的性能,1万条也足够了。所以训练集验证集和测试集的比列是98:1:1对于数据量过百万的应用训练集数据可以占到99.5%验证集和测试集各占0.25%(或者验证集0.4%测试集占0.1%)
现代深度学习的另一个趋势是越来越多的人在训练集和测试集分布不匹配的情况下进行训练,假设你要构建一个用户可以上传大量图片的应用程序,目的是找出并呈现所有猫咪图片。训练集可能是从网络上下载的猫咪图片,而验证集和测试集可能是用户在这个应用上上传的猫咪图片
结果许多网页上的猫咪照片图片分辨率很高很专业,而用户上传的照片可能是手机随手拍摄的,像素低 比较模糊,这两类数据有所不同。针对这种情况根据经验建议大家要确保验证集(dev)和测试集(test)的数据来自同一分布,因为你要用验证集来评估不同的模型,尽可能的优化性能如果验证集和测试集来自同一个分布将很好。但是由于深度学习算法需要大量的训练数据为了获得更大规模的训练数据集,我们可以采用当前流行的各种创意策略例如网页抓取,代价就是训练集数据和验证测试集数据有可能不是来自同一分布,但只要遵循这个经验法则------验证集(dev)和测试集(test)的数据来自同一分布。你会发现机器学习算法会变得更快。
最后其实没有测试集也不要紧,测试集的目的是对最终所选定的神经网络做出无偏估计,如果不需要无偏估计也可以不设置测试集,所以只要有验证集没有测试集,我们要做的就是在训练集上训练尝试不同的模型框架在验证集上进行评估然后迭代选出适用的模型因为验证集中已经覆盖测试集数据其不再提供无偏估计,当然如果你不需要无偏估计 那就再好不过了。在机器学习中如果只有一个训练集和验证集而没有独立的测试集,遇到这种情况还被人们称为训练集/测试集(验证集被称为测试集)不过在实际使用过程中人们只是把测试集当作验证集来用并没有完全实现该术语的功能。
有一些团队喜欢这样的说法(训练集/测试集),尽管训练集/验证集的说法可能更为准确。事实上如果你不需要无偏估计算法性能那么这样是ok的。
所以搭建训练验证集和测试集能够加速网络,也可以更有效衡量算法的偏差和方差从而帮助我们 更加高效的选择合适方法优化算法。
2 偏差方差
几乎所有机器学习从业人员都期望深度理解偏差和方差,这两个概念易学难精,即使你自认为已经理解了偏差和方差的基本概念却总有一些意想不到的新东西出现。关于深度学习的误差问题另一个趋势是对偏差和方差的权衡研究甚浅,大家可能听说过这个概念但深度学习的误差很少权衡二者,我们总是分别考虑偏差和方差。
左侧欠拟合,中间刚好,右侧过拟合
对于上面这种只有x1和x2两个特征的二维数据集中,我们可以绘制数据将偏差和方差可视化,在多维数据空间中绘制数据和可视化边界无法实现,但我们可以通过几个指标来研究偏差和方差
猫咪分类,假设人眼错误率接近0%(基本误差或叫最优误差)
以上分析的前提是假设基本误差很小,训练集和验证集来自同一分布,如果没有这些假设前提分析过程会更加复杂
高偏差和高方差
我们稍微改变一下线性分类器让它过度拟合部分数据,这样就具有高偏差和高方差,偏差高是因为它几乎是一条线性分类器并未拟合数据(有一条二次曲线可以很好的拟合数据)却过渡拟合了中间的两个样本。这种情况看起来可能不自然,从两个维度上看都不太自然但是对于高维数据有些数据区域偏差高有些数据区域方差高。所以在高维数据中采用这种分类器看起来就不会这么牵强了。
总结一下:介绍了如何通过分析训练集和验证集产生的误差来判断算法是否具有高偏差或高方差,是否两个都高或者两个值都不高。根据算法偏差和方差的具体情况决定你接下来要做的工作。
3 机器学习基础
如果高偏差,那么就需要更大的网络,更长的训练时间或者是其他网络,如果是高方差可能需要更多的数据,正则话或更合适的神经网络框架。直到找到一个低方差低偏差的框架。
有两点需要主要:1 高偏差和高方差是两种不同的情况,我们后续要尝试的方法也可能完全不同 。2 在机器学习的初期阶段关于所谓的偏差方差权衡的探讨屡见不鲜,原因是我们能尝试的方法有很多,增加偏差减少方差或者减少偏差增加方差,但是在深度学习的早期阶段我们没有太多工具可以做到只减少偏差或方差却不影响另外一方,但是在当前的深度学习和大数据时代只要持续训练一个更大的网络只要准备了更多的数据那么也并非只有这两种情况。我们假定是这样 那么得到一个更大的网络减小偏差而不损害方差,而采用更多的数据通常可以在不过多影响偏差的同时减少方差。
这两步的实际要做的工作就是训练网络选择网络或者准备更多的数据,现在我们有工具可以做到在减少偏差或方差的同时不对另一方产生过多的不良影响,我觉得这就是深度学习对监督式学习大有裨益的一个重要原因,也是我们不用过度平衡偏差和方差的一个重要原因,但有时我们有很多选择减少偏差或方差而不增加另一方,最终我们会得到一个非常规范化的网络,后面会将正则化,训练一个更大的网络几乎没有任何负面影响,而训练一个大型神经网络的主要代价也只 是计算时间
4 正则化
当你觉得神经网络过度拟合方差过高时最先想到的就是正则化,还有就是增加数据,但是你可能无法即使准备足够多的数据,或者获取更多数据的代价很大,但正则化通常有助于避免过拟合,以logistic回归为例
为什么只正则化参数w而不加上b呢
你可以这样做,但通常省略b,因为w通常是一个高维参数矢量(向量)已经可以表达高方差问题,w可能还有很大参数而b只是单个数字,所以w几乎覆盖所有参数,如果加了b其实也没什么太大影响,因为b只能众多参数中的一个,如果你想加上完全没有问题。
上面是L2正则化下面看看L1正则化
如果使用L1正则化W最终会是稀疏的(W向量中有很多0)有人说这样有助于压缩模型,因为集合中参数均为零,存储模型所占用的内存更少,事实上并没有降低多少存储内存,所以这并不是L1正则化的目的至少不是为了压缩模型,人们更倾向与L2正则化。
正则化参数 λ \lambda λ需要通过验证集不断调整。这是在logistic回归函数中的正则化过程,那么如何在神经网络中实现正则化呢
L2正则化也被称为“权重衰减”,因为权重指标乘了一个小于1的系数
5 为什么正则化可以减少过拟合
一个直观的解释就是如果 λ \lambda λ很大,那么权重矩阵W就接近于0,就是把很多隐藏单元的权值设为接近0,于是就消除了这些隐藏单元的影响
当 λ \lambda λ很大,假如激活函数是tanh
那么每层都几乎是线性函数,那么最终的决策边界也是线性的,因此不适用于非常复杂的决策,以及过度拟合数据集的非线性决策边界。
如果使用梯度下降函数,在调试梯度下降时不要忘记代价函数后加上正则化项
在深度学习中还有另外一种方法用到了正则化就是dropout正则化
6 dropout正则化
在一个网络中假设每个节点保留的概率为0.5
设置完概率删除掉一些节点
具体是怎么做的呢
除以keep-prob是为了保证a3的期望不变。
在测试阶段我们是不使用dropout,我们不期望输出结果是随机的,如果测试阶段应用dropout预测会受到干扰。理论上你多次运行测试数据,每一次不同的隐藏单元被随机归零,最终平均的结果和不做dropout的及其相似 但是这样计算效率低
7 理解dropout
dropout随机删除神经网络中的神经单元,使用一个较小神经网络和使用正则化的效果类似。我们从单个神经元入手
经过dropout有时候会消除上图两个神经单元,有时会是其他,因此
这个神经元它不能依赖任何特征,因为特征都可能被随机消除,因此不能把所有赌注放在一个节点上,不愿给任何一个输入加上太大的权重,因为它可能被删除,因此该单元通过这种方式积极传播开并为四个输入增加一点权重,通过传播所有权重,dropout将产生收缩权重平方范数的效果,和之前讲的L2正则类似,实施dropout的结果是它会压缩权重。
此外,每一层的keep-prob可以设置为不同的参数
w [ 2 ] w^{[2]} w[2]是一个7×7的参数矩阵,因此容易过拟合可以keep-prob设置的小一点,而其他层参数较少就可以设置的大一些。
dropout的一大缺点是代价函数 J 不再被明确定义,每次迭代都会随机移除一些节点,也就失去了调试工具。有一种办法是先关闭dropout运行代码确定J函数单调递减,然后再打开dropout函数
8 其他正则化方法
还可以通过数据扩增来达到正则化的作用,如果你正在训练猫咪分类器,想要通过数据扩增来达到正则化效果,那么你可以对训练图片进行水平翻转,对称,旋转裁剪等方法,这样就避免了获取额外数据的花费,这样的效果虽然不如全新的独立的猫咪图片,但我们这样做几乎没有额外的花费;对于光学字符识别,我们可以随意旋转或扭曲数字来扩增数据
还有一种方法可以起到正则化作用,early stopping
我们在训练数据的时候,cost function J 和 训练误差都在下降,但test error的趋势会是先下降后上升,
因此在test error开始上升的时候就停止训练了。
它是怎么发挥作用的,当你还未在神经网络上运行太多迭代过程时,w初始化的很小,在迭代和训练的过程中w越来越大,到最后w可能很大了,所以早停要做的就是在中间点停止迭代,得到一个大小中等的w 。
但是早停有一个缺点,机器学习过程包括几个步骤:其中一步是选择一个算法来优化代价函数 J (如梯度下降或Momentum,RMSprop,Adam)但是优化函数后我们不希望过拟合,有一些工具可以解决过拟合(正则化,扩增数据)在机器学习超参数越来越多选出可行的算法也越来越复杂
早停的缺点就是你没有采用不同的方法来解决这两个问题,而是用一种方法同时解决两个问题,这样做的结果是要考虑的东西变得更加复杂
9 归一化输入
训练神经网络,其中一种加速训练的方法就是归一化输入,假设有一个训练集是二维的,归一化需要两个步骤
第一是零均值化
第二步是归一化方差,目前特征x1的方差比x2的方差要大很多
这样x1和x2的方差都为1了(标准正态分布)。提示:测试集要使用和训练集一样的u和 σ \sigma σ
为什么要使用归一化?
回想一下cost function,
如果特征的取值范围不同,x1 :1…1000 ; x2: 0…1 那么代价函数是一个非常细长狭窄的代价函数,如果你在左图这样的代价函数上运行梯度下降,你必须使用一个非常小的学习率,因为如果在左下图蓝点位置开始梯度下降可能需要多次迭代,而右边的图可以使用更大的步长,学习的更快。
如果你的数据特征范围取值相近,比如0-1,1-2 ,那么也可以不进行归一化
补充:均值为0是为了让数据中心化,让各个维度的特征都平衡,标准差为1是把原来大小范围分布不通的数据缩放成统一量纲
10 梯度消失与梯度爆炸
为了简便假设神经网络每个隐藏层只有两个隐藏单元,激活函数选择线性激活函数
那么 y ^ \hat{y} y^
假设每一层的参数矩阵w都相同
那么对于一个很深的网络y的值将爆炸性增长,是呈指数级增长的。相反的如果权重是0.5
假设 x 1 和 x 2 x_1和x_2 x1和x2 都1,那么第一层的激活函数就是1/2,
所以当权重参数>1时,深度神经网络的激活函数将爆炸式增长,如果w比1略小在深度神经网络将以指数级递减。
虽然只论述了L对激活函数的指数级递减或递增,它也适用于与层数L相关的导数或者梯度函数也是呈指数增长或递减。这就导致梯度下降算法的步长非常小,梯度下降算法要花费很长的时间学习。可以在如何选择初始化权重问题上减轻这个问题。
11 神经网络的权重初始化
假设输入有四个特征,z=w1x+w2x…wnx,n越大,w就越小,因为你想要z的值较小
经过尝试你发现,尤其是使用relu激活函数,它取决于你对随机变量的熟悉程度,randn是高斯随机变量,然后乘以它的平方根,也就是引用方差2/n ,对于每一层来说就是 2 / n [ l − 1 ] 2/n^{[l-1]} 2/n[l−1]。如果激活函数的输入特征被零均值,标准方差,方差是1,z也会调整到相似范围,这就降低了梯度消失和爆炸问题,因为给权重参数设置了合适的值,既不能比1大很多也不能比1小很多。
对于其他函数,比如tanh,研究证明以下效果较好
12 梯度数值逼近
在实行反向传播时有一个测试叫梯度检验,它的作用是确保backprop正确实施。在此之前首先看看如何对计算梯度做数值逼近
当 ε \varepsilon ε=0.01,使用双边误差,逼近误差为0.001。使用双边误差可以判断是否正确实现了对函数f的偏导,我们也可以用这种方法来检验反向传播是否得以正确实施,如果不正确可能有bug需要修复
13 梯度检验
把所有的参数转化成一个巨大的向量数据,把所有的W矩阵转换成向量后,做连接得到一个巨型向量
你要做的就是检查dΘ和 d Θ a p p r o x dΘ_{approx} dΘapprox是否真的彼此接近
14 关于梯度检验实现的注记
2.1 Mini-batch梯度下降法
本周将学习优化算法 能让你的神经网络运行的更快。机器学习的应用是一个高度依赖经验的过程,伴随着大量的迭代过程,你需要训练诸多的模型才能找到合适的那一个,所以优化算法可以帮助你快速的训练模型。
之前需要运行全部的数据集(m=5000000)才能进行一次参数更新,如果把数据集分成更加小的部分算法会运行的更快。比如训练集500万个样本,每个mini batch=1000样本
对每个mini-batch执行前向传播和反向传播
mini-batch遍历一次训练集参数更新了5000次,而batch遍历一次训练集只更新了一次参数。
2.2 理解Mini-batch梯度下降法
用batch方法训练,每次迭代cost function都会下降,如果cost function在某次迭代中增加了 那肯定出了问题,而使用mini-batch,如果你做出成本函数在整个过程中的图,则并不是每次迭代都是下降的
因为每个mini-batch都是不同的数据集,噪声不同。你需要决定的变量之一是mini-batch的大小
当mini-batch=1时,就叫随机梯度下降
batch梯度下降从某处开始,相对噪声低些,幅度也大一些。相反在随机梯度下降法中,每次迭代只对一个样本,大部分情况下朝着全局最小值靠近,有时候会远离最小值。随机梯度下降永远不会收敛而是会一直在最小值附近波动,但它并不会到达最小值并停留在此
使用batch(mini-batch=m)如果数据量过大,一次迭代就需要花费很长时间,mini-batch=1,就失去了向量化带来的加速
2.3 指数加权平均
展示几个优化算法它们比梯度下降法快,要理解这些算法你需要用到指数加权平均,在统计中也叫指数加权移动平均
如此计算用红线画出v的图像,你得到了移动平均值(局部平均值)。
当 β \beta β=0.98,你多平均了几天的温度,所以曲线更加平滑,波动更小,缺点是曲线进一步右移,因为平均的温度值更多,要平均更多的值,指数加权平均公式在温度变化时适应地更加缓慢一些,所以会出现一定延迟
2.4 理解指数加权平均
这些所有的系数加起来为1或逼近1。你也许会问到底需要平均多少天的温度,实际上 0.9的10次方约等于0.35约等于1/e
大体上
这里 ε \varepsilon ε=0.1,换句话说十天权重衰减到不到当日的1/3,我们可以认为只关注前十天的温度
在代码中,可以只命名一个变量v即可,然后不断覆盖
https://zhuanlan.zhihu.com/p/29895933
2.5 指数加权平均的偏差修正
β \beta β=0.98,因为v0=0,v1和v2 都是一个很小的值,所以前两天的值预测的非常不好
因此我们让
v
t
1
−
β
t
\frac{v_t} {1-\beta^t}
1−βtvt
当t足够大时, β t \beta^t βt约等于0,1- β t \beta^t βt趋于1,所以偏差修正对于后期指数加权平均没有影响
2.6 动量梯度下降
有一种算法叫Momentum梯度下降,快于标准的梯度下降法。标准的梯度下降法的更新过程如下
你只能使用一个较小的学习率,如果你使用一个较大的学习率结果可能会偏离函数的范围。另一个看待问题的角度是,在纵轴上你希望学习慢一点,因为你不想要这些摆动,但是在横轴上你希望加快学习。
所以使用Momentum梯度下降,你要做的是
Momentum梯度下降不同于标准的梯度下降法每一步都独立于之前的步骤
β \beta β一般取0.9,关于偏差修正,实际上人们并不这样做,因为十次迭代后你的移动平均已经过了初始阶段,不再是一个具有偏差的预测
2.7 RMSprop
假设横轴代表w,纵轴代表b,可能有w1,w2或者其他参数,为了便于理解被称为w和b
我们希望在横轴方向或者例子中的w方向我们希望学习速率快,而在垂直方向也就是例子中的b方向我们希望减缓纵轴上的摆动所以有了 S d w 和 S d b S_{dw} 和S_{db} Sdw和Sdb,
采用RMSprop后的图像如绿色曲线,你可以用一个更大的学习率。dw实际可能是一个很大的维度,所以直观就是去掉了那些摆动的方向,这就是RMSprop全称是均方根。
为了防止分母除零,会加一个很小的数
是多少都没问题,10-8是个不错的选择,这只是保证数值能稳定一些。
Momentum和RMSprop都可以消除梯度下降中的摆动,并允许你使用一个更大的学习率,从而加快你算法的学习速度
2.8 Adam优化算法
深度学习的历史上提出优化算法并很好的解决了一些问题,但随后这些算法被指出并不能一般化, 并不适用于多种神经网络,RMSprop和Adam算法是少有的适用于不同的深度学习结构的算法。
其中一些超参数的设置
Adam:Adaptive Moment Estimation
2.9 学习率衰减
加快学习算法的一个办法就是随时间慢慢减少学习率,我们将之称为学习率衰减。我们来看看如何做到
假设你使用mini-batch梯度下降,mini-batch不大,大概64或者128个样本在迭代过程中会有噪音,下降朝向这里的最小值但是不会精准地收敛,所以你地算法最后在附近摆动,并不会真正地收敛因为你用的 α \alpha α是固定值,不同的mini-batch中有噪音。但是要慢慢减少学习率的话,最初学习率还是很大的,你的学习还是比较快的,随着学习率减小,你的步伐也会慢慢变小所以最后你的曲线会在最小值附近的一小块区域里摆动,而不是在训练过程中
α \alpha α设定为
这里的衰减率(decay rate)是另一个你需要调节的超参数。举个例子
除了这个学习率递减公式,还有其他的
学习率呈指数下降,还有一些其他的
2.10 局部最优问题
在深度学习早期人们总是担心优化算法会困在极差的局部最优,不过随着深度学习理论不断发展,我们对局部最优的理解也发生了改变。我向你展示一下现在我们怎么看待局部最优以及深度学习中的优化问题。
在高维空间你更可能碰见鞍点(右图)而不是左边的这种多个局部最优的情况
我们对低纬度空间的大部分直觉 ,比如你可以画出左边的图,并不能应用到高纬度空间。
如果局部最优不是问题,那么问题是什么
结果是平稳段会减缓学习,
第二个问题平稳段会减缓学习,这是Momentum,RMSprop和Adam这样的算法能够加速学习的地方
输入:零均值1方差
3.1 调试处理
你已经了解到神经网络的改变会涉及到很多不同的超参数设置,对于超参数而言怎么找到一套好的设定
从学习速率 α \alpha α 到Momentum的参数 β \beta β 。如果使用Momentum或Adam优化算法的参数, β 1 , β 2 \beta_1,\beta_2 β1,β2 和 ϵ \epsilon ϵ ,也许你还得选择层数,也许你还得选择不同层中隐藏单元的数量,也许你还想使用学习率衰减。所以,你使用的不是单一的学习率 α \alpha α 。接着,当然你可能还需要选择mini-batch的大小。
这些超参数重要程度:红色>橙色>紫色(这不是严格的标准,不同的研究者可能会有不同的观点)
假设有两个超参数
左侧就是机器学习里面的网格搜索,而右边是随机选取超参数点,同样是25组超参数,右边明显比左边的要好
之所以这么做是因为,对于你要解决的问题而言,你很难提前知道哪个超参数最重要,正如你之前看到的,一些超参数的确要比其它的更重要。
举个例子,取一个极端的例子,假设超参数1是 α \alpha α (学习速率),假设超参数2是Adam算法中分母中的 ϵ \epsilon ϵ。在这种情况下 α \alpha α的取值很重要,而 ϵ \epsilon ϵ 取值则无关紧要。如果你在网格中取点,接着,你试验了 α \alpha α的5个取值,那你会发现,无论 ϵ \epsilon ϵ取何值,结果基本上都是一样的。所以,你知道共有25种模型,但进行试验的 α \alpha α 值只有5个,我认为这是很重要的。
对比而言,如果你随机取值,你会试验25个独立的 α \alpha α ,似乎你更有可能发现效果做好的那个。
我已经解释了两个参数的情况,实践中,你搜索的超参数可能不止两个。假如,你有三个超参数,这时你搜索的不是一个方格,而是一个立方体,超参数3代表第三维,接着,在三维立方体中取值,你会试验大量的更多的值,三个超参数中每个都是。
实践中,你搜索的可能不止三个超参数有时很难预知,哪个是最重要的超参数,对于你的具体应用而言,随机取值而不是网格取值表明,你探究了更多重要超参数的潜在值,无论结果是什么。
当你给超参数取值时,另一个惯例是采用由粗糙到精细的策略。
比如在二维的那个例子中,你进行了取值,也许你会发现效果最好的某个点,也许这个点周围的其他一些点效果也很好,那在接下来要做的是放大这块小区域,然后在其中更密集得取值或随机取值
通过试验超参数的不同取值,你可以选择对训练集目标而言的最优值,或对于开发集而言的最优值,或在超参搜索过程中你最想优化的东西。
3.2 为超参数选择合适的范围
随机取值可以提升你的搜索效率。但随机取值并不是在有效范围内的随机均匀取值,而是选择合适的范围,用于探究这些超参数,这很重要
隐层神经元个数,和神经网络层数,这些超参数使用均匀采样看起来还不错,但是这对某些超参数而言不适用,比如学习率,假设你怀疑其值最小是0.0001或最大是1。
如果你画一条从0.0001到1的数轴,沿其随机均匀取值,那90%的数值将会落在0.1到1之间,结果就是,在0.1到1之间,应用了90%的资源,而在0.0001到0.1之间,只有10%的搜索资源,这看上去不太对。
用对数标尺搜索超参数的方式会更合理,因此这里不使用线性轴,分别依次取0.0001,0.001,0.01,0.1,1,在对数轴上均匀随机取点
另一个例子是
β \beta β=0.9时相当于对10天平均。这个问题也不能用线性轴取值。一种解决方法就是用 1 − β 1-\beta 1−β
这样就转化成刚才的形式了。
所以,如果你想研究更多正式的数学证明,关于为什么我们要这样做,为什么用线性轴取值不是个好办法,这是因为当 β \beta β接近1时,所得结果的灵敏度会变化,即使 β \beta β 有微小的变化。而 β \beta β 在0.9到0.9005之间取值,无关紧要,你的结果几乎不会变化。
但
β
\beta
β 值如果在0.999到0.9995之间,这会对你的算法产生巨大影响,对吧?在这两种情况下,0.9000和0.9005都是根据大概10个值取平均。但这里,它是指数的加权平均值,0.999基于1000个值,现在0.9995是2000个值。
当
β
\beta
β 接近1时,
β
\beta
β 就会对细微的变化变得很敏感, 所以整个取值过程中,你需要更加密集地取值,在
β
\beta
β 接近1的区间内.
希望能帮助你选择合适的标尺,来给超参数取值。如果你没有在超参数选择中作出正确的标尺决定,别担心,即使你在均匀的标尺上取值,如果数值总量较多的话,你也会得到还不错的结果,尤其是应用从粗到细的搜索方法,在之后的迭代中,你还是会聚焦到有用的超参数取值范围上。
3.3 超参数训练的实践 pandas vs Caviar
到现在为止,你已经听了许多关于如何搜索最优超参数的内容,在结束我们关于超参数搜索的讨论之前,我想最后和你分享一些建议和技巧,关于如何组织你的超参数搜索过程。
如今的深度学习已经应用到许多不同的领域,某个应用领域的超参数设定,有可能通用于另一领域,不同的应用领域出现相互交融。
深度学习领域中,发展很好的一点是,不同应用领域的人们会阅读越来越多其它研究领域的文章,跨领域去寻找灵感。
就超参数的设定而言,我见到过有些直觉想法变得很缺乏新意,所以,即使你只研究一个问题,比如说逻辑学,你也许已经找到一组很好的参数设置,并继续发展算法,或许在几个月的过程中,观察到你的数据会逐渐改变,或也许只是在你的数据中心更新了服务器,正因为有了这些变化,你原来的超参数的设定不再好用,所以我建议,或许只是重新测试或评估你的超参数,至少每隔几个月一次,以确保你对数值依然很满意。
最后,关于如何搜索超参数的问题,我见过大概两种重要的思想流派或人们通常采用的两种重要但不同的方式。
一种是你照看一个模型,通常是有庞大的数据组,但没有许多计算资源或足够的CPU和GPU的前提下,基本而言,你只可以一次负担起试验一个模型或一小批模型,在这种情况下,即使当它在试验时,你也可以逐渐改良。比如,第0天,你将随机参数初始化,然后开始试验,然后你逐渐观察自己的学习曲线,也许是损失函数 J ,或者数据设置误差或其它的东西,在第1天内逐渐减少,那这一天末的时候,你可能会说,看,它学习得真不错。我试着增加一点学习速率,看看它会怎样,也许结果证明它做得更好,那是你第二天的表现。两天后,你会说,它依旧做得不错,也许我现在可以填充下Momentum或减少变量。然后进入第三天,每天,你都会观察它,不断调整你的参数。也许有一天,你会发现你的学习率太大了,所以你可能又回归之前的模型,像这样,但你可以说是在每天花时间照看此模型,即使是它在许多天或许多星期的试验过程中。所以这是一个人们照料一个模型的方法,观察它的表现,耐心地调试学习率,但那通常是因为你没有足够的计算能力,不能在同一时间试验大量模型时才采取的办法。
而另一种就是你在计算资源非常丰富的情况下,可以同时运行多个不同超参数配置的模型
用这种方式你可以试验许多不同的参数设定,然后只是最后快速选择工作效果最好的那个
打个比方,我把左边的方法称为熊猫方式。当熊猫有了孩子,他们的孩子非常少,一次通常只有一个,然后他们花费很多精力抚养熊猫宝宝以确保其能成活,所以,这的确是一种照料,一种模型类似于一只熊猫宝宝。对比而言,右边的方式更像鱼类的行为,我称之为鱼子酱方式。在交配季节,有些鱼类会产下一亿颗卵,但鱼类繁殖的方式是,它们会产生很多卵,但不对其中任何一个多加照料,只是希望其中一个,或其中一群,能够表现出色。将称之为熊猫方式与鱼子酱方式,因为这很有趣,更容易记住。
所以这两种方式的选择,是由你拥有的计算资源决定的。
但在一些应用领域,比如在线广告设置和计算机视觉应用领域,那里的数据太多了,你需要试验大量的模型,所以同时试验大量的模型是很困难的,它的确是依赖于应用的过程。应用熊猫方式多一些,那里,你会像对婴儿一样照看一个模型,调试参数,试着让它工作运转。
尽管,当然,甚至是在熊猫方式中,试验一个模型,观察它工作与否,也许第二或第三个星期后,也许我应该建立一个不同的模型(绿色曲线),像熊猫那样照料它,我猜,这样一生中可以培育几个孩子,即使它们一次只有一个孩子或孩子的数量很少。
所以希望你能学会如何进行超参数的搜索过程,现在,还有另一种技巧,能使你的神经网络变得更加坚实,它并不是对所有的神经网络都适用,但当适用时,它可以使超参数搜索变得容易许多并加速试验过程,我们在下节中再讲解这个技巧。
3.4 正则化网络的激活函数
在深度学习兴起后,最重要的一个思想是它的一种算法,叫做Batch归一化,由Sergey loffe和Christian Szegedy两位研究者创造。Batch归一化会使你的参数搜索问题变得很容易,使神经网络对超参数的选择更加稳定,超参数的范围会更加庞大,工作效果也很好,也会是你的训练更加容易,甚至是深层网络。让我们来看看Batch归一化是怎么起作用的吧。
当训练一个模型,比如logistic回归时,你也许会记得,归一化输入特征可以加快学习过程,在之前的文章中我们看到,这是如何把学习问题的轮廓,从很长的东西,变成更圆的东西,更易于算法优化。
那么更深的模型呢?你不仅输入了特征值 x ,而且这层有激活值 a [ 1 ] a^{[1]} a[1] ,这层有激活值 a [ 2 ] a^{[2]} a[2] 等等。如果你想训练这些参数,比如, w [ 3 ] , b [ 3 ] w^{[3]},b^{[3]} w[3],b[3] 那归一化 a [ 2 ] a^{[2]} a[2] 的平均值和方差岂不是很好?以便使 w [ 3 ] , b [ 3 ] w^{[3]},b^{[3]} w[3],b[3] 的训练更有效率
尽管严格来说,我们真正归一化的不是 a [ 2 ] a^{[2]} a[2],而是 z [ 2 ] z^{[2]} z[2] ,深度学习文献中有一些争论,关于在激活函数之前是否应该将值 z [ 2 ] z^{[2]} z[2]归一化,或是否应该在应用激活函数 a [ 2 ] a^{[2]} a[2]后再规范值。实践中,经常做的是归一化 z [ 2 ] z^{[2]} z[2],所以这就是我介绍的版本,我推荐其为默认选择,那下面就是Batch归一化的使用方法。
对于第 l l l层的隐层, z [ l ] z^{[l]} z[l]为例
ε \varepsilon ε是一个很小的数比如 1 0 − 8 10^{-8} 10−8,防止方差为0,除数为0的情况。
所以现在我们已把这些 z值标准化,化为含平均值0和标准单位方差,所以 z 的每一个分量都含有平均值0和方差1,但我们不想让隐藏单元总是含有平均值0和方差1,也许隐藏单元有了不同的分布会有意义,所以我们所要做的就是计算,我们称之为 z ~ ( i ) \tilde{z}^{(i)} z~(i)
这里 γ \gamma γ 和 β \beta β 是你模型的学习参数,所以我们使用梯度下降或一些其它类似梯度下降的算法,比如Momentum或者Adam,你会更新 γ \gamma γ 和 β \beta β ,正如更新神经网络的权重一样.
请注意 γ \gamma γ 和 β \beta β 的作用是,你可以随意设置 z ~ ( i ) \tilde{z}^{(i)} z~(i) 的平均值。当然 z ~ ( i ) \tilde{z}^{(i)} z~(i)可能等于 z ( i ) z^{(i)} z(i)只要满足下面条件时
通过对 γ \gamma γ 和 β \beta β 合理设定,规范化过程,即这四个等式
从根本来说,只是计算恒等函数,通过赋予 γ \gamma γ和 β \beta β 其它值,可以使你构造含其它平均值和方差的隐藏单元值。
所以我希望你学到的是,归一化输入特征X 是怎样有助于神经网络中的学习,Batch归一化的作用是它适用的归一化过程,不只是输入层,甚至同样适用于神经网络中的深度隐藏层。你应用Batch归一化了一些隐藏单元值中的平均值和方差,不过训练输入和这些隐藏单元值的一个区别是,你也许不想隐藏单元值必须是平均值0和方差1。
比如,如果你有sigmoid激活函数,你不想让你的值总是全部集中在这里,你想使它们有更大的方差,或不是0的平均值,以便更好的利用非线性的sigmoid函数,而不是使所有的值都集中于这个线性版本中,这就是为什么有了 γ \gamma γ 和 β \beta β 两个参数后,你可以确保所有的 z ( i ) z^{(i)} z(i)值可以是你想赋予的任意值,或者它的作用是保证隐藏的单元已使均值和方差标准化。那里,均值和方差由两参数控制,即 γ \gamma γ 和 β \beta β ,学习算法可以设置为任何值,所以它真正的作用是,使隐藏单元值的均值和方差标准化,即 z ( i ) z^{(i)} z(i)有固定的均值和方差,均值和方差可以是0和1,也可以是其它值,它是由 γ \gamma γ和 β \beta β 两参数控制的。
3.5 将Batch Norm 拟合进神经网络
你已经看到那些等式,它可以在单一隐藏层进行Batch归一化,接下来,让我们看看它是怎样在深度网络训练中拟合的吧。
所以神经网络的参数就是下面
然后你可以用之前介绍过的任何一种优化算法,比如使用梯度下降法来执行它。
如果使用的是深度学习编程框架,通常你不必自己把Batch归一化步骤应用于Batch归一化层。因此,探究框架,可写成一行代码,比如说,在TensorFlow框架中,你可以用这个函数(tf.nn.batch_normalization)来实现Batch归一化,我们稍后讲解,但实践中,你不必自己操作所有这些具体的细节,但知道它是如何作用的,你可以更好的理解代码的作用。但在深度学习框架中,Batch归一化的过程,经常是类似一行代码的东西。
实践中,Batch归一化通常和训练集的mini-batch一起使用
现在,我想澄清此参数的一个细节。先前我说过每层的参数是 w [ l ] w^{[l]} w[l] 和 b [ l ] b^{[l]} b[l],还有 β [ l ] \beta^{[l]} β[l]和 γ [ l ] \gamma^{[l]} γ[l],请注意计算 z 的方式如下, z [ l ] = w [ l ] a [ l − 1 ] + b [ l ] z^{[l]}=w^{[l]}a^{[l-1]}+b^{[l]} z[l]=w[l]a[l−1]+b[l],但Batch归一化做的是,它要看这个mini-batch,先将 z [ l ] z^{[l]} z[l]归一化,结果为均值0和标准方差,再由 β \beta β 和 γ \gamma γ重缩放,但这意味着,无论 b [ l ] b^{[l]} b[l]的值是多少,都是要被减去的,因为在Batch归一化的过程中,你要计算 z [ l ] z^{[l]} z[l]的均值,再减去平均值,在此例中的mini-batch中增加任何常数,数值都不会改变,因为加上的任何常数都将会被均值减去所抵消。
然后就变成下面
总结
如果你还不清楚为什么其能如此显著的加速训练,我们进入下一节,详细讨论Batch归一化为何效果如此显著,它到底在做什么。
3.6 Batch Norm为什么奏效
为什么Batch归一化会起作用呢?
一个原因是,你已经看到如何归一化输入特征值 x ,使其均值为0,方差1,它又是怎样加速学习的,有一些从0到1而不是从1到1000的特征值,通过归一化所有的输入特征值 x ,以获得类似范围的值,可以加速学习。所以Batch归一化起的作用的原因,直观的一点就是,它在做类似的工作,但不仅仅对于这里的输入值,还有隐藏单元的值,这只是Batch归一化作用的冰山一角,还有些更深层的原理,它会有助于你对Batch归一化的作用有更深的理解,让我们一起来看看吧。
Batch归一化有效的第二个原因是,它可以使权重比你的网络更滞后或更深层,比如,第10层的权重更能经受得住变化,相比于神经网络中前层的权重,比如第1层,为了解释我的意思,让我们来看看这个最生动形象的例子。
这是一个网络的训练,也许是个浅层网络,比如logistic回归或是一个神经网络,也许是个浅层网络,像这个回归函数。或一个深层网络,建立在我们著名的猫脸识别检测上,但假设你已经在所有黑猫的图像上训练了数据集,如果现在你要把此网络应用于有色猫,这种情况下,正面的例子不只是左边的黑猫,还有右边其它颜色的猫,那么你的模型可能适用的不会很好。
你也许无法期待,在左边训练得很好的模块,同样在右边也运行得很好,即使存在运行都很好的同一个函数,但你不会希望你的学习算法去发现绿色的决策边界,如果只看左边数据的话。
如果x的分布改变了,那么你可能需要重新训练你的学习算法
试想一个像这样的深度网络,让我们从第三层来看看学习过程。此网络已经学习了参数
w
[
3
]
w^{[3]}
w[3] 和
b
[
3
]
b^{[3]}
b[3] ,从第三隐藏层的角度来看,它从前层中取得一些值,接着它需要做些什么,使希望输出值
y
^
\hat{y}
y^接近真实值 y 。
先遮住左边的部分
让我先遮住左边的部分,从第三隐藏层的角度来看,它得到一些值,称为 a 1 [ 2 ] , a 2 [ 2 ] , a 3 [ 2 ] , a 4 [ 2 ] a_1^{[2]},a_2^{[2]},a_3^{[2]},a_4^{[2]} a1[2],a2[2],a3[2],a4[2] ,但这些值也可以是特征值 x 1 , x 2 , x 3 , x 4 x_1,x_2,x_3,x_4 x1,x2,x3,x4 。第三层隐藏层的工作是找到一种方式,使这些值映射到 y ^ \hat{y} y^。你可以想象做一些截断,所以这些参数 w [ 3 ] w^{[3]} w[3]和 b [ 3 ] b^{[3]} b[3]或 w [ 4 ] w^{[4]} w[4]和 b [ 4 ] b^{[4]} b[4]或 w [ 5 ] w^{[5]} w[5]和 b [ 5 ] b^{[5]} b[5],也许是学习这些参数,所以网络做的不错,从左边我用黑色笔写的映射到输出值 y ^ \hat{y} y^。
现在我们把网络的左边揭开,
这个网络还有参数 w [ 2 ] , b [ 2 ] w^{[2]},b^{[2]} w[2],b[2]和 w [ 1 ] , b [ 1 ] w^{[1]},b^{[1]} w[1],b[1],如果这些参数改变,这些 a [ 2 ] a^{[2]} a[2]的值也会改变。所以从第三层隐藏层的角度来看,这些隐藏单元的值在不断地改变,所以它就有了“Covariate shift”的问题
Batch归一化做的,是它减少了这些隐藏值分布变化的数量。如果是绘制这些隐藏的单元值的分布(这里只绘制了2维情况)
Batch归一化讲的是 z 1 [ 2 ] , z 2 [ 2 ] z^{[2]}_1,z^{[2]}_2 z1[2],z2[2]的值可以改变,它们的确会改变,当神经网络在之前层中更新参数,Batch归一化可以确保无论其怎样变化 z 1 [ 2 ] , z 2 [ 2 ] z^{[2]}_1,z^{[2]}_2 z1[2],z2[2]的均值和方差保持不变,所以即使 z 1 [ 2 ] , z 2 [ 2 ] z^{[2]}_1,z^{[2]}_2 z1[2],z2[2]的值改变,至少他们的均值和方差也会是均值0,方差1,或不一定必须是均值0,方差1,而是由 β [ 2 ] \beta^{[2]} β[2] 和 γ [ 2 ] \gamma^{[2]} γ[2] 决定的值。如果神经网络选择的话,可强制其为均值0,方差1,或其他任何均值和方差。但它做的是,它限制了在前层的参数更新,会影响数值分布的程度,第三层看到的这种情况,因此得到学习。
Batch归一化减少了输入值改变的问题,它的确使这些值变得更稳定,神经网络的之后层就会有更坚实的基础。即使使输入分布改变了一些,它会改变得更少。它做的是当前层保持学习,当改变时,迫使后层适应的程度减小了,你可以这样想,它减弱了前层参数的作用与后层参数的作用之间的联系,它使得网络每层都可以自己学习,稍稍独立于其它层,这有助于加速整个网络的学习。
所以,希望这能带给你更好的直觉,重点是Batch归一化的意思是,尤其从神经网络后层之一的角度而言,前层不会左右移动的那么多,因为它们被同样的均值和方差所限制,所以,这会使得后层的学习工作变得更容易些。
Batch归一化还有一个作用,它有轻微的正则化效果
Batch归一化中非直观的一件事是,每个mini-batch,我会说mini-batch X { t } X^{\{t\}} X{t} 的值为 z [ l ] z^{[l]} z[l] ,在mini-batch计算中,由均值和方差缩放的,因为在mini-batch上计算的均值和方差,而不是在整个数据集上,均值和方差有一些小的噪声,因为它只在你的mini-batch上计算,比如64或128或256或更大的训练例子。因为均值和方差有一点小噪音,因为它只是由一小部分数据估计得出的。缩放过程从 z [ l ] z^{[l]} z[l] 到 z ~ [ l ] \tilde{z}^{[l]} z~[l] ,过程也有一些噪音,因为它是用有些噪音的均值和方差计算得出的。
所以和dropout相似,它往每个隐藏层的激活值上增加了噪音,dropout有增加噪音的方式,它使一个隐藏的单元,以一定的概率乘以0,以一定的概率乘以1,所以你的dropout含几重噪音,因为它乘以0或1。
对比而言,Batch归一化含几重噪音,因为标准偏差的缩放和减去均值带来的额外噪音。这里的均值和标准差的估计值也是有噪音的,所以类似于dropout,Batch归一化有轻微的正则化效果,因为给隐藏单元添加了噪音,这迫使后部单元不过分依赖任何一个隐藏单元,类似于dropout,它给隐藏层增加了噪音,因此有轻微的正则化效果。因为添加的噪音很微小,所以并不是巨大的正则化效果,你可以将Batch归一化和dropout一起使用,如果你想得到dropout更强大的正则化效果。
也许另一个轻微非直观的效果是,如果你应用了较大的mini-batch,对,比如说,你用了512而不是64,通过应用较大的min-batch,你减少了噪音,因此减少了正则化效果,这是dropout的一个奇怪的性质,就是应用较大的mini-batch可以减少正则化效果。
说到这儿,我会把Batch归一化当成一种正则化,这确实不是其目的,但有时它会对你的算法有额外的期望效应或非期望效应。但是不要把Batch归一化当作正则化,把它当作将你归一化隐藏单元激活值并加速学习的方式,我认为正则化几乎是一个意想不到的副作用。
Batch归一化一次只能处理一个mini-batch数据,它在mini-batch上计算均值和方差。所以测试时,你试图做出预测,试着评估神经网络,你也许没有mini-batch的例子,你也许一次只能进行一个简单的例子,所以测试时,你需要做一些不同的东西以确保你的预测有意义。
3.7 测试时的Batch Norm
请注意用于调节计算的
μ
\mu
μ 和
σ
2
\sigma^2
σ2 是在整个mini-batch上进行计算,但是在测试时,你可能不能将一个mini-batch中的6428或2056个样本同时处理,因此你需要用其它方式来得到
μ
\mu
μ 和
σ
2
\sigma^2
σ2 ,而且如果你只有一个样本,一个样本的均值和方差没有意义。那么实际上,为了将你的神经网络运用于测试,就需要单独估算
μ
\mu
μ 和
σ
2
\sigma^2
σ2,在典型的Batch归一化运用中,你需要用一个指数加权平均来估算,这个平均数涵盖了所有mini-batch,接下来我会具体解释。
正如我们之前用的指数加权平均来计算
θ
1
,
θ
2
,
θ
3
\theta_1,\theta_2,\theta_3
θ1,θ2,θ3 的均值,当时是试着计算当前气温的指数加权平均,你会这样来追踪你看到的这个均值向量的最新平均值,于是这个指数加权平均就成了你对这一隐藏层的 z 均值的估值。
因此在用不同的mini-batch训练神经网络的同时,能够得到你所查看的每一层的
μ
\mu
μ 和
σ
2
\sigma^2
σ2 的平均数的实时数值。
最后在测试时,用 μ \mu μ 和 σ 2 \sigma^2 σ2 的指数加权平均,用你手头的最新数值来做调整,然后你可以用左边我们刚算出来的 z n o r m z_{norm} znorm 和你在神经网络训练过程中得到的 β \beta β 和 γ \gamma γ 参数来计算你那个测试样本的 z ~ \tilde{z} z~ 值。
总结一下就是,在训练时, μ \mu μ 和 σ 2 \sigma^2 σ2是在整个mini-batch上计算出来的包含了像是64或128或其它一定数量的样本,但在测试时,你可能需要逐一处理样本,方法是根据你的训练集估算 μ \mu μ 和 σ 2 \sigma^2 σ2 ,估算的方式有很多种,理论上你可以在最终的网络中运行整个训练集来得到 μ \mu μ 和 σ 2 \sigma^2 σ2 ,但在实际操作中,我们通常运用指数加权平均来追踪在训练过程中你看到的 μ \mu μ 和 σ 2 \sigma^2 σ2的值。
3.8 Softmax回归
到目前为止,我们讲到过的分类的例子都使用了二分分类,这种分类只有两种可能的标记0或1,这是一只猫或者不是一只猫,如果我们有多种可能的类型的话呢?
输出层有4个,这里的 y ^ \hat{y} y^将是一个 4 ∗ 1 4 * 1 4∗1维向量,因为它必须输出四个数字,给你这四种概率,因为它们加起来应该等于1,输出中的四个数字加起来应该等于1。
让你的网络做到这一点的标准模型要用到Softmax层,以及输出层来生成输出,让我把式子写下来,然后回过头来,就会对Softmax的作用有一点感觉了。
那么Softmax分类器还可以代表其它的什么东西么?我来举几个例子,你有两个输入 x 1 , x 2 x_1,x_2 x1,x2 ,它们直接输入到Softmax层,它有三四个或者更多的输出节点,输出 y ^ \hat{y} y^ ,我将向你展示一个没有隐藏层的神经网络,它所做的就是计算 z [ 1 ] = W [ 1 ] x + b [ 1 ] z^{[1]}=W^{[1]}x+b^{[1]} z[1]=W[1]x+b[1] ,而输出的出 a [ 1 ] a^{[1]} a[1] ,或者说 y ^ \hat{y} y^
这个例子中,原始输入只有
x
1
x_1
x1 和
x
2
x_2
x2,一个
C
=
3
C=3
C=3个输出分类的Softmax层能够代表这种类型的决策边界,请注意这是几条线性决策边界,但这使得它能够将数据分到3个类别中,在这张图表中,我们所做的是选择这张图中显示的训练集,用数据的3种输出标签来训练Softmax分类器,图中的颜色显示了Softmax分类器的输出的阈值,输入的着色是基于三种输出中概率最高的那种。因此我们可以看到这是logistic回归的一般形式,有类似线性的决策边界,但有超过两个分类,分类不只有0和1,而是可以是0,1或2。
这是其他几个Softmax分类器可以代表的决策边界的例子,直觉告诉我们,任何两个分类之间的决策边界都是线性的
我们来看一下更多分类的例子
c=4,c=5,c6,这显示了Softmax分类器在没有隐藏层的情况下能够做到的事情,当然更深的神经网络会有x ,然后是一些隐藏单元,以及更多隐藏单元等等,你就可以学习更复杂的非线性决策边界,来区分多种不同分类。
3.9 训练一个Softmax分类器
回顾一下前面
Softmax这个名称的来源是与所谓hardmax对比
hardmax会把向量 z 变成这个向量,最大值是1,其他为0 。hardmax函数会观察z 的元素,然后在z 中最大元素的位置放上1,其它位置放上0,所这是一个hard max,也就是最大的元素的输出为1,其它的输出都为0。与之相反,Softmax所做的从 z 到这些概率的映射更为温和。
Softmax回归或Softmax激活函数将logistic激活函数推广到 C 类,而不仅仅是两类,结果就是如果 C=2 ,那么C=2 的Softmax实际上变回了logistic回归。
如何训练带有Softmax输出层的神经网络
对于这个样本神经网络的表现不佳,这实际上是一只猫,但却只分配到20%是猫的概率,所以在本例中表现不佳。
那么你想用什么损失函数来训练这个神经网络
这就意味着,如果你的学习算法试图将它变小,因为梯度下降法是用来减少训练集的损失的,要使它变小的唯一方式就是使 − log y ^ 2 -\log\hat{y}_2 −logy^2 变小,要想做到这一点,就需要使 y ^ 2 \hat{y}_2 y^2 尽可能大,因为这些是概率,所以不可能比1大。
这里有一个实现细节
注意因为 C=4 ,y 是一个4×1向量, y ^ \hat{y} y^ 也是一个4×1向量,如果你实现向量化,矩阵大写 Y维度就是4×m
其实初始化反向传播所需要的关键步骤或者说关键方程是这个表达 d z [ l ] = y ^ − y dz^{[l]}=\hat{y}-y dz[l]=y^−y,如果你精通微积分就可以自己推导
3.10 深度学习框架
现在有很多的深度学习框架
选择框架的标准
一个重要的标准就是便于编程,这既包括神经网络的开发和迭代,还包括为产品进行配置,为了成千上百万,甚至上亿用户的实际使用,取决于你想要做什么。
第二个重要的标准是运行速度,特别是训练大数据集时,一些框架能让你更高效地运行和训练神经网络。
还有一个标准人们不常提到,但我觉得很重要,那就是这个框架是否真的开放,要是一个框架真的开放,它不仅需要开源,而且需要良好的管理。不幸的是,在软件行业中,一些公司有开源软件的历史,但是公司保持着对软件的全权控制,当几年时间过去,人们开始使用他们的软件时,一些公司开始逐渐关闭曾经开放的资源,或将功能转移到他们专营的云服务中。因此我会注意的一件事就是你能否相信这个框架能长时间保持开源,而不是在一家公司的控制之下,它未来有可能出于某种原因选择停止开源,即便现在这个软件是以开源的形式发布的。但至少在短期内,取决于你对语言的偏好,看你更喜欢Python,Java还是C++或者其它什么,也取决于你在开发的应用,是计算机视觉,还是自然语言处理或者线上广告,等等,我认为这里的多个框架都是很好的选择。