zoukankan      html  css  js  c++  java
  • 什么是梯度下降

    梯度下降(Gradient Descent GD)简单来说就是一种寻找目标函数最小化的方法,它利用梯度信息,通过不断迭代调整参数来寻找合适的目标值。 本文将介绍它的原理和实现。

    什么是梯度?

    关于梯度的引入,可以分为四个概念:导数 -》偏导数 -》方向导数 -》 梯度。

    导数:当函数定义域和取值都在实数域中的时候,导数可以表示函数曲线上的切线斜率。

    偏导数:偏导其实就是多元函数一个多变量的函数的偏导数是它关于其中一个变量的导数,而保持其他变量恒定。因为曲面上的每一点都有无穷多条切线,描述这种函数的导数相当困难。偏导数就是选择其中一条切线,并求出它的斜率 。几何意义是表示固定面上一点的切线斜率。

    多元函数降维时候的变化,比如二元函数固定y,只让x单独变化,从而看成是关于x的一元函数的变化来研究。

    [公式]指的是函数在y方向不变,函数值沿着x轴方向的变化率

    [公式]指的是函数在x方向不变,函数值沿着y轴方向的变化率

    但是偏导数有一个缺点,就是只能表示多元函数沿坐标轴方向的变化率,但是很多时候要考虑多元函数沿任意方向的变化率,于是就有了方向导数。

    方向导数:某个方向的导数,本质就是函数在A点上无数个切线的斜率的定义,每个切线都代表一个方向,每个方向都是有方向导数的。

    梯度:梯度是一个矢量,在其方向上的方向导数最大,也就是函数在该点处沿着梯度的方向变化最快,变化率最大。

    那么在机器学习中逐步逼近、迭代求解最优化时,经常会使用到梯度,沿着梯度向量的方向是函数增加的最快,更容易找到函数的最大值,反过来,沿着梯度向量相反的地方,梯度减少的最快,更容易找到最小值。

    什么是梯度下降

    举个常见的例子:你站在山上某处,想要尽快下山,于是决定走一步算一步,也就是每走到一个位置时,求解当前位置的梯度,沿着梯度的负方向,也就是当前最陡峭的位置向下走,这样一直走下去,很可能走不到山脚,而是某个局部的山峰最低处。如下图所示:

    1584274080296

    以上,我们可以总结一下:梯度下降法就是沿着梯度下降的方向求解极小值,沿着梯度上升的方向可以求得最大值,这种方法叫梯度上升。

    从上图可以看到:受到起始点和目标函数特性的影响,梯度下降不一定找到的是全局最优解,可能只是局部最优解,那么什么时候能找到全局最优解呢?这个与损失函数有关,当损失函数是凸函数的话,可以找到全局最优。

    一些重要概念

    根据上述梯度下降的求解原理,我们需要了解如下几个梯度下降相关的重要概念:

    步长(Learning rate):每一步梯度下降时向目标方向前行的长度,用上面下山的例子,步长就是在当前这一步所在位置沿着最陡峭最易下山的位置走的那一步的长度。

    假设函数(hypothesis function) 在监督学习中,为了拟合输入样本,而使用的假设函数,常用h()表示,对于线性回归模型,假设函数就是函数

    [Y = W_0 + W_1X1 + W_2X2 + ... + W_nX_n ]

    损失函数(loss function): 常用J()表示,为了评估模型的好坏,通常用损失函数来度量拟合的程度。损失函数最小化,意味着拟合程度最好,对应的模型参数即为最优参数。每个机器学习模型都有一个损失函数,学习的目的就是将损失函数最小化,

    算法详解

    梯度下降的具体算法实现过程是:

    1. 确定模型的假设函数和损失函数
    2. 相关参数的初始化,包括:参数、算法终止距离和步长
    3. 确定当前位置损失函数的梯度
    4. 用步长乘以梯度,得到当前位置下降的距离
    5. 确定是否所有参数梯度下降的距离都小于算法终止距离,如果小于则算法终止,否则进行下一步
    6. 更新所有参数,更新完毕转到步骤1

    面临的问题

    梯度下降会遇到所有最优化问题中常见的两个问题:局部最小值和鞍点。

    局部最小值

    这是梯度下降法最常遇到的一个问题,当一个函数存在多个局部最小值,很可能梯度下降法只是找到其中的一个局部最小值而停止。

    怎么避免呢?

    下山的例子中,我们看到初始值不同,获得的最小值可能不同,所以规避局部最小值最简单的方法可以多次用不同的初始值执行算法,选择损失函数最小的初始值。

    鞍点

    鞍点是最优化问题中常遇到的一个现象,鞍点的数学含义是:目标函数在此点的梯度为0,但从该点出发的一个方向存在函数极大值点,而另一个方向是函数的极小值点。典型的鞍点函数是典型的鞍点是函数 f(x)=x^3 中的(0,0),函数 z=x^2-y^2 的 多个鞍点 (0,0,0),(1,1,0),(2,2,0)) 。

    在高度非凸空间中,存在大量的鞍点,这使得梯度下降法有时会失灵,虽然不是极小值,但是看起来确是收敛的。

    调优

    从算法的执行步骤来看,需要调优的地方包括:

    1. 步长:不同的场景中步长的选择需要实验和权衡,步长越长,迭代越快,有可能错过最优解,步长太小,迭代速度太慢,很长时间算法都不能结束。所以算法的步长需要多次运行后才能得到一个较为优的值。
    2. 初始值:初始值不同,最终得到的最小值有可能不同,可能获得的只是局部最小值;当然如果损失函数是凸函数则一定是最优解。需要多次用不同初始值运行算法,选择损失函数最小化的初值。

    常见的梯度下降法

    批量梯度下降(Batch Gradient Descent BGD)

    上面所介绍的算法其实就是批量梯度下降。需要首先计算所有数据上的损失值,然后再进行梯度下降,具体的操作步骤是:遍历全部数据集算一次损失函数,然后算函数对各个参数的梯度,更新梯度。这种方法每更新一次参数,都要把数据集里的所有样本计算一遍,计算量大,计算速度慢,不支持在线学习。

    随机梯度下降(Stochastic Gradient Descent SGD)

    不使用全量的样本来计算梯度,而使用单一样本来近似估计梯度,可以极大地减少计算量,提高计算效率。具体的操作步骤是:每次从训练集中随机选择一个样本,计算其对应的损失和梯度,进行参数更新,反复迭代。

    这种方式在数据规模比较大时可以减少计算复杂度,从概率意义上来说的单个样本的梯度是对整个数据集合梯度的无偏估计,但是它存在着一定的不确定性,因此收敛速率比批梯度下降得更慢。

    小批量梯度下降(Mini-batch Gradient Descent)

    为了克服上面两种方法的缺点,采用的一种折中手段:将数据分为若干批次,按批次更新参数,每一批次中的一组数据共同决定了本次梯度的方向,下降起来就不容易跑偏,减少了随机性,另一方面,因为批的样本数比整个数据集少了很多,计算量也不是很大。

    每次使用多个样本来估计梯度,这样可以减少不确定性,提高收敛速率,其中每次迭代选取的样本数量称为批大小(batch size)。

    参考:

    什么是梯度下降法

    为什么梯度反方向是函数值局部下降最快的方向?

    梯度下降小结

  • 相关阅读:
    SVG的学习(34—36)
    28-30 js 文本全选
    28-30 键盘事件
    react学习(四)之设置 css样式 篇
    跳台阶
    详解Django的CSRF认证
    Django model中数据批量导入bulk_create()
    Redis从入门到精通
    Python的进阶1:copy()与deepcopy()区别
    sql面试题
  • 原文地址:https://www.cnblogs.com/ybjourney/p/12508027.html
Copyright © 2011-2022 走看看