代码示例
先生成10个样本数据[1]
# 程序 11-1
# 一元线性回归
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
n = 10
# 产生n维标准正太分布随机数
x_data = np.random.randn(n) #[2]
# 我们假设模型为 y = 0.3x + 0.15,这里还要为其添加均值为0.0、标准差为0.05的服从正太(高斯)分布、维度为n的噪声
y_data = x_data * 0.3 + 0.15 + np.random.normal(0.0, 0.05, n)
# 画出原数据散点图
plt.plot(x_data, y_data, 'ro', label='Original data')
plt.legend()
plt.show()
线性回归拟合直线
weight = tf.Variable(0.5, dtype=tf.float64)
bias = tf.Variable(0.0, dtype=tf.float64)
y_model = weight * x_data + bias
loss = tf.pow((y_model - y_data), 2) # 求数组(y_model - y_data)的2次幂
train_op = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
sess = tf.Session()
init = tf.initialize_all_variables()
sess.run(init)
for _ in range(2000):
sess.run(train_op)
print(weight.eval(sess), bias.eval(sess))
plt.plot(x_data, y_data, 'ro', label='Original data')
plt.plot(x_data, sess.run(weight) * x_data + sess.run(bias), label='Fitted line')
plt.legend()
plt.show()
改进1:改批量输入为使用占位符逐个输入
对于训练模型来说,数据量的多少是训练模型能否成功的一个最为关键性的问题[1]。上述程序中只有10个数据,但是如果数据量增大,达到100个的时候会产生什么问题呢?
实验结果如下:
上面几幅图中的拟合直线都有可能出现(这主要跟数据集有关),由上图可知,生成的模型严重偏离正确的数据曲线。权重值w和偏置bias并不能收敛到一个固定的常数。
这时候需要转化数据的输入方式,将批量输入改为逐个输入:
for (x, y) in zip(x_data, y_data):
sess.run(train_op, feed_dict={x_:x, y_:y})
相应的,使用占位符作为数据输入的占位点:
x_ = tf.placeholder(tf.float64)
y_ = tf.placeholder(tf.float64)
完整示例代码如下:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
n = 100
# 产生n维标准正太分布随机数
x_data = np.random.randn(n) #[2]
# 我们假设模型为 y = 0.3x + 0.15,这里还要为其添加均值为0.0、标准差为0.05的服从正太(高斯)分布、维度为n的噪声
y_data = x_data * 0.3 + 0.15 + np.random.normal(0.0, 0.05, n)
# 画出原数据散点图
plt.plot(x_data, y_data, 'ro', label='Original data')
plt.legend()
plt.show()
weight = tf.Variable(0.5, dtype=tf.float64)
bias = tf.Variable(0.0, dtype=tf.float64)
x_ = tf.placeholder(tf.float64)
y_ = tf.placeholder(tf.float64)
y_model = weight * x_ + bias
loss = tf.pow((y_model - y_), 2) # 求(y_model - y)的2次幂
train_op = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
sess = tf.Session()
init = tf.initialize_all_variables()
sess.run(init)
for _ in range(10):
for (x, y) in zip(x_data, y_data):
sess.run(train_op, feed_dict={x_:x, y_:y})
print(weight.eval(sess), bias.eval(sess))
plt.subplot(221)
plt.plot(x_data, y_data, 'ro', label='Original data')
plt.subplot(222)
plt.plot(x_data, y_data, 'ro', label='Original data')
plt.plot(x_data, sess.run(weight) * x_data + sess.run(bias), label='Fitted line')
plt.legend()
plt.show()
实验结果如下图所示:
改进2:改传统的加减乘除运算为tensorflow特有的函数处理
主要改进的地方有:
y_model = tf.add(tf.multiply(x_, weight), bias)
loss = tf.reduce_mean(tf.pow((y_model - y_), 2)) # 求(y_model - y_)的2次幂,然后再求其均值
这里将损失函数改为 (y_model−y)2 ( y _ m o d e l − y ) 2 的均值是因为要计算出一个能够代表整体损失的loss_val值,以便于用该loss_val与threshold作比较。
完整代码如下:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
threshold = 1.0e-2
n = 100
# 产生n维标准正太分布随机数
x_data = np.random.randn(n) #[2]
# 我们假设模型为 y = 0.3x + 0.15,这里还要为其添加均值为0.0、标准差为0.05的服从正太(高斯)分布、维度为n的噪声
y_data = x_data * 0.3 + 0.15 + np.random.normal(0.0, 0.05, n)
# 画出原数据散点图
plt.plot(x_data, y_data, 'ro', label='Original data')
plt.legend()
plt.show()
weight = tf.Variable(1.0, dtype=tf.float64)
bias = tf.Variable(1.0, dtype=tf.float64)
x_ = tf.placeholder(tf.float64)
y_ = tf.placeholder(tf.float64)
y_model = tf.add(tf.multiply(x_, weight), bias)
loss = tf.reduce_mean(tf.pow((y_model - y_), 2)) # 求(y_model - y_)的2次幂,然后再求其均值
train_op = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
sess = tf.Session()
init = tf.initialize_all_variables()
sess.run(init)
flag = 1
loss_buf = []
while(flag):
for (x,y) in zip(x_data,y_data):
sess.run(train_op,feed_dict={x_:x,y_:y})
#print(weight.eval(sess), bias.eval(sess))
loss_val = sess.run(loss, feed_dict={x_: x_data, y_: y_data})
print(loss_val)
loss_buf.append(loss_val) # 用于画出损失曲线
if loss_val <= threshold:
flag = 0
loss_ndarray = np.array(loss_buf)
loss_size = np.arange(len(loss_ndarray))
plt.subplot(221)
plt.plot(x_data, y_data, 'ro', label='Original data')
plt.subplot(222)
plt.plot(x_data, y_data, 'ro', label='Original data')
plt.plot(x_data, sess.run(weight) * x_data + sess.run(bias), label='Fitted line')
plt.legend()
plt.subplot(212)
plt.plot(loss_size, loss_ndarray, 'b+', label='loss')
plt.legend()
plt.show()
实验结果如下:
参考文献
[1] 王晓华. TensorFlow深度学习应用实践
[2] numpy产生随机数 https://blog.csdn.net/jinxiaonian11/article/details/53143141