声明: 此笔记为吴恩达(Andrew Ng)的深度学习课程学习后的总结,会根据自己的学习进度更新,离上次更新晚了很久,学完前三个课程停了下来,回头肝机器学习的基础了。
调优(Hyperparameter tuning)
1.调试处理(Tuning process)
- 其中红色的 α \alpha α是最重要的参数,橙色的 β , h i d d e n u n i t s , l e a r n i n g r a t e d e c a y \beta ,\ hidden \ units, \ learning\ rate\ decay β, hidden units, learning rate decay也是经常需要调试的,紫色的有时会有大影响,但不会经常调试。特别是 β 1 , b e t a 2 , ϵ \beta_1,beta_2,\epsilon β1,beta2,ϵ这三个基本就是0.9,0.999, 1 0 − 8 10^{-8} 10−8三个值不怎么动( β \beta β是Momentum的参数, β 1 , b e t a 2 , ϵ \beta_1,beta_2,\epsilon β1,beta2,ϵ是使用Adam优化算法的参数)
- 假设就两个超参,在随机取值时,有上图左右两种情况,第一种取值按照矩阵排布,两参数各五个取值,这样总共25中情况,而第二种同样是25中情况,由于是随机取值,H1,H2都可以有25中取值,这样当参数增加时,随机取值对比网格取值而言,你探究了更多重要超参数的潜在值,这样更好。
1. 选择超参的合适范围(using an appropriate scale to pick hyperparameters)
均匀取值,对一些超参数是不太适用的,
- 例如学习率 0-1中分十段取值,看似合理,但是学习率基本上都是在0.oo01-0.1,这样搜索资源只有10%,浪费很多,这样对数轴上节点进行修改后,更合理,如图:
在实现上,r = 4 * np.random.rand()
,然后
α
=
1
0
r
\alpha = 10^r
α=10r这
α
∈
[
1
0
−
4
,
1
0
0
]
\alpha \in [10^{-4},10^0]
α∈[10−4,100]这样就达到上图下部的分布特征。
3. 超参数调试实践(“panda VS Caviar”)
对于超参数的设定,可能隔几个月就需要重新测试与评估
关于如何设定合适的超参数,大概有下面两种:
-
第一种,如图左所示,由于数据量庞大但CPU和GPU资源有限,一次只能实验一小批模型,每天进行一些细微的变化,不断地调整,观察表现,就像照顾一只熊猫一样。
-
第二种,如图右所示,同时实验多种模型,设置一些参数,让他自己运行,同时设定不不同的参数进行实验对比,这样就像一堆鱼子一样,不需要每一颗都去细微地关照。
4. Batch Normal
- 什么是Batch Normal?
之前已经验证过,归一化输入特征可以加快学习过程,但是那是归一化第一层的输入,那么针对隐藏层的输入是否可以归一化?
归一化每一层的输入肯定时可以的,但是现存一些争论,关于在激活函数之前是否应该将值 z [ l ] z^{[l]} z[l]归一化,或是否应该在应用激活函数后再规范值 a [ l ] a^{[l]} a[l]。实践中,经常做的是归一化前者,后面都是这样做的。当然 z [ l ] ( i ) z^{[l](i)} z[l](i)才是规范的书写,为了简化推导,省略层数,接着缺每个$$,使其规范化,推导如下:
μ = 1 m ∑ i z ( i ) \mu = \frac 1 m \sum_i z^{(i)} μ=m1i∑z(i)
σ 2 = 1 m ∑ i ( z ( i ) − μ ) \sigma ^2 = \frac 1 m \sum_i (z^{(i)}-\mu) σ2=m1i∑(z(i)−μ)
z n o r m ( i ) = z i − μ σ 2 + ϵ z^{(i)}_{norm}=\frac{z^{i}-\mu}{\sqrt{\sigma^2 + \epsilon}} znorm(i)=σ2+ϵzi−μ
现在已经经过标准化了,含平均值为0方差1的情况,但最好不让隐藏单元含有这样的情况,借鉴梯度下降的算法,例如Monmentumh,Adam,所以再进行一次操作:
z ^ ( i ) = γ z n o r m ( i ) + β \hat{z}^{(i)} = \gamma z^{(i)}_{norm} + \beta z^(i)=γznorm(i)+β
其中,若 γ = σ 2 + ϵ \gamma=\sqrt{\sigma^2+\epsilon} γ=σ2+ϵ,及 z n o r m ( i ) z^{(i)}_{norm} znorm(i)中的分母项, β = μ \beta=\mu β=μ,则 z ^ ( i ) = z ( i ) \hat{z}^{(i)}=z^{(i)} z^(i)=z(i)其精准的转化了这个方程,可以通过对 γ \gamma γ和 β \beta β的合理设定,规范化过程从根本来说,只是计算恒等函数,通过赋予和其它值,可以使你构造含其它平均值和方差的隐藏单元值。
- 如何将Batch Norm拟合进神经网络?
以第一层位例子简单来说,就是在 z [ 1 ] z^{[1]} z[1]代入到激活函数计算 a [ 1 ] a^{[1]} a[1]前,先对 z [ 1 ] z^{[1]} z[1]进行BN,由 β [ 1 ] \beta^{[1]} β[1]和 γ [ 1 ] \gamma^{[1]} γ[1]两参数来控制,后面的激活函数计算表达式: a [ 1 ] = g [ 1 ] ( z ^ [ l ] ) a^{[1]}=g^{[1]}(\hat{z}^{[l]}) a[1]=g[1](z^[l]),当然自己算 z [ 1 ] z^{[1]} z[1]的时候是由参数 b [ 1 ] b^{[1]} b[1]和 w [ 1 ] w^{[1]} w[1]来控制,后面的层数以此类推,需要补充的是, β [ 1 ] \beta^{[1]} β[1]和Monmentum、Adam、RMSprop里的 β \beta β是不一样的。对于此处 β \beta β的参数更新,可以采用梯度下降的办法,计算如下: β [ l ] = β [ l ] − α β [ l ] \beta^{[l]}=\beta^{[l]}-\alpha\beta{[l]} β[l]=β[l]−αβ[l],当然也可以用Adam、RMSprop或Momentum来更新 β \beta β和 γ \gamma γ。
在mini-bath上运用BN,先计算第一个mini-batch(
X
1
X^{{1}}
X1)不变,再计算第二个mini-batch(
X
2
X^{{2}}
X2),接着Batch归一化减去均值,除以标准差,由
β
[
1
]
\beta^{[1]}
β[1]和
γ
[
1
]
\gamma^{[1]}
γ[1]重新缩放的到
z
^
[
1
]
\hat{z}^{[1]}
z^[1],这样做的目的是在第一个mini-batch上进行一步梯度下降法。
需要特别注意的是,
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]但BN是针对mini-batch,先将
z
[
l
]
z^{[l]}
z[l]归一化,结果为均值0和标准方差,再由
β
\beta
β和
γ
\gamma
γ重新缩放,因为归一化时候减去了平均值
μ
\mu
μ所以无论\b^{[l]}
的值是多少,都要被减掉,所以超参失去一个
- 为何Batch Norm能奏效?
首先,与之前的归一化理论一样,假如有一些从0-1而不是从1-1000的特征值,通过归一化所有的输入特征x,以获得类似范围的值,可以加速学习,并且Batch归一化不仅仅对输入第一层的特征做归一化,还有隐藏层的值。
其次,可以使权重帮你的网络更之后或更深层,厚层的权重比前层更禁得起变化,举个例子:
图左,在黑猫与其他生物的数据集上训练出来的网络,现在把其用于识别包含有色猫数据的数据集,效果不一定很好,所以需要改变数据分布,叫做"Covariate shift"种做法同样适用于,如果真实函数由x到y映射保持不变,正如此例中,因为真实函数是此图片是否是一只猫,训练你的函数的需要变得更加迫切,如果真实函数也改变,情况就更糟了。
关于“Covariate shitf”如何影响神经网络?解释如下:
如果现在遮住前两层,但从第三层开始,输入都是第二层计算后的值,可以理解为从这里截断,学习后面几层的参数,照样效果不错,但是现在解开前几层的话,参数会多出前两层的( w , b w,b w,b),如果这些参数改变,第二层的输出值及第三层的输入就会改变,从第三层的角度看,隐藏单元的值不断地在改变,这就是"Covariate shift"问题。
而Batch归一化所做的,就是减少这些隐藏单元值得分布变化数量,在数学推导上,表现为:在前几层更新参数是可以的,及 z 1 , z 2 z_1,z_2 z1,z2的值是可以变化的,但是通过Batch归一化,无论 z 1 , z 2 z_1,z_2 z1,z2如何变化,均值和方差是可以由 β , γ \beta,\gamma β,γ的值来控制和确定的,说白了,就是减少前层参数更新,对于数值分布的影响程度,让神经网络的每一层都稍微独立于前一层,这样有利于加速整个网络的学习。
最后,BN还有轻微的正则化效果,因为是在每个mini-batch上计算均值和方差,不是整个数据集上,均值和方差会有一些效地噪声,所以和dropout相似,它往每个隐藏层的激活值上增加了噪音,dropout有增加噪音的方式,它使一个隐藏的单元,以一定的概率乘以0,以一定的概率乘以1,所以dropout含几重噪音,因为它乘以0或1。
对比而言,Batch归一化也含几重噪音,因为标准偏差的缩放和减去均值带来的额外噪音。这里的均值和标准差的估计值也是有噪音的,所以类似于dropout,Batch归一化有轻微的正则化效果,也许另一个轻微非直观的效果是,如果你应用了较大的mini-batch,比如说,你用了512而不是64,会减少噪音,因此减少了正则化效果,这是dropout的一个奇怪的性质,就是应用较大的mini-batch可以减少正则化效果。但是不要把Batch归一化当作正则化,把它当作将你归一化隐藏单元激活值并加速学习的方式,正则化几乎是一个意想不到的副作用。