前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >梯度下降算法

梯度下降算法

作者头像
用户6021899
发布2019-08-14 17:01:21
1.1K0
发布2019-08-14 17:01:21
举报

本篇介绍求解最优化问题的一种数值算法-- 梯度下降算法。

在微积分中我们学过,沿着梯度grad(f)方向,函数f的方向导数有最大值。所以要找到函数的极大值,最好的方法是沿着该函数的梯度方向探寻,称之为梯度上升算法。同理,要找到函数的极小值,沿着该函数的梯度的相反方向探寻,称之为梯度下降算法。在机器学习领域,我们常需求解权重参数取何值时损失函数最小,梯度下降算法是一种很重要的算法。

上述公式就是在梯度下降算法中,用于迭代求解各自变量的值。其中alpha 为迭代步长(需人为调参)。当函数值的变化量足够小,满足精度要求,或者迭代步数已足够时,就可以退出迭代。

下面以一个普通的二元函数为例,介绍梯度下降算法的基本实现。

二元函数的梯度公式如下:

此例中二元函数为:

z(x,y)= x**2 + 2*y**2 +2*x*y +4*x - 16*y +10

下面我们先利用python的符号计算模块sympy来计算它的理论最小值:

from sympy import *
x, y = symbols("x y")#创建符号变量x和y
z = x**2 + 2*y**2 +2*x*y +4*x - 16*y +10
print("z对x的一阶偏导数:",diff(z,x))
print("z对x的二阶偏导数:",diff(z,x,2))
print("z对y的一阶偏导数:",diff(z,y))
print("z对y的二阶偏导数:",diff(z,y,2))
print("两个二阶偏导数都为正,所以存在极小值")
print()
print("x, y 如下时:")
r = solve([diff(z,x), diff(z,y)],x,y) #求解方程组,返回一字典
print(r)
print("z取极小值,值为:", end =''); print(z.subs({x :r[x], y:r[y]}))
print("理论解 求解完毕!",end ="\n\n")

结果如下:

z对x的一阶偏导数: 2*x + 2*y + 4
z对x的二阶偏导数: 2
z对y的一阶偏导数: 2*x + 4*y - 16
z对y的二阶偏导数: 4
两个二阶偏导数都为正,所以存在极小值
x, y 如下时:
{x: -12, y: 10}
z取极小值,值为:-94
理论解 求解完毕!

下面是梯度下降算法的示例:

gx= diff(z,x)
gy= diff(z,y)
print("梯度下降算法")
func_z = lambda x,y : x**2 + 2*y**2 +2*x*y +4*x - 16*y +10
x_, y_ = 0, 0 #随便初始化 x 和 y
z_last = func_z(x_, y_)
alpha = 0.1 #步长,可以调整
x_  -= alpha * gx.evalf(subs ={x:x_, y:y_}, n =21)
y_  -= alpha * gy.evalf(subs ={x:x_, y:y_}, n =21)
z_offset = abs( func_z(x_, y_) - z_last)
i=1
while z_offset>0.000000001:
    #print(x_,y_,z_last)
    x_  -= alpha * gx.evalf(subs ={x:x_, y:y_}, n =21)
    y_  -= alpha * gy.evalf(subs ={x:x_, y:y_}, n =21)
    z_new = func_z(x_, y_)
    z_offset = abs(z_new - z_last)
    z_last = z_new
    i += 1
print("x, y, z_min:") ; print(x_, y_, z_last)
print("迭代步数:%d, 精度: %.21f" %(i, z_offset))

利用迭代公式依次更新x,y 和 z 的值,当z的变化量很小很小,满足精度要求时就可以停止迭代。

结果如下,可以看到结果收敛很快,精度很高。

x, y, z_min:
-11.9999033284856889273 9.99994395025263471318 -93.9999999952082978705
迭代步数:135, 精度: 0.000000000919632075122

注意,由于函数可能有多个极小值,所以,梯度下降算法有可能求得局部的最小值。需要合理设置各自变量的初始值,以及迭代步长,以免陷入局部最优解。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python可视化编程机器学习OpenCV 微信公众号,前往查看

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

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档