承接上篇 “信我,就一句話解釋神經網絡” ,接下來與大家分享機器學習世界裡的“hello,world”
背景:
MNIST是一個手寫數字的數據庫,該數據庫分為兩部分:手寫的圖片及其對應的標籤數字。在上一篇文章提到了,對於普通程序來說,很難定義“貓”。當然,圖片數字沒有瞄那麼困難。因為至少數字不會有不同的形態和種類。大體數字仍然要滿足一定的規律及形態。但是,由於是手寫的,書寫習慣及書寫位子不同,仍然給數字識別帶來困難。接下來我們將以機器學習的方法來識別該數據庫。
數據整理:
MNIST是一個簡單的手寫數字的數據庫,如下圖所示。同時MNIST 也包含了數字標籤,告訴我們每張圖片對應的數字,5,0,4,1。 那麼X就是每張圖片,y就是圖片對應的真實數字。
訓練樣本X:
MNIST數據庫包含了60000個手寫數字及其對應的標籤。單一手寫數字圖片是28*28像素,如下圖所示。
對於該圖片,我們的處理方式是將[28,28]的圖片拉平變成[784,1]的向量,換句話說此圖片有784個特徵值或者說是784維向量空間。
最終整個訓練樣本X就變成了[55000,784]的矩陣。
訓練樣本Y:
樣本數據庫的標籤是[5,0,4,1]。需要將其轉換為‘One-hot Vector’,如下圖分別代表著5,0,4,1. 此向量只有一個維度值為1,其他均為0.
例如對於數字5的向量是[0,0,0,0,0,1,0,0,0,0].
大家可能對於y為什麼要變成[0,0,0,0,0,0,0,1,0,0] 這種形式。 我個人理解是:如果仍然使用(0~9)作為y值,那麼沒有辦法有效分配 概率區間。比如[0,0,0,0,0,0,0,1,0,0] 這種形式只要計算每個元素的概率就行,各元素之間不會相互影響。但是對於(0~9):如果y_預測 算出來是0.5那麼怎麼劃分,如果算出來是-10000呢? 所以原來的y會受本身的數字屬性影響。
神經網絡結構:
神經網絡輸出層:
我們面對的問題是,輸入一張圖片需要判斷對應的數字。該問題可以轉化為一個概率問題,輸入一張圖片後,需要能夠計算出對應到10個選項的概率(0~9)。比如,模型輸入一張圖片後,可能判斷80%是9, 5%是8,剩餘的數字都有一些非常小的概率。
Softmax就是處理該問題的模型。Softmax能夠計算每個選項的概率,並且彙總概率為100%;
例如:在訓練前,圖片數字7,對應的Y_實際與 Y_預測
從概率上來說,Y_實際 代表的是100%概率是7
從概率上來說,Y_預測 代表的是每個數字的概率都是10%
Y_實際 = [0,0,0,0,0,0,0,0,1,0,0]
Y_預測 = [0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1]
強調下:在訓練前,輸出層輸出的數值並不重要,重要的是形式與Y_實際 一致
神經網絡輸入層:
神經網絡輸入層是由輸入對象決定的。因為MNIST的圖片有784個像素,所以輸入層有784的神經元。
隱藏層:
此次隱藏層為,全連接(Dense)層,每個神經元都與上一層及下一層的神經元相互連接。
至於神經元的作用已經在上一篇 “信我,就一句話解釋神經網絡” 提到。神經網絡隱藏層由於各個神經元相互連接,矩陣運算。使得其本身已經成為一個特別複雜的公式。
但是其本質是一個公式,該公式的輸出會受各個神經元參數的影響。
損失與訓練:
我們都已經知道:損失,其實指的是神經網絡輸出層結果與 實際數字標籤的差異。而訓練的目的就是縮小該差異。
那麼就MNIST來說,Y_預測與 Y_實際的差異是神經網絡預測的概率與樣本對應概率的差異。神經網絡在訓練前,有一個最基本的要求需要滿足,即神經網絡輸出層的格式需要與實際數字標籤的格式一致,如下:
Y_實際 = [0 , 0,0,0,0,0,0,0,1,0,0]
Y_預測 = [0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1]
在訓練結束後,以下是輸入數字圖片7,對應的神經網絡預測結果。大家能看到在第八個位子上(由於是0開始)的概率是99.67%
[0.000000754 0.000001885 0.000337282 0.002868271 0.000000039 0.000015610 0.000000001 0.996765610 0.000003079 0.000007443]
所以神經網絡訓練的目的就是縮小差異,縮小預測的概率與實際概率的差距。
訓練:
那麼訓練是如何實現的呢?(Gradient Descent 基礎版邏輯)
神經網絡搭建好之後,當輸入一張圖片後,神經網絡輸出結果其實取決於神經網絡的參數。所以,假設損失與 參數的關係如下圖:
那麼訓練的過程其實就是一個下山的過程。首先,找到切線;然後向下走一小步。
反向傳遞(Backpropagation),看神經網絡的資料必然會遇到這個單次,反向傳遞。通俗的理解,其實就是在我們訓練之初,存在很大差異。我們通過找該差異區間的切線,調整了神經網絡參數,使得差異值在切線方向下降一小步(下山)
下圖是訓練60000個樣本,4輪之後的差異值。
訓練結果:
最終該神經網絡的準確率達到97%,最後給大家展示下該神經網絡預測錯誤的幾個例子:
大家能看出來,實際上預測不準確的基本都是寫的並不規範的例子。比如第二個圖。
承接之前一篇 “信我,就一句話解釋神經網絡”,神經網絡就是一個巨複雜的公式。如果要訓練該公式達到分類(MNIST本質上是把圖片分成10類,那麼首先需要考慮到Y的形式,搭建整個神經網絡。然後將Y_預測 與 Y_實際的 GAP定義為損失值。 再根據樣本進行訓練。
本質上,該神經網絡最終是根據輸入的784個像素,計算出在【10,1】10維向量的概率分佈。該概率分佈計算的準確程度取決於幾個因素: 樣本數量是否足夠及離散、神經網絡結構及激勵函數、損失函數的定義及優化方程的定義 。
代碼實踐:
這麼複雜的東西。怎麼猜也得幾百行代碼吧。
最驚喜的地方就在這裡,整個神經網絡結構搭建(除初始數據整理,訓練及畫圖)真的只要10行代碼,,,就10行。意不意外,驚不驚喜。
閱讀更多 繁林林與機器學習 的文章