精华内容
下载资源
问答
  • 梯度下降算法代码及详细解释(非常易懂)Matlab代码,有详细图文解释,适合小白,全面介绍算法原理和公式推导
  • 上一期有写过关于机器学习的基础概念和梯度下降算法的基础公式和三种分类 今天内容: 1.梯度下降算法的矩阵算法及代码实现 2.凸函数 3.海森矩阵与泰勒展开式

    梯度下降算法的矩阵算法及代码实现:

    由上期梯度下降算法中公式可看出,主要难点在于梯度的计算,即公式中1mi=1m(hθ(xi)yi)\frac{1}{m}\sum_{i=1}^{m}(h _{\theta}(xi)-yi) 部分的计算.
    这部分的计算用矩阵形式来算的话会更容易理解一些,接下来要开始用代码矩阵来算梯度咯!
    首先

    导包:

    import numpy as np
    import os    #系统
    %matplotlib inline 
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    

    #随机种子

    np.random.seed(42)
    

    #保存图像

    DIR = '.'   # 当前目录
    

    #定义存储图片的函数

    def save_fig(fig_id,tight_layout = True):
        path = os.path.join(DIR,fig_id + '.png')    # 设置图片要保存在的路径
    #path = os.path.join(DIR,'images',MODEL_ID ,fig_id +'.png')
        print('Saving figure',fig_id)               # 打印存储过程
        plt.savefig(path,format='png',dpi=300)      # 保存图片
    

    #过滤警告信息

    import warnings
    warnings.filterwarnings(action='ignore',message='internal gelsd')
    

    #生成训练数据

    #(特征部分)
    X = 2*np.random.rand(100,1)   
    #(标签部分)
    y = 4 + 3 * X + np.random.randn(100,1)  
    

    #画原始数据的图像

    plt.plot(X,y,'b.')
    plt.xlabel('$x_1$',fontsize=18)
    plt.ylabel('$y$',rotation=0,fontsize=18)
    plt.axis([0,2,0,15])    # 横纵坐标轴刻度大小
    save_fig('generated_data_plot')     # 保存图片
    plt.show()
    

    #添加新特征

    X_b = np.c_[np.ones((100,1)),X]
    

    #创建测试数据

    X_new = np.array([[0],[2]])
    X_new_b = np.c_[np.ones((2,1)),X_new]
    

    1. 用现成包做线性回归模型

    #从sklearn包里导入线性回归模型
    from sklearn.linear_model import LinearRegression
    #创建线性回归对象
    lin_reg = LinearRegression()
    #拟合训练数据
    lin_reg.fit(X,y)
    #输出截距,斜率
    lin_reg.intercept_,lin_reg.coef_
    
    #对策测试集进行预测
    lin_reg.predict(X_new)
    

    预测结果为:
    array([[4.21509616],
    [9.75532293]])

    2.手写代码

    ①.批量梯度下降
    eta = 0.1   # 步长,学习率
    n_iterations = 1000       #迭代次数
    m = 100              #数据量
    theta = np.random.randn(2,1)    #随机取θ
    
    for iteration in range(n_iterations):
        gradients = 2/m * X_b.T.dot(X_b.dot(theta) - y)
        theta = theta - eta * gradients
    
    theta_path_bgd = []
    def plot_gradient_descent(theta,eta,theta_path=None):
        m = len(X_b)
        plt.plot(X,y,'b.')
        n_iterations = 1000
        for iteration in range(n_iterations):
            if iteration < 10:
                y_predict = X_new_b.dot(theta)
                style = 'b-'
                plt.plot(X_new,y_predict,style)
            gradients = 2/m * X_b.T.dot(X_b.dot(theta) - y)
            theta = theta - eta * gradients
            if theta_path is not None:
                theta_path.append(theta)
        plt.xlabel('$x_1$',fontsize = 18)
        plt.axis([0,2,0,15])
        plt.title(r'$\eta = {}$'.format(eta),fontsize = 16)
    
    np.random.seed(42)
    theta = np.random.randn(2,1)
    
    plt.figure(figsize = (10,4))
    plt.subplot(131);plot_gradient_descent(theta,eta = 0.02)
    plt.ylabel('$y$',rotation = 0,fontsize = 18)
    plt.subplot(132);plot_gradient_descent(theta,eta = 0.1,theta_path = theta_path_bgd)
    plt.subplot(133);plot_gradient_descent(theta,eta = 0.5)
    
    save_fig('gradient_descent_plot')
    plt.show()
    

    上述代码中gradients的求法用的便是矩阵算法:

    其中
    X_b.dot(theta) 是100行2列的矩阵*2行1列的矩阵,求出的值即为hθ=θ0+θ1x h _{\theta} = \theta _{0}+ \theta _{1}\cdot x
    y的值是一100行1列的矩阵,则 X_b.dot(theta) - y 的最终值为100行1列的矩阵.
    X_b.T 是100行两列的X_b矩阵的转置,转制为2行,100列的矩阵,最终与上述 X_b.dot(theta) - y 最终的100行1列值相乘,结果为两个值,两列一行,求出的值即为 θ0,θ1 \theta _{0}, \theta _{1}

    依次循环,则gradients的值在不断更新迭代,最终绘出线性回归模型为:
    在这里插入图片描述

    ②.随机梯度下降
    theta_path_sgd = []
    m = len(X_b)
    np.random.seed(42)
    
    n_epochs = 5
    
    theta = np.random.randn(2,1)
    
    for epoch in range(n_epochs):
        for i in range(m):
            if epoch == 0 and i < 20:
                y_predict = X_new_b.dot(theta)
                style = 'b-'
                plt.plot(X_new,y_predict,style)
            random_index = np.random.randint(m)
            xi = X_b[random_index:random_index + 1]
            yi = y[random_index:random_index + 1]
            gradients = 2 * xi.T.dot(xi.dot(theta) - yi)
            eta = 0.1
            theta = theta - eta * gradients
            theta_path_sgd.append(theta)
            
    plt.plot(X,y,'b.')
    plt.xlabel('$x_1$',fontsize = 18)
    plt.ylabel('$y$',rotation=0,fontsize=18)
    plt.axis([0,2,0,15])
    save_fig('sgd_plot')
    plt.show()
    

    在这里插入图片描述

    ③.小批量梯度下降
    theta_path_mgd = []
    
    n_iterations = 50
    minibatch_size = 20
    
    np.random.seed(42)
    theta = np.random.randn(2,1)
    
    for epoch in range(n_iterations):
        # 乱序数据
        shuffled_indices = np.random.permutation(m)
        X_b_shuffled = X_b[shuffled_indices]
        y_shuffled = y[shuffled_indices]
        for i in range(0,m,minibatch_size):
            xi = X_b_shuffled[i:i + minibatch_size]
            yi = y_shuffled[i:i + minibatch_size]
            gradients = 2/minibatch_size * xi.T.dot(xi.dot(theta) - yi)
            eta = 0.1
            theta = theta - eta * gradients
            theta_path_mgd.append(theta)
    

    我们再来看一下三种方法的绘制过程

    theta_path_bgd = np.array(theta_path_bgd)
    theta_path_sgd = np.array(theta_path_sgd)
    theta_path_mgd = np.array(theta_path_mgd)
    
    plt.figure(figsize = (7,4))
    plt.plot(theta_path_sgd[:,0],theta_path_sgd[:,1],'r-s',linewidth = 1,label = 'Stochastic')
    plt.plot(theta_path_bgd[:,0],theta_path_bgd[:,1],'b-o',linewidth = 3,label = 'Batch')
    plt.plot(theta_path_mgd[:,0],theta_path_mgd[:,1],'g-+',linewidth = 2,label = 'Mini-batch')
    plt.legend(loc = 'upper left',fontsize = 16)
    plt.xlabel(r'$\theta_0$',fontsize=20)
    plt.ylabel(r'$\theta_1$',fontsize=20,rotation = 0)
    plt.axis([2.5,4.5,2.3,3.9])
    save_fig('gradient_descent_paths_plot')
    plt.show()
    

    运行的结果图为
    在这里插入图片描述
    由图中可以看出,
    批量梯度算法是蓝色那条线,目标明确但需要计算量很大且速度会比较慢;
    随机梯度下降为红色线条,目标比较混乱,由随机值进行,计算量比较小但因为目标不明确,其行进的方向非常曲折;
    绿色线段为小批量梯度下降,小批量梯度下降的速度与目标明确程度介于批量和随机梯度之间,相比较而言是较优选择.

    今天的内容就要到此结束啦,一起前行在研究的小伙伴们或大神们,上述理解有错误或疑问的话欢迎讨论哦!~

    展开全文
  • 使用代码实现和验证梯度下降算法 梯度下降法原理 梯度下降,gradient descent(之后将简称GD),是一种通过迭代找最优的方式一步步找到损失函数最小值的算法,基本算法思路可总结为如下几点: (1) 随机设置一个初始...

    目录

    摘要

    梯度下降法原理

    使用二次函数简单实现和验证梯度下降

    画出梯度下降的过程

    学习率对梯度下降快慢的影响

    在线性回归模型中使用梯度下降法

    Conclusion(总结)


    摘要

    使用代码实现和验证梯度下降算法

    梯度下降法原理

    梯度下降,gradient descent(之后将简称GD),是一种通过迭代找最优的方式一步步找到损失函数最小值的算法,基本算法思路可总结为如下几点:

    (1) 随机设置一个初始值

    (2) 计算损失函数的梯度

    (3) 设置步长,步长的长短将会决定梯度下降的速度和准确度

    (4) 将初值减去步长乘以梯度,更新初值,然后将这一过程不断迭代

     

    使用二次函数简单实现和验证梯度下降

    import numpy as np
    import matplotlib.pyplot as plt
    
    plot_x = np.linspace(-1,6,141)
    plot_y = (plot_x - 2.5)**2 - 1
    plt.plot(plot_x,plot_y)
    plt.show()

     

    def dJ(theta):
        return 2*(theta - 2.5)
    
    def J(theta):
        try:
            return (theta - 2.5)**2-1
        except:
            return float('inf')
    

    实验结果:

    theta= 0.5
    函数值= 3.0
    第0次梯度下降.....
    theta= 0.9
    函数值= 1.5600000000000005
    第1次梯度下降.....
    theta= 1.2200000000000002
    函数值= 0.6383999999999994
    第2次梯度下降.....
    theta= 1.4760000000000002
    函数值= 0.04857599999999951
    第3次梯度下降.....
    theta= 1.6808
    函数值= -0.3289113600000001
    ......
    第42次梯度下降.....
    theta= 2.4998638870532313
    函数值= -0.9999999814732657
    第43次梯度下降.....
    最终theta= 2.499891109642585
    最终函数值= -0.99999998814289
     

    画出梯度下降的过程

    theta = 0.0
    theta_history = [theta]
    while True:
        gradient = dJ(theta)
        last_theta = theta
        theta = theta - eta * gradient
        theta_history.append(theta)
        if(abs(J(theta) - J(last_theta)) < epsilon):
            break
    
    plt.plot(plot_x,J(plot_x))
    plt.plot(np.array(theta_history),J(np.array(theta_history)),color="r",marker="+")
    plt.show()

    学习率对梯度下降快慢的影响

    当学习率eta = 0.001时的图像

    initial_theta = 0
    eta = 0.001
    theta_history = []
    gradient_descent(initial_theta,eta)
    plot_theta_history()

     

    当学习率eta = 0.8时的图像

    initial_theta = 0
    eta = 0.8
    theta_history = []
    gradient_descent(initial_theta,eta)
    plot_theta_history()

     

    当学习率eta = 1.1时的图像

    initial_theta = 0
    eta = 1.1
    theta_history = []
    gradient_descent(initial_theta,eta,n_iters=10)
    plot_theta_history()

     

     

     

    在线性回归模型中使用梯度下降法

    import numpy as np
    import matplotlib.pyplot as plt
    
    np.random.seed(666)
    x = 2 * np.random.random(size=100)
    y = x * 3. + 4. + np.random.normal(size=100)
    X = x.reshape(-1, 1)
    X.shape
    plt.scatter(x, y)
    plt.show()
    

     

    使用梯度下降法训练

    def J(theta, X_b, y):
        try:
            return np.sum((y - X_b.dot(theta))**2) / len(X_b)
        except:
            return float('inf')
    
    def dJ(theta, X_b, y):
        res = np.empty(len(theta))
        res[0] = np.sum(X_b.dot(theta) - y)
        for i in range(1, len(theta)):
            res[i] = (X_b.dot(theta) - y).dot(X_b[:,i])
        return res * 2 / len(X_b)
    
    def gradient_descent(X_b, y, initial_theta, eta, n_iters = 1e4, epsilon=1e-8):
        
        theta = initial_theta
        cur_iter = 0
    
        while cur_iter < n_iters:
            gradient = dJ(theta, X_b, y)
            last_theta = theta
            theta = theta - eta * gradient
            if(abs(J(theta, X_b, y) - J(last_theta, X_b, y)) < epsilon):
                break
                
            cur_iter += 1
    
        return theta
    
    X_b = np.hstack([np.ones((len(x), 1)), x.reshape(-1,1)])
    initial_theta = np.zeros(X_b.shape[1])
    eta = 0.01
    theta = gradient_descent(X_b, y, initial_theta, eta)

    实验结果:array([4.02145786, 3.00706277])

    即截距 b = 4.02145786 ,斜率 a = 3.00706277  大致满足设置的函数 y = x * 3. + 4. + np.random.normal(size=100)

     

    Conclusion(总结)

    1.学习率eta取值影响获得最优解的速度

    2.学习率eta取值不合适,甚至得不到最优解

    3.学习率eta是一个超参数

    4.使用梯度下降算法不一定能得到全局最优解,可能是局部最优解

    5.可以多次运行,随机化初始点,多次尝试找出最优解

    展开全文
  • import numpy as np import pandas as pd import matplotlib.pyplot as plt # 画出抛物线 f = lambda x:(x-2.5)**...# 梯度下降不是为了求目标函数的最小值,而是为了求目标函数最小是对应的系数 # 对x求导 dx = lambda
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    
    # 画出抛物线
    f = lambda x:(x-2.5)**2 + 5
    x = np.linspace(-10,15,100)
    plt.figure(figsize=(8,10))
    plt.plot(x,[f(i) for i in x],c='r')
    
    # 梯度下降不是为了求目标函数的最小值,而是为了求目标函数最小是对应的系数
    # 对x求导
    dx = lambda x:2*(x-2.5)
    
    x_initial=-8
    # 减少10倍学习力,迭代次数大大增加
    learning_rate=0.01
    
    max_iter=2000
    i=1
    ret=[]
    threshold = 1e-4
    while True:
        # 不停的更新x_initial
        # 先计算x的导数即梯度
        ret.append(x_initial)
        dx_=dx(x_initial)
        x_initial=x_initial - learning_rate*dx_
        i+=1
        # 1.根据迭代次数退出
    #     if i>2000:
    #         break
            
    #     #2.根据梯度绝对值退出
    #     if abs(dx(x_initial)) < threshold:
    #         break
        # 3.根据相邻x的差值
        if abs(x_initial - ret[-1])< threshold:
            break
            
    x =np.linspace(-10,15,100)
    plt.figure(figsize=(6,4))
    plt.plot(x,[f(i) for i in x],c='r')
    plt.scatter(ret[:1000],[f(i) for i in ret[:1000]],c='b')
    

    在这里插入图片描述

    展开全文
  • 本次代码实践之前,请大家一定要阅读前两期文章(深度学习理论篇之 (四) -- 梯度下降算法的魅力展现,深度学习理论篇之 (五) -- 梯度下降算法的数学推导)确保大家了解理论和数学推导后,我们才能理解今天代码,...
  • 2.结果的迭代次数是24,书上的是2118,代码和书上完全一样(我怀疑敲错了,从书籍的配套源码复制过来的,还是这个结果)。 3.求偏导部分,theta要迭代,theta -= alpha * ,代码中我没看出来体现在哪?代码中的两个...
  • 批量梯度下降算法和随机梯度下降算法代码实现 随机梯度下降和批量梯度下降都是梯度下降方法的一种,都是通过求偏导的方式求参数的最优解。批量梯度下降算法:,。是通过对每一个样本求偏导,然后挨个更新。...
  • 本文将从一个下山的场景开始,先提出梯度下降算法的基本思想,进而从数学上解释梯度下降算法的原理,解释为什么要用梯度,最后将此算法应用于具体的拟合直线的线性回归中。2 梯度下降算法2.1场景假设想象一...
  • 代码:批量梯度下降法(Batch Gradient Descent):Repeat until convergence{}随机梯度下降法(Stochastic Batch Gradient Descent):Loop{for i = 1 to m,,{}}小批量梯度下降(Mini Batch Gradient Descent):Repeat{...
  • https://www.jianshu.com/p/a20e11416a25 看的三种算法的完整版
  • 本文实例为大家分享了python实现梯度下降算法的具体代码,供大家参考,具体内容如下简介本文使用python实现了梯度下降算法,支持y = Wx+b的线性回归目前支持批量梯度算法和随机梯度下降算法(bs=1)也支持输入特征向量...
  • 梯度下降算法 梯度下降,依照所给数据,判断函数,随机给一个初值w,之后通过不断更改,一步步接近原函数的方法。更改的过程也就是根据梯度不断修改w的过程。 以简单的一元函数为例 原始数据为 x_data = [1.0,...
  • 批量梯度下降法(Batch Gradient Descent): Repeat until convergence{} 随机梯度下降法(Stochastic Batch Gradient Descent): Loop{     for i = 1 to m,,{                       ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,274
精华内容 509
关键字:

梯度下降算法代码