版权说明:浙江财经大学专业实践深度学习tensorflow——齐峰##
波士顿房价预测 目录 Tensorflow实现单变量线性回归** 详见示例:单变量线性回归.ipynb **
Tensorflow实现多变量线性回归** 在上一节中,我们使用Tensorflow构建了第一个完整的模型——一元线性回归。在这一节中,我们将构建一个多变量线性模型来实现多维数据的回归。此外,我们还将介绍如何利用Tensorflow自带的可视化工具TensorBoard分析训练过程。 **
载入数据
** 导入相关库 **
%matplotlib notebook
import matplotlib.pyplot as plt
import tensorflow as tf
import tensorflow.contrib.learn as skflow
from sklearn.utils import shuffle
import numpy as np
import pandas as pd
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
print(tf.__version__)
print(tf.test.is_gpu_available())
1.12.0
False
** 数据集简介 **
本数据集包含与波士顿房价相关的多个因素:
** CRIM **:城镇人均犯罪率
** ZN **:住宅用地超过25000 sq.ft. 的比例
** INDUS ** : 城镇非零售商用土地的比例
** CHAS **:Charles河空变量(如果边界是河流,则为1;否则,为0)
** NOX **:一氧化氮浓度
** RM **:住宅平均房间数
**AGE **:1940年之前建成的自用房屋比例
** DIS **:到波士顿5个中心区域的加权距离
** RAD **:辐射性公路的靠近指数
** TAX **:每1万美元的全值财产税率
** PTRATIO **:城镇师生比例
** LSTAT **:人口中地位低下者的比例
** MEDV **:自住房的平均房价,单位:千美元
** 数据集以CSV格式存储,可通过Pandas库读取并进行格式转换 **
** Pandas库 **可以帮助我们快速读取常规大小的数据文件
能够读取CVS文件, 文本文件、MS Excel、SQL数据库以及用于科学用途的HDF5格式文件
自动转换为Numpy的多维阵列
** 通过Pandas导入数据 **
df = pd.read_csv("data/boston.csv", header=0)
print (df.describe())
CRIM ZN INDUS CHAS NOX RM \
count 506.000000 506.000000 506.000000 506.000000 506.000000 506.000000
mean 3.613524 11.363636 11.136779 0.069170 0.554695 6.284634
std 8.601545 23.322453 6.860353 0.253994 0.115878 0.702617
min 0.006320 0.000000 0.460000 0.000000 0.385000 3.561000
25% 0.082045 0.000000 5.190000 0.000000 0.449000 5.885500
50% 0.256510 0.000000 9.690000 0.000000 0.538000 6.208500
75% 3.677082 12.500000 18.100000 0.000000 0.624000 6.623500
max 88.976200 100.000000 27.740000 1.000000 0.871000 8.780000
AGE DIS RAD TAX PTRATIO LSTAT \
count 506.000000 506.000000 506.000000 506.000000 506.000000 506.000000
mean 68.574901 3.795043 9.549407 408.237154 18.455534 12.653063
std 28.148861 2.105710 8.707259 168.537116 2.164946 7.141062
min 2.900000 1.129600 1.000000 187.000000 12.600000 1.730000
25% 45.025000 2.100175 4.000000 279.000000 17.400000 6.950000
50% 77.500000 3.207450 5.000000 330.000000 19.050000 11.360000
75% 94.075000 5.188425 24.000000 666.000000 20.200000 16.955000
max 100.000000 12.126500 24.000000 711.000000 22.000000 37.970000
MEDV
count 506.000000
mean 22.532806
std 9.197104
min 5.000000
25% 17.025000
50% 21.200000
75% 25.000000
max 50.000000
** 载入本示例所需数据 **
df = np.array(df)
for i in range(12):
df[:,i] = (df[:,i]-df[:,i].min())/(df[:,i].max()-df[:,i].min())
#x_data = df[['CRIM', 'DIS', 'LSTAT']].values.astype(float) #选取其中3个比较重要的影响因素
x_data = df[:,:12]
#y_data = df['MEDV'].values.astype(float) #获取y
y_data = df[:,12]
构建模型
** 定义\(x\)和\(y\)的占位符 **
x = tf.placeholder(tf.float32, [None,12], name = "x") # 3个影响因素
y = tf.placeholder(tf.float32, [None,1], name = "y")
** 创建变量 **
with tf.name_scope("Model"):
w = tf.Variable(tf.random_normal([12,1], stddev=0.01), name="w0")
b = tf.Variable(1., name="b0")
def model(x, w, b):
return tf.matmul(x, w) + b
pred= model(x, w, b)
可以看到** b0 和 w0 都在命名空间 Model **下
** 补充介绍——命名空间name_scope **
Tensorflow中常有数以千计节点,在可视化过程中很难一下子全部展示出来,因此可用name_scope为变量划分范围,在可视化中,这表示在计算图中的一个层级。
- name_scope** 不会影响 **用get_variable()创建的变量的名字
- name_scope** 会影响 **用Variable()创建的变量以及op_name
下面举例说明:
训练模型
** 设置训练参数 **
train_epochs = 500 # 迭代次数
learning_rate = 0.01 #学习率
** 定义均方差损失函数 **
with tf.name_scope("LossFunction"):
loss_function = tf.reduce_mean(tf.pow(y-pred, 2)) #均方误差MSE
同样,我们可以通过TensorBoard查看命名空间LossFunction下的操作(op),包括:mean, pow和sub(相减),与我们定义的loss_function = tf.reduce_mean(tf.pow(y-pred, 2))相一致。
** 选择优化器 **
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(loss_function)
** 声明会话 **
sess = tf.Session()
init = tf.global_variables_initializer()
** 生成图协议文件 **
tf.train.write_graph(sess.graph, 'log2/boston','graph.pbtxt')
'log2/boston\\graph.pbtxt'
loss_op = tf.summary.scalar("loss", loss_function)
merged = tf.summary.merge_all()
** 补充介绍——TensorBoard
TensorBoard是Tensorflow自带的可视化工具。
目前支持7种可视化对象: SCALARS, IMAGES,AUDIO,GRAPHS,DISTRIBUTIONS,HISTOGRAMS,EMBEDDINGS **。
在训练过程中,通过记录下结构化的数据,然后运行一个本地服务器,监听6006端口,即可实现可视化。
先指定需要记录的数据,然后通过以下指令则可打开TensorBoard面板:
** tensorboard --logdir=/your/log/path **
输入上述指令后,会显示:
此时,我们就可以在浏览器中打开 ** http://192.168.2.102:6006 ,查看面板各项功能。
注意:具体IP地址会因机器不同而不同,查看命令窗口中“You can navigate to”后面所显示的IP即可。
例如,本示例中通过 tf.summary.scalar **记录loss_function的值,因此可在TensorBoard的SCALARS面板中查看到如下可视化结果:
** 启动会话 **
sess.run(init)
** 创建摘要的文件写入符(FileWriter) **
writer = tf.summary.FileWriter('log/boston', sess.graph)
tf.summary.FileWriter('/path/to/logs', sess.graph) 中所指定的路径‘/path/to/logs’,是运行tensorboard命令时参数logdir的值
** 迭代训练 **
loss_list = []
for epoch in range (train_epochs):
loss_sum=0.0
for xs, ys in zip(x_data, y_data):
z1 = xs.reshape(1,12)
z2 = ys.reshape(1,1)
_,loss = sess.run([optimizer,loss_function], feed_dict={x: z1, y: z2})
summary_str = sess.run(loss_op, feed_dict={x: z1, y: z2})
#lossv+=sess.run(loss_function, feed_dict={x: z1, y: z2})/506.00
loss_sum = loss_sum + loss
# loss_list.append(loss)
writer.add_summary(summary_str, epoch)
x_data, y_data = shuffle(x_data, y_data)
print (loss_sum)
b0temp=b.eval(session=sess)
w0temp=w.eval(session=sess)
loss_average = loss_sum/len(y_data)
loss_list.append(loss_average)
print("epoch=", epoch+1,"loss=",loss_average,"b=", b0temp,"w=", w0temp )
149248.76506266068
epoch= 1 loss= 294.95803372067326 b= 3.94445 w= [[0.9625533]
[1.7546748]
[2.3211656]
[1.1788806]
[2.3749657]
[2.9518034]
[2.4899516]
[2.6423771]
[2.4740942]
[2.3962796]
[2.405994 ]
[1.7411354]]
79301.29809246541
epoch= 2 loss= 156.72193298906208 b= 5.731459 w= [[-0.10316267]
[ 3.2055295 ]
[ 2.7016158 ]
[ 1.8831778 ]
[ 2.8047607 ]
[ 4.819791 ]
[ 3.5140483 ]
[ 4.73509 ]
[ 2.2039707 ]
[ 2.4170697 ]
[ 3.5754337 ]
[ 1.6520783 ]]
59155.64258796818
epoch= 3 loss= 116.90838456120193 b= 6.8220057 w= [[-1.4175 ]
[ 4.436672 ]
[ 2.2779799]
[ 2.4264417]
[ 2.4682086]
[ 6.168085 ]
[ 3.792487 ]
[ 6.3616514]
[ 1.288084 ]
[ 1.6558697]
[ 3.8651628]
[ 0.6330488]]
47703.83335633681
....................
print("y=",w0temp[0], "x1+",w0temp[1], "x2+",w0temp[2], "x3+", [b0temp])
print("y=",w0temp[0], "CRIM+", w0temp[1], 'DIS+', w0temp[2], "LSTAT+", [b0temp])
y= [-10.775753] x1+ [4.629923] x2+ [0.36049515] x3+ [30.468655]
y= [-10.775753] CRIM+ [4.629923] DIS+ [0.36049515] LSTAT+ [30.468655]
plt.plot(loss_list)
<IPython.core.display.Javascript object>
[<matplotlib.lines.Line2D at 0x1567f8cda58>]