Tensorflow基本開發架構


Tensorflow基本開發架構       

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

#-*- 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.1、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次輸出當前的回歸系數與偏置系數,這樣可以讓我們看到訓練是否正在向預期的數值回歸。下面是這個程序的輸出結果:

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

tensorflow的實際作用即在於此,我們不用考慮復雜的數學公式以及如何編碼實現它,我們直接使用封裝好的算法即可完成數據訓練得到我們想要的模型,這一點非常重要。

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM