梯度下降法介绍及利用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中装饰器的用法
Apr 27 Python
在Python的Django框架中编写编译函数
Jul 20 Python
python+ffmpeg视频并发直播压力测试
Mar 06 Python
python 移动图片到另外一个文件夹的实例
Jan 10 Python
python实现计数排序与桶排序实例代码
Mar 28 Python
元组列表字典(莫烦python基础)
Apr 03 Python
利用PyCharm Profile分析异步爬虫效率详解
May 08 Python
python的一些加密方法及python 加密模块
Jul 11 Python
Python集合操作方法详解
Feb 09 Python
Django 实现将图片转为Base64,然后使用json传输
Mar 27 Python
python对接ihuyi实现短信验证码发送
May 10 Python
Python Tornado实现WEB服务器Socket服务器共存并实现交互的方法
May 26 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
全国FM电台频率大全 - 1 北京市
2020/03/11 无线电
ThinkPHP内置jsonRPC的缺陷分析
2014/12/18 PHP
php的sso单点登录实现方法
2015/01/08 PHP
php运行时动态创建函数的方法
2015/03/16 PHP
PHP实现的蚂蚁爬杆路径算法代码
2015/12/03 PHP
PJBlog插件 防刷新的在线播放器
2006/10/25 Javascript
jquery插件之easing 动态菜单
2010/08/21 Javascript
原生js实现查找/添加/删除/指定元素的class
2013/04/12 Javascript
jquery选择器需要注意的问题
2014/11/26 Javascript
使用jQuery mobile库检测url绝对地址和相对地址的方法
2015/12/04 Javascript
基于jquery插件实现拖拽删除图片功能
2020/08/27 Javascript
AnjularJS中$scope和$rootScope的区别小结
2016/09/18 Javascript
使用bootstrap实现多窗口和拖动效果
2016/09/22 Javascript
用nodeJS搭建本地文件服务器的几种方法小结
2017/03/16 NodeJs
JavaScript实现购物车基本功能
2017/07/21 Javascript
原生JavaScript实现todolist功能
2018/03/02 Javascript
详解如何在Angular优雅编写HTTP请求
2018/12/05 Javascript
[01:01:52]DOTA2-DPC中国联赛定级赛 SAG vs iG BO3第二场 1月9日
2021/03/11 DOTA
python益智游戏计算汉诺塔问题示例
2014/03/05 Python
Python自定义简单图轴简单实例
2018/01/08 Python
Python cookbook(数据结构与算法)将名称映射到序列元素中的方法
2018/03/22 Python
Python功能点实现:函数级/代码块级计时器
2019/01/02 Python
解决python super()调用多重继承函数的问题
2019/06/26 Python
Python企业编码生成系统之主程序模块设计详解
2019/07/26 Python
斯福泰克软件测试面试题
2015/02/16 面试题
制作部班长职位说明书
2014/02/26 职场文书
对党的十八届四中全会的期盼
2014/10/17 职场文书
学校党的群众路线教育实践活动整改措施
2014/10/25 职场文书
颐和园的导游词
2015/01/30 职场文书
证券公司客户经理岗位职责
2015/04/09 职场文书
2015年学校图书室工作总结
2015/05/19 职场文书
CSS实现章节添加自增序号的方法
2021/06/23 HTML / CSS
Python实现简单的俄罗斯方块游戏
2021/09/25 Python
mysql下的max_allowed_packet参数设置详解
2022/02/12 MySQL
使用Python通过企业微信应用给企业成员发消息
2022/04/18 Python
uniapp引入支付宝原生扫码插件步骤详解
2022/07/23 Javascript