MindSpore!这款刚刚开源的深度学习框架我爱了!

本文涉及的产品
简介: MindSpore!这款刚刚开源的深度学习框架我爱了!

         

image.png


犹记得今年的华为开发者大会 HDC 2020 上,一直受人瞩目的深度学习框架 MindSpore 终于开源了。


我之前一直关注 MindSpore,还是挺期待的。MindSpore 是一款支持端、边、云独立/协同的统一训练和推理框架。与 TensorFlow、PyTorch  等流行深度学习框架对标,MindSpore 旨在大幅度降低 AI 应用开发门槛,让人工智能无处不在。


image.png

MindSpore 最大的特点就是开发门槛大大降低,提高开发效率,这样可以显著减少模型开发时间。


因此,使用MindSpore的优势可以总结为以下四点:


  • 简单的开发体验
  • 灵活的调试模式
  • 充分发挥硬件潜能
  • 全场景快速部署


既然开源了,那就赶紧上手,试一试这款开源的 MindSpore 怎么样!本文我将介绍 MindSpore 的安装和上手教程,通过一个简单的图像识别案例来跑完整个 AI 训练和测试流程。


一、MindSpore 的安装


开源框架 MindSpore 的安装方法有很多,可以在 Windows、Ubuntu 上安装,也可以在华为 Ascend 910 上安装。各种详尽的安装方法请见下面的链接:


https://www.mindspore.cn/install


下面介绍两种最简单的安装方法!


1. Docker 安装


Docker 安装最为简单,可参考:


https://gitee.com/mindspore/mindspore#docker-image


0.3.0-alpha 版本为例:


  • CPU:
    docker pull mindspore/mindspore-cpu:0.3.0-alpha
  • GPU:
    docker pull mindspore/mindspore-gpu:0.3.0-alpha


安装好后,可以看到安装的镜像,并使用下面的命令创建一个你的容器:



docker run -it mindspore/mindspore-cpu:0.3.0-alpha /bin/bash


2. Win10+Anaconda+MindSpore


使用 Win10 +Anaconda+MindSpore 的方式进行安装也非常简单,本文将采用这种方式安装 MindSpore。


在 MindSpore 安装首页里,选择安装相关配置:


  • 版本:0.3.0-alpha
  • 硬件平台:CPU
  • 操作系统:Windows-64
  • 编程语言:Python 3.7.5


首先,在 Win10 上安装 Anaconda,Anaconda 是一个开源的 Python 发行版本,其包含了 conda、Python 等 180 多个科学包及其依赖项。


然后,创建一个虚拟环境。


1). 打开 Anaconda 组件中的 Anaconda Prompt 终端:


image.png


2). 使用下面的命令,创建一个虚拟环境 mindspore(名字可以自定义),并进入虚拟环境:

conda create -n mindspore python=3.7.5 
conda activate mindspore

.3). 安装依赖库,根据 https://gitee.com/mindspore/mindspore/blob/r0.3/requirements.txt 列出的依赖库,使用 conda 命令安装。例如:



conda install numpy


4). 根据之前选择的相关配置,在网站:https://www.mindspore.cn/versions 中选择所要相应的 MindSpore 版本:


mindspore-0.3.0-cp37-cp37m-win_amd64.whl


可以将.whl 文件下载到本地,使用 pip 安装(使用 conda 命令在线安装速度可能比较慢,因此可以选择将.whl文件下载到本地,使用 pip 命令安装):



pip install mindspore-0.3.0-cp37-cp37m-win_amd64.whl


最后测试是否安装成功,进入 Python shell,执行如下命令,如果没有提示 No module named 'mindspore' 等加载错误的信息,则说明安装成功。


image.png


至此,安装完成!


二、基于本地 Jupyter 实现 MNIST 手写数据集分类


1. 安装 Jupyter Notebook


首先,在虚拟环境 mindspore 中安装 Jupyter Notebook。方法是:打开 Anaconda 组件 Anaconda Navigator。


image.png


在 Anaconda Navigator 中,Application on 选择刚建立的虚拟环境 mindspore,在组件 Jupyter Notebook 下点击 install,安装。安装完成后如下图:


image.png


点击 Notebook 下的 Launch,即可打开 Jupyter Notebook。


2. 下载数据集


MNIST 手写数据集想必大家都很熟悉了,包含 0-9 的数字,由 60000 张训练图片和 10000 张测试图片组成。


image.png


MNIST 数据集下载页面:


http://yann.lecun.com/exdb/mnist/


使用 MindSpore,我们可以通过直接定义一个 download_dataset 函数来自动下载 MNIST 数据集:

def download_dataset():
    """Download the dataset from http://yann.lecun.com/exdb/mnist/."""
    print("******Downloading the MNIST dataset******")
    train_path = "./MNIST_Data/train/"
    test_path = "./MNIST_Data/test/"
    train_path_check = os.path.exists(train_path)
    test_path_check = os.path.exists(test_path)
    if train_path_check == False and test_path_check ==False:
        os.makedirs(train_path)
        os.makedirs(test_path)
    train_url = {"http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz", "http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz"}
    test_url = {"http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz", "http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz"}
    for url in train_url:
        url_parse = urlparse(url)
        # split the file name from url
        file_name = os.path.join(train_path,url_parse.path.split('/')[-1])
        if not os.path.exists(file_name.replace('.gz','')):
            file = urllib.request.urlretrieve(url, file_name)
            unzipfile(file_name)
            os.remove(file_name)
    for url in test_url:
        url_parse = urlparse(url)
        # split the file name from url
        file_name = os.path.join(test_path,url_parse.path.split('/')[-1])
        if not os.path.exists(file_name.replace('.gz','')):
            file = urllib.request.urlretrieve(url, file_name)
            unzipfile(file_name)
            os.remove(file_name)


该函数实现将数据集自动下载在本地的 ./MNIST_Data 目录下,训练集放在子目录 /train 下,测试集放在子目录 /test 下。


3. 数据预处理


MNIST 数据集准备好了之后,下一步就要对数据集进行一些预处理,包括图片尺寸调整为 32x32(因为我们使用的是 LeNet-5 网络,后面会介绍),像素归一化、batch_size 设为 32(可调整),等等。


MindSpore 提供了 mindspore.dataset.MnistDataset 来直接定义 Minist 数据集,非常方便。使用 mindspore.dataset.MnistDataset.map 映射函数,将数据操作应用到数据集。


我们定义 create_dataset() 函数来创建数据集:

def create_dataset(data_path, batch_size=32, repeat_size=1,
                   num_parallel_workers=1):
    """ create dataset for train or test
    Args:
        data_path: Data path
        batch_size: The number of data records in each group
        repeat_size: The number of replicated data records
        num_parallel_workers: The number of parallel workers
    """
    # define dataset
    mnist_ds = ds.MnistDataset(data_path)
    # define operation parameters
    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
    # define map operations
    resize_op = CV.Resize((resize_height, resize_width), interpolation=Inter.LINEAR)  # Resize images to (32, 32)
    rescale_nml_op = CV.Rescale(rescale_nml, shift_nml) # normalize images
    rescale_op = CV.Rescale(rescale, shift) # rescale images
    hwc2chw_op = CV.HWC2CHW() # change shape from (height, width, channel) to (channel, height, width) to fit network.
    type_cast_op = C.TypeCast(mstype.int32) # change data type of label to int32 to fit network
    # apply map operations on images
    mnist_ds = mnist_ds.map(input_columns="label", operations=type_cast_op, num_parallel_workers=num_parallel_workers)
    mnist_ds = mnist_ds.map(input_columns="image", operations=resize_op, num_parallel_workers=num_parallel_workers)
    mnist_ds = mnist_ds.map(input_columns="image", operations=rescale_op, num_parallel_workers=num_parallel_workers)
    mnist_ds = mnist_ds.map(input_columns="image", operations=rescale_nml_op, num_parallel_workers=num_parallel_workers)
    mnist_ds = mnist_ds.map(input_columns="image", operations=hwc2chw_op, num_parallel_workers=num_parallel_workers)
    # apply DatasetOps
    buffer_size = 10000
    mnist_ds = mnist_ds.shuffle(buffer_size=buffer_size)  # 10000 as in LeNet train script
    mnist_ds = mnist_ds.batch(batch_size, drop_remainder=True)
    mnist_ds = mnist_ds.repeat(repeat_size)
    return mnist_ds


通过上面的函数,就完成了对刚下载的 MNIST 数据集的预处理。


4. 定义网络


LeNet-5 是一种用于手写体字符识别的非常高效的卷积神经网络。LeNet-5 共有 7 层,不包含输入,每层都包含可训练参数;每个层有多个 Feature Map,每个 FeatureMap通过一种卷积滤波器提取输入的一种特征。


image.png


1) 模型初始化


使用 mindspore.common.initializer.TruncatedNormal 方法对参数进行初始化,定义 conv 和 fc_with_initialize 分别对卷积层和全连接层进行初始化。

import mindspore.nn as nn
from mindspore.common.initializer import TruncatedNormal
def conv(in_channels, out_channels, kernel_size, stride=1, padding=0):
    """Conv layer weight initial."""
    weight = weight_variable()
    return nn.Conv2d(in_channels, out_channels,
                     kernel_size=kernel_size, stride=stride, padding=padding,
                     weight_init=weight, has_bias=False, pad_mode="valid")
def fc_with_initialize(input_channels, out_channels):
    """Fc layer weight initial."""
    weight = weight_variable()
    bias = weight_variable()
    return nn.Dense(input_channels, out_channels, weight, bias)
def weight_variable():
    """Weight initial."""
    return TruncatedNormal(0.02)


使用 mindspore.common.initializer.TruncatedNormal 方法,可以非常便捷地实现网络权重系数的初始化操作,不需要自定义初始化函数。


2) 定义 LeNet-5 网络


MindSpore 来定义 LeNet-5 网络也很简单,根据网络结构,定义相应的卷积层和全连接层即可。在初始化函数 __init__ 种定义神经网络的各层,然后通过定义 construct 方法来完成神经网络的前向构造。

class LeNet5(nn.Cell):
    """Lenet network structure."""
    # define the operator required
    def __init__(self):
        super(LeNet5, self).__init__()
        self.conv1 = conv(1, 6, 5)
        self.conv2 = conv(6, 16, 5)
        self.fc1 = fc_with_initialize(16 * 5 * 5, 120)
        self.fc2 = fc_with_initialize(120, 84)
        self.fc3 = fc_with_initialize(84, 10)
        self.relu = nn.ReLU()
        self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2)
        self.flatten = nn.Flatten()
    # use the preceding operators to construct networks
    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


LeNet-5 是一个非常典型且简单的卷积神经网络,从 construct 方法可以详细看到 LeNet-5 各层的结构。


3) 定义损失函数


MindSpore 支持的损失函数有 SoftmaxCrossEntropyWithLogits、L1Loss、MSELoss 等。这里使用 SoftmaxCrossEntropyWithLogits 交叉熵损失函数。

from mindspore.nn.loss import SoftmaxCrossEntropyWithLogits
# define the loss function
net_loss = SoftmaxCrossEntropyWithLogits(is_grad=False, sparse=True, reduction='mean')


4) 定义网络梯度下降算法


MindSpore 支持的梯度下降算法有 Adam、AdamWeightDecay、Momentum 等。这里使用流行的 Momentum 算法。其中,学习率设为 0.01,momentum 参数设为 0.9。

# learning rate setting
lr = 0.01
momentum = 0.9
# define the optimizer
net_opt = nn.Momentum(network.trainable_params(), lr, momentum)


5. 训练网络


1) 模型保存


mindspore.train.callback.ModelCheckpoint 方法可以保存网络模型和参数。

config_ck = CheckpointConfig(save_checkpoint_steps=1875, keep_checkpoint_max=10)
# save the network model and parameters for subsequence fine-tuning
ckpoint_cb = ModelCheckpoint(prefix="checkpoint_lenet", config=config_ck)


2) 训练网络


训练网络使用 model.train 方法进行。这里把 epoch_size 设置为 1,对数据集进行 1 个迭代的训练。训练的过程中会打印 loss 值的变化。

from mindspore.nn.metrics import Accuracy
from mindspore.train.callback import LossMonitor
from mindspore.train import Model
def train_net(args, model, epoch_size, mnist_path, repeat_size, ckpoint_cb, sink_mode):
    """define the training method"""
    print("============== Starting Training ==============")
    #load training dataset
    ds_train = create_dataset(os.path.join(mnist_path, "train"), 32, repeat_size)
    model.train(epoch_size, ds_train, callbacks=[ckpoint_cb, LossMonitor()], dataset_sink_mode=sink_mode)
epoch_size = 1
mnist_path = "./MNIST_Data
# group layers into an object with training and evaluation features
model = Model(network, net_loss, net_opt, metrics={"Accuracy": Accuracy()})
train_net(args, model, epoch_size, mnist_path, repeat_size, ckpoint_cb)


其中,mnist_path 是 MNIST 数据集路径。


3) 硬件信息


在主函数中,别忘了配置 MindSpore 运行的硬件信息。因为我们是在 CPU 环境下,所以 ‘--device_target’ 设置为 “CPU”。

parser = argparse.ArgumentParser(description='MindSpore LeNet Example')
parser.add_argument('--device_target', type=str, default="CPU", choices=['Ascend', 'GPU', 'CPU'],
                        help='device where the code will be implemented (default: CPU)')
args = parser.parse_args(args=[])
context.set_context(mode=context.GRAPH_MODE, device_target=args.device_target)



这里的 '--device_target' 默认是 “CPU”,根据硬件情况也可以选择 “Ascend” 或 “GPU”。使用的是图模式 “context.GRAPH_MODE”。


4) 模型训练


执行程序,模型训练开始。训练过程中会打印 loss 值:

...
epoch: 1 step: 262, loss is 1.9212162
epoch: 1 step: 263, loss is 1.8498616
epoch: 1 step: 264, loss is 1.7990671
epoch: 1 step: 265, loss is 1.9492403
epoch: 1 step: 266, loss is 2.0305142
epoch: 1 step: 267, loss is 2.0657792
epoch: 1 step: 268, loss is 1.9582214
epoch: 1 step: 269, loss is 0.9459006
epoch: 1 step: 270, loss is 0.8167224
epoch: 1 step: 271, loss is 0.7432692
...


可以看到 loss 总体来说会逐步减小,精度逐步提高,最终的 loss 为 0.067。


训练完成之后,得到保存的模型文件:


checkpoint_lenet-1_1875.ckpt


6. 模型测试


在得到模型文件后,使用 model.eval() 接口读入测试数据集,通过模型运行测试数据集得到的结果。定义测试函数 test_net():

def test_net(args, network, model, mnist_path):
    """Define the evaluation method."""
    print("============== Starting Testing ==============")
    # load the saved model for evaluation
    param_dict = load_checkpoint("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(args, network, model, mnist_path)
============== Starting Testing ==============
============== Accuracy:{'Accuracy': 0.9663461538461539} ==============

最终,可以看到刚刚训练的 LeNet-5 网络模型在测试集上的精度是 96.63%,效果非常不错。


至此,我们使用 MindSpore 框架训练 LeNet-5 模型已经完成。实现了基于本地 Jupyter 实现 MNIST 手写数据集分类。总的来说,MindSpore 提供了很多模块化的方法来进行模型搭建和训练,非常方便我们能够快速搭建一个神经网络模型。大家可以根据自己实际需求,上手搭建一个自己的神经网络试试。


本节完整代码:


https://gitee.com/mindspore/docs/blob/master/tutorials/tutorial_code/lenet.py


相关实践学习
基于阿里云DeepGPU实例,用AI画唯美国风少女
本实验基于阿里云DeepGPU实例,使用aiacctorch加速stable-diffusion-webui,用AI画唯美国风少女,可提升性能至高至原性能的2.6倍。
相关文章
|
13天前
|
机器学习/深度学习 API 语音技术
|
13天前
|
机器学习/深度学习 PyTorch API
|
4月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
【深度学习】Tensorflow、MindSpore框架介绍及张量算子操作实战(超详细 附源码)
【深度学习】Tensorflow、MindSpore框架介绍及张量算子操作实战(超详细 附源码)
65 0
|
9月前
|
机器学习/深度学习 移动开发 算法
Python垃圾识别系统,TensorFlow+Django网页框架+深度学习模型+卷积网络【完整代码】
垃圾识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对5种垃圾数据集进行训练,最后得到一个识别精度较高的模型。并基于Django,开发网页端操作平台,实现用户上传一张垃圾图片识别其名称。
165 0
|
5月前
|
机器学习/深度学习 PyTorch 算法框架/工具
深度学习Pytorch框架Tensor张量
深度学习Pytorch框架Tensor张量
45 0
|
8月前
|
机器学习/深度学习 算法 PyTorch
深度学习框架Pytorch学习笔记
深度学习框架Pytorch学习笔记
|
11月前
|
机器学习/深度学习 缓存 人工智能
深度学习进阶篇-预训练模型[3]:XLNet、BERT、GPT,ELMO的区别优缺点,模型框架、一些Trick、Transformer Encoder等原理详解
深度学习进阶篇-预训练模型[3]:XLNet、BERT、GPT,ELMO的区别优缺点,模型框架、一些Trick、Transformer Encoder等原理详解
深度学习进阶篇-预训练模型[3]:XLNet、BERT、GPT,ELMO的区别优缺点,模型框架、一些Trick、Transformer Encoder等原理详解
|
1天前
|
机器学习/深度学习 边缘计算 监控
深度学习赋能智能监控:图像识别技术的革新与应用
【4月更文挑战第23天】 随着人工智能的迅猛发展,深度学习技术在图像处理领域取得突破性进展,特别是在智能监控系统中,基于深度学习的图像识别已成为提升系统智能化水平的核心动力。本文旨在探讨深度学习如何优化智能监控系统中的图像识别过程,提高监控效率和准确性,并分析其在不同应用场景下的具体实施策略。通过深入剖析关键技术、挑战及解决方案,本文为读者提供了一个关于深度学习图像识别技术在智能监控领域应用的全面视角。
|
1天前
|
机器学习/深度学习 存储 边缘计算
深度学习在图像识别中的应用与挑战
【4月更文挑战第23天】 随着人工智能技术的飞速发展,深度学习作为其重要分支之一,在图像识别领域取得了显著的成果。本文将探讨深度学习在图像识别中的应用,分析其优势和面临的挑战,并展望未来的发展趋势。
|
3天前
|
机器学习/深度学习 数据采集 自动驾驶
基于深度学习的图像识别技术在自动驾驶系统中的应用
【4月更文挑战第21天】 本文章深入探讨了深度学习技术在自动驾驶车辆图像识别领域的应用。不同于传统的摘要方式,本文将直接点出研究的核心价值和实际应用成果。我们专注于卷积神经网络(CNN)的创新设计,其在复杂道路场景下的行人和障碍物检测中的高效表现,以及这些技术如何整合到自动驾驶系统中以增强安全性和可靠性。通过实验验证,我们的模型在公开数据集上达到了行业领先水平的准确率,并且在真实世界的测试场景中展现了卓越的泛化能力。