机器学习 --超参数调优

 机器学习中,绝大部分模型没有解析解,需要采用梯度下降法求解最有参数,各种各样的梯度下降法都会遇到一个问题,就是如何设置学习率,是一个技术活,更是一个运气活。

一 学习率参数调优的原理

超参数调优,经常会遇到两个问题:
1、 模型发散,参数随着迭代数值绝对值越来越大,甚至发散到无穷,从损失函数来看,误差也会越来越大。
2、 震荡,从损失函数来看,误差出现震荡,模型在局部最优解附近徘徊。

1.1 模型参数发散的原因

假定损失函数为 Q(β)>0 Q ( β ) > 0 ,通常梯度下降法可表示为

βnew=βoldλQ(β)|β=βold β n e w = β o l d − λ ∇ Q ( β ) | β = β o l d

Q(β) Q ( β ) 满足条件:
Q(β)sβ;β>M>0ands>0 ‖ ∇ Q ( β ) ‖ ≥ s ‖ β ‖ ; ∀ ‖ β ‖ > M > 0 a n d s > 0

几乎所有损失函数都满足这一条件,比如最简单的 Q(θ)=aθ2,a>0,θ0 Q ( θ ) = a θ 2 , a > 0 , ∀ θ ≠ 0 ,有 c=2a c = 2 a

有:

βλQ(β)2=β22cos(θ)λQ(β)β+λ2Q(β)=β2+λQ(β)(Q(β)2cos(θ)β)β2+λQ(β)(λc2cos(θ)β ‖ β − λ ∇ Q ( β ) ‖ 2 = ‖ β ‖ 2 − 2 c o s ( θ ) λ ‖ ∇ Q ( β ) ‖ ‖ β ‖ + λ 2 ‖ ∇ Q ( β ) ‖ = ‖ β ‖ 2 + λ ‖ ∇ Q ( β ) ‖ ( ‖ ∇ Q ( β ) ‖ − 2 c o s ( θ ) ‖ β ‖ ) ≥ ‖ β ‖ 2 + λ ‖ ∇ Q ( β ) ‖ ( λ c − 2 c o s ( θ ) ‖ β ‖

λc>2 λ c > 2 时必有:
βλQ(β)2β2+λQ(β)(λc2cos(θ)β>λcϵβ2+β2=(1+λtϵ)β2 ‖ β − λ ∇ Q ( β ) ‖ 2 ≥ ‖ β ‖ 2 + λ ‖ ∇ Q ( β ) ‖ ( λ c − 2 c o s ( θ ) ‖ β ‖ > λ c ϵ ‖ β ‖ 2 + ‖ β ‖ 2 = ( 1 + λ t ϵ ) ‖ β ‖ 2

βk>(1+λcϵ)k/2β0 ‖ β k ‖ > ( 1 + λ c ϵ ) k / 2 ‖ β 0 ‖ ,此时迭代将使得参数指数增长,参数必发散且必有损失函数趋于无穷大。

 改变损失函数本身性质,必须改变损失函数,即便这样做也很难保证不出现参数爆炸的情况。剩下的就是改变超参数 λ λ .
 任何时候,当你设定的学习率导致参数发散的时候,简单的办法就是降低学习率 λ λ ,破坏条件 λc>2 λ c > 2 从而避免参数发散。

1.2 震荡的原因

 不同于参数发散,损失函数值震荡,主要是因为在局部最优解附近学习率过大,导致迭代无法收敛到局部最优值。
假定 β β ∗ 是局部最优值,在局部最优值附近有 β=tα+β β = t α + β ∗ ,简单起见,不防设 ϕα=2Q(β)α ϕ α = ∇ 2 Q ( β ∗ ) α ,即恰好 α α 是损失函数在局部最优解附近的海塞矩阵的特征方向。
则得到过程可以表示为

λQ(β)β(0)β(1)β(2)β(k)tλ2Q(β)α=tλϕαtα+ββ(0)tλϕα=β+t(1λϕ)αβ(1)t(1λϕ)λϕα=β+t(1λϕ)2αβ+t(1λϕ)kα λ ∇ Q ( β ) ≈ t λ ∇ 2 Q ( β ∗ ) α = t λ ϕ α ⇓ β ( 0 ) ≈ t α + β ∗ β ( 1 ) ≈ β ( 0 ) − t λ ϕ α = β ∗ + t ( 1 − λ ϕ ) α β ( 2 ) ≈ β ( 1 ) − t ( 1 − λ ϕ ) λ ϕ α = β ∗ + t ( 1 − λ ϕ ) 2 α β ( k ) ≈ β ∗ + t ( 1 − λ ϕ ) k α

可以看到:
1. 若 0<(1λϕ)<1 0 < ( 1 − λ ϕ ) < 1 则迭代逐步趋向于 β β ∗ ;
2. 若 0>(1λϕ)>1 0 > ( 1 − λ ϕ ) > − 1 则迭代也会逐步趋向于 β β ∗ ,但每一步会跳过局部最优值;
3. 若 (1λϕ)>1 ( 1 − λ ϕ ) > 1 则迭代会逐步离开 β β ∗ ,有可能离开该局部最优值,也可能既无法离开也无法收敛,与损失函数更大范围的性质有关系,损失曲线一般表现出不规则震动;
4. 若 (1λϕ)=1 ( 1 − λ ϕ ) = − 1 则迭代表现出在两个值之间周期性跳转,损失曲线上可能看不到变化,也可能表现为震动。
因此若要保证收敛,还是需要缩小学习率 λ λ .

1.3 其他情况

 复杂模型,还会遇到梯度爆炸和梯度消失的问题,梯度消失则表明模型已经训练到达一个局部最优解。而梯度爆炸的问题是训练过程中更为麻烦的问题,它会迫使搜索脱离当前区域。
 样本数量改变经常导致损失函数变化,因此在小样本上训练收敛的参数,在大样本下可能仍然不收敛,这导致工程应用中有麻烦,没法设定固定的学习率。

二 实战研究

 下面以简单回归模型为例,说明学习率参数对机器学习收敛的影响。一般而言学习率由大到小,先导致发散,缩小学习率后误差震荡,继续缩小则训练过程收敛。 跟混沌理论差不多,导致震荡学习率有一个临界区间。同时学习率并不是越小越好,缩小学习率需要更多的迭代次数才能。
 给定模型 y=5x1+6x2+abx3 y = 5 x 1 + 6 x 2 + a b x 3 ,产生随机样本:

Num=1000
set.seed(1000)
x1 = runif(n = Num,min = -10,max = 3)
x2 = runif(n = Num,min = -5,max = 5)
x3 = runif(n = Num,min = -5,max = 10)
X=cbind(x1,x2,x3)
y=5*x1+6*x2+5*6*x3
sd(y)
# 添加随机误差
y=y+rnorm(Num,mean = 0,sd = 1)

模型的损失函数为: Q(a,b)=12ni=1(yiaxi1bxi2abxi3)2 Q ( a , b ) = 1 2 ∑ i = 1 n ( y i − a x i 1 − b x i 2 − a b x i 3 ) 2

梯度为:

Q(a)aQ(a)b=ni=1(yiaxi1bxi2abxi3)(xi1+bxi3)=ni=1(yixi1ax2i1bxi1xi2abxi1xi3+b(yixi3axi1xi3bxi2xi3abx2i3))=ni=1(yiaxi1bx2abxi3)(xi2+axi3)=ni=1(yixi2axi1xi1xi2bx2i2abxi2xi3+a(yixi3axi1xi3bxi2xi3abx2i3)) ∂ Q ( a ) ∂ a = − ∑ i = 1 n ( y i − a x i 1 − b x i 2 − a b x i 3 ) ( x i 1 + b x i 3 ) = − ∑ i = 1 n ( y i x i 1 − a x i 1 2 − b x i 1 x i 2 − a b x i 1 x i 3 + b ( y i x i 3 − a x i 1 x i 3 − b x i 2 x i 3 − a b x i 3 2 ) ) ∂ Q ( a ) ∂ b = − ∑ i = 1 n ( y i − a x i 1 − b x 2 − a b x i 3 ) ( x i 2 + a x i 3 ) = − ∑ i = 1 n ( y i x i 2 − a x i 1 x i 1 x i 2 − b x i 2 2 − a b x i 2 x i 3 + a ( y i x i 3 − a x i 1 x i 3 − b x i 2 x i 3 − a b x i 3 2 ) )

梯度下降迭代公式为:
a(k+1)=a(k)+λi=1n(yiaxi1bxi2abxi3)(xi1+bxi3)b(k+1)=b(k)+λi=1n(yiaxi1bx2abxi3)(xi2+axi3) a ( k + 1 ) = a ( k ) + λ ∑ i = 1 n ( y i − a x i 1 − b x i 2 − a b x i 3 ) ( x i 1 + b x i 3 ) b ( k + 1 ) = b ( k ) + λ ∑ i = 1 n ( y i − a x i 1 − b x 2 − a b x i 3 ) ( x i 2 + a x i 3 )

R语言实现迭代过程:

olm<-function(y,x,lambda=0.02,iter=100,beta=runif(n = 2,min = 0.01,max = 0.2)){
  stopifnot(length(y)==dim(x)[1])
   stopifnot(3==dim(x)[2])
  xy=c(t(y)%*%x)
  xx=t(x)%*%x
  #为了观察内部过程,需要将每一步迭代后的参数保留下来
  betas=data.frame(a=rep(0,iter+1),b=rep(0,iter+1))
  betas[1,]=beta
  for(i in 1:iter){
    b0=c(beta,beta[1]*beta[2])
    b1=matrix(data=c(1,0,0,1,beta[2:1]),nrow = 2)
    #browser()
    beta=beta +lambda*b1%*%(xy-xx %*%b0)
    betas[i+1,]=beta
  }
  betas
}
#betas=olm(y,X,lambda = 0.00056,iter = 1000)

计算每一步迭代后个损失函数值:

betas=olm(y,X,lambda =0.0000028,iter = 500)
beta2=betas
beta2[,3]=beta2[,1]*beta2[,2]
err=0.5*colSums((y-X%*%t(beta2))^2)/Num
plot(err,type = "l")

plot(betas,type="b")


 从上图可以看出,此参数使得训练在若干步后发散,损失值突然发散到无穷大,训练模型参数由于最后太大,导致之前的模型参数被压缩在一个极小的区域,从而在图上显示为一个点。

 重新调整初始化参数,缩小学习率参数,同时加大迭代次数,可以从下图中看到,这一次明显有误差震荡。

betas1=olm(y,X,lambda = 0.000002,iter = 1000)
beta2=betas1
beta2[,3]=beta2[,1]*beta2[,2]
err1=0.5*colSums((y-X%*%t(beta2))^2)/Num
plot(err1,type = "l")

plot(betas1,type="b")


 上面的参数,使得参数在最优值附近跳转,在损失函数值上看来,表现为震荡。迭代参数基本在一条直线上,这并不是偶然的,这条直线会逐步逼近损失函数在改局部最小值的Hassan矩阵的特征方向,一般而言是有最大特征值的特征方向。来看最后50次迭代情况。

plot(betas1[950:1000,],type="b")


继续缩小学习率。

betas1=olm(y,X,lambda =0.0000014,iter = 1000)
beta2=betas1
beta2[,3]=beta2[,1]*beta2[,2]
err1=0.5*colSums((y-X%*%t(beta2))^2)/Num
plot(err1[-c(1:2)],type = "l")

plot(betas1,type="b")

plot(betas1[950:1000,],type="o")


 这时,训练误差迅速逼近最小值,从模型参数迭代过程来看,参数迅速靠近(5,6)附近从最后一图来看,模型参数值移动范围越来越小。

三、梯度下降法的改进思路

 不管是参数发散还是震荡,归根揭底都是由于给定学习率后,跟梯度模长有关系,实际上在梯度越大的地方,损失函数变化越大,这时我们恰好需要更小的学习率以免模型参数下一步跑过最小值。事实上梯度下降法的关键是梯度方向,而不是梯度的模长,而模长依赖于样本数据,尤其当样本数量变化时,对梯度影响更加明显,更多的样本量意味着需要更小的参数,而机器学习需要的样本越多越好。
 随机梯度下降法可以控制每次参与,但每次参与计算样本数量仍然对学习率参数有显著的影响。比较更好的办法是控制梯度模长,因为对于模型训练结果而言,尽需要保证每次迭代的梯度方向大致正确。
比随机梯度更彻底的办法是,是控制梯度模长。保障 V=tQ(β)|β=βold;βnew=βoldλV V = t ∇ Q ( β ) | β = β o l d ; β n e w = β o l d − λ V 迭代参数仍然可以做到收敛。若能任何时候保障 |V|<M | V | < M ,有

βλV2=β22cos(θ)λVβ+λ2V2=β2+λV(λV2cos(θ)β) ‖ β − λ V ‖ 2 = ‖ β ‖ 2 − 2 c o s ( θ ) λ ‖ V ‖ ‖ β ‖ + λ 2 ‖ V ‖ 2 = ‖ β ‖ 2 + λ ‖ V ‖ ( λ ‖ V ‖ − 2 c o s ( θ ) ‖ β ‖ )

 只要给定 λV<λM<2 λ ‖ V ‖ < λ M < 2 就能破坏参数发散的条件,也能避免当局部梯度太大时,模型参数 β β 脱离当前搜索区域,使得梯度下降法搜索趋于稳定。
这个改动可以避免参数发散的问题,也能避免梯度爆炸的问题,代价是训练过程需要更多的迭代次数,增加计算复杂。
一般我们可以取:
V=Q(β)max(Q(β)),1) V = ∇ Q ( β ) m a x ( ‖ ∇ Q ( β ) ‖ ) , 1 )

 此时,从而有 ||V||1 | | V | | ≤ 1 取范数取 p p − ∞ ,计算过程相对简单。
 令一种办法是取 V=sign(Q(β)) V = s i g n ( ∇ Q ( β ) ) ,能大致保持梯度方向,并且有 ||V||m | | V | | ≤ m m m <script type="math/tex" id="MathJax-Element-4404">m</script>是参数个数,这个计算也很简单,尤其是在分布式集群上运算的时候。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值