作者:康瑤明英特爾邊緣計算創新大使
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.0" import sys from pathlib import Path sys.path.append("../utils") from notebook_utils import download_file # Clone YOLOv7 repo if not Path('yolov7').exists(): !git clone https://github.com/WongKinYiu/yolov7 %cd yolov7
左滑查看更多
下圖為代碼執行后的輸出:
1.2下載預訓練模型
# Download pre-trained model weights MODEL_LINK = "https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-tiny.pt" DATA_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 ov model = ov.convert_model('model/yolov7-tiny.onnx') # serialize model for saving IR ov.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 results Image.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_tensor quantization_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工具來優化模型,從而在不損失精度的前提下提高推理性能,更好的服務于場景使用。
審核編輯:湯梓紅
-
英特爾
+關注
關注
61文章
10149瀏覽量
173690 -
檢測器
+關注
關注
1文章
882瀏覽量
48316 -
AI
+關注
關注
87文章
33711瀏覽量
274456 -
開發板
+關注
關注
25文章
5432瀏覽量
101227 -
OpenVINO
+關注
關注
0文章
112瀏覽量
387
原文標題:在英特爾 AI 開發板上用OpenVINO? NNCF 優化 YOLOv7,2.15 倍性能提升 | 開發者實戰
文章出處:【微信號:英特爾物聯網,微信公眾號:英特爾物聯網】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
請問OpenVINO?工具套件英特爾?Distribution是否與Windows? 10物聯網企業版兼容?
為什么在Ubuntu20.04上使用YOLOv3比Yocto操作系統上的推理快?
如何在您的英特爾? Edison 開發板上更新(刷新)固件
介紹英特爾?分布式OpenVINO?工具包
yolov7 onnx模型在NPU上太慢了怎么解決?
無法使用MYRIAD在OpenVINO trade中運行YOLOv7自定義模型怎么解決?
基于OpenVINO在英特爾開發套件上實現眼部追蹤
英特爾的開發板評測

評論