Python: 从PYTORCH导出模型到ONNX,并使用ONNX运行时运行它
本教程我们将描述如何将PyTorch中定义的模型转换为ONNX格式,然后使用ONNX运行时运行它。
ONNX运行时是一个针对ONNX模型的性能关注引擎,它可以高效地跨多个平台和硬件(Windows、Linux和Mac以及cpu和gpu)进行推理。ONNX运行时已被证明在多个模型上显著提高了性能。
对于本教程,您将需要安装ONNX和ONNX运行时。您可以使用pip install ONNX onnxruntime获得ONNX和ONNX运行时的二进制构建。请注意,ONNX运行时兼容Python 3.6到3.9版本。
注意: 本教程需要PyTorch主分支,它可以按照“
https://github.com/pytorch/pytorch#from-source
”说明安装。
# Some standard imports
import io
import numpy as np
from torch import nn
import torch.utils.model_zoo as model_zoo
import torch.onnx
超分辨率是提高图像、视频分辨率的一种方法,广泛应用于图像处理或视频编辑。本教程我们将使用一个小的超分辨率模型。
首先,让我们在PyTorch中创建一个超分辨率模型。该模型使用Shi等人在“使用有效的亚像素卷积神经网络实现实时单图像和视频超分辨率”中描述的有效的亚像素卷积层,以提高图像的分辨率。
该模型将图像YCbCr的Y分量作为输入,并以超分辨率输出放大后的Y分量。
这个模型直接来自PyTorch的例子,没有修改:
# Super Resolution model definition in PyTorch
import torch.nn as nn
import torch.nn.init as init
class SuperResolutionNet(nn.Module):
def __init__(self, upscale_factor, inplace=False):
super(SuperResolutionNet, self).__init__()
self.relu = nn.ReLU(inplace=inplace)
self.conv1 = nn.Conv2d(1, 64, (5, 5), (1, 1), (2, 2))
self.conv2 = nn.Conv2d(64, 64, (3, 3), (1, 1), (1, 1))
self.conv3 = nn.Conv2d(64, 32, (3, 3), (1, 1), (1, 1))
self.conv4 = nn.Conv2d(32, upscale_factor ** 2, (3, 3), (1, 1), (1, 1))
self.pixel_shuffle = nn.PixelShuffle(upscale_factor)
self._initialize_weights()
def forward(self, x):
x = self.relu(self.conv1(x))
x = self.relu(self.conv2(x))
x = self.relu(self.conv3(x))
x = self.pixel_shuffle(self.conv4(x))
return x
def _initialize_weights(self):
init.orthogonal_(self.conv1.weight, init.calculate_gain('relu'))
init.orthogonal_(self.conv2.weight, init.calculate_gain('relu'))
init.orthogonal_(self.conv3.weight, init.calculate_gain('relu'))
init.orthogonal_(self.conv4.weight)
# Create the super-resolution model by using the above model definition.
torch_model = SuperResolutionNet(upscale_factor=3)
通常,你会训练这个模型;然而,本教程我们将下载一些预先训练过的力量。请注意,这个模型并不是为了获得良好的准确性而完全训练的,这里仅用于演示目的。
在导出模型之前调用torch_model.eval()或torch_model.train(False)是很重要的,以便将模型转换为推理模式。这是必需的,因为像dropout或batchnorm这样的操作符在推理和训练模式中的行为不同。
# Load pretrained model weights
model_url = 'https://s3.amazonaws.com/pytorch/test_data/export/superres_epoch100-44c6958e.pth'
batch_size = 1 # just a random number
# Initialize model with the pretrained weights
map_location = lambda storage, loc: storage
if torch.cuda.is_available():
map_location = None
torch_model.load_state_dict(model_zoo.load_url(model_url, map_location=map_location))
# set the model to inference mode
torch_model.eval()
在PyTorch中导出模型可以通过跟踪或脚本实现。
本教程将使用一个通过跟踪导出的模型作为示例。
要导出模型,我们调用torch.onnx.export()函数。
这将执行模型,记录用于计算输出的操作符的跟踪。
因为export运行这个模型,所以我们需要提供一个输入张量x。只要它的类型和大小正确,其中的值就可以是随机的。
注意,除非指定为动态轴,否则输出的ONNX图中的所有输入尺寸都是固定的。
在本例中,我们使用batch_size 1的输入导出模型,然后在torch.onnx.export()中的dynamic_axes参数中将第一个维度指定为动态的。
因此,导出的模型将接受size [batch_size, 1, 224, 224]的输入,其中batch_size可以是可变的。
要了解关于PyTorch的导出接口的更多细节,请查看torch.onnx文档。
# Input to the model
x = torch.randn(batch_size, 1, 224, 224, requires_grad=True)
torch_out = torch_model(x)
# Export the model
torch.onnx.export(torch_model, # model being run
x, # model input (or a tuple for multiple inputs)
"super_resolution.onnx", # where to save the model (can be a file or file-like object)
export_params=True, # store the trained parameter weights inside the model file
opset_version=10, # the ONNX version to export the model to
do_constant_folding=True, # whether to execute constant folding for optimization
input_names = ['input'], # the model's input names
output_names = ['output'], # the model's output names
dynamic_axes={'input' : {0 : 'batch_size'}, # variable lenght axes
'output' : {0 : 'batch_size'}})
我们还计算了模型之后的输出torch_out,我们将使用它来验证我们导出的模型在ONNX运行时计算出的值相同。
但是在用ONNX运行时验证模型的输出之前,我们将用ONNX的API检查ONNX模型。
首先,onnx.load("super_resolution.onnx")将加载保存的模型并输出一个onnx.ModelProto结构(用于绑定ML模型的顶层文件/容器格式,更多信息参考
onnx.proto documentation
文档)。
然后,onnx_checker .check_model(onnx_model)将验证模型的结构,并确认模型有一个有效的模式。
通过检查模型的版本、图的结构、节点及其输入和输出来验证ONNX图的有效性。
import onnx
onnx_model = onnx.load("super_resolution.onnx")
onnx.checker.check_model(onnx_model)
现在让我们使用ONNX运行时的Python api来计算输出。
这部分通常可以在单独的进程或另一台机器上完成,但我们将继续在同一进程中进行,以便验证ONNX运行时和PyTorch为网络计算的值是否相同。
为了使用ONNX运行时运行模型,我们需要使用所选的配置参数(这里我们使用默认配置)为模型创建一个推断会话。
创建会话之后,我们使用run() api对模型进行评估。这个调用的输出是一个列表,其中包含由ONNX运行时计算的模型的输出。
import onnxruntime
ort_session = onnxruntime.InferenceSession("super_resolution.onnx")
def to_numpy(tensor):
return tensor.detach().cpu().numpy() if tensor.requires_grad else tensor.cpu().numpy()
# compute ONNX Runtime output prediction
ort_inputs = {ort_session.get_inputs()[0].name: to_numpy(x)}
ort_outs = ort_session.run(None, ort_inputs)
# compare ONNX Runtime and PyTorch results
np.testing.assert_allclose(to_numpy(torch_out), ort_outs[0], rtol=1e-03, atol=1e-05)
print("Exported model has been tested with ONNXRuntime, and the result looks good!")
我们应该看到PyTorch和ONNX运行时的输出在数字上与给定的精度匹配(rtol=1e-03和atol=1e-05)。
作为附注,如果他们不匹配,那么ONNX导出有问题,所以请联系我们。
Running the model on an image using ONNX Runtime
到目前为止,我们已经从PyTorch导出了一个模型,并展示了如何加载它并在ONNX运行时使用一个虚拟张量作为输入来运行它。
在本教程中,我们将使用一张著名的猫的图片,如下图所示:
首先,让我们加载图像,预处理它使用标准的PIL python库。注意,这种预处理是为训练/测试神经网络而处理数据的标准实践。
我们首先调整图像的大小以适应模型输入的大小(224x224)。然后我们将图像分割成Y、Cb和Cr三个分量。
这些分量代表灰度图像(Y),以及色度分量蓝差(Cb)和红差(Cr)。对于人眼来说,Y分量更敏感,我们感兴趣的是我们要转换的这个分量。
在提取Y分量后,我们将它转换成一个张量,这将是我们模型的输入。
from PIL import Image
import torchvision.transforms as transforms
img = Image.open("./_static/img/cat.jpg")
resize = transforms.Resize([224, 224])
img = resize(img)
img_ycbcr = img.convert('YCbCr')
img_y, img_cb, img_cr = img_ycbcr.split()
to_tensor = transforms.ToTensor()
img_y = to_tensor(img_y)
img_y.unsqueeze_(0)
现在,作为下一步,让我们使用表示灰度调整后的猫图像的张量,并在ONNX运行时中运行超分辨率模型,如前所述。
ort_inputs = {ort_session.get_inputs()[0].name: to_numpy(img_y)}
ort_outs = ort_session.run(None, ort_inputs)
img_out_y = ort_outs[0]
此时,模型的输出是一个张量。现在,我们将处理模型的输出,从输出张量中构造出最终的输出图像,并保存图像。后处理步骤在这里采用了超分辨率模型的PyTorch实现(
https://github.com/pytorch/examples/blob/master/super_resolution/super_resolve.py
)。
img_out_y = Image.fromarray(np.uint8((img_out_y[0] * 255.0).clip(0, 255)[0]), mode='L')
# get the output image follow post-processing step from PyTorch implementation
final_img = Image.merge(
"YCbCr", [
img_out_y,
img_cb.resize(img_out_y.size, Image.BICUBIC),
img_cr.resize(img_out_y.size, Image.BICUBIC),
]).convert("RGB")
# Save the image, we will compare this with the output image from mobile device
final_img.save("./_static/img/cat_superres_with_ort.jpg")
ONNX运行时是一个跨平台引擎,你可以在多个平台上运行它,包括cpu和gpu。
ONNX运行时也可以部署到云上,使用Azure机器学习服务进行模型推理。更多的信息在这里。
这里有更多关于ONNX运行时性能的信息。
关于ONNX运行时的更多信息,请点击这里。
脚本的总运行时间:(0分钟0.000秒)
Python: 从PYTORCH导出模型到ONNX,并使用ONNX运行时运行它本教程我们将描述如何将PyTorch中定义的模型转换为ONNX格式,然后使用ONNX运行时运行它。ONNX运行时是一个针对ONNX模型的性能关注引擎,它可以高效地跨多个平台和硬件(Windows、Linux和Mac以及cpu和gpu)进行推理。ONNX运行时已被证明在多个模型上显著提高了性能。对于本教程,您将需要安装ONNX和ONNX运行时。您可以使用pip install ONNX onnxruntime获得ONNX
1. 搭建自己的简单二分类网络,
使用
pytorch
训练和测试;
2. 将
pytorch
训练的pth
模型
转换成
ONNX
,并编码测试;
3. 含训练和测试数据,含训练ok的pth
模型
和
ONNX
模型
,含完整
python
和C++实现;
4.
使用
方法:首先
运行
“TrainTestConvert
Onnx
.py”执行“训练数据读入、
模型
训练、
模型
测试、
导出
onnx
”,再
运行
“Test
Onnx
.cpp”测试
onnx
(需要配置OpenCV);
git clone https://github.com/dayyass/
pytorch
_ner.git
# install dependencies
cd
pytorch
_ner
pip install -r requirements.txt
用户界面仅包含一个文件config.yaml 。 更改config.yaml以创建所需的配置,并
使用
以下命令启动管道:
python
main.py --config config.yaml
如果未指定--config参数,则
使用
config.yaml。
要将训练后的
模型
导出
到
ONNX
,请
使用
config.yaml:
save:
export_
onnx
: Tr
使用
ONNX
导出
和
运行
模型
本教程系列将涵盖txtai的主要用例,这是一个 AI 驱动的语义搜索平台。该系列的每章都有相关代码,可也可以在colab 中
使用
。
colab 地址
https://dev.to/neuml/tutorial-series-on-txtai-ibg
PyTorch
警告 UserWarning: You are trying to export the model with
onnx
:Upsample for
ONNX
opset version 9
flyfish
警告详细内容
PyTorch
的pth
模型
转换
onnx
格式时出现的警告
lib/
python
3.6/site-packages/torch/
onnx
/symbolic_helper.py:267: UserWarning: You are trying to export the model
在
使用
PyTorch
进行网络训练得到.pth
模型
文件后,我们可能会做一些
模型
部署和加速的工作。这里一般会涉及到将
PyTorch
模型
转为
ONNX
模型
的过程。
PyTorch
自带了
ONNX
转换方法(torch.
onnx
.export),可以很方便的将一些仅包含通用算子的网络的
PyTorch
模型
转为
ONNX
格式。
准备
模型
文件
将
PyTorch
模型
文件准备好,放在’./weights/torch.pth’路径下。
编写转换代码
import torch
TORCH_WEIGHT_PATH =
环境要求:
python
version >= 3.6
模型
训练:
python
3 train.py
模型
导出
:
python
3 models/export.py --weights "xxx.pt"
转换rknn:
python
3
onnx
_to_rknn.py
模型
推理:
python
3 rknn_detect_yolov5.py
注意事项:如果训练尺寸不是640那么,anchors会自动聚类重新生成,生成的结果在训练时打印在控制台,或者通过动态查看torch
模型
类属性获取,如果anchors不对应那么结果就会出现问题。
建议:在训练时如果size不是640,那么可以先通过聚类得到anchors并将新的anchors写入到
模型
配置文件中,然后再训练,防止动态获取的anchors在rknn上预测不准的问题。训练参数别忘记加上 --noautoanchor
文章目录1 准备工作1.1 efficientnet网络介绍1.2 efficientnet训练分类数据集2 为何要转3 安装相关依赖4 转换过程5 检验生成的
onnx
模型
5.1
onnx
.checker检验5.2 np.testing.assert_allclose校验5.3 warning消除记录5.4 测试一张图片校验6 整合到一起的代码
1 准备工作
1.1 efficientnet网络介绍
详见参考链接EfficientNet网络结构及代码详解。
1.2 efficientnet训练分类数据集
### 回答1:
MobileNetV2是一种用于图像分类和目标检测的轻量级卷积
神经网络
模型
,
PyTorch
是一种常用的
深度学习
框架,而
ONNX
是一种用于
模型
的开放式
神经网络
交换格式。
在
PyTorch
中
使用
MobileNetV2进行训练,可以通过加载预训练的
模型
,并进行微调来实现。我们可以
使用
PyTorch
提供的torchvision模块来加载MobileNetV2
模型
的预训练权重,然后将数据集导入
模型
进行训练。
训练过程中,我们可以
使用
交叉熵损失函数和随机梯度下降(SGD)优化器。通过迭代训练数据集,不断更新
模型
的权重参数,使
模型
能够应对新的输入数据。
训练完成后,我们可以将
PyTorch
模型
转换为
ONNX
格式,以便在其他平台上
使用
。在
PyTorch
中,可以
使用
torch.
onnx
.export()函数将
模型
转换为
ONNX
格式。此函数需要指定输入张量的形状和文件路径,以保存转换后的
模型
。
使用
ONNX
格式的
模型
,可以在不同的
深度学习
框架(如TensorFlow)或硬件平台上进行推理和部署。通过将
模型
转换为
ONNX
格式,可以实现更好的跨平台兼容性,并加速
模型
的部署过程。
总之,
使用
PyTorch
训练MobileNetV2
模型
,并将其转换为
ONNX
格式,可以提供一种灵活而高效的方式,用于图像分类和目标检测任务,并实现跨平台部署的便利性。
### 回答2:
MobileNetV2是一种轻量级的卷积
神经网络
,适用于移动设备和嵌入式系统。
PyTorch
是一个流行的
深度学习
框架,提供了训练和部署
模型
的功能。而
ONNX
是一种开放的中间表示格式,可以在不同的
深度学习
框架之间共享
模型
。
要
使用
PyTorch
训练MobileNetV2
模型
并将其转换为
ONNX
格式,可以按照以下步骤进行。
首先,需要导入所需的
PyTorch
和
ONNX
库:
```
python
import torch
import torchvision.models as models
import
onnx
然后,加载MobileNetV2
模型
并进行训练,可以
使用
PyTorch
提供的预训练
模型
或自定义训练数据集来进行训练。训练过程可以根据具体任务进行配置,包括选择优化器、损失函数和训练迭代次数等。
训练完成后,可以将
模型
保存为
PyTorch
的.pth文件:
```
python
torch.save(model.state_dict(), 'mobilenetv2.pth')
接下来,
使用
ONNX
库将.pth文件转换为
ONNX
格式:
```
python
dummy_input = torch.randn(1, 3, 224, 224) # 定义一个虚拟输入作为示例
model = models.mobilenet_v2(pretrained=True) # 加载预训练
模型
model.load_state_dict(torch.load('mobilenetv2.pth')) # 加载训练权重
torch.
onnx
.export(model, dummy_input, 'mobilenetv2.
onnx
', verbose=True) #
导出
为
ONNX
模型
最后,将训练和转换得到的.
onnx
文件用于推理和部署。可以
使用
ONNX
Runtime或其他支持
ONNX
格式的推理框架加载和
运行
模型
。
通过以上步骤,我们可以
使用
PyTorch
训练MobileNetV2
模型
,并将其转换为
ONNX
格式,以实现
模型
的跨框架和跨平台应用。
### 回答3:
MobileNetV2是一种轻量级的
神经网络
架构,适用于移动设备等资源受限的环境下进行图像分类任务。
PyTorch
是一种
深度学习
框架,具有易用性和高效性,训练
神经网络
模型
时是
使用
PyTorch
进行的。
ONNX
是一种开放的
深度学习
模型
格式,能够在不同的
深度学习
框架之间进行
模型
的互操作性。将MobileNetV2
模型
训练为
ONNX
格式,可以使得该
模型
能够
运行
在不同的
深度学习
框架中,而不仅仅局限于
PyTorch
。
要将MobileNetV2
模型
训练为
ONNX
格式,可以按照以下步骤进行:
1. 准备训练数据集:
使用
包含图像和对应标签的数据集进行训练,例如ImageNet数据集。
2. 定义并训练MobileNetV2
模型
:
使用
PyTorch
定义MobileNetV2
模型
,并
使用
训练数据集进行
模型
训练。
3.
导出
模型
为
ONNX
格式:在
模型
训练完成后,
使用
PyTorch
提供的
导出
函数将训练好的
模型
转换为
ONNX
格式。这可以通过
调用
`torch.
onnx
.export()`函数完成,将
模型
定义、训练好的参数和输入的形状等信息
导出
为
ONNX
模型
文件。
4. 验证
导出
的
ONNX
模型
:载入
导出
的
ONNX
模型
,并
使用
测试数据进行验证,以确保
模型
导出
正确无误。
通过将MobileNetV2
模型
训练为
ONNX
格式,可以使得该
模型
能够在其他
深度学习
框架中进行部署和应用。此外,
ONNX
格式还支持
模型
量化和优化等功能,有助于进一步减小
模型
的体积和提高
模型
的执行效率。