深度学习的优化算法——梯度下降和随机梯度下降

深度学习的优化算法——梯度下降和随机梯度下降

优化算法在深度学习中存在的问题

优化在深度学习中有很多挑战,下面描述其中两个,局部最小值和鞍点。

1.局部最小值

深度学习模型的目标函数可能存在若干极点——局部最优解(local mininum)。当一个优化问题的数值解在局部最优解附近时,此时目标函数关于自变量的梯度接近零甚至变成零,导致迭代无法继续进行下去,最终求的的数值解只能局部最优而非全局最优(global minimun)

2.鞍点

刚刚我们提到,梯度接近或变为零可能是由于当前解在局部最优解附近造成的。事实上,另一种可能性是当前解在鞍点(saddle point) 附近。
以一维函数f(x)=x3为例,其鞍点位于(0,0)。
下面以二维函数f(x)=x2-y2为例,首先画出其图像。

import numpy as np
x,y=np.mgrid[-1:1:31j,-1:1:31j]
z=x**2-y**2
#划分网格。31j为复数,代表在-1到1之间插入31个值,若为实数则代表步长。
ax=plt.figure().add_subplot(111,projection='3d')
#111代表一共1x1个图,返回的是第一个图。projection代表投影方式,为3d投影
ax.plot_wireframe(x,y,z,**{'rstride':2,'cstride':2})
#由于先前将x,y分成了31x31的网格,这里不想看起来得太密,rstride和cstride就可以设置网格现实的步长,即每隔一条显示一条。**{}
#即把字典中的值取出,等价于rstride=2,cstride=2
ax.plot([0],[0],[0],'rx')
ticks=[-1,0,1]
plt.xticks(ticks)
plt.yticks(ticks)
ax.set_zticks(ticks)

在这里插入图片描述
在图的鞍点位置,目标函数在x方向上是局部最小值,但在y方向上是局部最大值。
假设一个函数的输入为k维度向量,输出为标量,那么他的**海森矩阵(Hessian matrix)**有k个特征值,该函数在梯度为零的位置上可能是局部最小值、局部最大值或鞍点。

  • 当函数的海森矩阵在梯度为零的位置上的特征值全为正时,该函数得到局部最小值。
  • 当函数的海森矩阵在梯度为零的位置上的特征值全为负时,该函数得到局部最大值。
  • 当函数的海森矩阵在梯度为零的位置上的特征值有正有负时,该函数得到鞍点。

由于深度学习模型参数多数是高维的,目标函数的鞍点通常比局部最小值更常见。

梯度下降和随机梯度下降

1.一维梯度下降

根据泰勒公式 f ( x + ϵ ) ≈ f ( x ) + ϵ f ′ ( x ) f(x+\epsilon)\approx f(x)+\epsilon f'(x) f(x+ϵ)f(x)+ϵf(x) ϵ \epsilon ϵ 越小越接近相等。
f ( x ) f(x) f(x)为损失函数时,我们希望找到合适的 ϵ \epsilon ϵ , 使 f ( x + ϵ ) < f ( x ) f(x+\epsilon)< f(x) f(x+ϵ)<f(x),即令 ϵ f ′ ( x ) < 0 \epsilon f'(x)<0 ϵf(x)<0 。接下来,找到一个常数 η > 0 \eta>0 η>0,使 | η f ′ ( x ) | |\eta f'(x)| ηf(x)足够小,那么可以将 ϵ \epsilon ϵ替换成 − η f ′ ( x ) -\eta f'(x) ηf(x)并得到 f ( x − η f ′ ( x ) ) ≈ f ( x ) − η f ′ ( x ) 2 f(x-\eta f'(x))\approx f(x)-\eta f'(x)^2 f(xηf(x))f(x)ηf(x)2如果导数 f ′ ( x ) ! = 0 f'(x)!=0 f(x)!=0,那么 η f ′ ( x ) 2 > 0 \eta f'(x)^2>0 ηf(x)2>0,所以 f ( x − η f ′ ( x ) ) < = f ( x ) f(x-\eta f'(x))<= f(x) f(xηf(x))<=f(x)这意味着,如果通过 x ⇐ x − η f ′ ( x ) x\Leftarrow x-\eta f'(x) xxηf(x)来迭代 x x x,损失函数值可能会降低。这解释了学习率大于零且不可过大。
下面以 f ( x ) = x 2 f(x)=x^2 f(x)=x2为例解释梯度下降是怎么工作的。

import numpy as np
from matplotlib import pyplot as plt
def gd(lr):
    x=10
    results=[x]
    for i in range(10):
        x-=lr*2*x
        results.append(x)
    print('epoch 10,x:',x)
    return results
def show_trace(res):
    n=max(abs(min(res)),abs(max(res)),10)
    f_line=np.arange(-n,n,0.1)
    plt.figure()
    plt.plot(f_line,[x**2 for x in f_line])
    plt.plot(res,[x**2 for x in res],'-o')
    plt.xlabel('x')
    plt.ylabel('f(x)')
res=gd(0.2)
show_trace(res)

epoch 10,x: 0.06046617599999997
在这里插入图片描述
可见迭代10次后,x的值较接近最优解。

2.多维梯度下降

下面以多元函数 f ( x ) = x 1 2 + 2 x 2 2 f(x)=x_1^2+2x_2^2 f(x)=x12+2x22为例,通过绘制等高图来观察如何迭代到最优解的。我们将从(-5,-2)为起点对(x1,x2)进行迭代。

import numpy as np
from matplotlib import pyplot as plt
def train_2d(trainer):
    x1,x2,s1,s2=-5,-2,0,0
    results=[(x1,x2)]
    for i in range(20):
        x1,x2,s1,s2=trainer(x1,x2,s1,s2)
        results.append((x1,x2))
        print('epoch %d,x1 %f,x2 %f' % (i+1,x1,x2))
    return results
def show_trace_2d(f,results):
    plt.plot(*zip(*(results)),'-o',color='#ff7f0e')
    #x,y=np.mgrid([-5.0,1.0,0.1],[-3.0,1.0,0.1])
   x,y=np.meshgrid(np.arange(-5.0,1.0,0.1),np.arange(-3.0,1.0,0.1))
    C=plt.contour(x,y,f(x,y),color='#1f77b4')
    plt.xlabel('x1')
    plt.ylabel('x2')
    plt.clabel(C)

关于*zip(*(results))的说明:
results本是一个列表,其中每个元素为坐标(元组),例如results=[(1,2),(3,4),(5,6)]。
*results的作用在于将results“打散”,变为*results=(1,2),(3,4),(5,6)。
zip的作用在于“封装”,将上一步相同位置或相同地位的元素封装在一起,zip(*results)=(1,3,5),(2,4,6)。但该步骤得到的是一个zip实例,plt.plot()需要两个列表或者元组参数,所以需要将该zip实例再次打散,得到两个元组,传入plot()

lr=0.1
def f_2d(x1,x2):
    return x1**2+2*x2**2
def gd_2d(x1,x2,s1,s2):
    return x1-lr*2*x1,x2-lr*4*x2,0,0
show_trace_2d(f_2d,train_2d(gd_2d))

输出图像如下:good😌
在这里插入图片描述

3.随机梯度下降

在深度学习中,目标函数通常是训练数据集中各个样本的损失函数的平均,即 ∇ f ( x ) = 1 n ∑ i = 1 n ∇ f i ( x ) \nabla f(x)=\frac{1}{n} \sum_{i=1}^n \nabla f_i(x) f(x)=n1i=1nfi(x)如果使用梯度下降,每次迭代计算开销为 O n O_n On,当训练数据样本数很大时,计算开销很高。
**随机梯度下降(stochastic gradient descent,SGD)**随机采样一个样本,以该样本代替原梯度。这样本次迭代的计算量由 O n O_n On下降到了 O 1 O_1 O1。值得注意的是,随机梯度 ∇ f i ( x ) \nabla f_i(x) fi(x)是对梯度 ∇ f ( x ) \nabla f(x) f(x)的无偏估计(期望相同)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值