深度學習基礎 - 基於Theano-MLP的字元識別實驗(MNIST)
深度學習基礎 - 基於Theano-MLP的手寫字元識別實驗
本文的完整程式碼託管在我的Github PY131/Practice-of-Machine-Learning,歡迎訪問。
基礎知識
深度學習回顧
深度學習的概念起源於人工神經網路,本文所採用的包含多隱層的多層感知機(MLP)就是其中的典型模型。長期以來,由模型複雜度所帶來的計算效率低下問題一直是抑制深度學習進一步發展的瓶頸。近年來,隨著大資料、雲端計算的興起以及進步的演算法設計,以“深度學習”為代表的大容量複雜模型開始突破其效率瓶頸,走向實用。深度學習正被愈發廣泛地應用於計算機視覺、語音識別、自然語言處理等領域,其所具備的強大學習能力已初現威力。
Theano簡介
Theano是一個基於python的科學計算框架,它在整合了numpy/scipy的基礎上,實現了對GPU的透明支援,theano常被用作深度學習的基礎框架。下面回顧theano的幾個基礎概念(核心概念):
- tensor variable(張量)
- theano function(theano函式)
- shared variable(共享變數)
- gradient(梯度)
基於MLP的字元識別模型
這裡我們採用簡單的單隱層MLP來實現,具體過程可參考:MNIST_Multilayer Perceptron。
這裡列出一些建模過程中所要注意的內容:
- 引數(連線權+偏置)的初始化區間需根據啟用函式而定;
- 此處面向分類問題,輸出層可採用softmax來獲得最終預測結果;
- 採用MSGD(塊隨機梯度下降)來加速尋優,注意mini-batch的size選取;
- 採用L1/L2正則化提升模型泛化能力,注意正則化引數的調節;
- …
實驗內容
資料集分析
這裡我採用規約好的MNIST資料集,相關內容可參考:Getting Started - Datasets - MNIST Dataset,資料集(mnist.pkl.gz)相關統計內容如下:
- 維度屬性:
資料集包含3個子資料集,對應train_set、valid_set、test_set,樣本規模分別為50000、10000、10000;
每條樣本包含:
輸入向量[1*784],對應輸入圖片灰度矩陣[28*28];
輸出值,對應圖片類別標籤(數字0-9);
- 完整度:
樣本完整;
- 平衡度:
未知;
- 更多資訊:
手寫字元所覆蓋的灰度已被人工調整到了圖片的中部。
根據上面的分析,在資料處理時需要對資料進行維度轉換。
下面是一些樣例圖片:
網路模型實現
首先給出基於python-theano程式設計實現MLP的步驟如下:
- 編寫模型訓練、驗證、測試函式體;
- 基於theano.function及python函式實現相關函式(sigmoid、tanh、MSGD、train_model、valid_model、test_model、),;
- 基於theano.shared初始化引數(連線權+偏置);
- 設定其他引數(隱層節點數、學習率、塊大小、迭代次數、正則化係數、早停引數等);
- 完善模型訓練、驗證、測試函式體;
其中訓練函式體的流程概述如下:
1. 載入資料,生成訓練集、驗證集、測試集;
2. 根據資料維度,生成對應的MLP網路結構;
3. 訓練模型,更新引數,實時記錄訓練誤差、分時記錄驗證誤差和測試誤差(泛化誤差);
4. 達到訓練停止條件(迭代次數、耐心指數),輸出模型與相關記錄資訊;
簡化的模型訓練程式塊樣例如下:完整程式
# 函式引數包括相關引數設定
def test_mlp(learning_rate=0.01, # 學習率 (等號右邊為預設值)
L1_reg=0.00, L2_reg=0.0001, # 正則化係數
n_epochs=1000, # 迭代次數
batch_size=20, # mini-batch大小
n_hidden=500, # 隱層節點數
dataset='mnist.pkl.gz' # 資料集
):
# 載入資料、獲取訓練集、驗證集、測試集
datasets = load_data(dataset)
train_set_x, train_set_y = datasets[0]
valid_set_x, valid_set_y = datasets[1]
test_set_x, test_set_y = datasets[2]
...
# 初始化MLP網路結構和引數
classifier = MLP(
rng=rng,
input=x,
n_in=28 * 28,
n_hidden=n_hidden,
n_out=10
)
# 生成“似然+正則化”損失函式體
cost = (
classifier.negative_log_likelihood(y)
+ L1_reg * classifier.L1
+ + L2_reg * classifier.L2_sqr
)
# “模型測試”函式體
test_model = theano.function(...)
# “模型驗證”函式體
validate_model = theano.function(...)
# “梯度計算”函式體
gparams = [T.grad(cost, param) for param in classifier.params]
# “引數更新”機制
updates = [
(param, param - learning_rate * gparam)
for param, gparam in zip(classifier.params, gparams)
]
# 訓練函式體
train_model = theano.function(...)
###############
# 模型訓練主體 #
###############
# 早停機制設計
...
# 迭代主體
while (epoch < n_epochs) and (not done_looping):
epoch = epoch + 1
# 一個塊的迭代訓練
for minibatch_index in range(n_train_batches):
# 一條樣本迭代訓練(前向計算、基於梯度的引數更新)
train_outputs = train_model(minibatch_index)
# 訓練損失計算
minibatch_avg_cost = train_outputs[0]
# 驗證塊
# 達到驗證所要求迭代次數 - 進行驗證
validation_losses = [validate_model(i) for i in range(n_valid_batches)] # 計算0-1損失
this_validation_loss = numpy.mean(validation_losses) # 平均驗證誤差計算
# 記錄最優資訊
...
# 是否達到測試所要求條件 - 進行測試
test_losses = [test_model(i) for i in range(n_test_batches)] # 計算0-1損失
test_score = numpy.mean(test_losses) # 測試誤差計算
...
# 早停判斷
...
...
# 過程資訊反回
return err_train, err_valid, err_test
實驗結果分析
通過合適的引數設定,記錄訓練過程中的訓練誤差(每iteration記錄一次),驗證誤差(每epoch記錄一次),測試誤差(當驗證精度提高時計算一次),得出三種誤差的收斂曲線如下圖示:
最終的分類結果如下:
Optimization complete. Best validation score of 1.880000 % (驗證誤差結果)
obtained at iteration 2077500, with test performance 1.840000 % (測試誤差結果)
而整個程式執行時間為:
The code for file MLP.py ran for 68.32m (分鐘)
我們可以對結果作如下分析:
- 這裡的MLP模型在當前引數和軟硬體條件下下,採用了一個多小時(略長)的引數訓練,得到了小於2%的誤差精度,一方面說明了神經網路模型的龐大計算量,另一方面說明了該模型的出色效果。
- 誤差曲線在較早時就已經趨向於穩定,說明當前結構和引數下模型精度已經難再提升。
- 神經網路模型的引數設定,有時會對訓練過程和最終效果產生重要影響,比如這裡的學習率、L1/L2正則化係數、隱層規模、mini-batch規模等。
總結
這裡採用python-theano實現了一個簡單的多層感知機網路,並基於MNIST手寫字元資料集實現了分類實驗。
在這個過程中,我們回顧了神經網路的基礎知識,練習了theano計算框架的使用,採用了相關輔助方法來優化訓練,為後面開展“深度學習”研究積累了經驗。
通過實驗我們看到,一方面,神經網路模型訓練往往伴隨著巨大的計算量,相關引數設定也需要謹慎考慮並結合實驗結果科學調整;另一方面,通過大量訓練所得到的神經網路模型能夠表現出優異的效能。
參考資料
相關重要參考列出如下:
核心參考:
- 基礎知識:Introduction to Multi-Layer Perceptrons (Feedforward Neural Networks)
- 教程參考:Multilayer Perceptron
- 教程參考:General: MNIST - CNN example
其他參考:
相關文章
- 深度學習例項之基於mnist的手寫數字識別深度學習
- 實戰 | 基於深度學習模型VGG的影象識別(附程式碼)深度學習模型
- Pytorch 手寫數字識別 深度學習基礎分享PyTorch深度學習
- Action Recognition——基於深度學習的動作識別綜述深度學習
- 【實戰】基於OpenCV的水錶字元識別(OCR)OpenCV字元
- [OpenCV實戰]1 基於深度學習識別人臉性別和年齡OpenCV深度學習
- 深度學習基礎深度學習
- 基於pytorch的深度學習實戰PyTorch深度學習
- 基於TensorFlow的深度學習實戰深度學習
- 【機器學習基礎】關於深度學習的Tips機器學習深度學習
- 基於PaddlePaddle的詞向量實戰 | 深度學習基礎任務教程系列深度學習
- 基於深度學習的機器人目標識別和跟蹤深度學習機器人
- 深度學習基礎-基於Numpy的卷積神經網路(CNN)實現深度學習卷積神經網路CNN
- 基於PaddlePaddle的詞向量實戰 | 深度學習基礎任務教程系列(二)深度學習
- 深度學習--RNN基礎深度學習RNN
- TrOCR:基於Transformer的新一代光學字元識別ORM字元
- 使用深度學習進行基於AI的面部識別的不同方法深度學習AI
- 基於PaddlePaddle的影象分類實戰 | 深度學習基礎任務教程系列(一)深度學習
- 基於PaddlePaddle的影像分類實戰 | 深度學習基礎任務教程系列(一)深度學習
- 基於PaddlePaddle的圖片分類實戰 | 深度學習基礎任務教程系列深度學習
- 【機器學習基礎】神經網路/深度學習基礎機器學習神經網路深度學習
- 深度學習及pytorch基礎深度學習PyTorch
- 深度學習基礎之 Dropout深度學習
- DL-深度學習基礎深度學習
- 基於深度學習網路的寶石型別識別演算法matlab模擬深度學習型別演算法Matlab
- 基於深度學習的手勢識別系統(Python程式碼,UI介面版)深度學習PythonUI
- 基於深度學習的人臉性別識別系統(含UI介面,Python程式碼)深度學習UIPython
- 動手學深度學習需要這些數學基礎知識深度學習
- 基於二哈實現多人人臉學習和識別
- 深度學習實驗:Softmax實現手寫數字識別深度學習
- Android基礎知識學習Android
- 基於python+深度學習構建驗證碼識別服務系列文章 第一章Python深度學習
- 【深度學習-基於Tensorflow的實戰】公開課實況深度學習
- 基於CPU的深度學習推理部署優化實踐深度學習優化
- 基於深度學習的場景文字檢測和識別(Scene Text Detection and Recognition)綜述深度學習
- 基於深度學習的影像分割在高德的實踐深度學習
- 大眾點評搜尋基於知識圖譜的深度學習排序實踐深度學習排序
- matlab實現人臉識別(數學基礎原理)Matlab
- HTML 基礎知識(特殊字元的轉義)HTML字元