第三周:超参数调试、Batch正则化和程序框架

3.1调试处理:

超参数重要性优先级:

1、学习率α

2、Momentum的参数β、隐藏单元的数量、mini-batch的大小

3、神经网络的层数、学习率衰减

4、Momentum或Adam优化算法的参数,β1β2\beta_1、\beta_2ε\varepsilon

在深度学习中,采用随机选择点,用这些随机取的点试验超参数的效果。随机取值而不是比网格取值表明,你探究了更多重要超参数的潜在值,无论结果是什么。随机取值,可以提升搜索效率,但随机取值并不是在有效范围内的随机均匀取值,而是选择合适的标尺,用于探究这些超参数。

另一个惯例,是采用由粗糙到精确的策略,比如在二维(第一维为超参数1,第二维为超参数2)中,你进行了取值,你会发现效果最好的某个点,也许它周围其他的点效果也很好,接下来就是放大这块小区域,然后再其中更密集地取值或随机取值,聚集更多的资源。

3.2为超参数选择合适的范围

Appropriate scale for hyperparameters

采用对数标尺搜索超参数的方式,而不使用线性轴。(因为画一条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,在对数轴上均匀随机取点,这样在0.0001到0.001之间就会有更多搜索资源可用,还有在0.001到0.01之间等等。

eg:r = -4 * np.random.rand(), 然后a随机取值,a=10ra = 10^r,得到r∈[-4, 0], 所以a∈[104,10010^-4, 10^0]。

第三周:超参数调试、Batch正则化和程序框架
在此例中,10a(0.0001)10^a(0.0001),可通过0.0001算出a的值,即-4。在右边的值是10b10^b,算出b的值,即0.要做的就是在[a, b]区间均匀地给r取值,然后可以设置a的值,基于随机取样的超参数a=10ra = 10^r

总结:

在对数坐标下取值,取最小值的对数得到a的值,取最大值的对数就得到b的值。所以在对数轴上的10a10b10^a到10^b区间取值,在a, b间随意均匀的选取r值,将超参数设置为10r10^r,这就是在对数轴上取值的过程。

Hyperparameters for exponentially weighted averages

β取值,用于计算指数的加权平均。 假设β是0.9到0.999之间的某个值。记住,当计算指数的加权平均值时,取0.9就像在10个值中计算平均值,有点儿类似于i计算10天的温度平均值,而取0.999就是在1000个值中取平均。

如果想在0.9到0.999区间搜索,那就不能用线性轴取值。 不要随机均匀地在此区间取值,所以考虑这个问题最好的方法就是,探究1-β,此值在0.1到0.001区间内,所以会给1-β取值,这是101,10310^{-1}, 10^{-3}。 所以要做的就是在[-3, -1]里随机均匀的给r取值。你设定了1β=10r1-\beta = 10^{r},所以β=110r\beta = 1 - 10^r,就变成了在特定的选择范围内超参数随机取值。用这种方式,你在0.9到0.99区间探究的资源,和在0.99到0.999区间探究的一样多。

**Q:**为什么用线性轴不好?

**A:**由公式11β\frac{1}{1-\beta},当β接近于1时,所得结果的灵敏度会变化,即使β有微小的变化。 所以整个取值过程,需要更加密集地取值,在β接近1的区间内,或者当1-β接近于0时,这样就会更加有效地分布取样点,更有效率的探究可能的结果。

3.4归一化网络的**函数(Normalizing activations in a network)

输入归一化

这里采用了另个博主的部分材料。(转载至https://www.jianshu.com/p/cd3e9a491426)

为加快训练神经网络的速度,可以对输入数据进行归一化操作,在测试时,也要对测试集进行相同的归一化操作。

归一化步骤:

  1. 零均值
  2. 归一化方差

假设初始训练集分布如下:
第三周:超参数调试、Batch正则化和程序框架
第一步是通过零均值化,具体如下:
μ=1mi=1mx(i) \mu = \frac{1}{m}\sum^m_{i=1}x^{(i)}

这个一个向量,X是所有训练集组成的矩阵,令X=μX-=\mu,实际意义是移动训练集,完成零均值化。经过零均值化,训练及分布如下图:
第三周:超参数调试、Batch正则化和程序框架

第二步是归一化方差,具体方法如下:
σ2=1mi=1m(x(i))2 \sigma^2 = \frac{1}{m}\sum^m_{i=1}(x^{(i)})^2

它是一个向量,X是所有训练集组成的矩阵,通过零均值后再令X/=σ2X/=\sigma^2,经过归一化方差,训练集的分布如下图:
第三周:超参数调试、Batch正则化和程序框架
为什么要这么做能够加快训练速度?
从损失函数J说起,代价函数如下:
J(w,b)=1mi=1mL(y^(i),y(i)) J(w,b) = \frac{1}{m}\sum^m_{i=1}L(\widehat{y}^{(i)},y^{(i)})

如果没有进行归一化操作,代价函数细长狭窄,如图:
第三周:超参数调试、Batch正则化和程序框架
在这样的代价函数上运行梯度下降,必须使用一个非常小的学习率。因此梯度下降法可能需要多次迭代过程,直到找到最小值。

而如果使用了归一化特征,代价函数呈现球形轮廓,如图:
第三周:超参数调试、Batch正则化和程序框架
这种情况下,不论从哪个位置开始,梯度下降法都能够直接地找到最小值,也可使用较大步长。

Batch归一化

如果我们只对输入的数据进行归一化,却没有在中间层进行归一化处理,随着深度网络的多层运算后,数据分布的变化将越来越大,因此对任何一个隐藏层而已,我们想归一化a值,比如a[2]a^{[2]}的值(但可以是任何隐藏层的),以更快的速度训练w[3]b[3]w^{[3]},b^{[3]},因为a[2]a^{[2]}是下一层的输入值,所以会影响w[3]b[3]w^{[3]},b^{[3]}的训练,这就是Batch归一化的作用。严格来说,我们真正归一化的不是a[2]a^{[2]}而是z[2]z^{[2]}。实践中,默认选择:归一化z[2]z^{[2]}

Batch归一化的作用是:(具体见3.5节)

  1. 适用的归一化过程,不只是输入层,同样适用于神经网络中的深度隐藏层
  2. Batch归一化,使得参数搜索问题更容易,神经网络对超参数的选择更加稳定。

主要计算方公式如下:
(1) 求上一层输出数据的均值:
μ=1mi=1mz(i) \mu = \frac{1}{m}\sum^{m}_{i=1}z^{(i)}

(2) 求上一层输出数据的方差:
σ2=1mi=1m(z(i)μ)2 \sigma^2 = \frac{1}{m}\sum^{m}_{i=1}(z^{(i)}-\mu)^2

(3) 归一化处理,减去均值再除以标准差:
znorm(i)=ziμσ2+ε z^{(i)}_{norm}=\frac{z^{i}-\mu}{\sqrt{\sigma^2+\varepsilon}}

为了使数值稳定,通常将ε\varepsilon作为分母,以防σ=0\sigma=0的情况。

所以z的每一个分量都含有平均值0和方差1,但我们不想让隐藏单元总是含有平均值0和方差1,也许隐藏单元有了不同的分布会有意义,所以我们对上面归一化处理得到的数据进行重构,得到如下式子:
z~(i)=γznorm(i)+β \widetilde{z}^{(i)}=\gamma z^{(i)}_{norm} + \beta

这里γβ\gamma和\beta都是你的模型的学习参数,可以使用梯度下降或其他类似梯度下降的方法更新γβ\gamma和\beta

你可以随意设置z~(i)\widetilde{z}^{(i)}的值。若γ=σ2+εβ=μ\gamma=\sqrt{\sigma^2+\varepsilon},\beta=\mu,那么γβ\gamma和\beta的作用在于,它会精确转化这个方程,即z~(i)=z(i)\widetilde{z}^{(i)}=z^{(i)}

通过对γβ\gamma和\beta合理设定,规范化过程(即上述四个等式),从根本来说,只是计算恒等函数,通过赋予γ\gammaβ\beta其他值,可以使你构造含有其他平均值和方差的隐藏单元值。

应用了Batch归一化过程,**训练输入和这些隐藏单元值的区别:**隐藏单元值不是必须平均值为0,方差1。均值和方差由γβ\gamma和\beta控制。

3.5将Batch Norm拟合进神经网络

具体计算方法如图:

第三周:超参数调试、Batch正则化和程序框架
每一层都一次执行下面的计算过程:

μ=1mi=1mz(i) \mu = \frac{1}{m}\sum^{m}_{i=1}z^{(i)}

σ2=1mi=1m(z(i)μ)2 \sigma^2 = \frac{1}{m}\sum^{m}_{i=1}(z^{(i)}-\mu)^2

znorm(i)=ziμσ2+ε z^{(i)}_{norm}=\frac{z^{i}-\mu}{\sqrt{\sigma^2+\varepsilon}}

z~(i)=γznorm(i)+β \widetilde{z}^{(i)}=\gamma z^{(i)}_{norm} + \beta

即对每一个隐藏层的输入进行归一化计算,将归一化的结果作为**函数的输入,最终得到计算结果。

Batch归一化作用:

  1. 通过归一化所有的输入特征值x,以获取类似范围的值,可以加速学习。

  2. 如果数据分布发生改变,我们可能需要重新训练学习算法来拟合新的数据分布,Batch归一化做的是减少了这些隐藏值分布变化的数量,Batch归一化确保了无论其如何改变,其均值和方差将保持不变。

  3. 减少了输入值改变的问题,使得所有的输入值更稳定,神经网络的所有隐藏层的输入更稳定,它减弱了前层参数的作用与后层参数的作用之间的联系,使得网络每层都可以自己学习,稍稍独立于其他层,有助于加速整个网络的学习。

  4. Batch归一化有轻微的正则化效果。

3.7测试时的Batch Norm

在测试时需要对每个样本逐一处理。方法是根据你的训练集估算μσ2\mu和\sigma^2

为了将神经网络运用于测试,就需要单独估算μσ2\mu和\sigma^2,在典型的Batch归一化运用中,需要用一个指数加权平均来估算,这个平均数涵盖了所有mini-batch。

我们选择在第ll,假设我们有mini-batch
X[1],X[2],X[3], X^{[1]}, X^{[2]}, X^{[3]},\cdots

那么在为ll层训练时,训练第一个mini-batch,第二个mini-batch,第三个mini-batch,…,第m个mini-batch,在第ll层得到m个不同的mini-batch数据所计算的不同的z均值(每个mini-batch对应一个均值)如下:
μ{1}[l],μ{2}[l],μ{3}[l], \mu^{\{1\}[l]},\mu^{\{2\}[l]},\mu^{\{3\}[l]},\cdots

计算第ll层的m个均值的指数加权平均,这个指数加权平均就成了这一隐藏层的z均值的估值。

同理,用指数加权平均来追踪第ll层的第一个mini-batch中所见的σ2\sigma^2的值,以及第二个mini-batch中所见的σ2\sigma^2的值等等,然后计算出第llσ2\sigma^2的指数加权平均

因此在用不同的mini-batch训练神经网络的同时,能够得到你所查看的每一层μ\muσ2\sigma^2的平均数的实时数值

最后在测试时:

通过上述计算,将神经网络模型的所有层上的指数加权平均数μ,σ2\mu, \sigma^2计算出来,将测试集z带入下面的公式进行测试:
znorm(i)=ziμσ2+ε z^{(i)}_{norm}=\frac{z^{i}-\mu}{\sqrt{\sigma^2+\varepsilon}}

z~(i)=γznorm(i)+β \widetilde{z}^{(i)}=\gamma z^{(i)}_{norm} + \beta

注:εβγ\varepsilon、\beta、\gamma为神经网络模型已经训练好的参数。

总结
在测试时,首先根据训练集获得不同mini-batch的μ\muσ2\sigma^2,然后计算指数加权平均数 ,然后在测试中使用μ\muσ2\sigma^2的指数加权平均数来进行你所需要的隐藏单元z值的调整。