在英特尔AI开发板上用OpenVINO NNCF优化YOLOv7

作者:康瑶明 英特尔边缘计算创新大使
yolo代表“you only look once”,它是一种流行的实时物体检测算法系列。最初的yolo物体检测器于2016年首次发布。从那时起,yolo的不同版本和变体被提出,每个版本和变体都显着提高了性能和效率。yolo算法作为one-stage目标检测算法最典型的代表,其基于深度神经网络进行对象的识别和定位,运行速度很快,可以用于实时系统。yolov7 是 yolo 模型系列的下一个演进阶段,在不增加推理成本的情况下,大大提高了实时目标检测精度。
项目使用的代码在github开源,来源github。
01准备模型与环境
1.1安装openvino以及nncf包,并且clone yolov7的仓库
%pip install -q openvino>=2023.2.0 nncf>=2.5.0import sysfrom pathlib import pathsys.path.append(../utils)from notebook_utils import download_file# clone yolov7 repoif not path('yolov7').exists():    !git clone https://github.com/wongkinyiu/yolov7%cd yolov7  
左滑查看更多
下图为代码执行后的输出:
1.2下载预训练模型
# download pre-trained model weightsmodel_link = https://github.com/wongkinyiu/yolov7/releases/download/v0.1/yolov7-tiny.ptdata_dir = path(data/)model_dir = path(model/)model_dir.mkdir(exist_ok=true)data_dir.mkdir(exist_ok=true)download_file(model_link, directory=model_dir, show_progress=true)  
左滑查看更多
下图为代码执行后的输出:
02使用pytorch原生推理检查模型
调用推理脚本`ignore detect.py`,输入模型相关信息和推理图片执行推理:
!python -w ignore detect.py --weights model/yolov7-tiny.pt --conf 0.25 --img-size 640 --source inference/images/horses.jpg  
左滑查看更多
下图为代码执行后的输出,执行完成后可以看到输出图像尺寸信息以及torch版本,推理设备为cpu。推理结果可以看到识别到5匹马,推理耗时、nms耗时,结果图片保存路径等信息。
打开图片查看结果:
03导出模型为onnx格式
3.1查看`export.py`脚本参数说明
3.2输入模型权重文件路径和要导出detect()层网格,执行脚本生成onnx模型文件并保存
需要说明的是,将整个后处理包含到模型中有助于获得更高性能的结果,但同时会降低模型的灵活性,并且不能保证完全准确,这就是为什么我们只添加 --grid 参数来保留原始 pytorch 模型结果格式的原因。
04转换onnx格式为openvino支持的ir文件
虽然 openvino runtime直接支持 onnx 模型,但将它们转换为 ir 格式可以利用 openvino 模型转换的一些api特性。调用模型转换的python api 的 `ov.convert_model`可以转换模型。该api返回 openvino 模型类的实例,该实例可在 python 接口中使用。我们可以使用 `ov.save_model` api 接口以 openvino ir 格式保存在设备上,以备使用。
import openvino as ovmodel = ov.convert_model('model/yolov7-tiny.onnx')# serialize model for saving irov.save_model(model, 'model/yolov7-tiny.xml')  
左滑查看更多
05验证模型推理
`detect.py` 推理脚本包括预处理步骤、openvino模型的推理以及结果后处理以获得边界框等功能。  
左滑查看更多
模型需要rgb通道格式的图像,并在 [0, 1] 范围内归一化。要调整图像大小以适合模型大小,请使用`letterbox`方法调整,其中保留了宽度和高度的纵横比。为了保持特定的形状,预处理会自动启用填充。
5.1预处理阶段
  对图像进行预处理,以 `np.array` 格式获取图像,使用`letterbox`方法将其调整为特定大小,将色彩空间从 bgr(opencv 中的默认值)转换为 rgb,并将数据布局从 hwc 更改为 chw:  
def preprocess_image(img0: np.ndarray):    # resize    img = letterbox(img0, auto=false)[0]        # convert    img = img.transpose(2, 0, 1)    img = np.ascontiguousarray(img)    return img, img0  
左滑查看更多
将预处理后的图像转换为张量格式。以 np.array 格式获取图像,其中 unit8 数据在 [0, 255] 范围内,并将其转换为浮点数据在 [0, 1] 范围内的 torch.tensor 对象。
def prepare_input_tensor(image: np.ndarray):    input_tensor = image.astype(np.float32)  # uint8 to fp16/32    input_tensor /= 255.0  # 0 - 255 to 0.0 - 1.0        if input_tensor.ndim == 3:        input_tensor = np.expand_dims(input_tensor, 0)  
左滑查看更多
5.2后处理阶段
模型检测功能核心代码的介绍,使用 nms 读取图像、对其进行预处理、运行模型推理和后处理结果。
参数:     
      model(model):openvino编译的模型。
      image_path (path):输入图片路径。
      conf_thres(浮点数,*可选*,0.25):对象过滤的最小置信度
      iou_thres(float,*可选*,0.45):在 nms 中重新复制对象的最小重叠分数
      classes (list[int], *optional*, none):用于预测过滤的标签,如果未提供,则将使用所有预测标签
      agnostic_nms (bool, *optiona*, false):是否应用与类无关的 nms 方法
返回:
      pred (list):具有 (n,6) 形状的检测列表,其中 n - 格式为 [x1, y1, x2, y2, score, label] 的检测框数
      orig_img (np.ndarray):预处理前的图像,可用于结果可视化
      input_shape (tuple[int]):模型输入tensor的形状,可用于输出分辨率
def detect(model: ov.model, image_path: path, conf_thres: float = 0.25, iou_thres: float = 0.45, classes: list[int] = none, agnostic_nms: bool = false):    output_blob = model.output(0)    img = np.array(image.open(image_path))    preprocessed_img, orig_img = preprocess_image(img)    input_tensor = prepare_input_tensor(preprocessed_img)    predictions = torch.from_numpy(model(input_tensor)[output_blob])    pred = non_max_suppression(predictions, conf_thres, iou_thres, classes=classes, agnostic=agnostic_nms)    return pred, orig_img, input_tensor.shape  
左滑查看更多
图像上绘制预测边界框的核心代码实现,
参数:
      predictions (np.ndarray):形状为 (n,6) 的检测列表,其中 n - 检测到的框数,格式为 [x1, y1, x2, y2, score, label]
      image (np.ndarray):用于框可视化的图像
      names (list[str]): 数据集中每个类的名称列表
      colors (dict[str, int]): 类名和绘图颜色之间的映射
返回:
      image (np.ndarray):框可视化结果
def draw_boxes(predictions: np.ndarray, input_shape: tuple[int], image: np.ndarray, names: list[str], colors: dict[str, int]):    if not len(predictions):        return image    # rescale boxes from input size to original image size    predictions[:, :4] = scale_coords(input_shape[2:], predictions[:, :4], image.shape).round()    # write results    for *xyxy, conf, cls in reversed(predictions):        label = f'{names[int(cls)]} {conf:.2f}'        plot_one_box(xyxy, image, label=label, color=colors[names[int(cls)]], line_thickness=1)  
左滑查看更多
06选择设备并推理
compiled_model = core.compile_model(model, device.value)boxes, image, input_shape = detect(compiled_model, 'inference/images/horses.jpg')image_with_boxes = draw_boxes(boxes[0], input_shape, image, names, colors)# visualize resultsimage.fromarray(image_with_boxes)  
左滑查看更多
07验证模型准确性
为了评估模型的准确性,需要下载coco数据集以及注释。处理验证数据集并完成评估。评估完成后,下图可以看到准确度是符合要求的:
08使用 nncf 训练后量化 api 优化模型
nncf 是 openvino 中的神经网络推理优化提供了一套高级算法,精度下降最小。我们将在训练后模式下使用 8-bit量化来优化 yolov7。优化过程包含以下步骤:1)创建用于量化的数据集。2)运行 nncf.quantize 以获取优化的模型。3)使用 openvino.runtime.serialize 函数序列化 openvino ir 模型。
量化变换函数,从数据加载器项中提取和预处理输入数据以进行量化。量化完成后可以验证量化模型推理和验证量化模型的准确性,看是否符合要求。
import nncf def transform_fn(data_item):    img = data_item[0].numpy()    input_tensor = prepare_input_tensor(img)    return input_tensorquantization_dataset = nncf.dataset(dataloader, transform_fn)  
左滑查看更多
nncf.quantize 函数提供模型量化的接口。它需要openvino模型和量化数据集的实例。
quantized_model = nncf.quantize(model, quantization_dataset, preset=nncf.quantizationpreset.mixed)ov.save_model(quantized_model, 'model/yolov7-tiny_int8.xml')  
左滑查看更多
09比较原始模型和量化后模型的性能
量化完成后,我们希望使用 openvino 基准测试工具测量 fp32 和 int8 模型的推理性能,从而清楚nncf带来的优化提升。
下图为在ai爱克斯开发板上fp32格式的模型推理,cpu型号为n5105,可以看到吞吐为2.27fps。
下图为量化后 int8 格式的模型推理,可以看到吞吐为4.89fps。
总 结
fp32格式的模型推理ai爱克斯开发板上cpu吞吐为2.27fps,量化后 int8 格式为4.89fps,由此说明了量化的后性能提升很明显,提升至2.15倍,在工程和学习中推荐使用nncf等openvino工具来优化模型,从而在不损失精度的前提下提高推理性能,更好的服务于场景使用。


关于超声波气象站技术参数的详细介绍
华为目前没有上市计划,100%的股权由员工持有!
闭环伺服控制原理与系统
特斯拉频繁收购动力电池行业企业 将把握产业链主导权
智慧消防”项目多地试点成功,实现消防大数据与“智慧城市”等战略深度融合
在英特尔AI开发板上用OpenVINO NNCF优化YOLOv7
语音智能市场现状:亚马逊第一,谷歌第二,苹果沦为第三
光学系统的坐标系统、结构参数和光学特性参数
浅谈Wi-Fi&BT4.1嵌入式模块——EMW3239
铂电阻温度传感器故障的处理措施
dcs和组态软件有什么区别
台积电CoWoS订单增加 生产线满载运行
行业资讯 | 释放 AI 大模型潜能,硬件算力亟待突破互连瓶颈
T-Mobile同美国第四大电信运营商Sprint合并,联合加快5G的发展速度
华盛顿特区的儿童国家卫生系统中引进了VR技术协助手术
频谱仪RBW那些事
细说VL817S与VL817-Q7的区别
ntc热敏电阻B值/电阻比的详细讲解
印度部署5G应用的路线图,华为受邀参与
TA8777N引脚功能的电压资料参数