GD(梯度下降)

GD(梯度下降)
一.梯度下降分类
1.批量梯度下降(Batch Gradient Descent)——BGD
2.随机梯度下降(Stochastic Gradient Descent)——SGD
3.小批量梯度下降(Mini-Batch Gradient Descent)——MBGD
下面以线性回归算法来对三种不同梯度下降法进行理解:
假设线性回归函数(前向传播):

在这里插入图片描述

对应的损失函数(均方误差):
在这里插入图片描述

二.批量梯度下降(BGD)
思想:每一次的参数更新都用到了所有的训练样本数据;

1.损失函数对求偏导,求梯度loss.backward():

在这里插入图片描述在这里插入图片描述

2.对参数进行更新(以下缺少lr),opt.step():

在这里插入图片描述

3.以epoch的次数按以上步骤进行迭代,参数更新次数为epoch次;
4.BGD伪代码:
在这里插入图片描述

优点:
  由全数据集确定的方向能够更好地代表样本总体,从而更准确地朝向极值所在的方向。当目标函数为凸函数时,BGD一定能够得到全局最优。
缺点:
  当样本数目m 很大时,每迭代更新参数都需要对所有样本计算,训练过程会很慢。
  在这里插入图片描述

批量梯度下降的梯度变化趋势

在这里插入图片描述

批量梯度下降的收敛图

import numpy as np

#批量梯度下降(BGD)
def BatchGradientDescent(x, label, w):
    for epoch in range(5000):
        y = np.dot(x, w)     #前向传播,[10,]
        MSEloss = (1 / 2) * np.mean((y - label) ** 2)   #MSEloss:均方误差,[10,]
        print("MSEloss=",MSEloss)
        loss = y - label     #注意这里有10个样本的平均误差, [10,] ,下面更新10个都用到
        gradient = np.dot(loss, x) / x.shape[0]  #对所有的样本(10个样本)求梯度并相加,再除10(10个样本平均梯度),[3,]
        w = w - 0.1 * gradient     #更新参数w,[3,]
        # dw1 = np.dot(loss,x[:,0])/ x.shape[0]
        # dw2 = np.dot(loss, x[:, 1]) / x.shape[0]
        # dw3 = np.dot(loss, x[:, 2]) / x.shape[0]
        # w = w - 0.1*np.array([dw1,dw2,dw3])
    return w

#前向传播(测试用)
def predict(x, w):
    y = np.dot(x, w)
    return y

if __name__ == '__main__':
    #训练全部数据和标签(10个样本和10个标签)
    train_x = np.array([[1.1,1.5,1],[1.3,1.9,1],[1.5,2.3,1],[1.7,2.7,1],[1.9,3.1,1],[2.1,3.5,1],[2.3,3.9,1],[2.5,4.3,1],[2.7,4.7,1],[2.9,5.1,1]])
    train_y = np.array([2.5,3.2,3.9,4.6,5.3,6,6.7,7.4,8.1,8.8])

    #随机初始化权重w
    ran = np.random.RandomState(0)
    w = ran.randn(train_x.shape[1])

    #调用批量梯度下降,返回更新的参数w
    w = BatchGradientDescent(train_x, train_y, w)
    print ("w = ",w)

    #测试数据和测试
    test_x = np.array([[3.1, 5.5,1], [3.3, 5.9,1], [3.5, 6.3,1], [3.7, 6.7,1], [3.9, 7.1,1]])
    print (predict(test_x, w))

三.随机梯度下降(SGD)
思想:每一次的参数更新都用到了一个样本数据;
1.损失函数对求偏导,求梯度loss.backward():
在这里插入图片描述在这里插入图片描述

2.对参数进行更新(以下缺少lr),opt.step():
在这里插入图片描述

3.SGD伪代码:
在这里插入图片描述

优点:
  随机梯度下降在每次更新的时候,只考虑了一个样本点,这样会大大加快训练数据。
缺点:
开始容易陷入局部最优解,并震荡大跳出局部最优解,但由于更新次数多,整体方向还是一直朝这全局最优解方向走,SGD特点:每一次进行更新的过程中,就不一定是朝着极小值方向更新(盲目搜索过程)。
  在这里插入图片描述

随机梯度下降的梯度变化趋势
     在这里插入图片描述

随机梯度下降的收敛图

import numpy as np

#随机梯度下降(SGD)
def StochasticGradientDescent(x, label, w):

    # 选取一个样本来更新权重w
    for epoch in range(1000):
        for data in range(10):
            y = np.dot(x, w)                               #前向传播,[10,]
            MSEloss = (1 / 2) * np.mean((y - label) ** 2)  # MSEloss:均方误差,[10,]
            print("MSEloss=", MSEloss)
            loss = y - label                               #注意这里有10个样本的平均误差, [10,] ,取一个样本进行更新即可
            gradient = loss[data]*x[data]              #只取这一个样本进行更新计算梯度,[3,]
            w = w - 0.1 * gradient                    #更新参数w,[3,]
    return w

#前向传播(测试用)
def predict(x, w):
    y = np.dot(x, w)
    return y

if __name__ == '__main__':
    # 训练全部数据和标签(10个样本和10个标签)
    train_x = np.array(
        [[1.1, 1.5, 1], [1.3, 1.9, 1], [1.5, 2.3, 1], [1.7, 2.7, 1], [1.9, 3.1, 1], [2.1, 3.5, 1], [2.3, 3.9, 1],
         [2.5, 4.3, 1], [2.7, 4.7, 1], [2.9, 5.1, 1]])
    train_y = np.array([2.5, 3.2, 3.9, 4.6, 5.3, 6, 6.7, 7.4, 8.1, 8.8])

    # 随机初始化权重w
    ran = np.random.RandomState(0)
    w = ran.randn(train_x.shape[1])

    # 调用随机梯度下降,返回更新的参数w
    w = StochasticGradientDescent(train_x, train_y, w)
    print("w = ", w)

    # 测试数据和测试
    test_x = np.array([[3.1, 5.5, 1], [3.3, 5.9, 1], [3.5, 6.3, 1], [3.7, 6.7, 1], [3.9, 7.1, 1]])
    print(predict(test_x, w))

四.小批量梯度下降(MBGD)
思想:每一次的参数更新都用到了bitch_size个样本数据,假如以bitch_size=10为列,样本数m=1000;

1.MBGD过程:

在这里插入图片描述

2.MBGD伪代码:

在这里插入图片描述

3.优点:结合了BGD和SGD两者的优点,相比BGD算法的训练过程比较快,而且相比SGD也要保证最终参数训练的准确率;

import numpy as np

#批量梯度下降(MBGD)
def MiniBatchGradientDescent(x, label, w):

    # 选取一个batch_size来更新权重w
    for epoch in range(2000):
        batch_size=5
        for data in range(10//batch_size):
            y = np.dot(x, w)                               #前向传播,[10,]
            MSEloss = (1 / 2) * np.mean((y - label) ** 2)  # MSEloss:均方误差,[10,]
            print("MSEloss=", MSEloss)
            loss = y - label                               #注意这里有10个样本的误差, [10,] ,取bitch_size样本进行更新即可
            gradient = np.dot(loss[5*data:5*(data+1)],x[5*data:5*(data+1)])   #只取bitcg_size样本进行更新计算梯度,[3,]
            w = w - 0.01 * gradient                    #更新参数w,[3,]
    return w

#前向传播(测试用)
def predict(x, w):
    y = np.dot(x, w)
    return y

if __name__ == '__main__':
    # 训练全部数据和标签(10个样本和10个标签)
    train_x = np.array(
        [[1.1, 1.5, 1], [1.3, 1.9, 1], [1.5, 2.3, 1], [1.7, 2.7, 1], [1.9, 3.1, 1], [2.1, 3.5, 1],
         [2.3, 3.9, 1],[2.5, 4.3, 1], [2.7, 4.7, 1], [2.9, 5.1, 1]])
    train_y = np.array([2.5, 3.2, 3.9, 4.6, 5.3, 6, 6.7, 7.4, 8.1, 8.8])

    # 随机初始化权重w
    ran = np.random.RandomState(0)
    w = ran.randn(train_x.shape[1])

    # 调用随机梯度下降,返回更新的参数w
    w = MiniBatchGradientDescent(train_x, train_y, w)
    print("w = ", w)

    # 测试数据和测试
    test_x = np.array([[3.1, 5.5, 1], [3.3, 5.9, 1], [3.5, 6.3, 1], [3.7, 6.7, 1], [3.9, 7.1, 1]])
    print(predict(test_x, w))
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值