基于MindSpore框架的MNIST手写体识别

  1. 配置运行信息

MindSpore通过context.set_context来配置运行需要的信息,譬如运行模式、后端信息、硬件信息。

import os

import argparse

from mindspore import context

 

parser = argparse.ArgumentParser(description='MindSpore LeNet Example')

parser.add_argument('--device_target', type=str, default="CPU", choices=['Ascend', 'GPU', 'CPU'])

 

args = parser.parse_args()

context.set_context(mode=context.GRAPH_MODE,device_target=args.device_target)

在样例中我们配置运行使用图模式,根据实际情况配置硬件信息。

  1. 数据处理

MindSpore提供了用于数据处理的APImindspore.dataset,用于存储样本和标签。

这里,我们首先通过导入mindspore.dataest和其他需要的模块来定义数据集及数据操作。

import mindspore.dataset as ds

import mindspore.dataset.transforms.c_transforms as C

import  mindspore.dataset.vision.c_transforms as CV

from mindspore.dataset.vision import Inter

from mindspore import dtype as mstype

定义数据集通过构造create_dataest来实现

def create_dataset(data_path, batch_size=32,repeat_size=1,num_parallel_workers=1):                           

    # 定义数据集

mnist_ds = ds.MnistDataset(data_path)

同时在这个函数中,我们定义好需要进行的数据增强和处理操作,为之后的map映射做准备

    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映射

    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)

    hwc2chw_op = CV.HWC2CHW()

type_cast_op = C.TypeCast(mstype.int32)

在这之后,便可使用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)

为了能保证1个epoch内数据不重复,这里我先进行了shuffle、batch操作,再进行repeat操作

    buffer_size = 10000

    mnist_ds = mnist_ds.shuffle(buffer_size=buffer_size)

    mnist_ds = mnist_ds.batch(batch_size, drop_remainder=True)



return mnist_ds
  1. 创建模型

神经网络的各层需要预先在__init__方法种定义,然后通过定义construct方法来完成神经网络的前向构造,由此我使用了结构较为简单的LeNet网络结构,并且进行实例化

import mindspore.nn as nn

from mindspore.common.initializer import Normal



class LeNet5(nn.Cell):

    """

    LeNet5网络结构

    """

    def __init__(self,num_class=10, num_channel=1):

        super(LeNet5, self).__init__()                              #初始化

        #定义所需要的运算

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

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

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

        self.relu = nn.ReLU()                                   #激活函数

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

        self.flatten = nn.Flatten()   #用来将输入”压平“,即把多维的输入一维化



    def construct(self, x):

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

        x = self.conv1(x)

        x = self.relu(x)

        x = self.max_pool2d(x)

        x = self.conv2(x)

        x = self.relu(x)

        x = self.max_pool2d(x)

        x = self.flatten(x)

        x = self.fc1(x)

        x = self.relu(x)

        x = self.fc2(x)

        x = self.relu(x)

        x = self.fc3(x)

        return x



#实例化网络

net = LeNet5()
  1. 优化模型参数

要训练神经网络模型,需要定义损失函数和优化器,这里我使用了交叉熵损失函数SoftmaxCrossEntropyWithLogits

#定义损失函数

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

对于优化器我采用了Momentum

#定义优化器

net_opt = nn.Momentum(net.trainable_params(), learning_rate=0.01, momentum=0.9)
  1. 训练及保存模型

这里我以框架提供的ModelCheckpoint为例,它可以保存网络模型和参数,以便进行后续的fine-tuning操作

from mindspore.train.callback import ModelCheckpoint, CheckpointConfig

# 设置模型保存参数

config_ck = CheckpointConfig(save_checkpoint_steps=1875, keep_checkpoint_max=10)

#应用模型保存参数

ckpoint = ModelCheckpoint(prefix="checkpoint_lenet", config=config_ck)

同时,利用model.train接口可以方便地进行网络训练,LossMonitor可以监控训练过程中Loss的变化

#导入模型训练需要的库

from mindspore.nn.metrics import Accuracy

from mindspore.train.callback import LossMonitor

from mindspore import Model

def train_net(args, model, epoch_size, data_path, repeat_size, ckpoint_cb, sink_mode):

    """定义训练的方法"""

    #加载训练数据集

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

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

由此,通过模型运行测试数据集得到加过,验证其泛化能力:

        1.使用model.eval接口读入测试数据集;

       2.使用保存后的模型参数进行推理;

def test_net(network, model, data_path):

    """定义验证方法"""

    ds_eval = create_dataset(os.path.join(data_path,"test"))

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

    print("{}".format(acc))

这里把train_epoch设置为1,即对数据集进行一个迭代的训练,在train_net和test_net方法中,我加载了之前下载的训练数据集

train_epoch = 1

mnist_path = "D:\MNIST_Data"

dataset_size = 1

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

train_net(args, model, train_epoch, mnist_path, dataset_size, ckpoint, False)

test_net(net, model, mnist_path)
  1. 加载模型
from mindspore.train.serialization import load_checkpoint, load_param_into_net

#加载已经保存的用于测试的模型

param_dict = load_checkpoint("checkpoint_lenet-1_1875.ckpt")

#加载参数到网络中

load_param_into_net(net, param_dict)
  1. 验证模型
import numpy as np

import mindspore as ms

import matplotlib.pyplot as plt



mnist = Mnist("E:\\MNIST_Data", split="train", batch_size=6, resize=32)

dataset_infer = mnist.run()

ds_test = dataset_infer.create_dict_iterator()

data = next(ds_test)

images = data["image"].asnumpy()

labels = data["label"].asnumpy()



plt.figure()

for i in range(1, 7):

    plt.subplot(2, 3, i)

    plt.imshow(images[i-1][0], interpolation="None", cmap="gray")

plt.show()



# 使用函数model.predict预测image对应分类

output = model.predict(ms.Tensor(data['image']))

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



# 输出预测分类与实际分类

print(f'Predicted: "{predicted}", Actual: "{labels}"')

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卷七

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值