MXNet學習-第一個例子:訓練MNIST數據集


一個門外漢寫的MXNET跑MNIST的例子,三層全連接層最后驗證率是97%左右,畢竟是第一個例子,主要就是用來理解MXNet怎么使用。

#導入需要的模塊
import numpy as np #numpy只保存數值,用於數值運算,解決Python標准庫中的list只能保存對象的指針的問題
import os #本例子中沒有使用到
import gzip #使用zlib來壓縮和解壓縮數據文件,讀寫gzip文件
import struct #通過引入struct模塊來處理圖片中的二進制數據
import mxnet as mx #引入MXNet包
import logging #引入logging包記錄日志

#利用MNIST數據集進行訓練

def read_data(label_url,image_url): #定義讀取數據的函數
    with gzip.open(label_url) as flbl: #解壓標簽包
        magic, num = struct.unpack(">II",flbl.read(8)) #采用Big Endian的方式讀取兩個int類型的數據,且參考MNIST官方格式介紹,magic即為magic number (MSB first) 用於表示文件格式,num即為文件夾內包含的數據的數量
        label = np.fromstring(flbl.read(),dtype=np.int8) #將標簽包中的每一個二進制數據轉化成其對應的十進制數據,且轉換后的數據格式為int8(-128 to 127)格式,返回一個數組
    with gzip.open(image_url,'rb') as fimg: #已只讀形式解壓圖像包
        magic, num, rows, cols = struct.unpack(">IIII",fimg.read(16)) #采用Big Endian的方式讀取四個int類型數據,且參考MNIST官方格式介紹,magic和num上同,rows和cols即表示圖片的行數和列數
        image = np.fromstring(fimg.read(),dtype=np.uint8).reshape(len(label),rows,cols) #將圖片包中的二進制數據讀取后轉換成無符號的int8格式的數組,並且以標簽總個數,行數,列數重塑成一個新的多維數組
    return (label,image) #返回讀取成功的label數組和image數組
#且fileobject.read(size)的時候是按照流的方式讀取(可test)

(train_lbl, train_img) = read_data('mnist/train-labels-idx1-ubyte.gz','mnist/train-images-idx3-ubyte.gz') #構建訓練數據
(val_lbl, val_img) = read_data('mnist/t10k-labels-idx1-ubyte.gz','mnist/t10k-images-idx3-ubyte.gz') #構建測試數據

def to4d(img): #定義一個函數用於生成四維矩陣
    return img.reshape(img.shape[0],1,28,28).astype(np.float32)/255 #將圖像包中的數組以標簽總個數,圖像通道數(MNIST數據集為黑白數據集故只為1),行數,列數重塑后復制為一個數據類型為float32的新的四維矩陣,且其中的元素值都除以255后轉化為0-1的浮點值

batch_size = 100 #定義每次處理數據的數量為100
train_iter = mx.io.NDArrayIter(to4d(train_img),train_lbl,batch_size,shuffle=True) #構建訓練數據迭代器,且其中shuffle表示采用可拖動的方式,意味着可以將在早期已經訓練過的數據在后面再次訓練
val_iter = mx.io.NDArrayIter(to4d(val_img),val_lbl,batch_size) #構建測試數據迭代器

#創建多層網絡模型
data = mx.sym.Variable('data') #創建一個用於輸入數據的PlaceHolder變量(占位符)
data = mx.sym.Flatten(data=data) #將data中的四維數據轉化為二維數據且其中一維為每次處理數據的數量,第二維即為每張圖片的圖像通道數×長×寬(即為其像素點個數×圖像通道數)
fc1 = mx.sym.FullyConnected(data=data,name='fc1',num_hidden=128) #創建第一層全連接層,輸入數據為data,num_hidden表示該隱藏層有128個用於輸出的節點
act1 = mx.sym.Activation(data=fc1,name='relu1',act_type='relu') #為第一層全連接層設定一個Relu激活函數,輸入數據為fc1
fc2 = mx.sym.FullyConnected(data=act1,name='fc2',num_hidden=64) #創建第二層全連接層,輸入數據為act1,num_hidden表示該隱藏層有64個用於輸出的節點
act2 = mx.sym.Activation(data=fc2,name='relu2',act_type='relu') #為第一層全連接層設定一個Relu激活函數,輸入數據為fc2
fc3 = mx.sym.FullyConnected(data=act2,Name='fc3',num_hidden=10) #創建第三層全連接層,輸入數據為act2,num_hidden表示該隱藏層有10個用於輸出的節點
mlp = mx.sym.SoftmaxOutput(data=fc3,name='softmax') #對輸入的數據執行softmax變換,並且通過利用logloss執行BP算法

logging.getLogger().setLevel(logging.DEBUG) #返回作為層次結構根記錄器的記錄器,且記錄等級作為DEBUG

#構建前饋神經網絡模型
model = mx.model.FeedForward(
    symbol = mlp, #使網絡結構為構建好的mlp
    num_epoch = 10, #數據的訓練次數為10
    learning_rate = 0.1 #使模型按照學習率為0.1進行訓練
)
#數據擬合,訓練模型
model.fit(
    X = train_iter, #設置訓練迭代器
    eval_data = val_iter, #設置測試迭代器
    batch_end_callback = mx.callback.Speedometer(batch_size,200) #在每一批epoches結尾時調用,打印logging信息(每經過200個batch_size打印logging)
)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM