训练深度最难的事情之一是参数的数量。
结果证实一些超参数比其它的更为重要,我认为,最为广泛的学习应用是 a a a,学习速率是需要调试的最重要的超参数。
除了 a a a,还有一些参数需要调试,例如Momentum参数 β \beta β,0.9就是个很好的默认值,还有mini-batch的大小,以确保最优算法运行有效。
超参数有重要性区别。 a a a无疑是最重要的,接下来是用橙色圈住的那些,然后是用紫色圈住的那些,但这不是严格且快速的标准。
选择调试值: 在早一代的机器学习算法中,有两个超参数时常在网格中取样点,然后系统的研究这些数值。如5×5的网格,实践证明,网格可以是5×5,也可多可少,但对于这个例子,你可以尝试这所有的25个点,然后选择哪个参数效果最好。当参数的数量相对较少时,这个方法很实用。
在深度学习领域,常常随机选择点来调整。
给超参数取值时,另一个惯例是采用从粗到细的搜索:比如在二维的那个例子中,发现效果最好的某个点,接下来要做的是放大这块小区域(小蓝色方框内),然后在其中更密集得取值或随机取值,在这个蓝色的方格中搜索。
看看这个例子,假设你在搜索超参数 a a a(学习速率),假设你怀疑其值最小是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,在对数轴上均匀随机取点,这样,在0.0001到0.001之间,就会有更多的搜索资源可用。
所以在Python中,使r=-4*np.random.rand()
,然后 a a a随机取值, a = 1 0 r a =10^{r} a=10r,所以, r ∈ [ 4 , 0 ] r \in [ 4,0] r∈[4,0], a ∈ [ 1 0 − 4 , 1 0 0 ] a \in[10^{-4},10^{0}] a∈[10−4,100],最左边的数字是 1 0 − 4 10^{-4} 10−4,最右边是 1 0 0 10^{0} 100。
即,在对数坐标下取值, a a a为最小值的对数, b b b为最大值的对数,在 a a a, b b b间随意均匀的选取 r r r值,将超参数设置为 1 0 r 10^{r} 10r。
另一个棘手的例子是给 β \beta β 取值,用于计算指数的加权平均值。假设 β \beta β是0.9到0.999之间的某个值,也许这就是你想搜索的范围。
如果在0.9到0.999区间搜索,那就不能用线性轴取值。考虑这个问题最好的方法就是探究 1 − β 1-\beta 1−β,此值在0.1到0.001区间内。
β \beta β值如果在0.999到0.9995之间,这会对算法产生巨大影响,对吧?在这两种情况下,是根据大概10个值取平均。但这里,它是指数的加权平均值,基于1000个值,现在是2000个值,因为这个公式 1 1 − β \frac{1}{1- \beta} 1−β1,当 β \beta β接近1时, β \beta β就会对细微的变化变得很敏感。所以整个取值过程中,需要更加密集地取值,在 β \beta β 接近1的区间内,或者说,当 1 − β 1-\beta 1−β 接近于0时,这样,你就可以更加有效的分布取样点,更有效率的探究可能的结果。
如何搜索超参数?
babysit一个模型,通常是有庞大的数据组,但没有许多计算资源或足够的CPU和GPU的前提下,可以逐渐改良,观察它的表现,耐心地调试学习率,但那通常是因为没有足够的计算能力,不能在同一时间试验大量模型时才采取的办法。
同时试验多种模型。设置了一些超参数,尽管让它自己运行,或者是一天甚至多天。
Batch归一化:
归一化输入特征可以加快学习过程。
一般归一化 z ( i ) z^{(i)} z(i)。减去均值再除以标准偏差,为了使数值稳定,通常将 ε \varepsilon ε作为分母,以防 σ = 0 σ=0 σ=0的情况。
所以现在 z z z的每一个分量都含有平均值0和方差1,但也许隐藏单元有了不同的分布会有意义,所以 z ~ ( i ) = γ z norm ( i ) + β {\tilde{z}}^{(i)}= \gamma z_{\text{norm}}^{(i)} +\beta z~(i)=γznorm(i)+β这里 γ \gamma γ和 β \beta β是学习参数,作用是设置 z ~ ( i ) {\tilde{z}}^{(i)} z~(i)的平均值。
如果 γ = σ 2 + ε \gamma= \sqrt{\sigma^{2} +\varepsilon} γ=σ2+ε ,如果 γ \gamma γ等于这个分母项( z norm ( i ) = z ( i ) − μ σ 2 + ε z_{\text{norm}}^{(i)} = \frac{z^{(i)} -\mu}{\sqrt{\sigma^{2} +\varepsilon}} znorm(i)=σ2+ε z(i)−μ中的分母), β \beta β等于 μ \mu μ,这里的这个值是 z norm ( i ) = z ( i ) − μ σ 2 + ε z_{\text{norm}}^{(i)}= \frac{z^{(i)} - \mu}{\sqrt{\sigma^{2} + \varepsilon}} znorm(i)=σ2+ε z(i)−μ中的 μ \mu μ,那么 γ z norm ( i ) + β \gamma z_{\text{norm}}^{(i)} +\beta γznorm(i)+β的作用在于,它会精确转化这个方程,如果这些成立( γ = σ 2 + ε , β = μ \gamma =\sqrt{\sigma^{2} + \varepsilon},\beta =\mu γ=σ2+ε ,β=μ),那么 z ~ ( i ) = z ( i ) {\tilde{z}}^{(i)} = z^{(i)} z~(i)=z(i)。
通过对 γ \gamma γ和 β \beta β合理设定,规范化过程,即这四个等式,从根本来说,只是计算恒等函数,通过赋予 γ \gamma γ和 β \beta β其它值,可以构造含其它平均值和方差的隐藏单元值。
神经网络中,每个单元负责计算计算z,然后应用其到**函数中再计算a,每个圆圈代表着两步的计算过程。
如果你没有应用Batch归一化,你会把输入 X X X拟合到第一隐藏层,然后首先计算 z [ 1 ] z^{[1]} z[1],这是由 w [ 1 ] w^{[1]} w[1]和 b [ 1 ] b^{[1]} b[1]两个参数控制的。接着,通常而言,你会把 z [ 1 ] z^{[1]} z[1]拟合到**函数以计算 a [ 1 ] a^{[1]} a[1]。但Batch归一化的做法是将 z [ 1 ] z^{[1]} z[1]值进行Batch归一化,简称BN,此过程将由 β [ 1 ] {\beta}^{[1]} β[1]和 γ [ 1 ] \gamma^{[1]} γ[1]两参数控制,这一操作会给你一个新的规范化的 z [ 1 ] z^{[1]} z[1]值( z ~ [ 1 ] {\tilde{z}}^{[1]} z~[1]),然后将其输入**函数中得到 a [ 1 ] a^{[1]} a[1],即 a [ 1 ] = g [ 1 ] ( z ~ [ l ] ) a^{[1]} = g^{[1]}({\tilde{z}}^{[ l]}) a[1]=g[1](z~[l])。
Batch归一化是发生在计算 z z z和 a a a之间的。直觉就是,与其应用没有归一化的 z z z值,不如用归一过的 z ~ \tilde{z} z~,这是第一层( z ~ [ 1 ] {\tilde{z}}^{[1]} z~[1])。所以网络的参数就会是 w [ 1 ] w^{[1]} w[1], b [ 1 ] b^{[1]} b[1], w [ 2 ] w^{[2]} w[2]和 b [ 2 ] b^{[2]} b[2]等等,我们将要去掉这些参数。但现在,想象参数 w [ 1 ] w^{[1]} w[1], b [ 1 ] b^{[1]} b[1]到 w [ l ] w^{[l]} w[l], b [ l ] b^{[l]} b[l],我们将另一些参数加入到此新网络中 β [ 1 ] {\beta}^{[1]} β[1], β [ 2 ] {\beta}^{[2]} β[2], γ [ 1 ] \gamma^{[1]} γ[1], γ [ 2 ] \gamma^{[2]} γ[2]等等。对于应用Batch归一化的每一层而言。
接下来可以使用优化算法。
实践中,Batch归一化通常和训练集的mini-batch一起使用。
一个细节: z [ l ] = w [ l ] a [ l − 1 ] + b [ l ] z^{[l]} =w^{[l]}a^{\left\lbrack l - 1 \right\rbrack} +b^{[l]} z[l]=w[l]a[l−1]+b[l],将 z [ l ] z^{[l]} z[l]归一化,结果为均值0和标准方差,再由 β \beta β和 γ \gamma γ重缩放。但这意味着,无论 b [ l ] b^{[l]} b[l]的值是多少,都是要被减去的。所以,在使用Batch归一化时,其实你可以消除这个参数( b [ l ] b^{[l]} b[l]),或暂时把它设置为0。
那么,参数变成 z [ l ] = w [ l ] a [ l − 1 ] z^{[l]} = w^{[l]}a^{\left\lbrack l - 1 \right\rbrack} z[l]=w[l]a[l−1], z ~ [ l ] = γ [ l ] z [ l ] + β [ l ] {\tilde{z}}^{[l]} = \gamma^{[l]}z^{[l]} + {\beta}^{[l]} z~[l]=γ[l]z[l]+β[l]。
最后,请记住 z [ l ] z^{[l]} z[l]的维数,因为在这个例子中,维数会是 ( n [ l ] , 1 ) (n^{[l]},1) (n[l],1), b [ l ] b^{[l]} b[l]的尺寸为 ( n [ l ] , 1 ) (n^{[l]},1) (n[l],1),如果是l层隐藏单元的数量,那 β [ l ] {\beta}^{[l]} β[l]和 γ [ l ] \gamma^{[l]} γ[l]的维度也是 ( n [ l ] , 1 ) (n^{[l]},1) (n[l],1)。
关于如何用Batch归一化来应用梯度下降法:(假设使用mini-batch梯度下降法,运行 t = 1 t=1 t=1到batch数量的for循环)
*covariate shift: 已经学习了 x x x到 y y y 的映射,则 x x x 的分布改变了后可能需要重新训练你的学习算法。
Batch归一化做的,是它减少了这些隐藏值分布变化的数量。Batch归一化可以确保无论其怎样变化 z 1 [ 2 ] z_{1}^{[2]} z1[2], z 2 [ 2 ] z_{2}^{[2]} z2[2]的均值和方差保持不变,所以即使 z 1 [ 2 ] z_{1}^{[2]} z1[2], z 2 [ 2 ] z_{2}^{[2]} z2[2]的值改变,至少他们的均值和方差是由 β [ 2 ] {\beta}^{[2]} β[2]和 γ [ 2 ] \gamma^{[2]} γ[2]决定的值。它限制了在前层的参数更新,会影响数值分布的程度,第三层看到的这种情况,因此得到学习。它减弱了前层参数的作用与后层参数的作用之间的联系,它使得网络每层都可以自己学习,稍稍独立于其它层,这有助于加速整个网络的学习。
在测试时可能需要对每个样本逐一处理。
在训练时,这些就是用来执行Batch归一化的等式。用于调节计算的 μ \mu μ和 σ 2 \sigma^{2} σ2是在整个mini-batch上进行计算,但是在测试时,需要用其它方式来得到 μ \mu μ和 σ 2 \sigma^{2} σ2。一个样本的均值和方差没有意义。
那么就需要单独估算 μ \mu μ和 σ 2 \sigma^{2} σ2,在典型的Batch归一化运用中,你需要用一个指数加权平均来估算,这个平均数涵盖了所有mini-batch。
选择 l l l层,假设我们有mini-batch, X [ 1 ] X^{[1]} X[1], X [ 2 ] X^{[2]} X[2], X [ 3 ] X^{[3]} X[3]……以及对应的 y y y值等等,那么在为 l l l层训练 X 1 X^{{ 1}} X1时,你就得到了 μ [ l ] \mu^{[l]} μ[l]( μ [ l ] → μ { 1 } [ l ] \mu^{[l]} \rightarrow \mu^{\{1 \}[l]} μ[l]→μ{1}[l])。当你训练第二个mini-batch,在这一层和这个mini-batch中,你就会得到第二个 μ \mu μ( μ 2 [ l ] \mu^{{2}[l]} μ2[l])值。然后在这一隐藏层的第三个mini-batch,你得到了第三个 μ \mu μ( μ { 3 } [ l ] \mu^{\{3 \}[l]} μ{3}[l])值。正如我们之前用的指数加权平均来计算 θ 1 \theta_{1} θ1, θ 2 \theta_{2} θ2, θ 3 \theta_{3} θ3的均值,当时是试着计算当前气温的指数加权平均,你会这样来追踪你看到的这个均值向量的最新平均值,于是这个指数加权平均就成了对这一隐藏层的 z z z均值的估值。同样的,你可以用指数加权平均来追踪你在这一层的第一个mini-batch中所见的 σ 2 \sigma^{2} σ2的值,以及第二个mini-batch中所见的 σ 2 \sigma^{2} σ2的值等等。
因此在用不同的mini-batch训练神经网络时,能够得到所查看的每一层的 μ \mu μ和 σ 2 \sigma^{2} σ2的平均数的实时数值。
最后在测试时,对应这个等式( z norm ( i ) = z ( i ) − μ σ 2 + ε z_{\text{norm}}^{(i)} = \frac{z^{(i)} -\mu}{\sqrt{\sigma^{2} +\varepsilon}} znorm(i)=σ2+ε z(i)−μ),你只需要用你的 z z z值来计算 z norm ( i ) z_{\text{norm}}^{(i)} znorm(i),用 μ \mu μ和 σ 2 \sigma^{2} σ2的指数加权平均,用你手头的最新数值来做调整,然后你可以用左边我们刚算出来的 z norm z_{\text{norm}} znorm和你在神经网络训练过程中得到的 β \beta β和 γ \gamma γ参数来计算你那个测试样本的 z ~ \tilde{z} z~值。
总结一下就是,在训练时, μ \mu μ和 σ 2 \sigma^{2} σ2是在整个mini-batch上计算出来,但在测试时需要逐一处理样本,方法是根据训练集估算 μ \mu μ和 σ 2 \sigma^{2} σ2,理论上你可以在最终的网络中运行整个训练集来得到 μ \mu μ和 σ 2 \sigma^{2} σ2,但在实际操作中,通常运用指数加权平均来追踪在训练过程中你看到的 μ \mu μ和 σ 2 \sigma^{2} σ2的值。
假设你算出了 z [ l ] z^{[l]} z[l], z [ l ] z^{[l]} z[l]是一个四维向量,假设为 z [ l ] = [ 5 2 − 1 3 ] z^{[l]} = \begin{bmatrix} 5 \\ 2 \\ - 1 \\ 3 \ \end{bmatrix} z[l]=⎣⎢⎢⎡52−13 ⎦⎥⎥⎤,我们要做的就是用这个元素取幂方法来计算 t t t,所以 t = [ e 5 e 2 e − 1 e 3 ] = [ 148.4 7.4 0.4 20.1 ] t =\begin{bmatrix} e^{5} \\ e^{2} \\ e^{- 1} \\ e^{3} \ \end{bmatrix} = \begin{bmatrix} 148.4 \\ 7.4 \\ 0.4 \\ 20.1 \\ \end{bmatrix} t=⎣⎢⎢⎡e5e2e−1e3 ⎦⎥⎥⎤=⎣⎢⎢⎡148.47.40.420.1⎦⎥⎥⎤,我们从向量 t t t得到向量 a [ l ] a^{[l]} a[l]就只需要将这些项目归一化,使总和为1。如果你把 t t t的元素都加起来,把这四个数字加起来,得到176.3,最终 a [ l ] = t 176.3 a^{[l]} = \frac{t} {176.3} a[l]=176.3t, 输出 a [ l ] a^{[l]} a[l],也就是 y ^ \hat y y^,是一个4×1维向量,这个4×1向量的元素就是我们算出来的这四个数字( [ 0.842 0.042 0.002 0.114 ] \begin{bmatrix} 0.842 \\ 0.042 \\ 0.002 \\ 0.114 \\ \end{bmatrix} ⎣⎢⎢⎡0.8420.0420.0020.114⎦⎥⎥⎤),所以这种算法通过向量 z [ l ] z^{[l]} z[l]计算出总和为1的四个概率。
之前**函数都是接受单行数值输入, Softmax**函数的特殊之处在于,因为需要将所有可能的输出归一化,就需要输入一个向量,最后输出一个向量。
那么Softmax分类器还可以代表其它的什么东西么?
这个例子中(左边图),原始输入只有 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回归或Softmax**函数将logistic**函数推广到 C C C类,而不仅仅是两类,如果 C = 2 C=2 C=2,那么 C = 2 C=2 C=2的Softmax实际上变回了logistic回归。
先定义训练神经网络使会用到的损失函数。举个例子某个样本目标输出真实标签是 [ 0 1 0 0 ] \begin{bmatrix} 0 \\ 1 \\ 0 \\ 0 \\ \end{bmatrix} ⎣⎢⎢⎡0100⎦⎥⎥⎤,这表示这是一张猫的图片,因为它属于类1(我把猫加做类1,狗为类2,小鸡是类3),假设神经网络输出的是 y ^ \hat y y^, y ^ \hat y y^是一个包括总和为1的概率的向量, y = [ 0.3 0.2 0.1 0.4 ] y = \begin{bmatrix} 0.3 \\ 0.2 \\ 0.1 \\ 0.4 \\ \end{bmatrix} y=⎣⎢⎢⎡0.30.20.10.4⎦⎥⎥⎤,对于这个样本神经网络的表现不佳,这实际上是一只猫,但却只分配到20%是猫的概率。
来看上面的单个样本来更好地理解整个过程。在Softmax分类中,我们一般用到的损失函数是 L ( y ^ , y ) = − ∑ j = 1 4 y j l o g y ^ j L(\hat y,y ) = - \sum_{j = 1}^{4}{y_{j}log\hat y_{j}} L(y^,y)=−∑j=14yjlogy^j。在这个样本中 y 1 = y 3 = y 4 = 0 y_{1} =y_{3} = y_{4} = 0 y1=y3=y4=0,只有 y 2 = 1 y_{2} =1 y2=1,如果你看这个求和,所有含有值为0的 y j y_{j} yj的项都等于0,最后 L ( y ^ , y ) = − ∑ j = 1 4 y j log y ^ j = − y 2 l o g y ^ 2 = − l o g y ^ 2 L\left( \hat y,y \right) = - \sum_{j = 1}^{4}{y_{j}\log \hat y_{j}} = - y_{2}{\ log} \hat y_{2} = - {\ log} \hat y_{2} L(y^,y)=−∑j=14yjlogy^j=−y2 logy^2=− logy^2
因为梯度下降法是用来减少训练集的损失的,所以就需要使 y ^ 2 \hat y_{2} y^2尽可能大,但不可能比1大。
整个训练集的损失 J J J:
J ( w [ 1 ] , b [ 1 ] , … … ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) J( w^{[1]},b^{[1]},\ldots\ldots) = \frac{1}{m}\sum_{i = 1}^{m}{L( \hat y^{(i)},y^{(i)})} J(w[1],b[1],……)=m1∑i=1mL(y^(i),y(i))用梯度下降法,使这里的损失最小化。
最后还有一个实现细节,注意因为 C = 4 C=4 C=4, y y y是一个4×1向量, y y y也是一个4×1向量,如果你实现向量化,矩阵大写 Y Y Y就是 [ y ( 1 ) y ( 2 ) … … y ( m ) ] \lbrack y^{(1)}\text{}y^{(2)}\ldots\ldots\ y^{\left( m \right)}\rbrack [y(1)y(2)…… y(m)],例如如果上面这个样本是你的第一个训练样本,那么矩阵 Y = [ 0 0 1 … 1 0 0 … 0 1 0 … 0 0 0 … ] Y =\begin{bmatrix} 0 & 0 & 1 & \ldots \\ 1 & 0 & 0 & \ldots \\ 0 & 1 & 0 & \ldots \\ 0 & 0 & 0 & \ldots \ \end{bmatrix} Y=⎣⎢⎢⎡010000101000………… ⎦⎥⎥⎤,那么这个矩阵 Y Y Y最终就是一个 4 × m 4×m 4×m维矩阵。类似的, Y ^ = [ y ^ ( 1 ) y ^ ( 2 ) … … y ^ ( m ) ] \hat{Y} = \lbrack{\hat{y}}^{(1)}{\hat{y}}^{(2)} \ldots \ldots\ {\hat{y}}^{(m)}\rbrack Y^=[y^(1)y^(2)…… y^(m)],这个其实就是 y ^ ( 1 ) {\hat{y}}^{(1)} y^(1)( a l = y ( 1 ) = [ 0.3 0.2 0.1 0.4 ] a^{l} = y^{(1)} = \begin{bmatrix} 0.3 \\ 0.2 \\ 0.1 \\ 0.4 \\ \end{bmatrix} al=y(1)=⎣⎢⎢⎡0.30.20.10.4⎦⎥⎥⎤),或是第一个训练样本的输出,那么 Y ^ = [ 0.3 … 0.2 … 0.1 … 0.4 … ] \hat{Y} = \begin{bmatrix} 0.3 & \ldots \\ 0.2 & \ldots \\ 0.1 & \ldots \\ 0.4 & \ldots \\ \end{bmatrix} Y^=⎣⎢⎢⎡0.30.20.10.4…………⎦⎥⎥⎤, Y ^ \hat{Y} Y^本身也是一个 4 × m 4×m 4×m维矩阵。