本文主要是介绍超参数调试与BN(Batch Norm),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1. 深度学习中的超参数
深度学习最难之一的问题,也是被许多人不喜的愿意就是超参数,深度学习中有许多超参数,例如常见的学习率、隐藏层的数量、优化算法中的超参数等等。这些超参数往往没有一个固定的比较好的值,在不同的领域、不同的场景、甚至是硬件条件不变,最适合的超参数也在变化,因此,想要掌握深度学习,超参数是不得不面对的一件事。
那么超参数那么多,到底怎样选取合适的值呢?
我们首先根据大多数人的经验为常见的超参数分类,并给出常见的合适值。
根据超参数重要性,将其分类三类,重要性依次递减(非真理):
- 学习率(learning rate)
- 优化算法中的超参数(例如Adam算法中的)、隐藏层的单元数、mini-batch的大小
- 隐藏层的层数、学习率衰减值
以上是根据超参数对训练的影响程度对常见超参数进行排序,当然不绝对,但是当我们对超参数毫无头绪的时候,可以按照这个顺序对其重视。对于常见的合适值,请详见每个链接具体的blog。
了解了常见超参数对训练的影响程度,再介绍一下超参数调试中常用的方法:随机选择点
随机选择点指的是在选择超参数值的时候,随机选择比按照估计的间距选择点更好,因为当有两个以上的超参数需要调节时,多个超参数随机选择点,能够使得超参数覆盖的范围更广。
如上图所示,随机选择点,同样的组合数量,但是对于单个参数而言,能够达到更多调试值的目的。
另一个常用方法是:从粗糙到精细
顾名思义,先从比较大的范围内随机选择点,在确定某几个点效果不错时,缩小范围,再进行随机选择点测试。
2. 如何随机均匀取值
在第一节中,我们知道随机选择值的效果会比均匀取值更好一点,实际上,按照我们的直观想法,随机取值就是简单的随机生成区间内的数,但是真的所有的情况都如此吗?思考下面这个问题:
加入我们目前有一个超参数,它的值应该在0.0001到1之间,如果我们随机均匀取值,那么大部分(90%)的点都会落在0.1~1之间,这是我们想要的吗?
当然不是,这种情况下使用对数标尺搜索超参数的方式会更合理:
还是上面的情况,我们不使用线性轴,而是分别取0.0001,0.001,0.01,0.1,1,在对数轴上均匀随机取点,这样,在0.0001和0.001之间,就会有更多的资源可用。
总结上述方法:
令,令超参数,那么,因此我们将参数的对数标尺取值转换为只需对随机取值就可以。
似乎解决了上述资源分配不合理的问题,我们再想一下Adam中的超参数,它的取值一般是0.9~0.999,此时我们的做法应该也是类似对数表尺搜索超参数法,但是具体怎样呢,看一下:
我们不直接对随机取值,而是对随机取值,然后再使用上述标准的对数标尺搜索超参数法。
3. 训练中的超参数调试
超参数调试是在深度学习中不得不面对的问题,在实践中,往往有以下两种方式:
-
Pandas
这种方式适用于CPU\GPU资源不是很充足的情况下,它指的是一直照看同一个模型,通过在一个模型的训练过程中,根据模型训练即时效果,不断修改参数值。用一句话来说,这种方式是在同一个模型中同一个训练中进行参数调试。下面的图更有助于理解:
-
Caviar
这种方式适用于资源比较充足的情况下,它是使用不同的模型,每个模型有着自己的参数,每个模型的训练代表着一个参数的效果。
它可以使得不同参数的效果更充分体现,且简单粗暴,但是需要大量的资源,因为为了在短时间找到合适的参数,需要使不同参数所在的模型同时训练。
4. 归一化输入特征
训练神经网络,其中一个加速训练的方法就是归一化输入。
归一化输入有两个步骤:
- 零均值
- 归一化方差
我们最终的要求是无论是训练集还是测试集都是通过相同的和转换数据集,但是这两个值是通过训练集计算出来的。
-
零均值化 公式4-1中,代表第个样本。
本质其实是对数据集做平移操作,使得数据集更像0点汇聚。效果如下图所示
-
归一化方差 公式4-2是在公式4-1的基础上进行计算,因此求取方差的过程没有再减去均值。
本质上是对数据集进行缩放操作,使数据集尽可能”均匀”
上述讲解了归一化输入特征的做法,但是他为什么能够加快网络的训练呢?
我们从成本函数入手,在为归一化输入值之前,我们的输入1有可能取值在(0,1000)之间,输入2有可能在(0,1)之间,那么我们的成本函数可能长成这个样子:
像一个细长狭窄的碗,在这种情况下,我们要找到收敛值,需要使用很小的学习率(因为学习率大有可能导致越过碗的狭窄处的收敛值),于是导致学习过程很慢。
但是经过归一化输入特征后,我们的多个输入更加类似,成本函数长成这个样子:
像一个很圆的碗,这样无论我们从哪里进行学习,它能够更直接的找到最小值,使用一个大的学习率能够更快速的收敛到最优值。
5. 归一化网络的激活函数(BN)
上一小节讲了如何归一化输入值,使得模型的训练更快。
但是在多层神经网络中,对于每一个隐藏层而言,掩盖住之前数据的处理,每层的输入值是不是和特征值类似呢,因此,我们是否可以对每一层的激活函数也能用归一化,使得每一层的参数的训练更快更有效率?
其实是可以的,在深度学习中,这叫做Batch Norm(BN)
我们将第4小节的归一化输入值方法,运用到神经网络的一层中: 的作用是防止分母为0。通过公式我们可以看到,归一化的不是,而是,尽管从归一化输入值的角度来说,应该是针对,但是在实践中,更多是归一化,具体的可以查看相关文献。
通过公式5-1,我们将某层的值标准化,使其平均值为0,方差为标准单位方差(1)。但是有时候我们不想让值如此标准,或者略微不同的值对于神经元会更有意义,我们可以将其进一步处理。 公式5-2中和的作用是随意设置的均值和方差。当,,那么。
通过上面的讲解,我们知道归一化不仅适用于输入,同样适用于深度隐藏层;他们之间的区别是对于隐藏层,也许我们不想让输入值必须为平均值0方差1。
例如在sigmoid函数中,如果输入值集中在中间一部分,就没有很好的利用激活函数的非线性的特性,我们想让他的方差更大些,这就是和的作用。
6. BN在神经网络中的应用
第5小节介绍了BN在单个隐藏层的应用,在真正的神经网络中,我们需要将BN加入到与之间,并引入了参数和。 公式6-1中,中应用参数;使用参数和.
这里的和不是超参数,而是类似于w,b这种需要训练的参数,因此在更新时,需要更新。
值得注意的是,在隐藏层使用BN时,由于减去了均值,因此参数中的的作用已经被取代了。
所以,在使用BN时,我们要训练的参数应该是。
7. BN分析
让我们分析一下Batch Norm会什么会起作用。
首先,根据归一化输入的分析,BN首先可以获得类似范围的值,加速学习。
但是BN仅仅是这样吗?其实他还有一些别的用处:
-
减少了输入值改变(或者分布改变)对后面的影响
他减弱了前层参数的作用与后层参数作用之前的联系,使得网络的每层都可以自己学习,稍稍独立于其他层,有助于加速整个网络的学习并且使得网络更强壮。
-
轻微的正则化效果
例如在mini-batch中,计算均值与方差是在batch大小的数据集中,而不是在全量数据集中,因此有一定的噪声,类似于dropout的效果,迫使后部单元不过分依赖任何一个隐藏单元。(但是mini-batch增大会减少噪声)
在测试时的均值和方差如何得到呢?
之前提到过,测试时的均值和方差要从训练集中取得,因此我们可以使用训练好的模型运行整个训练集,记录均值和方差。
不过此种方法太过于繁琐,我们可以使用指数加权平均的方式来记录训练过程中的均值和方差。
如果使用深度学习框架,框架中也有默认估算均值和方差的方式。
8. 结论
在上面几个小节,主要讲了两部分内容:超参数调试和BN。
实际上在使用BN后,我们的网络会变得更加稳定(减少了对于输入值改变或者分布的依赖),越稳定的网络其实对超参数的依赖性,或者对超参数的敏感性越低,在一定程度上使用BN能够使超参数调节更加容易。
连接:https://zhuanlan.zhihu.com/p/68228985
这篇关于超参数调试与BN(Batch Norm)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!