梯度下降法及其优化

简介

1、梯度下降

  • 引入:目标函数 J ( θ ) J(\theta) J(θ)不一定可以直接求解,线性回归是个特例
  • 方向:梯度的反方向,梯度指向值增加的方向

2、面对的主要困难

  • 梯度的计算:样本流量巨大时,计算耗时又费力(每个 x i x_i xi都有一个 J x i ( θ ) {J_{x_i}}(\theta) Jxi(θ)
  • 学习率的选择
    • 过小:算法收敛太慢
    • 过大:算法不收敛

3、分类

  • 批量梯度下降法(GD):原始的梯度下降法,使用全部样本
    • 优点:容易得到最优解
    • 缺点:收敛太慢
  • 随机梯度下降法(SGD):每次只使用一个样本
    • 优点:减少了相似样本的冗余计算,收敛速度加快
    • 缺点:不一定每次都朝着收敛方向,不稳定
  • 小批量随机梯度下降法(Mini Batch SGD):使用小批量样本
    • 优点:比单样本稳定,且可利用矩阵计算

4、普通的小批量SGD(以下简称为SGD)的困难:

  • 主要困难:学习率的选择问题
    • 预定的学习率衰减法很难对当前的数据自适应
    • 对不同参数无法采取不同的学习率
  • 其他困难:
    • 局部梯度下降的方向不一定是函数整体的下降方向
    • 容易困在鞍点附近

SGD的优化算法

1、为什么不使用牛顿法?

  • 牛顿法需要二阶求导,对高维特征计算量巨大
  • 对小批量数据,牛顿法二阶导数的估计容易引进噪声
  • 对非凸函数,容易受到鞍点甚至是最大值的吸引

2、动量法(Momentum)——适用于隧道型曲面(一个方向很陡,其他方向比较平坦)

  • 普通的SGD:由于垂直于函数主体方向有更大的梯度,因此隧道两侧振荡频繁
  • 动量法:
      v t = γ v t − 1 + η ∇ θ J ( θ )   θ t = θ t − 1 − v t \ v_t=\gamma {v_{t-1}}+\eta {\nabla _\theta }J(\theta)\\ \ \theta_t={\theta_{t-1}}-v_t  vt=γvt1+ηθJ(θ) θt=θt1vt
    • 动量项( γ v t − 1 \gamma {v_{t-1}} γvt1):在梯度一致的时候累积;在梯度变化频繁的时候相互抵消
    • 削减隧道两侧无谓的振荡
    • γ \gamma γ一般取0.9左右

3、Nesterov Accelerated Gradient(NAG):动量法的改进

  • 改进问题:动量法在极小值处下降速度不减少,可能在极小值处上升
  • 改进方法:利用主体下降方向提供下一步的位置,并在预判位置计算梯度
      v t = γ v t − 1 + η ∇ θ J ( θ − γ v t − 1 )   θ t = θ t − 1 − v t \ v_t=\gamma {v_{t-1}}+\eta {\nabla _\theta }J(\theta-\gamma {v_{t-1}})\\ \ \theta_t={\theta_{t-1}}-v_t  vt=γvt1+ηθJ(θγvt1) θt=θt1vt
  • 作用:显著提升了RNN的表现

4、Adagrad——适用于稀疏的数据

  • 特点:可自动调节学习率(lr)
    • 随训练步数增加,lr自动衰减
    • 更新频繁的参数,较小的lr
    • 更新不频繁的参数,较大的lr
  • 实现:对每个参数的历史更新进行叠加,并用作下一次更新
    • 第t步i参数的梯度: g t , i = ∇ θ J ( θ
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用随机梯度下降优化Beale函数的Python代码: ```python import numpy as np def beale(x): """ Beale函数:f(x, y) = (1.5 - x + x*y)**2 + (2.25 - x + x*y**2)**2 + (2.625 - x + x*y**3)**2 """ return (1.5 - x[0] + x[0]*x[1])**2 + (2.25 - x[0] + x[0]*x[1]**2)**2 + (2.625 - x[0] + x[0]*x[1]**3)**2 def beale_gradient(x): """ Beale函数的梯度向量 """ grad = np.zeros_like(x) grad[0] = 2*(x[0]*x[1] - x[0] + 1.5)*(x[1]**3) + 2*(x[0]*x[1]**2 - x[0] + 2.25)*(x[1]**2) + 2*(x[0]*x[1]**3 - x[0] + 2.625)*x[1] grad[1] = 2*(x[0]*x[1] - x[0] + 1.5)*(x[0]) + 2*(x[0]*x[1]**2 - x[0] + 2.25)*(2*x[0]*x[1]) + 2*(x[0]*x[1]**3 - x[0] + 2.625)*(3*x[0]*x[1]**2) return grad def sgd_beale(x0, learning_rate=0.001, max_iter=10000, tol=1e-6): """ 使用随机梯度下降优化Beale函数 """ x = x0.copy() for i in range(max_iter): # 随机选择一个方向 direction = np.random.randn(2) # 计算梯度 grad = beale_gradient(x) # 更新参数 x -= learning_rate * grad * direction # 检查收敛性 if np.linalg.norm(grad) < tol: print("SGD converged in {} iterations.".format(i+1)) break return x # 测试 np.random.seed(0) x0 = np.array([1.0, 1.0]) x_opt = sgd_beale(x0) print("Optimized solution: x = {:.6f}, y = {:.6f}, f(x, y) = {:.6f}".format(x_opt[0], x_opt[1], beale(x_opt))) ``` 在上面的代码中,我们定义了Beale函数及其梯度向量,然后使用随机梯度下降优化这个函数。在每次迭代中,我们随机选择一个方向(即随机生成一个二维向量),计算梯度,并更新参数。我们使用欧几里得范数来检查梯度是否已经足够小,如果是,则认为算法已经收敛。最后,我们输出优化后的解及其函数值。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值