mxnet mnist

本文详细介绍了一种使用MXNet框架的手写数字识别方法,包括数据下载、预处理、BP神经网络和卷积神经网络(CNN)的构建、训练及评估过程。展示了如何从MNIST数据集训练模型,并在单张图片上进行预测。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import numpy as np
import os
import urllib
import urllib.request
import gzip
import struct
import matplotlib.pyplot as plt
import mxnet as mx
import logging

from IPython.display import HTML
import cv2
#from mnist_demo import html, script

def download_data(url, force_download=True):
    fname = url.split("/")[-1]
    if force_download or not os.path.exists(fname):
        urllib.request.urlretrieve(url,fname) # python2 与python3的urllib不同在与python3要加上.request
    return fname
	
def read_data(label_url, image_url):
    with gzip.open(download_data(label_url))as flbl:
        magic, num = struct.unpack(">II", flbl.read(8))
        label = np.fromstring(flbl.read(), dtype=np.int8)
    with gzip.open(download_data(image_url),'rb')as fimg:
        magic, num, rows, cols = struct.unpack(">IIII", fimg.read(16))
        image = np.fromstring(fimg.read(), dtype=np.uint8).reshape(len(label), rows, cols)
    return (label, image)
	
def get_data(path):
	(train_lbl, train_img)= read_data(
    path+'train-labels-idx1-ubyte.gz', path+'train-images-idx3-ubyte.gz')
	
	(val_lbl, val_img) = read_data(
    path+'t10k-labels-idx1-ubyte.gz', path+'t10k-images-idx3-ubyte.gz')
	
	print("train_img.shape=", train_img.shape)
	print("train_lbl.shape=", train_lbl.shape)
	print("val_lbl.shape=", val_lbl.shape)
	print("val_img.shape=", val_img.shape)
	
	for i in range(10):
		plt.subplot(1,10,i+1)
		plt.imshow(train_img[i], cmap='Greys_r')
		plt.axis('off')
	plt.show()
	print('label: %s'% (train_lbl[0:10],))
	
	return (train_lbl, train_img, val_lbl, val_img)

def to4d(img):
    return img.reshape(img.shape[0],1,28,28).astype(np.float32)/255
	
def bpnetWorkTrainMnist(train_lbl, train_img, val_lbl, val_img):
	batch_size=100
	train_iter= mx.io.NDArrayIter(to4d(train_img), train_lbl, batch_size, shuffle=True)
	val_iter= mx.io.NDArrayIter(to4d(val_img), val_lbl, batch_size)
	
	# Create a place holder variable for the input data
	data= mx.sym.Variable('data')
	
	# Flatten the data from 4-D shape (batch_size, num_channel, width, height)
	# into 2-D (batch_size, num_channel*width*height)
	data= mx.sym.Flatten(data=data)
	
	# The first fully-connected layer
	fc1 = mx.sym.FullyConnected(data=data, name='fc1', num_hidden=128)
	
	# Apply relu to the output of the first fully-connnected layer
	act1= mx.sym.Activation(data=fc1, name='relu1', act_type="relu")
	
	# The second fully-connected layer and the according activation function
	fc2 = mx.sym.FullyConnected(data=act1, name='fc2', num_hidden =64)
	
	act2= mx.sym.Activation(data=fc2, name='relu2', act_type="relu")
	
	# The thrid fully-connected layer, note that the hidden size should be 10, which is the number of unique digits
	fc3  = mx.sym.FullyConnected(data=act2, name='fc3', num_hidden=10)
	
	# The softmax and loss layer
	mlp  = mx.sym.SoftmaxOutput(data=fc3, name='softmax')
	
	# We visualize the network structure with output size (the batch_size is ignored.)
	shape= {"data" : (batch_size, 1,28,28)}
	mx.viz.plot_network(symbol=mlp, shape=shape)
	
	# 现在神经网络定义和数据迭代器都已经准备好了。我们可以开始训练了:
	logging.getLogger().setLevel(logging.DEBUG)
	
	model= mx.model.FeedForward(
		symbol = mlp,       # network structure
		num_epoch =10,     	# number of data passes for training 
		learning_rate =0.1	# learning rate of SGD 
	)
	
	model.fit(
		X=train_iter,       # training data
		eval_data=val_iter,# validation data
		batch_end_callback = mx.callback.Speedometer(batch_size,200)# output progress for each 200 data batches
	)	
		
	return (model, val_iter)

def classify(model, img):
	img = img[len('data:image/png;base64,'):].decode('base64')
	img = cv2.imdecode(np.fromstring(img, np.uint8),-1)
	img = cv2.resize(img[:,:,3], (28,28))
	img = img.astype(np.float32).reshape((1,1,28,28))/255.0
	return model.predict(img)[0].argmax()
	
def cnnTrainMnist(train_lbl, train_img, val_lbl, val_img):
	batch_size=100
	train_iter= mx.io.NDArrayIter(to4d(train_img), train_lbl, batch_size, shuffle=True)
	val_iter= mx.io.NDArrayIter(to4d(val_img), val_lbl, batch_size)
	
	data= mx.symbol.Variable('data')
	
	# first conv layer
	conv1= mx.sym.Convolution(data=data, kernel=(5,5), num_filter=20)
	tanh1= mx.sym.Activation(data=conv1, act_type="tanh")
	pool1= mx.sym.Pooling(data=tanh1, pool_type="max", kernel=(2,2), stride=(2,2))
	
	# second conv layer
	conv2= mx.sym.Convolution(data=pool1, kernel=(5,5), num_filter=50)
	tanh2= mx.sym.Activation(data=conv2, act_type="tanh")
	pool2= mx.sym.Pooling(data=tanh2, pool_type="max", kernel=(2,2), stride=(2,2))
	
	# first fullc layer
	flatten= mx.sym.Flatten(data=pool2)
	fc1= mx.symbol.FullyConnected(data=flatten, num_hidden=500)
	tanh3= mx.sym.Activation(data=fc1, act_type="tanh")
	
	# second fullc
	fc2 = mx.symbol.FullyConnected(data=tanh3, num_hidden=10)
	
	# softmax loss
	lenet= mx.sym.SoftmaxOutput(data=fc2, name='softmax')
	
	# We visualize the network structure with output size (the batch_size is ignored.)
	shape= {"data" : (batch_size, 1,28,28)}
	mx.viz.plot_network(symbol=lenet, shape=shape)
	
	# 现在神经网络定义和数据迭代器都已经准备好了。我们可以开始训练了:
	logging.getLogger().setLevel(logging.DEBUG)
	
	model= mx.model.FeedForward(
		ctx = mx.gpu(0),     # use GPU 0 for training, others are same as before
		symbol = lenet,       
		num_epoch =10,     
		learning_rate = 0.1
	)
	
	model.fit(
		X=train_iter,  
		eval_data=val_iter,
		batch_end_callback = mx.callback.Speedometer(batch_size,200)
	)
	
	return (model, val_iter)
	
def mnist():
	path='http://yann.lecun.com/exdb/mnist/'
	train_lbl, train_img, val_lbl, val_img = get_data(path)
	
	model, val_iter = bpnetWorkTrainMnist(train_lbl, train_img, val_lbl, val_img)
	
	#model, val_iter = cnnTrainMnist(train_lbl, train_img, val_lbl, val_img)
	
	#model.save_checkpoint('mxnet_mnist_weight',num_epoch) # 保存模型
	
	# 完成训练后,我们对单幅图片进行测试。
	plt.imshow(val_img[0], cmap='Greys_r')
	plt.axis('off')
	plt.show()
	
	# bpNetWork predict
	#prob= model.predict(val_img[0:1].astype(np.float32)/255)[0]
	
	# cnn Predict
	prob = model.predict((val_img[0:1].astype(np.float32)/255).reshape(1, 1, 28, 28))[0]
	
	print('Classified as %d with probability %f'% (prob.argmax(),max(prob)))
	
	# 我们也可以通过给予一个数据迭代器来计算正确率。
	print('Validation accuracy: %f%%'% (model.score(val_iter)*100,))
	
	
	
def main():
	mnist()
	
if __name__ == '__main__':
	main()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值