TensorFlow 101

關於tensorflow的第一堂課,課程只是一小半,更重要的是課後作業,如果你對課後有任何想法,可以將你的代碼和嘗試發郵件到guoruidong517@126.com。

要想學好深度學習界最最火的tensor-flow就要從這個名字講起。而本教程的目的就是通過一行一行的講解MINST代碼,讓你了解tensor-flow的基本構成。短短十幾行代碼,就可以實現深度學習,是不是很期待。

深度學習TF - 騰訊視頻 https://v.qq.com/x/page/m03787qm1m6.html

Tensor-flow是圍繞著圖構建出來的,不然這個名字中的flow怎麼解釋。要想了解tensor-flow,就要將這些代碼想像成畫圖的構成,先選好紙,搭好想畫的圖的骨架,然後上色,最後將圖拿去給懂行的人去評價。

我們要看的例子是熟悉機器學習的人都會遇到的手寫數字識別,專業一點的叫法是MINST數據集。(放MINST數據集的介紹圖片)這份數據集包括55000行訓練用點數據集(mnist.train),10000行測試數據集(mnist.test),以及5000行驗證數據集(mnist.validation),每一張圖片包含28*28像素.我們可以用一個數字數組來表示這張圖片,每一個MNIST數據單元有兩部分組成:一張包含手寫數字的圖片和一個對應的標籤.我們把這些圖片設為「xs」,把這些標籤設為「ys」.訓練數據集和測試數據集都包含xs和ys,比如訓練數據集的圖片是mnist.train.images,訓練數據集的標籤是mnist.train.labels.(這裡可以有代碼,語速可以快一點)

importinput_data

2mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

這兩行代碼是用來自動下載MINST數據集,不必深究。

import tensorflow as tf

這行代碼是用來導入tensorflow模塊的,相當於找了一張畫紙

下來我們要做的給我們的畫搭好骨架,就是告訴程序要做哪些準備工作

x = tf.placeholder("float", [None, 784])

這裡的佔位符(placeholder)是tensor-flow中最常用的一個概念,這句話告訴程序,x這個變數是一個類型為浮點數的一個向量,長度為784,為啥是784了,那是因為我們的數據是28像素*28的圖,而28*28就是784.我們的神經網路,要將每一個像素變成一個輸入。

那這裡x又是為啥叫x,x是未知數的意思,而對於tensor-flow來說,未知的也就是原始的數據集,即輸入的MINST數據。那None又是什麼意思了,沒有,那就是不知道了,所以這裡的None指的是這裡申請的矩陣長度不確定,寬為784.

W = tf.Variable(tf.zeros([784,10]))

b = tf.Variable(tf.zeros([10]))

如果你要的是可以變化的值,那麼在設置tensor-flow的時候,就需要設置為變數variable,這裡變數的命名是有學問的,w是weight的縮寫,b是bias的縮寫,我覺得要想代碼可讀,命名最好要寫完整點的。

你也許會問,這裡784我懂,那10又是為啥了?這裡的10指代的是從784個像素中選取10個特徵值,每一位對應不同數字類。

接下來的一步是畫龍點睛的一步,也就是告訴tensor-flow上面定義好的到底要怎麼連接起來

y = tf.nn.softmax(tf.matmul(x,W) + b)

這句有點複雜,我們先從括弧最裡面看起,tf.matmul(X,W)表示x乘以W,matmul分開就是matrix multiplication的意思,再將這一步得到的特徵值加上bias,作為softmax函數的輸入。

這裡的softmax可以看成是一個激勵(activation)函數或是鏈接(link)函數,把我們定義的線性函數的輸出轉換成我們想要的格式,也就是關於10個數字類的概率分布.因此,給定一張圖片,它對於每一個數字的吻合度可以被softmax函數轉換成為一個概率值.softmax函數可以定義為:

softmax(x) = normalize(exp(x))

Normalize,翻譯出來就是標準化,就是保證各個softmax的值加起來為一,而要做到這個,就需要除以各個值指數化後的加和。

這些都搞不懂,那沒關係,tensor-flow會給你搞定,而且不管是用CPU還是GPU,你都不用操心,tensor-flow作為一門高級語言,可以以靈活的方式來描述其他各種數值計算,一旦被定義好之後,我們的模型就可以在不同的設備上運行。

下面要確定的是該怎麼定義要優化的值,也就是神經網路要學習的是什麼,這裡要引入交叉熵的概念,比較粗糙的理解是,交叉熵是用來衡量我們的預測用於描述真相的低效性.要想學好深度學習,最好要深入理解交叉熵,這個我們會在之後的課程中詳細來講這個概念。

y = tf.placeholder("float", [None,10])

這裡新定義的佔位符長度位置,寬度為10,是我們要是我們預測的概率分布,下一句有點複雜

cross_entropy = tf.reduce_sum(y_*tf.log(y))

還是從括弧最裡面來看,這裡y_*tf.log(y)中後一項是tensor-flow計算出的概率分布,前一項是實際的上各個圖形屬於那個數字的概率分布。而這就是交叉熵公式中Sum中的部分。將其作為reduce_sum的輸入,這個函數計算(tensor)張量的所有元素的總和。

值得強調的是,值得注意的是,這裡的交叉熵不僅僅用來衡量單一的一對預測和真實值,而是所有100幅圖片的交叉熵的總和.對於100個數據點的預測表現比單一數據點的表現能更好地描述我們的模型的性能。這也是為啥定義佔位符y時將其長度設為None, 未知的原因。

現在我們知道我們需要我們的模型做什麼啦,用TensorFlow來訓練它是非常容易的.因為TensorFlow擁有一張描述你各個計算單元的圖,它可以自動地使用反向傳播演算法(backpropagation algorithm)來有效地確定你的變數是如何影響你想要最小化的那個成本值,也就是我們之前說的交叉熵.然後,TensorFlow會用你選擇的優化演算法來不斷地修改變數以降低成本.

train_step = tf.train.GradientDescentOptimizer(0.01).minimize(

cross_entropy)

這裡給定要用的優化演算法是最常見的梯度下降。這是一個簡單的學習過程,TensorFlow只需將每個變數一點點地往使成本不斷降低的方向移動.當然TensorFlow也提供了其他許多優化演算法:只要簡單地調整一行代碼就可以使用其他的演算法.

TensorFlow在這裡實際上所做的是,它會在後台給描述你的計算的那張圖裡面增加一系列新的計算操作單元用於實現反向傳播演算法和梯度下降演算法。當運行這個操作時,它用梯度下降演算法訓練你的模型,微調你的變數,也就是要學習的weight和bias,以達到不斷減少交叉熵的目的,最終提高判斷的準確度。

現在,我們已經設置好了我們的模型.在運行計算之前,我們需要添加一個操作來初始化我們創建的變數:就是這一句了

init = tf.initialize_all_variables()

圖的框架畫完了,找一個session,相當於將畫裝裱起來,然後run起來,tensor flow就幫你實現例如反向傳播演算法,梯度下降等的細節了。

sess = tf.Session()

sess.run(init)

開始訓練模型,這裡我們讓模型循環訓練1000次!隨機抓取訓練數據中的100個批處理數據點,然後我們用這些數據點作為參數替換之前的佔位符來運行train_step

foriin range(1000):

batch_xs, batch_ys = mnist.train.next_batch(100)

sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})

我們的模型性能如何呢?

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))

tf.argmax(y,1)是模型認為每個輸入最有可能對應的那些標籤,而tf.argmax(y_,1)代表正確的標籤.我們可以用tf.equal來檢測我們的預測是否真實標籤匹配.

accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

這一行將上一行得出的類似[True, False, True, True]會變成[1,0,1,1],取平均值後得到0.75 .

最後,我們計算所學習到的模型在測試數據集上面的正確率.

print sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.

test.labels})

最終結果值應該大約是91%。

總結一下,TensorFlow是一個以圖(graphs)來表示計算的編程系統,圖中的節點被稱之為op (operation 的縮寫).一個op獲得零或多個張量(tensors)執行計算,產生零或多個張量。 張量是一個按類型劃分的多維數組。

TensorFlow編程可按兩個階段組織起來:構建階段和執行階段;前者用於組

織計算圖,而後者利用session中執行計算圖中的op操作。

構建過程完成後就可運行執行過程。為了載入之前所構建的圖,必須先創建一個

會話對象(Session object)。會話構建器在未指明參數時會載入默認的圖。

TensorFlow事實上通過一個「翻譯」過程,將定義的圖轉化為不同的可用計算資源間實現分布計算的操作,如CPU或是顯卡GPU。

課後作業

難度1星

利用python的函數,按照圖的構建,圖的參數設置,圖的執行,以及效果評價,將上面提到的程序改成由4個函數組成的程序。

難度2星

改變訓練集的個數,將訓練集,測試集,驗證集的個數等比例縮小為之前的25%,50%,75%,在其他條件不變的情況下,記錄程序所消耗的時間以及預測準確度,給出相應的折現圖。

難度3星

我們將0 4 6 8 9 這5個數字定義為有封閉空間的數字, 將 1 2 3 5 7定義為沒有封閉空間的數字,修過程序,做出儘可能少的改變,讓你的神經網路能夠學習到數字是否包含封閉空間這個概念,並給出預測的準確度。

推薦閱讀:

TAG:深度学习DeepLearning | TensorFlow |