梯度下降法

Posted zsychanpin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了梯度下降法相关的知识,希望对你有一定的参考价值。

 梯度下降法在凸优化中应用很广泛。经常使用于求凸函数极值。

梯度是个向量。其形式为

技术分享

一般是表示函数上升最快的方向。因此。我们仅仅须要每一步往梯度方向走一小步。终于就能够到达极值点,其表现形式为:

技术分享

初始点为x0。 然后往梯度的反方向移动一小步r到x1。 再次往梯度反方向移动r到x2,... ...。终于会越来越接近极值点min的。

迭代时的公式为X(n+1) = X(n) - r * grad(f)

 

以下举样例说明梯度下降法求极值点的有效性:

#!/usr/bin/python
# -*- coding:utf8 -*-
import random
import numpy as np
import math

#f(x,y) = (x-2)^2+(y-1)^2 + 1
def solution(grad_func) :
    rate = 0.1
    x = random.uniform(-10,10)
    y = random.uniform(-10,10)
    point = np.array([x, y])
    for index in xrange(0, 1000) :
        grad = grad_func(point[0], point[1])
        point = point - rate * grad
        print grad
        if reduce(lambda a,b: math.sqrt(a*a+b*b), [grad[i] for i in xrange(grad.shape[0])]) < 0.000001 : break
    print "times of iterate : %s" % index
    return point[0], point[1]

if __name__ == "__main__" :
    x, y = solution(lambda a,b: np.array([2*(a-2), 2*(b-1)]))
    print "minimum point of f(x,y) = (x-2)^2+(y-1)^2 + 1 : (%s,%s)" % (x, y) 


 

f:\python_workspace\SGD>python gd.py
[  5.68071667 -21.54721046]
[  4.54457333 -17.23776836]
[  3.63565867 -13.79021469]
[  2.90852693 -11.03217175]
[ 2.32682155 -8.8257374 ]
[ 1.86145724 -7.06058992]
[ 1.48916579 -5.64847194]
[ 1.19133263 -4.51877755]
[ 0.95306611 -3.61502204]
[ 0.76245288 -2.89201763]
[ 0.60996231 -2.31361411]
[ 0.48796985 -1.85089128]
[ 0.39037588 -1.48071303]
[ 0.3123007  -1.18457042]
[ 0.24984056 -0.94765634]
[ 0.19987245 -0.75812507]
[ 0.15989796 -0.60650006]
[ 0.12791837 -0.48520004]
[ 0.10233469 -0.38816004]
[ 0.08186776 -0.31052803]
[ 0.0654942  -0.24842242]
[ 0.05239536 -0.19873794]
[ 0.04191629 -0.15899035]
[ 0.03353303 -0.12719228]
[ 0.02682643 -0.10175382]
[ 0.02146114 -0.08140306]
[ 0.01716891 -0.06512245]
[ 0.01373513 -0.05209796]
[ 0.0109881  -0.04167837]
[ 0.00879048 -0.03334269]
[ 0.00703239 -0.02667415]
[ 0.00562591 -0.02133932]
[ 0.00450073 -0.01707146]
[ 0.00360058 -0.01365717]
[ 0.00288047 -0.01092573]
[ 0.00230437 -0.00874059]
[ 0.0018435  -0.00699247]
[ 0.0014748  -0.00559398]
[ 0.00117984 -0.00447518]
[ 0.00094387 -0.00358014]
[ 0.0007551  -0.00286412]
[ 0.00060408 -0.00229129]
[ 0.00048326 -0.00183303]
[ 0.00038661 -0.00146643]
[ 0.00030929 -0.00117314]
[ 0.00024743 -0.00093851]
[ 0.00019794 -0.00075081]
[ 0.00015836 -0.00060065]
[ 0.00012668 -0.00048052]
[ 0.00010135 -0.00038442]
[  8.10778975e-05  -3.07532064e-04]
[  6.48623180e-05  -2.46025651e-04]
[  5.18898544e-05  -1.96820521e-04]
[  4.15118835e-05  -1.57456417e-04]
[  3.32095068e-05  -1.25965133e-04]
[  2.65676055e-05  -1.00772107e-04]
[  2.12540844e-05  -8.06176854e-05]
[  1.70032675e-05  -6.44941483e-05]
[  1.36026140e-05  -5.15953187e-05]
[  1.08820912e-05  -4.12762549e-05]
[  8.70567296e-06  -3.30210039e-05]
[  6.96453837e-06  -2.64168032e-05]
[  5.57163069e-06  -2.11334425e-05]
[  4.45730455e-06  -1.69067540e-05]
[  3.56584364e-06  -1.35254032e-05]
[  2.85267491e-06  -1.08203226e-05]
[  2.28213993e-06  -8.65625806e-06]
[  1.82571195e-06  -6.92500645e-06]
[  1.46056956e-06  -5.54000516e-06]
[  1.16845565e-06  -4.43200413e-06]
[  9.34764516e-07  -3.54560330e-06]
[  7.47811614e-07  -2.83648264e-06]
[  5.98249291e-07  -2.26918611e-06]
[  4.78599433e-07  -1.81534889e-06]
[  3.82879547e-07  -1.45227911e-06]
[  3.06303638e-07  -1.16182329e-06]
[  2.45042910e-07  -9.29458632e-07]
times of iterate : 76
minimum point of f(x,y) = (x-2)^2+(y-1)^2 + 1 : (2.00000009802,0.999999628217)


能够看到梯度长度慢慢地变小,终于的解与实际解(2, 1)也非常接近。在实际应用中。我们须要对步长r值进行调整。假设步长r太小。那么须要迭代非常多次才干收敛,而假设太大。则会越过极值点。一直在极值点附近徘徊。针对这样的情况。能够让步长r随着迭代次数的添加而变小。

 

 

 



以上是关于梯度下降法的主要内容,如果未能解决你的问题,请参考以下文章

Python实现简单的梯度下降法

梯度下降法的原理是啥?

02_有监督学习--简单线性回归模型(梯度下降法代码实现)

对数几率回归法(梯度下降法,随机梯度下降与牛顿法)与线性判别法(LDA)

matlib实现梯度下降法

梯度下降法是啥?