最优化算法-梯度下降法

  梯度下降(gradient descent)是机器学习中的一种最优化算法,广泛应用于线性回归和逻辑回归中。它的核心思想是:要获得函数的最小值,最好的方法是沿着该函数的梯度的反方向探寻。
  假设这样一个场景:你当前在半山腰上,想要走到山脚下。但这时雾特别大,你只能看到2米远的距离,不能看到山脚的方向。这种情况下,如何继续往山脚的方向走呢?你只要看自己的脚下,往地面坡度下降最大的方向走,如果在地面放一个球,即是球滚动的方向,走完一步后,重新找下山方向,如此继续走下去,就走到山脚下了。
在这里插入图片描述

  梯度下降的过程类似于下山的场景,对于一个可微分的函数,要找到函数的极小值,就是要沿着的梯度的反方向走,通过不断迭代,最终到达最低点。

梯度下降

  梯度的本意是一个向量,表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大(此梯度的模)。梯度的表示如下:
< ∂ f ∂ x , ∂ f ∂ y , ∂ f ∂ z > < \frac{\partial f}{\partial x},\frac{\partial f}{\partial y},\frac{\partial f}{\partial z}> <xf,yf,zf>

  在单变量函数中,梯度其实就是函数的导数,其几何意义是该函数在某个给定点的切线的斜率。比如函数 y = x 2 y=x^2 y=x2,它的导数为 y ′ = 2 x y'=2x y=2x,对于函数上的任意一点 x 0 x_0 x0,该点的梯度为 2 x 0 2x_0 2x0
  在多变量函数中,梯度是一个向量,向量有方向,指向的是函数在给定点上升最快的方向。向量的每一个分量是该函数对每一个变量的导数。比如函数 f ( x , y ) = x 2 + y 2 f(x,y)=x^2+y^2 f(x,y)=x2+y2,该函数在点 ( x 0 , y 0 ) (x_0,y_0) (x0,y0)处的梯度为 ( 2 x 0 , 2 y 0 ) (2x_0,2y_0) (2x0,2y0)
  对于函数 J ( θ ) J(\theta) J(θ),假设上一个给定点为 θ t − 1 \theta^{t-1} θt1,则沿梯度负方向的下一个点:
θ t = θ t − 1 + Δ θ \theta^t = \theta^{t-1} + \Delta \theta θt=θt1+Δθ

  将 J ( θ t ) J( \theta^t ) J(θt) θ t − 1 \theta^{t-1} θt1处进行一阶泰勒展开,泰勒公式的内容可学习前文《如何理解泰勒公式?》
J ( θ t ) = J ( θ t − 1 + Δ θ ) ≈ J ( θ t − 1 ) + J ′ ( θ t − 1 ) Δ θ \begin{aligned} J( \theta^t ) &= J(\theta^{t-1} + \Delta \theta) \\ &\approx J(\theta^{t-1}) + J'( \theta^{t-1})\Delta \theta \end{aligned} J(θt)=J(θt1+Δθ)J(θt1)+J(θt1)Δθ

  要使 J ( θ t ) < J ( θ t − 1 ) J( \theta^t ) < J(\theta^{t-1}) J(θt)<J(θt1),可取: Δ θ = − α J ′ ( θ t − 1 ) \Delta \theta = -\alpha J'(\theta^{t-1}) Δθ=αJ(θt1),则
θ t = θ t − 1 − α J ′ ( θ t − 1 ) \theta^t = \theta^{t-1} -\alpha J'(\theta^{t-1}) θt=θt1αJ(θt1)

其中 α \alpha α为步长,又称学习率,是一个需要设置的超参数。步长决定了在梯度下降迭代的过程中,每一步沿梯度负方向前进的长度,步长设置过小,需要花费的学习时间就很长,设置过大,就可能在最小值附近来回震荡。
  举例来讲,给定一个多元目标函数: J ( Θ ) = θ 1 2 + θ 2 2 J(\Theta)=\theta^2_1+\theta^2_2 J(Θ)=θ12+θ22

  现在要通过梯度下降法计算这个函数的最小值。通过观察就能知道最小值所在的点是(0,0),使用梯度下降法也可以一步步的得到这个最小值点。
  首先设定一个初始的起点为:
Θ 0 = ( 1 , 3 ) \Theta^0=(1,3) Θ0=(1,3)

  初始的学习率设为:
α = 0.1 \alpha=0.1 α=0.1

  函数的梯度为:
Δ J ( Θ ) = ( 2 θ 1 , 2 θ 2 ) \Delta J(\Theta)=(2\theta_1,2\theta_2) ΔJ(Θ)=(2θ1,2θ2)

  进行如下多轮迭代:
Θ ( 0 ) = ( 1 , 3 ) Θ ( 1 ) = Θ ( 0 ) − α Δ J ( Θ ( 0 ) ) = ( 1 , 3 ) − 0.1 ( 2 , 6 ) = ( 0.8 , 2.4 ) Θ ( 2 ) = Θ ( 1 ) − α Δ J ( Θ ( 1 ) ) = ( 0.8 , 2.4 ) − 0.1 ( 1.6 , 4.8 ) = ( 0.64 , 1.92 ) Θ ( 3 ) = ( 0.512 , 1.536 ) Θ ( 4 ) = ( 0.4096 , 1.2288 ) . . . . . . . . . . \begin{aligned} \Theta^{(0)}&=(1,3) \\ \Theta^{(1)}&=\Theta^{(0)}-\alpha \Delta J(\Theta^{(0)}) \\ &=(1,3)-0.1(2,6) \\ &=(0.8,2.4) \\ \Theta^{(2)}&=\Theta^{(1)}-\alpha \Delta J(\Theta^{(1)}) \\ &=(0.8,2.4)-0.1(1.6,4.8) \\ &=(0.64,1.92) \\ \Theta^{(3)}&= (0.512,1.536)\\ \Theta^{(4)}&= (0.4096,1.2288)\\ &..........\\ \end{aligned} Θ(0)Θ(1)Θ(2)Θ(3)Θ(4)=(1,3)=Θ(0)αΔJ(Θ(0))=(1,3)0.1(2,6)=(0.8,2.4)=Θ(1)αΔJ(Θ(1))=(0.8,2.4)0.1(1.6,4.8)=(0.64,1.92)=(0.512,1.536)=(0.4096,1.2288)..........

  最终,迭代结果不断逼近最优参数,即 Θ = ( 0 , 0 ) \Theta= (0,0) Θ=(0,0)

编程实战

  给定20个身高-体重样本,如下图所示。显然,可以用一条直线拟合图上的点。
在这里插入图片描述
  假设我们要拟合的这条直线为: y ^ = θ 0 + θ 1 x \hat{y}=\theta_0+\theta_1x y^=θ0+θ1x

  为了评估模型拟合的好坏,需要定义一个损失函数(loss function),损失函数越小,意味着拟合程度最好,对应的模型参数即为最优参数。一般定义该模型的预测值与真实值的误差为损失函数: L = ∣ y ^ − y ∣ L = |\hat{y}-y| L=y^y

其中 y ^ \hat{y} y^为预测值, y y y为真实值
  这里,我们只使用风险损失(均方误差)来评估模型拟合程度,省略结构损失,即目标函数(成本函数)为:
J ( Θ ) = 1 N ∑ i = 1 N ( y i ^ − y i ) 2 J(\Theta)=\frac{1}{N}\sum^N_{i=1}(\hat{y_i}-y_i)^2 J(Θ)=N1i=1N(yi^yi)2

  梯度为:
Δ J ( Θ ) = < ∂ J ∂ θ 0 , ∂ J ∂ θ 1 > \Delta J(\Theta)=<\frac{\partial J}{\partial \theta_0},\frac{\partial J}{\partial \theta_1}> ΔJ(Θ)=<θ0J,θ1J>

  梯度的偏导数为
∂ J ∂ θ 0 = ∂ ( y ^ − y ) 2 ∂ θ 0 = 2 ( y ^ − y ) ∂ ( y ^ − y ) ∂ θ 0 = 2 ( θ 0 + θ 1 x − y ) ∂ ( θ 0 + θ 1 x − y ) ∂ θ 0 = 2 ( θ 0 + θ 1 x − y ) ∂ J ∂ θ 1 = 2 ( θ 0 + θ 1 x − y ) x \begin{aligned} \frac{\partial J}{\partial \theta_0}&=\frac{\partial (\hat{y}-y)^2}{\partial \theta_0} \\ &=2(\hat{y}-y)\frac{\partial (\hat{y}-y)}{\partial \theta_0} \\ &=2(\theta_0+\theta_1x-y)\frac{\partial (\theta_0+\theta_1x-y)}{\partial \theta_0} \\ &=2(\theta_0+\theta_1x-y) \\ \frac{\partial J}{\partial \theta_1}&=2(\theta_0+\theta_1x-y)x \end{aligned} θ0Jθ1J=θ0(y^y)2=2(y^y)θ0(y^y)=2(θ0+θ1xy)θ0(θ0+θ1xy)=2(θ0+θ1xy)=2(θ0+θ1xy)x

  我们可以基于经验画一条拟合直线,通过梯度下降法,不断优化参数,达到最好的拟合效果,如下图所示:
在这里插入图片描述

import numpy as np
#创建包含20个样本的数据集
def createDataSet():
    #特征:身高、体重
    dataSet = \
    [\
        [208.,110.],\
        [203.,107.],\
        [196.,94.],\
        [191.,92.],\
        [188.,87.],\
        [183.,85.],\
        [178.,81.],\
        [174.,77.],\
        [171.,78.],\
        [167.,73.],\
        [163.,74.],\
        [159.,68.],\
        [157.,64.],\
        [153.,59.],\
        [148.,56.],\
        [141.,54.],\
        [139.,55.],\
        [135.,45.],\
        [131.,47.],\
        [128.,40.]\
    ]
    labels = ['height','weight']
    return dataSet, labels

# 生成数据集
dataSet,labels = createDataSet()
heightList =[item[0] for item in dataSet]
weightList =[item[1] for item in dataSet]
m = np.shape(dataSet)[0]     #数据集大小
X0 = np.mat(np.ones((m,1)))  # m行1列的矩阵
X1 = np.mat(dataSet)[:,0]    
X = np.hstack((X0,X1))       # 按照列堆叠形成新矩阵
Y = np.mat(dataSet)[:,1]
alpha = 0.00005  # 学习率(步长)

# 定义代价函数
def cost_function(theta, X, Y):
    error = X * theta - Y # 损失函数
    return (1/(2*m)) * (error.T * error) #成本函数

# 定义梯度函数
def gradient_function(theta, X, Y):
    diff = X * theta - Y
    return (1./m) * (X.T * diff)

# 梯度下降迭代:
def gradient_descent(X, Y ,alpha):
    theta = np.mat([[-90],[0.9]])
    gradient = gradient_function(theta, X ,Y)
    while not all(abs(gradient) <= 1e-3):
        theta = theta - alpha * gradient
        gradient = gradient_function(theta, X ,Y)
    return theta

optimal = gradient_descent(X, Y ,alpha)
print('optimal:', optimal)
print('cost function:', cost_function(optimal, X, Y)[0,0])

# 根据数据画出对应的图像
def plot(X, Y, theta):
    %matplotlib inline
    import matplotlib.pyplot as plt
    p1 = plt.scatter(X,Y,c='blue', marker='o')
    x = np.arange(120, 215, 0.1)
    y = x*theta[1,0]+theta[0,0]
    p2 = plt.plot(x,y,c='red')
    plt.xlabel("height(cm)")
    plt.ylabel("weight(kg)")
    plt.show()

plot(X1.T.A[0], Y.T.A[0], optimal)

  最终得到的拟合函数为 y ^ = 0.81343906 x − 62.44718038 \hat{y}=0.81343906x-62.44718038 y^=0.81343906x62.44718038,拟合直线如下图所示:
在这里插入图片描述

小结

  梯度下降法是求解无约束最优化问题的一种常用方法,具有实现简单的优点。它是一种迭代算法,每一步需要求解目标函数的梯度向量。
  当目标函数是凸函数时,梯度下降法的解是全局最优解。一般情况下,其解不保证是全局最优解。在线性回归和逻辑回归算法中,他们的损失函数是严格意义上的凸函数,存在全局唯一的极小值,只要有足够的迭代次数,一定可以到达极小值点。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值