1. 程式人生 > >Tensorflow學習筆記(三)

Tensorflow學習筆記(三)

此文章摘抄自Tensorflow中文社群,外加自己學習理解http://www.tensorfly.cn/

在我看來,TensorFlow作為以個用於深度學習的計算庫,已然是非常的強大,但是對於真正想去學習機器學習或者深度學習的人來說,反而成就了我們自己的懶惰,祝好,各位碼農!

執行TensorFlow的IntertiveSession

TensorFlow依賴於一個高效的C++後端來進行計算。與後端的這個連結叫做session。一般而言,使用TensorFlow程式的流程是先建立一個圖,然後在session中啟動它。
這裡,我們使用更加方便的InteractiveSession類。通過它,你可以更加靈活地構建你的程式碼。它能讓你在執行圖的時候,插入一些計算圖,這些計算圖是由某些操作(operation)構成的。這對於工作在互動環境中的人們來說非常便利,比如使用IPython。如果你沒有使用InteractiveSession,那麼你需要在啟動session之前構建整個計算圖,然後起訂該計算圖。

import tensorflow as tf
sess=tf.InteractiveSession()

計算圖

為了在Python中進行高效的數值計算。我們通常會使用像NumPy一類的庫,將一些諸如矩陣乘法的耗時操作在 Python環境的外部來計算,這些計算通常會通過其語言並用更為高效的程式碼實現。
因此Python程式碼的目的是用來構建這個可以在外部執行的計算圖,以及安排計算圖的哪一部分應該被執行。

構建Softmax迴歸模型

佔位符
我們通過為輸入影象和目標輸出類別建立節點,來開始構建計算圖。

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

這裡的x和y並不是特定的值,相反,他們都只是一個佔位符,可以在Tensorflow執行某一計算時根據該佔位符輸入具體的值。
輸入圖片x是一個2維的浮點數張量。這裡,分配給他的shape為[None,784],其中784是一張展平的MNIST圖片的維度。None表示其值大小不定,在這裡作為第一個維度值,用以指代batch的大小,意即x的數量不定。輸出類別值y_也是一個2維張量,其中每一行為一個10維的one-hot向量,用來代表對應某一MNIST圖片的類別。

變數
我們現在為模型定義權重w和偏置b。可以將他們當作額外的輸入量,但是TensorFlow有一個更好的處理方式:變數。一個變數代表著TensorFlow計算圖中的一個值,能夠在計算過程中使用,甚至進行修改。在機器學習的應用過程中,模型引數一般用Variable來表示。

w=tf.Variable(tf.zreos([784,10]))
b=tf.Variable(tf.zeros([10]))

我們在呼叫tf.Variable的時候傳入初始值。在這個例子裡,我們把w和b都初始化零向量。w是一個784*10的矩陣(因為我們有784個特徵和10個輸出值)。b是一個10維的向量(因為我們有10個分類)。

變數需要通過session初始化後,才能在session中使用。這一初始化步驟為,為初始值指定具體值(本例當中全是零),並將其分配給每個變數,可以一次性為所有變數完成此操作。(也就說變數要經過兩部的初始化,先用Variable進行初始化之後,再使用session初始化)

sess,run(tf.initialize_all_variables())

類別預測與損失函式

現在我們可以實現我們的迴歸模型了。我們把向量化後的圖片x和權重矩陣w相乘,加上偏置b,然後計算每個分類的softmax概率值。

y=tf.nn.sofemax(tf.matmul(x,w)+b)

可以很容易的為訓練過程指定最小化誤差用的損失函式,我們的損失函式是目標類別和預測類別之間的交叉熵。

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

訓練模型

我們已經定義好模型和訓練用的損失函式,那麼用TensorFlow進行訓練就很簡單了。因為TensorFlow知道整個計算圖,他可以使用自動微分法找到對於各個變數的損失的梯度值。TensorFlow有大量內建的優化演算法。這個例子中,我們用最快速下降法讓交叉熵下降,步長為0.01。

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

這一行程式碼實際上是用來往計算圖上新增一個新操作,其中包括計算梯度,計算每個引數的步長變化,並且計算出新的引數值。
返回的train_step操作物件,在執行時會使用梯度下降來更新引數,因此,整個模型的訓練可以通過反覆的執行train_step來完成。

for i in range(1000):
    batch=mnist.train.next_batch(50)
    train_step.run(feed_dict={x:batch[0],y_:batch[1]})

每一步迭代,我們都會載入50個訓練樣本,然後執行一次train_step,並通過feed_dict將x和y_張量佔位符用訓練資料代替。

評估模型

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))

這裡返回一個布林值。為了計算我們分類的準確率,我們將布林值轉換為浮點數來代表對、錯,然後取平均值。

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

構建一個多卷積網路

權重初始化
為了建立這個模型,我們需要建立大量的權重和偏置項。這個模型中的權重在初始化時應該加入少量的噪聲來打破對稱性一級避免0梯度。由於我們使用的是ReLU神經元,因此比較好的做法是用一個較小的正數來初始化偏置項,以避免神經元節點輸出恆為零的問題。為了不在建立模型的時候反覆做初始化操作,我們定義兩個函式用於初始化。

def weight_variable(shape):
     initial=tf.truncated_normal(shape,stddev=0.1)
     return tf.Variable(initial)

def bias