李宏毅深度学习(五)

Task05 网络设计的技巧
本次学习基于李宏毅老师的《机器学习》课程:https://www.bilibili.com/video/BV11K4y1S7AD?p=5
笔记参照Github:https://github.com/unclestrong/DeepLearning_LHY21_Notes

1、局部最小值与鞍点

1.1 Critical Point

  在做Optimization的时候有时我们会发现,随著参数不断的更新,到一定程度不管怎样update参数,loss都掉不下去。这到底是为什么?
  这是其实就是因为我们现在走到了一个参数对loss的微分为零的地方,这时gradient descent就没有办法再update参数了,loss当然就不会再下降了。这种gradient为零的点,统称為critical point。如下图中的local minima和saddle point。
在这里插入图片描述
  那我们如何判断这个critical point到底是local minima,还是saddle point?

  • 如果是local minima,四周都比较高,现在所在的位置已经是loss最低的点了,往四周走 loss都会比较高。
  • 如果是saddle point,旁边还是有路可以使loss更低的。

  因此我们要知道loss function的形状。可是我们怎么知道loss function的形状呢?

1.2 Tayler Series Approximation

  Network本身很复杂,用复杂network算出来的loss function显然也很复杂。虽然我们无法知道loss function长什么样子,但是如果给定某一组参数,比如说蓝色的这个 θ ′ θ' θ在附近的loss function可以通过泰勒级数展开表示出来。
在这里插入图片描述
第一项 L ( θ ′ ) L(θ') L(θ)。就告诉我们说,当 θ θ θ θ ′ θ' θ很近的时候, L ( θ ) L(θ) L(θ)应该跟 L ( θ ′ ) L(θ') L(θ)还蛮靠近的。
在这里插入图片描述
第二项 ( θ − θ ′ ) T g (θ-θ')^Tg (θθ)Tg。这个绿色 g g g是一个向量,也就是我们的gradient,这个gradient会来弥补, θ ′ θ' θ θ θ θ之间的差距。
在这里插入图片描述
第三项跟Hessian有关。这个 H H H叫做Hessian,它是一个矩阵,第三项是 ( θ − θ ′ ) T H ( θ − θ ′ ) (θ-θ')^TH(θ-θ') (θθ)TH(θθ)会再补足与真正的 L ( θ ) L(θ) L(θ)之间的差距。
  总之,这个 L ( θ ) L(θ) L(θ) θ ′ θ' θ附近跟一次微分gradient有关系,,跟二次微分hessian也有关系。
  当 L ( θ ′ ) L(θ') L(θ)处在critical point,意味著gradient為零,也就是绿色的这一项完全都不见了。
在这里插入图片描述
所以我们可以根据红色包含 H H H的这一项来判断在 θ ′ θ' θ附近的error surface到底长什么样子,我们这个critical point究竟是什么样的点。

1.3 Hession

  我们来看一下怎样根据Hessian来判断 θ ′ θ' θ附近的error surface样貌。

符号方便起见,我们把 ( θ − θ ′ ) (θ-θ') (θθ) v v v这个向量来表示。

  • 如果对任何可能的 v v v v T H v v^THv vTHv都大于零,那意味着 L ( θ ) > L ( θ ′ ) L(θ)>L(θ') L(θ)>L(θ) L ( θ ) L(θ) L(θ)不管为多少,只要在 θ ′ θ' θ附近, L ( θ ) L(θ) L(θ)都大于 L ( θ ′ ) L(θ') L(θ),所以它是local minima。
  • 如果对任何可能的 v v v v T H v v^THv vTHv都小于零,那意味着 L ( θ ) < L ( θ ′ ) L(θ)<L(θ') L(θ)<L(θ)。代表 L ( θ ′ ) L(θ') L(θ)是附近最高的一个点,所以它是local maxima。
  • 如果对任何可能的 v v v v T H v v^THv vTHv有时候大于零,有时候小于零,那意味着在 θ ′ θ' θ附近,有时候 L ( θ ) > L ( θ ′ ) L(θ)>L(θ') L(θ)>L(θ),有时候 L ( θ ) < L ( θ ′ ) L(θ)<L(θ') L(θ)<L(θ),所以它是一个saddle point。
    在这里插入图片描述

  我们怎么有可能把所有的 v v v都拿来试试看呢?所以有一个更简便的方法来判断这个条件会不会发生。
在这里插入图片描述
  根据线性代数理论,如果对所有的 v v v而言, v T H v v^THv vTHv都大于零,那这种矩阵叫做positive definite正定矩阵。positive definite的矩阵,它所有的eigen value特征值都是正的。
  所以我们只要去直接看这个 H H H的eigen value特征值,如果:

  • 所有eigen value都是正的, v T H v v^THv vTHv大于零,它就是local minima。
  • 所有eigen value都是负的, v T H v v^THv vTHv小于零,它就是local maxima。
  • 如果eigen value有正有负, v T H v v^THv vTHv有正有负,它就是saddle point。

1.4 Example

  假设有一个史上最废的network,输入一个 x x x,它只有一个neuron,乘上 w ₁ w₁ w,而且这个neuron还没有activation function,所以 x x x乘上 w ₁ w₁ w以后之后就输出。然后再乘上 w ₂ w₂ w 然后就再输出就得到最终的数据就是 y y y y = w ₁ × w ₂ × x y= w₁×w₂×x y=w×w×x
  假设有一个史上最废的training set,只有一笔data,这笔data x x x=1, y y y=1。我们可以穷举所有 w ₁ w₁ w w ₂ w₂ w的数值,算出所有 w ₁ w₁ w w ₂ w₂ w数值所代来的loss,然后就画出error surface 长这个样。在这里插入图片描述
  山沟裡面,有两排local minima,原点的地方,有一个saddle point。这个是我们把error surface暴力所有的参数得到的loss function,得到的loss的值以后,画出error surface,可以得到这样的结论。
  现在假设如果不暴力所有可能的loss,如果要直接算说一个点是local minima还是saddle point的话怎么算呢?
在这里插入图片描述 我们可以把loss的function写出来: L = ( y ^ − w 1 w 2 x ) 2 L=(\hat{y}-w_1 w_2 x)^2 L=(y^w1w2x)2​正确答案 y ^ ŷ y^减掉model的输出 w ₁ w ₂ x w₁w₂x wwx,取square error,因为只有一笔data,所以就不用summation over所有的training data,所以loss function就是 L = ( y ^ − w 1 w 2 x ) 2 L=(\hat{y}-w_1 w_2 x)^2 L=(y^w1w2x)2 w ₁ w₁ w L L L的微分, w ₂ w₂ w L L L的微分写出来是这个样子: ∂ L ∂ w 1 = 2 ( 1 − w 1 w 2 ) ( − w 2 ) \frac{∂L}{∂w_1 }=2(1-w_1 w_2 )(-w_2 ) w1L=2(1w1w2)(w2) ∂ L ∂ w 2 = 2 ( 1 − w 1 w 2 ) ( − w 1 ) \frac{∂L}{∂w_2 }=2(1-w_1 w_2 )(-w_1 ) w2L=2(1w1w2)(w1)
​这个东西: [ ∂ L ∂ w 1 ∂ L ∂ w 2 ] \begin{bmatrix} \frac{∂L}{∂w_1 }\\\\\frac{∂L}{∂w_2 } \end{bmatrix} w1Lw2L​ 就是所谓的gradient。什么时候gradient会零呢?gradient为零,它是local maxima,local minima还是saddle point呢?
在这里插入图片描述
如果w₁=0 w₂=0,也就是在圆心这个地方w₁对L的微分 w₂对L的微分都是零。这个时候我们就知道说,原点就是一个critical point,但它是local maxima,它是local maxima,local minima,还是saddle point呢,那就要看hessian才能够知道了。把w₁=0 w₂=0代进去,在原点的地方,hessian是这样的一个矩阵 [ 0 − 2 − 2 0 ] \begin{bmatrix} {0}&-2\\{-2}&0 \end{bmatrix} [0220]​ 这个矩阵有两个eigen value,2和-2,eigen value有正有负,代表saddle point。

1.5 Update parameters at saddle point

如果今天你卡的地方是saddle point,也许你就不用那么害怕了,因为如果你今天你发现,你停下来的时候,是因为saddle point停下来了,那其实就有机会可以放心了。因为H它不只可以帮助我们判断saddle point,它还指出了我们参数可以update的方向。那H怎么告诉我们如何update参数呢?

假设 μ \mu μ是H的eigenvector特征向量, λ λ λ μ \mu μ的eigen value特征值。如果我们把这边的 v v v换成 μ \mu μ的话,我们把 μ \mu μ乘在H的左边,跟H的右边,也就是 μ T H μ \mu^TH\mu μTHμ, H μ H\mu Hμ会得到 λ μ λ\mu λμ,因为 μ \mu μ是一个eigen vector。H乘上eigen vector特征向量会得到特征向量λ eigen value乘上eigen vector即 λ μ λ\mu λμ
在这里插入图片描述
​所以我们得到 u ᵀ uᵀ u乘上 λ u λu λu,然后再整理一下,把 u ᵀ uᵀ u u u u乘起来,得到 ‖ u ‖ ² ‖u‖² u²,所以得到 λ ‖ u ‖ ² λ‖u‖² λu²
在这里插入图片描述

​假设 v v v代的是一个eigen vector, θ θ θ θ ′ θ' θ放的是一个eigen vector的话,会发现说我们这个红色的项其实就是 λ ‖ u ‖ ² λ‖u‖² λu²
在这里插入图片描述
如果 λ λ λ小于零,那 λ ‖ u ‖ ² λ‖u‖² λu²就会小于零,也就是红色这个框里是负的。这意思是说假设 θ − θ ′ = μ θ-θ'=\mu θθ=μ,那这一项 ( θ − θ ′ ) T H ( θ − θ ′ ) (θ-θ')^TH(θ-θ') (θθ)TH(θθ)就是负的,也就是 L ( θ ) < L ( θ ′ ) L(θ)<L(θ') L(θ)<L(θ)

所以虽然在critical point没有gradient,如果我们今天是在一个saddle point,只要找出负的eigen value,再找出它对应的eigen vector,用这个eigen vector去加 θ ′ θ' θ,就可以找到一个新的点,这个点的loss比原来还要低
举个例子:
在这里插入图片描述

2、批次与动量

2.1 Optimization with Batch

我们实际上在算微分的时候,并不是真的对所有 Data 算出来的 L 作微分,是把所有的 Data 分成一个一个的 Batch
在这里插入图片描述
每次在 Update 参数的时候,我们是拿一笔资料出来,算个 Loss,算个 Gradient,Update 参数,拿另外一笔资料,再算个 Loss,再算个 Gradient,再 Update 参数。以此类推,所以我们不会拿所有的资料一起去算出 Loss,我们只会拿一个 Batch 的资料,拿出来算 Loss。

所有的 Batch 算过一遍,叫做一个 Epoch。事实上啊,在做这些 Batch 的时候,我们会做一件事情叫做 Shuffle(随机排序)。Shuffle 有很多不同的做法,但一个常见的做法就是,在每一个 Epoch 开始之前,会分一次 Batch,每一个 Epoch 的 Batch 都不一样,就是第一个 Epoch,我们分这样子的 Batch,第二个 Epoch,会重新再分一次 Batch,这就叫做Shuffle。

2.2 Small Batch v.s. Large Batch

我们先解释为什么要用 Batch,再说 Batch 对 Training 带来了什么样的帮助。
在这里插入图片描述
我们来比较左右两边这两个 Case,那假设现在我们有20笔训练资料

  • 左边的 Case 就是没有用 Batch,Batch Size和我训练资料一样多。这种状况叫做 Full Batch,就是没有用 Batch 的意思。
  • 右边的 Case 就是Batch Size 等于1。

所以如果我们比较左边跟右边,哪一个比较好呢?
在这里插入图片描述
看起来左边的方法跟右边的方法,他们各自都有擅长跟不擅长的东西,左边是蓄力时间长,但是威力比较大,右边技能冷却时间短,但是它是比较不准。看起来各自有各自的优缺点,但是没有考虑并行运算的问题,实际上考虑并行运算的话,左边这个并不一定时间比较长。下边是真正的实验结果,事实上比较大的 Batch Size要算 Loss,再进而算 Gradient,所需要的时间不一定比小的 Batch Size 要花的时间长。
在这里插入图片描述
GPU 虽然有平行运算的能力,但它平行运算能力终究是有个极限,所以你 Batch Size 真的很大的时候,时间还是会增加的。
在这里插入图片描述
这样看起来大的 Batch Update 比较稳定,小的 Batch它的 Gradient 的方向比较 Noisy ,那大的 Batch 好像应该比小的 Batch要好。神奇的是 Noisy 的 Gradient反而可以帮助 Training,这个也是跟直觉正好相反的。
在这里插入图片描述
大的 Batch Size,往往在 Training 的时候会给你带来比较差的结果。为什么呢?可能的解释是:
在这里插入图片描述
​假设你是 Full Batch,那你今天在 Update 你的参数的时候,你就是沿著一个 Loss Function 来 Update 参数,今天 Update 参数的时候走到一个 Local Minima,走到一个 Saddle Point,显然就停下来了,Gradient 是零,如果你不特别去看Hession的话,那你用 Gradient Descent 的方法,你就没有办法再更新你的参数了。

​但是假如是 Small Batch 的话,因為我们每次是挑一个 Batch 出来,算它的 Loss,所以每一次 Update 你的参数的时候,你用的 Loss Function 都是有差异的,你选到第一个 Batch 的时候,你是用 L1 来算你的 Gradient,你选到第二个 Batch 的时候,你是用 L2 来算你的 Gradient,假设你用 L1 算 Gradient 的时候,发现 Gradient 是零,卡住了,但 L2 它的 Function 跟 L1 又不一样,L2 就不一定会卡住。

其实小的 Batch 也对 Testing 有帮助:
在这里插入图片描述
就算是在 Training 的时候结果差不多,Testing 的时候你还是看到了大的 Batch 居然比小的 Batch 差,这代表着Over Fitting,那为什么会有这样子的现象呢?
在这里插入图片描述
假设说这个 Training 跟 Testing,它的差距就是把 Training 的 Loss,这个 Function 往右平移一点,这时候你会发现,对左边这个在一个盆地裡面的 Minima 来说,它的在 Training 跟 Testing 上面的结果不会差太多,,只差了一点点,但是对右边这个在峡谷裡面的 Minima 来说,一差就可以天差地远。大的 Batch Size,会让我们倾向于走到峡谷裡面,而小的 Batch Size,倾向于让我们走到盆地裡面。
下边就是比较了一下,大的 Batch 跟小的 Batch:
在这里插入图片描述
所以大的 Batch 跟小的 Batch,它们各自有它们擅长的地方,你需要去调整Hyperparameter

2.3 Momentum

Momentum这也是另外一个有可能可以对抗 Saddle Point或 Local Minima 的技术,Momentum 的运作是这个样子的:
在这里插入图片描述
在物理的世界里,一个球如果从高处滚下来,从高处滚下来就算滚到 Saddle Point,如果有惯性,它从左边滚下来,因为惯性的关系它还是会继续往右走,甚至它走到一个 Local Minima。如果今天它的动量够大的话,它还是会继续往右走,甚至翻过这个小坡然后继续往右走。

这个是 Vanilla 的 Gradient Descent。Vanilla 的意思就是一般的的意思,它直译是香草的,但就其实是一般的,一般的 Gradient Descent 长什么样子呢?
在这里插入图片描述
一般的 Gradient Descent 是说,我们有一个初始的参数叫做 θ 0 θ^0 θ0,我们计算一下 Gradient,然后计算完这个 Gradient 以后呢,我们往 Gradient 的反方向去 Update 参数 θ 1 = θ 0 − η g 0 θ^1 = θ^0 - {\eta}g^0 θ1=θ0ηg0​我们到了新的参数以后,再计算一次 Gradient,再往 Gradient 的反方向,再 Update 一次参数,到了新的位置以后再计算一次 Gradient,再往 Gradient 的反方向去 Update 参数,这个 Process 就一直这样子下去。

加上 Momentum 以后,每一次我们在移动我们的参数的时候,我们不是只往 Gradient 的反方向来移动参数。我们是 Gradient 的反方向加上前一步移动的方向,两者加起来的结果,去调整去到我们的参数。
在这里插入图片描述具体说起来是这个样子,一样找一个初始的参数,然后我们假设前一步的参数的 Update 量为為 0 m 0 = 0 m^0 = 0 m0=0​接下来在 θ 0 θ^0 θ0 的地方,计算 Gradient 的方向 g 0 g^0 g0

​然后接下来你要决定下一步要怎么走,它是 Gradient 的方向加上前一步的方向,不过因为前一步正好是 0,现在是刚初始的时候所以前一步是 0,所以 Update 的方向跟原来的 Gradient Descent 是一样的。 m 1 = λ m 0 − η g 0 θ 1 = θ 0 + m 1 m^1 = {\lambda}m^0-{\eta}g^0\\ θ^1 = θ^0 + m^1 m1=λm0ηg0θ1=θ0+m1​但从第二步开始,有加上 Momentum 以后就不太一样了。从第二步开始,我们计算 g 1 g^1 g1,然后接下来我们 Update 的方向,不是 g 1 g^1 g1的反方向,而是根据上一次 Update 方向,也就是 m1 减掉 g1,当做我们新的 Update 的方向,这边写成 m 2 m^2 m2 m 2 = λ m 1 − η g 1 m^2 = {\lambda}m^1-{\eta}g^1 m2=λm1ηg1
在这里插入图片描述
Gradient 告诉我们要往红色反方向这边走,但是我们不是只听 Gradient 的话。加上 Momentum 以后,我们也会看前一次 Update 的方向。把两者相加起来,走两者的折中,也就是往蓝色 m 2 m^2 m2这一个方向走,所以我们就移动了 m 2 m^2 m2,走到 θ 2 θ^2 θ2 这个地方。
在这里插入图片描述
接下来就反覆进行同样的过程,这样就有可能通过动量对抗 Saddle Point或 Local Minima 。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、自动调整学习率

3.1 Training stuck ≠ Small Gradient

走到critical point的时候,意味著gradient非常的小,但是你有确认过当你的loss不再下降的时候,gradient真的很小吗?其实多数的同学可能都没有确认过这件事。而事实上在这个例子裡面当我们的loss不再下降的时候,gradient并没有真的变得很小。
在这里插入图片描述
gradient是一个向量,下面是gradient的norm,即gradient这个向量的长度,随著参数更新的时候的变化,你会发现说虽然loss不再下降,但是这个gradient的norm,gradient的大小并没有真的变得很小。

这样子的结果其实也不难猜想,也许你遇到的是这样子的状况,gradient在error surface山谷的两个谷壁间不断的来回的震荡:
在这里插入图片描述
所以你要注意,当你今天训练一个network,train到后来发现loss不再下降的时候,你不要随便说我卡在local minima或者saddle point。有时候根本两个都不是,你只是单纯的loss没有办法再下降。如果今天critical point不是问题的话,为什么我们的training会卡住呢?
在这里插入图片描述
我们只有两个参数,这两个参数值不一样的时候,Loss的值不一样。我们就画出了一个error surface。这个error surface的最低点在黄色X这个地方。事实上,这个error surface是convex的形状。

那现在我们要从黑点这个地方来做gradient descend。你可能觉得说这个convex的error surface做gradient descend有什麼难的吗?不就是一路滑下来,然后可能再走过去吗,应该是非常容易。你实际上自己试一下,你会发现说,就连这种convex的error surface,形状这么简单的error surface,你用gradient descend,都不见得能把它做好。
在这里插入图片描述
我learning rate设10⁻²的时候,这个参数在峡谷的两端不断的振荡,使得loss掉不下去,但是gradient其实仍然是很大的。因为learning rate设太大,learning rate决定了我们update参数的时候步伐有多大。只要把learning rate设小一点,不就可以解决这个问题了吗?

事实不然。试着去调整这个learning rate就会发现,你光是要train这种convex的optimization的问题,你就觉得很痛苦。就调这个learning rate,从10⁻²,一直调到10⁻⁷,调到10⁻⁷以后,终於不再振荡了。
在这里插入图片描述
终于从这个地方滑到山谷底左转。但是这个训练永远走不到终点,因为我的learning rate已经太小了,竖直往上这一段这个很斜的地方,因为这个坡度很陡,gradient的值很大,所以还能够前进一点,左拐以后这个地方坡度已经非常的平滑了,这么小的learning rate根本没有办法再让我们的训练前进。

所以我们需要更好的gradient descend的版本。在之前我们的gradient descend裡面,所有的参数都是设同样的learning rate,这显然是不够的,,learning rate它应该要为每一个参数定制化,所以接下来我们就是要讲如何定制化learning rate。

3.2 Different parameters needs different learning rate

从刚才的例子裡面,其实我们可以看到一个大原则。如果在某一个方向上,我们的gradient的值很小,非常的平坦,那我们会希望learning rate调大一点,如果在某一个方向上非常的陡峭,坡度很大,那我们其实期待,learning rate可以设得小一点
在这里插入图片描述
那这个learning rate要如何自动根据gradient的大小做调整呢?

我们要改一下gradient descend原来的式子。我们只放某一个参数update的式子,我们只看一个参数,但是你完全可以把这个方法推广到所有参数的状况 θ i t + 1 ← θ i t − η g i t {θ{_i}{^{t+1}}} ← {θ{_i}{^{t}}}-{\eta}{g{_i}{^{t}}} θit+1θitηgit 我们只看一个参数,这个参数叫做 θ i t {θ{_i}{^{t}}} θit,这个 θ i t {θ{_i}{^{t}}} θit在第t个iteration的值,减掉在第t个iteration这个参数i算出来的gradient g i t {g{_i}{^{t}}} git g i t = ∂ L ∂ θ i ∣ θ = θ t {g{i}{^{t}}}=\frac{\partial{L}}{\partial{θ_i}}|{θ=θ^t} git=θiLθ=θt 这个 g i t {g{_i}{^{t}}} git代表在第t个iteration,也就是θ等於θᵗ的时候,参数θᵢ对loss的微分。我们把这个θᵢᵗ减掉learning rate乘上gᵢᵗ,会更新learning rate到θᵢᵗ⁺¹。这是我们原来的gradient descend,我们的learning rate是固定的。现在我们要有一个随著参数定制化的learning rate。我们把原来learning rate η η η这一项改写成 η σ ᵢ ᵗ \frac{η}{σᵢᵗ} ση θ i t + 1 ← θ i t − η σ ᵢ ᵗ g i t {θ{_i}{^{t+1}}} ← {θ{_i}{^{t}}}-{\frac{η}{σᵢᵗ}}{g{_i}{^{t}}} θit+1θitσηgit 这个 σ ᵢ ᵗ σᵢᵗ σ你发现它有一个上标t,有一个下标i,这代表说这个σ这个参数首先它是depend on i的,不同的参数我们要给它不同的σ,同时它也是iteration dependent的,不同的iteration我们也会有不同的σ

所以当我们把我们的learning rate,从η改成 η σ ᵢ ᵗ \frac{η}{σᵢᵗ} ση的时候,我们就有一个parameter dependent的learning rate。接下来我们是要看这个parameter dependent的learning rate有什么常见的计算方式。

Root mean square
那这个σ有什么样的方式,可以把它计算出来呢,一个常见的类型是算gradient的Root Mean Square。
在这里插入图片描述
现在参数要update的式子,我们从θᵢ⁰初始化参数减掉gᵢ⁰乘上learning rate η除以σᵢ⁰。就得到θᵢ¹, θ i 1 ← θ i 0 − η σ ᵢ 0 g i 0 {θ{_i}{^{1}}} ← {θ{_i}{^{0}}}-{\frac{η}{σᵢ^0}}{g{_i}{^{0}}} θi1θi0σ0ηgi0 θ i t + 1 ← θ i t − η σ ᵢ t g i t {θ{_i}{^{t+1}}} ← {θ{_i}{^{t}}}-{\frac{η}{σᵢ^t}}{g{_i}{^{t}}} θit+1θitσtηgit
Adagrad
这一招被用在一个叫做Adagrad的方法裡面。为什麼这一招可以做到我们刚才讲的,坡度比较大的时候,learning rate就减小,坡度比较小的时候,learning rate就放大呢?
在这里插入图片描述
你可以想像说,现在我们有两个参数:一个叫θᵢ¹ 一个叫θᵢ²。 θᵢ¹坡度小 ,θᵢ²坡度大。

θᵢ¹因为它坡度小,所以你在θᵢ¹这个参数上面算出来的gradient值都比较小因为gradient算出来的值比较小,然后这个σ是gradient的平方和取平均再开根号
σ ᵢ t = 1 t + 1 ∑ i = 0 t ( g i t ) 2 {σᵢ^t}=\sqrt{\frac{1}{t+1}\sum_{i=0}^{t}{(g{_i}{^{t}}})^2} σt=t+11i=0t(git)2

所以算出来的σ就小,σ小 learning rate就大 η σ ᵢ t {\frac{η}{σᵢ^t}} σtη
反过来说θᵢ²。θᵢ²是一个比较陡峭的参数,在θᵢ²这个方向上loss的变化比较大,所以算出来的gradient都比较大,你的σ就比较大,你在update的时候,参数update的量就比较小。

所以有了σ这一项以后,你就可以随著gradient的不同,每一个参数的gradient的不同,来自动的调整learning rate的大小。
RMSProp
刚才那个版本,就算是同一个参数它需要的learning rate也会随著时间而改变。我们刚才的假设好像是同一个参数它的gradient的大小就会固定是差不多的值。但事实上并不一定是这个样子的。

举例来说我们来看,这个新月形的error surface
在这里插入图片描述
如果我们考虑横轴的话,考虑左右横的水平线的方向的话,你会发现在绿色箭头这个地方坡度比较陡峭,所以我们需要比较小的learning rate。
在这里插入图片描述
但是走到了中间这一段,到了红色箭头的时候呢,坡度又变得平滑了起来。平滑了起来就需要比较大的learning rate。所以就算是同一个参数同一个方向,我们也期待learning rate是可以动态的调整的。于是就有了一个新的招数,这个招数叫做RMS Prop
在这里插入图片描述
RMS Prop这个方法,它的第一步跟刚才讲的Apagrad方法是一模一样的 σ ᵢ 0 = ( g i 0 ) 2 {σᵢ^0}=\sqrt{({g_i^0})^2} σ0=(gi0)2 第二步,一样要算出σᵢ¹。只是我们现在算出σᵢ¹的方法跟刚才算Root Mean Square的时候不一样。在RMS Prop里面你可以自己调整现在的这个gradien有多重要 σ ᵢ 1 = α ( σ i 0 ) 2 + ( 1 − α ) ( g i 1 ) 2 {σᵢ^1}=\sqrt[]{\alpha(σ_i^0)^2+(1-\alpha)(g_i^1)^2} σ1=α(σi0)2+(1α)(gi1)2 所以在RMS Prop里面我们这个σᵢ¹它是前一步算出来的σᵢ⁰,里面就是有gᵢ⁰。所以这个σᵢ⁰就代表了gᵢ⁰的大小。所以它是(σᵢ⁰)²乘上α加上(1-α)乘上现在我们刚算出来的gᵢ¹。这个α就像learning rate一样,你要自己调它,它是一个hyperparameter。

那同样的过程就反复继续下去,σᵢᵗ等於根号α乘上(σᵢᵗ⁻¹)²,加上(1-α) (gᵢᵗ)²。 σ ᵢ t = α ( σ i t − 1 ) 2 + ( 1 − α ) ( g i t ) 2 {σᵢ^t}=\sqrt[]{\alpha(σ_i^{t-1})^2+(1-\alpha)(g_i^t)^2} σt=α(σit1)2+(1α)(git)2 用α来决定现在刚算出来的gᵢᵗ它有多重要,这个就是RMSProp。
Adam
今天最常用的optimization的策略,有人又叫做optimizer,就是Adam。
在这里插入图片描述
Adam就是RMS Prop加上Momentum。今天pytorch等深度学习框架里都帮你写得好好的了。所以这个你不用担心这种optimization的问题。optimizer里面也有一些一些hyperparameter需要人工决定,但往往用预设的那一种参数就够好了。

3.3 Learning Rate Scheduling

我们刚才讲说这个简单的error surface我们都train不起来。现在我们来看一下,加上Adaptive Learning Rate以后train不train得起来。
在这里插入图片描述
那现在有Adagrad以后你可以再继续走下去。走到非常接近终点的位置,因为当你走到这个地方的时候gradient很小,所以learning rate会自动调整变大。所以你这个步伐就可以变大,就可以不断的前进。接下来的问题就是为什么快走到终点的时候突然爆炸了呢?

我们在做这个σ的时候,我们是把过去所有看到的gradient都拿来作平均。所以这个纵轴的方向,在这个初始的这个地方,感觉gradient很大。可是这边走了很长一段路以后,这个纵轴的方向gradient算出来都很小,所以纵轴这个方向,这个y轴的方向就累积了很小的σ。我们在这个y轴的方向看到很多很小的gradient,所以我们就累积了很小的σ,累积到一个地步以后,这个step就变很大,然后就爆走就喷出去了。喷出去以后没关系,因为喷出去以后就走到了这个gradient比较大的地方,走到gradient比较大的地方以后这个σ又慢慢的变大,σ慢慢变大以后这个参数update的步伐大小就慢慢的变小。怎么办呢,有一个方法也许可以解决这个问题,这个叫做learning rate的scheduling。
在这里插入图片描述
我们刚才这边还有一项η,这个η是一个固定的值。learning rate scheduling的意思就是说,我们不要把η当一个常数,我们把它跟时间有关。最常见的策略叫做Learning Rate Decay。也就是说,随著时间的不断地进行,随著参数不断的update,我们这个η让它越来越小。

在这里插入图片描述
刚才那个状况如果加上Learning Rate Decay的话,我们就可以很平顺的走到终点。除了Learning Rate Decay以外,还有另外一个经典常用的Learning Rate Scheduling的方式叫做Warm Up
在这里插入图片描述
Warm Up这个方法听起来有点匪夷所思。这Warm Up的方法是让learning rate要先变大后变小。你会问说变大要变到多大呢,变大速度要多快呢 ,小速度要多快呢。这个也是hyperparameter,你要自己用手调的,但是大方向的大策略就,learning rate要先变大后变小。那为什么需要warm Up呢?这个仍然是今天可以研究的问题。
在这里插入图片描述
这边有一个可能的解释是说,当我们在用Adam RMS Prop或Adagrad的时候,一开始我们的σ是不精准的。所以我们一开始不要让我们的参数走离初始的地方太远,先让它在初始的地方做一些探索。等σ统计得比较精准以后再让learning rate慢慢地爬升。

4、损失函数

4.1 Classification as Regression

Regression就是输入一个向量,然后输出一个数值。我们希望输出的数值跟某一个label也就是我们要学习的目标越接近越好。
在这里插入图片描述
我们其实可以把Classification当作是Regression来看。
在这里插入图片描述
这个方法也许在某些状况下,是会有瑕疵的
在这里插入图片描述
因为如果你假设说Class one就是编号1,Class two就是编号2,Class3就是编号3。意味著说你觉得Class1跟Class2是比较像,然后Class1跟Class3 它是比较不像。像这样子的表示Class的方式有时候可行,有时候不可行。

  • 假设你的Class one two three真的有某种关係举例来说,你想要根据一个人的身高跟体重然后预测他是几年级的小学生,一年级,二年级还是三年级。那可能一年级真的跟二年级比较接近,一年级真的跟三年级比较没有关系。
  • 但是假设你的三个Class本身并没有什么特定的关係的话。你说Class one是1,Class two是2,Class two是3那就很奇怪了。因为你这样是预设说一二有比较近的关系,一三有比较远的关係。所以怎么办呢?

4.2 Class as one-hot vector

当你在做分类的问题的时候,比较常见的做法是把你的Class用 One-hot vector来表示
在这里插入图片描述
如果有三个Class,我们的 label 这个ŷ就是一个三维的向量。如果是Class1就是 [ 1 0 0 ] \begin{bmatrix}{1} \\ {0}\\ {0}\end{bmatrix} 100,如果是Class2就是 [ 0 1 0 ] \begin{bmatrix} {0}\\ {1}\\ {0}\end{bmatrix} 010,如果是Class3就是 [ 0 0 1 ] \begin{bmatrix} {0}\\ {0}\\ {1}\end{bmatrix} 001。所以每一个Class你都用一个One-hot vector来表示。

而且你用One-hot vector来表示的话就没有说Class1跟Class2比较接近,Class1跟Class3比较远这样子的问题。如果你把这个One-hot vector,用算距离的话,Class之间两两它们的距离都是一样。

如果我们今天的目标ŷ是一个向量。比如说ŷ是有三个element的向量,那我们的network也应该要Output的维度也是三个数字才行。
在这里插入图片描述
到目前为止我们讲的network其实都只Output一个数值。因為我们过去做的都是Regression的问题,所以只Output一个数字。其实从一个数值改到三个数值它是没有什么不同的,你可以Output一个数值就可以Output三个数值。只要把本来Output一个数值的方法重复三次。
在这里插入图片描述

  • 把a₁ a₂ a₃,乘上三个不同的Weight 加上bias,得到y₁
  • 再把a₁ a₂ a₃乘上另外三个Weight,再加上另外一个bias得到y₂
  • 再把a₁ a₂ a₃再乘上另外一组Weight,再加上另外一个bias得到y₃

你就可以Input一个feature的Vector然后产生y₁ y₂ y₃,然后希望y₁ y₂ y₃跟我们的目标越接近越好。

4.3 Classification with softmax

如果是Classification。input x可能乘上一个W,再加上b,再通过activation function,再乘上W’再加上b’ 得到y。我们现在的y它不是一个数值,它是一个向量。
在这里插入图片描述
但是在做Classification的时候,我们往往会把y再通过一个叫做Soft-max的function得到y’,然后我们才去计算y’跟ŷ之间的距离。为什么要加上Soft-max呢?一个比较简单的解释就是,这个ŷ 它裡面的值都是0跟1。但是y里面有任何值,既然我们的目标只有0跟1,但是y有任何值,我们就先把它Normalize到0到1之间,这样才好跟 label 的计算相似度

这个是Soft-max的block,输入y₁ y₂ y₃,,它会产生y₁’ y₂’ y₃’
在这里插入图片描述
它里面运作的模式是这个样子的 y i ′ = e x p ( y i ) ∑ j e x p ( y i ) y_i'=\frac{exp(y_i)}{\sum_j exp(y_i)} yi=jexp(yi)exp(yi) 我们会先把所有的y取一个exponential,就算是负数取exponential以后也变成正的,。然后你再对它做Normalize,除掉所有y的exponential值的和,然后你就得到y’。
在这里插入图片描述
y₁取exp,y₂取exp,y₃取exp,把它全部加起来得到一个Summation。接下来再把exp y₁’除掉Summation,exp y₂’除掉Summation,exp y₃’除掉Summation,就得到y₁’ y₂’ y₃’。

有了这个式子以后,你就会发现

  • y₁’ y₂’ y₃’,它们都是介於0到1之间
  • y₁’ y₂’ y₃’,它们的和是1

这个Soft-max它要做的事情,除了Normalized让 y₁’ y₂’ y₃’,变成0到1之间,还有和為1以外,它还有一个附带的效果是它会让大的值跟小的值的差距更大。本来-3,通过exponential再做Normalized以后会变成趋近於0的值。这个Soft-max的输入往往就叫它logit。如果是两个class你当然可以直接套soft-max这个function没有问题,但当有两个class的时候我们一般就不套soft-max,而是直接取sigmoid。这两种方法是等价的。

4.4 Loss of Classification

我们把x丢到一个Network里面产生y以后,我们会通过soft-max得到y’,再去计算y’跟ŷ之间的距离。这个写作е。计算y’跟ŷ之间的距离不只一种做法。举例来说,如果我喜欢的话,我要让这个距离是Mean Square Error e = ∑ i ( y i ^ − y i ′ ) 2 e=\sum_i(\hat{y_i}-y_i')^2 e=i(yi^yi)2 就是把ŷ裡面每一个element拿出来,然后计算它们的平方和。当作我们的error,这样也是计算两个向量之间的距离。你也可以说,你也可以做到说当minimize Mean Square Error的时候我们可以让ŷ等于y’

但是有另外一个更常用的做法,叫做Cross-entropy e = − ∑ i y i ^ ln ⁡ y i ′ e=-\sum_i\hat{y_i}\ln{y_i'} e=iyi^lnyi 这个Cross-entropy它的式子乍看之下,会让你觉得有点匪夷所思,怎么是这个样子呢?

  • Cross-entropy是summation over所有的i
  • 然后把ŷ的第i位拿出来,乘上y’的第i位取Natural log
  • 然后再全部加起来

为什么会有Cross-entropy这么奇怪的式子出现呢?
在这里插入图片描述
那如果要讲得长一点的话,这整个故事我们可以把它讲成Make Minimize Cross-entropy其实就是maximize likelihood。举一个例子来告诉你说,为什么是Cross-entropy比较好。
在这里插入图片描述
那现在我们要做一个3个Class的分类。Network先输出y₁ y₂ y₃,在通过soft-max以后产生y₁’ y₂’跟y₃’。
假设我们的正确答案就是100,我们要去计算100这个向量跟y₁’ y₂’跟y₃’他们之间的距离。那这个距离我们用е来表示,е可以是Mean square error,也可以是Cross-entropy。

假设y₁的变化是从-10到10,y₂的变化也是从-10到10,y₃我们就固定设成-1000。因为y₃设很小,所以过soft-max以后y₃’就非常趋近於0,它跟正确答案非常接近且它对我们的结果影响很少。

总之我们y₃设一个定值,我们只看跟有变化的时候对我们的e对我们的Loss有什么样的影响。

如果我们这个e设定为Mean Square Error跟Cross-entropy的时候,算出来的Error surface会有什么样不一样的地方。底下这两个图,就分别在我们e是Mean square error跟Cross-entropy的时候y₁ y₂的变化对loss的影响。
在这里插入图片描述
我们这边是用红色代表Loss大,蓝色代表Loss小

  • 那如果今天y₁很大 y₂很小,就代表y₁’会很接近1,y₂’会很接近0。所以不管是对Mean Square Error或是Cross-entropy而言,y₁大 y₂小的时候 Loss都是小的。

  • 如果y₁小 y₂大的话,这边y₁’就是0,y₂’就是1。所以这个时候Loss会比较大

所以这两个图都是左上角Loss大,右下角Loss小,所以我们就期待在Training的时候,我们的参数可以走到右下角的地方。

在这里插入图片描述
那假设我们开始的地方,都是左上角

  • 如果我们选择Cross-Entropy,左上角这个地方它是有斜率的,所以你有办法透过gradient一路往右下的地方走。
  • 如果你选Mean square error的话,你就卡住了。Mean square error在这种Loss很大的地方它是非常平坦的,它的gradient是非常小趋近於0的。如果你初始的时候在这个地方离你的目标非常远,那它gradient又很小你就会没有办法用gradient descent顺利的走到右下角的地方去

所以就算是Loss function不同的定义,都可能影响Training。

5、批次标准化

5.1 Changing Landscape

我们能不能够直接改error surface 的 landscape,error surface 如果很崎岖的时候,它比较难 train,那我们能不能够直接把山铲平让它变得比较好 train呢?Batch Normalization 就是一个把山铲平的想法。

假设两个参数它们对 Loss 的斜率差别非常大。在 w 1 w_1 w1 这个方向上面斜率变化很小,在 w 2 w_2 w2 这个方向上面斜率变化很大。如果是固定的 learning rate你可能很难得到好的结果。所以我们才说你需要adaptive 的 learning rate、 Adam 等等比较进阶的 optimization 的方法才能够得到好的结果。现在我们要从另外一个方向想,直接把难做的 error surface 把它改掉看能不能够改得好做一点。

假设现在有一个非常非常非常简单的 model,它的输入是 x 1 x_1 x1 x 2 x_2 x2,它对应的参数就是 $ w_1 $ 跟 w 2 w_2 w2,它是一个 linear 的 model,没有 activation function。
在这里插入图片描述
$ w_1 $ 乘 x 1 x_1 x1 w 2 w_2 w2 x 2 x_2 x2 加上 b 以后就得到 y,然后计算 y 跟 y ^ \hat{y} y^ 之间的差距当做 e,把所有 training data e 加起来就是Loss,然后去 minimize Loss。那什么样的状况我们会产生像上面这样子比较不好 train 的 error surface 呢?
在这里插入图片描述
当我们对 w 1 w_1 w1 有一个小小的改变,比如说加上 delta w 1 w_1 w1 的时候,那这个 L 也会有一个改变,那这个 w 1 w_1 w1 呢,是透过 w 1 w_1 w1 改变的时候,你就改变了 y,y 改变的时候你就改变了 e,然后接下来就改变了 L。那什么时候 w 1 w_1 w1 的改变会对 L 的影响很小呢,也就是它在 error surface 上的斜率会很小呢。一个可能性是当你的 input 很小的时候,假设 x 1 x_1 x1 的值在不同的 training example 里面,它的值都很小,那因為 x 1 x_1 x1 是直接乘上 w 1 w_1 w1,如果 x 1 x_1 x1 的值都很小, w 1 w_1 w1 有一个变化的时候,它对 y 的影响也是小的,对 e 的影响也是小的,它对 L 的影响就会是小的。

反之如果是 x 2 x_2 x2 的话
在这里插入图片描述
假设 x 2 x_2 x2 的值都很大,当你的 w 2 w_2 w2 有一个小小的变化的时候,虽然 w 2 w_2 w2 这个变化可能很小,但是因为它乘上了 x 2 x_2 x2 x 2 x_2 x2 的值很大,那 y 的变化就很大,那 e 的变化就很大,那 L 的变化就会很大,就会导致我们在 w 这个方向上做变化的时候,我们把 w 改变一点点,那我们的 error surface 就会有很大的变化。

所以在这个 linear 的 model 里面,当我们 input 的 feature每一个 dimension 的值它的 scale 差距很大的时候,我们就可能产生像这样子的 error surface,就可能产生不同方向,斜率非常不同,坡度非常不同的 error surface。

所以怎么办呢,我们有没有可能给feature 里面不同的 dimension,让它有同样的数值的范围?
在这里插入图片描述
如果我们可以给不同的 dimension,同样的数值范围的话,那我们可能就可以制造比较好的 error surface,让 training 变得比较容易一点。其实有很多不同的方法,这些不同的方法往往就合起来统称为Feature Normalization

5.2 Feature Normalization

以下所讲的方法只是Feature Normalization 的一种可能性,它并不是 Feature Normalization 的全部。假设 x 1 x^1 x1 x R x^R xR是我们所有的训练资料的 feature vector
在这里插入图片描述
我们把所有训练资料的 feature vector 统统都集合起来。每一个 vector x 1 x_1 x1 裡面就 x 1 1 x^1_1 x11代表 x 1 x_1 x1 的第一个 element, x 1 2 x^2_1 x12就代表 x 2 x_2 x2 的第一个 element,以此类推。

我们把不同笔资料即不同 feature vector,同一个 dimension 裡面的数值,把它取出来,然后去计算某一个 dimension 的 mean,它的 mean 呢 就是 m i m_i mi,我们计算第 i 个 dimension 的,standard deviation,我们用 σ i \sigma_i σi来表示它

那接下来我们就可以做一种 normalization,那这种 normalization 其实叫做标准化,其实也叫 standardization x ~ i r ← x i r − m i σ i \tilde{x}^r_i ← \frac{x^r_i-m_i}{\sigma_i} x~irσixirmi 就是把这边的某一个数值x减掉这一个 dimension 算出来的 mean,再除掉这个 dimension算出来的 standard deviation,得到新的数值叫做 x ~ \tilde{x} x~

然后得到新的数值以后再把新的数值把它塞回去,以下都用这个 tilde来代表有被 normalize 后的数值

那做完 normalize 以后有什么好处呢?
在这里插入图片描述

  • 做完 normalize 以后这个 dimension 上面的数值就会平均是 0,然后它的 variance就会是 1,所以这一排数值的分布就都会在 0 上下

  • 对每一个 dimension都做一样的 normalization,就会发现所有 feature 不同 dimension 的数值都在 0 上下,那你可能就可以制造造一个比较好的 error surface

所以像这样子 Feature Normalization 的方式往往对你的 training 有帮助。它可以让你在做 gradient descent 的时候它的 Loss 收敛更快一点,可以让你的 gradient descent它的训练更顺利一点。

5.3 Considering Deep Learning

x ~ \tilde{x} x~ 代表 normalize 的 feature,把它丢到 deep network 里面,去做接下来的计算和训练,所以把 x 1 x_1 x1 tilde 通过第一个 layer 得到 z 1 z^1 z1,那你有可能通过 activation function,不管是选 Sigmoid 或者 ReLU 都可以,然后再得到 a 1 a^1 a1,然后再通过下一层等等,那就看你有几层 network 你就做多少的运算。
在这里插入图片描述
所以每一个 x 都做类似的事情,但是如果我们进一步来想的话,对 w 2 w_2 w2 来说

在这里插入图片描述
这边的 a 1 a^1 a1 a 3 a^3 a3 这边的 z 1 z^1 z1 z 3 z^3 z3,其实也是另外一种 input。如果这边 x ~ \tilde{x} x~虽然它已经做 normalize 了,但是通过 w 1 w_1 w1 以后它就没有做 normalize。如果 x ~ \tilde{x} x~ 通过 w 1 w_1 w1 得到是 z 1 z^1 z1,而 z 1 z^1 z1 不同的 dimension 间,它的数值的分布仍然有很大的差异的话,那我们要 train w 2 w_2 w2 第二层的参数,会不会也有困难呢。

w 2 w_2 w2 来说,这边的 a 或这边的 z 其实也是一种 feature,我们应该要对这些 feature 也做 normalization。那如果你选择的是 Sigmoid那可能比较推荐对 z 做 Feature Normalization,因为Sigmoid 是一个 s 的形状,它在 0 附近斜率比较大,所以如果你对 z 做 Feature Normalization把所有的值都挪到 0 附近,那你到时候算 gradient 的时候算出来的值会比较大。

因为你不见得是用 sigmoid,所以你也不一定要把 Feature Normalization放在 z 这个地方,如果是选别的也许你选a也会有好的结果也说不定。Ingeneral 而言,这个 normalization要放在 activation function 之前或之后都是可以的。实际上可能没有太大的差别。

那怎么对 z 做 Feature Normalization 呢?
在这里插入图片描述
你就把 z想成是另外一种 feature,和上一节中x一样做个 Feature Normalization。
在这里插入图片描述
z 1 z^1 z1 z 2 z^2 z2 z 3 z^3 z3做了 Feature Normalization变成 z ~ 1 \tilde{z}^1 z~1 z ~ 2 \tilde{z}^2 z~2 z ~ 3 \tilde{z}^3 z~3
在这里插入图片描述
z 1 z^1 z1 本来如果我们没有做 Feature Normalization 的时候,你改变了 z 1 z^1 z1 的值,你会改变这边 a 的值。但是现在当你改变 z 1 z^1 z1 的值的时候, μ μ μ σ \sigma σ 也会跟着改变。 μ μ μ σ \sigma σ 改变以后, z 2 z^2 z2 的值 a 2 a^2 a2 的值, z 3 z^3 z3 的值 a 3 a^3 a3 的值,也会跟着改变。
在这里插入图片描述
之前,我们每一个 x ~ 1 \tilde{x}_1 x~1 x ~ 2 \tilde{x}_2 x~2 x ~ 3 \tilde{x}_3 x~3,它是独立分开处理的。但是我们在做 Feature Normalization 以后,这三个 example它们变得彼此关联了。

z 1 z^1 z1 只要有改变,接下来 z 2 z^2 z2 a 2 a^2 a2 z 3 z^3 z3 a 3 a^3 a3也都会跟著改变。所以其实有做 Feature Normalization 的时候,你要把这一整个 process,就是有收集一堆 feature,把这堆 feature 算出 μ μ μ σ \sigma σ 这件事情当做是 network 的一部分。
在这里插入图片描述
也就是说,你现在有一个比较大的 network

  • 你之前的 network,都只吃一个 input,得到一个 output
  • 现在你有一个比较大的 network,这个大的 network,它是吃一堆 input,用这堆 input 在这个 network 里面要算出 μ μ μ σ \sigma σ,然后接下来产生一堆 output

在实作的时候,你不会让这一个 network 考虑整个 training data 里面的所有 example。你只会考虑一个 batch 裡面的 example。举例来说,你 batch 设 64,那你这个巨大的 network就是把 64 笔 data 读进去,算这 64 笔 data 的 μ μ μ,算这 64 笔 data 的 σ \sigma σ,对这 64 笔 data 都去做 normalization。因为我们在实作的时候,我们只对一个 batch 里面的 data做 normalization,所以这招叫做 Batch Normalization

这个 Batch Normalization,显然有一个问题,就是你一定要有一个够大的 batch,你才算得出 μ μ μ σ \sigma σ,假设你 batch size 设 1,那你就没有 μ μ μ σ \sigma σ 可以算。

所以这个 Batch Normalization,是适用于 batch size 比较大的时候。因为 batch size 如果比较大,也许这个 batch size 里面的 data就足以表示整个 corpus 的分布。那这个时候你就可以把这个本来要对整个 corpus做 Feature Normalization 这件事情,改成只在一个 batch做 Feature Normalization,作为 approximation。

在做 Batch Normalization 的时候,往往还会有这样的设计。你算出这个 z ~ \tilde{z} z~ 以后,接下来你会把这个 z ~ \tilde{z} z~再乘上另外一个向量叫做 γ γ γ,这个 γ γ γ 也是一个向量。所以你就是把 z ~ \tilde{z} z~ γ γ γ 做 element wise 的相乘,把 z 这个向量里面的 element,跟 γ γ γ 这个向量里面的 element两两做相乘再加上 β β β 这个向量,得到 z ^ \hat{z} z^。而 β β β γ γ γ,你要把它想成是 network 的参数,它是另外再被learn出来的。
在这里插入图片描述
那为什么要加上 β β β γ γ γ 呢?

如果我们做 normalization 以后, z ~ \tilde{z} z~它的平均是 0 的话,会带来负面的影响,所以我们把 β β β γ γ γ 加回去。现在它的 hidden layer 的 output平均不是 0 的话,他就自己去learn这个 β β β γ γ γ,来调整一下输出的分布,来调整这个 z ^ \hat{z} z^ 的分布。

但刚才做 Batch Normalization 就是为了要让每一个不同的 dimension它的 range 都是一样,现在如果加去乘上 γ γ γ再加上 β β β,把 γ γ γ β β β 加进去这样不会不同 dimension 的分布它的 range 又都不一样了吗?有可能,但实际上在训练的时候,这个 γ γ γ β β β 的初始值都设为 1,所以 γ γ γ 是一个里面的值全部都是 1 的向量。那 β β β 是一个里面的值全部都是 0 的向量。

所以让你的 network 在一开始训练的时候,每一个 dimension 的分布是比较接近的。也许训练到后来,你已经训练够长的一段时间,已经找到一个比较好的 error surface,走到一个比较好的地方以后,那再把 γ γ γ β β β 慢慢地加进去。

5.4 Testing

这个 Batch Normalization 在testing 的时候会有什么样的问题呢?
在做 Batch Normalization 的时候,一个 x ~ \tilde{x} x~一个 normalization 过的 feature 进来。然后你有一个 z,你的 z 要减掉 μ μ μ 跟除 σ \sigma σ,这个 μ μ μ σ \sigma σ,是用一个 batch 的资料算出来的。但如果今天在 testing 的时候,根本就没有 batch那我们要怎么算这个 μ μ μ,跟怎么算这个 σ \sigma σ 呢?

其实在 training 的时候,如果你有在做 Batch Normalization 的话,在 training 的时候你每一个 batch 计算出来的 μ μ μ σ \sigma σ他都会拿出来算 moving average
在这里插入图片描述
你每一次取一个 batch 出来的时候,你就会算一个 μ 1 μ^1 μ1,取第二个 batch 出来的时候,你就算个 μ 2 μ^2 μ2,一直到取第 t 个 batch 出来的时候,你就算一个 μ t μ^t μt

接下来你会算一个 moving average,你会把你现在算出来的 μ μ μ 的一个平均值,叫做 μ μ μ bar,乘上某一个 factor,那这也是一个常数,这个这也是一个 constant。这也是一个那个 hyperparameter,也是需要调的。

testing 在真正 application 上,也没有 batch 这个东西,你就直接拿 μ ˉ \barμ μˉ σ ˉ \bar\sigma σˉ,也就是 μ μ μ σ \sigma σ 在训练的时候得到的 moving average, μ ˉ \barμ μˉ σ ˉ \bar\sigma σˉ 来取代这边的 μ μ μ σ \sigma σ,这个就是 Batch Normalization在 testing 的时候的运作方式。

5.5 Comparison

Batch Normalization用在CNN上效果如下图:
在这里插入图片描述

  • 横轴代表的是训练的过程,纵轴代表的是 validation set 上面的 accuracy
  • 黑色的虚线是没有做 Batch Normalization 的结果,它用的是 inception 的 network
  • 如果有做 Batch Normalization,你会得到红色的这一条虚线,它训练的速度显然比黑色的虚线还要快很多
  • 粉红色的线是 sigmoid function,但一般都会选择 ReLu而不是用 sigmoid function。因为 sigmoid function它的 training 是比较困难的,sigmoid 不加 Batch Normalization根本连 train 都 train 不起来
  • 蓝色的实线跟这个蓝色的虚线,是把 learning rate 设比较大一点

5.6 Internal Covariate Shift?

Batch Normalization它为什么会有帮助呢?在原始的 Batch Normalization那篇 paper 里,他提出来一个概念,叫做 internal covariate shiftcovariate shift(训练集和预测集样本分布不一致的问题就叫做“covariate shift”现象) 这个词汇是原来就有的。internal covariate shift应该是Batch Normalization 的作者自己发明的。他认为说今天在 train network 的时候,会有以下这个问题:
在这里插入图片描述
network 有很多层

x 通过第一层以后 得到 a

a 通过第二层以后 得到 b

计算出 gradient 以后,把 A update 成 A′,把 B 这一层的参数 update 成 B′。

但是作者认为说,我们在计算 B update 到 B′ 的 gradient 的时候,这个时候前一层的参数是 A ,或者是前一层的 output 是小 a。当前一层从 A 变成 A′ 的时候,它的 output 就从小 a 变成小 a′ 。但是我们计算这个 gradient 的时候,是根据这个 a 算出来的。所以这个 update 的方向也许它适合用在 a 上,但不适合用在 a′ 上。

如果做了 Batch Normalization 的话,我们会让 a 跟 a′ 的分布比较接近,也许这样就会对训练有帮助。
在这里插入图片描述
但是有一篇 paper 叫做How Does Batch Normalization Help Optimization就打脸了internal covariate shift 的这一个观点。在这篇 paper 里面从各方面来告诉你internal covariate shift,首先它不一定是 training network 的时候的一个问题,然后 Batch Normalization它会比较好可能不见得是因为它解决了 internal covariate shift。但无论如何,这篇文献支持了 Batch Normalization可以改变 error surface让 error surface 比较不崎岖的这个观点。也许这是一种偶然的发现,但至少它是一个有用的方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值