iOS中深度学习部署方案实现

pytorch模型文件.pth转换为.mlmodel

Posted by JohnWayne on April 28, 2020

深度学习部署到移动端除了苹果的MLCore,还有NCNN,MNN,这篇文章尝试用工具转换.pth模型到iOS适用的.mlmodel。

笔者希望将研究生阶段做的CGAN一直到ios端,由于是image segment,资料不是特别多,遇到许多坑,这里分享出来帮助大家排坑,共同学习。


pytorch to CoreML

这里不做太多介绍,直接看流程图 process

1. 保存pytroch模型.pth文件

#在train.py的里面有torch.save()

2. pth2onnx

我的模型是Unet,在models.network里定义好了

from models.networks import *
model = UnetGenerator(3,3,8)#input_nc=3,output_nc=3,num_downs=8(数字越大层级越复杂,模型也越臃肿)
model.load_state_dict(torch.load("Unet.pth")) # pytorch模型加载
print(model)
batch_size =1  #批处理大小
input_shape = (3,256,256)   #输入数据

x = torch.randn(batch_size,*input_shape)		# 生成张量
torch.onnx.export(model, x, "Unet.onnx", verbose=True,input_names=['inputImage'],output_names=['outputImage'])#输入输出名要和后面保持一致

3. onnx2mlmodel

坑来了:一开始发现onnx的input尺寸是对的,但是转换成mlmodel后并不是Image,而是,直到在这个issue里找到了问题的所在。

https://github.com/onnx/onnx-coreml/issues/92

指定顺利解决

import sys
from onnx import onnx_pb
from onnx_coreml import convert

model_in = sys.argv[1]
model_out = sys.argv[2]
model_file = open(model_in, 'rb')
model_proto = onnx_pb.ModelProto()
model_proto.ParseFromString(model_file.read())
coreml_model = convert(model_proto,minimum_ios_deployment_target='13',preprocessing_args={'image_scale':1.0/(255.0*0.5),'red_bias':-0.5/0.5,'green_bias':-0.5/0.5,'blue_bias':-0.5/0.5,'is_bgr':False},deprocessing_args={'image_scale':255.0},image_input_names=['inputImage'],image_output_names=['outputImage'])
coreml_model.save(model_out)

执行下面语句运行

python onnx_to_coreml.py ./saved_models/Unet.onnx ./saved_models/Unet.mlmodel

另一个坑是preprocessing_args和deprocessing_args。由于我的Unet模型都是转成0~1的tensor处理的,所以要将输入图片除255,再将输出乘255。这个问题网上没有找到解释的很明确的。

其中还有个均值方差的问题,查了下面的链接后才知道为啥我的结果和电脑上的不一样。 https://zhuanlan.zhihu.com/p/110269410 ‘image_scale’:1.0/(255.0*0.5),’red_bias’:-0.5/0.5,’green_bias’:-0.5/0.5,’blue_bias’:-0.5/0.5 因为在pytorch训练时归一化transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))均值和方差都是0.5

4. 找一个写好的Xcode程序换模型

我希望是通过上传图片再转换的形式,下面这个项目挺合适,是风格迁移 https://github.com/kirualex/NSTDemo

5. 修改参数

注意划红线部分

就可以愉快的用手机实现深度学习的应用啦!


作者 [张巍]

2020 年 04月 28日