1. 程式人生 > >Tensorflow #1 祖傳例子 MNIST 手寫識別

Tensorflow #1 祖傳例子 MNIST 手寫識別

1 前語

最近想學習DL,但是發現沒有什麼好的入門的東西,最近方向一直比較迷茫,東做做西做做,現在又來這裡做Tensorflow了。

關於Tensorflow 1.0是如何安裝的,可以直接參照他的官方文件,我是裝在了Ubuntu 14.04 64bit上的,之前在12的版本上死活裝不上,這點留給大家參考,萬一你的也裝不上。14.04則可以完全按照官方的說明安裝。

Tensorflow目前不能直接在Windows上跑,所以先找個對應的系統吧。
安裝首先安裝依賴:

# Ubuntu/Linux 64-bit
$ sudo apt-get install python-pip python-dev

# Mac OS X
$ sudo easy_install pip $ sudo easy_install --upgrade six

然後從下面的版本中選擇一個安裝,只用選擇一個就可以,比如我選擇的是第一個,只用CPU,Python2.7,看自己情況了

# Ubuntu/Linux 64-bit, CPU only, Python 2.7
$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.10.0-cp27-none-linux_x86_64.whl

# Ubuntu/Linux 64-bit, GPU enabled, Python 2.7
# Requires CUDA toolkit 7.5 and CuDNN v5. For other versions, see "Install from sources" below. $ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.10.0-cp27-none-linux_x86_64.whl # Mac OS X, CPU only, Python 2.7: $ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-0.10
.0-py2-none-any.whl # Mac OS X, GPU enabled, Python 2.7: $ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/gpu/tensorflow-0.10.0-py2-none-any.whl # Ubuntu/Linux 64-bit, CPU only, Python 3.4 $ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.10.0-cp34-cp34m-linux_x86_64.whl # Ubuntu/Linux 64-bit, GPU enabled, Python 3.4 # Requires CUDA toolkit 7.5 and CuDNN v5. For other versions, see "Install from sources" below. $ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.10.0-cp34-cp34m-linux_x86_64.whl # Ubuntu/Linux 64-bit, CPU only, Python 3.5 $ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.10.0-cp35-cp35m-linux_x86_64.whl # Ubuntu/Linux 64-bit, GPU enabled, Python 3.5 # Requires CUDA toolkit 7.5 and CuDNN v5. For other versions, see "Install from sources" below. $ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.10.0-cp35-cp35m-linux_x86_64.whl # Mac OS X, CPU only, Python 3.4 or 3.5: $ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-0.10.0-py3-none-any.whl # Mac OS X, GPU enabled, Python 3.4 or 3.5: $ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/gpu/tensorflow-0.10.0-py3

選好版本後,根據你選擇的Python版本,使用對應的PIP進行安裝,這個可能要翻牆,或者改HOST,請自己動手解決,或者微博私信我給你HOST,這樣就可以直接下載

# Python 2
$ sudo pip install --upgrade $TF_BINARY_URL

# Python 3
$ sudo pip3 install --upgrade $TF_BINARY_URL

這樣基本就安裝完了,沒什麼問題就開啟python,試下匯入可以

import tensorflow

任務描述

這裡寫圖片描述
MNIST這個Demo感覺已經是遍地都是了,在這裡也是,就是最簡單的手寫數字識別,輸入理論上是一個寫了數字的影象作為測試資料,這裡測試資料轉化成的文字矩陣了(28*28=784 維),我們可以通過在python環境中執行如下程式碼自動獲取資料,程式碼執行完會在對應的資料夾儲存好資料,如果需要可以自定義地址:

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

MNIST的資料集,共有三部分:
55,000 points 訓練集 (mnist.train), 10,000 points 測試集 (mnist.test), 5,000 驗證集 (mnist.validation).

與之同時,由於其是一個有監督的學習任務,所以還有對應的標籤(也就是影象對應的真實數字),這部分位於(mnist.train.labels),標籤也是以one-hot的方式表示,即這個向量共有10維,第I個位1就是證明這個Label是I

好了,那麼我們任務很清楚了,就是儘可能的準確識別出正確的數字。

Softmax 迴歸

如果大家之前看過機器學習實戰那本書,會發現那裡的手寫數字識別直接使用了KNN去做的,那邊對於一個數字對應的向量,並沒有考慮其權重,都是直接聚類的。

而在Softmax迴歸當中,他首先並不是聚類的,而是計算概率後選擇概率最大的那個輸出。即假設我們有0-9的輸出,那麼softmax在模型學習後,對於每一個輸入,都會給出其是0-9中每一個數字的概率,且這個概率之和為0.

而我們要做的,就是從這裡面找一個概率最大的作為結果輸出。

這裡寫圖片描述

其中Softmax首先會構建一個“證據”,如上圖,即參考權重,即對應的位置下,相同Label取到1的情況,如果在某個位置,某個Label很容易是1(即有書寫的),那麼他的權重就是一個正值,如果是基本不會出現筆畫的那麼就是一個負值。
其實看上面的圖就很清楚了,紅色的對應負值,藍色的代表正值。

這裡寫圖片描述
假設用i代表第i個Label(數字),那麼上面的公式既可以表示為,根據輸入(x)而得到的第I個數字的證據是多大的。其中Wi是第I個Label的權重,j則表示對應維度的索引(如這裡一共784),而bi則是對應的偏置。
這裡寫圖片描述
而對應的輸出y,我們使用softmax方程來表示,而softmax的具體資訊如下
這裡寫圖片描述
等效於
這裡寫圖片描述

Action

我已經把需要做什麼東西,為什麼這麼做放到了程式碼註釋裡了,大家對著看就可以了,理論上結果應該是92%附近。

# -*- coding:utf-8 -*-  
# Noted by: @MebiuW sina weibo
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
#載入資料,如果不存在他會首先自動下載資料到指定的目錄
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
# X是一個Placeholder ,這個值後續再放入讓TF計算,這裡是一個784維,但是訓練數量不確定的(用None表示)的浮點值
x = tf.placeholder(tf.float32, [None, 784])
# 設定對應的權值和偏置的表示,Variable代表一個變數,會隨著程式的生命週期做一個改變
# 需要給一個初始的值,這裡都全部表示為0
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
# 這裡根據我們上面描述的,構件我們的模型,y是模型的輸出,matmul是矩陣乘法,公式請參見之前的
y = tf.nn.softmax(tf.matmul(x, W) + b)
# 這裡是儲存真是的Label,同樣是Placeholder,原理同X
y_ = tf.placeholder(tf.float32, [None, 10])
# 在機器學習的模型中,我們需要定義一個衡量模型好壞的方式,稱為代價函式(Cost Loss),這裡使用了交叉熵去衡量 reduce_sum 累加
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
#訓練的步驟,告訴tf,用梯度下降法去優化,學習率是0.5,目的是最小化交叉熵
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
# 到目前為止,我們已經定義完了所有的步驟,下面就需要初始化這個訓練步驟了,首先初始化所有變數(之前定義的變數)
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
#執行步驟1000次
for i in range(1000):
  #載入資料
  batch_xs, batch_ys = mnist.train.next_batch(100)
  #執行步驟,但是需要填入placeholder的值
  sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})
#進行模型的的衡量
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
#理論上應該是92%附近
print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))

參考