TensorFlow实战——单变量线性回归


单变量线性回归

概述

单变量线性回归问题,因为其变量单一,因此,模型的搭建十分简单,拿来TensorFlow入门实战是最简单不过的了。

因为人工收集数据,再输入其中,比较麻烦,所以之间用随机数的方法生成人工数据集,来达到简化操作的目的。

生成人工数据集

假设需要学习的函数为线性函数:y=2x+1

导入库:

# 在Jupyter中,使用 matplotlib 显示图像需要设置为 inline 模式,否则不会显示图像
%matplotlib inline

import matplotlib.pyplot as plt # 载入matplotlib
import numpy as np # 载入numpy
import tensorflow as tf # 载入TensorFlow

# 设置随机数种子
np.random.seed(5)

生成随机数:

#直接采用np生成等差数列的方法,生成100个点,每个点取值在-1~1之间
x_data=np.linspace(-1,1,100)

#y=2x+1+噪声,其中,噪声的维度与x_data一致
y_data=2*x_data+1.0+np.random.randn(*x_data.shape)*0.4

画出生成的散点和目标线性函数:

# 画出随机生成数据的散点图

plt.scatter(x_data,y_data)

# 画出想要通过学习得到的目标线性函数y=2x+1

plt.plot(x_data,1.0+2*x_data,color="red",linewidth=3)

输出展示:

.png)

构建线性模型

定义x和y的占位符:

# 定义训练数据的占位符,x是特征值,y是标签值

x=tf.placeholder("float",name="x")
y=tf.placeholder("float",name="y")

构建回归模型:

def model(x,w,b):
    return tf.multiply(x,w)+b

创建变量

  • TensorFlow变量的声明函数是tf.Variable
  • tf.Variable的作用是保存和更新参数
  • 变量的初始值可以是随机数、常数、或是通过其他变量的初始值计算得到
# 构建线性函数的斜率,变量w
w=tf.Variable(1.0,name="wO")

# 构建线性函数的截距,变量b
b=tf.Variable(0.0,name="bO")

预测值表示:

# pred是预测值,前向计算
pred=model(x,w,b)

训练模型

设置训练参数:

# 迭代次数(训练轮数)
train_epochs=10
# 学习率
learning_rate=0.05
# 控制显示loss值的粒度
display_step=10

定义损失函数

  • 损失函数用于描述预测值与真实值之间的误差,从而指导模型收敛方向
  • 常见损失函数:均方差和交叉熵
# 采用均方差作为损失函数
loss_function=tf.reduce_mean(tf.square(y-pred))

定义优化器、定义最小化损失函数

选择优化器:

# 梯度下降优化器
optimizer=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss_function)

执行训练

声明会话:

sess=tf.Session()

变量初始化:

init=tf.global_variables_initializer()
sess.run(init)

训练开始:

# 开始训练,轮数为 epoch,采用SGD随机梯度下降优化方法

for epoch in range(train_epochs):
    for xs,ys in zip(x_data,y_data):
        _,loss=sess.run([optimizer,loss_function],feed_dict={x: xs,y: ys})
    bOtemp=b.eval(session=sess)
    wOtemp=w.eval(session=sess)
    plt.plot(x_data,wOtemp*x_data+bOtemp)# 画图

输出展示:

.png)

训练结果的可视化

输出w和b:

print("w:",sess.run(w))
print("b:",sess.run(b))

可视化:

plt.scatter(x_data,y_data,label="Original data")
plt.plot(x_data,x_data*sess.run(w)+sess.run(b),label="Fitted line",color="r",linewidth=3)
plt.legend(loc=2)

输出展示:

.png)

利用学习到的模型进行预测

预测方法一:

x_test=3.21

predict=sess.run(pred,feed_dict={x:x_test})
print("预测值:%f"%predict)

target=2*x_test+1.0
print("目标值:%f"%target)

输出展示:

预测值:7.405184

目标值:7.420000

预测方法二:

x_test=3.21
predict=sess.run(w)*x_test+sess.run(b)
print("预测值:%f"%predict)

预测值:7.405184

显示loss的训练

训练方式和前面的训练方式相同,只是在训练的工程中输出loss,具体代码如下:

# 开始训练,轮数为 epoch,采用SGD随机梯度下降优化方法
step=0 # 记录训练步数 
loss_list=[] # 用于保存loss值的列表

for epoch in range(train_epochs):
    for xs,ys in zip(x_data,y_data):
        _,loss=sess.run([optimizer,loss_function],feed_dict={x: xs,y: ys})
        # 显示损失值 loss
        # display_step: 控制报告粒度
        # 例如,如果display_step设为2,则将每训练2个样本输出一次损失值
        # 与超参数不同,修改display_step不会更改模型所学习的规律
        loss_list.append(loss)
        step+=1
        if step%display_step==0:
            print("Train Epoch:","%02d"%(epoch+1),"step:%03d"%(step),"loss=",\
                 "{:.9f}".format(loss))

    bOtemp=b.eval(session=sess)
    wOtemp=w.eval(session=sess)
    plt.plot(x_data,wOtemp*x_data+bOtemp)# 画图

显示loss图(1):

plt.plot(loss_list)

输出展示:

.png)

显示loss图(2):

plt.plot(loss_list,"g2")

输出展示:

.png)

输出异常点:

[x for x in loss_list if x>1]

输出展示:

[1.0133754, 1.2284044, 1.0088208, 1.2116321, 2.3539772, 2.3148305, 1.3175836, 1.0387748, 1.5018207, 1.547514, 1.5513999, 1.5517284, 1.5517554, 1.5517581, 1.5517581, 1.5517581, 1.5517581]


文章作者: Amonologue
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Amonologue !
  目录