Tensorflow基本開發架構

Tensorflow基本開發架構       

        先說句題外話, 這段時間一直研究爬蟲技術,主要目的是爲未來爬取訓練數據作準備,同時學習python編程。這一研究才發現,python的開發資源實在是太豐富了,全部你能想到的應用都有對應的開發庫提供支持,簡直是無所不能。舉一個簡單的例子,之前認爲比較難辦的驗證碼輸入,python居然提供了多個庫供咱們選擇以實現自動識別驗證碼、並自動輸入,這對於爬取需輸入驗證碼的網站很是有用。另外,對人臉識別、天然語音處理、數據挖掘等AI領域的支持也至關強大。目前主流的算法像線性迴歸、支持向量機、聚類、決策樹、kNN等python實現比較容易,要是用C/C++可就麻煩多了,由於這些算法要用到大量的矩陣運算,python的數學庫NumPy對此支持至關好。同時,像tensorflow這樣的開源的深度學習庫其提供的開發例程也是以python爲主。因此,通過這段時間的學習,我相信python在未來必定會成爲大部分程序員必須掌握的一門語言之一。固然,從如今看python的熱度也已經在GitHub、StackOverflow等網站上表現出強勁的增加勢頭。
       本週4結束了爬蟲技術的學習,本身開發了一個自動登陸京東、自動下訂單購買的爬蟲程序做爲檢驗本身學習成果的結業項目,感受很不錯,之後再搶東西,確定比別人手快了,不用再熬夜搶了。如今轉過頭開始看tensorflow的文檔,小有收穫,理解了tensorflow的基本開發架構。有一點須要特別注意的是,使用tensorflow以前,必須肯定本身已經安裝了NumPy庫,大量的算法實現都圍繞這個庫完成,核心就是矩陣運算,也就是線性代數要學習的內容。
        tensorflow的基本開發架構參見以下開發例程:python

#-*- coding: utf-8 -*-

import tensorflow as tf
import numpy as np

#在tensorflow中,全部變量必須用tf.Variable定義,0爲初始值,name爲該變量名稱(可選)
state = tf.Variable(0, name = 'counter')
#print(state.name)
one = tf.constant(1)

#與new_vale = state + 1等價,tf中必須用專有函數操做,且下述語句僅是定義該操做,並不執行
new_value = tf.add(state, one)
#指定將new_value的值更新到state,這裏依然是事先指定這個操做給變量update,並不會執行
update = tf.assign(state, new_value)

#指定tf啓動session時要進行全部變量初始化操做,這裏依然只是指定初始化操做給init,並不實際執行
#換句話說,只要上面存在tf.Variable()的調用,就必須調用init操做
init = tf.global_variables_initializer()

#啓動tf會話並執行
with tf.Session() as sess:
    sess.run(init) #全部tf.Vaiable()定義的變量被真正初始化
    print('-' * 8, sess.run(state))
    #測試變量更新操做,執行屢次
    for _ in range(10):
        sess.run(update)        #變量更新操做
        print(sess.run(state))  #輸出state值,注意tf中要查看某個變量的值一樣須要用sess.run()函數

從語句state = tf.Variable(...)開始到 init = tf.global_variables_initializer()結束,這屬於tensorflow基本輸入結構的定義區,全部要訓練的輸入數據或要使用的訓練算法都在這裏定義好,而後經過tf.Session()啓動一個會話並經過run()函數開始執行上面的基本輸入結構提早定義好的操做。查看執行結果也是經過run函數,像上面這個例子咱們經過語句sess.run(state)來查看其操做結果,以下:程序員

經過這個例子能夠看出,tensorflow其基本開發架構不難,難點仍是在於對核心實現算法的理解。像下面這個例子,利用邏輯迴歸算法咱們求得了一組測試數據的迴歸係數和偏置量:算法

#-*- coding: utf-8 -*-

import tensorflow as tf
import numpy as np

#使用NumPy生成測試數據,共100個點
x_data = np.float32(np.random.rand(2, 100))
y_data = np.dot([0.100, 0.700], x_data) + 0.300 #其實就是線性方程: y = 0.1 * x2 + 0.7 * x2 + 0.3
                                                #最後預測數據看是否是0.一、0.2(W: weights, 權重)和0.3(b: baises, 偏置係數)
print(x_data)
print(y_data)

#構造一個線性模型
b = tf.Variable(tf.zeros(1))                          #偏置係數初始爲0
W = tf.Variable(tf.random_uniform([1, 2], -1.0, 1.0)) #產生一個1行2列的矩陣,數值從-1到1之間,爲權重的初始值
y = tf.matmul(W, x_data) + b                          #生成訓練數據

#最小化方差
loss = tf.reduce_mean(tf.square(y - y_data))          #與真實數據(y_data)之間的方差
optimizer = tf.train.GradientDescentOptimizer(0.5)    #梯度降低步長
train = optimizer.minimize(loss)                      #使用梯度降低算法開始優化數據使其變到最小

#初始化變量,tf中只要定義變量就必須初始化變量
init = tf.global_variables_initializer()

#啓動圖
sess = tf.Session()
sess.run(init)      #執行變量初始化

#擬合平面,201次循環執行sess.run(train),使方差最小
for step in range(0, 201):
    sess.run(train)
    if step % 20 == 0:
        print(step, sess.run(W), sess.run(b))

上面這個例子的執行流程很清晰,比較容易理解,主要難點在於這段代碼幹了啥事?這段代碼首先生成了一段訓練數據x_data和y_data,這段數據爲兩個矩陣x和y,其關係能夠用二元一次方程式表示:
y = 0.1 * X1  + 0.7 * X2 + 0.3

其中語句y_data = np.dot(...) 便是對這個方程式的代碼實現。np.dot()函數實現了矩陣的標準乘運算。其中,x_data爲一個二維矩陣:2行100列,而後咱們用一個1行2列的矩陣[0.100, 0.700]與之相乘,獲得一個1行100列的新矩陣,而後新矩陣每一個向量加0.3獲得y_data。這個過程徹底利用numpy庫完成了上述矩陣運算,實現了y_data與x_data之間由上述二元一次方程式表示的向量關係。
而後咱們開始構建邏輯迴歸(Logistic迴歸)模型,首先將偏置係數初始值置爲0(意思就是從0開始找,直至找到合適的偏置係數0.3),而後再利用隨機數構建一個1行2列的矩陣,這個矩陣的做用與[0.100, 0.700]徹底相同。在這裏用隨機數生成只是由於模型尚且不知道哪兩個係數與x_data相乘能獲得y_data:
y = tf.matmul(W, x_data) + b

因此程序要找的就是根據上式可以獲得或者最接近y_data的W和b的最優值。所以,咱們用隨機數生成了迴歸係數矩陣W的向量值做爲初始值,從這兩個值開始計算查找直至找到0.1和0.7爲止。邏輯迴歸模型的真正做用亦在於此,其可以根據一組給定的多維數值,找到它們之間的邏輯關係。在程序中其表現就是,從上述兩個初始值開始迭代執行梯度降低算法:編程

#最小化方差
loss = tf.reduce_mean(tf.square(y - y_data))          #與真實數據(y_data)之間的方差
optimizer = tf.train.GradientDescentOptimizer(0.5)    #梯度降低步長
train = optimizer.minimize(loss)                      #使用梯度降低算法開始優化數據使其變到最小
使得loss,也就是與真實數據之間的方差最小(用方差的緣由是去掉正、負號對計算結果的影響),從而獲得最優的迴歸係數與偏置係數。

        最後的for循環便是啓動tensorflow執行上述的梯度降低算法,在這裏sess.run(train)共迭代執行201次,程序每隔20次輸出當前的迴歸係數與偏置係數,這樣可讓咱們看到訓練是否正在向預期的數值迴歸。下面是這個程序的輸出結果:session

圖中,從第0次開始,W和b逐漸接近[0.1 ,0.7]、0.3,到第200次的時候,W等於[0.10000169, 0.70000368] ,b等於0.29999697,與實際數值基本相同,算法驗證成功。架構

tensorflow的實際做用即在於此,咱們不用考慮複雜的數學公式以及如何編碼實現它,咱們直接使用封裝好的算法便可完成數據訓練獲得咱們想要的模型,這一點很是重要。

那麼接下來的問題是,上述算法實現到底能有啥實際用處呢? 引用機器學習領域最著名的波士頓房價問題來解釋這個。在波士頓,有經驗的房屋銷售人員能夠根據房屋地段、面積、戶型給出估算的房屋售價,基本這個售價不會偏離實際售出價太多,可是對於剛入行的人來講這個就很難了。那麼,咱們怎樣可以讓全部銷售人員可以比較準確的預測要出售房屋的售價呢?這就是上述算法要大展身手的地方了。假如咱們已經有了最近幾年的已經銷售房屋的樣本數據,包括地段、房屋面積、房屋戶型以及實際售價。那麼咱們將上述數據輸給上面那個程序,讓它找出地段、面積、戶型這三組數據與實際售價之間的邏輯關係,最終通過N次迭代執行,咱們會獲得三個W值,一個b值。這個過程咱們稱之爲數據訓練(也就是機器學習)。因而,有了這個模型,銷售人員只需輸入地段、面積、戶型三個已知數值,就能夠獲得預測的房價。只要樣本數據訓練足夠多(固然實際樣本數據類型也應該不止這三種),那麼預測房價就會逐漸趨近實際售價,模型的準確率就會愈來愈高。
固然房價預測只是上述算法的其中一個應用而已,更重要的是,這個算法不用任何改動,其就能夠用到其它領域的數值預測中,而咱們要作的只是把訓練數據換一下而已,機器學習的優點在這方面體現的淋漓盡致。另外,監督學習中的各類分類問題上述算法亦用處多多。其實,這個算法在tensorflow中只是冰山一角,其豐富的算法庫能夠幫助咱們解決諸如圖像識別、數據挖掘、天然語言處理等諸多領域的實際應用問題。dom

相關文章
相關標籤/搜索