随机梯度下降算法(SGD)

随机梯度下降算法(SGD)何为随机梯度下降?在scikit-learn官方文档中有着这样的定义:是一种简单但又非常高效的方法,主要用于凸损失函数下线性分类器的判别式学习,例如(线性)支持向量机和Logistic回归。在百度百科中对梯度下降法的解释:梯度下降法(英语:Gradientdescent)是一个一阶最优化算法,通常也称为最速下降法。要使用梯度下降法找到一个函数的局部极小值,必须向函数上当前点对应梯度…

大家好,欢迎来到IT知识分享网。

何为随机梯度下降?

scikit-learn官方文档中有着这样的定义:是一种简单但又非常高效的方法,主要用于凸损失函数下线性分类器的判别式学习,例如(线性) 支持向量机 和 Logistic 回归。

百度百科中对梯度下降法的解释:梯度下降法(英语:Gradient descent)是一个一阶最优化算法,通常也称为最速下降法。 要使用梯度下降法找到一个函数的局部极小值,必须向函数上当前点对应梯度(或者是近似梯度)的反方向的规定步长距离点进行迭代搜索。如果相反地向梯度正方向迭代进行搜索,则会接近函数的局部极大值点;这个过程则被称为梯度上升法。

以函数y=x²为例,”U”型的样式,假设U型的左侧(或者右侧)存在一个点A。现在A需要到达U型的最低端,那么点A只能一步一步地移动,直到它觉得所到的位置是最低点为止(前后两个点的误差最小,即达到收敛条件)。显然,如果函数存在多个极值点,这个方法是不适用的。

对于一元函数来说,应该如何算出它的最低点呢?采用数值计算极值的思想:选择一个初始点,计算该点的导数,然后通过导数和步长推进到下一个点,直到两个点之差很小为止(达到收敛条件)。
以函数 y = x**2 为例:

import numpy as np
import matplotlib.pyplot as plt

def targetFunc(x):
    return   x**2

def  gradientFunc(x):
    return 2*x

listx = []
def gradientCal(guessX,targetFunc,gradientFunc,rating=0.1,tolent=0.000001):
    ''' :param initX:猜测的点 :param targetFunc: 目标函数 :param gradientFunc: 导函数,梯度函数 :param rating: 步进系数 :param tolent: 收敛条件 :return: 返回极值点x的值 '''
    newguessX = targetFunc(guessX)  # 猜测点的实际值
    gradientX = gradientFunc(guessX) # 猜测点的导数

    newX = guessX - rating*gradientX # 获取新的x值
    newResult = targetFunc(newX) # 获取新的x的值的实际值

    subResult = np.abs( newResult - newguessX)

    while subResult>tolent:
        guessX = newX
        newguessX=newResult
        listx.append(guessX)

        newX = newX - rating*targetFunc(newX)
        newResult = targetFunc(newX)
        subResult = np.abs(newguessX-newResult)

    return guessX


if __name__ =='__main__':
    print(gradientCal(1, targetFunc, gradientFunc))
    x = np.arange(-10, 11)
    y = x**2
    plt.plot(x, y)
    plt.grid(linestyle='--')
    plt.scatter(np.array(listx),np.array(listx)**2,s=20)
    plt.show()
    

在这里插入图片描述
对于二元函数应该怎样求解呢?

from mpl_toolkits.mplot3d.axes3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np


lista = []
def tarFunc(w):
    # w 是一个数组
    x1,x2 = w
    return 5*(x1+2)**2+2*x1*x2+7*x2**2+3*x1+6*x2 +100

def graFunc(w):
    # w 是一个数组
    x1,x2 = w
    X1 =  10*(x1+2)+2*x2+3 #x1 的偏导
    X2 =  2*x1+14*x2+6     #x2 的偏导
    return np.array([X1,X2])

def targetCal(initX,tarFunc,graFunc,rate=0.01,tolent=0.00001,times=50000):

    w = initX
    initX_value = tarFunc(w) #猜测点的值
    i = 0
    while  i<times:
        initX_gra =graFunc(w) #猜测点的导数
        newX = w -initX_gra*rate #获取新的点
        lista.append(newX)
        newX_value = tarFunc(newX) #new点的值

        if abs(newX_value-initX_value)<tolent:
            return newX
        else:
            w,initX_value = newX,newX_value
            i += 1
    else:
        print('无极值')

if __name__ == '__main__':

    np.random.seed(0)
    initX = np.array([np.random.random(),np.random.random()])    #随机初始的x1,x2
    x1,x2 = targetCal(initX,tarFunc,graFunc)
    print(lista)
    # print(x1,x2)
    #画图
    xx1=np.arange(-10,11,1)    #绘制函数的原图像
    xx2=np.arange(-10,11,1)

    xx1, xx2 = np.meshgrid(xx1, xx2)  #3D坐标系

    z=5*(xx1+2)**2+2*xx1*xx2+7*xx2**2+3*xx1+6*xx2 +100

    fig = plt.figure()
    ax = Axes3D(fig)
    ax.plot_surface(xx1, xx2, z)    #绘制3D坐标系中的函数图像
    for i in lista:
        x1,x2 = i
        ax.scatter(x1,x2, tarFunc(i), s=5, c='red') #绘制已经找到的极值点
    ax.legend()    #使坐标系为网格状
    plt.show()     #显示

在这里插入图片描述
显然曲面上的点正在逐步靠近曲面的最低点。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/14679.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信