【昇腾CANN训练营第二期】【模型营】第三周作业:使用GhostNet实现手写数字识别

举报
张辉 发表于 2021/07/21 11:33:46 2021/07/21
【摘要】 【模型营】第三周作业实操

模型营第三周的作业链接为: https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=140322&fromuid=446160

具体实操作业如下:

  1. 将Lenet的两个卷积替换为GhostModule,完成MNIST网络的训练,贴出网络结构代码及训练Loss、推理acc截图即可。15分
  2. 导出成MindIRAIR格式,贴出导出部分代码截图,即导出文件截图即可。5

在作业实操之前,我们先来看一下

GhostNet的原理:

GhostNet是华为2020年提出的一种新兴的端侧神经网络架构。它提供全新的Ghost Module,可以通过cheap operations操作生成更多的feature map。

具体的思想来源是:当分析到ResNet50的经过第一个残差块处理后的feature map拿出来,可以看到以下的结果:相同颜色的feature map非常相似。。(原图中,输出的通道数很多。导致整体计算量大,存储量也很大。但是feature map高度相似)

那么,头脑灵活的华为人就心想,如果对其中一个feature map做一些cheap operations(像图中的扳手那样)变换成其他的feature map,这样,前面就不需要做那么多的计算了。

这个时候,变出来的feature map可以认为是原来feature map的一个幻影(Ghost)

cheap operations,一般是一些廉价的线性运算。实际上可能有几种不同的线性运算,如3X3,5X5线性内核等等。

Ghost模块:

用少的feature map,通过cheap operations增加feature map。


构建GhostNet:

GhostNet设计了专为小型CNN设计的Ghost bottleneck.主要由2个堆叠的Ghost Module组成。stride= 1时,看左边的结构:

其中第一个Ghost Module作为扩展层,增加了通道数。第二个Ghost Module减少通道数,与shortcut路径匹配。然后使用shortcut连接这两个Ghost Module的输入和输出。


参考资料:

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


下面先来做第一题:

  1. 将Lenet的两个卷积替换为GhostModule,完成MNIST网络的训练,贴出网络结构代码及训练Loss、推理acc截图即可。15分


GhostNet的源码地址在这里:https://gitee.com/mindspore/mindspore/tree/master/model_zoo/research/cv/ghostnet

MNIST的LeNet的源码地址在这里:https://gitee.com/mindspore/mindspore/tree/master/model_zoo/official/cv/lenet

先做下解题思路:

我们在LeNet网络代码的基础上,将GhostNet的GhostModule模块加起来。然后把LeNet模块的两个卷积替换为GhostModule(解题思路说的跟题目一模一样,还真有你的,张小白!!)

先将这个地址的ghostnet.py文件拷贝到LeNet的工程目录下:

ghostnet.py(你完全可以一字不改)

(copy 自:https://gitee.com/mindspore/mindspore/edit/master/model_zoo/research/cv/ghostnet/src/ghostnet.py

我们来修改LeNet的网络代码:

src/lenet.py

( 修改自 https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/lenet/src/lenet.py

引入GhostModule:

from ghostnet import GhostModule

替换卷积:

将self.conv1和self.conv2替换为GhostModule...

       #self.conv1 = nn.Conv2d(num_channel, 6, 5, pad_mode='valid')
        #self.conv2 = nn.Conv2d(6, 16, 5, pad_mode='valid')
        self.conv1 = GhostModule(num_channel, 6, kernel_size=5, stride=1, padding=0)
        self.conv2 = GhostModule(6, 16, kernel_size=5, stride=1, padding=0, use_act=False)

(这么简单?对,就这么简单!!!)

先在Windows本地测试下吧:

default_config.yaml文件修改:

# Builtin Configurations(DO NOT CHANGE THESE CONFIGURATIONS unless you know exactly what you are doing)
enable_modelarts: False
data_url: ""
train_url: ""
checkpoint_url: ""
data_path: ".\\dataset"
output_path: ".\\cache\\train"
load_path: ".\\cache\\train"
#device_target: Ascend
device_target: CPU
enable_profiling: False

ckpt_path: '.\\cache\\train\\'
ckpt_file: '.\\cache\\train\\checkpoint_lenet-10_1875.ckpt'

# ==============================================================================
# Training options
num_classes: 10
lr: 0.01
momentum: 0.9
epoch_size: 10
batch_size: 32
buffer_size: 1000
image_height: 32
image_width: 32
save_checkpoint_steps: 1875
keep_checkpoint_max: 10
air_name: "lenet"
device_id: 0
file_name: "lenet"
file_format: "MINDIR"
  
model_name: lenet
learning_rate: 0.002
dataset_name: 'mnist'
sink_size: -1
dataset_sink_mode: True
save_checkpoint: True
save_checkpoint_epochs: 2

# lenet acc calculation
result_path: ''
img_path: ''

---
# Config description for each option
enable_modelarts: 'Whether training on modelarts, default: False'
data_url: 'Dataset url for obs'
train_url: 'Training output url for obs'
data_path: 'Dataset path for local'
output_path: 'Training output path for local'

device_target: 'Target device type' 
enable_profiling: 'Whether enable profiling while training, default: False'
file_name: 'output file name.'
file_format: 'file format'
result_path: "result files path."
img_path: "image file path."
---
device_target: ['Ascend', 'GPU', 'CPU']
file_format: ['AIR', 'ONNX', 'MINDIR']


跟default_config.yaml 对应的相关的目录也要建起来:

包含

cache/dataset(以后OBS用)

cache/train:存放训练结果

dataset/train, dataset/test 存放MNIST数据集

其余均不变。

然后执行python train.py开始训练:

训练中会打印出Loss:

然后执行评估脚本:python eval.py

评估脚本会打印出推理的acc:

这就完成了第一个作业。

作业2:

不过第二个作业:

导出成MindIR和AIR格式,贴出导出部分代码截图,即导出文件截图即可

就不能在Windows的CPU模式下做了。

所以我们用PyCharm的ModelArts来做吧。

当然,在做第二个作业之前,还是要在ModelArts上把第一个作业重新跑通的。

在ModelArts上重做第一个作业:

修改default_config.yaml文件:

# Builtin Configurations(DO NOT CHANGE THESE CONFIGURATIONS unless you know exactly what you are doing)
enable_modelarts: False
data_url: ""
train_url: ""
checkpoint_url: ""
data_path: "/cache/dataset"
output_path: "/cache/train"
load_path: "/cache/train"
#device_target: Ascend
device_target: Ascend
enable_profiling: False

ckpt_path: '/cache/train/'
ckpt_file: '/cache/train/checkpoint_lenet-10_1875.ckpt'

# ==============================================================================
# Training options
num_classes: 10
lr: 0.01
momentum: 0.9
epoch_size: 10
batch_size: 32
buffer_size: 1000
image_height: 32
image_width: 32
save_checkpoint_steps: 1875
keep_checkpoint_max: 10
air_name: "lenet"
device_id: 0
file_name: "lenet"
file_format: "MINDIR"
  
model_name: lenet
learning_rate: 0.002
dataset_name: 'mnist'
sink_size: -1
dataset_sink_mode: True
save_checkpoint: True
save_checkpoint_epochs: 2

# lenet acc calculation
result_path: ''
img_path: ''

---
# Config description for each option
enable_modelarts: 'Whether training on modelarts, default: False'
data_url: 'Dataset url for obs'
train_url: 'Training output url for obs'
data_path: 'Dataset path for local'
output_path: 'Training output path for local'

device_target: 'Target device type' 
enable_profiling: 'Whether enable profiling while training, default: False'
file_name: 'output file name.'
file_format: 'file format'
result_path: "result files path."
img_path: "image file path."
---
device_target: ['Ascend', 'GPU', 'CPU']
file_format: ['AIR', 'ONNX', 'MINDIR']


在现有环境下跑通train.py 需要将 数据集上传到OBS:

且需要修改train.py 将数据集从OBS copy到docker,再在结束时从docker拷贝回OBS。

import moxing as mox
    mox.file.copy_parallel(src_url="obs://mindspore-lenet/MNIST_Data/", dst_url="/cache/dataset/")
   mox.file.copy_parallel(src_url="/cache/train/", dst_url="obs://mindspore-lenet/train/")

运行train.py进行训练:

设置ModelArts训练作业的参数:

运行结果如下:

。。。

。。。

训练完毕,查看OBS中的ckpt文件:

发现ckpt文件已生成。

修改评估代码eval.py,将OBS的ckpt再拷贝回docker

import moxing as mox
    mox.file.copy_parallel(src_url="obs://mindspore-lenet/train/checkpoint_lenet-10_1875.ckpt", dst_url=config.ckpt_file)
    mox.file.copy_parallel(src_url="obs://mindspore-lenet/MNIST_Data/", dst_url="/cache/dataset/")

在pycharm的ModelArts上运行:

运行结果如下:

可见,acc为:

============== {'Accuracy': 0.9868790064102564} ==============

下面真正的开始做作业2:模型转换:

修改 export.py代码:

我们就连续做两次转换吧。因为default_config.yaml文件里面,设置的config.file_format为MINDIR,我们写死第二个转换格式。

# Copyright 2020 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
"""export checkpoint file into air, onnx, mindir models"""

from src.model_utils.config import config
from src.model_utils.device_adapter import get_device_id
from src.model_utils.moxing_adapter import moxing_wrapper
from src.lenet import LeNet5

import numpy as np
import mindspore
from mindspore import Tensor, context, load_checkpoint, load_param_into_net, export
import moxing as mox

context.set_context(mode=context.GRAPH_MODE, device_target=config.device_target)
if config.device_target == "Ascend":
    context.set_context(device_id=get_device_id())

def modelarts_process():
    pass

@moxing_wrapper(pre_process=modelarts_process)
def export_lenet():
    mox.file.copy_parallel(src_url="obs://mindspore-lenet/train/checkpoint_lenet-10_1875.ckpt", dst_url=config.ckpt_file)
    # define fusion network
    network = LeNet5(config.num_classes)
    # load network checkpoint
    param_dict = load_checkpoint(config.ckpt_file)
    load_param_into_net(network, param_dict)

    # export network
    inputs = Tensor(np.ones([config.batch_size, 1, config.image_height, config.image_width]), mindspore.float32)

    print('begin convert..config.file_name='+config.file_name)

    output_filename = config.ckpt_path + config.file_name


    #export(network, inputs, file_name= config.file_name, file_format=config.file_format)
    export(network, inputs, file_name= output_filename, file_format=config.file_format)

    export(network, inputs, file_name=output_filename, file_format="AIR")

    print("end convert filename=" + output_filename)
    mox.file.copy_parallel(src_url="/cache/train/", dst_url="obs://mindspore-lenet/train/")

if __name__ == '__main__':
    export_lenet()


在pycharm的ModelArts上运行:

运行结果如下:

在OBS上被拷贝回来的MINDIR和AIR文件如下:

可见lenet.air和lenet.mindir文件都已经成功生成。

(全文完,谢谢阅读)

CANN训练营第二期 高玩赛即将开启,请点击:https://bbs.huaweicloud.com/forum/thread-129524-1-1.html

添加下方工作人员微信,添加备注:CANN训练营~ 邀请进群~

6.jpg

模型2.png

算子2.jpg

磊25.jpg

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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