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实现线程池代码分享
Jun 21 Python
Python selenium 三种等待方式解读
Sep 15 Python
Django REST为文件属性输出完整URL的方法
Dec 18 Python
python实现单向链表详解
Feb 08 Python
Python 移动光标位置的方法
Jan 20 Python
在vscode中配置python环境过程解析
Sep 28 Python
python实现从尾到头打印单链表操作示例
Feb 22 Python
Python面向对象程序设计之继承、多态原理与用法详解
Mar 23 Python
python如何调用字典的key
May 25 Python
Python OpenCV去除字母后面的杂线操作
Jul 05 Python
用python写PDF转换器的实现
Oct 29 Python
聊聊基于pytorch实现Resnet对本地数据集的训练问题
Mar 25 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数组实现无限分类,不使用数据库,不使用递归.
2006/12/09 PHP
用PHP获取Google AJAX Search API 数据的代码
2010/03/12 PHP
PHP提示Cannot modify header information - headers already sent by解决方法
2014/09/22 PHP
php中10个不同等级压缩优化图片操作示例
2016/11/14 PHP
php中yii框架实例用法
2020/12/22 PHP
JS冒泡事件的快速解决方法
2013/12/16 Javascript
jquery ztree异步搜索(搜叶子)实践
2016/02/25 Javascript
基于javascript实现简单的抽奖系统
2020/04/15 Javascript
深入理解JavaScript中的浮点数
2016/05/18 Javascript
利用原生js和jQuery实现单选框的勾选和取消操作的方法
2016/09/04 Javascript
Angular.js中处理页面闪烁的方法详解
2017/03/09 Javascript
vue2.0获取自定义属性的值
2017/03/28 Javascript
jQuery实现可编辑表格并生成json结果(实例代码)
2017/07/19 jQuery
实现一个 Vue 吸顶锚点组件方法
2019/07/10 Javascript
vue中nextTick用法实例
2019/09/11 Javascript
JavaScript实现指定数量的并发限制的示例代码
2020/03/10 Javascript
Python的pycurl包用法简介
2015/11/13 Python
Python中序列的修改、散列与切片详解
2017/08/27 Python
浅谈pandas用groupby后对层级索引levels的处理方法
2018/11/06 Python
Python编写一个验证码图片数据标注GUI程序附源码
2019/12/09 Python
Python 从attribute到property详解
2020/03/05 Python
CSS3 中filter(滤镜)属性使用详解
2020/04/07 HTML / CSS
HTML5拖拉上传文件的简单实例
2017/01/11 HTML / CSS
文秘专业应届生求职信范文
2013/11/14 职场文书
工作人员思想汇报
2014/01/09 职场文书
文秘人员工作职责
2014/01/31 职场文书
银行职员个人的工作自我评价
2014/02/15 职场文书
暑期研修感言
2014/02/17 职场文书
地球一小时倡议书
2014/04/15 职场文书
物业消防安全责任书
2014/07/23 职场文书
质量在我心中演讲稿
2014/09/02 职场文书
学习党的群众路线教育实践活动心得体会范文
2014/11/03 职场文书
2014年残联工作总结
2014/11/21 职场文书
质量保证书怎么写
2015/02/27 职场文书
餐饮店长岗位职责
2015/04/14 职场文书
人事部:年度述职报告范文
2019/07/12 职场文书