1. 程式人生 > >Tensorflow-MNIST入門例項

Tensorflow-MNIST入門例項

MNIST是一個簡單的計算機視覺資料集。 它由像這樣的手寫數字的影象組成:
MNIST資料集
它還包括每個影象的標籤,告訴我們是哪個數字。 例如,上述影象的標籤是5,0,4和1。我們將訓練一個模型來檢視影象並預測它們的數字。

MNIST資料分為三部分:訓練資料(mnist.train)55,000個數據點,10,000點測試資料(mnist.test)和5,000點驗證資料(mnist.validation)。每個MNIST資料點都有兩部分:手寫數字的影象和相應的標籤。 我們稱影象“x”和標籤“y”。 訓練集和測試集都包含影象及其相應的標籤; 例如,訓練影象是mnist.train.images,訓練標籤是mnist.train.labels。

每個影象是28畫素乘以28畫素。 我們可以把它解釋為一大批數字:

這裡寫圖片描述

我們可以把這個陣列變成一個28×28 = 784數字的向量。從這個角度來看,MNIST影象只是一個784維向量空間中的一個點。這樣我們就把mnist.train.images表示為一個形狀為[55000,784]的張量(n維陣列)。 第一個維度是影象列表中的索引,第二個維度是每個影象中每個畫素的索引。 對於特定影象中的特定畫素,張量中的每個條目是0和1之間的畫素強度。

這裡寫圖片描述

MNIST中的每個影象都具有相應的標籤,0到9之間的數字表示影象中繪製的數字。我們將要將我們的標籤稱為“one-hot vectors”。 一個one-hot vectors是其他維數為0,單個維度為1的向量。 在這種情況下,第n個數字將被表示為在第n維中為1的向量。 例如,3將是[0,0,0,1,0,0,0,0,0,0]。 因此,mnist.train.labels是一個[55000,10]的浮點陣列。

這裡寫圖片描述

Softmax Regressions建模:
我們知道MNIST中的每個影象都是零到九之間的手寫數字。所以給定的影象只有十個可能的東西可以。我們希望能夠看到一個影象,並給出它作為每個數字的概率。例如,我們的模型可能會看到一個9的圖片,並且有80%的人肯定它是一個9,但是給出5%的機會是8,並且有一點概率給所有其他人,因為它不是100%確定。這是一個經典的情況,其中softmax迴歸是一種自然,簡單的模型。 如果要將概率分配給幾個不同的東西之一的物件,softmax非常適合做這個事,因為softmax給出了一個0到1之間的值列表,加起來為1.即使在以後,當我們訓練的模型更復雜,最後一步也是softmax層。

softmax迴歸有兩個步驟:首先,我們將輸入的evidence加在某些類中,然後將該evidence轉換為概率。

為了統計給定影象在特定類中的證據,我們進行畫素強度的加權和。 如果畫素是給該圖是該類所起貢獻是不利的證據,那麼權重是負的,如果是有利的證據則為正。

我們還增加了一些稱為偏置的額外證據。 基本上,我們希望能夠說一些事情更有可能獨立於輸入。The result is that the evidence for a class i given an input x is::
這裡寫圖片描述

通過softmax轉換為概率:
這裡寫圖片描述

這裡寫圖片描述
輸入為指數化,最後進行歸一化從而形成一個概率分佈。

我們可以把畫素看出x,對應的標籤看成y,首先搭建神經網路:
這裡寫圖片描述

寫成等式形式:
這裡寫圖片描述

我們可以“向量化”這個過程,把它變成矩陣乘法和向量加法:

這裡寫圖片描述

更緊湊和簡潔,我們可以寫:

這裡寫圖片描述

程式碼實現:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2017/7/10
# @Author  : yuquanle
# @Software: PyCharm

from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf

# 註冊一個預設的Session,之後的運算都跑在這個session裡面
sess = tf.InteractiveSession()
# 讀取資料,one_hot是10類表示的師0-9的10個數字
mnist = input_data.read_data_sets("MNIST_data", one_hot = True)
# 建立一個Placeholder,輸入資料的地方,引數(資料型別,tensor的shape),其中None表示不限制條數輸入,n表示n維向量
x = tf.placeholder(tf.float32, [None, 784])
# 初始化weight和biases全部初始化為0,模型訓練會選擇合適的值
w = tf.Variable(tf.zeros([784, 10]))
# 其中w的shape是[784,10],784為特徵數,10代表有10類,因為one_hot編碼後是10維向量
b = tf.Variable(tf.zeros([10]))
# tf.nn包含大量的神經網路的元件,tf.matmul是矩陣乘法
y = tf.nn.softmax(tf.matmul(x, w) + b)
# 定義一個模型分類的損失函式,損失越小,模型越準確
y_ = tf.placeholder(tf.float32, [None, 10])
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1])) # 一個資訊熵的計算
# 優化演算法,隨機梯度下降SGD,通過反向傳播進行訓練更新引數減少loss,學習速率0.5,優化目標就是定義的loss
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
# 使用全域性引數初始化器tf.global_variables_initializer,執行其run方法
tf.global_variables_initializer().run()

for i in range(1000):
    # 每次隨機從訓練集中抽取100條樣本構成一個mini_batch,並feed給placeholder
    batch_xs, batch_ys = mnist.train.next_batch(100)
    # 小樣本避免全域性樣本的區域性最優,以及速度問題,小樣本收斂速度越快
    train_step.run({x: batch_xs, y_: batch_ys})

# 對於模型的準確性驗證,tf,argmax尋找最大值的序號,tf.equal用於判斷是否分類到正確類別
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
# 統計全部樣本的精度,tf.cast將之前的correct_prediction輸出的bool值轉化為float32,再去求平均值
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(accuracy.eval({x:mnist.test.images, y_:mnist.test.labels}))

執行結果:
這裡寫圖片描述