机器学习——梯度下降

本文主要讲解梯度下降的数学推导,并假定读者已经了解梯度下降的思想,不适合没有任何基础的同学

推荐博客 梯度下降
https://imgconvert.csdnimg.cn/aHR0cHM6Ly9oaXBob3Rvcy5iYWlkdS5jb20vZmVlZC9waWMvaXRlbS81ODgyYjJiN2QwYTIwY2Y0MjRlNDg0ZDQ3YjA5NGIzNmFjYWY5OTQwLmpwZw
了解上述推荐博客后,我们来推导一下最简单的梯度下降方法

很明显,梯度下降主要用于解决无约束的最优化问题,我们以最小化损失函数为例
θ ∗ = arg ⁡ min ⁡ θ L ( θ ) \theta^* = \mathop{\arg \min_{\theta}L(\theta)} θ=argθminL(θ)

首先我们画出损失函数 L ( θ ) L(\theta) L(θ)的等高线(这里是用两个自变量为例的 θ 1 , θ 2 \theta_1,\theta_2 θ1,θ2
在这里插入图片描述
我们最终的目标就是求出 θ ∗ \theta^* θ使得 L ( θ ) L(\theta) L(θ)最小。

首先,我们随机的取一个点,假定为 ( θ 1 ′ , θ 2 ′ ) (\theta_1^{'},\theta_2^{'}) (θ1,θ2),接下来我们需要确定下一步我们要向哪边走。

此点的损失函数为(泰勒计数,仅仅展开到一阶)
L ( θ ) = L ( θ 1 ′ , θ 2 ′ ) + ∂ L ( θ 1 ′ , θ 2 ′ ) ∂ θ 1 ( θ 1 − θ 1 ′ ) + ∂ L ( θ 1 ′ , θ 2 ′ ) ∂ θ 2 ( θ 2 − θ 2 ′ ) L(\theta) = L(\theta_1^{'},\theta_2^{'})+\frac{\partial L(\theta_1^{'},\theta_2^{'}) }{\partial \theta_1}(\theta_1 - \theta_1^{'}) + \frac{\partial L(\theta_1^{'},\theta_2^{'})}{\partial \theta_2}(\theta_2 - \theta_2^{'}) L(θ)=L(θ1,θ2)+θ1L(θ1,θ2)(θ1θ1)+θ2L(θ1,θ2)(θ2θ2)

首先明确目标是为了使得 L ( θ ) L(\theta) L(θ)最小,又因为 L ( θ 1 ′ , θ 2 ′ ) L(\theta_1^{'},\theta_2^{'}) L(θ1,θ2) ∂ L ( θ 1 ′ , θ 2 ′ ) ∂ θ 1 \frac{\partial L(\theta_1^{'},\theta_2^{'})}{\partial \theta_1} θ1L(θ1,θ2), ∂ L ( θ 1 ′ , θ 2 ′ ) ∂ θ 2 \frac{\partial L(\theta_1^{'},\theta_2^{'})}{\partial \theta_2} θ2L(θ1,θ2)都是常数,所以只能让 ∂ L ( θ 1 ′ , θ 2 ′ ) ∂ θ 1 ( θ 1 − θ 1 ′ ) + ∂ L ( θ 1 ′ , θ 2 ′ ) ∂ θ 2 ( θ 2 − θ 2 ′ ) \frac{\partial L(\theta_1^{'},\theta_2^{'}) }{\partial \theta_1}(\theta_1 - \theta_1^{'}) + \frac{\partial L(\theta_1^{'},\theta_2^{'})}{\partial \theta_2}(\theta_2 - \theta_2^{'}) θ1L(θ1,θ2)(θ1θ1)+θ2L(θ1,θ2)(θ2θ2)取得最小值,首先我们在图中画出两个偏导数的向量(即 ∂ L ( θ 1 ′ , θ 2 ′ ) ∂ θ 1 \frac{\partial L(\theta_1^{'},\theta_2^{'})}{\partial \theta_1} θ1L(θ1,θ2), ∂ L ( θ 1 ′ , θ 2 ′ ) ∂ θ 2 \frac{\partial L(\theta_1^{'},\theta_2^{'})}{\partial \theta_2} θ2L(θ1,θ2)),由于本文以二维表示,故尚可在平面中画出,如果自变量维数增多,便很难进行可视化。
在这里插入图片描述
图中 △ θ 1 = θ 1 − θ 1 ′ \triangle \theta_1 =\theta_1 - \theta_1^{'} θ1=θ1θ1 △ θ 2 = θ 2 − θ 2 ′ \triangle \theta_2 =\theta_2 - \theta_2^{'} θ2=θ2θ2 u = ∂ L ( θ 1 ′ , θ 2 ′ ) ∂ θ 1 u = \frac{\partial L(\theta_1^{'},\theta_2^{'})}{\partial \theta_1} u=θ1L(θ1,θ2) v = ∂ L ( θ 1 ′ , θ 2 ′ ) ∂ θ 2 v = \frac{\partial L(\theta_1^{'},\theta_2^{'})}{\partial \theta_2} v=θ2L(θ1,θ2)

由上图可以很明显的看出,只有 ( △ θ 1 , △ θ 2 ) (\triangle \theta_1 ,\triangle \theta_2) (θ1,θ2) ( u , v ) (u,v) (u,v)反向而且取得最长时,使得 L ( θ ) L(\theta) L(θ)最小。即为 − η ( u , v ) T - \eta (u,v)^T η(u,v)T

由于 L ( θ ) L(\theta) L(θ)的近似公式是由泰勒级数展开获得的,所以一定要要满足 ( θ 1 − θ 1 ′ ) ⟶ 0 (\theta_1 - \theta_1^{'})\longrightarrow 0 (θ1θ1)0 ( θ 2 − θ 2 ′ ) ⟶ 0 (\theta_2 - \theta_2^{'})\longrightarrow 0 (θ2θ2)0
由此可以得出约束条件
( θ 1 − θ 1 ′ ) 2 + ( θ 2 − θ 2 ′ ) 2 ≤ d 2 (\theta_1 - \theta_1^{'}) ^2+(\theta_2 - \theta_2^{'}) ^2 \le d^2 (θ1θ1)2+(θ2θ2)2d2
其中 d ⟶ 0 d \longrightarrow 0 d0

到此我们可以得出如果要让 L ( θ ) L(\theta) L(θ)最小,此时 θ 1 \theta_1 θ1 θ 2 \theta_2 θ2 需要满足的条件为

( θ 1 , θ 2 ) T = ( θ 1 ′ , θ 2 ′ ) T − η ( u , v ) T (\theta_1, \theta_2)^T = (\theta_1^{'}, \theta_2^{'})^T- \eta (u,v)^T (θ1,θ2)T=(θ1,θ2)Tη(u,v)T

即为本文第二个图,从一个圈,尽最大可能向最小点迈进,从而开始下一圈的迈进。

这就是我们套用的梯度下降的公式,经过公式推导可以看出由于受到泰勒级数条件的限制,其中的 η \eta η 应该是趋近于0的,这样才能保证寻找局部最优值。但是在实际的训练过程中, η \eta η的值可以认为进行设定,这样也就能解释为何在 η \eta η过大的时候,会使得损失函数 L ( θ ) L(\theta) L(θ) 增大。


下面用python 写一下梯度下降
本文以 f ( x ) = b + w x f(x) = b+wx f(x)=b+wx 为例
其损失函数为 L ( w , b ) = ( y i − f ( x i ) ) 2 L(w,b) = (y_i - f(x_i))^2 L(w,b)=(yif(xi))2
偏导数为
∂ L ∂ w = 2 ∗ ( y i − f ( x i ) ) ∗ x i \frac{\partial L}{\partial w} = 2*(y_i - f(x_i))*x_i wL=2(yif(xi))xi
∂ L ∂ b = 2 ∗ ( y i − f ( x i ) ) ∗ 1 \frac{\partial L}{\partial b} = 2*(y_i - f(x_i))*1 bL=2(yif(xi))1

由梯度公式得

b = b − l e a r n _ r a t i o × ∂ L ∂ b b = b - learn\_ratio \times \frac{\partial L}{\partial b} b=blearn_ratio×bL
w = w − l e a r n _ r a t i o × ∂ L ∂ w w = w - learn\_ratio \times \frac{\partial L}{\partial w} w=wlearn_ratio×wL

每次更新去平均值作为更新值

# Gradient Decesent
# @author Hongchuan CAO

import numpy as np
import matplotlib.pyplot as plt

class SGD:

    def __init__(self):
        # self.x_data = [338., 333., 328., 207., 226., 25., 179., 60., 208., 606.]
        # self.y_data = [640., 633., 619., 393., 428., 27., 193., 66., 226., 1591]
        self.x_data = [100, 80, 120, 75, 60, 43, 140, 132, 63, 55, 74, 44, 88]
        self.y_data = [120, 92, 143, 87, 60, 50, 167, 147, 80, 60, 90, 57, 99]


    def regression(self):
        self.b = 10
        self.w = 1
        iteration = 100000  # 迭代次数
        ratio = 0.00001     #学习率
 
        for i in range(iteration):
            w_ratio = 0
            b_ratio = 0

            for j in range(len(self.x_data)):
                w_ratio = w_ratio + 2*(self.b+self.w*self.x_data[j]-self.y_data[j])*self.x_data[j]
                b_ratio = b_ratio + 2*(self.b+self.w*self.x_data[j]-self.y_data[j])*1
			
			#将样例数据取平均
            self.w = self.w - ratio* w_ratio /len(self.x_data) 
            self.b = self.b - ratio* b_ratio /len(self.x_data)
            #print(str(i)+" "+str(self.w) + " " + str(self.b))



    def plot1(self):
    	#离散数据点
        plt.scatter(self.x_data,self.y_data)

        xx = [x for x in np.arange(0,max(self.x_data),1)]
        yy = []
        for i in range(len(xx)):
            yy.append(self.w*xx[i]+self.b)
		# 回归
        plt.plot(xx,yy,'b-')
        plt.show()


if __name__ == '__main__':
    obj = SGD()
    obj.regression()
    obj.plot1()

结果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值