OpenVINO简介
OpenVINO(Open Visual Inference & Neural Network Optimization)是Intel推出的一套用于推理和优化深度学习模型的工具套件。其中,openvino.inference_engine是OpenVINO工具套件中的一部分,用于进行推理(inference)。openvino.inference_engine提供了一组Python API,使得用户可以在Python环境中加载、配置、推理和优化深度学习模型。该模块可以与OpenVINO的推理引擎(Inference Engine)交互,实现高性能的深度学习模型推理。
主要的步骤:
加载模型:使用ie.read_network方法加载已经优化的模型文件(包括.xml和.bin文件)。
配置设备:使用ie.load_network方法将模型加载到指定的计算设备(如CPU、GPU、VPU等)上,以便进行推理。
准备输入数据:将输入数据准备成适合模型输入要求的格式(通常是多维数组)。
进行推理:使用exec_net.infer方法进行推理,并获取推理结果。
后处理:根据模型的输出,对推理结果进行后处理(如解码、可视化等)。
通过OpenVINO的openvino.inference_engine模块,您可以使用Python对深度学习模型进行快速、高效的推理,以便在各种计算设备上部署和优化深度学习应用程序。这使得在嵌入式设备、服务器和云端上执行深度学习推理任务变得更加简单和灵活。
import cv2
import numpy as np
import matplotlib.pyplot as plt
from openvino.inference_engine import IECore
# 参数
IMG_FPATH = "./data/XXX.jpg"
IR_MODEL_FPATH = "./model/model.xml"
DEVICE = "CPU"
num_classes = 5 # 类别数
#加载图像
img = cv2.imread(IMG_FPATH)
if img is None:
raise Exception('Image not found!')
# 加载IR模型
ie = IECore()
net = ie.read_network(model=IR_MODEL_FPATH, weights=IR_MODEL_FPATH[:-3] + "bin")
exec_net = ie.load_network(network=net, device_name=DEVICE)
# 归一化方法
mean = np.array([0.13049585 ,0.12472586 ,0.12034116])
std = np.array([0.20819635,0.19878454 ,0.19172224])
# mean = np.array([0.15599174,0.15599174, 0.15599174])
# std = np.array([0.1543564,0.1543564,0.1543564])
# 模型的输入准备数据
input_blob = next(iter(net.input_info))
input_shape = net.input_info[input_blob].input_data.shape
resized_img = cv2.resize(img, (input_shape[3], input_shape[2]))
preprocessed_img = np.transpose(resized_img, (2, 0, 1)).astype(np.float32) / 255.0 # Normalize to [0, 1]
# 标准化
preprocessed_img[0] = (preprocessed_img[0] - mean[0]) / std[0]
preprocessed_img[1] = (preprocessed_img[1] - mean[1]) / std[1]
preprocessed_img[2] = (preprocessed_img[2] - mean[2]) / std[2]
preprocessed_img = preprocessed_img.reshape(1, *preprocessed_img.shape)
# Perform inference
outputs = exec_net.infer(inputs={input_blob: preprocessed_img})
# 得到输出
output_blob = next(iter(net.outputs))
output_data = outputs[output_blob].reshape((input_shape[2], input_shape[3]))
# 获取每一个类别1像素值
classIds = output_data.astype(np.uint8)
# 自定义mask
COLORS = np.zeros((255, 3), dtype="uint8")
# Background (Black)
COLORS[0] = [0, 0, 0]
# Class 1 (Red)
COLORS[1] = [255, 0, 0]
# Class 2 (Green)
COLORS[2] = [0, 255, 0]
# Class 3 (Blue)
COLORS[3] = [0, 0, 255]
# Class 4 (Yellow)
COLORS[4] = [255, 255, 0]
# Process output data
segment_map = COLORS[classIds]
segment_map = cv2.resize(segment_map, (img.shape[1], img.shape[0]), interpolation=cv2.INTER_NEAREST)
# Mix original with segmentation map
img_with_segmentation = (0.4 * segment_map + 0.6 * img).astype(np.uint8)
# 可视化结果
def show_img(img):
dpi = 80
height, width, _ = img.shape
figsize = width / float(dpi), height / float(dpi)
fig = plt.figure(figsize=figsize)
plt.axis('off')
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()
show_img(img_with_segmentation)
推理速度慢?有NNCF
NNCF(Neural Network Compression Framework)是一个用于深度学习模型压缩的开源工具,旨在减小神经网络模型的大小并提高其推理性能,而无需牺牲准确性。NNCF集成了各种压缩技术,如权重剪枝、量化、通道剪枝和结构化剪枝,以帮助用户优化模型。它可以与多个深度学习框架(如PyTorch、TensorFlow)无缝集成,提供了易于使用的API和配置选项,使用户能够自定义压缩策略。NNCF不仅适用于部署在资源受限环境中的模型,还能加速训练和推理过程,从而在不牺牲质量的情况下提升效率。无论是移动设备、嵌入式系统还是服务器端,NNCF都是一个强大的工具,有助于优化深度学习模型的性能和效率。
量化脚本
import nncf
import openvino.runtime as ov
import torch
from torchvision import datasets, transforms
import openvino.runtime as ov
# 加载需要量化的模型
model = ov.Core().read_model("./IR/model.xml")
#需要注意,校准集的数据预处理方法需与训练阶段使用的一致,不然会导致精度丢失。可能其中一个类别识别、检测、分割不到
train_transforms = transforms.Compose([
transforms.Resize((512, 512)),
transforms.RandomCrop((512, 512)),
transforms.RandomHorizontalFlip(),
transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1),
transforms.ToTensor(),
transforms.Normalize(mean=[0.33, 0.32, 0.32], std=[0.43, 0.42, 0.41]),
])
# 校准集数据加载
#calibration_dataset = ImageFolder("./calibration_dataset", transform=train_transforms)
# 校准数据集预处理函数
val_dataset = datasets.ImageFolder("./calibration_dataset", transform=train_transforms )
dataset_loader = torch.utils.data.DataLoader(val_dataset, batch_size=1)
# 第一步 初始化 transformation 函数
def transform_fn(data_item):
images, _ = data_item
return images
# 第二步 初始化数据集
calibration_dataset = nncf.Dataset(dataset_loader, transform_fn)
# 第三步,推理nncf.quantize
quantized_model = nncf.quantize(model, calibration_dataset)
#保存量化后的模型
ov.serialize(quantized_model, "./IR/INT8_model.xml")