Tensorflow框架載tensorflow.contrib.learn.python.learn.datasets包中提供多個機器學習的數據集。本節介紹的是MNIST數據集,其功能都定義在mnist.py模塊中。python
MNIST是一個入門級的計算機視覺數據集,它包含各類手寫數字圖片:web
圖 11 數組
它也包含每一張圖片對應的標籤,告訴咱們這個是數字幾。好比,上面這四張圖片的標籤分別是5,0,4,1網絡
有兩種方式能夠獲取MNIST數據集:框架
TensorFlow框架提供了一個函數:read_data_sets,該函數可以實現自動下載的功能。以下所示的程序,就可以自動下載數據集。機器學習
from tensorflow.examples.tutorials.mnist import input_data 函數 mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)性能 |
//因爲input_data只是對read_data_sets進行了包裝,其什麼也沒有作,因此咱們能夠直接使用read_data_sets. 學習 From tensorflow.contrib.learn.python.learn.datasets.mnist import read_data_sets 測試 Mnist=read_data_sets("MNIST_data",one_hot=True) |
用戶也可以手動下載數據集,而後向read_data_sets函數傳遞所在的本地目錄,以下所示:
from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets("/tmp/MNIST_data/", False, one_hot=True) |
PS:
MNIST數據集能夠Yann LeCun's website進行下載,如所示是下載後的目錄:/tmp/MNIST_data/
圖 12
自動下載方式的數據集被分紅如表 11所示的三部分。這樣的切分很重要,在機器學習模型設計時必須有一個單獨的測試數據集不用於訓練,而是用來評估這個模型的性能,從而更加容易把設計的模型推廣到其餘數據集上(泛化)。
表 11
數據集 |
目的 |
mnist.train |
55000 組圖片和標籤, 用於訓練。 |
mnist.test |
10000 組圖片和標籤, 用於最終測試訓練的準確性。 |
mnist.validation |
5000 組圖片和標籤, 用於迭代驗證訓練的準確性。 |
PS:
如果手動下載則只有兩部分,即表中的train和test兩部分。
正如前面提到的同樣,每個MNIST數據單元有兩部分組成:一張包含手寫數字的圖片和一個對應的標籤。咱們把這些圖片設爲"X",把這些標籤設爲"Y"。訓練數據集和測試數據集都包含X和Y,好比訓練數據集的圖片是 mnist.train.images ,訓練數據集的標籤是 mnist.train.labels。
其中每一張圖片包含28像素*28像素。咱們能夠用一個數字數組來表示這張圖片:
圖 13
TensorFlow把這個數組展開成一個向量(數組),長度是 28x28 = 784,即TensorFlow將一個二維的數組展開成一個一維的數組,從[28, 28]數組轉換爲[784]數組。所以,在MNIST訓練數據集中,mnist.train.images 是一個形狀爲 [60000, 784] 的張量,第一個維度數字用來索引圖片,第二個維度數字用來索引每張圖片中的像素點。在此張量裏的每個元素,都表示某張圖片裏的某個像素的灰度值,值介於0和1之間,如圖 14所示的二維結構。
圖 14
相對應的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] 的數字矩陣。
圖 15
傳統的M-P神經元模型中,每一個神經元都接收來自n個其它神經元傳遞過來的輸入信號,這些輸入信號經過待權重的鏈接進行傳遞,神經元接收到的總輸入值將與神經元的閾值進行比較,而後經過"激活函數"處理以產生神經元的輸出。如圖 21所示的一個神經元模型。
圖 21
PS:
圖中所示的值都爲real value,並不是爲向量或矩陣。
softmax函數與sigmoid函數相似均可以做爲神經網絡的激活函數。sigmoid將一個real value映射到(0,1)的區間(固然也能夠是(-1,1)),這樣能夠用來作二分類。
而softmax把一個k維的real value向量[a1,a2,a3,a4….]映射成一個[b1,b2,b3,b4….],其中bi是一個0-1的常數,而後能夠根據bi的大小來進行多分類的任務,如取權重最大的一維。
因此對於MNIST分類任務是多分類類型,因此須要使用softmax函數做爲神經網絡的激活函數。
正如圖 14所分析的,輸入的訓練圖片或測試圖片爲一個[60000, 784]的矩陣,每張圖片都是一個[784]的向量;輸出爲一個[60000, 10]的矩陣,每張圖片都對應有一個[10]的向量標籤。因此對於每張圖片的輸入和每一個標籤的輸出,其神經網絡模型可表示爲錯誤! 未找到引用源。所示的簡化版本,圖中全部值都爲read value。
圖 22 前饋神經網絡(一個帶有10個神經元的隱藏層)
若是把它寫成一個等式,咱們能夠獲得:
咱們也能夠用向量表示這個計算過程:用矩陣乘法和向量相加。這有助於提升計算效率。(也是一種更有效的思考方式)
更進一步,能夠寫成更加緊湊的方式:
式中, B和Y都爲一個[10]類型的向量,X爲一個[784]類型的向量,W是一個[10,784]類型的矩陣。
對於機器學習中的監督學習任務能夠分四個步驟完成,以下所示:
因爲咱們已經選擇神經網絡爲監督學習任務的模型,即式(3)所示的等式,咱們可經過使用下標來代表等式中變量的維數,以下所示:
因此在TensorFlow中的實現,就須要定義相應的變量和等式。可是式(4)中的X是一個[784]的向量,而實際待訓練的輸入數據是一個[60000, 784] 的矩陣,因此須要對式(4)進行稍微的變形,使其知足數據輸入和數據輸出的要求,即以下所示的等式:
以下所示是TensorFlow的實現:
# Create the model x = tf.placeholder("float", [None, 784]) W = tf.Variable(tf.zeros([784,10])) b = tf.Variable(tf.zeros([10])) y = tf.nn.softmax(tf.matmul(x,W) + b) |
咱們能夠建立一個模型(model),但咱們仍然不知道模型的好壞。爲了評估一個TensorFlow模型的性能,咱們能夠提供一個指望值,而後比較模型產生值和指望值之差來進行評估。
傳統方法採用"均分偏差"法評估一個模型的性能:,首先提供一個指望向量,而後對產生值(f(x))和指望值(y)兩個向量的每一個元素進行取平方差,而後求出每一個元素的總和。
因爲傳遞神經網絡採用梯度降低法來逐漸調整式(4)中的W和B參數,即逐步減小均分偏差的值;然而若以"均分偏差"爲標準逐步調整參數,其歸約的速度很是慢。因此提出以"交叉熵"法爲標準評估模型的值,以下所示:
以下所示的TensorFlow實現:
# Define loss and optimizer y_ = tf.placeholder("float", [None,10]) cross_entropy = -tf.reduce_sum(y_ * tf.log(y)) |
TensorFlow提供多個優化器來逐步優化模型,即逐步優化未知參數。優化器以用戶指定的評估的偏差爲優化目標,即最小化模型評估的偏差,或最大化模型評估的偏差。
優化器基於梯度降低法自動修改神經網絡的訓練參數,即W和b的值。
以下是以GradientDescentOptimizer優化器爲示例的訓練過程:
# Train train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy) 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}) |
爲了評估模型的泛化性能,咱們經過比較產生值(f(x))和指望值(y)之間的差別來進行評測性能。
因爲本節的MNIST數據標籤(輸出值)是一個one-hot的便利,向量中的元素直郵一個爲"1",因此使用特性的比較方式,以下所示是TensorFlow的實現:
# Test trained model correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels})) |
其中:
上述三個小節的完整程序以下所示:
from __future__ import print_function import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data
# Import data mnist = input_data.read_data_sets("/tmp/MNIST_data/", False, one_hot=True)
# Create the model x = tf.placeholder("float", [None, 784]) W = tf.Variable(tf.zeros([784,10])) b = tf.Variable(tf.zeros([10])) y = tf.nn.softmax(tf.matmul(x,W) + b)
# Define loss and optimizer y_ = tf.placeholder("float", [None,10]) cross_entropy = -tf.reduce_sum(y_ * tf.log(y)) train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
init = tf.initialize_all_variables() sess = tf.Session() sess.run(init)
# Train 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})
# Test trained model #下述y的值是在上述訓練最後一步已經計算得到,因此可以與原始標籤y_進行比較 correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels})) |