私的AI研究会 > RevYOLOv5

【復習】物体検出アルゴリズム「YOLO V5」

「PyTorch ではじめる AI開発」Chapter04 で使用する「YOLO V5」について復習する。
以前の作成ページ 物体検出アルゴリズム「YOLO V5」 を全面改定する

▲ 目 次
※ 最終更新:2024/04/16 

Official YOLOv5 考察1 推論/モデル変換編

物体検出とは

YOLO について

 『YOLO』とは "You only live once”「人生一度きり」を引用した "You Only Look Once"「見るのは一度きり」が名の由来。

YOLOv5 をローカルマシンにインストール

  1. 仮想環境「py_learn」をアクティブにする
    (base) conda activate py_learn
  2. プロジェクトの実行ディレクトリに切り替える

     Windows の場合 
    (py_learn) PS > cd /anaconda_win/workspace_pylearn
     Linux の場合 
    (py_learn) $ cd ~/workspace_pylearn
  3. 次のコマンドで サイト https://github.com/ultralytics/yolov5 から「YOLOv5」をインストール
    (py_learn) git clone https://github.com/ultralytics/yolov5
    ・パッケージ構成ファイル「requirements.txt」は使わず現在の環境で不足パッケージのみインストールする
    ・プロジェクトのディレクトリ
    c:\anaconda_win\workspace_pylearn\     ← Windows の場合
    ~/workspace_pylearn/                   ← Linux   の場合
      ├ chapter01
      ├ chapter02 
      ├ forest-path-movie-dataset
      ├ sample
      │    :
      └ yolov5
  4. 冒頭の update_20240405.zip を解凍してできた「workspace_pylearn/yolov5」を「git clone」でできた「yolov5」にコピーする

YOLOv5 推論プログラムの実行

  1. カメラ画像を推論する
    (py_learn) cd yolov5
    (py_learn) python detect.py --source 0
    ・実行結果
    (py_learn) python detect.py --source 0
    Traceback (most recent call last):
      File "C:\anaconda_win\workspace_pylearn\yolov5\detect.py", line 46, in <module>
        from ultralytics.utils.plotting import Annotator, colors, save_one_box
    ModuleNotFoundError: No module named 'ultralytics'
  2. パッケージ「ultralytics」が無いようなのでインストール
    (py_learn) pip install ultralytics
  3. もう一度 カメラ画像で実行
    ・終了はターミナル画面で 'Ctrl' + 'c' を押す
    (py_learn) python detect.py --source 0
    ・実行結果
    (py_learn) python detect.py --source 0
    detect: weights=yolov5s.pt, source=0, data=data\coco128.yaml, imgsz=[640, 640], conf_thres=0.25, iou_thres=0.45, max_det=1000, device=, view_img=False, save_txt=False, save_csv=False, save_conf=False, save_crop=False, nosave=False, classes=None, agnostic_nms=False, augment=False, visualize=False, update=False, project=runs\detect, name=exp, exist_ok=False, line_thickness=3, hide_labels=False, hide_conf=False, half=False, dnn=False, vid_stride=1
    YOLOv5  v7.0-294-gdb125a20 Python-3.11.7 torch-2.2.0+cu121 CUDA:0 (NVIDIA GeForce RTX 4070 Ti, 12282MiB)
    
    Fusing layers...
    YOLOv5s summary: 213 layers, 7225885 parameters, 0 gradients, 16.4 GFLOPs
    1/1: 0...  Success (inf frames 640x480 at 30.00 FPS)
    
    0: 480x640 1 person, 1 chair, 198.1ms
    0: 480x640 1 person, 8.0ms
    0: 480x640 1 person, 1 chair, 5.0ms
    0: 480x640 1 person, 1 chair, 4.0ms
        :
        :
    0: 480x640 1 person, 2 chairs, 6.0ms
    0: 480x640 1 person, 1 chair, 16.0ms
    Traceback (most recent call last):
        :
        :
    KeyboardInterrupt

実行プログラムの修正「detect.py」→「detect2.py」

  1. 入力ソースをカメラ('0') に指定したとき、終了する手段がないので正常に実行結果を保存できない。
    'Esc'キー入力で終了できるように変更する。
    (修正済みプログラムを プロジェクト・パッケージ「update_20240405.zip」に同梱)
    ## Official YOLOv5 https://github.com/ultralytics/yolov5
    ##
    ## detect2.py        (original: detect.py)
    ##  ver 0.01    2024.03.12      'Esc' key Break
            :
            :
        # Run inference
        model.warmup(imgsz=(1 if pt or model.triton else bs, 3, *imgsz))                    # warmup
        seen, windows, dt = 0, [], (Profile(device=device), Profile(device=device), Profile(device=device))
    
        break_flag = False                                      # 'Esc' key Break     2024/03/12
    
        for path, im, im0s, vid_cap, s in dataset:
    
            if break_flag:                                      # 'Esc' key Break     2024/03/12
                break
    
            with dt[0]:
            :
            :
                # Stream results
                im0 = annotator.result()
                if view_img:
    #                if platform.system() == "Linux" and p not in windows:
    #                    windows.append(p)
    #                    cv2.namedWindow(str(p), cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)  # allow window resize (Linux)
    #                    cv2.resizeWindow(str(p), im0.shape[1], im0.shape[0])
                    cv2.namedWindow(str(p), flags=cv2.WINDOW_AUTOSIZE | cv2.WINDOW_GUI_NORMAL) # 2024/03/12
                    cv2.imshow(str(p), im0)
    #                cv2.waitKey(1)                             # 1 millisecond
    
                    ## 'Esc' key Break    2023/06/18
                    c = cv2.waitKey(1)                          # 1 millisecond
                    if c == 27: 
                        break_flag = True
                        break 
    
                # Save results (image with detections)
            :
  2. 推論実行結果の実行中ログをターミナルに出力しないようにする
            # Print time (inference-only)
            # 途中表示なし 2024/03/12
    #        LOGGER.info(f"{s}{'' if len(det) else '(no detections), '}{dt[1].dt * 1E3:.1f}ms")
  3. 修正済みソースコード
    ▼「detect2.py」

推論プログラム「detect2.py」の実行

学習済みモデルのフォーマット変換「export.py」

変換した学習済みモデルで 推論プログラム「detect2.py」の実行

YOLO V5 を「PyTorch」で使う

YOLO V5 テストプログラム

YOLO V5 物体検出プログラム「detect2_yolov5.py」の作成

PyTorch モデル実行速度

モデルによる推論結果の違い

YOLO V5 / YOLO V3 比較

YOLO V5 を「OpenVINO™」で使う

OpenVINO™ API 2.0 対応方法を調べる

  1. サンプルデモのインストール
    実行ディレクトリ「workspace_pylearn/」
    (py_learn) git clone https://github.com/violet17/yolov5_demo.git
    ・実行ログ
    (py_learn) git clone https://github.com/violet17/yolov5_demo.git
    Cloning into 'yolov5_demo'...
    remote: Enumerating objects: 31, done.
    remote: Counting objects: 100% (31/31), done.
    remote: Compressing objects: 100% (30/30), done.
    remote: Total 31 (delta 13), reused 0 (delta 0), pack-reused 0Receiving objects:  58% (18/31)
    Receiving objects: 100% (31/31), 59.87 KiB | 5.99 MiB/s, done.
    Resolving deltas: 100% (13/13), done.
  2. 冒頭の update_20240405.zip を解凍してできた「workspace_pylearn/yolov5_demo」を「git clone」でできた「yolov5_demo」にコピーする

  3. オリジナルのデモプログラムを動かす
    実行ディレクトリ「workspace_pylearn/yolov5_demo/」
    (py_learn2) python yolov5_demo_sync_ov2023.py -i ../yolov5/data/images/zidane.jpg -m ../yolov5/yolov5s_openvino_model/yolov5s.xml
    ・オリジナルの API2.0 対応デモプログラム「yolov5_demo_sync_ov2023.py」
    (py_learn2) python yolov5_demo_sync_ov2023.py -i ../yolov5/data/images/zidane.jpg -m ../yolov5/yolov5s_openvino_model/yolov5s.xml
    [ INFO ] Creating OpenVINO Runtime Core...
    [ INFO ] Reading the model:
            ../yolov5/yolov5s_openvino_model/yolov5s.xml
    [ INFO ] Preparing inputs
    *********** [1,3,640,640]
    --------- ../yolov5/data/images/zidane.jpg
    [ INFO ] Loading model to the plugin
    [ INFO ] Starting inference...
    [ INFO ]          classes : 80
    [ INFO ]          num     : 3
    [ INFO ]          coords  : 4
    [ INFO ]          anchors : [10.0, 13.0, 16.0, 30.0, 33.0, 23.0, 30.0, 61.0, 62.0, 45.0, 59.0, 119.0, 116.0, 90.0, 156.0, 198.0, 373.0, 326.0]
    Traceback (most recent call last):
      File "C:\anaconda_win\workspace_pylearn\yolov5_demo\yolov5_demo_sync_ov2023.py", line 349, in <module>
        sys.exit(main() or 0)
                 ^^^^^^
      File "C:\anaconda_win\workspace_pylearn\yolov5_demo\yolov5_demo_sync_ov2023.py", line 281, in main
        objects += parse_yolo_region(out_blob, in_frame.shape[2:],
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\anaconda_win\workspace_pylearn\yolov5_demo\yolov5_demo_sync_ov2023.py", line 153, in parse_yolo_region
        out_blob_n, out_blob_c, out_blob_h, out_blob_w = blob.shape
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ValueError: not enough values to unpack (expected 4, got 3)
     ※ 変換した学習済みモデルには対応できないよう

  4. 以前 物体検出アルゴリズム「YOLO V5」 で使用したモデル(V3) で動かしてみる
    ・学習済みモデルを「workspace_pylearn/yolov5_demo/」内に「yolov5s_v3.xml」「yolov5s_v3.bin」の名前で用意しておく
     → GitHUNB: ultralytics/yolov5 V3
    (py_learn) python yolov5_demo_sync_ov2023.py -i ../yolov5/data/images/zidane.jpg -m yolov5s_v3.xml -show
    ・実行結果
    (py_learn) python yolov5_demo_sync_ov2023.py -i ../yolov5/data/images/zidane.jpg -m yolov5s_v3.xml -show
    [ INFO ] Creating OpenVINO Runtime Core...
    [ INFO ] Reading the model:
            yolov5s_v3.xml
    [ INFO ] Preparing inputs
    *********** [1,3,640,640]
    --------- ../yolov5/data/images/zidane.jpg
    [ INFO ] Loading model to the plugin
    [ INFO ] Starting inference...
    [ INFO ]          classes : 80
    [ INFO ]          num     : 3
    [ INFO ]          coords  : 4
    [ INFO ]          anchors : [10.0, 13.0, 16.0, 30.0, 33.0, 23.0, 30.0, 61.0, 62.0, 45.0, 59.0, 119.0, 116.0, 90.0, 156.0, 198.0, 373.0, 326.0]
    [ INFO ]          classes : 80
    [ INFO ]          num     : 3
    [ INFO ]          coords  : 4
    [ INFO ]          anchors : [10.0, 13.0, 16.0, 30.0, 33.0, 23.0, 30.0, 61.0, 62.0, 45.0, 59.0, 119.0, 116.0, 90.0, 156.0, 198.0, 373.0, 326.0]
    [ INFO ]          classes : 80
    [ INFO ]          num     : 3
    [ INFO ]          coords  : 4
    [ INFO ]          anchors : [10.0, 13.0, 16.0, 30.0, 33.0, 23.0, 30.0, 61.0, 62.0, 45.0, 59.0, 119.0, 116.0, 90.0, 156.0, 198.0, 373.0, 326.0]
    (720, 1280)
     ※ 以前の学習済みモデル(V3) では問題なく動作する

  5. プログラムを改良する 「yolov5_demo_sync_ov2023x.py」
    ・「yolov5_demo_sync_ov2023.py」を「yolov5_demo_sync_ov2023x.py」としてコピーし修正する
     (プロジェクト・パッケージ「update_20240405.zip」に同梱)
    ・表示出力を日本語対応にする
    ・不具合修正(キー入力による中断など)
    ・コマンドパラメータを修正して使いやすくする

    ・ラベルファイルをコピーしておく
    (py_learn) cp ../yolov5/coco.names ./
    (py_learn) cp ../yolov5/coco.names_jp ./
    ・修正した「yolov5_demo_sync_ov2023x.py」の実行
    (py_learn) python yolov5_demo_sync_ov2023x.py -i ../yolov5/data/images/zidane.jpg -r
    ・実行結果
    (py_learn) python yolov5_demo_sync_ov2023x.py -i ../yolov5/data/images/zidane.jpg -r
    
    --- YOLO V5 OpenVINO(API 2.0) demoprogram Ver 0.01 ---
    OpenCV: 4.9.0
    OpenVINO inference_engine: 2024.0.0-14509-34caeefd078-releases/2024/0
    
     Creating OpenVINO Runtime Core...
     Reading the model: yolov5s_v3.xml
     Label file  : coco.names_jp
     Input source: ../yolov5/data/images/zidane.jpg
     Starting inference...
    [ INFO ]
    Detected boxes for batch 1:
    [ INFO ]  Class ID      | Confidence | XMIN | YMIN | XMAX | YMAX | COLOR
    [ INFO ]     人         |   0.873057 |  747 |   39 | 1148 |  711 | (0, 80, 0)
    [ INFO ]     人         |   0.816089 |  116 |  197 | 1003 |  711 | (0, 80, 0)
    [ INFO ]   ネクタイ     |   0.778782 |  422 |  430 |  517 |  719 | (128, 0, 128)
    
     FPS average:      11.80
    
     Finished.
    ・動画入力の実行
    (py_learn) python yolov5_demo_sync_ov2023x.py -i ../../Videos/car1_m.mp4
    ・実行結果
    (py_learn) python yolov5_demo_sync_ov2023x.py -i ../../Videos/car1_m.mp4
    
    --- YOLO V5 OpenVINO(API 2.0) demoprogram Ver 0.01 ---
    OpenCV: 4.9.0
    OpenVINO inference_engine: 2024.0.0-14509-34caeefd078-releases/2024/0
    
     Creating OpenVINO Runtime Core...
     Reading the model: yolov5s_v3.xml
     Label file  : coco.names_jp
     Input source: ../../Videos/car1_m.mp4
     Starting inference...
    
     FPS average:       9.20
    
     Finished.
    ・カメラ入力の実行
    (py_learn) python yolov5_demo_sync_ov2023x.py
    ・実行結果
    (py_learn) python yolov5_demo_sync_ov2023x.py
    
    --- YOLO V5 OpenVINO(API 2.0) demoprogram Ver 0.01 ---
    OpenCV: 4.9.0
    OpenVINO inference_engine: 2024.0.0-14509-34caeefd078-releases/2024/0
    
     Creating OpenVINO Runtime Core...
     Reading the model: yolov5s_v3.xml
     Label file  : coco.names_jp
     Input source: 0
     Starting inference...
    
     FPS average:      10.40
    
     Finished.

YOLO V5 学習済みモデル バージョンによる違い

 「yolov5_demo_sync_ov2023x.py」がエラーとなる原因を調べる

「export.py」で得られた ONNXファイルを OpenVINO™ IR に変換

  参考サイト:→ Object Detection & YOLOs

  1. ONNXファイルからモデルオプティマイザーを使用してIRファイルに変換できる
    ・モデルオプティマイザーを使用して YOLOv5 モデルを変換するときに、IR の出力ノードを指定する必要がある
    ・YOLOv5 には 3 つの出力ノードがある

  2. 「Netron (Web版)」 で YOLOv5 ONNX の重みを視覚化する
    ・Netronでキーワード「Transpose」を検索して出力ノードを見つける
    ・前図赤印 ① の畳み込みノードダブルクリックし、右のプロパティパネルで、名前「/model.24/m.0/Conv」を読み取る~ことができる
    ・同様に ②「/model.24/m.1/Conv」, ③「/model.24/m.2/Conv」を得る
    ・モデルオプティマイザーの出力ノード パラメーターとして「/model.24/m.0/Conv」「/model.24/m.1/Conv」「/model.24/m.2/Conv」を使用する

  3. モデルオプティマイザーを使用してコンバートする
    ・「workspace_pylearn/yolov5/」ディレクトリで実行する
    ・「yolov5s.onnx」→「yolov5s_v7.xml」「yolov5s_v7..bin」
    (py_learn) mo --input_model yolov5s.onnx --model_name yolov5s_v7 -s 255 --reverse_input_channels --output '/model.24/m.0/Conv','/model.24/m.1/Conv','/model.24/m.2/Conv'
    ・実行結果
    (py_learn) mo --input_model yolov5s.onnx --model_name yolov5s_v7 -s 255 --reverse_input_channels --output '/model.24/m.0/Conv','/model.24/m.1/Conv','/model.24/m.2/Conv'
    [ INFO ] Generated IR will be compressed to FP16. If you get lower accuracy, please consider disabling compression explicitly by adding argument --compress_to_fp16=False.
    Find more information about compression to FP16 at https://docs.openvino.ai/2023.0/openvino_docs_MO_DG_FP16_Compression.html
    [ INFO ] MO command line tool is considered as the legacy conversion API as of OpenVINO 2023.2 release. Please use OpenVINO Model Converter (OVC). OVC represents a lightweight alternative of MO and provides simplified model conversion API.
    Find more information about transition from MO to OVC at https://docs.openvino.ai/2023.2/openvino_docs_OV_Converter_UG_prepare_model_convert_model_MO_OVC_transition.html
    [ SUCCESS ] Generated IR version 11 model.
    [ SUCCESS ] XML file: C:\anaconda_win\workspace_pylearn\yolov5\yolov5s_v7.xml
    [ SUCCESS ] BIN file: C:\anaconda_win\workspace_pylearn\yolov5\yolov5s_v7.bin

OpenVINO™ API 2.0 対応プログラムを作成

OpenVINO™ API 2.0 対応プログラム実行速度

 

対処したエラー詳細

UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument.

ImportError: /lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.29' not found

 【Ubuntu20.04LTSで発生】

 

更新履歴

 

参考資料

 

Last-modified: 2024-04-16 (火) 14:00:26