tensorflow入门学习,对二次函数的非线性回归,并使用matplotlib库使训练结果动态可视化(11)
发表于: 2018-07-01 18:17:36 | 已被阅读: 100 | 分类于: tensorflow
本节再介绍一个实例,对二次函数进行非线性回归
,并且使用 python 的matplotlib
库使训练结果动起来。

生成二次函数模拟数据
首先,创建一个等差数列,作为二次函数的自变量,然后按照
#encoding=utf8
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
# 构建数据
xdata = np.linspace(-1,1,200, dtype=np.float32)[:, np.newaxis] # -1 到 1 范围,共 200 个数据,类型为 float32
ydata = np.square(xdata) - 0.5
xdata[:, np.newaxis],是将数据转成矩阵形式。
>> x = np.arange(3)
array([0, 1, 2])
>> x.shape
(3,)
>> x[:, np.newaxis]
array([[0],
[1],
[2]])
>> x[:, np.newaxis].shape
(3, 1)
为了让数据看起来更像是真实数据,加入随机噪声:
noise = np.random.normal(0, 0.05, xdata.shape).astype(np.float32)
ydata = ydata + noise
利用 matplotlib 库将生成的数据绘制成散点图(matplotlib 库的使用,可参考:
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.scatter(xdata, ydata)
plt.show()
执行,得到:

构建网络模型
输入 x 和实际值 y_ 使用
# 输入和实际值
x = tf.placeholder(tf.float32)
y_ = tf.placeholder(tf.float32)
隐藏层我们使用 10 个神经元,那么隐藏层的权重
# 隐藏层
w1 = tf.Variable(tf.random_normal([1, 10]))
b1 = tf.Variable(tf.zeros([1, 10]) + 0.1)
l1 = tf.nn.relu(tf.matmul(x, w1) + b1)
每次训练,我们只需输出 1 个值,所以输出层权重
# 输出层
w2 = tf.Variable(tf.random_normal([10, 1]))
b2 = tf.Variable(tf.zeros([1, 1]) + 0.1)
y = tf.matmul(l1, w2) + b2
接下来,定义好损失函数和训练方法,就可以训练网络了。
# 定义损失函数和训练方法
loss = tf.reduce_mean(tf.reduce_sum(tf.square(y - y_),
reduction_indices=[1]))
train = tf.train.GradientDescentOptimizer(0.2).minimize(loss)

训练网络,并且使结果可视化
初始化后,就可以在 session 里训练网络了。这里共训练 1001 次,每 50 次打印一次损失,并且描点作图一次,因此我们可以动态的看到训练结果。
# 初始化
init = tf.global_variables_initializer()
# 训练
with tf.Session() as sess:
sess.run(init)
for i in range(1001):
sess.run(train, feed_dict={x:xdata, y_:ydata})
if i%50 == 0:
print sess.run(loss, feed_dict={x:xdata, y_:ydata})
try:
ax.lines.remove(lines[0])
except Exception:
pass
lines = ax.plot(xdata, sess.run(y, feed_dict={x:xdata}), 'r-', lw=2)
plt.pause(0.1)
最终,全部代码如下:
#encoding=utf8
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
# 构建数据
xdata = np.linspace(-1,1,200, dtype=np.float32)[:, np.newaxis]
noise = np.random.normal(0, 0.05, xdata.shape).astype(np.float32)
ydata = np.square(xdata) - 0.5 + noise
# 绘制构建的数据
fig = plt.figure()
plt.ylim(-1,1) # 限制 y 轴的绘制区域
ax = fig.add_subplot(1,1,1)
ax.scatter(xdata, ydata)
plt.ion()#本次运行请注释,全局运行不要注释
plt.show()
# 构建网络
x = tf.placeholder(tf.float32)
y_ = tf.placeholder(tf.float32)
# 隐藏层
w1 = tf.Variable(tf.random_normal([1, 10]))
b1 = tf.Variable(tf.zeros([1, 10]) + 0.1)
l1 = tf.nn.relu(tf.matmul(x, w1) + b1)
# 输出层
w2 = tf.Variable(tf.random_normal([10, 1]))
b2 = tf.Variable(tf.zeros([1, 1]) + 0.1)
y = tf.matmul(l1, w2) + b2
# 定义损失函数和训练方法
loss = tf.reduce_mean(tf.reduce_sum(tf.square(y - y_),
reduction_indices=[1]))
train = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
# 初始化
init = tf.global_variables_initializer()
# 训练
with tf.Session() as sess:
sess.run(init)
for i in range(1001):
sess.run(train, feed_dict={x:xdata, y_:ydata})
if i%50 == 0:
print sess.run(loss, feed_dict={x:xdata, y_:ydata})
try:
ax.lines.remove(lines[0])
except Exception:
pass
lines = ax.plot(xdata, sess.run(y, feed_dict={x:xdata}), 'r-', lw=2)
plt.pause(0.1)
运行之,可在终端里看到损失不断减小。
$ python t.py
0.00894436
0.0060519846
0.004842156
0.0042339526
0.0038231497
...
而且,训练的曲线也在不断往参考数据靠近,如下图,整个训练结果的变化,清晰的显示了出来。
