机器学习实战—手写体数字识别(基于MNIST)
什么是MNIST?
MNIST(官方網站)是非常有名的手寫體數字識別數據集,在Tensorflow的官方網站里,第一個就拿它來做實戰講解,咱們也以此作為開始的項目。它由手寫體數字的圖片和相對應的標簽組成,如:

MNIST數據集分為訓練圖像和測試圖像。訓練圖像60000張,測試圖像10000張,每一個圖片代表0-9中的一個數字,且圖片大小均為28*28的矩陣。
train-images-idx3-ubyte.gz: training set images (9912422 bytes) 訓練圖片
train-labels-idx1-ubyte.gz: training set labels (28881 bytes) 訓練標簽
t10k-images-idx3-ubyte.gz: test set images (1648877 bytes) 測試圖片
t10k-labels-idx1-ubyte.gz: test set labels (4542 bytes) 測試標簽
啟動虛擬環境
source activate <virtual env> # virtual env是你的環境名字
打開Jupyter Notebook
jupyter notebook
加載Tensorflow,導入數據
我們使用被封裝到tensorflow內部的MNIST數據
import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
創建變量(varaible)和占位符(placeholder)
占位符類似一個函數,使用時傳入參數值來使用。通俗來講就好像我去教室里貼個紙條說這個位子被占了,但是我可以選擇讓誰去做。在這里None代表著可以是任何數值。
x = tf.placeholder(tf.float32, [None, 784]) y_ = tf.placeholder(tf.float32, [None, 10])
在TensorFlow中,變量的參數用tf.Variable表示
# W是模型的參數,是一個784*10的矩陣將一個784維的輸入轉換為一個10維的輸出 W = tf.Variable(tf.zeros([784, 10])) # b是偏置項(bias)。 b = tf.Variable(tf.zeros([10])) # y=softmax(Wx + b),y表示模型的輸出 y = tf.nn.softmax(tf.matmul(x, W) + b)
softmax是個簡單的分類器,其結果是一個矩陣,分別代表著模型對于輸入數據的預測屬于各個分類的可能性。比如
[0.00, 0.01, 0.02, 0.01, 0.98, 0.01, 0.01, 0.00, 0.01, 0.02]
損失函數
損失函數是我們評價模型好壞的標準,我們優化模型的目標就是為了最小化損失函數,所以如何設定合理的損失函數是至關重要的。當然沒有統一通用的損失函數,因為不同的模型可能是為了達到不同的效果,比如有的為了提高平均準確率,有的為了得出最小離散率等等。在這個基本款的模型里,我們暫時只使用交叉熵作為損失函數。為了方便理解,我們使用數學表達式。同學們也可以使用Tensorflow封裝的函數:sparse_softmax_cross_entropy_with_logits
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y)))
參數優化
我們使用固定參數0.01,大家也可以試一試其他的參數值。我會在下一篇里提出這一步的優化方案以及解釋。
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
創建Session
sess = tf.InteractiveSession() # 創建一個Session tf.global_variables_initializer().run() # 初始化所有變量,分配內存。
進行梯度下降訓練,優化模型參數
我們每次取100個數據作為一個batch用來訓練參數,然后再取100個,共訓練1000次。將當前batch(100組數據)的圖片矩陣和標簽傳入占位符,并通過session運行train_step
# 分1000步梯度下降 for _ in range(1000): batch_x, batch_y = mnist.train.next_batch(100) sess.run(train_step, feed_dict={x: batch_x, y_: batch_y})
結果檢測
# 正確的預測結果 correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1)) # 計算預測準確率 accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) # 傳入測試數據集,獲取模型測試的正確率 print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))
對于模型的輸出值,我們的到是一個關于各個分類的可能性預測,比如
[0.00, 0.01, 0.02, 0.01, 0.98, 0.01, 0.01, 0.00, 0.01, 0.02]。所以我們使用tf.argmax(y, 1)之后得到的是最有可能的那個值,即4。
tf.equal返回的是boolean值,所以我們使用tf.cast將其轉換成float便于計算。
最終將測試數據集傳入占位符進行計算,得到最終結果。
鏈接:https://www.jianshu.com/p/a2c9d39d90c6
來源:簡書