1. 程式人生 > >TensorFlow入門之二:tensorflow手寫數字識別

TensorFlow入門之二:tensorflow手寫數字識別

一、基礎知識

基礎知識可以跳過,可以直接看後面的程式碼實現

MNIST資料集

MNIST資料集的官網是Yann LeCun’s website。可以使用下面的python程式碼自動下載資料集。

#已經下載input_data.py
#import input_data
#沒有下載input_data.py
from tensorflow.examples.tutorials.mnist import 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。

每一張圖片包含28畫素X28畫素。我們可以用一個數字陣列來表示這張圖片:

我們把這個陣列展開成一個向量,長度是 28x28 = 784。如何展開這個陣列(數字間的順序)不重要,只要保持各個圖片採用相同的方式展開。從這個角度來看,MNIST資料集的圖片就是在784維向量空間裡面的點, 並且擁有比較複雜的結構 (提醒: 此類資料的視覺化是計算密集型的)。

展平圖片的數字陣列會丟失圖片的二維結構資訊。這顯然是不理想的,最優秀的計算機視覺方法會挖掘並利用這些結構資訊,我們會在後續教程中介紹。但是在這個教程中我們忽略這些結構,所介紹的簡單數學模型,softmax迴歸(softmax regression),不會利用這些結構資訊。

一般的計算機視覺會先把影象轉為影象矩陣,然後再轉化為一維向量,處理圖片過程如下:

from PIL import Image
#開啟影象
image = Image.open("smallpi.jpg")
#轉化成灰度影象,這一步不是必須的,但為了效率一般都會處理
image_gray = image.convert("L") 
#Image物件轉化成影象矩陣
image_array = np.array(image_gray )
#flatten可以將矩陣轉化成一維序列
image_vectors = image_array.flatten()
#歸一化處理到0-1範圍內
image_vectors_float =
image_vectors/255

因此,在MNIST訓練資料集中,mnist.train.images 是一個形狀為 [60000, 784] 的張量,第一個維度數字用來索引圖片,第二個維度數字用來索引每張圖片中的畫素點。在此張量裡的每一個元素,都表示某張圖片裡的某個畫素的強度值,值介於0和1之間。

相對應的MNIST資料集的標籤是介於0到9的數字,用來描述給定圖片裡表示的數字。為了用於這個教程,我們使標籤資料是"one-hot vectors"。 一個one-hot向量除了某一位的數字是1以外其餘各維度數字都是0。所以在此教程中,數字n將表示成一個只有在第n維度(從0開始)數字為1的10維向量。比如,標籤0將表示成([1,0,0,0,0,0,0,0,0,0,0])。因此, mnist.train.labels 是一個 [60000, 10] 的數字矩陣。

我們可以通過下面的python程式碼檢視mnist這個資料集的情況:

print(mnist.train.images.shape, mnist.train.labels.shape)
print(mnist.test.images.shape, mnist.test.labels.shape)
print(mnist.validation.images.shape, mnist.validation.labels.shape)

其中mnist.train.images返回訓練集的圖片資訊,minist.test返回測試集的圖片資訊,mnist.validation.images返回測試集的圖片資訊。而labels就是圖片標籤:0-9shape就是矩陣資料的維度,比如 [[2,3],[3,5],[1,5]]通過shape運算就返回(3,2)。
以上執行結果為:

(55000, 784) (55000, 10)
(10000, 784) (10000, 10)
(5000, 784) (5000, 10)

Softmax迴歸

softmax用於多分類過程中,它將多個神經元的輸出,對映到(0,1)區間內,可以看成概率來理解,從而來進行多分類!
假設我們有一個數組,V,Vi表示V中的第i個元素,那麼這個元素的softmax值就是
s i = e i j e j s_i = \dfrac{e^i}{\sum_j e^j}
更形象的如下圖表示:

計算過程如下(用了四捨五入,保留2位有效數字):
y 1 = e z 1 j = 1 3 e z j = e z 1 e z 1 + e z 2 + e z 3 y_1=\dfrac{e^{z_1}}{\sum_{j=1}^3e^{z_j}}=\dfrac{e^{z_1}}{e^{z_1}+e^{z_2}+e^{z_3}} = e 3 e 3 + e 1 + e 3 = 20 20 + 2.7 + 0.05 = 0.88 =\dfrac{e^3}{e^3+e^1+e^{-3}} =\dfrac{20}{20+2.7+0.05}=0.88
y 2 = e z 2 j = 1 3 e z j = e z 2 e z 1 + e z 2 + e z 3 y_2=\dfrac{e^{z_2}}{\sum_{j=1}^3e^{z_j}}=\dfrac{e^{z_2}}{e^{z_1}+e^{z_2}+e^{z_3}} = e 1 e 3 + e 1 + e 3 = 2.7 20 + 2.7 + 0.05 = 0.12 =\dfrac{e^1}{e^3+e^1+e^{-3}} =\dfrac{2.7}{20+2.7+0.05}=0.12
y 3 = e z 3 j = 1 3 e z j = e z 3 e z 1 + e z 2 + e z 3 y_3=\dfrac{e^{z_3}}{\sum_{j=1}^3e^{z_j}}=\dfrac{e^{z_3}}{e^{z_1}+e^{z_2}+e^{z_3}} =