本周主要学习超参数的系统调整,批量归一化和深度学习框架的相关知识。
超参数的调整
调参的优先级
- 第一优先级:学习率 $\alpha$
- 第二优先级:动量算法参数 $\beta$ (默认值0.9),最小批的个数 mini-batch size,每层的隐藏单元数 hidden units
- 第三优先级:神经网络的层数 layers,学习率衰减 learning rate decay
- 几乎不需要调优:Adam 算法中的 $\beta_1,\beta_2,\varepsilon$,几乎每次只用默认值 $0.9,0.999,10^{-8}$
调参的注意事项
随机取样
当需要调整多个超参数时,尽量在网格中随机取样(下图右),而不是规则抽样(下图左)
由于你不知道两个参数哪个更加重要,需要更多尝试。我们先假设超参数 1 更加重要:如果是左边的规则取样,那么即使取样 25 个点,实际上只尝试到了 5 个参数 1 的值,如果像右边那样随机取样,那么就可以尝试到 25 个参数 1 的值,而超参数 2 的值对结果影响并不大,所以随机取样更加合理。
如果同时要选择三个超参数,那么就在三维空间中随机取样。
区域定位的抽样方案
假设在上图的超参数样本空间中发现右下角那三个打圈的点表现更好,那么接下来对这些点所在的区域进行限定,然后在这个区域进行密度更高的随机抽样,如下图所示。
采用合适的尺度
假设现在需要调整学习率 $\alpha$,我们认为它的是一个 0.0001~1 之间的一个值,在数轴上画出它的范围:
如果我们在这个之间随机取样,如下图,那么将会有 90% 的样本落在 0.1~1 之间,只有 10% 的样本落在 0.001~0.1 之间,这明显是不合理的。
正确的方法应该是使用“对数尺度”而不是“线性尺度”来进行取样,即将数轴变成对数数轴,分成 0.0001、0.001、0.01、0.1、1 这几个部分,在每个部分之间进行均匀取样。
假设我们要在线性尺度的 a,b 两点之间取样, 那么就需要在对数尺度 $log_{10}^a$ 和 $log_{10}^b$ 之间进行均匀取样得到 $r$ ,那么对应的超参数就是 $10^r$.
假设现在我们要取样的是动量算法参数 $\beta$,它的合适范围在 0.9~0.999,我们可以先取样 $1-\beta$,它对应的范围在 0.1~0.001。使用上述方法取样得到 r,则最后的超参数为 $\beta=1-10^{r}$ .
随着 $\beta$ 趋近于 1 ,其结果对于 $\beta$ 的改变非常敏感,例如 $\beta$ 从0.9 变成 0.9005 这没什么大不了,结果几乎不变,但是如果 $\beta$ 从 0.999 变成 0.9995,它将会对你正在运行的算法产生巨大的影响,即:在 $\beta$ 趋近于 1 的时候,你能得到更高效的样本分布,搜索超参数时更有效率。
两者超参数搜索策略
熊猫模式
精心照料某个单一的模型,通常你需要处理一个非常庞大的数据集,但没有充足的计算资源,比如没有很多CPU 没有很多GPU,那你只能一次训练一个或者非常少量的模型,这种情况下 即使枯燥的训练你也要盯着,每天都在照看你的模型,尝试微调参数,就像一个母亲一样每天精心照料着你的模型,即使是在好几天甚至几周的训练过程中都不离不弃,照看着模型,观察性能曲线,耐心地微调学习率,这通常发生在你没有足够的计算资源同时训练几个模型的情况下。就像熊猫产子一样,数量稀少,经常一次一个,但是会投入全部精力,确保孩子平安无事。
鱼子酱模式
并行训练许多个模型,这种情况下你可能设置一些超参数,然后让模型自己运行一天或几天,与此同时,你可能会使用完全不同的超参数,开始运行另一个不同的模型,同时,你可能开始训练第三个模型,你会同时运行许多不同的模型,用这样的方式,你就可以尝试不同的超参数设置。这可以让超参数选择变得简单,只要找一个最终结果最好的就行了。这更像鱼类的行为,为了简单易懂,称之为鱼子酱策略,有许多鱼在交配季节能产下一亿枚卵,然后无需投入太多精力去照看某个鱼卵,只希望其中一个或者一部分能够存活。
如何挑选合适的模式?取决于你有多少计算资源,如果你有足够的计算机来并行训练很多模型,那不用考虑别的,采用鱼子酱模式就行了,尝试大量不同的超参数,看看结果如何。但在某些应用领域,例如在线广告设置以及计算机视觉识别,都有海量的数据和大量的模型需要去训练,而同时训练大量模型是极其困难的事情,这时只能采用熊猫模式。
批量归一化 (Batch Normalization)
批量归一化可以使得你的超参数搜索变得简单,即神经网络对于超参数的选择不再那么敏感,让你更容易训练非常深的网络。
概况
之前在第二周第一课中提到对训练集的归一化,先求训练集的均值,再求训练集的方差,将训练集每个数据减去均值再处以标准差就对其进行了归一化操作。可以让代价函数从一个扁圆变成一个正圆形,提高梯度下降的效率。
上述只适用于没有隐藏层的逻辑回归,如果是一个层数更多的模型呢?每一层的输出又是下一层的输入,那么我们就需要将每一层的输入都进行归一化操作,否则该层以后的训练都不会很有效率。对任何一个隐藏层的输入进行归一化操作就叫做批量归一化 BN。
对于输入是在激活函数之前做归一化还是在之后做归一化存在争议,一般来说:对线性值 z 进行归一化,也就是在激活之前进行归一化。
批量归一化的实现
下面是在神经网络某一层的实现过程:
$\mu = \frac{1}{m} \sum\limits _i z^{(i)} \leftarrow 求数据的均值\\ \sigma^2 = \frac{1}{m}\sum\limits _i (z^{(i)-\mu^{}})^2 \leftarrow 求数据的方差\\ z_{norm}^{(i)}=\frac{z^{(i)}-\mu}{\sqrt{\sigma^2+\varepsilon}} \leftarrow 将数据归一化为正态分布\\ \tilde{z}^{(i)}=\gamma z_{norm}^{(i)}+\beta \leftarrow 变换尺度,使得数据有可控的方差和均值$
- 其中 $\gamma,\beta$ 是模型的参数,可以从反向传播中学习,使用梯度下降来更新它们
- $\varepsilon$ 是一个很小的数防止分母为零
在整个神经网络上如何实现?以下面的神经网络为例。
对于每个小批次,都做如下的操作:
有效参数:$W^{[l]},\gamma^{[2]},\beta^{[l]}$
之所以参数没有 b,是因为在进行归一化时,参数 b 在均值中被减掉,所以永远是零,于是我们的前向传播算法变为
$z^{[l]}=W^{[l]}a^{[l-1]} \\ z_{norm}^{[l]}=\frac{z^{[l]}-\mu^{[l]}}{\sqrt{ {\sigma^2}^{[l]}+\varepsilon}} \\ \tilde{z}^{[l]}=\gamma^{[l]} z_{norm}^{[l]}+\beta^{[l]}$
其中参数 $z^{[l]},z_{norm}^{[l]},\tilde{z}^{[l]},\gamma^{[l]},\beta^{[l]}$ 的维度都是 $(n^{[l]},1)$
批量归一化的小批量梯度下降的实现过程:
$for \quad t=1…num_minibatch:\\ \quad \quad 计算第 t 批次的前向传播\\ \quad \quad \quad \quad 在隐藏层中进行归一化,用 \tilde{z}^{[l]}代替z^{[l]} \\ \quad \quad 用反向传播计算 dW^{[l]},d\beta^{[l]},d\gamma^{[l]} (没有 db^{[l]})\\ \quad \quad 更新参数 W^{[l]}:=W^{[l]}-\alpha dW^{[l]} \\ \quad \quad \quad \quad \quad \quad \beta^{[l]}:=\beta^{[l]}-\alpha d\beta^{[l]} \\ \quad \quad \quad \quad \quad \quad \gamma ^{[l]}:=\gamma^{[l]}-\alpha d\gamma^{[l]}$
为什么 BN 如此有效
协变量
首先要提到协变量 (Covariate),什么是协变量?它与自变量是相对的。
自变量:指研究者主动操纵,而引起因变量发生变化的因素或条件,因此自变量被看作是因变量的原因。在机器学习中,训练的模型可以称之为自变量。
协变量:在实验的设计中,协变量是一个独立变量(解释变量),不为实验者所操纵,但仍影响响应。在机器学习中,模型的输入变量是协变量。
协变量偏移 (Covariate Shift)
假设我们用左边黑猫的图片训练了一个逻辑回归模型,则训练的模型是自变量,而输入的数据是协变量。因为黑猫和黄猫的颜色深浅明显是不同的,输入数据分布发生了改变,也就是说发生了协变量偏移 (Covariate Shift),所以我们不能指望这个模型可以适用于右边的猫的图片。
即使两个完全一样的模型,如果输入变量的分布不同,得到的结果也会有很大差异,所以机器学习算法都要求输入变量在训练集和测试集上的分布是相似的。如果训练了一个模型,然而输入 x 的分布发生了变化,那么我们就得重新训练模型。
神经网络中的内部协变量偏移 (Internal Covariate Shift)
在上面这个神经网络中,第二层的激活值可以当作这一层后面的神经网络的输入,从而影响第三第四第五层的参数的值,那么它就是这个神经网络的内部协变量,但是它的值并不是一成不变的,它又是前面的神经网络的参数所决定,这些参数不停地更新,导致第二层的值不停在改变,从而发生了内部协变量偏移 (Internal Covariate Shift)。
BN 的作用
批量归一化将每个隐藏单元的输入进行归一化,减少了隐藏单元值分布的不稳定性,虽然这些隐藏结点的值会发生变化,但是 BN 算法确保无论它怎么变化,它的均值和方差将保持不变,所以限制了先前层中参数的更新对后面的网络的输入的影响,使后层神经网络有更加稳固的基础,从而提高整个网络的学习速度。
在 BN 中,由于每个小批次都被那一批次的均值和方差归一化,因为我们在该 min-batch 上计算了均值和方差,而不是在整个数据集上计算,所以该均值和方差包含有噪声,所以某个 $\tilde z$ 也会有噪声,就像 dropout 给隐藏层增加噪声一样,所以 BN 会有轻微的正则化效果,但是它不是一个正则化方法。
多分类问题
多分类问题概况
假设我们要将图片分为四类,则不同的类别用不同的数字代表,比如 1 是小鸡,2 是小猫,3 是小狗,0 是其他动物,则这是一个多分类问题,分类的类别用 C 表示,在这里 C = 4.
解决这类问题,只需要将神经网络的输出层单元数变成 4,即 $n^{[L]}=4=C$,第一个单元表示图片是小鸡的概率,第二个单元表示图片是小猫的概率,第三个单元表示图片是小狗的概率,第四个单元表示图片是其他的概率,输出向量 $\hat y$ 的维度为 (4,1).
softmax 层的前向传播
第 L 层为输出层,这一层也叫 softmax 层,这一层的运算如下:
$z^{[L]}=W^{[L]}a^{[l-1]}+b^{[L]} \\ 激活函数:\\ t=e^{(z^{[L]})} \\ \hat y = a^{[L]}=\frac{t}{\sum\limits _{i=1}^4 t_i},a^{[L]}_i=\frac{t_i}{\sum\limits _{i=1}^4 t_i}$
- $z^{[L]},t,\hat y$ 的维度都是 (4,1) 向量
- i 代表第 L 的第 i 个结点
把上面的运算当成一个激活函数:
- softmax() 输入一个向量,输出一个尺寸一样的向量
下面是在逻辑回归中将输入通过 softmax 的线性分类结果:
那么 softmax 的实质是什么?
实际上 softmax 将一组向量映射成了它们的概率向量,这组向量中某个值越大,它通过 softmax 映射的概率值就越大。与 softmax 对应的是 hardmax,它也是将输入向量映射为另一个向量,但它是直接找出输入向量的最大值并将它置为 1,其他置为 0,非常简单粗暴,而 softmax 的映射就更加平和。同时 softmax 将逻辑回归中的二分类推广到 C分类,也就是多分类,当 C=2 的时候,softmax 就简化为逻辑回归。
softmax 的代价函数
假设某个样本的标签值 $y=\begin{bmatrix} 0\\1\\0\\0 \end{bmatrix}$,预测值 $\hat y=\begin{bmatrix} 0.3\\0.2\\0.1\\0.4 \end{bmatrix}$,用下列公式计算单个样本代价函数:
所有样本的总代价函数为:
- 实际上 $y,\hat y$ 应该是 $Y,\hat Y$ ,是一个维度为 (C,m)的矩阵
简单的证明:因为 $y_2=1,y_1=y_3=y_4=0$,则 $L(\hat y,y)=-\sum\limits_{j=1}^4 y_jlog\hat y_j=-y_2log \hat y_2=-log \hat y_2$,假设代价函数越小,则 $log \hat y_2$ 越大,则 $\hat y_2$ 越大,则图片的标签值为 2 的概率越大,而这张图片的实际标签值就是 2。于是我们建立逻辑链条:代价函数越小 $\rightarrow$ 预测这张图片标签值是 2 的概率 $\hat y_2$ 越大 $\rightarrow$ 图片真实标签值就是 2 $\rightarrow$ 越符合实际情况 $\rightarrow$ 模型预测越准确
softmax 的反向传播
初始化公式为:
- 其中 $dz^{[L]},\hat y,y$ 都是 (C,1)的向量