【人工智慧專案】mnist手寫體識別實驗及分析
本實驗採用的軟硬體實驗環境如表所示:
在windows作業系統下,採用基於tensorflow的keras的深度學習框架,對mnist進行訓練和測試。
採用keras的深度學習框架,keras是乙個專為簡單的神經網路組裝而設計的python庫,具有大量預先包裝的網路型別,包括二維和三維風格的卷積網路、短期和長期的網路以及更廣泛的一般網路。使用keras構建網路是直接的,keras在其api設計中使用的語義是面向層次的,網路組建相對直觀,所以本次選用keras人工智慧框架,其專注於使用者友好,模組化和可擴充套件性。
mnist(官方**)是非常有名的手寫體數字識別資料集。它由手寫體數字的和相對應的標籤組成,如:
mnist資料集分為訓練影象和測試影象。訓練影象60000張,測試影象10000張,每乙個代表0-9中的乙個數字,且大小均為28*28的矩陣。
資料預處理階段對影象進行歸一化處理,我們將中的這些值縮小到 0 到 1 之間,然後將其饋送到神經網路模型。為此,將影象元件的資料型別從整數轉換為浮點數,然後除以 255。這樣更容易訓練,以下是預處理影象的函式:務必要以相同的方式對訓練集和測試集進行預處理:
之後對標籤進行one-hot編碼處理:將離散特徵的取值擴充套件到了歐式空間,離散特徵的某個取值就對應歐式空間的某個點;機器學習演算法中,特徵之間距離的計算或相似度的常用計算方法都是基於歐式空間的;將離散型特徵使用one-hot編碼,會讓特徵之間的距離計算更加合理
# build mlp
model = sequential()
model.add(dense(units=256,
input_dim=784,
kernel_initializer='normal',
activation='relu'))
model.add(dense(units=128,
kernel_initializer='normal',
activation='relu'))
model.add(dense(units=64,
kernel_initializer='normal',
activation='relu'))
model.add(dense(units=10,
kernel_initializer='normal',
activation='softmax'))
model.summary()
# build lenet-5
model = sequential()
model.add(conv2d(filters=6, kernel_size=(5, 5), padding='valid', input_shape=(28, 28, 1), activation='relu')) # c1
model.add(maxpooling2d(pool_size=(2, 2))) # s2
model.add(conv2d(filters=16, kewww.cppcns.comrnel_size=(5, 5), padding='valid', activation='relu')) # c3
model.add(maxpooling2d(pool_size=(2, 2))) # s4
model.add(flatten())
model.add(dense(120, activation='tanh')) # c5
model.add(dense(84, activation='tanh')) # f6
model.add(dense(10, activation='softmax')) # output
model.summary()
模型訓練過程中,我們用到lenet-5的卷積神經網路結構。
第一層,卷積層
這一層的輸入是原始的影象畫素,lenet-5 模型接受的輸入層大小是28x28x1。第一卷積層的過濾器的尺寸是5x5,深度(卷積核種類)為6,不使用全0填充,步長為1。因為沒有使用全0填充,所以這一層的輸出的尺寸為32-5+1=28,深度為6。這一層卷積層引數個數是5x5x1x6+6=156個引數(可訓練引數),其中6個為偏置項引數。因為下一層的節點矩陣有有28x28個節點(神經元數量),每個節點和5x5=25個當前層節點相連,所以本層卷積層總共有28x28x6x(5x5+1)個連線。
第二層,池化層
這一層的輸入是第一層的輸出,是乙個28x28x6=4704的節點矩陣。本層採用的過濾器為2x2的大小,長和寬的步長均為2,所以本層的輸出矩陣大小為14x14x6。原始的lenet-5 模型中使用的過濾器和這裡將用到的過濾器有些許的差別,這裡不過多介紹。
第三層,卷積層
本層的輸入矩陣大小為14x14x6,使用的過濾器大小為5x5,深度為16。本層不使用全0填充,步長為1。本層的輸出矩陣大小為10x10x16。按照標準卷積層本層應該有5x5x6x16+16=2416個引數(可訓練引數),10x10x16x(5x5+1)=41600個連線。
第四層,池化層
本層的輸入矩陣大小是10x10x16,採用的過濾器大小是2x2,步長為2,本層的輸出矩陣大小為5x5x16。
第五層,全連線層
本層的輸入矩陣大小為5x5x16。如果將此矩陣中的節點拉成乙個向量,那麼這就和全連線層的輸入一樣了。本層的輸出節點個數為120,總共有5x5x16x120+120=48120個引數。
第六層,全連線層
本層的輸入節點個數為120個,輸出節點個數為84個,總共引數為120x84+84=10164個。
第七層,全連線層
lenet-5 模型中最後一層輸出層的結構和全連線層的結構有區別,但這裡我們用全連線層近似的表示。本層的輸入節點為84個,輸出節點個數為10個,總共有引數84x10+10=850個。
初始引數設定好之後開始訓練,每次訓練需要微調引數以得到更好的訓練結果,經過多次嘗試,最終設定引數為:
lenet-5的卷積神經網路對mnist資料集進行訓練,並採用上述的模型引數,進行10輪訓練,在訓練集上達到了95%的準確率
為了驗證模型的魯棒性,在上述最優引數下儲存在驗證集上效能最好的模型,在測試集上進行最終的測試,得到最終的準確率為:95.13%.
為了更好的分析我們的結果,這裡用混淆矩陣來評估我們的模型效能。在模型評估之前,先學習一些指標。
tp(true positive):將正類**為正類數,真實為0,**也為0fn(false negative):將正類**為負類數,真實為0程式設計客棧,**為1fp(false positive):將負類**為正類數, 真實為1,**為0。tn(true negative):將負類**為負類數,真實為1,**也為1混淆矩陣定義及表示含義:
混淆矩陣是機器學習中總結分類模型**結果的情形分析表,以矩陣形式將資料集中的記錄按照真實的類別與分類模型**的類別判斷兩個標準進行彙總。其中矩陣的行表示真實值,矩陣的列表示**值,下面以本次案例為例,看下矩陣表現形式,如下:
並與四層全連線層模型進行對比,全連線層的模型結構如下:
其結果如下:
總之,從結果上來看,最後經過不斷地引數調優最終訓練出了乙個分類正確率在95%左右的模型,並且通過實驗證明了模型具有很強的魯棒性。
對單張影象進行**:
本文通過對卷積神經網路的研究流程分析,提出了一套完整的卷積神經網路mnist手寫體識別流程並也將本文的數www.cppcns.com據集分類正確率提高到95%的水平;其次,本www.cppcns.com文構建的模型是具有普適性的,可以稍加改進就應用於不同的資料集進行特徵提取及分類。再次,本文在構建模型的過程中綜合考慮了計算資源和時間成本,構建的卷積神經網路模型在普通的個人筆記本上即可進行訓練,此外還增加了mlp感知器作為對比,從結果中看出卷積神經網路效果更好。綜合以上幾點來看,本文的研究具有現實可應用性,具有可推廣性,因而具有較高的實用價值!
Tensorflow MINIST手寫體識別
1 設計演算法來訓練模型 對於處理這種多分類任務,通常用softmax regression。工作原理就是對每一種類別估計乙個概率,然後取概率最大的類別作為模型的輸出結果。2 定義乙個loss function來描述模型對問題的分類精度 對多分類問題通常用cross entropy作為loss fu...
kaggle練習 手寫體識別
coding utf 8 created on sun apr 22 10 25 14 2018 author zhangsh import csv import numpy as np from sklearn.neighbors import kneighborsclassifier list ...
tensorflow 之手寫體識別
原因 由於tensorflow相對於caffe更加靈活,準備轉戰tensorflow,昨天看了下大概的基本函式,今天打算先跑跑簡單的例子 tensorflow的安裝太簡單了,一行 搞定,網上很多教程,不一一列出。想安裝固定tensorflow版本 pip install tensorflow gpu...