1. 程式人生 > >TensorFlow入門教程:11:線性迴歸

TensorFlow入門教程:11:線性迴歸

在這裡插入圖片描述 相較於前面的基礎,這篇文章才是真正意義上的第一個tensorflow的Hello World。我們將使用tensorflow提供的方法來對資料中所體現的線性關係進行建模,通過輸入資料對模型進行訓練,然後使用訓練生成的穩定模型對未知的自變數所對應的因變數進行確認。

迴歸分析

迴歸分析研究的是因變數和自變數之間的關係,在預測模型中被廣泛地應用。自變數的個數/因變數的型別/迴歸線的形狀都是需要考慮的,常見的迴歸分析方式如下:

  • Linear Regression:線性迴歸
  • Logistic Regression:邏輯迴歸
  • Polynomial Regression:多項式迴歸
  • Lasso Regression:套索迴歸
  • ElasticNet Regression:ElasticNet迴歸

線性迴歸

線性,簡單來說就是y = k*x + b,自變數和因變數之間的關係用一條直線來進行表述,k是數學意義上的斜率,而b則是調整的偏差。(為了與常用的各種資料儲存一致,將k調整為w)

場景說明

求解問題:Y = K*X +B

選項 說明
Y 因變數:資料有訓練資料和測試資料兩類,為輸入資料
X 自變數:資料有訓練資料和測試資料兩類,訓練資料為輸入資料,測試資料為待求解的輸出資料
K 斜率:自變數和因變數之間的線性關係,為待求解的值,為輸出資料
B 偏差:調整的偏差值,為待求解的值,為輸出資料

求解過程

事前準備

假定帶求解的線性問題為:Y = 2*X + 1

資料準備:

  • 自變數:xdata,將0到1進行100等分所形成的等差數列
  • 因變數:ydata,滿足2*xdata + 1的線性關係
xdata = np.linspace(0,1,100)
ydata = 2 * xdata + 1

具體設定值:

>>> print(xdata)
[0.         0.01010101 0.02020202 0.03030303 0.04040404 0.05050505
 0.06060606 0.07070707 0.08080808 0.09090909 0.1010101  0.11111111
 0.12121212 0.13131313 0.14141414 0.15151515 0.16161616 0.17171717
 0.18181818 0.19191919 0.2020202  0.21212121 0.22222222 0.23232323
 0.24242424 0.25252525 0.26262626 0.27272727 0.28282828 0.29292929
 0.3030303  0.31313131 0.32323232 0.33333333 0.34343434 0.35353535
 0.36363636 0.37373737 0.38383838 0.39393939 0.4040404  0.41414141
 0.42424242 0.43434343 0.44444444 0.45454545 0.46464646 0.47474747
 0.48484848 0.49494949 0.50505051 0.51515152 0.52525253 0.53535354
 0.54545455 0.55555556 0.56565657 0.57575758 0.58585859 0.5959596
 0.60606061 0.61616162 0.62626263 0.63636364 0.64646465 0.65656566
 0.66666667 0.67676768 0.68686869 0.6969697  0.70707071 0.71717172
 0.72727273 0.73737374 0.74747475 0.75757576 0.76767677 0.77777778
 0.78787879 0.7979798  0.80808081 0.81818182 0.82828283 0.83838384
 0.84848485 0.85858586 0.86868687 0.87878788 0.88888889 0.8989899
 0.90909091 0.91919192 0.92929293 0.93939394 0.94949495 0.95959596
 0.96969697 0.97979798 0.98989899 1.        ]
>>> print(ydata)
[1.         1.02020202 1.04040404 1.06060606 1.08080808 1.1010101
 1.12121212 1.14141414 1.16161616 1.18181818 1.2020202  1.22222222
 1.24242424 1.26262626 1.28282828 1.3030303  1.32323232 1.34343434
 1.36363636 1.38383838 1.4040404  1.42424242 1.44444444 1.46464646
 1.48484848 1.50505051 1.52525253 1.54545455 1.56565657 1.58585859
 1.60606061 1.62626263 1.64646465 1.66666667 1.68686869 1.70707071
 1.72727273 1.74747475 1.76767677 1.78787879 1.80808081 1.82828283
 1.84848485 1.86868687 1.88888889 1.90909091 1.92929293 1.94949495
 1.96969697 1.98989899 2.01010101 2.03030303 2.05050505 2.07070707
 2.09090909 2.11111111 2.13131313 2.15151515 2.17171717 2.19191919
 2.21212121 2.23232323 2.25252525 2.27272727 2.29292929 2.31313131
 2.33333333 2.35353535 2.37373737 2.39393939 2.41414141 2.43434343
 2.45454545 2.47474747 2.49494949 2.51515152 2.53535354 2.55555556
 2.57575758 2.5959596  2.61616162 2.63636364 2.65656566 2.67676768
 2.6969697  2.71717172 2.73737374 2.75757576 2.77777778 2.7979798
 2.81818182 2.83838384 2.85858586 2.87878788 2.8989899  2.91919192
 2.93939394 2.95959596 2.97979798 3.        ]
>>>

變數初始化

對於四個相關的tensorflow中使用到的變數進行如下設定: 其中X和Y用於上述訓練輸入資料的輸入

X = tf.placeholder("float",name="X")
Y = tf.placeholder("float",name="Y")
W = tf.Variable(3., name="W")
B = tf.Variable(3., name="B")

設定模型

設定模型為X*W + B

linearmodel = tf.add(tf.multiply(X,W),B)

損失函式

loss function也被成為cost function,這裡使用方差作為損失函式,用於確認期待值和計算值之間的差距。

lossfunc = (tf.pow(Y - linearmodel, 2))

Optimizer

tensorflow的train中包含多種Optimizer,這裡使用最為常用的梯度下降的優化器,以在不斷的運算中調整引數的值。這裡設定Learning Rate為0.01, 設定過小,收斂速度可能會很慢,但是過大反而可能會導致不收斂,需要根據具體情況進行調整。

learningrate = 0.01
trainoperation = tf.train.GradientDescentOptimizer(learningrate).minimize(lossfunc)

初期化Session

進行訓練之前,對session進行初期化

sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)

進行訓練

至此,所需要的準備已經全部完畢,科技進行訓練了,而訓練而只是使用前面簡單例子中說明的方法,向X和Y中灌入訓練資料即可。 這裡特意使用一個簡單的兩層迴圈來說明資料訓練的層次,內層i對應xdata和ydata的100條資料,外層j表示對此訓練資料整體迴圈的次數。總體資料運算次數為:100*100 = 10000次

print("caculation begins ...")
for j in range(100):
  for i in range(100):
    sess.run(trainoperation, feed_dict={X: xdata[i], Y:ydata[i]})

結果展示

使用scatter展示訓練資料的分佈狀況,使用plot顯示訓練後資料:

plt.scatter(xdata,ydata)
plt.plot(xdata,B.eval(session=sess)+W.eval(session=sess)*xdata,'b',label='caculated : w*x + b')
plt.legend()
plt.show()

資料預測

訓練穩定後的模型,可以用來預測訓練資料以外的其他情況,這裡使用如下測試資料:

測試資料(自變數X) 期待結果
3 3*2 + 1 = 7
10 10*2 + 1 =21

示例程式碼

liumiaocn:Notebook liumiao$ cat basic-operation-6.py 
import tensorflow as tf
import numpy      as np
import os
import matplotlib.pyplot as plt

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

xdata = np.linspace(0,1,100)
ydata = 2 * xdata + 1

print("init modole ...")
X = tf.placeholder("float",name="X")
Y = tf.placeholder("float",name="Y")
W = tf.Variable(3., name="W")
B = tf.Variable(3., name="B")
linearmodel = tf.add(tf.multiply(X,W),B)
lossfunc = (tf.pow(Y - linearmodel, 2))
learningrate = 0.01

print("set Optimizer")
trainoperation = tf.train.GradientDescentOptimizer(learningrate).minimize(lossfunc)

sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)

print("caculation begins ...")
for j in range(100):
  for i in range(100):
    sess.run(trainoperation, feed_dict={X: xdata[i], Y:ydata[i]})
    #print("i = " + str(i) + "b: " + str(B.eval(session=sess)) + ", w : " + str(W.eval(session=sess)))
print("caculation ends ...")
print("##After Caculation: ") 
print("   B: " + str(B.eval(session=sess)) + ", W : " + str(W.eval(session=sess)))
print("   B: 2  W: 1 (Real Value)")
print("##Test for the trained model: Y = X*W + B")
testxdata       = 3.
expectydata     = testxdata*2 + 1
calculatedydata = W.eval(session=sess) * testxdata + B.eval(session=sess)
precision       = 100 - np.abs(calculatedydata/expectydata - 1) * 100
print("  X=%f , Y = ? (2*%f + 1 = %f)" %(testxdata,testxdata,expectydata))
print("  Y= %f, pricse = %f %%" %(calculatedydata,precision)) 

testxdata       = 10.
expectydata     = testxdata*2 + 1
calculatedydata = W.eval(session=sess) * testxdata + B.eval(session=sess)
precision       = 100 - np.abs(calculatedydata/expectydata - 1) * 100
print("  X=%f , Y = ? (2*%f + 1 = %f)" %(testxdata,testxdata,expectydata))
print("  Y= %f, pricse = %f %%" %(calculatedydata,precision)) 

plt.scatter(xdata,ydata)
plt.plot(xdata,B.eval(session=sess)+W.eval(session=sess)*xdata,'b',label='caculated : w*x + b')
plt.legend()
plt.show()
liumiaocn:Notebook liumiao$ 

結果確認

測試資料覆蓋狀況

使用測試資料3與10,使用上面100次迭代後得到的Model進行預測,與期待值有較好的一個匹配,達到了99.999%

liumiaocn:Notebook liumiao$ python basic-operation-6.py 
init modole ...
set Optimizer
caculation begins ...
caculation ends ...
##After Caculation: 
   B: 0.99998814, W : 2.0000176
   B: 2  W: 1 (Real Value)
##Test for the trained model: Y = X*W + B
  X=3.000000 , Y = ? (2*3.000000 + 1 = 7.000000)
  Y= 7.000041, pricse = 99.999413 %
  X=10.000000 , Y = ? (2*10.000000 + 1 = 21.000000)
  Y= 21.000165, pricse = 99.999216 %
liumiaocn:Notebook liumiao$

訓練資料覆蓋狀況

使用梯度下降的方式所計算出來的曲線,可以看出將輸入資料幾乎完全覆蓋 在這裡插入圖片描述

這裡就是典型的測試資料和訓練資料都有很好的結果的狀況,基本上就是理想狀況,原因當然和很簡單,因為是完美的資料,超級簡單的線性模型。

總結

通過這篇文章,雖然只是一個非常簡單的線性迴歸模擬,我們瞭解到了tensorflow使用的方式,看到了有導師監督的演算法的訓練和使用方式,也可以看出tensorflow的強大,至少梯度下降只需要設定Learningrate即可,不再需要再確認導數相關的內容,也不必過於擔心簡單編碼錯誤導致的結論錯誤,節省了很多的時間,所以即使沒有強大的數學底子,進行AI的研究也不是不可能了,極大地降低了入門的門檻。 接下來,我們將會繼續使用這樣一個超級簡單的例子,來模擬實際環境中的各種情況比如影響資料的模擬下的,同樣的迭代所能達到的程度等更為具體的情況。