TF中的多元线性回归———波士顿房价问题

多元性线性回归

与之前的一元线性回归相比:都是线性模型,但是输入的特征维度是多维的,所以应建立多维的线性映射关系来实现对于数据的预测。本文将以波士顿房价为例进行多维线性模型的建立、训练以及预测。

数据说明

  1. 共506个样本,每个样本共12个特征;
  2. 数据以csv的格式进行存储,在csv中表现为507行13列;第一行为列名,前12列表示特征,最后一列表示标签值。

读取数据:

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import sklearn.utils import shuffle

df = pd.read_csv("Boston.csv")
print(df.describe())
print(df)

上述代码实现了对于csv数据的载入。主要是利用了pandas这一模块,pandas是基于python的开源第三方库,可用于载入包括csv在内的多种形式的数据,并且在载入csv数据时可以按列索引;利用上述的代码的倒数第二行,可以得到csv文件中每列参数的摘要,包括最值、均值等;利用最后一行可以将csv的所有数据按表格的形式打印出来。并且,使用pandas要进一步转化为np形式,才能进一步处理,所以要载入numpy模块。

数据准备

# 将pandas文件转化为numpy格式,因为后续数据分离以及归一化对是基于numpy
df = df.values
df = np.array(df)
print(df)  # 打印所有数据

# 数据归一化,已知有13列数据,前12列是特征,最后一列是标签
# 数据归一化是为了压缩各个特征的取值范围,有利于loss的收敛
# 但是注意是对特征信息给归一化,不要压缩标签值
for i in range(12):
    df[:, i] = df[:, i]/(df[:, i].max()-df[:, i].min())

# 分离csv数据
x_data = df[:, :12]  # 取前12列
y_data = df[:, 12]  # 取第13列

csv数据读入后首先要转化为np格式,以便之后做矩阵的处理。由于各个特征对于最终结果的实际影响作用不同,所以要对数据进行归一化,压缩其变化范围,这样有利于训练时的快速有效收敛。但是注意,归一化是针对输入值的,不要对标签值进行归一化。

构建模型

# 建立模型
# 此处的x即为对于一个样本的概述,一个样本有12个特征;为了适应batchsize,此处不指明有几个样本;None可以为1,也可以是更大的
# y同理,每个标签只有一个维度
x = tf.placeholder(tf.float32, [None, 12], name='X')
y = tf.placeholder(tf.float32, [None, 1], name='Y')

with tf.name_scope("Model"):  # 封装权重、偏差、loss以及前向计算于一个命名空间
    w = tf.Variable(tf.random_normal([12, 1], stddev=0.01), name='W')
    b = tf.Variable(1.0, name='b')


    def model(x, w, b):  # 定义前行计算模型
        return(tf.matmul(x,w)+b)


    preb = model(x, w, b)  # 建立前向计算操作

如上述代码实现多维线性模型的建立,并建立的对应的前向计算操作;上述代码中,使用了命名空间,这其实有点类似c++中的命名空间,不同的是,此处使用的效果不仅在代码上有更好的可读性,在graph上一个命名空间表示一个子图,即在计算图上也有较好的可读性。着重理解占位符中的NONE,即不固定输入的样本数目,这将在批量训练时有重要作用。

进行训练前的准备

# 设置超参
train_epochs = 200
learning_rate = 0.01
logdir = 'E:/log'

with tf.name_scope("Loss_Function"):  # 封损失函数在此命名空间
    loss_function = tf.reduce_mean(tf.pow(y-preb, 2))

# 优化器
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss_function)
# 将loss记录在graph上
sum_loss_op = tf.summary.scalar("loss", loss_function)
merged = tf.summary.merge_all()

训练前要设好超参,此处的模型较为简单,超参只包括训练的轮数以及学习率;同时要为模型建立损失函数以及优化器;并且,为了将loss值显示在graph上,此处定义了一个sum_loss_op,由于是summary.scalar所以将在tensorboard的scalar中显示,注意要实现显示,merge是必要的操作,尤其是有多个数据要显示在tensorboard中时,此步是必需要有的。

进行训练

# 启动会话
sess = tf.Session()
sess.run(tf.global_variables_initializer())
writer = tf.summary.FileWriter(logdir,sess.graph)  # 记录日志
print('***********TRAIN***********')
loss_list = []  # loss统计值集合
for epoch in range(train_epochs):  # 逐轮次训练
    loss_sum = 0.0  # 统计每轮训练的loss值
    for xs, ys in zip(x_data, y_data):  # 从训练数据与标签值中对应抽取数据
        xs = xs.reshape(1, 12)  # feeddict前一定要确保尺寸与占位符规定的一致
        ys = ys.reshape(1, 1)
        _, summary_str, loss = sess.run([optimizer, sum_loss_op, loss_function], feed_dict={x: xs, y: ys})# 进行优化、记录loss,计算loss三个操作
        loss_sum = loss_sum+loss  # 统计每轮训练的loss值
        writer.add_summary(summary_str, epoch)  # 将记录loss的返回值与轮数对应绘制图像
    xvalues, yvaules = shuffle(x_data, y_data)  # 每次训练打乱原数据集

    btemp = b.eval(session=sess)  # 获取此轮训练得到的b值
    wtemp = w.eval(session=sess)  # 获取本轮训练得到的w值
    loss_average = loss_sum/len(y_data)  # 计算本轮评价loss值
    loss_list.append(loss_average)  # 记录本轮评价loss值
    # 打印本轮训练结果
    print("epoch:", epoch+1, "loss: ", loss_average, "b: ", btemp, "w: ", wtemp) 

上述代码实现了对于所建立模型的训练;注意在feed_dict之前,要确保喂的值与占位符所规定的维度一致;每轮训练后要打乱原有数据集,是为了防止模型取背答案,换句话说就是防止模型将顺序当作特征进行了学习。

模型应用

# 检验模型
n = np.random.randint(506)
print(n)
x_test = x_data[n]
target = y_data[n]
x_test = x_test.reshape(1, 12)
predict = sess.run(preb, feed_dict={x: x_test})

print("prediction: ", predict, "Target: ", target)

writer.close()

利用上述代码检测模型;由于初步教程,并未对数据集进行训练集测试集以及验证集的划分,所以仅以实验目的,此处利用随机数生成索引值,利用索引值去抽取一个样本,进行检测值与实际标签值的对比。

 

发布了5 篇原创文章 · 获赞 0 · 访问量 64

猜你喜欢

转载自blog.csdn.net/weixin_41707744/article/details/104701216