TensorFlow实现简单线性回归
采用波士顿房价数据集的房间数量(RM)进行简单线性回归,目标是预测在最后一列(MEDV)给出的房价。数据下载地址:下载
下载数据之后是.data格式,把拓展名改为.txt然后再导入到excel的csv文件中,可以得到如下的数据集:
或者,可以直接从TensorFlow contrib数据集加载数据。
1. 导入需要的所有软件包
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
2. 归一化数据
在神经网络中,所有的输入都线性增加。为了使训练有效,输入应该被归一化,所以这里定义一个函数来归一化(Z-score)输入数据:
def normalize(X):
"""Normalize the array X"""
mean = np.mean(X) # 求矩阵中所有数的平均值
std = np.std(X) # 求矩阵中所有数的标准差
X = (X - mean) / std # z-score标准化
return X
3. 数据预处理
现在使用TensorFlow contrib数据集加载波士顿房价数据集,并将其分解为X_train和Y_train。可以对数据进行归一化处理:
# Data
boston = tf.contrib.learn.datasets.load_dataset('boston') # 载入数据
X_train, Y_train = boston.data[:, 5], boston.target # 数据提取
X_train = normalize(X_train) # 标准化
n_samples = len(X_train) # 样本数目
4. 声明占位符
为训练数据声明TensorFlow占位符:
# Placeholder for the Training data
X = tf.placeholder(tf.float32, name='X')
Y = tf.placeholder(tf.float32, name='Y')
5. 创建权重和偏置
创建的w和b值均为0:
# Variables for coefficients initialized to 0
b = tf.Variable(0.0)
w = tf.Variable(0.0)
6. 定义模型
# The Linear Regression Model
Y_hat = X * w + b
7. 定义损失函数
采用平方损失:
# Loss function
loss = tf.square(Y - Y_hat, name='loss')
8. 优化器
选择梯度下降优化器来进行loss最小化:
# Gradient Decent with learning rate of 0.01 to minimize loss
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(loss)
9. 初始化
声明初始化操作符和记录所有loss的变量:
# Initializing Variables
init_op = tf.global_variables_initializer()
total = [] # 所有训练次数中平均Loss变化的记录
10. 开始训练
现在开始编写计算图,训练100次:
# Computation Graph
with tf.Session() as sess:
# 初始化变量
sess.run(init_op)
writer = tf.summary.FileWriter('graphs', sess.graph) # 将计算图保存为tensorboard可视化
# 训练100个epoch
for i in range(100):
total_loss = 0
for x, y in zip(X_train, Y_train): # 将训练数据分成单例
_, l = sess.run([optimizer, loss], feed_dict={X: x, Y: y})
total_loss += l
total.append(total_loss / n_samples)
print('Epoch{0}: Loss{1}'.format(i, total_loss / n_samples))
writer.close()
b_value, w_value = sess.run([b, w])
11.结果可视化
Y_pred = X_train * w_value + b_value
print('Done')
# Plot the result
plt.plot(X_train, Y_train, 'bo', label='Real Data')
plt.plot(X_train, Y_pred, 'r', label='Predicted Data')
plt.legend()
plt.show()
plt.plot([i for i in range(100)], total)
plt.title('Loss')
plt.xlabel('Epochs')
plt.ylabel('Total Loss')
plt.show()
结果分析
从下图中可以看到,简单线性回归试图拟合给定数据集的线性线:
在下图中可以看到,随着模型不断学习数据,损失函数不断下降:
下图是简单线性回归的TensorBoard图:
该图有两个名称范围节点:Variable和Variable_1,它们分别是表示偏置和权重的高级节点。以梯度命名的节点也是一个高级节点,展开节点,可以看到它需要7个输入并使用GradientDecentOptimizer计算梯度,对权重和偏置进行更新: