单变量线性回归
概述
单变量线性回归问题,因为其变量单一,因此,模型的搭建十分简单,拿来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]