版权说明:浙江财经大学专业实践深度学习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]

构建模型

定义xy的占位符

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>]