专栏首页腾讯智能钛AI开发者【技术分享】梯度下降算法
原创

【技术分享】梯度下降算法

本文原作者:尹迪,经授权后发布。

  梯度下降(GD)是最小化风险函数、损失函数的一种常用方法,随机梯度下降和批量梯度下降是两种迭代求解思路。

1 批量梯度下降算法

  假设h(theta)是要拟合的函数,J(theta)是损失函数,这里theta是要迭代求解的值。这两个函数的公式如下,其中m是训练集的记录条数,j是参数的个数:

  梯度下降法目的就是求出使损失函数最小时的theta。批量梯度下降的求解思路如下:

  • 对损失函数求theta的偏导,得到每个theta对应的的梯度
  • 按每个参数theta的梯度负方向,来更新每个theta

  从上面公式可以看到,虽然它得到的是一个全局最优解,但是每迭代一步(即修改jtheta参数中的一个),都要用到训练集所有的数据,如果m很大,迭代速度会非常慢。

2 随机梯度下降算法

  随机梯度下降是通过每个样本来迭代更新一次theta,它大大加快了迭代速度。更新theta的公式如下所示。

  批量梯度下降会最小化所有训练样本的损失函数,使得最终求解的是全局的最优解,即求解的参数是使得风险函数最小。随机梯度下降会最小化每条样本的损失函数, 虽然不是每次迭代得到的损失函数都向着全局最优方向, 但是大的整体的方向是向全局最优解的,最终的结果往往是在全局最优解附近。

3 批随机梯度下降算法

  在MLlib中,并不是严格实现批量梯度下降算法和随机梯度下降算法,而是结合了这两种算法。即在每次迭代中,既不是使用所有的样本,也不是使用单个样本,而是抽样一小批样本用于计算。

  下面分析该算法的实现。首先我们看看GradientDescent的定义。

class GradientDescent private[spark] (private var gradient: Gradient, private var updater: Updater)
  extends Optimizer with Logging 

  这里Gradient类用于计算给定数据点的损失函数的梯度。Gradient类用于实现参数的更新,即上文中的theta。梯度下降算法的具体实现在runMiniBatchSGD中。

def runMiniBatchSGD(
      data: RDD[(Double, Vector)],
      gradient: Gradient,
      updater: Updater,
      stepSize: Double,
      numIterations: Int,
      regParam: Double,
      miniBatchFraction: Double,
      initialWeights: Vector,
      convergenceTol: Double): (Vector, Array[Double])

  这里stepSize是更新时的步长,regParam表示归一化参数,miniBatchFraction表示采样比例。迭代内部的处理分为两步。

  • 1 采样并计算梯度
val (gradientSum, lossSum, miniBatchSize) = data.sample(false, miniBatchFraction, 42 + i)
        .treeAggregate((BDV.zeros[Double](n), 0.0, 0L))(
          seqOp = (c, v) => {
            // c: (grad, loss, count), v: (label, features)
            val l = gradient.compute(v._2, v._1, bcWeights.value, Vectors.fromBreeze(c._1))
            (c._1, c._2 + l, c._3 + 1)
          },
          combOp = (c1, c2) => {
            // c: (grad, loss, count)
            (c1._1 += c2._1, c1._2 + c2._2, c1._3 + c2._3)
          })

  这里treeAggregate类似于aggregate方法,不同的是在每个分区,该函数会做两次(默认两次)或两次以上的merge聚合操作,避免将所有的局部值传回driver端。

  该步按照上文提到的偏导公式求参数的梯度,但是根据提供的h函数的不同,计算结果会有所不同。MLlib现在提供的求导方法分别有HingeGradientLeastSquaresGradientLogisticGradient以及 ANNGradient。这些类的实现会在具体的算法中介绍。

  • 2 更新权重参数
val update = updater.compute(
          weights, Vectors.fromBreeze(gradientSum / miniBatchSize.toDouble),
          stepSize, i, regParam)
weights = update._1
regVal = update._2

  求出梯度之后,我们就可以根据梯度的值更新现有的权重参数。MLlib现在提供的Updater主要有SquaredL2UpdaterL1UpdaterSimpleUpdater等。这些类的实现会在具体的算法中介绍。

参考文献

【1】随机梯度下降和批量梯度下降的公式对比、实现对比

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 大神齐聚,算法大赛复赛晋级名单揭晓!

    6月23日12:00:00,由腾讯广告携手腾讯云、腾讯大数据、腾讯招聘及腾讯高校合作等合作伙伴联袂举办的2020腾讯广告算法大赛正式进入复赛阶段。

    腾讯智能钛AI开发者
  • 【技术分享】高斯混合模型

      在上述定义中,x是维数为D的样本向量,mu是模型期望,sigma是模型协方差。对于单高斯模型,可以明确训练样本是否属于该高斯模型,所以我们经常将mu用训练样...

    腾讯智能钛AI开发者
  • 【技术分享】带权最小二乘

    $$minimize_{x}\frac{1}{2} \sum_{i=1}^n \frac{w_i(a_i^T x -b_i)^2}{\sum_{k=1}^n w...

    腾讯智能钛AI开发者
  • 机器学习入门 6-1 什么是梯度下降

    本系列是《玩转机器学习教程》一个整理的视频笔记。本小节主要介绍解决多元线性回归的另一种方法梯度下降算法,梯度下降算法也是求解机器学习算法比较通用的方法。

    触摸壹缕阳光
  • 机器学习笔记之梯度下降算法原理讲解

    梯度下降(gradient descent)在机器学习中应用十分的广泛,不论是在线性回归还是Logistic回归中,它的主要目的是通过迭代找到目标函数的最小值,...

    Jetpropelledsnake21
  • Java并发编程的艺术(三)——volatile

    1. 并发编程的两个关键问题 并发是让多个线程同时执行,若线程之间是独立的,那并发实现起来很简单,各自执行各自的就行;但往往多条线程之间需要共享数据,此时在并...

    大闲人柴毛毛
  • 梯度消失和梯度爆炸原因及其解决方案

    当我们需要解决一个非常复杂的问题,例如在高分辨率图像中检测数百种类型的对象,我们可能需要训练一个非常深的DNN,可能需要几十层或者上百层,每层包含数百个神经元,...

    于小勇
  • 8个与安全相关的PHP函数

    1. mysql_real_escape_string() 这个函数对于在PHP中防止SQL注入攻击很有帮助,它对特殊的字符,像单引号和双引号,加...

    wangxl
  • 深入理解Java多线程中的volatile关键字Java 的 volatile关键字对可见性的保证Java 的 volatile关键字在保证可见性之前的所做的事情Volatile有时候也是不够的什么时

    Java关键字用于将一个变量标记为“存储在内存中的变量”。更准确的说,意思就是每一次对volatile标记的变量进行读取的时候,都是直接从电脑的主内存进行的,而...

    desperate633
  • 【深度学习思维导图】必备的基本概念和架构

    概念一节下分为激活函数:反向传播算法、学习率、梯度下降和损失(最小化)目标(最大化)函数。

    机器人网

扫码关注云+社区

领取腾讯云代金券