Gradient Descent梯度下降
▽ -> 梯度gradient -> vector向量 -> 下图中的红色箭头(loss等高线的法线方向)
Tip1: Tuning your learning rates
Adaptive Learning Rates自适应lr
通常lr会越来越小
Adaptive Learning Rates中每个参数都给它不同的lr
Adagrad
Adagrad也是Adaptive Learning Rates,因此每个参数都给它不同的lr
Tip2: Stochastic Gradient Descent随机梯度下降
左边走一步,右边已经二十步
天下武功唯快不破
Tip3: Feature Scaling特征缩放
为什么要做归一化处理
如果要predict宝可梦进化以后CP值,有两个input feature:x1是进化前CP值,x2是它的生命值
如果x1和x2分布的range很不一样,建议把它们做scaling,也就是把它们的range分布变成是一样的
希望不同的feature,它们的scale是一样的
左边这种情况下会发现,w1的变化对y的变化而言是比较小的,而w2的变化对y的变化而言是比较大的
如果画error surface会是长椭圆形状的:因此,w1对loss是有比较小的微分的,因此w1方向上比较平滑。此时,在不同方向上,就会需要非常不同的lr,除非Adagrad等adaptive lr否则很难搞定它,很难update参数
正圆形update参数就比较容易,而且注意到梯度方向就是指向最低点的,效率就比较高,而椭圆形开始时不是指向最低点
常见的Feature Scaling方式:
深度学习中典型的特征归一化代表就是Batch Normalization批归一化,具体的计算方法也是较简单即计算批中均值和方差,通过均值和方差对原数据进行归一化操作:
看上图绿色框框圈起来的地方,我们称作它是“第i个dimension”。然后在第i个dimension当中再取出其中一个element出来看(就是红色框框的地方)。
每一个元素减掉同一个dimension的所有elements平均值再除以standard deviation后再放回原位,然后每一个elements都经过一次这样的计算,就完成了feature normalization
那做完Normalization后有什么好处?
所有dimension的mean会被限制是0,而variance变成全部是1。呈现一个统计上的常态分布,这样就可以制造出一个较好(较smooth)的error surface。
再做梯度下降可以收敛地更快更好
此外,在 Deep Learning 中,还要考虑 hidden layer (中间层)的输出。如下图所示的
z
i
z^i
zi它同时是下一层的输入,因此也需要做 Normalization。
看上图,最左边的三个x tilde已经做feature normalization(x变成x tilde: tilde就是波浪符号的意思),但他们还会因为要经过下一层的hidden layer,经过下一层的hidden layer,代表必须再做一次feature normalization的动作.可以在z的那层做或是在a的那层做feature normalization都可以; 事实上在实作上, 在activation前或后做feature normalization不会有太大的变化,所以其实都可以。
在什么位置做 Normalization 呢?
一般来说,在 activation function 之前(对 z i z^i zi做)或之后(对 a i a^i ai做)都可以。不过,如果 activation function 是 Sigmoid,因为 Sigmoid function 在取值范围 [0,1] 的 gradient 较大,因此对 z i z^i zi做normalization 更好。
我们接下来对z层做feature normalization。先算出
μ
\mu
μ和
σ
\sigma
σ
再对每一个element做feature normalization,得到z-tilde
对
z
i
z^i
zi做了 normalization 之后,有一个有趣的现象:本来各条数据(各个 sample )之间是互不影响的。例如
z
1
z^1
z1的变化只影响
a
1
a^1
a1 。但是做 normalization 要在全部数据 (samples) 上求均值和方差,如下图所示,
z
1
z^1
z1的变化会通过
μ
\mu
μ,
σ
\sigma
σ影响KaTeX parse error: Expected group after '_' at position 2: z_̲^2,KaTeX parse error: Expected group after '_' at position 2: z_̲^3,进而影响到
a
2
a^2
a2,
a
3
a^3
a3
也就是说,以前是一次只需要考虑一个 sample ,输入到 deep neural network 得到一个 output。做 Normalization 会使得 samples 之间互相有影响,因此现在一次需要考虑一批 samples,输入一个大的 deep neural network,得到一批 outputs。
但我们经过feature normalization关联化之后,那我们下一层必须把被关联化的所有input都包在一起做计算。这也是为什么这个演算法叫做Batch的原因。所以请记住一个关键: Batch的原因就是input已经在feature normalization的时候就"被关联"起来了。也可以看做,不是一个network处理一个example,而是变成一个巨大的network处理一大把example然后output出另一大把example.
然而,这边又有一个问题,我们资料要是有好几百万笔的话,我们在实作的时候或许会受限于硬体效能状况下会跑很久,那这时候我们就可以只取Batch做计算。
但另一个问题是,若我们只取Batch,这个Batch也必须要够大,大到足以表示整个data corpus的分布。这个时候就可以把原本要对整个corpus做feature normalization变成只需要对一个batch做feature normalization,做为整个data corpus的概估值。
所以这样大大减少计算量且减小了”Internal Covariate Shift”带来的负面效应。
把输入 samples 的各个维度都调整成均值为 0,方差为 1的分布,有时可能不好解决问题,此时可以做一点改变。如下图右上角的公式所示。注意:
γ
\gamma
γ 和
β
\beta
β 的值通过学习得到,也就是根据模型和数据的情况调整。
γ
\gamma
γ 初始设为全 1 向量,
β
\beta
β 初始设为全 0 向量。
Testing Performance
刚刚说的都是training的状况,接下来看一下testing时怎么做:
Batch Normalization 虽好,但是在 testing 时就遇到了问题。testing 或者实际部署时,数据都是实时处理,不可能每次等到满一个 batch 才处理。
怎么办呢?
训练时,每处理一个 batch,就按下图中所示公式,更新均值
μ
\mu
μ 的 moving average
μ
‾
\overline\mu
μ ,
σ
\sigma
σ 也是类似操作。训练结束后,把得到的
μ
‾
\overline\mu
μ和
σ
‾
\overline\sigma
σ 用作 testing data 的均值和方差。
为什么说 Batch Normalization 对优化参数有帮助?
“Experimental results (and theoretically analysis) support batch normalization change the landscape of error surface.”
实验结果和理论分析验证了 Batch Normalization 可以通过改变 error surface,让 optimization 更顺利。
Batch Normalization的表现
所以BN实际上有一些对抗过拟合的效果
看到一个方法时要考虑是对training performance有用还是对testing performance有用。BN是对两个stage都有用,主要的作用还是在training不好的时候帮助比较大;如果是training已经很好但testing不好,还有很多其他方法可用
BN归一化的表现没有说特别突出,因为Normalization不仅仅只有BN,还有其他Layer Normalization,Instance Normalization等等,但是BN所使用最为广泛,并且如图实验数据可以看出BN的加入能够使得模型收敛速度更快并且随着batch的增大表现出更大的优势,特别是在使用sigmoid的时候,由于sigmoid函数曲线的特殊性,使得BN后输入sigmoid激活函数中能够表现出更好的梯度。要有BN,sigmoid才train的起来
Gradient Descent Theory
update参数后,loss不一定会下降
此时,人物往前和往右都会变低,因此会往右前方走,但是却变高了