TF中的多元線性迴歸———波士頓房價問題

多元性線性迴歸

與之前的一元線性迴歸相比:都是線性模型,但是輸入的特徵維度是多維的,所以應建立多維的線性映射關係來實現對於數據的預測。本文將以波士頓房價爲例進行多維線性模型的建立、訓練以及預測。

數據說明

  1. 共506個樣本,每個樣本共12個特徵;
  2. 數據以csv的格式進行存儲,在csv中表現爲507行13列;第一行爲列名,前12列表示特徵,最後一列表示標籤值。

讀取數據:

import tensorflow asd 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()

利用上述代碼檢測模型;由於初步教程,並未對數據集進行訓練集測試集以及驗證集的劃分,所以僅以實驗目的,此處利用隨機數生成索引值,利用索引值去抽取一個樣本,進行檢測值與實際標籤值的對比。

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章