【MindSpore训练营第五期】快速体验MindSpore+MindIR
MindSpore端边云统一格式 — MindIR
MindIR • 全称MindSpore IR,是MindSpore的一种基于图表示的函数式IR,定义了可扩展的图 结构以及算子的IR表示。它消除了不同后端的模型差异,一般用于跨硬件平台执行推理任务。
(1)MindSpore通过统一IR定义了网络的逻辑结构和算子的属性,将MindIR格式的模型文件 与硬件平台解耦,实现一次训练多次部署。
(2)MindIR作为MindSpore的统一模型文件,同时存储了网络结构和权重参数值。同时支持 部署到云端Serving和端侧Lite平台执行推理任务。
(3)同一个MindIR文件支持多种硬件形态的部署:
- Serving部署推理
- 端侧Lite推理部署
1-1导出LeNet网络的MindIR格式模型
于是我参照着大佬的简单的写了一个py解决了这题
1.定义网络
LeNet网络不包括输入层的情况下,共有7层:2个卷积层、2个下采样层(池化层)、3个全连接层。每层都包含不同数量的训练参数,如下图所示:
我们对全连接层以及卷积层采用Normal
进行参数初始化。
MindSpore支持TruncatedNormal
、Normal
、Uniform
等多种参数初始化方法,默认采用Normal
。具体可以参考MindSpore API的mindspore.common.initializer
模块说明。
使用MindSpore定义神经网络需要继承mindspore.nn.Cell
。Cell
是所有神经网络(Conv2d
等)的基类。
神经网络的各层需要预先在__init__
方法中定义,然后通过定义construct
方法来完成神经网络的前向构造。按照LeNet的网络结构,定义网络各层如下:
import mindspore.nn as nn
from mindspore.common.initializer import Normal
class LeNet5(nn.Cell):
"""
Lenet network structure
"""
#define the operator required
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()
#use the preceding operators to construct networks
def construct(self, x):
x = self.max_pool2d(self.relu(self.conv1(x)))
x = self.max_pool2d(self.relu(self.conv2(x)))
x = self.flatten(x)
x = self.relu(self.fc1(x))
x = self.relu(self.fc2(x))
x = self.fc3(x)
return x
MindSpore官网为我们提供了LeNet的Checkpoint文件,提供了不同版本的:https://download.mindspore.cn/model_zoo/official/cv/lenet/
*Checkpoint • 采用了Protocol Buffers格式,存储了网络中所有的参数值。一般用于训练任务中断后恢复训练,或训练后的微调(Fine Tune)任务。
在这里我选择了CPU,因为题目说可以不用训练,所以定义完网络我就直接使用了
2.模型转换
import time
import mindspore.nn as nn
from datetime import datetime
from mindspore.common.initializer import Normal
lenet = LeNet5()
# 返回模型的参数字典
param_dict = load_checkpoint("./lenet.ckpt")
# 加载参数到网络
load_param_into_net(lenet, param_dict)
input = np.random.uniform(0.0, 1.0, size=[32, 1, 32, 32]).astype(np.float32)
# 以指定的名称和格式导出文件
export(lenet, Tensor(input), file_name='lenet.mindir', file_format='MINDIR',)
t = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(" ")
print("============== Model conversion succeeded ==============")
print(t)
1-2训练一个ResNet50网络。使用训练好的checkpoint文件,导出MindIR格式模型
训练ResNet50网络生成checkpoint
参照着官网的教程使用MindSpore训练了一个ResNet50网络图像分类模型,官网的教程里那个文档适用于CPU、GPU和Ascend AI处理器环境。使用ResNet-50网络实现图像分类:https://www.mindspore.cn/tutorial/training/zh-CN/r1.1/advanced_use/cv_resnet50.html
(1)数据集的准备,这里使用的是CIFAR-10数据集。
(2)构建一个卷积神经网络,这里使用ResNet-50网络。
这里担心自己电脑跑不起来,使用了ModelArts平台提供的Notebook来跑 8vCPU+64G+1 x Tesla V100-PCIE-32G,不得不说性能很强
这里对训练好的ResNet50网络导出为MindIR 格式
import numpy as np
from resnet import resnet50
from mindspore.train.serialization import export, load_checkpoint, load_param_into_net
from mindspore import Tensor
resnet = resnet50(batch_size=32, num_classes=10)
# return a parameter dict for model
param_dict = load_checkpoint("./models/ckpt/mindspore_vision_application/train_resnet_cifar10-10_1562.ckpt")
# load the parameter into net
load_param_into_net(resnet, param_dict)
input = np.random.uniform(0.0, 1.0, size=[32, 3, 224, 224]).astype(np.float32)
export(resnet, Tensor(input), file_name='resnet_Jack20.mindir', file_format='MINDIR')
为了保存数据,我把它下载了下来,结果发现原训练好的Checkpoint文件文件过大超过了100MB不能直接下载,于是找到了另一种解决方法:
在Notebook中,新建一个“ipynb”文件,使用MoXing先将大文件从Notebook上传到OBS中,然后我再从我OBS桶了下载不就完了嘛
import moxing as mox
mox.file.copy('./train_resnet_cifar10-10_1562.ckpt', 'obs://bucket_name/train_resnet_cifar10-10_1562.ckpt')
注:其中"./train_resnet_cifar10-10_1562.ckpt”为文件在Notebook中的存储路径,"train_resnet_cifar10-10_1562.ckpt”为该文件上传到OBS的存储路径。