注:本文源自極客學院整理的TensorFlow官方文檔的中文版,小編只是好資源的搬運工,下篇文章將介紹tensorflow ubuntu14.04下的安裝過程,親測有效。python
這個教程的目標讀者是對機器學習和TensorFlow都不太瞭解的新手。算法
當咱們開始學習編程的時候,第一件事每每是學習打印"Hello World"。就比如編程入門有Hello World,機器學習入門有MNIST。編程
MNIST是一個入門級的計算機視覺數據集,它包含各類手寫數字圖片:ubuntu
它也包含每一張圖片對應的標籤,告訴咱們這個是數字幾。好比,上面這四張圖片的標籤分別是5,0,4,1。數組
在此教程中,咱們將訓練一個機器學習模型用於預測圖片裏面的數字。咱們的目的不是要設計一個世界一流的複雜模型 -- 儘管咱們會在以後給你源代碼去實現一流的預測模型 -- 而是要介紹下如何使用TensorFlow。因此,咱們這裏會從一個很簡單的數學模型開始,它叫作Softmax Regression。微信
對應這個教程的實現代碼很短,並且真正有意思的內容只包含在三行代碼裏面。可是,去理解包含在這些代碼裏面的設計思想是很是重要的:TensorFlow工做流程和機器學習的基本概念。所以,這個教程會很詳細地介紹這些代碼的實現原理。機器學習
MNIST數據集分佈式
下載MNIST數據集,而後用下面的代碼導入到你的項目裏面,也能夠直接複製粘貼到你的代碼文件裏面。函數
import tensorflow.examples.tutorials.mnist.input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
性能
下載下來的數據集被分紅兩部分:60000行的訓練數據集(mnist.train
)和10000行的測試數據集(mnist.test
)。這樣的切分很重要,在機器學習模型設計時必須有一個單獨的測試數據集不用於訓練而是用來評估這個模型的性能,從而更加容易把設計的模型推廣到其餘數據集上(泛化)。
正如前面提到的同樣,每個MNIST數據單元有兩部分組成:一張包含手寫數字的圖片和一個對應的標籤。咱們把這些圖片設爲「xs」,把這些標籤設爲「ys」。訓練數據集和測試數據集都包含xs和ys,好比訓練數據集的圖片是mnist.train.images
,訓練數據集的標籤是 mnist.train.labels
。
每一張圖片包含28X28個像素點。咱們能夠用一個數字數組來表示這張圖片:
咱們把這個數組展開成一個向量,長度是 28x28 = 784。如何展開這個數組(數字間的順序)不重要,只要保持各個圖片採用相同的方式展開。從這個角度來看,MNIST數據集的圖片就是在784維向量空間裏面的點。
對於softmax迴歸模型能夠用下面的圖解釋,對於輸入的xs
加權求和,再分別加上一個偏置量,最後再輸入到softmax函數中:
若是把它寫成一個等式,咱們能夠獲得:
咱們也能夠用向量表示這個計算過程:用矩陣乘法和向量相加。這有助於提升計算效率。(也是一種更有效的思考方式)
更進一步,能夠寫成更加緊湊的方式:
實現迴歸模型
爲了用python實現高效的數值計算,咱們一般會使用函數庫,好比NumPy,會把相似矩陣乘法這樣的複雜運算使用其餘外部語言實現。不幸的是,從外部計算切換回Python的每個操做,仍然是一個很大的開銷。若是你用GPU來進行外部計算,這樣的開銷會更大。用分佈式的計算方式,也會花費更多的資源用來傳輸數據。
TensorFlow也把複雜的計算放在python以外完成,可是爲了不前面說的那些開銷,它作了進一步完善。Tensorflow不單獨地運行單一的複雜計算,而是讓咱們能夠先用圖描述一系列可交互的計算操做,而後所有一塊兒在Python以外運行。(這樣相似的運行方式,能夠在很多的機器學習庫中看到。)
使用TensorFlow以前,首先導入它:
import tensorflow as tf
咱們經過操做符號變量來描述這些可交互的操做單元,能夠用下面的方式建立一個:
x = tf.placeholder(tf.float32, [None, 784])
x
不是一個特定的值,而是一個佔位符placeholder
,咱們在TensorFlow運行計算時輸入這個值。咱們但願可以輸入任意數量的MNIST圖像,每一張圖展平成784維的向量。咱們用2維的浮點數張量來表示這些圖,這個張量的形狀是[None,784 ]
。(這裏的None
表示此張量的第一個維度能夠是任何長度的。)
咱們的模型也須要權重值和偏置量,固然咱們能夠把它們當作是另外的輸入(使用佔位符),但TensorFlow有一個更好的方法來表示它們:Variable
。 一個Variable
表明一個可修改的張量,存在在TensorFlow的用於描述交互性操做的圖中。它們能夠用於計算輸入值,也能夠在計算中被修改。對於各類機器學習應用,通常都會有模型參數,能夠用Variable
表示。
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
咱們賦予tf.Variable
不一樣的初值來建立不一樣的Variable
:在這裏,咱們都用全爲零的張量來初始化W
和b
。由於咱們要學習W
和b
的值,它們的初值能夠隨意設置。
注意,W
的維度是[784,10],由於咱們想要用784維的圖片向量乘以它以獲得一個10維的證據值向量,每一位對應不一樣數字類。b
的形狀是[10],因此咱們能夠直接把它加到輸出上面。
如今,咱們能夠實現咱們的模型啦。只須要一行代碼!
y = tf.nn.softmax(tf.matmul(x,W) + b)
首先,咱們用tf.matmul(X,W)
表示x
乘以W
,對應以前等式裏面的
,這裏
x
是一個2維張量擁有多個輸入。而後再加上b
,把和輸入到tf.nn.softmax
函數裏面。
至此,咱們先用了幾行簡短的代碼來設置變量,而後只用了一行代碼來定義咱們的模型。TensorFlow不只僅可使softmax迴歸模型計算變得特別簡單,它也用這種很是靈活的方式來描述其餘各類數值計算,從機器學習模型對物理學模擬仿真模型。一旦被定義好以後,咱們的模型就能夠在不一樣的設備上運行:計算機的CPU,GPU,甚至是手機!
訓練模型
爲了訓練咱們的模型,咱們首先須要定義一個指標來評估這個模型是好的。其實,在機器學習,咱們一般定義指標來表示一個模型是壞的,這個指標稱爲成本(cost)或損失(loss),而後儘可能最小化這個指標。可是,這兩種方式是相同的。
一個很是常見的,很是漂亮的成本函數是「交叉熵」(cross-entropy)。交叉熵產生於信息論裏面的信息壓縮編碼技術,可是它後來演變成爲從博弈論到機器學習等其餘領域裏的重要技術手段。它的定義以下:
y 是咱們預測的機率分佈, y' 是實際的分佈(咱們輸入的one-hot vector)。比較粗糙的理解是,交叉熵是用來衡量咱們的預測用於描述真相的低效性。更詳細的關於交叉熵的解釋超出本教程的範疇,可是你頗有必要好好反向傳播算法(backpropagation algorithm)來有效地肯定你的變量是如何影響你想要最小化的那個成本值的。而後,TensorFlow會用你選擇的優化算法來不斷地修改變量以下降成本。
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
在這裏,咱們要求TensorFlow用梯度降低算法(gradient descent algorithm)以0.01的學習速率最小化交叉熵。梯度降低算法(gradient descent algorithm)是一個簡單的學習過程,TensorFlow只需將每一個變量一點點地往使成本不斷下降的方向移動。固然TensorFlow也提供了其餘許多優化算法:只要簡單地調整一行代碼就可使用其餘的算法。
TensorFlow在這裏實際上所作的是,它會在後臺給描述你的計算的那張圖裏面增長一系列新的計算操做單元用於實現反向傳播算法和梯度降低算法。而後,它返回給你的只是一個單一的操做,當運行這個操做時,它用梯度降低算法訓練你的模型,微調你的變量,不斷減小成本。
如今,咱們已經設置好了咱們的模型。在運行計算以前,咱們須要添加一個操做來初始化咱們建立的變量:
init = tf.initialize_all_variables()
如今咱們能夠在一個Session
裏面啓動咱們的模型,而且初始化變量:
sess = tf.Session()
sess.run(init)
而後開始訓練模型,這裏咱們讓模型循環訓練1000次!
for i in range(1000):
batch_xs, batch_ys = mnist.train.next_batch(100)
sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})
該循環的每一個步驟中,咱們都會隨機抓取訓練數據中的100個批處理數據點,而後咱們用這些數據點做爲參數替換以前的佔位符來運行train_step
。
使用一小部分的隨機數據來進行訓練被稱爲隨機訓練(stochastic training)- 在這裏更確切的說是隨機梯度降低訓練。在理想狀況下,咱們但願用咱們全部的數據來進行每一步的訓練,由於這能給咱們更好的訓練結果,但顯然這須要很大的計算開銷。因此,每一次訓練咱們可使用不一樣的數據子集,這樣作既能夠減小計算開銷,又能夠最大化地學習到數據集的整體特性。
評估咱們的模型
那麼咱們的模型性能如何呢?
首先讓咱們找出那些預測正確的標籤。tf.argmax
是一個很是有用的函數,它能給出某個tensor對象在某一維上的其數據最大值所在的索引值。因爲標籤向量是由0,1組成,所以最大值1所在的索引位置就是類別標籤,好比tf.argmax(y,1)
返回的是模型對於任一輸入x預測到的標籤值,而 tf.argmax(y_,1)
表明正確的標籤,咱們能夠用 tf.equal
來檢測咱們的預測是否真實標籤匹配(索引位置同樣表示匹配)。
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
這行代碼會給咱們一組布爾值。爲了肯定正確預測項的比例,咱們能夠把布爾值轉換成浮點數,而後取平均值。例如,[True, False, True, True]
會變成 [1,0,1,1]
,取平均值後獲得 0.75
.
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
最後,咱們計算所學習到的模型在測試數據集上面的正確率。
print sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels})
這個最終結果值應該大約是91%。
比結果更重要的是,咱們從這個模型中學習到的設計思想。你還能夠學習如何用TensorFlow構建更加複雜的模型以得到更好的性能!
但願對你們有幫助!
本文分享自微信公衆號 - AI MOOC人工智能平臺(AIMOOC_XLAB)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。