对于MNIST手写体识别实验 —使用LeNet算法实现手写数字识别代码的理解

举报
凉城予梦 发表于 2021/11/23 15:48:15 2021/11/23
【摘要】 对 MNIST手写体识别实验实现手写数字识别代码的个人查找与理解,对于map映射与数据增强和卷积神经网络的代码有充分的注释,卷积与池化的过程也有充分的注释标明,因本人能力很弱,难免有错误的地方,烦请大家指出,我会立即更正。

MNIST手写体识别实验

—使用LeNet算法实现手写数字识别

 

 

 

 

姓名:祁蓁倬

 

一、MindSpore介绍

MindSpore是一个全场景深度学习框架,旨在实现易开发、高效执行、全场景覆盖三大目标

  • 易开发表现为API友好、调试难度低,
  • 高效执行包括计算效率、数据预处理效率和分布式训练效率,
  • 全场景则指框架同时支持云、边缘以及端侧场景。

MindSpore提供了Python编程范式,用户使用Python原生控制逻辑即可构建复杂的神经网络模型,AI编程变得简单

 

二、特点

目前主流的深度学习框架的执行模式有两种,分别为静态图模式和动态图模式。静态图模式拥有较高的训练性能,但难以调试。动态图模式相较于静态图模式虽然易于调试,但难以高效执行。

MindSpore提供了动态图和静态图统一的编码方式,大大增加了静态图和动态图的可兼容性,用户无需开发多套代码,仅变更一行代码便可切换动态图/静态图模式

 

三、实验目标

Notebook将展示如何使用MindSporeMNIST数据集上开发和训练一个LeNet模型,并将LeNet模型用于手写数字识别。

通过本实验你可以了解到如何使用MindSpore进行简单CNN网络的开发、简单图片分类任务的训和验证。

 

四、实验步骤

# 确认当前环境的版本

(请给出代码)

import mindspore  #导入mindspore AI框架

print(mindspore.__version__)  #打印mindspore版本号

           >>1.2.0

1. 数据集下载

MNIST是一个手写数字数据集,训练集包含60000张手写数字,测试集包含10000张手写数字,共10类。

从华为云OBS公共桶中下载。

(请给出代码,并且在每一句后面手写解释这一句代码实现的功能)

import os      #导入程序与操作系统进行交互的接口模块

import moxing as mox #导入moxing网络模型开发API模块并简名为mox

 

if not os.path.exists("./MNIST_Data.zip"):

mox.file.copy("obs://modelarts-labs-bj4-v2/course/hwc_edu/python_module_framework/datasets/mindspore_data/MNIST_Data.zip", "./MNIST_Data.zip")

#检测os模块路径,若路径不符,重置路径

 

!unzip -o MNIST_Data.zip -d ./  #解压手写数据集压缩包

!tree ./MNIST_Data/   #以树状图列出目录的内容

运行结果:

>>INFO:root:Using MoXing-v1.17.3-43fbf97f

INFO:root:Using OBS-Python-SDK-3.20.7

Archive:  MNIST_Data.zip

  inflating: ./MNIST_Data/__pycache__/load_data_zeros_ones.cpython-37.pyc 

  inflating: ./MNIST_Data/load_data_all.py 

  inflating: ./MNIST_Data/load_data_zeros_ones.py 

  inflating: ./MNIST_Data/process_dataset.py 

  inflating: ./MNIST_Data/test/t10k-images-idx3-ubyte 

  inflating: ./MNIST_Data/test/t10k-labels-idx1-ubyte 

  inflating: ./MNIST_Data/train/train-images-idx3-ubyte 

  inflating: ./MNIST_Data/train/train-labels-idx1-ubyte 

./MNIST_Data/

├── load_data_all.py

├── load_data_zeros_ones.py

├── process_dataset.py

├── __pycache__

   └── load_data_zeros_ones.cpython-37.pyc

├── test

   ├── t10k-images-idx3-ubyte

   └── t10k-labels-idx1-ubyte

└── train

    ├── train-images-idx3-ubyte

    └── train-labels-idx1-ubyte

 

3 directories, 8 files

2、处理MNIST数据集

由于我们后面会采用LeNet这样的卷积神经网络对数据集进行训练,而采用LeNet在训练数据时,对数据格式是有所要求的,所以接下来的工作需要我们先查看数据集内的数据是什么样的,这样才能构造一个针对性的数据转换函数,将数据集数据转换成符合训练要求的数据形式。

 

步骤1 查看原始数据集数据:

(请给出代码,并在每一句后面手写解释这一句代码实现的功能,在最后给出代码运行的输出结果)

 

from mindspore import context   #导入mindspore子模块context,其下有set_context方法来配置运行需要的信息

import matplotlib.pyplot as plt  #导入matplotlib子模块pyplot简名为plt,用来处理图像,数据可视化有关操作

import matplotlib    #导入matplotlib模块

import numpy as np     #导入numpy模块简名为np,包含多维数组用来整理数据

import mindspore.dataset as ds  #导入mindspore子数据集模块,这个API模块用于数据处理主,存储样本和标签,同时也集成了一些常见的数据处理方法。

 

# device_target 可选 CPU/GPU/Ascend, 当选择GPUmindspore规格也需要切换到GPU

context.set_context(mode=context.GRAPH_MODE, device_target="CPU")  #通过set_context方法配置,mode设置运行模式(动态图模式),用CPU运行

train_data_path = "./MNIST_Data/train"  #设置训练集路径

test_data_path = "./MNIST_Data/test"   #设置测试集路径

mnist_ds = ds.MnistDataset(train_data_path)  # 定义数据集

print('The type of mnist_ds:', type(mnist_ds))   #输出得到数据集的数据类型

print("Number of pictures contained in the mnist_ds:", mnist_ds.get_dataset_size())  #输出得到训练集的数据个数

 

dic_ds = mnist_ds.create_dict_iterator()  #create_dict_iterator创建数据迭代器,迭代访问定义好的训练集

item = next(dic_ds)  #返回迭代器的下一个项目

img = item["image"].asnumpy()  #将迭代训练集的张量用numpy数组表示

label = item["label"].asnumpy()   #将迭代训练集的标签用numpy数组表示

 

print("The item of mnist_ds:", item.keys())  #输出训练集储存不同数据的变量名

print("Tensor of image in item:", img.shape)  #输出迭代对象张量数组的形状

print("The label of item:", label)  #输出迭代对象的标签值

 

plt.imshow(np.squeeze(img)) #调用imshow()函数实现热图绘制,squeeze函数通过降秩使matplotlib能进行数据的可视化

plt.title("number:%s"% item["label"].asnumpy()) #布置图片分布格式,添加标题

plt.show()  #进行数据可视化,图片的显示

 

运行结果:

>>The type of mnist_ds: <class 'mindspore.dataset.engine.datasets.MnistDataset'>

Number of pictures contained in the mnist_ds 60000

The item of mnist_ds: dict_keys(['image', 'label'])

Tensor of image in item: (28, 28, 1)

The label of item: 1


 

步骤2 数据处理:

数据集对于训练非常重要,好的数据集可以有效提高训练精度和效率,在加载数据集前,我们通常会对数据集进行一些处理。

定义数据集及数据操作

定义完成后,使用create_datasets对原始数据进行增强操作,并抽取一个batch的数据,查看数据增强后的变化。

(请给出代码,并在每一句后面手写解释这一句代码实现的功能,在最后给出代码运行的输出结果)

import mindspore.dataset.vision.c_transforms as CV #导入MindSpore提供的增强数据集模块对图像进行预处理,从而提高模型的广泛性,简名为CV

import mindspore.dataset.transforms.c_transforms as C  #导入MindSpore提供的支持常见的图形增强功能的模块对图像进行预处理,简名为C

from mindspore.dataset.vision import Inter  #导入MindSpore提供的vision子模块可以调整图像大小

from mindspore import dtype as mstype   #导入数据类型转换处理模块

 

 

def create_dataset(data_path, batch_size=32, repeat_size=1,

                   num_parallel_workers=1):   #定义函数create_dataset来创建数据集,参数数据路径,抽取数据集大小,设置并行工作口数量

    """

    create dataset for train or test

   

    Args:

        data_path (str): Data path

        batch_size (int): The number of data records in each group

        repeat_size (int): The number of replicated data records

        num_parallel_workers (int): The number of parallel workers

    """

    # define dataset

    mnist_ds = ds.MnistDataset(data_path)   #定增强义数据集

 

    # define some parameters needed for data enhancement and rough justification

    resize_height, resize_width = 32, 32  #设置图像变量高与宽

    rescale = 1.0 / 255.0

    shift = 0.0  #设置偏移量

    rescale_nml = 1 / 0.3081  #设置插值偏移量

shift_nml = -1 * 0.1307 / 0.3081

#定义算法计算变量与参数

#定义需要进行的数据增强和处理操作,为之后进行map映射做准备。

# according to the parameters, generate the corresponding data enhancement method

#定义所需要的操作的map映射

    resize_op = CV.Resize((resize_height, resize_width), interpolation=Inter.LINEAR)  #缩小或者放大函数至预定高与宽,指定像素插值方式为双线性插值

    rescale_nml_op = CV.Rescale(rescale_nml, shift_nml)

rescale_op = CV.Rescale(rescale, shift) #对图像数据进行标准化、归一化操作,使得每个像素的数值大小在(0,1)范围中,可以提升训练效率,shift增加偏移量

hwc2chw_op = CV.HWC2CHW()#对图像数据张量进行变换,张量形式由高xx通道(HWC)变为通道xx宽(CHW),方便进行数据训练。

 

    type_cast_op = C.TypeCast(mstype.int32)  #将数据类型转化为int32

 

# using map to apply operations to a dataset

#使用map映射函数,将数据操作应用到数据集

    mnist_ds = mnist_ds.map(operations=type_cast_op, input_columns="label", num_parallel_workers=num_parallel_workers)  #应用到数据集操作方法数据类型转换,操作列为标签列,并行一接口计算

    mnist_ds = mnist_ds.map(operations=resize_op, input_columns="image", num_parallel_workers=num_parallel_workers)  #应用到数据集操作方法对图像放大缩小处理,预备插值,操作列为图像列,并行一接口计算

 

    mnist_ds = mnist_ds.map(operations=rescale_op, input_columns="image", num_parallel_workers=num_parallel_workers)  #应用到数据集操作方法标准化归一化,操作列为图象列,并行一接口计算

mnist_ds = mnist_ds.map(operations=rescale_nml_op, input_columns="image", num_parallel_workers=num_parallel_workers)   #应用到数据集操作方法编译文件标准化归一化,操作列为图象列,并行一接口计算

 

    mnist_ds = mnist_ds.map(operations=hwc2chw_op, input_columns="image", num_parallel_workers=num_parallel_workers)  #应用到数据集操作方法张量进行变换,操作列为图象列,并行一接口计算

   

# process the generated dataset

#先进行shufflebatch操作,再进行repeat操作,这样能保证1epoch内数据不重复

    buffer_size = 10000

    mnist_ds = mnist_ds.shuffle(buffer_size=buffer_size) #shuffle用于将数据集随机打乱,不希望有太多的人为因素干扰训练,因为可能MNIST数据集本身是有一定规律的,不希望按照制作这个数据集的前辈的顺序来训练神经网络

    mnist_ds = mnist_ds.batch(batch_size, drop_remainder=True)   #将整个数据集按照batch_size的大小分为若干批次,每一次训练的时候都是按一个批次的数据进行训练,drop_remainder确定是否删除数据行数小于批大小的最后一个块,这里设置为True就是只保留数据集个数整除

mnist_ds = mnist_ds.repeat(repeat_size)  #将数据集重复repeat_size次,注意该操作一般使用在batch操作之后

 

    return mnist_ds  #返回数据集

 

ms_dataset = create_dataset(train_data_path)  #将所有训练集创建数据集进行数据增强处理

print('Number of groups in the dataset:', ms_dataset.get_dataset_size()) #输出训练集大小

 

运行结果:

>> Number of groups in the dataset: 1875

步骤3 进一步查看增强后的数据:

  • 1875组数据中取出一组数据查看其数据张量及label将张量数据和下标对应的值进行可视化。

(请给出代码,并在每一句后面手写解释这一句代码实现的功能,在最后给出代码运行的输出结果)

data = next(ms_dataset.create_dict_iterator(output_numpy=True))

#返回迭代器的下一个项目,create_dict_iterator创建数据迭代器,迭代访问增强后的训练集,并以数组形式输出

images = data["image"]  #进行迭代image列并赋值给images变量

labels = data["label"]   #进行迭代label列并赋值给labels变量

print('Tensor of image:', images.shape)  #输出images形状(四维numpy数组)

print('labels:', labels)   #输出labels标签数组

运行结果:

>> Tensor of image: (32, 1, 32, 32)

labels: [0 4 6 2 2 5 5 3 6 5 1 6 4 1 0 1 8 3 0 6 2 2 4 1 4 2 4 2 3 7 8 0]

 

  • 将张量数据和下标对应的值进行可视化

(请给出代码,并在每一句后面手写解释这一句代码实现的功能,在最后给出代码运行的输出结果)

count = 1   #count变量赋值为1

for i in images:   #用变量iimages变量进行迭代循环

    plt.subplot(4, 8, count)  #分为4*8的网格图,在第count个图上进行图片显示

    plt.imshow(np.squeeze(i))  # 调用imshow()函数实现热图绘制,squeeze函数是从数组的形状中删除单维条目,即把shape中为1的维度去掉(通过降秩)使matplotlib能进行数据的可视化

 

    plt.title('num:%s'%labels[count-1])  #为每幅图片撰写标题在labels数组中索引

    plt.xticks([])    #x轴不显示任何数据,为空白

    count += 1    #count变量自加一

    plt.axis("off")   #关闭坐标轴

plt.show()  #数据的可视化,图片的显示

运行结果:

>>

3、 定义模型

在对手写字体识别上,通常采用卷积神经网络架构(CNN)进行学习预测,最经典的属1998年由Yann LeCun创建的LeNet5架构,
结构示意如下图:

 

 

(请给出代码,并在每一句后面手写解释这一句代码实现的功能,在最后给出代码运行的输出结果)

import mindspore.nn as nn  #创模型,配置网络结构(卷积,压平,全连接,激活函数,最大池化),导入nn子模块简名为nn

from mindspore.common.initializer import Normal  # 导入Normal模块类配置初始权重(正态分布)

 

class LeNet5(nn.Cell):  #定义LeNet5类并继承nn.Cell类的属性和方法

    """Lenet network structure."""   #构建Lenet神经网络结构

    # define the operator required  #定义所需要的运算

    def __init__(self, num_class=10, num_channel=1):  #定义方法和默认参数与值

        super(LeNet5, self).__init__()  #声明继承父类nn.cell__init__方法

        self.conv1 = nn.Conv2d(num_channel, 6, 5, pad_mode='valid') 

#nn.Conv2d的第一个参数是输入图片的通道数为1,即单个过滤器应有的通道数,第二个参数是输出图片的通道数,第三个参数是过滤器的二维属性,它可以是一个int元组,但由于一般过滤器都是a x a形式的,而且为奇数。所以这里填入单个数即可,参数pad_mode为卷积方式,valid卷积即padding0的卷积

self.conv2 = nn.Conv2d(6, 16, 5, pad_mode='valid')

#nn.Conv2d的第一个参数是输入图片的通道数为6,第二个参数是输出图片的通道数,第三个参数是过滤器的二维属性,它可以是一个int元组,但由于一般过滤器都是a x a形式的,而且为奇数。所以这里填入单个数即可,参数pad_mode为卷积方式,valid卷积即padding0的卷积,现在也比较流行same卷积,即卷积后输出的图片不会缩小。需要注意的是卷积层我们是不需要设置参数的随机方式的,因为它默认会给我们选择为Noremal

self.fc1 = nn.Dense(16 * 5 * 5, 120, weight_init=Normal(0.02))

        self.fc2 = nn.Dense(120, 84, weight_init=Normal(0.02))

        self.fc3 = nn.Dense(84, num_class, weight_init=Normal(0.02))

        #nn.Dense为致密连接层,它的第一个参数为输入层的维度,第二个参数为输出的维度,第三个参数为神经网络可训练参数W权重矩阵的初始化方式,默认为normal,以上代码对号入座即可

        self.relu = nn.ReLU()   #nn.ReLU()非线性激活函数,它往往比论文中的sigmoid激活函数具有更好的效益

        self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2)

      #nn.MaxPool2d为最大池化层的定义,kernel_size为采样器的大小,stride为采样步长,本例中将其都设置为2相当于将图片的宽度和高度都缩小一半

        self.flatten = nn.Flatten()   #nn.Flatten为输入展成平图层,即去掉那些空的维度

 

     # use the preceding operators to construct networks

     #使用定义好的运算构建前向网络

    def construct(self, x):  #构建输入参数调用方法的方法,输入x,下面即是将x通过LeNet5网络执行前向传播的过程

        x = self.max_pool2d(self.relu(self.conv1(x)))

        x = self.max_pool2d(self.relu(self.conv2(x)))

#调用max_pool2d最大池化层方法

        x = self.flatten(x)  #调用flatten方法将输入展成平图层(去掉那些空的维度)

x = self.relu(self.fc1(x))

        x = self.relu(self.fc2(x))  #调用relu方法利用非线性激活函数对数据进行处理

        x = self.fc3(x)  #调用致密连接层算法方法对数据进行处理

        return x   #返回全部经过算法处理过的数据x

   

network = LeNet5()  #用实例名networkLeNet5类进行实例化

print("layer conv1:", network.conv1)  #查看卷积后conv1的参数

print("*"*40)   #输出星号行进行作为分隔

print("layer fc1:", network.fc1)  #查看卷积后fc1的参数

 

运行结果:

>> layer conv1: Conv2d<input_channels=1, output_channels=6, kernel_size=(5, 5),stride=(1, 1),  pad_mode=valid, padding=0, dilation=(1, 1), group=1, has_bias=Falseweight_init=normal, bias_init=zeros, format=NCHW>

****************************************

layer fc1: Dense<input_channels=400, output_channels=120, has_bias=True>

4、搭建训练网络并进行训练

构建完成神经网络后,就可以着手进行训练网络的构建,模型训练函数为Model.train

此步骤案例中使用epoch=1,使用CPU训练大概耗时15分钟,为实现快速训练,可选用更高规格的资源训练。

(请给出代码,并在每一句后面手写解释这一句代码实现的功能,在最后给出代码运行的输出结果)

#前面已经定义好了网络的前向传播过程,为了改变可训练参数,即所使用的参数能够预测出更加精确的值。需要定义损失函数即优化器,在MindSpore框架中是封装好了损失函数和优化器的,这使得编程可以更快更加高效

import os   #导入程序与操作系统进行交互的接口模块

from mindspore import Tensor, Model  #张量的初始化方式有多种,构造张量时,支持传入TensorfloatintbooltuplelistNumPy.array类型,Tensorshape,是一个tuple

from mindspore import load_checkpoint, load_param_into_net  # 加载已经保存的用于测试的模型

from mindspore.train.callback import ModelCheckpoint, CheckpointConfig, LossMonitor

from mindspore.nn.metrics import Accuracy

from mindspore.nn.loss import SoftmaxCrossEntropyWithLogits  # MindSpore 支持的损失函数有 SoftmaxCrossEntropyWithLogitsL1LossMSELoss 等。这里使用 SoftmaxCrossEntropyWithLogits 交叉熵损失函数

#损失函数:又叫目标函数,用于衡量预测值与实际值差异的程度。深度学习通过不停地迭代来缩小损失函数的值。定义一个好的损失函数,可以有效提高模型的性能。常见的有二分类的损失函数L,以及softmax损失函数等。

优化器:用于最小化损失函数,从而在训练过程中改进模型。

lr = 0.01  #learingrate,学习率,可以使梯度下降的幅度变小,从而可以更好的训练参数

momentum = 0.9

epoch_size = 1  #每个epoch需要遍历完成图片的batch,这里是只要遍历一次

mnist_path = "./MNIST_Data" #使用了流行的Momentum优化器进行优化

model_path = "./models/ckpt/"

 

# clean up old run files before in Linux

os.system('rm -f {}*.ckpt {}*.meta {}*.pb'.format(model_path, model_path, model_path))

#布置接口在Linux架构上运行

 

# create the network

network = LeNet5()

#创建手写神经网络

# define the optimizer

net_opt = nn.Momentum(network.trainable_params(), lr, momentum)

#其中gradlrpvu分别表示梯度、学习率、参数、力矩和动量。

# define the loss function

net_loss = SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean')

#相当于softmax分类器
#sparse
指定标签(label)是否使用稀疏模式,默认为false,reduction为损失的减少类型:mean表示平均值,一般
#
情况下都是选择平均地减少

# define the model

model = Model(network, net_loss, net_opt, metrics={"Accuracy": Accuracy()} )

#调用Model高级API,将LeNet-5网络与损失函数和优化器连接到一起,具有训练和推理功能的对象。metrics 参数是指训练和测试期,模型要评估的一组度量,这里设置的是"Accuracy"准确度

# save the network model and parameters for subsequence fine-tuning

config_ck = CheckpointConfig(save_checkpoint_steps=375, keep_checkpoint_max=16)

# group layers into an object with training and evaluation features

ckpoint_cb = ModelCheckpoint(prefix="checkpoint_lenet", directory=model_path, config=config_ck)

#自定义一个回调类
自定义一个数据收集的回调类StepLossAccInfo该类继承自Callback类。主要用于收集两类信息,steploss值之间地关系。step与对应模型精度之间联系。

eval_dataset = create_dataset("./MNIST_Data/test")

#创建数据集并使用数据集路径

step_loss = {"step": [], "loss_value": []}

steps_eval = {"step": [], "acc": []}

#回调类中提到的我们要声明的数据格式

repeat_size = 1

ds_train = create_dataset(os.path.join(mnist_path, "train"), 32, repeat_size)

model.train(epoch_size, ds_train, callbacks=[ckpoint_cb, LossMonitor(125)], dataset_sink_mode=False)

#调用Model类的train方法进行训练,LossMonitor(125)每隔125step打印训练过程中的loss,dataset_sink_mode为设置数据下沉模式,但该模式不支持CPU,所以这里我们只能设置为False

运行结果:

>> epoch: 1 step: 125, loss is 2.2997866

epoch: 1 step: 250, loss is 2.3055472

epoch: 1 step: 375, loss is 2.2988715

epoch: 1 step: 500, loss is 2.2939103

epoch: 1 step: 625, loss is 2.3018577

epoch: 1 step: 750, loss is 2.3118253

epoch: 1 step: 875, loss is 1.4138937

epoch: 1 step: 1000, loss is 0.27308625

epoch: 1 step: 1125, loss is 0.18187436

epoch: 1 step: 1250, loss is 0.06290328

epoch: 1 step: 1375, loss is 0.04215096

epoch: 1 step: 1500, loss is 0.43650156

epoch: 1 step: 1625, loss is 0.13031071

epoch: 1 step: 1750, loss is 0.16527386

epoch: 1 step: 1875, loss is 0.061115555

 

5、测试数据验证模型精度

(请给出代码,并在每一句后面手写解释这一句代码实现的功能,在最后给出代码运行的输出结果)

# testing relate modules  #测试相关模型

def test_net(network, model, mnist_path):  #定义测试神经网络函数

    """Define the evaluation method."""

    print("============== Starting Testing ==============")  #打印分割线

    # load the saved model for evaluation

    param_dict = load_checkpoint("./models/ckpt/checkpoint_lenet-1_1875.ckpt")      # 加载路径数据集

    # load parameter to the network

    load_param_into_net(network, param_dict)   #加载预测神经网络数据集

    # load testing dataset

    ds_eval = create_dataset(os.path.join(mnist_path, "test"))  #创建测试数据集函数

    acc = model.eval(ds_eval, dataset_sink_mode=False)

    print("============== Accuracy:{} ==============".format(acc))  #打印分割线

 

test_net(network, model, mnist_path)

运行结果:

>> ============== Starting Testing ==============

============== Accuracy:{'Accuracy': 0.9669471153846154} ==============

 

6、推理(训练后)

(请给出代码,并在每一句后面手写解释这一句代码实现的功能,在最后给出代码运行的输出结果)

提取出一个批次的图片,使用已训练好的上面的模型来预测一下每一张图片的标签,并将其可视化。

ds_test = create_dataset(test_data_path).create_dict_iterator()  #录入测试数据路径给ds_test变量存储一个字典类型迭代器,

data = next(ds_test)   #设置data变量存入ds_test进行迭代的内容

images = data["image"].asnumpy()  #设置images变量存入数据集image列转换为数组类型的数据

labels = data["label"].asnumpy()  #设置labels变量存入数据集label列转换为数组类型的数据

output = model.predict(Tensor(data['image']))  #利用加载好的模型的predict进行预测,注意返回的是对应的(09)的概率

pred = np.argmax(output.asnumpy(), axis=1) 

err_num = []  #设置初始空列表

index = 1  #设置初始索引为1

for i in range(len(labels)):  #对数据集测试长度判断循环次数并使用range循环进行遍历

    plt.subplot(4, 8, i+1)  #设置分割图用i循环进行数据可视化

    color = 'blue' if pred[i] == labels[i] else 'red'  #设置图片颜色

    plt.title("pre:{}".format(pred[i]), color=color)  #设置标题颜色架构

    plt.imshow(np.squeeze(images[i]))  #去秩(去掉一维的维度)用来实现图片的二维显示

    plt.axis("off")  #关闭坐标轴

    if color == 'red':  #当颜色为红色时,索引为0

        index = 0

        print("Row {}, column {} is incorrectly identified as {}, the correct value should be {}".format(int(i/8)+1, i%8+1, pred[i], labels[i]), '\n')

if index:

    print("All the figures in this group are predicted correctly!")

print(pred, "<--Predicted figures")

print(labels, "<--The right number")

plt.show()  #图片进行显示

运行结果:

>>Row 1, column 2 is incorrectly identified as 7, the correct value should be 9

 

[5 7 7 6 8 1 4 4 0 9 6 3 0 3 5 9 3 4 3 2 8 0 1 6 0 7 0 8 2 1 5 4] <--Predicted figures

[5 9 7 6 8 1 4 4 0 9 6 3 0 3 5 9 3 4 3 2 8 0 1 6 0 7 0 8 2 1 5 4] <--The right number


 

  1. 实验分析与结论

本实验展示了如何使用MindSpore进行手写数字识别,以及开发和训练LeNet5模型。通过对LeNet5模型做几代的训练,然后使用训练后的LeNet5模型对手写数字进行识别,识别准确率大于95%。即LeNet5学习到了如何进行手写数字识别。

至此,本案例完成。

 

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。