python+numpy+matplotalib实现梯度下降法


Posted in Python onAugust 31, 2018

这个阶段一直在做和梯度一类算法相关的东西,索性在这儿做个汇总:

一、算法论述

梯度下降法(gradient  descent)别名最速下降法(曾经我以为这是两个不同的算法-.-),是用来求解无约束最优化问题的一种常用算法。下面以求解线性回归为题来叙述:

设:一般的线性回归方程(拟合函数)为:(其中python+numpy+matplotalib实现梯度下降法的值为1)

python+numpy+matplotalib实现梯度下降法

python+numpy+matplotalib实现梯度下降法这一组向量参数选择的好与坏就需要一个机制来评估,据此我们提出了其损失函数为(选择均方误差):

python+numpy+matplotalib实现梯度下降法

我们现在的目的就是使得损失函数python+numpy+matplotalib实现梯度下降法取得最小值,即目标函数为:

python+numpy+matplotalib实现梯度下降法

如果python+numpy+matplotalib实现梯度下降法的值取到了0,意味着我们构造出了极好的拟合函数,也即选择出了最好的python+numpy+matplotalib实现梯度下降法值,但这基本是达不到的,我们只能使得其无限的接近于0,当满足一定精度时停止迭代。

那么问题来了如何调整python+numpy+matplotalib实现梯度下降法使得python+numpy+matplotalib实现梯度下降法取得的值越来越小呢?方法很多,此处以梯度下降法为例:

分为两步:(1)初始化python+numpy+matplotalib实现梯度下降法的值。

(2)改变python+numpy+matplotalib实现梯度下降法的值,使得python+numpy+matplotalib实现梯度下降法按梯度下降的方向减少。

python+numpy+matplotalib实现梯度下降法值的更新使用如下的方式来完成:

python+numpy+matplotalib实现梯度下降法

python+numpy+matplotalib实现梯度下降法

其中python+numpy+matplotalib实现梯度下降法为步长因子,这里我们取定值,但注意如果python+numpy+matplotalib实现梯度下降法取得过小会导致收敛速度过慢,python+numpy+matplotalib实现梯度下降法过大则损失函数可能不会收敛,甚至逐渐变大,可以在下述的代码中修改python+numpy+matplotalib实现梯度下降法的值来进行验证。后面我会再写一篇关于随机梯度下降法的文章,其实与梯度下降法最大的不同就在于一个求和符号。

二、代码实现

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
from matplotlib import style
 
 
#构造数据
def get_data(sample_num=10000):
 """
 拟合函数为
 y = 5*x1 + 7*x2
 :return:
 """
 x1 = np.linspace(0, 9, sample_num)
 x2 = np.linspace(4, 13, sample_num)
 x = np.concatenate(([x1], [x2]), axis=0).T
 y = np.dot(x, np.array([5, 7]).T) 
 return x, y
#梯度下降法
def GD(samples, y, step_size=0.01, max_iter_count=1000):
 """
 :param samples: 样本
 :param y: 结果value
 :param step_size: 每一接迭代的步长
 :param max_iter_count: 最大的迭代次数
 :param batch_size: 随机选取的相对于总样本的大小
 :return:
 """
 #确定样本数量以及变量的个数初始化theta值
 m, var = samples.shape
 theta = np.zeros(2)
 y = y.flatten()
 #进入循环内
 print(samples)
 loss = 1
 iter_count = 0
 iter_list=[]
 loss_list=[]
 theta1=[]
 theta2=[]
 #当损失精度大于0.01且迭代此时小于最大迭代次数时,进行
 while loss > 0.001 and iter_count < max_iter_count:
 loss = 0
 #梯度计算
 theta1.append(theta[0])
 theta2.append(theta[1])
 for i in range(m):
  h = np.dot(theta,samples[i].T) 
 #更新theta的值,需要的参量有:步长,梯度
  for j in range(len(theta)):
  theta[j] = theta[j] - step_size*(1/m)*(h - y[i])*samples[i,j]
 #计算总体的损失精度,等于各个样本损失精度之和
 for i in range(m):
  h = np.dot(theta.T, samples[i])
  #每组样本点损失的精度
  every_loss = (1/(var*m))*np.power((h - y[i]), 2)
  loss = loss + every_loss
 
 print("iter_count: ", iter_count, "the loss:", loss)
 
 iter_list.append(iter_count)
 loss_list.append(loss)
 
 iter_count += 1
 plt.plot(iter_list,loss_list)
 plt.xlabel("iter")
 plt.ylabel("loss")
 plt.show()
 return theta1,theta2,theta,loss_list
def painter3D(theta1,theta2,loss):
 style.use('ggplot')
 fig = plt.figure()
 ax1 = fig.add_subplot(111, projection='3d')
 x,y,z = theta1,theta2,loss
 ax1.plot_wireframe(x,y,z, rstride=5, cstride=5)
 ax1.set_xlabel("theta1")
 ax1.set_ylabel("theta2")
 ax1.set_zlabel("loss")
 plt.show()
def predict(x, theta):
 y = np.dot(theta, x.T)
 return y 
if __name__ == '__main__':
 samples, y = get_data()
 theta1,theta2,theta,loss_list = GD(samples, y)
 print(theta) # 会很接近[5, 7] 
 painter3D(theta1,theta2,loss_list)
 predict_y = predict(theta, [7,8])
 print(predict_y)

三、绘制的图像如下:

迭代次数与损失精度间的关系图如下:步长为0.01

python+numpy+matplotalib实现梯度下降法

变量python+numpy+matplotalib实现梯度下降法python+numpy+matplotalib实现梯度下降法与损失函数loss之间的关系:(从初始化之后会一步步收敛到loss满足精度,之后python+numpy+matplotalib实现梯度下降法python+numpy+matplotalib实现梯度下降法会变的稳定下来)

python+numpy+matplotalib实现梯度下降法

下面我们来看一副当步长因子变大后的图像:步长因子为0.5(很明显其收敛速度变缓了)

python+numpy+matplotalib实现梯度下降法

python+numpy+matplotalib实现梯度下降法

当步长因子设置为1.8左右时,其损失值已经开始震荡

python+numpy+matplotalib实现梯度下降法

python+numpy+matplotalib实现梯度下降法

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python文件处理
Feb 29 Python
python3爬取淘宝信息代码分析
Feb 10 Python
python利用高阶函数实现剪枝函数
Mar 20 Python
python如何使用unittest测试接口
Apr 04 Python
python数字图像处理之高级形态学处理
Apr 27 Python
Python 实现子类获取父类的类成员方法
Jan 11 Python
深度辨析Python的eval()与exec()的方法
Mar 26 Python
python中正则表达式与模式匹配
May 07 Python
解决ROC曲线画出来只有一个点的问题
Feb 28 Python
python 中不同包 类 方法 之间的调用详解
Mar 09 Python
django下创建多个app并设置urls方法
Aug 02 Python
python 实现控制鼠标键盘
Nov 27 Python
python实现随机梯度下降法
Mar 24 #Python
python实现决策树分类(2)
Aug 30 #Python
python实现决策树分类
Aug 30 #Python
python实现多人聊天室
Mar 31 #Python
Python实现将数据写入netCDF4中的方法示例
Aug 30 #Python
Python使用爬虫抓取美女图片并保存到本地的方法【测试可用】
Aug 30 #Python
Python使用一行代码获取上个月是几月
Aug 30 #Python
You might like
php数组函数序列之rsort() - 对数组的元素值进行降序排序
2011/11/02 PHP
JavaScript 继承的实现
2009/07/09 Javascript
jQuery 定时局部刷新(setInterval)
2010/11/19 Javascript
js函数调用常用方法详解
2012/12/03 Javascript
JavaScript字符串插入、删除、替换函数使用示例
2013/07/25 Javascript
jquery实现metro效果示例代码
2013/09/06 Javascript
JavaScript动态改变HTML页面元素例如添加或删除
2014/08/10 Javascript
AngularJS 依赖注入详解和简单实例
2016/07/28 Javascript
详解Vue组件实现tips的总结
2017/11/01 Javascript
Angular6新特性之Angular Material
2018/12/28 Javascript
Vue实现input宽度随文字长度自适应操作
2020/07/29 Javascript
nodejs+koa2 实现模仿springMVC框架
2020/10/21 NodeJs
nuxt引入组件和公共样式的操作
2020/11/05 Javascript
[06:13]DOTA2进化论(修改版)
2013/10/08 DOTA
[03:35]2018年度DOTA2最佳辅助位选手5号位-完美盛典
2018/12/17 DOTA
python中的随机函数random的用法示例
2018/01/27 Python
Python使用分布式锁的代码演示示例
2018/07/30 Python
python机器学习之KNN分类算法
2018/08/29 Python
Python中的Socket 与 ScoketServer 通信及遇到问题解决方法
2019/04/01 Python
Python实现的栈、队列、文件目录遍历操作示例
2019/05/06 Python
Python使用__new__()方法为对象分配内存及返回对象的引用示例
2019/09/20 Python
Python文件时间操作步骤代码详解
2020/04/13 Python
PyCharm 2020.2.2 x64 下载并安装的详细教程
2020/10/15 Python
阿迪达斯芬兰官方网站:adidas芬兰
2017/01/30 全球购物
Python里面如何拷贝一个对象
2014/02/17 面试题
公益活动策划方案
2014/01/09 职场文书
投标邀请书范文
2014/01/31 职场文书
制药工程专业职业生涯规划范文
2014/03/10 职场文书
项目经理任命书
2014/06/04 职场文书
销售岗位职责范本
2014/06/12 职场文书
优秀教师自我评价范文
2014/09/27 职场文书
谢师宴邀请函
2015/02/02 职场文书
社区党务工作总结2015
2015/05/19 职场文书
社区安全温馨提示语
2015/07/14 职场文书
Redis安装使用RedisJSON模块的方法
2022/03/23 Redis
Oracle用户管理及赋权
2022/04/24 Oracle