理解梯度下降(三)- python实现随机梯度下降

上一篇理解梯度下降(二)- spark和python分别实现批量梯度下降 实现了简单的批量梯度下降。最后引出了随机梯度下降(Stochastic gradient descent)。

什么是随机梯度下降,SGD是对全批量梯度下降法计算效率的改进算法。本质上来说,我们预期随机梯度下降法得到的结果和全批量梯度下降法相接近;SGD的优势是更快地计算梯度。

我们先回顾以下全批量法是如何计算每次迭代中的梯度的:

其中N是样本数量,我们很容易看出,对于最小二乘法来说,每计算一次梯度的代价是O(N)O(N),运算次数与N成线性关系。

而随机梯度下降法能将计算一次梯度的代价降低到O(1),也就是运算次数为常数次,与N无关。所以SGD特别适合大训练样本的计算。

SGD在计算∇L时,并不使用全部样本,而是随机地挑选了一个样本

直接修改一下上一篇文章中BSG的代码,我们在求偏导数之前,每次随机选择一个样本进行迭代。

#coding=utf-8

import random
import numpy as np
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

def data():
    x = range(10)
    y = [(2*s+4) for s in x]
    return x, y

def SGD(x,y):
    flag = True
    a = 0
    b = 0
    m = len(x)
    arf = 0.05 #学习率
    n = 0
    sum1 = 0
    sum2 = 0
    exp = 0.000001
    error0 = 0
    error1 = 0
    while flag:
        # for i in range(m):
        i = np.random.randint(0, m)  #每次随机选择一个样本
        #计算对应的偏导数
        sum1 = a*x[i]+b-y[i]
        sum2 = (a*x[i]+b-y[i])*x[i]
        error1 = (a*x[i]+b-y[i])**2
        a = a - sum2*arf/m  #对a,b进行更新
        b = b - sum1*arf/m

        if abs(error1-error0)<exp: #计算误差
            break
        error0 = error1
        print('a=%f,b=%f,error=%f' % (a, b, error1))
        if n > 1000:
            break
        n += 1
        if n % 10 == 0:
            print('第%d次迭代:a=%f,b=%f' % (n, a, b))
    return a,b

if __name__ == '__main__':
    x,y = data()

    a,b = SGD(x,y)
    print('梯度下降BGD: y=%fX+%f'%(a,b))

部分结果如下:

...
a=2.111940,b=3.158513,error=0.079138
a=2.119525,b=3.161042,error=0.255698
a=2.119525,b=3.165236,error=0.703851
a=2.126668,b=3.167617,error=0.226755
a=2.131644,b=3.168613,error=0.039618
第1000次迭代:a=2.131644,b=3.168613
a=2.135143,b=3.172111,error=0.489641
a=2.140719,b=3.174899,error=0.310921
梯度下降BGD: y=2.140719X+3.174899

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值