Python通过TensorFLow进行线性模型训练原理与实现方法详解


Posted in Python onJanuary 15, 2020

本文实例讲述了Python通过TensorFLow进行线性模型训练原理与实现方法。分享给大家供大家参考,具体如下:

1、相关概念

例如要从一个线性分布的途中抽象出其y=kx+b的分布规律

Python通过TensorFLow进行线性模型训练原理与实现方法详解

特征是输入变量,即简单线性回归中的 x 变量。简单的机器学习项目可能会使用单个特征,而比较复杂的机器学习项目可能会使用数百万个特征。

标签是我们要预测的事物,即简单线性回归中的 y 变量。

样本是指具体的数据实例。有标签样本是指具有{特征,标签}的数据,用于训练模型,总结规律。无标签样本只具有特征的数据x,通过模型预测其y值。

模型是由特征向标签映射的工具,通过机器学习建立。

训练是指模型通过有标签样本来学习,确定其参数的理想值。通俗理解就是在给出一些样本点(x,y),总结其规律确定模型y=kx+b中的两个参数k、b,进而利用这个方程,在只给出x的情况下计算出对应的y值。

损失是一个数值,用于表示对于单个样本而言模型预测的准确程度。预测值与准确值相差越大,损失越大。检查样本并最大限度地减少模型损失的过程叫做经验风险最小化。L1损失是标签预测值与实际值差的绝对值。平方损失是样本预测值与实际值的方差。

模型的训练是一个迭代的过程,首先对模型的参数进行初始参数,得到一个初步模型并计算出特征对应的标签值,然后经过比对计算出损失。之后对模型的参数进行调整,之后再进行预测、计算损失,如此循环直到总损失不再变化或变化很缓慢为止,这时称该模型已经收敛

Python通过TensorFLow进行线性模型训练原理与实现方法详解

类似于对于一个二次函数,通过不断调整x的值,找到其函数的极值点,在该点处函数的变化率为0。那么如何找到极值点,可以采用梯度下降法,即对于函数曲线,朝着其梯度值减少的方向(负梯度)探索便可以最快找到极值点。

前向传播:根据输入计算输出值。反向传播:根据优化器算法计算内部变量的调整幅度,从输出层级开始,并往回计算每个层级,直到抵达输入层。

在梯度下降法中,批量是指单次迭代中用于计算梯度的样本数。随机梯度下降法是指每次随机选择一个样本进行梯度计算。

Python通过TensorFLow进行线性模型训练原理与实现方法详解   Python通过TensorFLow进行线性模型训练原理与实现方法详解

那么朝探索的方向前进多少比较合适?这就涉及到学习速率,用梯度乘以学习速率就得到了下一个点的位置,也叫做步长,如果步长过小,那么可能需要许多次才可到达目标点,如果步长过大,则可能越过目标点。

这种参数需要人为在学习之前设置参数,而不是通过训练得到的参数,这种参数叫做超参数。超参数是编程人员用于对机器学习进行调整的旋钮。

2、算法设计与训练

通过Tensor FLow进行训练的步骤主要有:准备数据、构建模型、训练模型、进行预测

准备数据

使用的数据可以是从生活中的数据经过加工而来,也可以是人工生成的数据集,例如产生y=2x+1附近的随机数点:

#在jupyter中设置图像的显示方式inline,否则图像不显示
%matplotlib inline         
import tensorflow as tf
import numpy as np             #Python的一种开源的数值计算扩展
import matplotlib.pyplot as plt      #Python的一种绘图库
 
np.random.seed(5)             #设置产生伪随机数的类型
x=np.linspace(-1,1,100)          #在-1到1之间产生100个等差数列作为图像的横坐标
#根据y=2*x+1+噪声产生纵坐标
#randn(100)表示从100个样本的标准正态分布中返回一个样本值,0.4为数据抖动幅度
y=2*x+1.0+np.random.randn(100)*0.4
 
plt.scatter(x,y)              #生成散点图
plt.plot(x,2*x+1,color='red',linewidth=3)  #生成直线y=2x+1

在jupyter中绘制出了人工数据的散点图与曲线如下:

Python通过TensorFLow进行线性模型训练原理与实现方法详解

构建模型

#定义函数模型,y=kx+b
def model(x,k,b):
  return tf.multiply(k,x)+b
#定义模型中的参数变量,并为其赋初值
k=tf.Variable(1.0,name='k')
b=tf.Variable(0,name='b')
 
#定义训练数据的占位符,x为特征值,y为标签
x=tf.placeholder(name='x')
y=tf.placeholder(name='y')
#通过模型得出特征值x对应的预测值yp
yp=model(x,k,b)

k、b的初始值并不会影响最终结果的得到,所以可以随意指定一个值。

训练模型

#训练模型,设置训练参数(迭代次数、学习率)
train_epoch=10
rate=0.05
#定义均方差为损失函数
loss=tf.reduce_mean(tf.square(y-yp))
#定义梯度下降优化器,并传入参数学习率和损失函数
optimizer=tf.train.GradientDescentOptimizer(rate).minimize(loss)
 
ss=tf.Session()
init=tf.global_variables_initializer()
ss.run(init)
 
#进行多轮迭代训练,每轮将样本值逐个输入模型,进行梯度下降优化操作得出参数,绘制模型曲线
for _ in range(train_epoch):
  for x1,y1 in zip(sx,sy):
    ss.run([optimizer,loss],feed_dict={x:x1,y:y1})
  tmp_k=k.eval(session=ss)
  tmp_b=b.eval(session=ss)
  plt.plot(sx,tmp_k*sx+tmp_b)
 
ss.close()

迭代次数是人为规定模型要训练的次数。学习率不能太大或太小,根据经验一般设置在0.01到0.1之间

采用均方差为损失函数,square求出y-yp的平方,再通过reduce_mean()求出平均值

再将之前人工生成的数据输入到占位符时,通过zip()函数先将每个sx,sy对应压缩为一个二维数组,然后对100个二维数组进行遍历取出并分别填充到占位符x、y,使会话运行优化器optimizer进行迭代训练。

可以看到运行结果如下,预测的曲线慢慢向分布的散点进行拟合

Python通过TensorFLow进行线性模型训练原理与实现方法详解

进行预测

根据函数模型,y=kx+b,将得到的参数k、b和特质值x带入即可得到标签y的预测值

3、数组操作

Numpy是一个支持大量的维度数组与矩阵运算的python库,通过它可以很便捷地将数据转换为数组并进行操作。np类型的shape属性可以输出数组的维数构成。可以通过np.T对数组进行转置,或者np.rashape(3,2)将数组转换为目标形状。例子如下

scalar=1
scalar_np=np.array(scalar)       #将标量转化为np的数组类型
print(scalar_np.shape)         #只有np才有shape属性,标量对应的shape输出为()
 
#二维以上的有序数组才可以看作矩阵
matrix=[[1,2,3],[4,5,6]]
matrix_np=np.array(matrix)       #将list转化为np矩阵
print('二维数组:',matrix)       #输出为单行数组
print('矩阵形式:\n',matrix_np)     #结果将以多行矩阵的形式输出
print('矩阵转置:\n',matrix_np.T)
print('shape值',matrix_np.shape)

Python通过TensorFLow进行线性模型训练原理与实现方法详解      Python通过TensorFLow进行线性模型训练原理与实现方法详解

矩阵可以直接进行+、-、*运算,但前提是两个矩阵的形状相同。矩阵还可以进行叉乘运算,要求前者的行与后者的列相同,例子如下,运行结果为右上图:

ma=np.array([[1,2,3],[4,5,6]])
mb=np.array([[1,2],[3,4],[5,6]])
print(ma+ma)
print(ma*ma)             #矩阵点乘
print(np.matmul(ma,mb))       #矩阵叉乘

4、多元线性回归模型

多元线性回归模型就是在一元线性函数y=kx+b的基础上,对于不同的特质值x1,x2...xn,将参数k扩展为多个,即y=k1x1+k2x2+...knxn+b,进而求解n+1个参数的过程。其中n个k与x相乘可以看作是两个矩阵相乘。例如下面是一个房价预测的简单模型,有x1~x12共12个影响房价的特质值,对应的标签为房价,通过多元线性模型求解对应的参数k1~k12、b,从而对房价进行预测:

%matplotlib notebook
 
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.utils import shuffle
 
#利用pandas读取数据csv文件
data=pd.read_csv('D:/Temp/data/boston.csv',header=0)
#显示数据摘要描述信息
#print(data.describe())
data=np.array(data.values)                #将data的值转换为np数组
for i in range(12):                    #将所有数据进行归一化处理
  data[:,i]=data[:,i]/(data[:,i].max()-data[:,i].min())
x_data=data[:,:12]                  #截取所有行,0到11列作为特质值x
y_data=data[:,12]                   #截取所有行,第12列作为标签值y
 
x=tf.placeholder(tf.float32,[None,12],name='x')  
#None代表行数不确定,12代表一行特征值有12个子数据
y=tf.placeholder(tf.float32,[None,1],name='y')
 
with tf.name_scope('Model'):             #定义命名空间
  k=tf.Variable(tf.random_normal([12,1],stddev=0.01),name='k')
  b=tf.Variable(1.0,name='b')
  
  def model(x,k,b):
    return tf.matmul(k,x)+b            #数组k,x进行叉乘运算再加上b
  
  yp=model(x,k,b)
 
#定义超参数:训练次数、学习率、损失函数
train_epochs=50
learning_rate=0.01
with tf.name_scope('Loss'):
  loss_function=tf.reduce_mean(tf.square(y-yp))
#使用梯度下降法定义优化器  
optimizer=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss_function)
 
ss=tf.Session()
init=tf.global_variables_initializer()
ss.run(init)
loss_list=[]
 
for _ in range(train_epochs):
  loss_sum=0
  for(xs,ys)in zip(x_data,y_data):
    xs=xs.reshape(1,12)             #调整数据的维数格式以匹配占位符x
    ys=ys.reshape(1,1)
    _,loss=ss.run([optimizer,loss_function],feed_dict={x:xs,y:ys})
    loss_sum+=loss
    
  shuffle(x_data,y_data)              #每轮循环后,打乱数据顺序
  k_tmp=k.eval(session=ss)
  b_tmp=b.eval(session=ss)
  print('k:',k_tmp,',b:',b_tmp)
  
  loss_avg=loss_sum/len(y_data)            #求每轮的损失值
  loss_list.append(loss_avg)  
  
plt.plot(loss_list)

注:

pandas是一个python库,可以提供高性能且易使用的数据结构与数据分析工具,可以从csv、excel、txt、sql等文件中读取数据,并且将数据结构自动转换为Numpy多维数组。

在使用梯度下降法进行多元线性回归模型训练时,如果不同的特征值取值范围相差过大(比如有的特质值取值为0.3~0.7,有点特质值在300~700),就会影响训练结果的得出。因此需要对数据进行归一化处理,即用特征值/(最大值-最小值),也就是通过放缩将数据都统一到0~1之间。

通过tf.name_scope()定义命名空间,定义的变量名只在当前空间内有效,防止命名冲突。

在初始化变量k时,通过tf.random_normal()从正太分布[1,12]之间随机选取一个值,其方差stddev=0.01

由于在定义占位符时x为[None,12]类型的二维数组,所以在填充数据时需要通过xs.reshape(1,12)将数据xs重新排列为一维含有12个元素,二维含有1个子数组的二维数组,同理,y也需要转换。

实现定义loss_list用于保存损失值,在每轮训练后求出损失值的平均值保存到loss_list,最后将其打印成一幅图,可以看到损失值从一开始急速下降,直到最后变化趋于平缓。

运行结果如下,截取部分的参数值以及损失值的曲线:

                       Python通过TensorFLow进行线性模型训练原理与实现方法详解        Python通过TensorFLow进行线性模型训练原理与实现方法详解

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
Python  __getattr__与__setattr__使用方法
Sep 06 Python
Python中用于去除空格的三个函数的使用小结
Apr 07 Python
Python类定义和类继承详解
May 08 Python
使用Django的模版来配合字符串翻译工作
Jul 27 Python
python使用tkinter实现简单计算器
Jan 30 Python
python实现SOM算法
Feb 23 Python
Python实现多态、协议和鸭子类型的代码详解
May 05 Python
Python实现的栈、队列、文件目录遍历操作示例
May 06 Python
python之当你发现QTimer不能用时的解决方法
Jun 21 Python
python实现双色球随机选号
Jan 01 Python
使用tensorboard可视化loss和acc的实例
Jan 21 Python
python实现杨辉三角的几种方法代码实例
Mar 02 Python
详解Python实现进度条的4种方式
Jan 15 #Python
pytorch常见的Tensor类型详解
Jan 15 #Python
pytorch 常用线性函数详解
Jan 15 #Python
python3.8下载及安装步骤详解
Jan 15 #Python
浅谈pytorch、cuda、python的版本对齐问题
Jan 15 #Python
pytorch模型预测结果与ndarray互转方式
Jan 15 #Python
pytorch实现对输入超过三通道的数据进行训练
Jan 15 #Python
You might like
wiki-shan写的php在线加密的解密程序
2008/09/07 PHP
针对PHP开发安全问题的相关总结
2019/03/22 PHP
Yii框架分页技术实例分析
2019/08/30 PHP
修改好的jquery滚动字幕效果实现代码
2011/06/22 Javascript
单击按钮显示隐藏子菜单经典案例
2013/01/04 Javascript
Js实现滚动变色的文字效果
2014/06/16 Javascript
有效提高JavaScript执行效率的几点知识
2015/01/31 Javascript
js实现滑动触屏事件监听的方法
2015/05/05 Javascript
JS基于ocanvas插件实现的简单画板效果代码(附demo源码下载)
2016/04/05 Javascript
第七章之菜单按钮图标组件
2016/04/25 Javascript
JS 对象(Object)和字符串(String)互转方法
2016/05/20 Javascript
javascript中的 object 和 function小结
2016/08/14 Javascript
js制作可以延时消失的菜单
2017/01/13 Javascript
详解用vue.js和laravel实现微信授权登陆
2017/06/23 Javascript
微信小程序使用checkbox显示多项选择框功能【附源码下载】
2017/12/11 Javascript
在Vue项目中使用d3.js的实例代码
2018/05/01 Javascript
Vue 实现列表动态添加和删除的两种方法小结
2018/09/07 Javascript
微信小程序--获取用户地理位置名称(无须用户授权)的方法
2019/04/29 Javascript
jQuery实现简单轮播图效果
2020/12/27 jQuery
vue实现桌面向网页拖动文件的示例代码(可显示图片/音频/视频)
2021/03/01 Vue.js
[59:07]海涛为你详解DOTA2新版本“贤哲秘契”
2014/11/22 DOTA
python网页请求urllib2模块简单封装代码
2014/02/07 Python
Python之父谈Python的未来形式
2016/07/01 Python
Python使用time模块实现指定时间触发器示例
2017/05/18 Python
python对DICOM图像的读取方法详解
2017/07/17 Python
Python实现PS滤镜Fish lens图像扭曲效果示例
2018/01/29 Python
Python实现的读取电脑硬件信息功能示例
2018/05/30 Python
用Python实现二叉树、二叉树非递归遍历及绘制的例子
2019/08/09 Python
Docker部署Python爬虫项目的方法步骤
2020/01/19 Python
Evisu官方网站:日本牛仔品牌,时尚街头设计风格
2016/12/30 全球购物
科颜氏美国官网:Kiehl’s美国
2017/01/31 全球购物
台湾最大银发乐活百货:乐龄网
2018/05/21 全球购物
美国儿童玩具、装扮和玩偶商店:Magic Cabin
2018/09/02 全球购物
澳大利亚拥有最好的家具和家居用品在线目的地:Nestz
2019/02/23 全球购物
c语言常见笔试题总结
2016/09/05 面试题
应届毕业生求职信范例分享
2013/12/17 职场文书