TensorFlow MNIST初级学习
2019獨角獸企業重金招聘Python工程師標準>>>
MNIST
MNIST 是一個入門級計算機視覺數據集,包含了很多手寫數字圖片,如圖所示:
數據集中包含了圖片和對應的標注,在 TensorFlow 中提供了這個數據集,我們可以用如下方法進行導入:
from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets('MNIST_data/', one_hot=True) print(mnist)輸出結果如下:
Extracting MNIST_data/train-images-idx3-ubyte.gzExtracting MNIST_data/train-labels-idx1-ubyte.gzExtracting MNIST_data/t10k-images-idx3-ubyte.gzExtracting MNIST_data/t10k-labels-idx1-ubyte.gzDatasets(train=<tensorflow.contrib.learn.python.learn.datasets.mnist.DataSet object at 0x101707ef0>, validation=<tensorflow.contrib.learn.python.learn.datasets.mnist.DataSet object at 0x1016ae4a8>, test=<tensorflow.contrib.learn.python.learn.datasets.mnist.DataSet object at 0x1016f9358>)在這里程序會首先下載 MNIST 數據集,然后解壓并保存到剛剛制定好的 MNIST_data 文件夾中,然后輸出數據集對象。
數據集中包含了 55000 行的訓練數據集(mnist.train)、5000 行驗證集(mnist.validation)和 10000 行的測試數據集(mnist.test),文件如下所示:
正如前面提到的一樣,每一個 MNIST 數據單元有兩部分組成:一張包含手寫數字的圖片和一個對應的標簽。我們把這些圖片設為 xs,把這些標簽設為 ys。訓練數據集和測試數據集都包含 xs 和 ys,比如訓練數據集的圖片是 mnist.train.images ,訓練數據集的標簽是 mnist.train.labels,每張圖片是 28 x 28 像素,即 784 個像素點,我們可以把它展開形成一個向量,即長度為 784 的向量。
所以訓練集我們可以轉化為 [55000, 784] 的向量,第一維就是訓練集中包含的圖片個數,第二維是圖片的像素點表示的向量。
Softmax
Softmax 可以看成是一個激勵(activation)函數或者鏈接(link)函數,把我們定義的線性函數的輸出轉換成我們想要的格式,也就是關于 10 個數字類的概率分布。因此,給定一張圖片,它對于每一個數字的吻合度可以被 Softmax 函數轉換成為一個概率值。Softmax 函數可以定義為:
展開等式右邊的子式,可以得到:
比如判斷一張圖片中的動物是什么,可能的結果有三種,貓、狗、雞,假如我們可以經過計算得出它們分別的得分為 3.2、5.1、-1.7,Softmax 的過程首先會對各個值進行次冪計算,分別為 24.5、164.0、0.18,然后計算各個次冪結果占總次冪結果的比重,這樣就可以得到 0.13、0.87、0.00 這三個數值,所以這樣我們就可以實現差別的放縮,即好的更好、差的更差。
如果要進一步求損失值可以進一步求對數然后取負值,這樣 Softmax 后的值如果值越接近 1,那么得到的值越小,即損失越小,如果越遠離 1,那么得到的值越大。
實現回歸模型
首先導入 TensorFlow,命令如下:
import tensorflow as tf接下來我們指定一個輸入,在這里輸入即為樣本數據,如果是訓練集那么則是 55000 x 784 的矩陣,如果是驗證集則為 5000 x 784 的矩陣,如果是測試集則是 10000 x 784 的矩陣,所以它的行數是不確定的,但是列數是確定的。
所以可以先聲明一個 placeholder 對象:
x = tf.placeholder(tf.float32, [None, 784])這里第一個參數指定了矩陣中每個數據的類型,第二個參數指定了數據的維度。
接下來我們需要構建第一層網絡,表達式如下:
這里實際上是對輸入的 x 乘以 w 權重,然后加上一個偏置項作為輸出,而這兩個變量實際是在訓練的過程中動態調優的,所以我們需要指定它們的類型為 Variable,代碼如下:
w = tf.Variable(tf.zeros([784, 10]))b = tf.Variable(tf.zeros([10]))接下來需要實現的就是上圖所述的公式了,我們再進一步調用 Softmax 進行計算,得到 y:
y = tf.nn.softmax(tf.matmul(x, w) + b)通過上面幾行代碼我們就已經把模型構建完畢了,結構非常簡單。
損失函數
為了訓練我們的模型,我們首先需要定義一個指標來評估這個模型是好的。其實,在機器學習,我們通常定義指標來表示一個模型是壞的,這個指標稱為成本(cost)或損失(loss),然后盡量最小化這個指標。但是這兩種方式是相同的。
一個非常常見的,非常漂亮的成本函數是“交叉熵”(cross-entropy)。交叉熵產生于信息論里面的信息壓縮編碼技術,但是它后來演變成為從博弈論到機器學習等其他領域里的重要技術手段。它的定義如下:
y 是我們預測的概率分布, y_label 是實際的分布,比較粗糙的理解是,交叉熵是用來衡量我們的預測用于描述真相的低效性。
我們可以首先定義 y_label,它的表達式是:
y_label = tf.placeholder(tf.float32, [None, 10])接下來我們需要計算它們的交叉熵,代碼如下:
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_label * tf.log(y), reduction_indices=[1]))首先用 reduce_sum() 方法針對每一個維度進行求和,reduction_indices 是指定沿哪些維度進行求和。
然后調用 reduce_mean() 則求平均值,將一個向量中的所有元素求算平均值。
這樣我們最后只需要優化這個交叉熵就好了。
所以這樣我們再定義一個優化方法:
train = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)這里使用了 GradientDescentOptimizer,在這里,我們要求 TensorFlow 用梯度下降算法(gradient descent algorithm)以 0.5 的學習速率最小化交叉熵。梯度下降算法(gradient descent algorithm)是一個簡單的學習過程,TensorFlow 只需將每個變量一點點地往使成本不斷降低的方向移動即可。
運行模型
定義好了以上內容之后,相當于我們已經構建好了一個計算圖,即設置好了模型,我們把它放到 Session 里面運行即可:
with tf.Session() as sess:sess.run(tf.global_variables_initializer())for step in range(total_steps + 1):batch_x, batch_y = mnist.train.next_batch(batch_size)sess.run(train, feed_dict={x: batch_x, y_label: batch_y})該循環的每個步驟中,我們都會隨機抓取訓練數據中的 batch_size 個批處理數據點,然后我們用這些數據點作為參數替換之前的占位符來運行 train。
這里需要一些變量的定義:
batch_size = 100total_steps = 5000測試模型
那么我們的模型性能如何呢?
首先讓我們找出那些預測正確的標簽。tf.argmax() 是一個非常有用的函數,它能給出某個 Tensor 對象在某一維上的其數據最大值所在的索引值。由于標簽向量是由 0,1 組成,因此最大值 1 所在的索引位置就是類別標簽,比如 tf.argmax(y, 1) 返回的是模型對于任一輸入 x 預測到的標簽值,而 tf.argmax(y_label, 1) 代表正確的標簽,我們可以用 tf.equal() 方法來檢測我們的預測是否真實標簽匹配(索引位置一樣表示匹配)。
correct_prediction = tf.equal(tf.argmax(y, axis=1), tf.argmax(y_label, axis=1))這行代碼會給我們一組布爾值。為了確定正確預測項的比例,我們可以把布爾值轉換成浮點數,然后取平均值。例如,[True, False, True, True] 會變成 [1, 0, 1, 1] ,取平均值后得到 0.75。
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))最后,我們計算所學習到的模型在測試數據集上面的正確率,定義如下:
steps_per_test = 100if step % steps_per_test == 0:print(step, sess.run(accuracy, feed_dict={x: mnist.test.images, y_label: mnist.test.labels}))這個最終結果值應該大約是92%。
這樣我們就通過完成了訓練和測試階段,實現了一個基本的訓練模型,后面我們會繼續優化模型來達到更好的效果。
運行結果如下:
0 0.453100 0.8915200 0.9026300 0.9081400 0.9109500 0.9108600 0.9175700 0.9137800 0.9158900 0.91761000 0.91671100 0.91861200 0.92061300 0.91611400 0.92181500 0.91791600 0.9161700 0.91961800 0.92221900 0.9212000 0.92232100 0.92142200 0.91912300 0.92282400 0.92282500 0.92182600 0.91972700 0.92252800 0.92382900 0.92193000 0.92243100 0.91843200 0.92533300 0.92163400 0.92183500 0.92123600 0.92253700 0.92243800 0.92253900 0.92264000 0.92014100 0.91384200 0.91844300 0.92224400 0.924500 0.9244600 0.92344700 0.92194800 0.9234900 0.92545000 0.9218結語
本節通過一個 MNIST 數據集來簡單體驗了一下真實數據的訓練和預測過程,但是準確率還不夠高,后面我們會學習用卷積的方式來進行模型訓練,準確率會更高。
?
轉載于:https://my.oschina.net/u/3720876/blog/1595953
總結
以上是生活随笔為你收集整理的TensorFlow MNIST初级学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数组遍历 map()、forEach(
- 下一篇: python函数编程-偏函数partia