一個門外漢寫的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) )