基于mxnet的mnist手写数字识别
mnist手写数字识别是入门深度学习,或者学习一个新的深度学习框架时,最容易上手的程序。本文中,我将使用mxnet深度学习框架在mnist数据集上实现一个简单的手写数字识别模型。
整个程序的代码思路来源于GitHub 上别人的一个小项目,并使用mxnet框架复现了一遍:
https://gist.github.com/alexcpn/0683bb940cae510cf84d5976c1652abd
运行环境
运行软件
Python3
依赖包
mxnet
numpy
pandas
matplotlib
time (默认自带)
random (默认自带)
代码讲解
依赖包导入
from mxnet import gluon, init, nd, autograd
from mxnet.gluon import nn, utils as gutils
from mxnet.gluon import loss as gloss
import mxnet as mx
import time
import numpy as np
import random
import matplotlib.pyplot as plt
import pandas as pd
基础配置
np.random.seed(123) #设置随机数种子
use_gpu = False #指示是否使用GPU,当使用GPU时应设为True
导入数据
数据集的下载请点击这里(mnist.npz)
def load_data(path='mnist.npz'): # 读入本地文件
f = np.load(path)
x_train, y_train = f['x_train'], f['y_train']
x_test, y_test = f['x_test'], f['y_test']
f.close()
return (x_train, y_train), (x_test, y_test)
# 将数据读入
(X_train, y_train), (X_test, y_test) = load_data()
# 查看一下数据的格式,输入输出维度
print(X_train.shape,y_train.shape,X_test.shape,y_test.shape)
数据可视化
有时候,为了方便,或者更直观,我们往往需要将数据可视化。对于图像数据来说,可视化就是家常便饭了,而且也是最容易可视化的一类数据之一。这里我们使用到一个强大的绘图库matplotlib,同样,做过数学建模以及仿真的应该都用过这类库,尤其是用过matlab的话。
plt.subplot(221)
print(y_train[4545],y_train[1],y_train[2],y_train[3])
plt.imshow(X_train[4545], cmap=plt.get_cmap('gray'))
plt.subplot(222)
plt.imshow(X_train[1], cmap=plt.get_cmap('gray'))
plt.subplot(223)
plt.imshow(X_train[2], cmap=plt.get_cmap('gray'))
plt.subplot(224)
plt.imshow(X_train[3], cmap=plt.get_cmap('gray'))
# show the plot
plt.show()
数据预处理
往往我们拿到的数据,都需要进行一些处理,在不同的场景下,有不同的处理方法。这里的mnist数据集是已经处理过的,我们只需要将其转为我们所需的输入格式即可。这里,我们需要将其转换为mxnet框架运算所需要的nd.array格式。对于数据的10个数字标签,由于mxnet框架提供的损失函数的特性,我们不需要像其他框架那样进行正交化处理。
# 调整shape
X_train = X_train.reshape(X_train.shape[0], 1, 28, 28)
X_test = X_test.reshape(X_test.shape[0], 1, 28, 28)
# 调整数据类型
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
# 归一化
X_train /= 255
X_test /= 255
print(len(y_train),len(y_test))
# 从numpy.array转换为mxnet.nd.array
Y _train = nd.array(y_train)
Y _test = nd.array(y_test)
搭建神经网络模型
net = nn.Sequential()
net.add(nn.Conv2D(channels=32,kernel_size=3,padding=1,strides=1))
net.add(nn.Conv2D(channels=32,kernel_size=3,padding=1,strides=1))
net.add(nn.MaxPool2D(pool_size=(2,2), strides=(2,2)))
net.add(nn.Dense(units=128,activation='relu', flatten=True))
net.add(nn.Dense(units=10, activation='softrelu', flatten=True))
模型训练前的初始化设置
lr=0.001 # 学习率
num_epochs = 1 # 训练轮数
batch_size = 32 # batch大小
if(use_gpu == True):
ctx = mx.gpu(0)
else:
ctx = mx.cpu(0)
# 取一个与输入shape一样的随机值
X = nd.random.uniform(shape=(1, 1, 28, 28), ctx=ctx)
# 网络结构初始化
net.initialize(init=init.MSRAPrelu(),ctx=ctx)
# 进行一次正向传播测试
y = net(X)
# 设置数据加载器
dataset_train = mx.gluon.data.ArrayDataset(X_train, Y_train) # ArrayDataset不需要从硬盘上加载数据
dataset_test = mx.gluon.data.ArrayDataset(X_test, Y_test)
Train_data_loader = gluon.data.DataLoader(dataset_train, batch_size = batch_size)
Test_data_loader = gluon.data.DataLoader(dataset_test, batch_size = batch_size)
# 设置训练器,使用adam优化器
trainer = gluon.Trainer(net.collect_params(), 'adam', {'learning_rate': lr})
# 设置损失函数
loss = gloss.SoftmaxCrossEntropyLoss()
Train_Loss = []
Train_Acc = []
Test_Acc = []
# 定义一些模型评估函数
def accuracy(y_hat, y):
"""Get accuracy."""
return (y_hat.argmax(axis=1) == y.astype('float32')).mean().asscalar()
def evaluate_accuracy(data_loader, net, ctx):
acc = nd.array([0], ctx=ctx)
for X, y in data_loader:
X, y = X.as_in_context(ctx), y.as_in_context(ctx)
acc += accuracy(net(X), y)
return acc.asscalar() / len(data_loader)
训练模型
for epoch in range(num_epochs):
train_l_sum, train_acc_sum, start = 0, 0, time.time()
count_datatrain = 0
for X, y in Train_data_loader:
X, y = X.as_in_context(ctx), y.as_in_context(ctx)
with autograd.record():
y_hat = net(X)
l = loss(y_hat, y)
l.backward()
trainer.step(batch_size)
train_l_sum += l.mean().asscalar()
train_acc_sum += accuracy(y_hat, y)
count_datatrain += batch_size
if(count_datatrain % batch_size == 0):
print('have train',count_datatrain,end='r')
print('have train',count_datatrain,end='n')
test_acc = evaluate_accuracy(Test_data_loader, net, ctx)
print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f, '
'time %.1f sec' % (epoch + 1, train_l_sum / len(Train_data_loader),
train_acc_sum / len(Train_data_loader),
test_acc, time.time() - start))
Train_Acc.append(train_acc_sum / len(Train_data_loader))
Train_Loss.append(train_l_sum / len(Train_data_loader))
Test_Acc.append(test_acc)
保存模型参数
filename='mnist.model.mxnet'
net.save_parameters(filename)
保存相关实验数据
Temp = []
Data = []
for i in range(len(Train_Acc)):
Temp.append(Train_Loss[i])
Temp.append(Train_Acc[i])
Temp.append(Test_Acc[i])
Data.append(Temp)
Temp = []
name=['loss','train_Acc','test_Acc']
test=pd.DataFrame(columns=name,data=Data)#数据有三列
print(test)
test.to_csv('./mnist.csv',encoding='gbk')
实验结果
模型在训练结束后,loss降为0.15305,训练集准确率为95.42%,测试集准确率为97.10%。
一THE END一
免责声明:本文来自互联网新闻客户端自媒体,不代表本网的观点和立场。
合作及投稿邮箱:E-mail:editor@tusaishared.com
热门资源
应用笔画宽度变换...
应用背景:是盲人辅助系统,城市环境中的机器导航...
GAN之根据文本描述...
一些比较好玩的任务也就应运而生,比如图像修复、...
端到端语音识别时...
从上世纪 50 年代诞生到 2012 年引入 DNN 后识别效...
人体姿态估计的过...
人体姿态估计是计算机视觉中一个很基础的问题。从...
谷歌发布TyDi QA语...
为了鼓励对多语言问答技术的研究,谷歌发布了 TyDi...
智能在线
400-630-6780
聆听.建议反馈
E-mail: support@tusaishared.com