梯度下降法介绍及利用Python实现的方法示例


Posted in Python onJuly 12, 2017

本文主要给大家介绍了梯度下降法及利用Python实现的相关内容,分享出来供大家参考学习,下面话不多说,来一起看看详细的介绍吧。

梯度下降法介绍

梯度下降法(gradient descent),又名最速下降法(steepest descent)是求解无约束最优化问题最常用的方法,它是一种迭代方法,每一步主要的操作是求解目标函数的梯度向量,将当前位置的负梯度方向作为搜索方向(因为在该方向上目标函数下降最快,这也是最速下降法名称的由来)。

梯度下降法特点:越接近目标值,步长越小,下降速度越慢。

直观上来看如下图所示:

梯度下降法介绍及利用Python实现的方法示例

这里每一个圈代表一个函数梯度,最中心表示函数极值点,每次迭代根据当前位置求得的梯度(用于确定搜索方向以及与步长共同决定前进速度)和步长找到一个新的位置,这样不断迭代最终到达目标函数局部最优点(如果目标函数是凸函数,则到达全局最优点)。

下面我们将通过公式来具体说明梯度下降法

下面这个h(θ)是我们的拟合函数

梯度下降法介绍及利用Python实现的方法示例

也可以用向量的形式进行表示:

梯度下降法介绍及利用Python实现的方法示例

下面函数是我们需要进行最优化的风险函数,其中的每一项梯度下降法介绍及利用Python实现的方法示例都表示在已有的训练集上我们的拟合函数与y之间的残差,计算其平方损失函数作为我们构建的风险函数(参见最小二乘法及其Python实现)

梯度下降法介绍及利用Python实现的方法示例

这里我们乘上1/2是为了方便后面求偏导数时结果更加简洁,之所以能乘上1/2是因为乘上这个系数后对求解风险函数最优值没有影响。

我们的目标就是要最小化风险函数,使得我们的拟合函数能够最大程度的对目标函数y进行拟合,即:

梯度下降法介绍及利用Python实现的方法示例

后面的具体梯度求解都是围绕这个目标来进行。

批量梯度下降BGD

按照传统的思想,我们需要对上述风险函数中的每个梯度下降法介绍及利用Python实现的方法示例求其偏导数,得到每个梯度下降法介绍及利用Python实现的方法示例对应的梯度

梯度下降法介绍及利用Python实现的方法示例

这里梯度下降法介绍及利用Python实现的方法示例表示第i个样本点梯度下降法介绍及利用Python实现的方法示例的第j分量,即h(θ)中的梯度下降法介绍及利用Python实现的方法示例

接下来由于我们要最小化风险函数,故按照每个参数的负梯度方向来更新每一个

梯度下降法介绍及利用Python实现的方法示例

这里的α表示每一步的步长

从上面公式可以注意到,它得到的是一个全局最优解,但是每迭代一步,都要用到训练集所有的数据,如果m很大,那么可想而知这种方法的迭代速度!!所以,这就引入了另外一种方法,随机梯度下降。

随机梯度下降SGD

因为批量梯度下降在训练集很大的情况下迭代速度非常之慢,所以在这种情况下再使用批量梯度下降来求解风险函数的最优化问题是不具有可行性的,在此情况下,提出了——随机梯度下降
我们将上述的风险函数改写成以下形式:

梯度下降法介绍及利用Python实现的方法示例

其中,

梯度下降法介绍及利用Python实现的方法示例

称为样本点梯度下降法介绍及利用Python实现的方法示例的损失函数

接下来我们对每个样本的损失函数,对每个梯度下降法介绍及利用Python实现的方法示例求其偏导数,得到每个梯度下降法介绍及利用Python实现的方法示例对应的梯度

梯度下降法介绍及利用Python实现的方法示例

然后根据每个参数梯度下降法介绍及利用Python实现的方法示例的负梯度方向来更新每一个梯度下降法介绍及利用Python实现的方法示例

梯度下降法介绍及利用Python实现的方法示例

与批量梯度下降相比,随机梯度下降每次迭代只用到了一个样本,在样本量很大的情况下,常见的情况是只用到了其中一部分样本数据即可将θ迭代到最优解。因此随机梯度下降比批量梯度下降在计算量上会大大减少。

SGD有一个缺点是,其噪音较BGD要多,使得SGD并不是每次迭代都向着整体最优化方向。而且SGD因为每次都是使用一个样本进行迭代,因此最终求得的最优解往往不是全局最优解,而只是局部最优解。但是大的整体的方向是向全局最优解的,最终的结果往往是在全局最优解附近。

下面是两种方法的图形展示:

梯度下降法介绍及利用Python实现的方法示例

梯度下降法介绍及利用Python实现的方法示例

从上述图形可以看出,SGD因为每次都是用一个样本点进行梯度搜索,因此其最优化路径看上去比较盲目(这也是随机梯度下降名字的由来)。

对比其优劣点如下:

批量梯度下降:

优点:全局最优解;易于并行实现;总体迭代次数不多

缺点:当样本数目很多时,训练过程会很慢,每次迭代需要耗费大量的时间。

随机梯度下降:

优点:训练速度快,每次迭代计算量不大

缺点:准确度下降,并不是全局最优;不易于并行实现;总体迭代次数比较多。

Python实现方法示例

上面我们讲解了什么是梯度下降法,以及如何求解梯度下降,下面我们将通过python来实现梯度下降法。

# _*_ coding: utf-8 _*_ 
# 作者: yhao 
# 博客: http://blog.csdn.net/yhao2014 
# 邮箱: yanhao07@sina.com 
 
# 训练集 
# 每个样本点有3个分量 (x0,x1,x2) 
x = [(1, 0., 3), (1, 1., 3), (1, 2., 3), (1, 3., 2), (1, 4., 4)] 
# y[i] 样本点对应的输出 
y = [95.364, 97.217205, 75.195834, 60.105519, 49.342380] 
 
# 迭代阀值,当两次迭代损失函数之差小于该阀值时停止迭代 
epsilon = 0.0001 
 
# 学习率 
alpha = 0.01 
diff = [0, 0] 
max_itor = 1000 
error1 = 0 
error0 = 0 
cnt = 0 
m = len(x) 
 
 
# 初始化参数 
theta0 = 0 
theta1 = 0 
theta2 = 0 
 
while True: 
 cnt += 1 
 
 # 参数迭代计算 
 for i in range(m): 
 # 拟合函数为 y = theta0 * x[0] + theta1 * x[1] +theta2 * x[2] 
 # 计算残差 
 diff[0] = (theta0 + theta1 * x[i][1] + theta2 * x[i][2]) - y[i] 
 
 # 梯度 = diff[0] * x[i][j] 
 theta0 -= alpha * diff[0] * x[i][0] 
 theta1 -= alpha * diff[0] * x[i][1] 
 theta2 -= alpha * diff[0] * x[i][2] 
 
 # 计算损失函数 
 error1 = 0 
 for lp in range(len(x)): 
 error1 += (y[lp]-(theta0 + theta1 * x[lp][1] + theta2 * x[lp][2]))**2/2 
 
 if abs(error1-error0) < epsilon: 
 break 
 else: 
 error0 = error1 
 
 print ' theta0 : %f, theta1 : %f, theta2 : %f, error1 : %f' % (theta0, theta1, theta2, error1) 
print 'Done: theta0 : %f, theta1 : %f, theta2 : %f' % (theta0, theta1, theta2) 
print '迭代次数: %d' % cnt

结果(截取部分):

theta0 : 2.782632, theta1 : 3.207850, theta2 : 7.998823, error1 : 7.508687 
 theta0 : 4.254302, theta1 : 3.809652, theta2 : 11.972218, error1 : 813.550287 
 theta0 : 5.154766, theta1 : 3.351648, theta2 : 14.188535, error1 : 1686.507256 
 theta0 : 5.800348, theta1 : 2.489862, theta2 : 15.617995, error1 : 2086.492788 
 theta0 : 6.326710, theta1 : 1.500854, theta2 : 16.676947, error1 : 2204.562407 
 theta0 : 6.792409, theta1 : 0.499552, theta2 : 17.545335, error1 : 2194.779569 
 theta0 : 74.892395, theta1 : -13.494257, theta2 : 8.587471, error1 : 87.700881 
 theta0 : 74.942294, theta1 : -13.493667, theta2 : 8.571632, error1 : 87.372640 
 theta0 : 74.992087, theta1 : -13.493079, theta2 : 8.555828, error1 : 87.045719 
 theta0 : 75.041771, theta1 : -13.492491, theta2 : 8.540057, error1 : 86.720115 
 theta0 : 75.091349, theta1 : -13.491905, theta2 : 8.524321, error1 : 86.395820 
 theta0 : 75.140820, theta1 : -13.491320, theta2 : 8.508618, error1 : 86.072830 
 theta0 : 75.190184, theta1 : -13.490736, theta2 : 8.492950, error1 : 85.751139 
 theta0 : 75.239442, theta1 : -13.490154, theta2 : 8.477315, error1 : 85.430741 
 theta0 : 97.986390, theta1 : -13.221172, theta2 : 1.257259, error1 : 1.553781 
 theta0 : 97.986505, theta1 : -13.221170, theta2 : 1.257223, error1 : 1.553680 
 theta0 : 97.986620, theta1 : -13.221169, theta2 : 1.257186, error1 : 1.553579 
 theta0 : 97.986735, theta1 : -13.221167, theta2 : 1.257150, error1 : 1.553479 
 theta0 : 97.986849, theta1 : -13.221166, theta2 : 1.257113, error1 : 1.553379 
 theta0 : 97.986963, theta1 : -13.221165, theta2 : 1.257077, error1 : 1.553278 
Done: theta0 : 97.987078, theta1 : -13.221163, theta2 : 1.257041 
迭代次数: 3443

可以看到最后收敛到稳定的参数值。

注意:这里在选取alpha和epsilon时需要谨慎选择,可能不适的值会导致最后无法收敛。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

参考文档:

  • 随机梯度下降(Stochastic gradient descent)和 批量梯度下降(Batch gradient descent )的公式对比、实现对比
  • python实现梯度下降算法
Python 相关文章推荐
Python中的super用法详解
May 28 Python
编写Python脚本抓取网络小说来制作自己的阅读器
Aug 20 Python
python学习入门细节知识点
Mar 29 Python
python+pandas生成指定日期和重采样的方法
Apr 11 Python
python批量导入数据进Elasticsearch的实例
May 30 Python
Python给图像添加噪声具体操作
Mar 03 Python
python调用外部程序的实操步骤
Mar 04 Python
Windows 安装 Anaconda3+PyCharm的方法步骤
Jun 13 Python
解决Python计算矩阵乘向量,矩阵乘实数的一些小错误
Aug 26 Python
python实现图片上添加图片
Nov 26 Python
用python实现学生管理系统
Jul 24 Python
一篇文章带你搞定Ubuntu中打开Pycharm总是卡顿崩溃
Nov 02 Python
python3之微信文章爬虫实例讲解
Jul 12 #Python
python脚本替换指定行实现步骤
Jul 11 #Python
Python书单 不将就
Jul 11 #Python
Python编写一个闹钟功能
Jul 11 #Python
python自定义异常实例详解
Jul 11 #Python
详解python中的文件与目录操作
Jul 11 #Python
python 系统调用的实例详解
Jul 11 #Python
You might like
谈一谈收音机的高放电路
2021/03/02 无线电
第十节--抽象方法和抽象类
2006/11/16 PHP
php 问卷调查结果统计
2015/10/08 PHP
PHP中explode函数和split函数的区别小结
2016/08/24 PHP
Windows平台实现PHP连接SQL Server2008的方法
2017/07/26 PHP
jquery ajax 登录验证实现代码
2009/09/23 Javascript
jQuery中实现动画效果的基本操作介绍
2013/04/16 Javascript
js为数字添加逗号并格式化数字的代码
2013/08/23 Javascript
基于jquery插件制作左右按钮与标题文字图片切换效果
2013/11/07 Javascript
javascript异步编程代码书写规范Promise学习笔记
2015/02/11 Javascript
PHP+jQuery实现随意拖动层并即时保存拖动位置
2015/04/30 Javascript
CSS+JS实现点击文字弹出定时自动关闭DIV层菜单的方法
2015/05/12 Javascript
JavaScript模拟push
2016/03/06 Javascript
Javascript基础知识盲点总结之函数
2016/05/15 Javascript
基于jQuery的ajax方法封装
2016/07/14 Javascript
详解微信小程序开发之——wx.showToast(OBJECT)的使用
2017/01/18 Javascript
JavaScript 格式化数字、金额、千分位、保留几位小数、舍入舍去
2019/07/23 Javascript
javascript中contains是否包含功能实现代码(扩展字符、数组、dom)
2020/04/07 Javascript
vuejs element table 表格添加行,修改,单独删除行,批量删除行操作
2020/07/18 Javascript
解决vue中el-tab-pane切换的问题
2020/07/19 Javascript
[02:40]DOTA2英雄基础教程 先知
2013/11/29 DOTA
使用Mixin设计模式进行Python编程的方法讲解
2016/06/21 Python
利用Python查看微信共同好友功能的实现代码
2019/04/24 Python
Python实现微信翻译机器人的方法
2019/08/13 Python
python GUI库图形界面开发之PyQt5动态(可拖动控件大小)布局控件QSplitter详细使用方法与实例
2020/03/06 Python
解决pycharm不能自动补全第三方库的函数和属性问题
2020/03/12 Python
基于打开pycharm有带图片md文件卡死问题的解决
2020/04/24 Python
基于Pyinstaller打包Python程序并压缩文件大小
2020/05/28 Python
关于CSS Tooltips(鼠标经过时显示)的效果
2013/04/10 HTML / CSS
html5 web本地存储将取代我们的cookie
2012/12/26 HTML / CSS
HTML5和CSS3实例教程总结(推荐)
2016/07/18 HTML / CSS
印尼综合在线预订网站:Tiket.com(机票、酒店、火车、租车和娱乐)
2018/10/11 全球购物
游戏商店:Eneba
2020/04/25 全球购物
服务行业演讲稿
2014/09/02 职场文书
世界文化遗产导游词
2019/08/07 职场文书
微信小程序APP的生命周期及页面的生命周期
2022/04/19 Javascript