<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【深度學習】當YOLOv5遇見OpenVINO!

          共 11450字,需瀏覽 23分鐘

           ·

          2021-07-04 15:43

          一、YOLOv5網(wǎng)絡

          YOLOv5代碼鏈接:https://github.com/ultralytics/yolov5

          YOLOv5 于2020年6月發(fā)布!一經(jīng)推出,便得到CV圈的矚目,目前在各大目標檢測競賽、落地實戰(zhàn)項目中得到廣泛應用。

          YOLOv5在COCO上的性能表現(xiàn):

          YOLOv5一共有4個版本,分別是Yolov5s、Yolov5m、Yolov5l、Yolov5x,其中性能依次增強。比如YOLOv5s模型參數(shù)量最小,速度最快,AP精度最低;YOLOv5x模型參數(shù)量最大,速度最慢,AP精度最高。

          其中YOLOv5網(wǎng)絡結(jié)構(gòu)如下:

          圖源:https://zhuanlan.zhihu.com/p/172121380

          二、OpenVINO?工具套件介紹

          OpenVINO?工具套件是英特爾針對自家硬件平臺開發(fā)的一套深度學習工具庫,包含推理庫,模型優(yōu)化等等一系列與深度學習模型部署相關(guān)的功能。同時可以兼容各種開源框架訓練好的模型,擁有算法模型上線部署的各種能力,只要掌握了該工具,你可以輕松的將預訓練模型在英特爾的CPU、VPU等設(shè)備上快速部署起來。

          三、重新訓練YOLOv5

          3.1 下載YOLOv5代碼和權(quán)重文件

          大家可以直接clone YOLOv5官方github代碼:

          git clone https://github.com/ultralytics/yolov5

          也可以在官方github的releases中下載正式發(fā)布的版本:

          https://github.com/ultralytics/yolov5/releases

          我們這里下載YOLOv5 v3.1版本的源代碼和yolov5s.pt權(quán)重文件。值得注意,目前YOLOv5已更新至v5.0,但在實際轉(zhuǎn)換OpenVINO?工具套件推理應用中遇到不少問題,為了方便使用,這里推薦較穩(wěn)定的YOLOv5 v3.1版本。

          3.2 數(shù)據(jù)集準備

          數(shù)據(jù)集可以是自己標注的,也可以用網(wǎng)上開源的數(shù)據(jù)集。如果是標注自己的目標檢測數(shù)據(jù)集,一般使用labelImg工具(超好用!支持COCO等格式)。

          這里我們下載使用roboflow開源的口罩檢測數(shù)據(jù)集(Mask Wearing Dataset),該數(shù)據(jù)集只有149幅圖像,方便練手,而且格式直接支持YOLOv5!

          https://public.roboflow.com/object-detection/mask-wearing

          3.3 重新訓練YOLOv5

          3.3.1 修改參數(shù)

          訓練自定義數(shù)據(jù)集,一般需要修改兩個參數(shù):

          • nc:需要識別的類別

          • anchors:YOLOv5默認自適應anchors計算,也可以自定義通過k-means算法計算

          其中,nc是一定要修改的,比較每個數(shù)據(jù)集的類別會不一樣,而anchors可以不用修改,即默認自適應計算。

          比如Mask Wearing數(shù)據(jù)集只有兩種類別:mask和no-mask,所以nc = 2??梢奷ata.yaml中的信息:

          這里使用YOLOv5s進行訓練,所以需要同步修改yolov5/models/yolov5s.yaml 文件中的nc數(shù)值,設(shè)置為2:

          3.3.2 訓練YOLOv5

          訓練命令如下:

          python train.py --data 數(shù)據(jù)集路徑/data.yaml --cfg models/yolov5s.yaml --weights '' --batch-size 64 --epochs 100

          注:訓練命令行的參數(shù)含義可參考:https://docs.ultralytics.com,比如batch size、epochs可以根據(jù)訓練設(shè)備自行調(diào)整

          訓練完成后,權(quán)重文件會自動保存在runs文件夾中,自動生成last.pt和best.pt,如下圖所示:

          3.3.3 YOLOv5 Demo檢測

          對測試集中的圖像進行檢測,執(zhí)行命令如下:

          python detect.py --weight runs/exp6/weights/best.pt --source 數(shù)據(jù)集路徑/test/images/1288126-10255706714jpg_jpg.rf.95f7324cbfd48e0386e0660b5e932223.jpg


          輸入圖像:

          口罩檢測結(jié)果:

          四、模型轉(zhuǎn)換(YOLOv5—>OpenVINO?工具套件)

          將YOLOv5的.pt訓練權(quán)重文件轉(zhuǎn)換成OpenVINO?工具套件調(diào)用的文件,主要的流程是:.pt 權(quán)重文件 —> ONNX 權(quán)重文件 —> IR 文件(.bin和xml)。其中利用ONNX(Open Neural Network Exchange,開放神經(jīng)網(wǎng)絡交換)進行文件格式轉(zhuǎn)換。

          使用版本說明:

          • Ubuntu 18.04

          • OpenVINO?工具套件  2021.03

          4.1 .pt 權(quán)重文件 —> ONNX 權(quán)重文件

          先安裝ONNX,然后運行腳本,實現(xiàn)轉(zhuǎn)換。

          4.1.1 安裝ONNX

          ONNX的安裝方法相對簡單,直接pip安裝即可:

          pip install onnx

          4.1.2 ONNX轉(zhuǎn)換

          YOLOv5官方提供了轉(zhuǎn)換成ONNX權(quán)重的腳本文件,位于yolov5/models/export.py,使用說明詳見:https://github.com/ultralytics/yolov5/issues/251

          注意,這里需要將export.py腳本文件中的opset_version修改為10

          torch.onnx.export(model, img, f, verbose=False, opset_version=10, input_names=['images'],                          output_names=['classes', 'boxes'] if y is None else ['output'])

          然后再執(zhí)行如下轉(zhuǎn)換指令:

          python models/export.py --weights runs/exp6/weights/best.pt --img 640 --batch 1

          轉(zhuǎn)換成功后,就會在runs/exp6/weights文件夾中生成best.onnx文件。

          注:這里可以使用Netron打開yolov5s.onnx,進而可視化YOLOv5模型。

          • Netron在線可視化:https://netron.app/

          • Netron github:https://github.com/lutzroeder/netron

          4.2 ONNX 權(quán)重文件 —> IR 文件(.bin和.xml)

          先安裝、配置OpenVINO?工具套件,然后運行腳本,實現(xiàn)轉(zhuǎn)換。

          4.2.1 安裝OpenVINO?工具套件

          安裝OpenVINO?工具套件的方法有很多,詳見官網(wǎng):

          https://docs.openvinotoolkit.org/latest/index.html

          這里我是使用APT的方式,具體參考:https://docs.openvinotoolkit.org/latest/openvino_docs_install_guides_installing_openvino_apt.html

          安裝命令如下:

          wget https://apt.repos.intel.com/openvino/2021/GPG-PUB-KEY-INTEL-OPENVINO-2021apt-key add GPG-PUB-KEY-INTEL-OPENVINO-2021apt-key listtouch /etc/apt/sources.list.d/intel-openvino-2021.listecho "deb https://apt.repos.intel.com/openvino/2021 all main" >> /etc/apt/sources.list.d/intel-openvino-2021.listapt update

          執(zhí)行完上述命令后,可出現(xiàn):

          然后搜索可下載的包,要注意系統(tǒng)版本:

          sudo apt-cache search intel-openvino-dev-ubuntu18

          這里安裝intel-openvino-dev-ubuntu18-2021.3.394版本

          apt install intel-openvino-dev-ubuntu18-2021.3.394

          安裝成功后,輸出內(nèi)容如下圖所示:

          4.2.2 OpenVINO?工具套件轉(zhuǎn)換

          安裝好OpenVINO?工具套件后,我們需要使用OpenVINO?工具套件的模型優(yōu)化器(Model Optimizer)將ONNX文件轉(zhuǎn)換成IR(Intermediate Representation)文件。

          首先設(shè)置 OpenVINO?工具套件的環(huán)境和變量:

          source /opt/intel/openvino_2021/bin/setupvars.sh

          然后運行如下腳本,實現(xiàn)ONNX模型到IR文件(.xml和.bin)的轉(zhuǎn)換:

          python /opt/intel/openvino_2021/deployment_tools/model_optimizer/mo.py --input_model runs/exp6/weights/best.onnx --model_name yolov5s_best -s 255 --reverse_input_channels --output Conv_487,Conv_471,Conv_455

          關(guān)于命令行的參數(shù)用法,更多細節(jié)可參考:https://docs.openvinotoolkit.org/cn/latest/openvino_docs_MO_DG_prepare_model_convert_model_Converting_Model_General.html

          轉(zhuǎn)換成功后,即可得到yolov5s_best.xmlyolov5s_best.bin文件。

          五、使用OpenVINO?工具套件進行推理部署

          5.1 安裝Python版的OpenVINO?工具套件

          這里使用Python進行推理測試。因為我上面采用apt的方式安裝OpenVINO?工具套件,這樣安裝后Python環(huán)境中并沒有OpenVINO?工具套件,所以我這里需要用pip安裝一下OpenVINO?工具套件。

          注:如果你是編譯源碼等方式進行安裝的,那么可以跳過這步:

          pip install openvino

          另外,安裝時要保持版本的一致性:

          5.2 OpenVINO?工具套件實測

          OpenVINO?工具套件官方提供了YOLOv3版本的Python推理demo,可以參考:

          https://github.com/openvinotoolkit/open_model_zoo/blob/master/demos/object_detection_demo/python/object_detection_demo.py

          我們這里參考這個已經(jīng)適配好的YOLOv5版本:https://github.com/violet17/yolov5_demo/blob/main/yolov5_demo.py,該源代碼的輸入數(shù)據(jù)是camera或者video,所以我們可以將test數(shù)據(jù)集中的圖像轉(zhuǎn)換成視頻(test.mp4)作為輸入,或者可以自行修改成圖像處理的代碼。

          其中YOLOv5版本相對于官方Y(jié)OLOv3版本的主要修改點:

          1. 自定義letterbox函數(shù),預處理輸入圖像:

          def letterbox(img, size=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True):    # Resize image to a 32-pixel-multiple rectangle https://github.com/ultralytics/yolov3/issues/232    shape = img.shape[:2]  # current shape [height, width]    w, h = size
          # Scale ratio (new / old) r = min(h / shape[0], w / shape[1]) if not scaleup: # only scale down, do not scale up (for better test mAP) r = min(r, 1.0)
          # Compute padding ratio = r, r # width, height ratios new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r)) dw, dh = w - new_unpad[0], h - new_unpad[1] # wh padding if auto: # minimum rectangle dw, dh = np.mod(dw, 64), np.mod(dh, 64) # wh padding elif scaleFill: # stretch dw, dh = 0.0, 0.0 new_unpad = (w, h) ratio = w / shape[1], h / shape[0] # width, height ratios
          dw /= 2 # divide padding into 2 sides dh /= 2
          if shape[::-1] != new_unpad: # resize img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR) top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1)) left, right = int(round(dw - 0.1)), int(round(dw + 0.1)) img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color) # add border
          top2, bottom2, left2, right2 = 0, 0, 0, 0 if img.shape[0] != h: top2 = (h - img.shape[0])//2 bottom2 = top2 img = cv2.copyMakeBorder(img, top2, bottom2, left2, right2, cv2.BORDER_CONSTANT, value=color) # add border elif img.shape[1] != w: left2 = (w - img.shape[1])//2 right2 = left2 img = cv2.copyMakeBorder(img, top2, bottom2, left2, right2, cv2.BORDER_CONSTANT, value=color) # add border return img


          2. 自定義parse_yolo_region函數(shù), 使用Sigmoid函數(shù)的YOLO Region層  :

          def parse_yolo_region(blob, resized_image_shape, original_im_shape, params, threshold):    # ------------------------------------------ Validating output parameters ------------------------------------------        out_blob_n, out_blob_c, out_blob_h, out_blob_w = blob.shape    predictions = 1.0/(1.0+np.exp(-blob))                        assert out_blob_w == out_blob_h, "Invalid size of output blob. It sould be in NCHW layout and height should " \                                     "be equal to width. Current height = {}, current width = {}" \                                     "".format(out_blob_h, out_blob_w)
          # ------------------------------------------ Extracting layer parameters ------------------------------------------- orig_im_h, orig_im_w = original_im_shape resized_image_h, resized_image_w = resized_image_shape objects = list() side_square = params.side * params.side
          # ------------------------------------------- Parsing YOLO Region output ------------------------------------------- bbox_size = int(out_blob_c/params.num) #4+1+num_classes
          for row, col, n in np.ndindex(params.side, params.side, params.num): bbox = predictions[0, n*bbox_size:(n+1)*bbox_size, row, col] x, y, width, height, object_probability = bbox[:5] class_probabilities = bbox[5:] if object_probability < threshold: continue x = (2*x - 0.5 + col)*(resized_image_w/out_blob_w) y = (2*y - 0.5 + row)*(resized_image_h/out_blob_h) if int(resized_image_w/out_blob_w) == 8 & int(resized_image_h/out_blob_h) == 8: #80x80, idx = 0 elif int(resized_image_w/out_blob_w) == 16 & int(resized_image_h/out_blob_h) == 16: #40x40 idx = 1 elif int(resized_image_w/out_blob_w) == 32 & int(resized_image_h/out_blob_h) == 32: # 20x20 idx = 2
          width = (2*width)**2* params.anchors[idx * 6 + 2 * n] height = (2*height)**2 * params.anchors[idx * 6 + 2 * n + 1] class_id = np.argmax(class_probabilities) confidence = object_probability objects.append(scale_bbox(x=x, y=y, height=height, width=width, class_id=class_id, confidence=confidence, im_h=orig_im_h, im_w=orig_im_w, resized_im_h=resized_image_h, resized_im_w=resized_image_w)) return objects


          3. 自定義scale_bbox函數(shù),進行邊界框后處理 :

          def scale_bbox(x, y, height, width, class_id, confidence, im_h, im_w, resized_im_h=640, resized_im_w=640):    gain = min(resized_im_w / im_w, resized_im_h / im_h)  # gain  = old / new    pad = (resized_im_w - im_w * gain) / 2, (resized_im_h - im_h * gain) / 2  # wh padding    x = int((x - pad[0])/gain)    y = int((y - pad[1])/gain)
          w = int(width/gain) h = int(height/gain) xmin = max(0, int(x - w / 2)) ymin = max(0, int(y - h / 2)) xmax = min(im_w, int(xmin + w)) ymax = min(im_h, int(ymin + h)) # Method item() used here to convert NumPy types to native types for compatibility with functions, which don't # support Numpy types (e.g., cv2.rectangle doesn't support int64 in color parameter) return dict(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, class_id=class_id.item(), confidence=confidence.item())

          但在實際測試中,會出現(xiàn)這個問題 'openvino.inference_engine.ie_api.IENetwork' object has no attribute 'layers'

          [ INFO ] Creating Inference Engine... [ INFO ] Loading network files: yolov5/yolov5s_best.xml yolov5/yolov5s_best.bin yolov5_demo.py:233: DeprecationWarning: Reading network using constructor is deprecated. Please, use IECore.read_network() method instead  net = IENetwork(model=model_xml, weights=model_bin) Traceback (most recent call last):  File "yolov5_demo.py", line 414, in <module>    sys.exit(main() or 0)  File "yolov5_demo.py", line 238, in main    not_supported_layers = [l for l in net.layers.keys() if l not in supported_layers] AttributeError: 'openvino.inference_engine.ie_api.IENetwork' object has no attribute 'layers'

          經(jīng)過我調(diào)研后才得知,在OpenVINO?工具套件2021.02及以后版本, 'ie_api.IENetwork.layers' 就被官方刪除了:

          所以需要將第327、328行的內(nèi)容:

          out_blob = out_blob.reshape(net.layers[layer_name].out_data[0].shape) layer_params = YoloParams(net.layers[layer_name].params, out_blob.shape[2])

          修改為:

          out_blob = out_blob.reshape(net.outputs[layer_name].shape)params = [x._get_attributes() for x in function.get_ordered_ops() if x.get_friendly_name() == layer_name][0]layer_params = YoloParams(params, out_blob.shape[2])

          并在第322行下面新添加一行代碼:

          function = ng.function_from_cnn(net)

          最終在終端,輸入下面命令:

          python yolov5_demo.py -m yolov5/yolov5s_best.xml test.mp4

          加上后處理,使用OpenVINO?工具套件的推理時間平均在220ms左右,測試平臺為英特爾? 酷睿? i5-7300HQ,而使用PyTorch CPU版本的推理時間平均在1.25s,可見OpenVINO?工具套件加速明顯!

          最終檢測結(jié)果如下:

          如果你想在CPU上實現(xiàn)模型的快速推理,可以試試OpenVINO?工具套件哦~

          往期精彩回顧




          本站qq群851320808,加入微信群請掃碼:
          瀏覽 62
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  中文字幕在线欧美 | 国内aV免费 | 日韩一级一级CC | 青青草在线免费视频 | 经典三级精品国产 |