Python环境依赖
CPU版本推理:onnxruntime
GPU版本推理:onnxruntime-gpu
torchvision
PIL
torch
netron
把 PyTorch 模型转换成 ONNX 模型时,我们往往只需要轻松地调用一句torch.onnx.export就可以了。这个函数的接口看上去简单,但它在使用上还有着诸多的注意事项。
前三个必选参数为模型、模型输入、导出的 onnx 文件名,我们对这几个参数已经很熟悉了。我们来着重看一下后面的一些常用可选参数。
import torch
# 这一块区域为模型加载的步骤具体可以依据自己使用情况替换
from model import efficientnetv2_s as create_model
device = "cpu"
model = create_model(num_classes=2).to(device)
model_weight_path = "./weights1/model-54.pth"
model.load_state_dict(torch.load(model_weight_path, map_location=device))
model.eval()
batch_size = 1 # 批处理大小
input_shape = (3, 224, 224) # 输入数据
x = torch.randn(batch_size, *input_shape) # 生成张量
export_onnx_file = "test.onnx" # 目的ONNX文件名
torch.onnx.export(model,
x,
export_onnx_file,
opset_version=10,
do_constant_folding=True, # 是否执行常量折叠优化
input_names=["input"], # 输入名
output_names=["output"], # 输出名
dynamic_axes={"input": {0: "batch_size"}, # 批处理变量
"output": {0: "batch_size"}})
import netron
modelData = "./test.onnx"
netron.start(modelData)

import os, sys
sys.path.append(os.getcwd())
import onnxruntime
import torchvision.models as models
import torchvision.transforms as transforms
from PIL import Image
def to_numpy(tensor):
return tensor.detach().cpu().numpy() if tensor.requires_grad else tensor.cpu().numpy()
# 自定义的数据增强
def get_test_transform():
return transforms.Compose([
transforms.Resize([224, 224]),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
# 推理的图片路径
image = Image.open('./0a0b8641cac0ce40315e38af020bb18f-device4-0-f_items6.jpg').convert('RGB')
img = get_test_transform()(image)
img = img.unsqueeze_(0) # -> NCHW, 1,3,224,224
# 模型加载
onnx_model_path = "test.onnx"
resnet_session = onnxruntime.InferenceSession(onnx_model_path)
inputs = {resnet_session.get_inputs()[0].name: to_numpy(img)}
outs = resnet_session.run(None, inputs)[0]
print("onnx weights", outs)
print("onnx prediction", outs.argmax(axis=1)[0])