《计算机视觉之PyTorch数字图像处理》--模型部署
[复制链接]
本篇讲述模型部署,分为使用LibTorch部署、ONNX部署、OpenCV部署、OpenVINO部署,重点会倾向使用ONNX部署和OpenCV部署。
一.模型部署概述
不论对于图像的分类、分割和检测任务,完成深度学习模型的训练和测试并不是终点,将模型集成到系统中,在工程和生产中进行部署,发挥价值才是最终目的。模型部署就是在使用深度学习框架构建和训练深度学习模型后,将训练好的模型集成到项目或工程中作为整个系统的一部分,以提升系统的智能性。
目前大部分的深度学习框架大部分都使用Python作为接口语言,但在实际部署时环境是多样的。与模型在训练时既需要进行前向传播和反向传播不同,模型在部署时通常只需要进行前向传播即可。
PyTorch作为一种当前最为成熟和流行的深度学习框架之一,提供了多种模型部署方法。一种是利用TorchScript把PyTorch深度学习模型(继承自nn.Module)转化为一种能够被C++等高性能环境所使用的中间格式。另一种是,PyTorch包括一个onnx子包,该包能够把将模型导出为ONNX格式,从而使模型可以在任何支持ONNX的环境中进行部署。
ONNX是一个由社区发起的、完全开放的AI生态系统,旨在打破AI中各自为战的情况,提升AI的互操作性(interoperability)。ONNX定义了一系列标准和一组基于标准的工具集,为 AI 模型(深度学习和传统机器学习)提供可扩展的计算图模型和开源格式,并且内置张量数据类型和张量算子。ONNX整个项目以开源的方式发布在:
OpenCV长期以来作为最经典、应用最广泛的图像处理库,也提出了用于深度学习模型部署的DNN模块.DNN模块对于在无GPU环境中使用CPU进行模型的推理具有极优的性能。目前,DNN模块支持图像分类、分割、检测、文本识别、姿态估计、深度估计等各种深度学习模型,同时也支持Caffee,TensorFlow,DarkNet,ONNX等格式模型的推理。因此,当一个项目里需要经典图像处理和深度学习模型共同使用时,用OpenCV部署是最适宜的。
OpenVINO是Intel专门针对自家处理器和其他硬件平台,对各种深度学习模型进行优化和布署的一整套方案。
二.模型部署
使用LibTorch部署
LibTorch是PyTorch的C++版本,PyTorch就是LibTorch对Python语言的绑定,因此,LibTorch十分适于把PyTorch模型以C++的方式进行部署.
关于LibTorch下载如下:
在Visual Studio中新建一个C++任务后,将项目配置为Release版本,把include文件夹加入到项目编译的包含目录中,把包含.dll和.lib的lib文件夹加入到项目的库目录中,并且在链接器的输入-附加依赖选项中添加所有.lib结尾的库文件.最后还需要在项目属性页将C/C++选项下的语言菜单下的符合模式修改为“否”。
配置完成后可以在项目的主cpp文件中输入并编译代码以验证LibTorch库配置成功。编译后产生的可执行文件会保存在项目文件夹中,一个名为x64目录下的Release文件夹里。此时,还需要将LibTorch库中lib文件夹下的所有.dll复制到该目录中,在接下来进行模型部署时会使用这些动态链接库。
在配置好LibTorch库后,对于部署具体的深度学习模型主要有4个步骤:
(1)把PyTorch训练的模型使用追踪的方式转化为Torch Script格式。
(2)通过序列化保存Torch Script模型为文件。
(3)在C++工程中加载Torch Script序列化后的模型。
(4)使用模型进行预测。
由于LibTorch仅适于PyTorch框架模型的部署,不能对其他框架的模型部署,适用范围较窄。鉴于社区和各企业的推动,ONNX已经成为了深度学习模型事实上的标准,PyTorch也加入了对ONNX格式的支持,使用ONNX进行PyTorch模型的部署是一种更好的选择。
使用OpenVINO部署
OpenVINO是由Intel开发并维护的一套深度学习模型推理工具集,秉承了高性能、易开发、一次定义处处部署的理念。特别是,Intel从硬件底层对模型进行优化,从而提升模型推理的效率。
OpenVINO提供Windows,macOS和Linux等平台下的工具集,特别针对模型部署提供了OpenVINO运行时环境。OpenVINO运行时定义了有关深度学习的相关运算,支持Python和C++两种语言的部署。
以上使用LibTorch部署、OpenVINO部署略有局限性,下面将通用性更高的使用ONNX部署和OpenCV部署。
使用ONNX部署
ONNX不仅定义了一种机器学习模型的开放格式,而且提供了对于该格式模型的API和工具库。这就使得当前各种深度学习框架按照ONNX规范即可将自身模型转化为ONNX格式,从而使用ONNX提供的API,统一模型的部署,非常有利于深度学习模型的落地。目前许多深度学习框架都支持自己的模型转为ONNX格式,PyTorch也通过onnx子包实现了模型格式的转换。
对于ONNX格式的深度学习模型的部署,ONNX提供了专门用于模型的推理的ONNX Runtime环境,其官网是:https://onnxruntime.ai/。ONNX Runtime环境支持Python,C++,C#,Java,Javascript等多种语言场景,适配了Windows,Linux,Mac,Android,iOS和浏览器等多种平台,只需要掌握一套API,几乎就能适配所有应用场景,这极大便利了模型的跨平台部署。
PyTorch提供了一个onnx的子包,用于将PyTorch模型导出为onnx格式。在onnx子包中,export()函数就负责把PyTorch模型转化为ONNX格式的模型。在该函数的调用时必须设置3个参数,此外还可设置数个可选的参数:
torch.onnx.export(model, args, f, export_params=True, verbose=False, training=<TrainingMode.EVAL: 0>, input_names=None, output_names=None, operator_export_type=<OperatorExportTypes.ONNX: 0>, opset_version=None, do_constant_folding=True, dynamic_axes=None, keep_initializers_as_inputs=None, custom_opsets=None, export_modules_as_functions=False)
其中,model参数为要导出的PyTorch模型,可以是nn.Module,torch.jit.ScriptModule和torch.jit.ScriptFunction类型之一;args参数为输入模型的数据,可以是张量类型,表示模型只有1个输入,也可以是包含多个张量的元组类型,给模型多个输入;f参数为导出模型的路径,在设置时一般以.onnx作为导出模型的后缀;export_params参数表示导出的模型是否包含权重,对于完成训练的网络,包含权重时可直接用于推理即可,默认值是True,表示导出权重;verbose参数表示是否在导出时在终端时显示相关信息,默认不输出;training参数表示模型是否以训练方式导出,默认是以评估方式导出;input_names和output_names用于给模型的输入和输出设置名称,以增加模型的可读性;对于其他的一些可选参数一般无需设置,使用默认参数即可。
使用以上export()函数就可以把PyTorch模型导出为ONNX格式的模型:
from torchvision import models
import torch as tc
#创建一个模型
res18=models.resnet18(weights=models.ResNet18_Weights.DEFAULT)
res18.eval()
#生成一个正确尺寸的伪造图像
img=tc.ones((1,3,224,224))
tc.onnx.export(res18, img, "res18.onnx", input_names=['img'], output_names=['out'])
以上代码就会将PyTorch定义的resnet18模型导出为名为res18.onnx的ONNX格式的模型文件。在导出为ONNX格式后,就可以使用ONNX Runtime进行模型的部署了。在部署前,首先要安装ONNX Runtime提供的Python库。
在安装完onnxruntime库后,就可以使用InferenceSession()方法加载ONNX模型,得到用于模型推断的会话,调用会话的run()方法进行输入数据的计算,并返回模型的输出。对于输入数据,不能直接使用numpy数组,需要使用OrtValue.ortvalue_from_numpy()函数进行格式转化后才能作为模型的输入。此外,在调用run()方法时,指定输入和输出数据的名称,要与模型导出时设置的名称一致。
使用OpenCV部署
OpenCV目前提供了对Caffe,TensorFlow,Torch,Darknet等框架模型的支持,能够直接读取以上框架导出的模型,并直接进行使用,同时,OpenCV还对ONNX格式的模型提供了支持。对于Pytroch模型OpenCV并没有提供单独的模型加载接口,只能将PyTorch模型导出为ONNX格式后,按照ONNX模型的导入方法部署即可。
在将PyTorch模型导出为ONNX格式后,使用dnn下的readNetFromONNX()函数即可加载模型。在模型加载完成后,使用模型的setInput()方法设置模型的输入数据,再使用forward()方法进行推断,得到模型的输出结果。
使用OpenCV部署深度学习模型的实现可参考如下代码:
#导入OpenCV和numpy
import cv2
import numpy as np
#使用readNetFromONNX加载已经转换为ONNX格式的resnet18模型
res18=cv2.dnn.readNetFromONNX('res18.onnx')
#生成一个OpenCV格式的图像,并使用blobFromImage()方法转换为模型接受的数据类型
img=np.ones((224,224,3)).astype(np.float32)
img=cv2.dnn.blobFromImage(img)
#设置模型的输入数据
res18.setInput(img)
#使模型推断输入的数据
pred=res18.forward()
#得到分类结果
pred[0].argmax()
以上使用OpenCV部署转化为ONNX格式的PyTorch模型十分方便,并且很容易与OpenCV提供的其他图像处理方法联合使用,从而更方便的进行项目集成和工程部署。
本篇的学习,使对模型的部署流程、工具资源有了深入认识,对四种部署有了整体的了解把握,在工程实践中可以作为参考。
|