这篇博客我提供了一个全新的openvino部署思路,并且通过这个思路您可以直接调用300多种飞桨算法系统地了解他们,并在在openvino的部署。同时您还可以部署的算子有哪些可以用的哪些是不能用的。
在这篇博客中我将演示从以mobilenet_v3_large_imagenet_ssld这个例子来演示如何部署。
所有代码和资源都挂载到aistudio的平台上,您可以直接打开下面的链接直接运行:
https://aistudio.baidu.com/aistudio/projectdetail/3596186?contributionType=1
注意:这篇博客主要是在python和jupyter notebook下的运行的。
参考:Raymond Lo的demo(博士、英特尔智慧边缘软件布道者)
当然先阶段来说只能通过这种麻烦的多步转化的方法,在3月15日OpenVINO发布的新版本中可以直接将飞桨模型进行转化,大部分模型哦度不需要进行转化了。
为什么说覆盖300多种算法呢?这就要先介绍一下paddle-Hub。
这是飞桨直接提供训练好模型的模块,总的来说有三个功能:
1、您可以直接下载调用这个模型
2、您可以下载这个模型的权重
3、您可以通过服务器调用模型
我们可以通过这个模块直接下载飞桨训练好的模型,大部分的模型都是可以下载训练好的冻结模型来使用,然后我们将会使用这些冻结模型进行
后面我们的模型转化。
这个是paddle-Hub的链接:
https://www.paddlepaddle.org.cn/hublist
下面是模型页面
您可以直接点开任意一个模型,如果您之前没有安装过这个模型,可以根据指导安装一下,后面我也会提供安装的代码。
关于API的调用这里我就不多说了,感兴趣的朋友可以直接根据我提供的链接深入了解,这里我只讲解怎么下载冻结模型,这是一个很简单的语句,就下面这句话,您在自己的电脑里面输入您想要下载模型的全程,规定好下载的名字即可,这个我会在下面的代码中演示,只需要简单了解就行。
参数
dirname: 存在模型的目录名称
model_filename: 模型文件名称,默认为__model__
params_filename: 参数文件名称,默认为__params__(仅当combined为True时生效)
combined: 是否将参数保存到统一的一个文件中
这里我们需要做的工作是将我们下载好的动态模型导出ONNX,想要更加深入了解导出细节可以参考我的这篇文章,等会我直接在代码中讲解:
https://aistudio.baidu.com/aistudio/projectdetail/3459413?contributionType=1
静态模型的导出也不难,只需要下面这段代码,等会详细讲:
!paddle2onnx \
--model_dir u2netp \
--model_filename __model__ \
--params_filename __params__ \
--save_file u2netp_static.onnx \
--opset_version 12
这里我们只能使用OpenVINO的转化模块了,这里后面代码中演示了,难度也不大,只需要几句代码就可以的。
首先毫无疑问需要引入我们所需要的库,这里的环境配置已经默认已经配置好了,如果没有配置好的朋友可以参考我的这一篇博客
import os, os.path
import sys
import json
import urllib.request
import cv2
import numpy as np
import time
from pathlib import Path
import torch
from fastseg import MobileV3Large
from IPython.display import Markdown, display
from scipy.special import softmax
from openvino.inference_engine import IENetwork, IECore, ExecutableNetwork
from IPython.display import Image
第二步是要安装好paddlehub等会我们需要用他下载模型
! pip install xlrd==1.2.0
! pip install --upgrade paddlehub
引入了paddle hub,您可以尝试通过输入模型到name=“模型”,只要这个模型是可以在hub上找到的并且已经上传了就可以下载他们的静态模型pdmodel、pdiparams。
import paddlehub as hub
model = hub.Module(name="mobilenet_v3_large_imagenet_ssld")
model.save_inference_model(dirname="paddlehub_model1/",
model_filename="paddlehub_model1/inference.pdmodel",
params_filename="paddlehub_model1/inference.pdiparams")
image_classes = model.label_list
这里如果您已经根据我的上篇博客配置好环境了,就可以直接使用,如果没有就需要使用pip install paddle2onnx 安装好库,这里就是输入需要转化的模型名称和对应的文件夹,然后输出模型的onnx的名称就可以开始转化。
! paddle2onnx --model_dir paddlehub_model1/ \
--model_filename inference.pdmodel \
--params_filename inference.pdiparams \
--save_file model.onnx \
--opset_version 11
这里我们定义两个自定义的函数来帮助我们处理图像,第一个函数如您所见,是用来读取图像并处理成RGB图像,第二个是因为这里模型的原因,我们引入一层softmax来处理结果的。如果您使用的是其他则不必在意这段
def image_preprocess_mobilenetv3(img_path):
img = cv2.imread(img_path)
img = cv2.resize(img, (224,224), interpolation=cv2.INTER_LANCZOS4)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = np.transpose(img, [2,0,1]) / 255
img = np.expand_dims(img, 0)
img_mean = np.array([0.485, 0.456,0.406]).reshape((3,1,1))
img_std = np.array([0.229, 0.224, 0.225]).reshape((3,1,1))
img -= img_mean
img /= img_std
return img.astype(np.float32)
def top_k(result, image_classes, topk=5):
softmax_result = softmax(result)
top_indices = np.argsort(-softmax_result)[:topk]
#print(top_indices)
top_softmax = softmax_result[top_indices]
for index, softmax_probability in zip(top_indices, top_softmax):
print(f"Class Name: {image_classes[index]}, Probability: {softmax_probability:.5f}")
IMAGE_WIDTH = 1024 # 建议图形的宽度是: 2048, 1024 or 512.
# 按照正方形的变长来设置
IMAGE_HEIGHT = 1024 if IMAGE_WIDTH == 2048 else 512
# 这里执行的将我们的onnx模型转化成为IR模型的树枝定义,您需要提前定义好相关的配置参数
mo_command = f"""mo
--input_model "model.onnx"
--input_shape "[1,3, {IMAGE_HEIGHT}, {IMAGE_WIDTH}]"
--mean_values="[123.675, 116.28 , 103.53]"
--scale_values="[58.395, 57.12 , 57.375]"
--data_type FP16
--output_dir "model/"
"""
mo_command = " ".join(mo_command.split())
print("Model Optimizer command to convert the ONNX model to OpenVINO:")
display(Markdown(f"`{mo_command}`"))
开始转化
print("Exporting ONNX model to IR... This may take a few minutes.")
mo_result = %sx $mo_command
print("\n".join(mo_result))
ie = IECore()
net = ie.read_network(model="model/model.xml")
#MobileNetV3_large_x1_0
filename = "1.jpeg"
test_image = image_preprocess_mobilenetv3(filename)
# Pdmodel可能是动态模型,这将根据输入进行重塑
input_key = list(net.input_info.items())[0][0] # 'inputs'
net.reshape({input_key: test_image.shape})
#l将模型加载到CPU
exec_net = ie.load_network(net, 'CPU')
assert isinstance(exec_net, ExecutableNetwork)
#执行推理步骤
output = exec_net.infer({input_key: test_image})
result_ie = list(output.values())[0][0]
#展示图形分类的最有可能的五个种类。
top_k(result_ie, image_classes)
Image(filename=filename)
识别的图片是一张火柴,这是结果