ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

3.5tensorflow线性回归和线性拟合

2021-01-14 13:04:40  阅读:225  来源: 互联网

标签:loss plot dtype reduce raw 3.5 tf 线性 tensorflow


自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取:

https://www.cnblogs.com/bclshuai/p/11380657.html

1.1  tensorflow线性回归

以线性回归为例,以梯度下降法计算线程方程的参数,通过多次学习和迭代计算出参数。如果采用numpy等常规的科学计算法库去实现,需要人工求出函数的偏导数,并且需要根据求导结果更新参数。如果采用tensorflow框架,可以自动求导和更新参数。

1.1.1         变量归一化

归一化定义

由于实际求解往往使用迭代算法,如果目标函数的形状太“扁”,即变量之间的数量级相差太大,迭代算法可能收敛得很慢甚至不收敛。所以对于具有伸缩不变性的模型,最好也进行数据标准化,即归一化让数值在同一个数量级内。

归一化优点

(1)提升模型的收敛速度,变量数量级相差大,成椭圆形梯度下降,走之路线,收敛速度慢,数量级相同,成圆形梯度下降,垂直于圆心迭代,所以收敛速度快。

 

 

 

(2)提高模型的精度,数量级相差太大,波动对结果的影响大,造成精度损失。

归一化方法

线性归一化,线性归一化会把输入数据都转换到[0 1]的范围,公式如下

 

1.1.2         reduce_sum、reduce_mean、reduce_max、reducemin函数介绍

reduce_sum函数是用来求多维tensor的元素之和的方法,reduce是降维的意思,sum是求和的意思。其定义如下:

reduce_sum(input_tensor, axis=None, keepdims=False, name=None)

input_tensor:输入求和的张量

axis:降维的维度,比如2行3列的矩阵,维度是(0,1)0表示行,1表示列。axis等于0时,2行3列变成1行3列;axis=1时,2行3列默认变为1行两列,只有在keepdims ,才是2行1列。

keepdims:是否保持维度,如果为True,axis=1时,2行3列变为2行1列

实例

import tensorflow as tf
import numpy as np
x = tf.constant([[1, 1, 1], [1, 1, 1]])
print(x)
y1=tf.reduce_max(x);
print(y1)#不指定axis时,等于所有元素相加1+1+1+1+1+1+1=6
y2=tf.reduce_max(x,0)
print(y2)#指定按行降维,变成一行3列,每列元素相加[2,2,2]
y3=tf.reduce_max(x,1)
print(y3)#指定按列降维,每行元素相加,因为keepdims默认为false,输出1行2列[3,3]
y4=tf.reduce_max(x,1,True)
print(y4)#指定按列降维,每行元素相加,同时保持维度,输出2行1列[[3],[3]]

 

 

输出

tf.Tensor(

[[1 1 1]

 [1 1 1]], shape=(2, 3), dtype=int32)

tf.Tensor(6, shape=(), dtype=int32)

tf.Tensor([2 2 2], shape=(3,), dtype=int32)

tf.Tensor([3 3], shape=(2,), dtype=int32)

tf.Tensor(

[[3]

 [3]], shape=(2, 1), dtype=int32)

 

同理reduce_mean是求平均值,参数含义相同

reduce_mean(input_tensor, axis=None, keepdims=False, name=None)

reduce_max求最大值,参数含义相同

reduce_max(input_tensor, axis=None, keepdims=False, name=None):

reduce_min求最小值,参数含义相同

1.1.3         numpy和tensorflow线程回归对比

线性回归是给出线程方程y=ax+b,给出损失函数误差平方和

 

 

然后将损失函数对参数a,b求导数,得到偏导数,偏导数乘以学习率,对参数a,b进行迭代计算。

实例代码

使用numpy需要手动计算偏导数,并更新参数,对于一些复杂的函数,很难求出导数,这时就要使用tensorflow 来自动求导数。

某城市的房价和年份的数据如下,求出线性参数y=ax+b

年份x

2013

2014

2015

2016

2017

价格y

12000

14000

15000

16500

17500

因为年份和价格数据量级不同,所以需要进行归一化,将数据范围控制在0,1之间。通过减去最小值再除以区间值的方式得到归一化之后的数据,再进行线性回归。

(1)   使用numpy手动求导线性回归

实例代码如下

import numpy as np
import matplotlib.pyplot as plot
x_raw=np.array([2013,2014,2015,2016,2017],dtype=np.float)
y_raw=np.array([12000,14000,15000,16500,17500],dtype=np.float)
#归一化
x=(x_raw-x_raw.min())/(x_raw.max()-x_raw.min())
y=(y_raw-y_raw.min())/(y_raw.max()-y_raw.min())
print(x)#[0.   0.25 0.5  0.75 1.  ]
print(y)#[0.         0.36363636 0.54545455 0.81818182 1.        ]
a,b=0.0,0.0#初始值
num=10000#迭代次数
learnrate=0.001#学习率
for e in range(num):#循环迭代
    y_predit=a*x+b
    grad_a,grad_b=(y_predit-y).dot(x),2*(y_predit-y).sum()
    a,b=a-learnrate*grad_a,b-learnrate*grad_b
print(a,b)#0.9784232246514815 0.05634210319697519
ytest=a*x+b
print(ytest)#[0.0563421  0.30094791 0.54555372 0.79015952 1.03476533]
plot.scatter(x,y,c='r')
plot.plot(x,ytest,c='b')
plot.show()

 

输出结果图像如下

 

 

 

(2)   使用tensorflow自动求导线性回归

实例代码如下

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plot
x_raw=np.array([2013,2014,2015,2016,2017],dtype=np.float)
y_raw=np.array([12000,14000,15000,16500,17500],dtype=np.float)
#归一化
x=(x_raw-x_raw.min())/(x_raw.max()-x_raw.min())
y=(y_raw-y_raw.min())/(y_raw.max()-y_raw.min())
#转化为tensorflow的张量
x=tf.constant(x,dtype=tf.float32)#指定float32,否则会变成float64报错
y=tf.constant(y,dtype=tf.float32)
print(x)#tf.Tensor([0.   0.25 0.5  0.75 1.  ], shape=(5,), dtype=float32)
print(y)#tf.Tensor([0.  0.36363637 0.54545456 0.8181818  1.], shape=(5,), dtype=float32)
#初始化变量
a,b=tf.Variable(initial_value=0.),tf.Variable(initial_value=0.)
#组成变量数组
variables=[a, b]
#循环次数
num=10000
#迭代算法
optimizer=tf.keras.optimizers.SGD(learning_rate=1e-3)
#循环
for e in range(num):
    with tf.GradientTape() as tape:
        #预测函数
        y_pred=a*x+b
        #损失函数
        loss=tf.reduce_sum(tf.square(y_pred-y))
        #对变量求导
    grads=tape.gradient(loss, variables)
        #调整参数
    optimizer.apply_gradients(grads_and_vars=zip(grads,variables))
print(a,b)#<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.9817748> <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.0545703>
ytest=a*x+b
print(ytest)#tf.Tensor([0.0545703 0.300014  0.5454577 0.7909014 1.0363451], shape=(5,), dtype=float32)
plot.scatter(x,y,c='r')
plot.plot(x,ytest,c='b')
plot.show()

 

输出的图像结果如下:

 

 

 

通过对比可以知道,输出的结果完全一致。

(3)   使用tensorflow自动求导线性拟合

构造线性的离散点y=0.3x+0.7+np.random.normal(0.0,0.1),然后用线性回归去拟合这些离散的点求得参数看是否接近0.3和0.7。

代码如下

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plot
#定义数据数量
num=100
xdata=[]
ydata=[]
#生成数据
xdata=np.linspace(-1.,1.,100)#线性等分生成100个数据
#生成线性数据a=0.3,b=0.7,加上随机噪声
ydata=[0.3*v+0.7+np.random.normal(0.0,0.1) for v in xdata]
#定义变量
a=tf.Variable(initial_value=0.,dtype=tf.float32)
b=tf.Variable(initial_value=0.,dtype=tf.float32)
variables=[a, b]
#声明梯度下降优化算法
optimizer = tf.keras.optimizers.SGD(learning_rate=2e-3)
#声明循环迭代次数
num=1000
#进行迭代,更新参数
for s in range(num):
    with tf.GradientTape() as tape:
        #预测值
        y_pred=a*xdata+b
        #损失函数
        loss=tf.reduce_sum(tf.square(y_pred-ydata))
        #计算梯度
        grads=tape.gradient(loss,variables)
        #更新参数
        optimizer.apply_gradients(grads_and_vars=zip(grads,variables))
        #每隔100次输出一次结果
        if s%100==0:
            print("step: %i, loss: %f, a: %f, b: %f" % (s, loss, a.numpy(), b.numpy()))

print(a.numpy(),b.numpy())
plot.scatter(xdata,ydata,c='r')
plot.plot(xdata,a*xdata+b,c='b')
plot.show()

 

输出结果如下,每隔100次迭代输出一次一次结果,大家可以看到经过100迭代之后,参数就已经收敛,不在变化。输出结果也非常接近实际值。

step: 0, loss: 50.548035, a: 0.040768, b: 0.273359

step: 100, loss: 0.790290, a: 0.299707, b: 0.683397

step: 200, loss: 0.790290, a: 0.299707, b: 0.683397

step: 300, loss: 0.790290, a: 0.299707, b: 0.683397

step: 400, loss: 0.790290, a: 0.299707, b: 0.683397

step: 500, loss: 0.790290, a: 0.299707, b: 0.683397

step: 600, loss: 0.790290, a: 0.299707, b: 0.683397

step: 700, loss: 0.790290, a: 0.299707, b: 0.683397

step: 800, loss: 0.790290, a: 0.299707, b: 0.683397

step: 900, loss: 0.790290, a: 0.299707, b: 0.683397

0.29970676 0.68339676

 

用matlabplot画出图片如下所示

 

 

 

标签:loss,plot,dtype,reduce,raw,3.5,tf,线性,tensorflow
来源: https://www.cnblogs.com/bclshuai/p/14276598.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有