记录机器学习作业

我们学习的机器学习课程和华为合作,最后需要将训练完成模型部署到昇腾系列开发板上,这里记录一下踩过的坑。

模型转换

昇腾系列开发板支持的模型格式为Caffe(非Caffe2)和Tensorflow(后缀为.pb),通过华为自己开发的MindStudio 开发环境进行转换得到开发板支持的.om格式网络。
这里我一开始使用的是Pytorch框架进行自己模型的编写即训练(不得不说Pytorch是真的好用,比较起来Caffe和老版的Tensorflow太不方便了),然后通过一些方式转换成开发板支持的网络格式,主要事实为了偷懒,不太想再去学Tensorflow和Caffe。这里两种转换方式我都尝试过,下面依次讲一下踩过的坑。

Tensorflow

如果是在华为昇腾开发板上使用的话,这里不太推荐用Tensorflow去转,好像华为官方对Tensorflow(.pb)转换的支持还不是太好,可能会遇到某些算子不支持的情况,但这里还是记录一下。
可以通过ONNX(Open Neural Network Exchange)交换格式进行转换,即Pytorch转ONNX再转Tensorflow:

  1. Pytorch to ONNX
from torch.autograd import Variable
import torch.onnx
import torchvision

dummy_input = Variable(torch.randn(10, 3, 224, 224)).cuda()
model = torchvision.models.alexnet(pretrained=True).cuda()
torch.onnx.export(model, dummy_input, "alexnet.proto", verbose=True)
  1. ONNX to Tensorflow
    首先需要安装onnx和onnx_tf.这里尤其要主要Tensorflow的版本(升级到2.0后很多函数都改动了),测试Tensorflow1.15版本可用,2.0版本报错。安装方法参考这里。

import onnx
import warnings
from onnx_tf.backend import prepare
from torchvision.models.alexnet import alexnet

model = alexnet(pretrained=False)
warnings.filterwarnings('ignore') # Ignore all the warning messages in this tutorial
model = onnx.load('alexnet.onnx') # Load the ONNX file
tf_rep = prepare(model) # Import the ONNX model to Tensorflow
tf_rep.export_graph('aplexnet.pb')	# Export to Tensorflow .pb

Pytorch 转 Caffe

Pytorch转Caffe 2很方便,可以使用Pytorch官方的ONNX实现进行转换,但转Caffe就不那么方便了。
我首先尝试了微软开源的mmdnn,效果不是很好,一方面其中对Pytorch转Caffe的实现只支持版本0.4.0,并且其中实现的算子也很少,只有下列算子:

layer_map = {
     
    'onnx::Conv': 'Conv',
    'onnx::Flatten': 'Flatten',
    'onnx::Gemm': 'FullyConnected',
    'onnx::MaxPool': 'Maxpool',
    'onnx::AveragePool': 'Avgpool',
    'onnx::Dropout': 'Dropout',
    'onnx::BatchNormalization': 'BatchNormalization',
    'onnx::Add': 'Add',
    'onnx::Concat': 'Concat',
    'onnx::Relu': 'Relu',
    'onnx::Tanh': 'Tanh',
    'onnx::Sigmoid': 'Sigmoid',
    'onnx::Mul': 'Mul'

后来我在GitHub上找了一个大佬自己实现的转换工具,Here,这个工具支持的算子比较多(但也有不支持的,比如我自己用到的RefletionPad层,所以还是要主要鉴别)。转换完成后得到.prototxt以及.caffemodel格式文件,最后就可以使用华为MindStudio进行转换了,这里可能还会遇到部分算子的定义不合适的问题,比如华为的网络转换定义里面UpSample层只有scale参数,没有upsample_h以及upsample_w参数,这里可能需要手动修改.prototxt文件定义。

最后记录一个关于多GPU训练加载保存模型的问题:使用DataParallel训练后保存的网络文件,再加载进行推理时会出现问题,除非是强行在加载网络参数前将模型使用DataParallel()进行多GPU操作,或者参考链接,将相应的网络参数文件进行修改再加载。

你可能感兴趣的:(其它)