1. 程式人生 > >[機器學習] 3: TensorFlow練習+MNIST手寫資料集+softmax實驗(未完待續)

[機器學習] 3: TensorFlow練習+MNIST手寫資料集+softmax實驗(未完待續)

前言

MNIST是一個入門級的計算機視覺資料集,是NIST的一個子集,常被用於機器學習的入門實踐。 它包含各種手寫數字圖片,同時也包含每一張圖片對應的標籤,告訴我們這個是數字幾。比如,上面這四張圖片的標籤分別是5,0,4,1 在這裡插入圖片描述 本文目標是練習tensorflow使用方法,鞏固概念。 從較為簡單的softmax regression模型入手,熟悉後再嘗試更復雜的模型。 主要參考tensorflow的教程 www.tensorfly.cn

MNIST資料集下載

常見的程式碼是如下

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

但國內由於網路限制,經常出現無法成功下載的情況。

手動下載:Yann LeCun’s website官網 下載後,不要解壓,直接將4個檔案放在你的py檔案同目錄下的MNIST_data資料夾下。 在這裡插入圖片描述

訓練集:60000個訓練樣本 測試集:10000個測試樣本 數字已經規格化,並位於固定大小影象的中心,每一張圖片包含28X28個畫素點。 分為images影象,和labels標籤 在這裡插入圖片描述 將28 * 28的影象轉換為784(=28*28)維的向量。 這樣丟失了原有圖片的二維結構資訊,暫且不管(之後會用到)

mnist.train.images:[60000,784]張量 mnist.test.images: [10000,784]張量 每個元素,表示某圖片裡的某個畫素的強度值,值介於0和1之間

MNIST手寫數字識別的標籤是介於0到9的數字,用來描述給定圖片裡表示的數字。 標籤資料是"one-hot vectors"。( one-hot向量除了某一位的數字是1以外其餘各維度數字都是0) 所以,標籤為10維向量(0-9),且數字n的向量只在第n維度為1其餘為0。標籤0將表示成([1,0,0,0,0,0,0,0,0,0,0])

mnist.train.labels:[60000, 10] mnist.test.labels: [10000, 10]

Softmax Regression

  1. 我們知道MNIST的每一張圖片都表示一個數字,從0到9。我們希望得到給定圖片代表每個數字的概率. 對於包含9的圖片,模型可能給出 屬於9的概率所80%,屬於8的概率是7%,屬於0的概率…

這是一個使用softmax迴歸(softmax regression)模型的經典案例。softmax模型可以用來給不同的物件分配概率。即使在複雜的神經網路中,也常常最後使用softmax來分配概率。

如果這個畫素具有很強的證據說明這張圖片不屬於該類,那麼相應的權值為負數,相反如果這個畫素擁有有利的證據支援這張圖片屬於這個類,那麼權值是正數。如果這個畫素具有很強的證據說明這張圖片不屬於該類,那麼相應的權值為負數,相反如果這個畫素擁有有利的證據支援這張圖片屬於這個類,那麼權值是正數。

下面的圖片顯示了一個模型學習到的圖片上每個畫素對於特定數字類的權值。紅色代表負數權值,藍色代表正數權值。 在這裡插入圖片描述 我們也需要加入一個額外的偏置量(bias),因為輸入往往會帶有一些無關的干擾量。因此對於給定的輸入圖片 x 它代表的是數字 i 的證據可以表示為 在這裡插入圖片描述 其中Wi代表權重,bi代表數字 i 類的偏置量,j 代表給定圖片 x 的畫素索引用於畫素求和。然後用softmax函式可以把這些證據轉換成概率 y: 在這裡插入圖片描述 這裡的softmax可以看成是一個激勵(activation)函式或者連結(link)函式,把我們定義的線性函式的輸出轉換成我們想要的格式,也就是關於10個數字類的概率分佈。因此,給定一張圖片,它對於每一個數字的吻合度可以被softmax函式轉換成為一個概率值。softmax函式可以定義為: 在這裡插入圖片描述 展開等式右邊的子式,可以得到: 在這裡插入圖片描述

但是更多的時候把softmax模型函式定義為前一種形式:把輸入值當成冪指數求值,再正則化這些結果值。這個冪運算表示,更大的證據對應更大的假設模型(hypothesis)裡面的乘數權重值。反之,擁有更少的證據意味著在假設模型裡面擁有更小的乘數係數。假設模型裡的權值不可以是0值或者負值。Softmax然後會正則化這些權重值,使它們的總和等於1,以此構造一個有效的概率分佈。(更多的關於Softmax函式的資訊,可以參考Michael Nieslen的書裡面的這個部分,其中有關於softmax的可互動式的視覺化解釋。)

對於softmax迴歸模型可以用下面的圖解釋,對於輸入的xs加權求和,再分別加上一個偏置量,最後再輸入到softmax函式中: 在這裡插入圖片描述

如果把它寫成一個等式,我們可以得到: 在這裡插入圖片描述 我們也可以用向量表示這個計算過程:用矩陣乘法和向量相加。這有助於提高計算效率。(也是一種更有效的思考方式) 在這裡插入圖片描述 更進一步,可以寫成更加緊湊的方式: 在這裡插入圖片描述

實現Softmax迴歸模型

為了用python實現高效的數值計算,我們通常會使用函式庫,比如NumPy,會把類似矩陣乘法這樣的複雜運算使用其他外部語言實現。不幸的是,從外部計算切換回Python的每一個操作,仍然是一個很大的開銷。如果你用GPU來進行外部計算,這樣的開銷會更大。用分散式的計算方式,也會花費更多的資源用來傳輸資料。

TensorFlow也把複雜的計算放在python之外完成,但是為了避免前面說的那些開銷,它做了進一步完善。Tensorflow不單獨地執行單一的複雜計算,而是讓我們可以先用圖描述一系列可互動的計算操作,然後全部一起在Python之外執行。(這樣類似的執行方式,可以在不少的機器學習庫中看到。)

使用TensorFlow之前,首先匯入它:

我們通過操作符號變數來描述這些可互動的操作單元,可以用下面的方式建立一個:

x = tf.placeholder("float", [None, 784])

x不是一個特定的值,而是一個佔位符placeholder,我們在TensorFlow執行計算時輸入這個值。我們希望能夠輸入任意數量的MNIST影象,每一張圖展平成784維的向量。我們用2維的浮點數張量來表示這些圖,這個張量的形狀是[None,784 ]。(這裡的None表示此張量的第一個維度可以是任何長度的。)

我們的模型也需要權重值和偏置量,當然我們可以把它們當做是另外的輸入(使用佔位符),但TensorFlow有一個更好的方法來表示它們:Variable 。 一個Variable代表一個可修改的張量,存在在TensorFlow的用於描述互動性操作的圖中。它們可以用於計算輸入值,也可以在計算中被修改。對於各種機器學習應用,一般都會有模型引數,可以用Variable表示。

W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))

我們賦予tf.Variable不同的初值來建立不同的Variable:在這裡,我們都用全為零的張量來初始化W和b。因為我們要學習W和b的值,它們的初值可以隨意設定。

注意,W的維度是[784,10],因為我們想要用784維的圖片向量乘以它以得到一個10維的證據值向量,每一位對應不同數字類。b的形狀是[10],所以我們可以直接把它加到輸出上面。

現在,我們可以實現我們的模型啦。只需要一行程式碼!

y = tf.nn.softmax(tf.matmul(x,W) + b)

首先,我們用tf.matmul(​​X,W)表示x乘以W,對應之前等式裡面的,這裡x是一個2維張量擁有多個輸入。然後再加上b,把和輸入到tf.nn.softmax函式裡面。

至此,我們先用了幾行簡短的程式碼來設定變數,然後只用了一行程式碼來定義我們的模型。TensorFlow不僅僅可以使softmax迴歸模型計算變得特別簡單,它也用這種非常靈活的方式來描述其他各種數值計算,從機器學習模型對物理學模擬模擬模型。一旦被定義好之後,我們的模型就可以在不同的裝置上執行:計算機的CPU,GPU,甚至是手機!