4.8 线性回归问题TensorFlow实战

4.8.1 核心步骤

使用TensorFlow进行算法设计与训练有以下四个核心步骤:

(1)准备数据

(2)构建模型

(3)训练模型

(4)进行预测

上述步骤是我们使用TensorFlow进行算法设计和训练的核心步骤,贯穿于后面介绍的具体实战中,本章用一个简单的例子来讲解这几个步骤。

4.8.2 准备数据

本例通过生成人工数据集。随机生成一个近似采样随机分布,使得w=2.0, b=1, 并加入一个噪声,噪声的最大振幅为0.4。

下面我们来展示具体代码,假设我们要学习的函数为线性函数 𝑦=2𝑥+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, 2 * x_data + 1.0, color = 'red',linewidth=3) 

上面的代码产生了随机的-1到1的100个点,我们使用matplotlib库将这些点和要学习得到的线性函数可视化出来,得到图4-16。

4.8.3 构建模型

首先我们定义训练数据的占位符,这是后面数据输入的入口,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="w0")

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

# 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)

4.8.4 训练模型

模型训练阶段,设置迭代轮次,每次通过将样本逐个输入模型,进行梯度下降优化操作,每轮迭代后,绘制出模型曲线。

# 开始训练,轮数为 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}) 
                
    b0temp=b.eval(session=sess)
    w0temp=w.eval(session=sess)
    plt.plot (x_data, w0temp * x_data + b0temp  )# 画图

从上图可以看出,本案例所拟合的模型较简单,训练3次之后已经接近收敛 对于复杂模型,需要更多次训练才能收敛。

4.8.5 进行预测

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)

Last updated