随机梯度下降法,批量梯度下降法和小批量梯度下降法以及代码实现

前言

梯度下降法是深度学习领域用于最优化的常见方法,根据使用的batch大小,可分为随机梯度下降法(SGD)和批量梯度下降法(BGD)和小批量梯度下降法(MBGD),这里简单介绍下并且提供Python代码演示。
如有谬误,请联系指正。转载请注明出处。
联系方式:
e-mail: FesianXu@163.com
QQ: 973926198
github: https://github.com/FesianXu
代码开源:click

梯度下降法

其基本思想就是使得网络的各个参数朝着优化函数的梯度的反方向更新,因为梯度的方向是增长最速方向,所以梯度的反方向就是减少的最速方向,因此只要设定一个步进 η \eta η,然后朝着梯度的反方向下降减小即可将优化函数最小化。公式表达如:
w i j l : = w i j l − η ∂ C ∂ w i j l w^l_{ij} := w^l_{ij}-\eta \frac{\partial{C}}{\partial{w^l_{ij}}} wijl:=wijlηwijlC

以下讨论都假设使用的损失函数是MSE损失函数,模型为线性回归模型。
L = 1 2 m ∑ i = 1 m ( y − h ( x ( i ) ) ) 2 , m 是 样 本 总 数 L = \frac{1}{2m} \sum_{i=1}^m (y-h(x^{(i)}))^2,m是样本总数 L=2m1i=1m(yh(x(i)))2m
h ( x i ) = θ T x ( i ) + b , 其 中 x ( i ) 为 第 i 个 样 本 , x ( i ) ∈ R n h(x_i) = \theta^Tx^{(i)}+b,其中x^{(i)}为第i个样本,x^{(i)} \in R^n h(xi)=θTx(i)+bx(i)ix(i)Rn

批量梯度下降法(BGD)

批量梯度下降法(Batch Gradient Descent, BGD)是梯度下降法的最原始的形式,其特点就是每一次训练迭代都需要利用所有的训练样本,其表达式为:
∂ L ∂ θ j = − 1 m ∑ i = 1 m [ ( y − h ( x ( i ) ) ) x j ( i ) ] , x j ( i ) 是 第 i 个 样 本 的 第 j 个 输 入 分 量 \frac{\partial{L}}{\partial{\theta_j}} = -\frac{1}{m}\sum_{i=1}^m [(y-h(x^{(i)}))x^{(i)}_j],x^{(i)}_j是第i个样本的第j个输入分量 θjL=m1i=1m[(yh(x(i)))xj(i)]xj(i)ij
θ j : = θ j + η 1 m ∑ i = 1 m [ ( y − h ( x ( i ) ) ) x j ( i ) ] \theta_j := \theta_j+\eta \frac{1}{m}\sum_{i=1}^m [(y-h(x^{(i)}))x^{(i)}_j] θj:=θj+ηm1i=1m[(yh(x(i)))xj(i)]
  可以发现,对于每一个参数的更新都需要利用到所有的m个样本,这样会导致训练速度随着训练样本的增大产生极大地减慢,不适合于大规模训练样本的场景,但是,其解是全局最优解,精度高。

随机梯度下降法(SGD)

随机梯度下降法(Stochastic Gradient Descent, SGD)是梯度下降法的改进形式之一,其特点就是每一次训练迭代只需要训练样本集中的一个样本,其表达式为:
∂ L ∂ θ j = − ( y − h ( x ) ) x j , x j 是 选 定 样 本 的 第 j 个 输 入 分 量 \frac{\partial{L}}{\partial{\theta_j}} = -(y-h(x))x_j, x_j是选定样本的第j个输入分量 θjL=(yh(x))xjxjj
θ j : = θ j + η ( y − h ( x ) ) x j \theta_j := \theta_j+\eta (y-h(x))x_j θj:=θj+η(yh(x))xj
  和BGD进行对比可以发现,其参数更新过程中,只需要选取训练集中的一个训练样本,因此训练速度快,但是因为其只是利用了训练集的一部分知识,因此其解为局部最优解,精度较低。

小批量梯度下降法(MBGD)

小批量梯度下降法(Mini-Batch Gradient Descent, MBGD)是结合了SGD和BGD的一种改进版本,既有训练速度快,也有精度较高的特点,其基本特点就是每一次训练迭代在训练集中随机采样batch_size个样本,其表达式为:
∂ L ∂ θ j = − 1 M ∑ i = 1 M [ ( y − h ( x ( i ) ) ) x j ( i ) ] , 其 中 M 为 b a t c h _ s i z e \frac{\partial{L}}{\partial{\theta_j}} = -\frac{1}{M}\sum_{i=1}^M [(y-h(x^{(i)}))x^{(i)}_j],其中M为batch\_size θjL=M1i=1M[(yh(x(i)))xj(i)]Mbatch_size
θ j : = θ j + η 1 M ∑ i = 1 M [ ( y − h ( x ( i ) ) ) x j ( i ) ] \theta_j := \theta_j+\eta \frac{1}{M}\sum_{i=1}^M [(y-h(x^{(i)}))x^{(i)}_j] θj:=θj+ηM1i=1M[(yh(x(i)))xj(i)]
  这个改进版本在深度学习的网络训练中有着广泛地应用,因为其既有较高的精度,也有较快的训练速度。

代码实现

这里以线性回归模型作为演示,实现梯度下降。代码实现基于python和numpy,matplotlib绘图,matlab生成数据集。代码由github托管。

数据描述

目标直线为 y = 2.5 x + 3.5 y=2.5x+3.5 y=2.5x+3.5,加上了一个高斯噪声,代码如:

x = -20:0.01:20;
line = 2.5*x+3.5;
x_rand = randn(1, length(line))*10;
line = line+x_rand;
x = x';
line = line';
samples = [x, line];

图像如:
dataset
主要代码如:

import numpy as np
import scipy.io as sio
import random
import matplotlib.pyplot as plt

path = u'./samples.mat'
mat = sio.loadmat(path)
dataset = mat['samples']
batch_size = 1

def random_get_samples(mat, batch_size):
    batch_id = random.sample(range(mat.shape[0]), batch_size)
    ret_batch = mat[batch_id, 0]
    ret_line = mat[batch_id, 1]
    return ret_batch, ret_line


params = {
    'w1': np.random.normal(size=(1)),
    'b': np.random.normal(size=(1))
}

def predict(x):
    return params['w1']*x+params['b']

learning_rate = 0.001
for i in range(3000):
    batch, line = random_get_samples(dataset, batch_size)
    y_pred = predict(batch)
    y_pred = np.reshape(y_pred, (batch_size, 1))
    line = np.reshape(line, (batch_size, 1))
    batch = np.reshape(batch, (batch_size, 1))
    delta = line-y_pred
    params['w1'] = params['w1']+learning_rate*np.sum(delta*batch)/batch_size
    params['b'] = params['b']+learning_rate*np.sum(delta)/batch_size
    if i % 100 == 0:
        print(np.sum(np.abs(line-y_pred))/batch_size)

print(params['w1'])
print(params['b'])
x = dataset[:, 0]
line = dataset[:, 1]
y = params['w1']*x+params['b']
plt.figure(1)
plt.plot(x, line, 'b--')
plt.plot(x, y, 'r--')
plt.show()

其中调整batch_size可以分别实现SGD,BGD和MBGD,当其为1时为SGD,当其为dataset.shape[0]时为BGD,当其为其他固定常数时如128,为MBGD。通过实验可以明显发现,当batch_size为1时,训练速度最快,但是精度欠佳,当batch_size=dataset.shape[0]时,训练速度最慢,但是精度较高,当batch_size=128或其他常数时,速度和精度兼有顾及。最后的结果图像如:
regression
可见红线成功拟合了原数据。

  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FesianXu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值