资源技术动态基于mxnet的mnist手写数字识别

基于mxnet的mnist手写数字识别

2019-10-18 | |  108 |   0

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))


模型训练前的初始化设置

  1. lr=0.001  # 学习率

  2. num_epochs = 1  # 训练轮数

  3. batch_size = 32  # batch大小

  4. if(use_gpu == True):

  5.    ctx = mx.gpu(0)

  6. else:

  7.    ctx = mx.cpu(0)

  8. # 取一个与输入shape一样的随机值

  9. X = nd.random.uniform(shape=(1, 1, 28, 28), ctx=ctx)

  10. # 网络结构初始化

  11. net.initialize(init=init.MSRAPrelu(),ctx=ctx)

  12. # 进行一次正向传播测试

  13. y = net(X)

  14. # 设置数据加载器

  15. dataset_train = mx.gluon.data.ArrayDataset(X_train, Y_train) # ArrayDataset不需要从硬盘上加载数据

  16. dataset_test = mx.gluon.data.ArrayDataset(X_test, Y_test)

  17. Train_data_loader = gluon.data.DataLoader(dataset_train, batch_size = batch_size)

  18. Test_data_loader = gluon.data.DataLoader(dataset_test, batch_size = batch_size)

  19. # 设置训练器,使用adam优化器

  20. trainer = gluon.Trainer(net.collect_params(), 'adam', {'learning_rate': lr})

  21. # 设置损失函数

  22. loss = gloss.SoftmaxCrossEntropyLoss()

  23. Train_Loss = []

  24. Train_Acc = []

  25. Test_Acc = []

  26. # 定义一些模型评估函数

  27. def accuracy(y_hat, y):

  28.    """Get accuracy."""

  29.    return (y_hat.argmax(axis=1) == y.astype('float32')).mean().asscalar()

  30. def evaluate_accuracy(data_loader, net, ctx):

  31.    acc = nd.array([0], ctx=ctx)

  32.    for X, y in data_loader:

  33.        X, y = X.as_in_context(ctx), y.as_in_context(ctx)

  34.        acc += accuracy(net(X), y)

  35.    return acc.asscalar() / len(data_loader)


训练模型


  1. for epoch in range(num_epochs):

  2.  train_l_sum, train_acc_sum, start = 0, 0, time.time()

  3.  count_datatrain = 0

  4.  for X, y in Train_data_loader:

  5.    X, y = X.as_in_context(ctx), y.as_in_context(ctx)

  6.    with autograd.record():

  7.      y_hat = net(X)

  8.      l = loss(y_hat, y)

  9.    l.backward()

  10.    trainer.step(batch_size)

  11.    train_l_sum += l.mean().asscalar()

  12.    train_acc_sum += accuracy(y_hat, y)

  13.    

  14.    count_datatrain += batch_size

  15.    if(count_datatrain % batch_size == 0):

  16.      print('have train',count_datatrain,end='r')

  17.    

  18.  print('have train',count_datatrain,end='n')

  19.  test_acc = evaluate_accuracy(Test_data_loader, net, ctx)

  20.  print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f, '

  21.      'time %.1f sec' % (epoch + 1, train_l_sum / len(Train_data_loader),

  22.               train_acc_sum / len(Train_data_loader),

  23.               test_acc, time.time() - start))

  24.  Train_Acc.append(train_acc_sum / len(Train_data_loader))

  25.  Train_Loss.append(train_l_sum / len(Train_data_loader))

  26.  Test_Acc.append(test_acc)


保存模型参数


  1. filename='mnist.model.mxnet'

  2. net.save_parameters(filename)


保存相关实验数据


  1. Temp = []

  2. Data = []

  3. for i in range(len(Train_Acc)):

  4.  Temp.append(Train_Loss[i])

  5.  Temp.append(Train_Acc[i])

  6.  Temp.append(Test_Acc[i])

  7.  Data.append(Temp)

  8.  Temp = []

  9. name=['loss','train_Acc','test_Acc']

  10. test=pd.DataFrame(columns=name,data=Data)#数据有三列

  11. print(test)

  12. test.to_csv('./mnist.csv',encoding='gbk')


实验结果


3333.png

模型在训练结束后,loss降为0.15305,训练集准确率为95.42%,测试集准确率为97.10%。

THE END

免责声明:本文来自互联网新闻客户端自媒体,不代表本网的观点和立场。

合作及投稿邮箱:E-mail:editor@tusaishared.com

上一篇:NLP | 自然语言处理 - 语法解析(Parsing, and Context-Free Grammar

下一篇:为声音文件添加白噪音

用户评价
全部评价

热门资源

  • 应用笔画宽度变换...

    应用背景:是盲人辅助系统,城市环境中的机器导航...

  • GAN之根据文本描述...

    一些比较好玩的任务也就应运而生,比如图像修复、...

  • 端到端语音识别时...

    从上世纪 50 年代诞生到 2012 年引入 DNN 后识别效...

  • 人体姿态估计的过...

    人体姿态估计是计算机视觉中一个很基础的问题。从...

  • 谷歌发布TyDi QA语...

    为了鼓励对多语言问答技术的研究,谷歌发布了 TyDi...