批梯度下降(BGD)、随机梯度下降(SGD)、小批量梯度下降(MBGD)的理解和python 实现

 

梯度下降一般有以下三种,分别是:批梯度下降(BGD)、随机梯度下降(SGD)、小批量梯度下降(MBGD)

多元回归或者逻辑回归的梯度下降公式如下:

1.批量梯度下降法(Batch Gradient Descent,简称BGD),它是梯度下降法最原始的形式,具体思路是在更新每一参数时都使用所有的样本来进行更新,也就是方程(1)中的m表示样本的所有个数。


优点:全局最优解;易于并行实现;

缺点:当样本数目很多时,训练过程会很慢。

2.随机梯度下降法:它的具体思路是在更新每一参数时都使用一个样本来进行更新,也就是方程中的m等于1。每一次跟新参数都用一个样本,更新很多次。如果样本量很大的情况(例如几十万),那么可能只用其中几万条或者几千条的样本,就已经将theta迭代到最优解了,对比上面的批量梯度下降,迭代一次需要用到十几万训练样本,一次迭代不可能最优,如果迭代10次的话就需要遍历训练样本10次,这种跟新方式计算复杂度太高。

但是,SGD伴随的一个问题是噪音较BGD要多,使得SGD并不是每次迭代都向着整体最优化方向。

优点:训练速度快;

缺点:准确度下降,并不是全局最优;不易于并行实现

从迭代的次数上来看,SGD迭代的次数较多,在解空间的搜索过程看起来很盲目。

小批量梯度下降法(Mini-batch Gradient Descent,简称MBGD):它的具体思路是在更新每一参数时都使用一部分样本来进行更新,也就是方程中的m的值大于1小于所有样本的数量。为了克服上面两种方法的缺点,又同时兼顾两种方法的有点。
 

样本量较少时,一般采用BGD,样本量很大时,常常采用MBGD

以下是三种梯度下降算法的python实现:

# 在多元回归上比较不同的梯度下降法:批梯度下降(BGD)、随机梯度下降(SGD)、小批量梯度下降(MBGD)

x0=np.random.randint(1,2,100).reshape(100,1) #x0全为1
x1=np.random.randint(1,10,100).reshape(100,1)
x2=np.random.randint(1,10,100).reshape(100,1)
x3=np.random.random(100).reshape(100,1)

# y=x0+x1+2*x2+3*x3
# X=np.hstack((x0,x1,x2,x3))

y=x0+x1
X=np.hstack((x0,x1))


#BGD
def BGD(X,y):

    ept=0.001 #精度
    loss=1 #定义一个损失 方便进入循环体 后来表示两次迭代损失函数的差异
    alpha=0.01 #学习率
    max_iter=0 #梯度更新次数
    theta=np.random.randint(1,10,(X.shape[1],1)) #初始化theta
    while max_iter<10000 and loss>ept:
        partial=(1/X.shape[0])*X.T.dot(X.dot(theta)-y) #损失函数关于theta的偏导数
        theta=theta-alpha*partial

        max_iter+=1
        loss=(1/(2*X.shape[0]))*np.sum((X.dot(theta)-y)**2) #计算两次迭代之间的差异(损失函数) 无明显差异就说明算法收敛到了全局最优解
    return max_iter,theta

max_iter,theta=BGD(X,y)

print('BGD:max_iter:%s\ntheta:%s'%(max_iter,theta))




def SGD(X,y):

    ept=0.001 #精度
    loss=1 #定义一个损失 方便进入循环体 后来表示两次迭代损失函数的差异
    alpha=0.01 #学习率
    max_iter=0 #梯度更新次数
    theta=np.random.randint(1,10,(X.shape[1],1)) #初始化theta
    numsSample=X.shape[0]
    while max_iter<10000 and loss>ept:

        i = np.random.randint(0, numsSample) #随机抽取一个样本

        # for i in range(numsSample): 这样其实也是遍历了所有数据
        #     partial=X[i:i+1,:].T.dot((X[i:i+1,:].dot(theta)-y[i,:]).reshape(1,1)) #损失函数关于theta的偏导数
        #     theta=theta-alpha*partial
        partial=X[i:i+1,:].T.dot((X[i:i+1,:].dot(theta)-y[i,:]).reshape(1,1)) #损失函数关于theta的偏导数 注意shape必须都为2维
        theta=theta-alpha*partial
        max_iter+=1
        loss=(1/(2*X.shape[0]))*np.sum((X.dot(theta)-y)**2) #计算两次迭代之间的差异(损失函数) 无明显差异就说明算法收敛到了全局最优解
    return max_iter,theta

max_iter,theta=SGD(X,y)

print('SGD:max_iter:%s\ntheta:%s'%(max_iter,theta))


def MBGD(X,y):

    ept=0.001 #精度
    loss=1 #定义一个损失 方便进入循环体 后来表示两次迭代损失函数的差异
    alpha=0.01 #学习率
    max_iter=0 #梯度更新次数
    numsSample = X.shape[0]#样本数量
    theta=np.random.randint(1,10,(X.shape[1],1)) #初始化theta
    while max_iter<10000 and loss>ept:

        #这里的小批量梯度下降每次选取两个样本
        i = np.random.randint(0, numsSample-1)  # 随机抽取一个样本
        # j=(i+1)%numsSample #选取另一个样本

        partial=(1/2)*X[i:i+2,:].T.dot(X[i:i+2,:].dot(theta)-y[i:i+2,:]) #损失函数关于theta的偏导数
        theta=theta-alpha*partial

        max_iter+=1
        loss=(1/(2*X.shape[0]))*np.sum((X.dot(theta)-y)**2) #计算两次迭代之间的差异(损失函数) 无明显差异就说明算法收敛到了全局最优解
    return max_iter,theta

max_iter,theta=MBGD(X,y)

print('MBGD:max_iter:%s\ntheta:%s'%(max_iter,theta))

这是算法收敛的迭代次数对比 

BGD:max_iter:2151

SGD:max_iter:1266

MBGD:max_iter:987

参考文章:

https://blog.csdn.net/UESTC_C2_403/article/details/74910107

https://blog.csdn.net/kwame211/article/details/80364079

https://blog.csdn.net/zouxy09/article/details/20319673

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值