手把手教你用MindSpore训练一个AI模型!

首先我们要先了解深度学习的概念和AI计算框架的角色(https://zhuanlan.zhihu.com/p/463019160),本篇文章将演示怎么利用MindSpore来训练一个AI模型。和上一章的场景一致,我们要训练的模型是用来对手写数字图片进行分类的LeNet5模型

请参考(http://yann.lecun.com/exdb/lenet/)。

图1 MindSpore使用流程

安装MindSpore

MindSpore提供给用户使用的是Python接口(什么是Python,请参考:

https://zhuanlan.zhihu.com/p/462756985),所以我们首先需要安装MindSpore的whl包,安装之后就可以导入(import)MindSpore提供的方法接口了。安装whl包有两种方式:

方式一:进入MindSpore官网,根据自己的设备和Python版本选择安装命令。比如我的Python版本是3.7.5,我的设备是笔记本(CPU),那么我就复制下图红框中的命令进行安装:

图2 MindSpore安装界面

安装过程如下:

图3 MindSpore安装过程

注意:由于MindSpore还依赖于其他的Python三方库,所以在安装过程中,系统还会自动下载、安装其他的Python三方库,如numpy、pillow、scipy等等,安装结束后,如果能 import mindspore 成功,说明MindSpore安装成功了:

图4 MindSpore安装成功

方式二:可以在版本列表中找到对应的whl包,点击就能下载:

图5 MindSpore版本下载列表

下载完成后,把whl包放到自己的目录下,执行 pip install xxx.whl:

图6 MindSpore第二种安装方式

定义模型

安装好MindSpore之后,我们就可以导入MindSpore提供的算子(卷积、全连接、池化等函数:https://zhuanlan.zhihu.com/p/463019160)来构建我们的模型了。可以这么比喻:我们构建一个AI模型就像建一个房子,而MindSpore提供给我们的算子就像是砖块、窗户、地板等基本组件。

图7 定义LeNet5模型

如上图所示,我们用到的“砖块”都是mindspore.nn模块提供的。注意:这里用到了Python的类(class),由②和③两部分组成。我们这里定义的类是class LeNet5,它由初始化函数 __init__(self) 和构造函数construct(self, x)组成。初始化函数定义了我们构造模型所需要用到的算子,比如conv算子、relu算子、flatten算子等等,这些算子都是从mindspore.nn获取的;构造函数就是把我们在初始化函数中导入的算子按顺序排放,构成我们最终的模型。construct()函数的输入就是我们这个模型预测的对象,比如第一章讲的黑白图片像素矩阵;而“return y”中的就是预测的结果,对应于第一章讲到的10分类手写数字数据集,就是一个行10列的数组(这里的是指输入图片的数量,AI模型支持多张图片同时推理)。

导入训练数据集

什么是训练数据集?刚刚定义好的模型是不能对图片进行正确分类的,我们要通过“训练”过程来调整模型的参数矩阵的值。训练过程就需要用到训练样本,也就是打上了正确标签的图片。这就好比我们教小孩儿认识动物,需要拿几张图片给他们看,然后告诉他们这是什么、那是什么,教了几遍之后,小孩儿就能认识了。那么我们训练LeNet5模型就需要用到MNIST数据集,请参考(http://yann.lecun.com/exdb/mnist/)。这个数据集由两部分组成:训练集(6万张图片)和测试集(1万张图片),都是0~9的黑白手写数字图片。训练集是用来训练AI模型的,测试集是用来测试训练后的模型分类准确率的。

下载得到的数据集最初是压缩文件,还不能直接传给MindSpore的训练接口使用,我们要先用MindSpore提供的数据处理接口把他们读进来:

import mindspore.dataset as ds
mnist_ds = ds.MnistDataset(data_path)  # 导入下载的MNIST数据集

然后进行数据增强(比如把图片大小转化成相同的尺寸、像素值标准化、归一化等操作),提升训练效率:

import mindspore.dataset.vision.c_transforms as CV
import mindspore.dataset.transforms.c_transforms as C
from mindspore.dataset.vision import Inter
from mindspore import dtype as mstype

# 定义数据增强函数
def create_dataset(data_path, batch_size=32):  # batch_size是每一步训练使用的图片数量,一般取32
    """
    create dataset for train or test

    Args:
        data_path (str): Data path
        batch_size (int): The number of data records in each group
    """
    # define dataset
    mnist_ds = ds.MnistDataset(data_path)  # 导入下载的MNIST数据集
    # 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

    # according to the parameters, generate the corresponding data enhancement method
    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)

    # using map to apply operations to a dataset
    mnist_ds = mnist_ds.map(operations=type_cast_op, input_columns="label")
    mnist_ds = mnist_ds.map(operations=resize_op, input_columns="image")
    mnist_ds = mnist_ds.map(operations=rescale_op, input_columns="image")
    mnist_ds = mnist_ds.map(operations=rescale_nml_op, input_columns="image")
    mnist_ds = mnist_ds.map(operations=hwc2chw_op, input_columns="image")

    # process the generated dataset
    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

 训练模型

训练数据集和模型定义完成之后呢,我们就可以开始训练模型了。但是在训练之前,我们还需要从MindSpore导入两个函数:

  • 损失函数,也就是衡量预测结果和真实标签之间的差距的函数。看过上一章的同学可能会记得,我们之前用的损失函数是真实值与预测值之差的2-范数:

图8 2-范数损失

在这里,我们使用业界最常用的交叉熵损失函数SoftmaxCrossEntropyWithLogits,对于真实标签

和预测值,它们之间的交叉熵损失计算公式为:

其中J代表数组的下标,。从MindSpore导入损失函数:

from mindspore.nn import SoftmaxCrossEntropyWithLogits
# define the loss function
net_loss = SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean') 
  • 优化器,优化器就是用来求解损失函数关于模型参数的更新梯度的,它是整个训练过程中最重要的工具!我们这里用MindSpore提供的Momentum优化器:

import mindspore.nn as nn

lr = 0.01  # 定义学习率
momentum = 0.9  # 定义Momentum优化器的超参
# define the optimizer
net_opt = nn.Momentum(network.trainable_params(), lr, momentum)  # 导入mindspore提供

 准备好损失函数和优化器之后我们就可以开始训练模型了,也非常简单,我们先把前面定义好的模型、损失函数、优化器封装成一个Model:

from mindspore import Model
net = LeNet5()
model = Model(net, net_loss , net_opt , metrics={'acc', 'loss'})

然后使用model.train接口就可以训练我们定义的LeNet5模型了:

loss_cb = LossMonitor(per_print_times=ds_train.get_dataset_size())  # 用于监控训练过程中损失函数值的变化
ds_train = create_dataset(train_data_dir)  # 传入下载的训练集的路径
model.train(num_epochs, ds_train, callbacks=[loss_cb])  # num_epochs是训练的轮数,往往训练多轮才能使模型收敛

测试训练后的模型准确率

训练结束后,调用model.eval()计算训练后的模型在测试集上面的分类准确率:

ds_eval = create_dataset(test_data_dir)  # 传入下载的训练集的路径
metrics = model.eval(ds_eval)

小结

祝贺你耐心看完了MindSpore训练模型的完整过程,如果你想动手操作一遍,但是又没有现成的环境,那么你可以使用官网提供的“在线运行”来体验一番:

图9 MindSpore官网提供的免费体验入口

这是体验过程的实操视频:

https://zhuanlan.zhihu.com/p/463229660

欢迎投稿

欢迎大家踊跃投稿,有想投稿技术干货、项目经验等分享的同学,可以添加MindSpore官方小助手:小猫子(mindspore0328)的微信,告诉猫哥哦!

昇思MindSpore官方交流QQ群 : 486831414群里有很多技术大咖助力答疑!

MindSpore官方资料

GitHub : https://github.com/mindspore-ai/mindspore

Gitee : https : //gitee.com/mindspore/mindspore

官方QQ群 : 486831 

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
心中带点小风骚的头像心中带点小风骚普通用户
上一篇 2023年6月16日
下一篇 2023年6月16日

相关推荐