From 9ceae167c103ddb70424c31bdfd8e93c32ae8ea7 Mon Sep 17 00:00:00 2001 From: NYH <175484793@qq.com> Date: Wed, 27 Dec 2023 15:00:04 +0800 Subject: [PATCH] V1.0 --- CMakeLists.txt | 52 + README.md | 158 ++- __pycache__/val.cpython-37.pyc | Bin 0 -> 12122 bytes __pycache__/val.cpython-38.pyc | Bin 0 -> 12077 bytes data/Argoverse.yaml | 67 ++ data/GlobalWheat2020.yaml | 53 + data/Objects365.yaml | 104 ++ data/SKU-110K.yaml | 52 + data/VOC.yaml | 80 ++ data/VisDrone.yaml | 61 ++ data/coco.yaml | 44 + data/coco128.yaml | 30 + data/data_class_4.yaml | 37 + data/hyps/hyp.finetune.yaml | 39 + data/hyps/hyp.finetune_objects365.yaml | 29 + data/hyps/hyp.scratch-p6.yaml | 34 + data/hyps/hyp.scratch.yaml | 34 + data/img.cache | Bin 0 -> 94802 bytes data/img.cache.npy | Bin 0 -> 113581 bytes data/img1.cache | Bin 0 -> 8820 bytes data/scripts/download_weights.sh | 17 + data/scripts/get_coco.sh | 27 + data/scripts/get_coco128.sh | 17 + data/xView.yaml | 102 ++ detect.py | 239 +++++ detect1.py | 239 +++++ export.py | 189 ++++ gen_wts.py | 59 ++ images | 1 + models/__init__.py | 0 models/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 143 bytes models/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 142 bytes models/__pycache__/common.cpython-37.pyc | Bin 0 -> 20039 bytes models/__pycache__/common.cpython-38.pyc | Bin 0 -> 21210 bytes .../__pycache__/experimental.cpython-37.pyc | Bin 0 -> 6042 bytes .../__pycache__/experimental.cpython-38.pyc | Bin 0 -> 5942 bytes models/__pycache__/yolo.cpython-37.pyc | Bin 0 -> 10833 bytes models/__pycache__/yolo.cpython-38.pyc | Bin 0 -> 10863 bytes models/common.py | 457 ++++++++ models/common_1.py | 433 ++++++++ models/experimental.py | 136 +++ models/hub/anchors.yaml | 58 + models/hub/yolov3-spp.yaml | 49 + models/hub/yolov3-tiny.yaml | 39 + models/hub/yolov3.yaml | 49 + models/hub/yolov5-bifpn.yaml | 46 + models/hub/yolov5-fpn.yaml | 40 + models/hub/yolov5-p2.yaml | 52 + models/hub/yolov5-p6.yaml | 54 + models/hub/yolov5-p7.yaml | 65 ++ models/hub/yolov5-panet.yaml | 46 + models/hub/yolov5l6.yaml | 58 + models/hub/yolov5m6.yaml | 58 + models/hub/yolov5s6.yaml | 58 + models/hub/yolov5x6.yaml | 58 + models/yolo.py | 300 ++++++ models/yolov5l.yaml | 46 + models/yolov5m-2transformer.yaml | 46 + models/yolov5m.yaml | 47 + models/yolov5m_add_detect.yaml | 65 ++ models/yolov5m_s.yaml | 57 + models/yolov5s-2transformer.yaml | 46 + models/yolov5s-transformer.yaml | 46 + models/yolov5s.yaml | 46 + models/yolov5x.yaml | 46 + plugin/yololayer.cu | 280 +++++ plugin/yololayer.h | 106 ++ requirements.txt | 31 + src/calibrator.cpp | 97 ++ src/calibrator.h | 39 + src/config.h | 55 + src/cuda_utils.h | 18 + src/logging.h | 504 +++++++++ src/macros.h | 29 + src/model.cpp | 629 +++++++++++ src/model.h | 16 + src/postprocess.cpp | 189 ++++ src/postprocess.h | 16 + src/preprocess.cu | 153 +++ src/preprocess.h | 15 + src/types.h | 17 + src/utils.h | 70 ++ train.py | 620 +++++++++++ utils/__init__.py | 0 utils/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 142 bytes utils/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 141 bytes .../__pycache__/augmentations.cpython-37.pyc | Bin 0 -> 8848 bytes .../__pycache__/augmentations.cpython-38.pyc | Bin 0 -> 8843 bytes utils/__pycache__/autoanchor.cpython-37.pyc | Bin 0 -> 6252 bytes utils/__pycache__/autoanchor.cpython-38.pyc | Bin 0 -> 6208 bytes utils/__pycache__/callbacks.cpython-37.pyc | Bin 0 -> 6428 bytes utils/__pycache__/callbacks.cpython-38.pyc | Bin 0 -> 6277 bytes utils/__pycache__/datasets.cpython-37.pyc | Bin 0 -> 34193 bytes utils/__pycache__/datasets.cpython-38.pyc | Bin 0 -> 34153 bytes utils/__pycache__/downloads.cpython-37.pyc | Bin 0 -> 3801 bytes utils/__pycache__/downloads.cpython-38.pyc | Bin 0 -> 3846 bytes utils/__pycache__/general.cpython-37.pyc | Bin 0 -> 26277 bytes utils/__pycache__/general.cpython-38.pyc | Bin 0 -> 26373 bytes utils/__pycache__/loss.cpython-37.pyc | Bin 0 -> 6640 bytes utils/__pycache__/loss.cpython-38.pyc | Bin 0 -> 6532 bytes utils/__pycache__/metrics.cpython-37.pyc | Bin 0 -> 10639 bytes utils/__pycache__/metrics.cpython-38.pyc | Bin 0 -> 10573 bytes utils/__pycache__/plots.cpython-37.pyc | Bin 0 -> 15994 bytes utils/__pycache__/plots.cpython-38.pyc | Bin 0 -> 15859 bytes utils/__pycache__/torch_utils.cpython-37.pyc | Bin 0 -> 12057 bytes utils/__pycache__/torch_utils.cpython-38.pyc | Bin 0 -> 12115 bytes utils/activations.py | 98 ++ utils/augmentations.py | 271 +++++ utils/autoanchor.py | 161 +++ utils/aws/__init__.py | 0 utils/aws/mime.sh | 26 + utils/aws/resume.py | 37 + utils/aws/userdata.sh | 27 + utils/callbacks.py | 175 ++++ utils/datasets.py | 989 ++++++++++++++++++ utils/downloads.py | 146 +++ utils/flask_rest_api/README.md | 68 ++ utils/flask_rest_api/example_request.py | 13 + utils/flask_rest_api/restapi.py | 37 + utils/general.py | 721 +++++++++++++ utils/google_app_engine/Dockerfile | 25 + .../additional_requirements.txt | 4 + utils/google_app_engine/app.yaml | 14 + utils/loggers/__init__.py | 141 +++ .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 6269 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 0 -> 6278 bytes utils/loggers/wandb/README.md | 140 +++ utils/loggers/wandb/__init__.py | 0 .../wandb/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 156 bytes .../wandb/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 155 bytes .../__pycache__/wandb_utils.cpython-37.pyc | Bin 0 -> 18644 bytes .../__pycache__/wandb_utils.cpython-38.pyc | Bin 0 -> 18704 bytes utils/loggers/wandb/log_dataset.py | 23 + utils/loggers/wandb/sweep.py | 33 + utils/loggers/wandb/sweep.yaml | 143 +++ utils/loggers/wandb/wandb_utils.py | 510 +++++++++ utils/loss.py | 245 +++++ utils/metrics.py | 332 ++++++ utils/plots.py | 432 ++++++++ utils/torch_utils.py | 327 ++++++ val.py | 352 +++++++ yolov5_cls.cpp | 288 +++++ yolov5_cls_trt.py | 248 +++++ yolov5_det.cpp | 233 +++++ yolov5_det_cuda_python.py | 453 ++++++++ yolov5_det_trt.py | 452 ++++++++ yolov5_seg.cpp | 245 +++++ yolov5_seg_trt.py | 561 ++++++++++ 148 files changed, 15117 insertions(+), 2 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 __pycache__/val.cpython-37.pyc create mode 100644 __pycache__/val.cpython-38.pyc create mode 100644 data/Argoverse.yaml create mode 100644 data/GlobalWheat2020.yaml create mode 100644 data/Objects365.yaml create mode 100644 data/SKU-110K.yaml create mode 100644 data/VOC.yaml create mode 100644 data/VisDrone.yaml create mode 100644 data/coco.yaml create mode 100644 data/coco128.yaml create mode 100644 data/data_class_4.yaml create mode 100644 data/hyps/hyp.finetune.yaml create mode 100644 data/hyps/hyp.finetune_objects365.yaml create mode 100644 data/hyps/hyp.scratch-p6.yaml create mode 100644 data/hyps/hyp.scratch.yaml create mode 100644 data/img.cache create mode 100644 data/img.cache.npy create mode 100644 data/img1.cache create mode 100644 data/scripts/download_weights.sh create mode 100644 data/scripts/get_coco.sh create mode 100644 data/scripts/get_coco128.sh create mode 100644 data/xView.yaml create mode 100644 detect.py create mode 100644 detect1.py create mode 100644 export.py create mode 100644 gen_wts.py create mode 100644 images create mode 100644 models/__init__.py create mode 100644 models/__pycache__/__init__.cpython-37.pyc create mode 100644 models/__pycache__/__init__.cpython-38.pyc create mode 100644 models/__pycache__/common.cpython-37.pyc create mode 100644 models/__pycache__/common.cpython-38.pyc create mode 100644 models/__pycache__/experimental.cpython-37.pyc create mode 100644 models/__pycache__/experimental.cpython-38.pyc create mode 100644 models/__pycache__/yolo.cpython-37.pyc create mode 100644 models/__pycache__/yolo.cpython-38.pyc create mode 100644 models/common.py create mode 100644 models/common_1.py create mode 100644 models/experimental.py create mode 100644 models/hub/anchors.yaml create mode 100644 models/hub/yolov3-spp.yaml create mode 100644 models/hub/yolov3-tiny.yaml create mode 100644 models/hub/yolov3.yaml create mode 100644 models/hub/yolov5-bifpn.yaml create mode 100644 models/hub/yolov5-fpn.yaml create mode 100644 models/hub/yolov5-p2.yaml create mode 100644 models/hub/yolov5-p6.yaml create mode 100644 models/hub/yolov5-p7.yaml create mode 100644 models/hub/yolov5-panet.yaml create mode 100644 models/hub/yolov5l6.yaml create mode 100644 models/hub/yolov5m6.yaml create mode 100644 models/hub/yolov5s6.yaml create mode 100644 models/hub/yolov5x6.yaml create mode 100644 models/yolo.py create mode 100644 models/yolov5l.yaml create mode 100644 models/yolov5m-2transformer.yaml create mode 100644 models/yolov5m.yaml create mode 100644 models/yolov5m_add_detect.yaml create mode 100644 models/yolov5m_s.yaml create mode 100644 models/yolov5s-2transformer.yaml create mode 100644 models/yolov5s-transformer.yaml create mode 100644 models/yolov5s.yaml create mode 100644 models/yolov5x.yaml create mode 100644 plugin/yololayer.cu create mode 100644 plugin/yololayer.h create mode 100644 requirements.txt create mode 100644 src/calibrator.cpp create mode 100644 src/calibrator.h create mode 100644 src/config.h create mode 100644 src/cuda_utils.h create mode 100644 src/logging.h create mode 100644 src/macros.h create mode 100644 src/model.cpp create mode 100644 src/model.h create mode 100644 src/postprocess.cpp create mode 100644 src/postprocess.h create mode 100644 src/preprocess.cu create mode 100644 src/preprocess.h create mode 100644 src/types.h create mode 100644 src/utils.h create mode 100644 train.py create mode 100644 utils/__init__.py create mode 100644 utils/__pycache__/__init__.cpython-37.pyc create mode 100644 utils/__pycache__/__init__.cpython-38.pyc create mode 100644 utils/__pycache__/augmentations.cpython-37.pyc create mode 100644 utils/__pycache__/augmentations.cpython-38.pyc create mode 100644 utils/__pycache__/autoanchor.cpython-37.pyc create mode 100644 utils/__pycache__/autoanchor.cpython-38.pyc create mode 100644 utils/__pycache__/callbacks.cpython-37.pyc create mode 100644 utils/__pycache__/callbacks.cpython-38.pyc create mode 100644 utils/__pycache__/datasets.cpython-37.pyc create mode 100644 utils/__pycache__/datasets.cpython-38.pyc create mode 100644 utils/__pycache__/downloads.cpython-37.pyc create mode 100644 utils/__pycache__/downloads.cpython-38.pyc create mode 100644 utils/__pycache__/general.cpython-37.pyc create mode 100644 utils/__pycache__/general.cpython-38.pyc create mode 100644 utils/__pycache__/loss.cpython-37.pyc create mode 100644 utils/__pycache__/loss.cpython-38.pyc create mode 100644 utils/__pycache__/metrics.cpython-37.pyc create mode 100644 utils/__pycache__/metrics.cpython-38.pyc create mode 100644 utils/__pycache__/plots.cpython-37.pyc create mode 100644 utils/__pycache__/plots.cpython-38.pyc create mode 100644 utils/__pycache__/torch_utils.cpython-37.pyc create mode 100644 utils/__pycache__/torch_utils.cpython-38.pyc create mode 100644 utils/activations.py create mode 100644 utils/augmentations.py create mode 100644 utils/autoanchor.py create mode 100644 utils/aws/__init__.py create mode 100644 utils/aws/mime.sh create mode 100644 utils/aws/resume.py create mode 100644 utils/aws/userdata.sh create mode 100644 utils/callbacks.py create mode 100644 utils/datasets.py create mode 100644 utils/downloads.py create mode 100644 utils/flask_rest_api/README.md create mode 100644 utils/flask_rest_api/example_request.py create mode 100644 utils/flask_rest_api/restapi.py create mode 100644 utils/general.py create mode 100644 utils/google_app_engine/Dockerfile create mode 100644 utils/google_app_engine/additional_requirements.txt create mode 100644 utils/google_app_engine/app.yaml create mode 100644 utils/loggers/__init__.py create mode 100644 utils/loggers/__pycache__/__init__.cpython-37.pyc create mode 100644 utils/loggers/__pycache__/__init__.cpython-38.pyc create mode 100644 utils/loggers/wandb/README.md create mode 100644 utils/loggers/wandb/__init__.py create mode 100644 utils/loggers/wandb/__pycache__/__init__.cpython-37.pyc create mode 100644 utils/loggers/wandb/__pycache__/__init__.cpython-38.pyc create mode 100644 utils/loggers/wandb/__pycache__/wandb_utils.cpython-37.pyc create mode 100644 utils/loggers/wandb/__pycache__/wandb_utils.cpython-38.pyc create mode 100644 utils/loggers/wandb/log_dataset.py create mode 100644 utils/loggers/wandb/sweep.py create mode 100644 utils/loggers/wandb/sweep.yaml create mode 100644 utils/loggers/wandb/wandb_utils.py create mode 100644 utils/loss.py create mode 100644 utils/metrics.py create mode 100644 utils/plots.py create mode 100644 utils/torch_utils.py create mode 100644 val.py create mode 100644 yolov5_cls.cpp create mode 100644 yolov5_cls_trt.py create mode 100644 yolov5_det.cpp create mode 100644 yolov5_det_cuda_python.py create mode 100644 yolov5_det_trt.py create mode 100644 yolov5_seg.cpp create mode 100644 yolov5_seg_trt.py diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..a1522ce --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,52 @@ +cmake_minimum_required(VERSION 3.10) + +project(yolov5) + +add_definitions(-std=c++11) +add_definitions(-DAPI_EXPORTS) +option(CUDA_USE_STATIC_CUDA_RUNTIME OFF) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_BUILD_TYPE Debug) + +# TODO(Call for PR): make cmake compatible with Windows +set(CMAKE_CUDA_COMPILER /usr/local/cuda/bin/nvcc) +enable_language(CUDA) + +# include and link dirs of cuda and tensorrt, you need adapt them if yours are different +# cuda +include_directories(/usr/local/cuda/include) +link_directories(/usr/local/cuda/lib64) +# tensorrt +# TODO(Call for PR): make TRT path configurable from command line +include_directories(/home/nvidia/TensorRT-8.2.5.1/include/) +link_directories(/home/nvidia/TensorRT-8.2.5.1/lib/) + +include_directories(${PROJECT_SOURCE_DIR}/src/) +include_directories(${PROJECT_SOURCE_DIR}/plugin/) +file(GLOB_RECURSE SRCS ${PROJECT_SOURCE_DIR}/src/*.cpp ${PROJECT_SOURCE_DIR}/src/*.cu) +file(GLOB_RECURSE PLUGIN_SRCS ${PROJECT_SOURCE_DIR}/plugin/*.cu) + +add_library(myplugins SHARED ${PLUGIN_SRCS}) +target_link_libraries(myplugins nvinfer cudart) + +find_package(OpenCV) +include_directories(${OpenCV_INCLUDE_DIRS}) + +add_executable(yolov5_det yolov5_det.cpp ${SRCS}) +target_link_libraries(yolov5_det nvinfer) +target_link_libraries(yolov5_det cudart) +target_link_libraries(yolov5_det myplugins) +target_link_libraries(yolov5_det ${OpenCV_LIBS}) + +add_executable(yolov5_cls yolov5_cls.cpp ${SRCS}) +target_link_libraries(yolov5_cls nvinfer) +target_link_libraries(yolov5_cls cudart) +target_link_libraries(yolov5_cls myplugins) +target_link_libraries(yolov5_cls ${OpenCV_LIBS}) + +add_executable(yolov5_seg yolov5_seg.cpp ${SRCS}) +target_link_libraries(yolov5_seg nvinfer) +target_link_libraries(yolov5_seg cudart) +target_link_libraries(yolov5_seg myplugins) +target_link_libraries(yolov5_seg ${OpenCV_LIBS}) + diff --git a/README.md b/README.md index edc6200..6d53628 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,157 @@ -# TensorRT_Transform +# YOLOv5 + +TensorRTx inference code base for [ultralytics/yolov5](https://github.com/ultralytics/yolov5). + +## Contributors + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Different versions of yolov5 + +Currently, we support yolov5 v1.0, v2.0, v3.0, v3.1, v4.0, v5.0, v6.0, v6.2, v7.0 + +- For yolov5 v7.0, download .pt from [yolov5 release v7.0](https://github.com/ultralytics/yolov5/releases/tag/v7.0), `git clone -b v7.0 https://github.com/ultralytics/yolov5.git` and `git clone -b yolov5-v7.0 https://github.com/wang-xinyu/tensorrtx.git`, then follow how-to-run in [tensorrtx/yolov5-v7.0](https://github.com/wang-xinyu/tensorrtx/tree/yolov5-v7.0/yolov5) +- For yolov5 v6.2, download .pt from [yolov5 release v6.2](https://github.com/ultralytics/yolov5/releases/tag/v6.2), `git clone -b v6.2 https://github.com/ultralytics/yolov5.git` and `git clone -b yolov5-v6.2 https://github.com/wang-xinyu/tensorrtx.git`, then follow how-to-run in [tensorrtx/yolov5-v6.2](https://github.com/wang-xinyu/tensorrtx/tree/yolov5-v6.2/yolov5) +- For yolov5 v6.0, download .pt from [yolov5 release v6.0](https://github.com/ultralytics/yolov5/releases/tag/v6.0), `git clone -b v6.0 https://github.com/ultralytics/yolov5.git` and `git clone -b yolov5-v6.0 https://github.com/wang-xinyu/tensorrtx.git`, then follow how-to-run in [tensorrtx/yolov5-v6.0](https://github.com/wang-xinyu/tensorrtx/tree/yolov5-v6.0/yolov5). +- For yolov5 v5.0, download .pt from [yolov5 release v5.0](https://github.com/ultralytics/yolov5/releases/tag/v5.0), `git clone -b v5.0 https://github.com/ultralytics/yolov5.git` and `git clone -b yolov5-v5.0 https://github.com/wang-xinyu/tensorrtx.git`, then follow how-to-run in [tensorrtx/yolov5-v5.0](https://github.com/wang-xinyu/tensorrtx/tree/yolov5-v5.0/yolov5). +- For yolov5 v4.0, download .pt from [yolov5 release v4.0](https://github.com/ultralytics/yolov5/releases/tag/v4.0), `git clone -b v4.0 https://github.com/ultralytics/yolov5.git` and `git clone -b yolov5-v4.0 https://github.com/wang-xinyu/tensorrtx.git`, then follow how-to-run in [tensorrtx/yolov5-v4.0](https://github.com/wang-xinyu/tensorrtx/tree/yolov5-v4.0/yolov5). +- For yolov5 v3.1, download .pt from [yolov5 release v3.1](https://github.com/ultralytics/yolov5/releases/tag/v3.1), `git clone -b v3.1 https://github.com/ultralytics/yolov5.git` and `git clone -b yolov5-v3.1 https://github.com/wang-xinyu/tensorrtx.git`, then follow how-to-run in [tensorrtx/yolov5-v3.1](https://github.com/wang-xinyu/tensorrtx/tree/yolov5-v3.1/yolov5). +- For yolov5 v3.0, download .pt from [yolov5 release v3.0](https://github.com/ultralytics/yolov5/releases/tag/v3.0), `git clone -b v3.0 https://github.com/ultralytics/yolov5.git` and `git clone -b yolov5-v3.0 https://github.com/wang-xinyu/tensorrtx.git`, then follow how-to-run in [tensorrtx/yolov5-v3.0](https://github.com/wang-xinyu/tensorrtx/tree/yolov5-v3.0/yolov5). +- For yolov5 v2.0, download .pt from [yolov5 release v2.0](https://github.com/ultralytics/yolov5/releases/tag/v2.0), `git clone -b v2.0 https://github.com/ultralytics/yolov5.git` and `git clone -b yolov5-v2.0 https://github.com/wang-xinyu/tensorrtx.git`, then follow how-to-run in [tensorrtx/yolov5-v2.0](https://github.com/wang-xinyu/tensorrtx/tree/yolov5-v2.0/yolov5). +- For yolov5 v1.0, download .pt from [yolov5 release v1.0](https://github.com/ultralytics/yolov5/releases/tag/v1.0), `git clone -b v1.0 https://github.com/ultralytics/yolov5.git` and `git clone -b yolov5-v1.0 https://github.com/wang-xinyu/tensorrtx.git`, then follow how-to-run in [tensorrtx/yolov5-v1.0](https://github.com/wang-xinyu/tensorrtx/tree/yolov5-v1.0/yolov5). + +## Config + +- Choose the YOLOv5 sub-model n/s/m/l/x/n6/s6/m6/l6/x6 from command line arguments. +- Other configs please check [src/config.h](src/config.h) + +## Build and Run + +### Detection + +1. generate .wts from pytorch with .pt, or download .wts from model zoo + +``` +git clone -b v7.0 https://github.com/ultralytics/yolov5.git +git clone -b yolov5-v7.0 https://github.com/wang-xinyu/tensorrtx.git +cd yolov5/ +wget https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5s.pt +cp [PATH-TO-TENSORRTX]/yolov5/gen_wts.py . +python gen_wts.py -w yolov5s.pt -o yolov5s.wts +# A file 'yolov5s.wts' will be generated. +``` + +2. build tensorrtx/yolov5 and run + +``` +cd [PATH-TO-TENSORRTX]/yolov5/ +# Update kNumClass in src/config.h if your model is trained on custom dataset +mkdir build +cd build +cp [PATH-TO-ultralytics-yolov5]/yolov5s.wts . +cmake .. +make + +./yolov5_det -s [.wts] [.engine] [n/s/m/l/x/n6/s6/m6/l6/x6 or c/c6 gd gw] // serialize model to plan file +./yolov5_det -d [.engine] [image folder] // deserialize and run inference, the images in [image folder] will be processed. + +# For example yolov5s +./yolov5_det -s yolov5s.wts yolov5s.engine s +./yolov5_det -d yolov5s.engine ../images + +# For example Custom model with depth_multiple=0.17, width_multiple=0.25 in yolov5.yaml +./yolov5_det -s yolov5_custom.wts yolov5.engine c 0.17 0.25 +./yolov5_det -d yolov5.engine ../images +``` + +3. Check the images generated, _zidane.jpg and _bus.jpg + +4. Optional, load and run the tensorrt model in Python + +``` +// Install python-tensorrt, pycuda, etc. +// Ensure the yolov5s.engine and libmyplugins.so have been built +python yolov5_det_trt.py + +// Another version of python script, which is using CUDA Python instead of pycuda. +python yolov5_det_trt_cuda_python.py +``` + +

+ +

+ +### Classification + +``` +# Download ImageNet labels +wget https://github.com/joannzhang00/ImageNet-dataset-classes-labels/blob/main/imagenet_classes.txt + +# Build and serialize TensorRT engine +./yolov5_cls -s yolov5s-cls.wts yolov5s-cls.engine s + +# Run inference +./yolov5_cls -d yolov5s-cls.engine ../images +``` + +### Instance Segmentation + +``` +# Build and serialize TensorRT engine +./yolov5_seg -s yolov5s-seg.wts yolov5s-seg.engine s + +# Download the labels file +wget -O coco.txt https://raw.githubusercontent.com/amikelive/coco-labels/master/coco-labels-2014_2017.txt + +# Run inference with labels file +./yolov5_seg -d yolov5s-seg.engine ../images coco.txt +``` + +

+ +

+ +# INT8 Quantization + +1. Prepare calibration images, you can randomly select 1000s images from your train set. For coco, you can also download my calibration images `coco_calib` from [GoogleDrive](https://drive.google.com/drive/folders/1s7jE9DtOngZMzJC1uL307J2MiaGwdRSI?usp=sharing) or [BaiduPan](https://pan.baidu.com/s/1GOm_-JobpyLMAqZWCDUhKg) pwd: a9wh + +2. unzip it in yolov5/build + +3. set the macro `USE_INT8` in src/config.h and make + +4. serialize the model and test + + +## More Information + +See the readme in [home page.](https://github.com/wang-xinyu/tensorrtx) -TensorRT转化代码 \ No newline at end of file diff --git a/__pycache__/val.cpython-37.pyc b/__pycache__/val.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..be7358d41750a6cc753c155e07f52ac40a4d20a8 GIT binary patch literal 12122 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 TDBujW>r={nd^El{2`u|xr@EUb literal 0 HcmV?d00001 diff --git a/__pycache__/val.cpython-38.pyc b/__pycache__/val.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..52e55146fe3065a7a478d38c248b7da3abe06944 GIT binary patch literal 12077 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 Mm7QM7KlG~of2=p|W&i*H literal 0 HcmV?d00001 diff --git a/data/img.cache.npy b/data/img.cache.npy new file mode 100644 index 0000000000000000000000000000000000000000..c500837b81f4e4e080a33d071c400d6303993388 GIT binary patch literal 113581 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 I;l|qk2lmi{T>t<8 literal 0 HcmV?d00001 diff --git a/data/img1.cache b/data/img1.cache new file mode 100644 index 0000000000000000000000000000000000000000..1458e87d567b91f4ede05cbe2e204b5be15b5e34 GIT binary patch literal 8820 zcmbuFcXU<77Kbk#0-;Fnp(eDD9zr>TR3S76X~F<07ZM;Od*^^42_hg(Q50<0JBo@0 z>|JaiA}T5Dh31DA z#pj1h^Dw@5TzuK+`0jD>Gm6p0oVnAAF+a@T9+ESsG)&(wEyyVeQ=ibKdt7u|wRV7qQ$gb2SGL-KwED6Uz^@){3q0s1FP-FF~l~7Yct%U3<6D!g8${=Rcs8Pc! z=u4Mu;X>`))e7pALu|stWEvUVd&-!FZZYN+Oj%ewr+9vPkD{DXH;g?nJio9sJS9KJ z&6!eIG&6ZhdQx)Ytdf~fS3$jmf>41bt6xA^4J2GdSoEjb3TRm1@ytkrM$FS#LKDN& z7n=SzPsoL4xvK{@B9Q(=%0gmY*-%mY-7?X#<~|3SyU-#x`)Kyj70^;at8if66wTXO zK^x24mU-hOw6nbJqr4rMx1)qk#9Q#cq@6v|C1TU0kl2#jPYkJDE=tCJ=0Lm)2@%pR z3c3a-P1U5`6m++wJ(x66LQhMY6eUe&(i91){-kN<-!vvOB+ky>?<^ftE}pr6ynu8U zG9sjz3VH=6P1B@V3VK`8K1|wILO)CDL`emc_Lp$6Kj{EN+IdoilRBn@!0=+RwppTp zfi4V+kPcQbBsgihCLOBa5=%OaNry|wwxlDXq$8Phl!Vd#q+<*z|D2wg*i`?V4&6CI zz@;w82BJ5KrnxXZLYku>H#li8O`4}5-;#!zbcTePmb4&BTF9icB+T|FonuJ()jxb|JN@cE zjIjcWT$mdnEmlwxm^3*_lY#=Yq@_&iN|mvUmh=WDT_@p2OL|k3bUl-9kZ`j<=`H^z z&8)S~VbYHa>k7Elh1(*ew=38foYXs?-l5=5OL`ZR-YwxCOL}jV^gbrNU%~_aqz@X> z+M%}n~ZgeNTNlTp$wO!}0B zr~OHvF{J#CYCknmzoU+)yzaoWE^LjEZd34Fa8mDl`n-Y{Ea{6(`jUi~E$J&!(pQ=E zH3_f#lfGd{`QP-|!6b1cwoEMhw6TCUU3e=(`nH1Y!AUdpd;c8;?^@FLnDl)KA6U{I zQPQ1E`k{nf{-hrn(v#aNoC6QWY0~1I^mDq~g^weodlY;UoYXt>f2!a!OS+dyKbP=@ zCH*o=x{pcsOZdv4^lL-P@BO`bE%bZ8!NJWA9B|=ag!GVt!@)_tGyf3<-&oS4OnOYh zaZCDbl=M3$Jt5(Hf6^Ze=^K+TIBU-j5Ut0S31|Fq2Tr6s|$?@aoKgg^aB&l=K{xRCg*V}_V?TbXFsWw!%=xo|E*`nQ6A0+XhA z*QoOfE?CkEBE=BhyGyJ@)$n3vYAiBVp^m7rsvfMS2Yv2Xu{tFNe@)$xSa#xir^WO| zqSdfifi);}u_lk`n{2E_ONB91gRAI^7}nN1)S+sGFqRs2s!KN?qZ-^vU+%EE-k}9m z>(r7Oc4|dOiLE&@PHi}{PHm}Ur#L;>P7nGywWq{5#T^TY2f8&B6aH8vPVb@`XPdlfE!wyxt*!s&(o@4LfzEqr`3;8K>?XS*IS3W9@s@5r!8g}YMM~PV+8K>SH zS*JeKu~T0?*iR4oIXRRVr@M|;I74^073cPsi*s3(1PTgW?9U^f)5Ww@IDl$!Cw;NS zfqI8QRISrsYS?KA9VHIs$T(fXk#!nI9Xk!zgV}n}&uIiD#)%&nmlv+mkBbk9>H$NngNmn%-eLRqK>P4Ljx1QDPoP z#wnj8>lCJroo494nR?LAselsW#OJ;ByQ=H+-i1v^9W12K#aTS!InAb}!Z}ofJLyY3 z7U>=4QngOS)UZkM)E^bBpWH~`H59tIf=4{3m9$j2ifV8t?_9oG@34ldb-I=scDjy^64!EM zoUZ4{I^94WJFU}$H|jw@r<*7-PVs+NI2${ybNGhsz@FLy*Hh@?1|IR8ZlK$&QYMpMUhMhLjQQ{pO8K*lrvQBqV$4+rlrDXs0MfP&gIYQ9kx=nPTQzq zr|0M>@p+Dn(+eC~rx&SXrh^cn;Lf7PDhFFaAcg`<;Xg{M;$x8uLnQSgMLmsC^1fa-rN2G zID8+`H0P9qJ1KPWLmu&*cF|JdM^uA5dFS%odWVmxTBkkKu+t}Wl=vw}#_2PTtkYiV z*y(dU_=O(ybNZ4J~xrp5|40XoW9}6Ivu5sosQ|j<9g7~>03&S(+>?RoT4{l#1oG#78~B9bNP1^ zx_E*|Jg4tzsqhD?ft}LyqadEtJDj3woqnW-oqnRD#Gg4bPQP$uoqnZ`olfh)-}IoL z(-}%UrzL{#%QJpY*7xOymYi|$cM4tngGW54KWVA(EY;vn-ZSA}dWUmVt<&Gsu+u+u zlz5&a<8*-|>r_DMT=YOp)&G94G9~79;%jc>{U;s%HB#|3`h`Lj3SF$qBc4+= zS}LqgHMo;^A5lZ^P?M^4sznVu#n4e=ZH|mn9geJ1EOqQuR}a?HgMP15eM*cI-|scu zdac7BIxotoCa?j8E?&eVo>N0wDr`hGxRZAu(OB=$gsOFFN)0pO0)ZwX#gE14&=x<4dTc;4W^Er zhUmeedeG155=x8{UvuX*sG^@W794ISa2SOy4(AciDVvrGM^Fv!K#T=wN9g{ zVW%;4lz1se#z}HyoyJnfPM7JyaeC0tX*?yyiQi9)-@Z?u_qHr=BX9zRF7p2kh&WB6 zrNYap26jsKu1}No4pXRFCq)fAO{Js6X&f1+=^R<79O~F9R}bdtK|iN_N{mzCjyj_0 zo~~khmwd5C((4qa(8U=%;=N8YX{oS)YItH*`dM~|zWF%+KNKZ@2 zOiIg5&CJZoOA2SEWu>NOX65FjWZ*2GtU;3)E~WpHQHrza8wuInvP1e$Hy7vd1n*o_ oI_d{Izjjj*BJqjoifl08nTRJ^%m! literal 0 HcmV?d00001 diff --git a/data/scripts/download_weights.sh b/data/scripts/download_weights.sh new file mode 100644 index 0000000..a576c95 --- /dev/null +++ b/data/scripts/download_weights.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# YOLOv5 🚀 by Ultralytics https://ultralytics.com, licensed under GNU GPL v3.0 +# Download latest models from https://github.com/ultralytics/yolov5/releases +# Example usage: bash path/to/download_weights.sh +# parent +# └── yolov5 +# ├── yolov5s.pt ← downloads here +# ├── yolov5m.pt +# └── ... + +python - <= cls >= 0, f'incorrect class index {cls}' + + # Write YOLO label + if id not in shapes: + shapes[id] = Image.open(file).size + box = xyxy2xywhn(box[None].astype(np.float), w=shapes[id][0], h=shapes[id][1], clip=True) + with open((labels / id).with_suffix('.txt'), 'a') as f: + f.write(f"{cls} {' '.join(f'{x:.6f}' for x in box[0])}\n") # write label.txt + except Exception as e: + print(f'WARNING: skipping one label for {file}: {e}') + + + # Download manually from https://challenge.xviewdataset.org + dir = Path(yaml['path']) # dataset root dir + # urls = ['https://d307kc0mrhucc3.cloudfront.net/train_labels.zip', # train labels + # 'https://d307kc0mrhucc3.cloudfront.net/train_images.zip', # 15G, 847 train images + # 'https://d307kc0mrhucc3.cloudfront.net/val_images.zip'] # 5G, 282 val images (no labels) + # download(urls, dir=dir, delete=False) + + # Convert labels + convert_labels(dir / 'xView_train.geojson') + + # Move images + images = Path(dir / 'images') + images.mkdir(parents=True, exist_ok=True) + Path(dir / 'train_images').rename(dir / 'images' / 'train') + Path(dir / 'val_images').rename(dir / 'images' / 'val') + + # Split + autosplit(dir / 'images' / 'train') diff --git a/detect.py b/detect.py new file mode 100644 index 0000000..a48d498 --- /dev/null +++ b/detect.py @@ -0,0 +1,239 @@ +"""Run inference with a YOLOv5 model on images, videos, directories, streams + +Usage: + $ python path/to/detect.py --source path/to/img.jpg --weights yolov5s.pt --img 640 +""" + +import argparse +import sys +import time +from pathlib import Path + +import cv2 +import torch +import torch.backends.cudnn as cudnn + +FILE = Path(__file__).absolute() +sys.path.append(FILE.parents[0].as_posix()) # add yolov5/ to path + +from models.experimental import attempt_load +from utils.datasets import LoadStreams, LoadImages +from utils.general import check_img_size, check_requirements, check_imshow, colorstr, non_max_suppression, \ + apply_classifier, scale_coords, xyxy2xywh, strip_optimizer, set_logging, increment_path, save_one_box +from utils.plots import colors, plot_one_box +from utils.torch_utils import select_device, load_classifier, time_sync + + +@torch.no_grad() +def run(weights='yolov5s.pt', # model.pt path(s) + source='data/images', # file/dir/URL/glob, 0 for webcam + imgsz=640, # inference size (pixels) + conf_thres=0.25, # confidence threshold + iou_thres=0.45, # NMS IOU threshold + max_det=1000, # maximum detections per image + device='', # cuda device, i.e. 0 or 0,1,2,3 or cpu + view_img=False, # show results + save_txt=False, # save results to *.txt + save_conf=False, # save confidences in --save-txt labels + save_crop=False, # save cropped prediction boxes + nosave=False, # do not save images/videos + classes=None, # filter by class: --class 0, or --class 0 2 3 + agnostic_nms=False, # class-agnostic NMS + augment=False, # augmented inference + visualize=False, # visualize features + update=False, # update all models + project='runs/detect', # save results to project/name + name='exp', # save results to project/name + exist_ok=False, # existing project/name ok, do not increment + line_thickness=3, # bounding box thickness (pixels) + hide_labels=False, # hide labels + hide_conf=False, # hide confidences + half=False, # use FP16 half-precision inference + ): + save_img = not nosave and not source.endswith('.txt') # save inference images + webcam = source.isnumeric() or source.endswith('.txt') or source.lower().startswith( + ('rtsp://', 'rtmp://', 'http://', 'https://')) + + # Directories + save_dir = increment_path(Path(project) / name, exist_ok=exist_ok) # increment run + (save_dir / 'labels' if save_txt else save_dir).mkdir(parents=True, exist_ok=True) # make dir + + # Initialize + set_logging() + device = select_device(device) + half &= device.type != 'cpu' # half precision only supported on CUDA + + # Load model + w = weights[0] if isinstance(weights, list) else weights + classify, pt, onnx = False, w.endswith('.pt'), w.endswith('.onnx') # inference type + stride, names = 64, [f'class{i}' for i in range(1000)] # assign defaults + if pt: + model = attempt_load(weights, map_location=device) # load FP32 model + stride = int(model.stride.max()) # model stride + names = model.module.names if hasattr(model, 'module') else model.names # get class names + if half: + model.half() # to FP16 + if classify: # second-stage classifier + modelc = load_classifier(name='resnet50', n=2) # initialize + modelc.load_state_dict(torch.load('resnet50.pt', map_location=device)['model']).to(device).eval() + elif onnx: + check_requirements(('onnx', 'onnxruntime')) + import onnxruntime + session = onnxruntime.InferenceSession(w, None) + imgsz = check_img_size(imgsz, s=stride) # check image size + + # Dataloader + if webcam: + view_img = check_imshow() + cudnn.benchmark = True # set True to speed up constant image size inference + dataset = LoadStreams(source, img_size=imgsz, stride=stride) + bs = len(dataset) # batch_size + else: + dataset = LoadImages(source, img_size=imgsz, stride=stride) + bs = 1 # batch_size + vid_path, vid_writer = [None] * bs, [None] * bs + + # Run inference + if pt and device.type != 'cpu': + model(torch.zeros(1, 3, imgsz, imgsz).to(device).type_as(next(model.parameters()))) # run once + t0 = time.time() + for path, img, im0s, vid_cap in dataset: + if pt: + img = torch.from_numpy(img).to(device) + img = img.half() if half else img.float() # uint8 to fp16/32 + elif onnx: + img = img.astype('float32') + img /= 255.0 # 0 - 255 to 0.0 - 1.0 + if len(img.shape) == 3: + img = img[None] # expand for batch dim + + # Inference + t1 = time_sync() + if pt: + visualize = increment_path(save_dir / Path(path).stem, mkdir=True) if visualize else False + pred = model(img, augment=augment, visualize=visualize)[0] + elif onnx: + pred = torch.tensor(session.run([session.get_outputs()[0].name], {session.get_inputs()[0].name: img})) + + # NMS + pred = non_max_suppression(pred, conf_thres, iou_thres, classes, agnostic_nms, max_det=max_det) + t2 = time_sync() + + # Second-stage classifier (optional) + if classify: + pred = apply_classifier(pred, modelc, img, im0s) + + # Process predictions + for i, det in enumerate(pred): # detections per image + if webcam: # batch_size >= 1 + p, s, im0, frame = path[i], f'{i}: ', im0s[i].copy(), dataset.count + else: + p, s, im0, frame = path, '', im0s.copy(), getattr(dataset, 'frame', 0) + + p = Path(p) # to Path + save_path = str(save_dir / p.name) # img.jpg + txt_path = str(save_dir / 'labels' / p.stem) + ('' if dataset.mode == 'image' else f'_{frame}') # img.txt + s += '%gx%g ' % img.shape[2:] # print string + gn = torch.tensor(im0.shape)[[1, 0, 1, 0]] # normalization gain whwh + imc = im0.copy() if save_crop else im0 # for save_crop + if len(det): + # Rescale boxes from img_size to im0 size + det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round() + + # Print results + for c in det[:, -1].unique(): + n = (det[:, -1] == c).sum() # detections per class + s += f"{n} {names[int(c)]}{'s' * (n > 1)}, " # add to string + + # Write results + for *xyxy, conf, cls in reversed(det): + if save_txt: # Write to file + xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist() # normalized xywh + line = (cls, *xywh, conf) if save_conf else (cls, *xywh) # label format + with open(txt_path + '.txt', 'a') as f: + f.write(('%g ' * len(line)).rstrip() % line + '\n') + + if save_img or save_crop or view_img: # Add bbox to image + c = int(cls) # integer class + label = None if hide_labels else (names[c] if hide_conf else f'{names[c]} {conf:.2f}') + plot_one_box(xyxy, im0, label=label, color=colors(c, True), line_thickness=line_thickness) + if save_crop: + save_one_box(xyxy, imc, file=save_dir / 'crops' / names[c] / f'{p.stem}.jpg', BGR=True) + + # Print time (inference + NMS) + print(f'{s}Done. ({t2 - t1:.3f}s)') + + # Stream results + if view_img: + cv2.imshow(str(p), im0) + cv2.waitKey(1) # 1 millisecond + + # Save results (image with detections) + if save_img: + if dataset.mode == 'image': + cv2.imwrite(save_path, im0) + else: # 'video' or 'stream' + if vid_path[i] != save_path: # new video + vid_path[i] = save_path + if isinstance(vid_writer[i], cv2.VideoWriter): + vid_writer[i].release() # release previous video writer + if vid_cap: # video + fps = vid_cap.get(cv2.CAP_PROP_FPS) + w = int(vid_cap.get(cv2.CAP_PROP_FRAME_WIDTH)) + h = int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) + else: # stream + fps, w, h = 30, im0.shape[1], im0.shape[0] + save_path += '.mp4' + vid_writer[i] = cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, (w, h)) + vid_writer[i].write(im0) + + if save_txt or save_img: + s = f"\n{len(list(save_dir.glob('labels/*.txt')))} labels saved to {save_dir / 'labels'}" if save_txt else '' + print(f"Results saved to {colorstr('bold', save_dir)}{s}") + + if update: + strip_optimizer(weights) # update model (to fix SourceChangeWarning) + + print(f'Done. ({time.time() - t0:.3f}s)') + + +def parse_opt(): + parser = argparse.ArgumentParser() + parser.add_argument('--weights', nargs='+', type=str, default='weights/smogfire_20230105.pt', help='model.pt path(s)') + #parser.add_argument('--source', type=str, default='image', help='file/dir/URL/glob, 0 for webcam') + parser.add_argument('--source', type=str, default='/home/thsw/WJ/nyh_submission/0_smogfire/image_for_test', help='file/dir/URL/glob, 0 for webcam') + parser.add_argument('--imgsz', '--img', '--img-size', type=int, default=640, help='inference size (pixels)') + parser.add_argument('--conf-thres', type=float, default=0.5, help='confidence threshold') + parser.add_argument('--iou-thres', type=float, default=0.7, help='NMS IoU threshold') + parser.add_argument('--max-det', type=int, default=1000, help='maximum detections per image') + parser.add_argument('--device', default='0,1', help='cuda device, i.e. 0 or 0,1,2,3 or cpu') + parser.add_argument('--view-img', action='store_true', help='show results') + parser.add_argument('--save-txt', action='store_true', help='save results to *.txt') + parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels') + parser.add_argument('--save-crop', action='store_true', help='save cropped prediction boxes') + parser.add_argument('--nosave', action='store_true', help='do not save images/videos') + parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3') + parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS') + parser.add_argument('--augment', action='store_true', help='augmented inference') + parser.add_argument('--visualize', action='store_true', help='visualize features') + parser.add_argument('--update', action='store_true', help='update all models') + parser.add_argument('--project', default='runs/detect', help='save results to project/name') + parser.add_argument('--name', default='exp', help='save results to project/name') + parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment') + parser.add_argument('--line-thickness', default=3, type=int, help='bounding box thickness (pixels)') + parser.add_argument('--hide-labels', default=False, action='store_true', help='hide labels') + parser.add_argument('--hide-conf', default=False, action='store_true', help='hide confidences') + parser.add_argument('--half', action='store_true', help='use FP16 half-precision inference') + opt = parser.parse_args() + return opt + + +def main(opt): + print(colorstr('detect: ') + ', '.join(f'{k}={v}' for k, v in vars(opt).items())) + check_requirements(exclude=('tensorboard', 'thop')) + run(**vars(opt)) + + +if __name__ == "__main__": + opt = parse_opt() + main(opt) diff --git a/detect1.py b/detect1.py new file mode 100644 index 0000000..7a5c469 --- /dev/null +++ b/detect1.py @@ -0,0 +1,239 @@ +"""Run inference with a YOLOv5 model on images, videos, directories, streams + +Usage: + $ python path/to/detect.py --source path/to/img.jpg --weights yolov5s.pt --img 640 +""" + +import argparse +import sys +import time +from pathlib import Path + +import cv2 +import torch +import torch.backends.cudnn as cudnn + +FILE = Path(__file__).absolute() +sys.path.append(FILE.parents[0].as_posix()) # add yolov5/ to path + +from models.experimental import attempt_load +from utils.datasets import LoadStreams, LoadImages +from utils.general import check_img_size, check_requirements, check_imshow, colorstr, non_max_suppression, \ + apply_classifier, scale_coords, xyxy2xywh, strip_optimizer, set_logging, increment_path, save_one_box +from utils.plots import colors, plot_one_box +from utils.torch_utils import select_device, load_classifier, time_sync + + +@torch.no_grad() +def run(weights='yolov5s.pt', # model.pt path(s) + source='data/images', # file/dir/URL/glob, 0 for webcam + imgsz=640, # inference size (pixels) + conf_thres=0.25, # confidence threshold + iou_thres=0.45, # NMS IOU threshold + max_det=1000, # maximum detections per image + device='', # cuda device, i.e. 0 or 0,1,2,3 or cpu + view_img=False, # show results + save_txt=False, # save results to *.txt + save_conf=False, # save confidences in --save-txt labels + save_crop=False, # save cropped prediction boxes + nosave=False, # do not save images/videos + classes=None, # filter by class: --class 0, or --class 0 2 3 + agnostic_nms=False, # class-agnostic NMS + augment=False, # augmented inference + visualize=False, # visualize features + update=False, # update all models + project='runs/detect', # save results to project/name + name='exp', # save results to project/name + exist_ok=False, # existing project/name ok, do not increment + line_thickness=3, # bounding box thickness (pixels) + hide_labels=False, # hide labels + hide_conf=False, # hide confidences + half=False, # use FP16 half-precision inference + ): + save_img = not nosave and not source.endswith('.txt') # save inference images + webcam = source.isnumeric() or source.endswith('.txt') or source.lower().startswith( + ('rtsp://', 'rtmp://', 'http://', 'https://')) + + # Directories + save_dir = increment_path(Path(project) / name, exist_ok=exist_ok) # increment run + (save_dir / 'labels' if save_txt else save_dir).mkdir(parents=True, exist_ok=True) # make dir + + # Initialize + set_logging() + device = select_device(device) + half &= device.type != 'cpu' # half precision only supported on CUDA + + # Load model + w = weights[0] if isinstance(weights, list) else weights + classify, pt, onnx = False, w.endswith('.pt'), w.endswith('.onnx') # inference type + stride, names = 64, [f'class{i}' for i in range(1000)] # assign defaults + if pt: + model = attempt_load(weights, map_location=device) # load FP32 model + stride = int(model.stride.max()) # model stride + names = model.module.names if hasattr(model, 'module') else model.names # get class names + if half: + model.half() # to FP16 + if classify: # second-stage classifier + modelc = load_classifier(name='resnet50', n=2) # initialize + modelc.load_state_dict(torch.load('resnet50.pt', map_location=device)['model']).to(device).eval() + elif onnx: + check_requirements(('onnx', 'onnxruntime')) + import onnxruntime + session = onnxruntime.InferenceSession(w, None) + imgsz = check_img_size(imgsz, s=stride) # check image size + + # Dataloader + if webcam: + view_img = check_imshow() + cudnn.benchmark = True # set True to speed up constant image size inference + dataset = LoadStreams(source, img_size=imgsz, stride=stride) + bs = len(dataset) # batch_size + else: + dataset = LoadImages(source, img_size=imgsz, stride=stride) + bs = 1 # batch_size + vid_path, vid_writer = [None] * bs, [None] * bs + + # Run inference + if pt and device.type != 'cpu': + model(torch.zeros(1, 3, imgsz, imgsz).to(device).type_as(next(model.parameters()))) # run once + t0 = time.time() + for path, img, im0s, vid_cap in dataset: + if pt: + img = torch.from_numpy(img).to(device) + img = img.half() if half else img.float() # uint8 to fp16/32 + elif onnx: + img = img.astype('float32') + img /= 255.0 # 0 - 255 to 0.0 - 1.0 + if len(img.shape) == 3: + img = img[None] # expand for batch dim + + # Inference + t1 = time_sync() + if pt: + visualize = increment_path(save_dir / Path(path).stem, mkdir=True) if visualize else False + pred = model(img, augment=augment, visualize=visualize)[0] + elif onnx: + pred = torch.tensor(session.run([session.get_outputs()[0].name], {session.get_inputs()[0].name: img})) + + # NMS + pred = non_max_suppression(pred, conf_thres, iou_thres, classes, agnostic_nms, max_det=max_det) + t2 = time_sync() + + # Second-stage classifier (optional) + if classify: + pred = apply_classifier(pred, modelc, img, im0s) + + # Process predictions + for i, det in enumerate(pred): # detections per image + if webcam: # batch_size >= 1 + p, s, im0, frame = path[i], f'{i}: ', im0s[i].copy(), dataset.count + else: + p, s, im0, frame = path, '', im0s.copy(), getattr(dataset, 'frame', 0) + + p = Path(p) # to Path + save_path = str(save_dir / p.name) # img.jpg + txt_path = str(save_dir / 'labels' / p.stem) + ('' if dataset.mode == 'image' else f'_{frame}') # img.txt + s += '%gx%g ' % img.shape[2:] # print string + gn = torch.tensor(im0.shape)[[1, 0, 1, 0]] # normalization gain whwh + imc = im0.copy() if save_crop else im0 # for save_crop + if len(det): + # Rescale boxes from img_size to im0 size + det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round() + + # Print results + for c in det[:, -1].unique(): + n = (det[:, -1] == c).sum() # detections per class + s += f"{n} {names[int(c)]}{'s' * (n > 1)}, " # add to string + + # Write results + for *xyxy, conf, cls in reversed(det): + if save_txt: # Write to file + xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist() # normalized xywh + line = (cls, *xywh, conf) if save_conf else (cls, *xywh) # label format + with open(txt_path + '.txt', 'a') as f: + f.write(('%g ' * len(line)).rstrip() % line + '\n') + + if save_img or save_crop or view_img: # Add bbox to image + c = int(cls) # integer class + label = None if hide_labels else (names[c] if hide_conf else f'{names[c]} {conf:.2f}') + plot_one_box(xyxy, im0, label=label, color=colors(c, True), line_thickness=line_thickness) + if save_crop: + save_one_box(xyxy, imc, file=save_dir / 'crops' / names[c] / f'{p.stem}.jpg', BGR=True) + + # Print time (inference + NMS) + print(f'{s}Done. ({t2 - t1:.3f}s)') + + # Stream results + if view_img: + cv2.imshow(str(p), im0) + cv2.waitKey(1) # 1 millisecond + + # Save results (image with detections) + if save_img: + if dataset.mode == 'image': + cv2.imwrite(save_path, im0) + else: # 'video' or 'stream' + if vid_path[i] != save_path: # new video + vid_path[i] = save_path + if isinstance(vid_writer[i], cv2.VideoWriter): + vid_writer[i].release() # release previous video writer + if vid_cap: # video + fps = vid_cap.get(cv2.CAP_PROP_FPS) + w = int(vid_cap.get(cv2.CAP_PROP_FRAME_WIDTH)) + h = int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) + else: # stream + fps, w, h = 30, im0.shape[1], im0.shape[0] + save_path += '.mp4' + vid_writer[i] = cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, (w, h)) + vid_writer[i].write(im0) + + if save_txt or save_img: + s = f"\n{len(list(save_dir.glob('labels/*.txt')))} labels saved to {save_dir / 'labels'}" if save_txt else '' + print(f"Results saved to {colorstr('bold', save_dir)}{s}") + + if update: + strip_optimizer(weights) # update model (to fix SourceChangeWarning) + + print(f'Done. ({time.time() - t0:.3f}s)') + + +def parse_opt(): + parser = argparse.ArgumentParser() + parser.add_argument('--weights', nargs='+', type=str, default='weights/yolov5s.pt', help='model.pt path(s)') + parser.add_argument('--source', type=str, default='image', help='file/dir/URL/glob, 0 for webcam') + parser.add_argument('--imgsz', '--img', '--img-size', type=int, default=640, help='inference size (pixels)') + parser.add_argument('--conf-thres', type=float, default=0.5, help='confidence threshold') + parser.add_argument('--iou-thres', type=float, default=0.7, help='NMS IoU threshold') + parser.add_argument('--max-det', type=int, default=1000, help='maximum detections per image') + parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu') + parser.add_argument('--view-img', action='store_true', help='show results') + parser.add_argument('--save-txt', action='store_true', help='save results to *.txt') + parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels') + parser.add_argument('--save-crop', action='store_true', help='save cropped prediction boxes') + parser.add_argument('--nosave', action='store_true', help='do not save images/videos') + parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3') + parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS') + parser.add_argument('--augment', action='store_true', help='augmented inference') + parser.add_argument('--visualize', action='store_true', help='visualize features') + parser.add_argument('--update', action='store_true', help='update all models') + parser.add_argument('--project', default='runs/detect', help='save results to project/name') + parser.add_argument('--name', default='exp', help='save results to project/name') + parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment') + parser.add_argument('--line-thickness', default=3, type=int, help='bounding box thickness (pixels)') + parser.add_argument('--hide-labels', default=False, action='store_true', help='hide labels') + parser.add_argument('--hide-conf', default=False, action='store_true', help='hide confidences') + parser.add_argument('--half', action='store_true', help='use FP16 half-precision inference') + opt = parser.parse_args() + return opt + + + +def main(opt): + print(colorstr('detect: ') + ', '.join(f'{k}={v}' for k, v in vars(opt).items())) + check_requirements(exclude=('tensorboard', 'thop')) + run(**vars(opt)) + + +if __name__ == "__main__": + opt = parse_opt() + main(opt) diff --git a/export.py b/export.py new file mode 100644 index 0000000..cec8595 --- /dev/null +++ b/export.py @@ -0,0 +1,189 @@ +"""Export a YOLOv5 *.pt model to TorchScript, ONNX, CoreML formats + +Usage: + $ python path/to/export.py --weights yolov5s.pt --img 640 --batch 1 +""" + +import argparse +import sys +import time +from pathlib import Path + +import torch +import torch.nn as nn +from torch.utils.mobile_optimizer import optimize_for_mobile + +FILE = Path(__file__).absolute() +sys.path.append(FILE.parents[0].as_posix()) # add yolov5/ to path + +from models.common import Conv +from models.yolo import Detect +from models.experimental import attempt_load +from utils.activations import Hardswish, SiLU +from utils.general import colorstr, check_img_size, check_requirements, file_size, set_logging +from utils.torch_utils import select_device + + +def export_torchscript(model, img, file, optimize): + # TorchScript model export + prefix = colorstr('TorchScript:') + try: + print(f'\n{prefix} starting export with torch {torch.__version__}...') + f = file.with_suffix('.torchscript.pt') + ts = torch.jit.trace(model, img, strict=False) + (optimize_for_mobile(ts) if optimize else ts).save(f) + print(f'{prefix} export success, saved as {f} ({file_size(f):.1f} MB)') + return ts + except Exception as e: + print(f'{prefix} export failure: {e}') + + +def export_onnx(model, img, file, opset, train, dynamic, simplify): + # ONNX model export + prefix = colorstr('ONNX:') + try: + check_requirements(('onnx', 'onnx-simplifier')) + import onnx + + print(f'\n{prefix} starting export with onnx {onnx.__version__}...') + f = file.with_suffix('.onnx') + torch.onnx.export(model, img, f, verbose=False, opset_version=opset, + training=torch.onnx.TrainingMode.TRAINING if train else torch.onnx.TrainingMode.EVAL, + do_constant_folding=not train, + input_names=['images'], + output_names=['output'], + dynamic_axes={'images': {0: 'batch', 2: 'height', 3: 'width'}, # shape(1,3,640,640) + 'output': {0: 'batch', 1: 'anchors'} # shape(1,25200,85) + } if dynamic else None) + + # Checks + model_onnx = onnx.load(f) # load onnx model + onnx.checker.check_model(model_onnx) # check onnx model + # print(onnx.helper.printable_graph(model_onnx.graph)) # print + + # Simplify + if simplify: + try: + import onnxsim + + print(f'{prefix} simplifying with onnx-simplifier {onnxsim.__version__}...') + model_onnx, check = onnxsim.simplify( + model_onnx, + dynamic_input_shape=dynamic, + input_shapes={'images': list(img.shape)} if dynamic else None) + assert check, 'assert check failed' + onnx.save(model_onnx, f) + except Exception as e: + print(f'{prefix} simplifier failure: {e}') + print(f'{prefix} export success, saved as {f} ({file_size(f):.1f} MB)') + print(f"{prefix} run --dynamic ONNX model inference with detect.py: 'python detect.py --weights {f}'") + except Exception as e: + print(f'{prefix} export failure: {e}') + + +def export_coreml(model, img, file): + # CoreML model export + prefix = colorstr('CoreML:') + try: + import coremltools as ct + + print(f'\n{prefix} starting export with coremltools {ct.__version__}...') + f = file.with_suffix('.mlmodel') + model.train() # CoreML exports should be placed in model.train() mode + ts = torch.jit.trace(model, img, strict=False) # TorchScript model + model = ct.convert(ts, inputs=[ct.ImageType('image', shape=img.shape, scale=1 / 255.0, bias=[0, 0, 0])]) + model.save(f) + print(f'{prefix} export success, saved as {f} ({file_size(f):.1f} MB)') + except Exception as e: + print(f'\n{prefix} export failure: {e}') + + +def run(weights='./yolov5s.pt', # weights path + img_size=(640, 640), # image (height, width) + batch_size=1, # batch size + device='cpu', # cuda device, i.e. 0 or 0,1,2,3 or cpu + include=('torchscript', 'onnx', 'coreml'), # include formats + half=False, # FP16 half-precision export + inplace=False, # set YOLOv5 Detect() inplace=True + train=False, # model.train() mode + optimize=False, # TorchScript: optimize for mobile + dynamic=False, # ONNX: dynamic axes + simplify=False, # ONNX: simplify model + opset=12, # ONNX: opset version + ): + t = time.time() + include = [x.lower() for x in include] + img_size *= 2 if len(img_size) == 1 else 1 # expand + file = Path(weights) + + # Load PyTorch model + device = select_device(device) + assert not (device.type == 'cpu' and half), '--half only compatible with GPU export, i.e. use --device 0' + model = attempt_load(weights, map_location=device) # load FP32 model + names = model.names + + # Input + gs = int(max(model.stride)) # grid size (max stride) + img_size = [check_img_size(x, gs) for x in img_size] # verify img_size are gs-multiples + img = torch.zeros(batch_size, 3, *img_size).to(device) # image size(1,3,320,192) iDetection + + # Update model + if half: + img, model = img.half(), model.half() # to FP16 + model.train() if train else model.eval() # training mode = no Detect() layer grid construction + for k, m in model.named_modules(): + if isinstance(m, Conv): # assign export-friendly activations + if isinstance(m.act, nn.Hardswish): + m.act = Hardswish() + elif isinstance(m.act, nn.SiLU): + m.act = SiLU() + elif isinstance(m, Detect): + m.inplace = inplace + m.onnx_dynamic = dynamic + # m.forward = m.forward_export # assign forward (optional) + + for _ in range(2): + y = model(img) # dry runs + print(f"\n{colorstr('PyTorch:')} starting from {weights} ({file_size(weights):.1f} MB)") + + # Exports + if 'torchscript' in include: + export_torchscript(model, img, file, optimize) + if 'onnx' in include: + export_onnx(model, img, file, opset, train, dynamic, simplify) + if 'coreml' in include: + export_coreml(model, img, file) + + # Finish + print(f'\nExport complete ({time.time() - t:.2f}s)' + f"\nResults saved to {colorstr('bold', file.parent.resolve())}" + f'\nVisualize with https://netron.app') + + +def parse_opt(): + parser = argparse.ArgumentParser() + parser.add_argument('--weights', type=str, default='./yolov5s.pt', help='weights path') + parser.add_argument('--img-size', nargs='+', type=int, default=[640, 640], help='image (height, width)') + parser.add_argument('--batch-size', type=int, default=1, help='batch size') + parser.add_argument('--device', default='cpu', help='cuda device, i.e. 0 or 0,1,2,3 or cpu') + parser.add_argument('--include', nargs='+', default=['torchscript', 'onnx', 'coreml'], help='include formats') + parser.add_argument('--half', action='store_true', help='FP16 half-precision export') + parser.add_argument('--inplace', action='store_true', help='set YOLOv5 Detect() inplace=True') + parser.add_argument('--train', action='store_true', help='model.train() mode') + parser.add_argument('--optimize', action='store_true', help='TorchScript: optimize for mobile') + parser.add_argument('--dynamic', action='store_true', help='ONNX: dynamic axes') + parser.add_argument('--simplify', action='store_true', help='ONNX: simplify model') + parser.add_argument('--opset', type=int, default=12, help='ONNX: opset version') + opt = parser.parse_args() + return opt + + +def main(opt): + set_logging() + print(colorstr('export: ') + ', '.join(f'{k}={v}' for k, v in vars(opt).items())) + run(**vars(opt)) + + +if __name__ == "__main__": + opt = parse_opt() + main(opt) diff --git a/gen_wts.py b/gen_wts.py new file mode 100644 index 0000000..789e5d7 --- /dev/null +++ b/gen_wts.py @@ -0,0 +1,59 @@ +import sys +import argparse +import os +import struct +import torch +from utils.torch_utils import select_device + + +def parse_args(): + parser = argparse.ArgumentParser(description='Convert .pt file to .wts') + parser.add_argument('-w', '--weights', required=True, + help='Input weights (.pt) file path (required)') + parser.add_argument( + '-o', '--output', help='Output (.wts) file path (optional)') + parser.add_argument( + '-t', '--type', type=str, default='detect', choices=['detect', 'cls', 'seg'], + help='determines the model is detection/classification') + args = parser.parse_args() + if not os.path.isfile(args.weights): + raise SystemExit('Invalid input file') + if not args.output: + args.output = os.path.splitext(args.weights)[0] + '.wts' + elif os.path.isdir(args.output): + args.output = os.path.join( + args.output, + os.path.splitext(os.path.basename(args.weights))[0] + '.wts') + return args.weights, args.output, args.type + + +pt_file, wts_file, m_type = parse_args() +print(f'Generating .wts for {m_type} model') + +# Load model +print(f'Loading {pt_file}') +device = select_device('cpu') +model = torch.load(pt_file, map_location=device) # Load FP32 weights +model = model['ema' if model.get('ema') else 'model'].float() + +if m_type in ['detect', 'seg']: + # update anchor_grid info + anchor_grid = model.model[-1].anchors * model.model[-1].stride[..., None, None] + # model.model[-1].anchor_grid = anchor_grid + delattr(model.model[-1], 'anchor_grid') # model.model[-1] is detect layer + # The parameters are saved in the OrderDict through the "register_buffer" method, and then saved to the weight. + model.model[-1].register_buffer("anchor_grid", anchor_grid) + model.model[-1].register_buffer("strides", model.model[-1].stride) + +model.to(device).eval() + +print(f'Writing into {wts_file}') +with open(wts_file, 'w') as f: + f.write('{}\n'.format(len(model.state_dict().keys()))) + for k, v in model.state_dict().items(): + vr = v.reshape(-1).cpu().numpy() + f.write('{} {} '.format(k, len(vr))) + for vv in vr: + f.write(' ') + f.write(struct.pack('>f', float(vv)).hex()) + f.write('\n') diff --git a/images b/images new file mode 100644 index 0000000..02cc755 --- /dev/null +++ b/images @@ -0,0 +1 @@ +../yolov3-spp/samples \ No newline at end of file diff --git a/models/__init__.py b/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/models/__pycache__/__init__.cpython-37.pyc b/models/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6dd7b8b1a6812ac95297fa268e8aba932f02e3b GIT binary patch literal 143 zcmZ?b<>g`kg0*g9i6Hthh=2h`Aj1KOi&=m~3PUi1CZpdg`kg0*g9i6Hthh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vQKO;XkRlm3* zJ4-*WGDAN(KP6SaGCwE3%rw5FC^4^CKNl#HQ>-5!pP83g5+AQuP@yHE006~8AP)cl literal 0 HcmV?d00001 diff --git a/models/__pycache__/common.cpython-37.pyc b/models/__pycache__/common.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eef6f3fe524f0e305d58dbd1578193a2cfffd645 GIT binary patch literal 20039 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 literal 0 HcmV?d00001 diff --git a/models/__pycache__/common.cpython-38.pyc b/models/__pycache__/common.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..03b3fb79360cd0b1aa7ee9a061f6528d75c42203 GIT binary patch literal 21210 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 literal 0 HcmV?d00001 diff --git a/models/__pycache__/experimental.cpython-37.pyc b/models/__pycache__/experimental.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..80c482d6e79c8a98b8921183ffaaacab33ad773f GIT binary patch literal 6042 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 literal 0 HcmV?d00001 diff --git a/models/__pycache__/experimental.cpython-38.pyc b/models/__pycache__/experimental.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..004fd2e56cd34d57b1749a2836d7cfe2329c356c GIT binary patch literal 5942 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 literal 0 HcmV?d00001 diff --git a/models/__pycache__/yolo.cpython-37.pyc b/models/__pycache__/yolo.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fc2ba194a7635a3434e7b2fc8146c092325c3ba9 GIT binary patch literal 10833 zcmcIqTZ|jmd7djd9A0*p%e_ik)3&6Dvb0`Fw&NPIe3Ru%m9=6ikuz!4@7f-yTu_Q~qt+AAUvi_-Uvv>+MX_i4vW>`~TV{H6wt$5l$&L-B3_jTU& z_5LGR;~D=<{VdD+i)@nR*wj7jhOC)pGi;X4-7~4&e-u5J{G7j3Kew&>OWrwuY8$ih z7f^G4TQ8pX3#zSu!9R~VJ?1~we|#Y4dtEEccW=J=+SS)?KYljo_~lxqR?auuY@^`^ zuKT&5RP~>7^Y|Ulcecc8yOr;h#OkA>{U|#5jo{I(cB8%6*~*_iTdq{|RJ#3mu((xf zHr!nz_i{mx9OnC-a=WvIymbxF?}F?a3i@dz+48DiUh_(=@@kuVZO(jNFr!SfwB~!P zcDokTRvLcfs$P{E^2xv#UZY*D)>>5zFjetOVuSl0`fijOwQfn&+O0x7N{Cw1_kyif zIU28Q1in{pw{GJ_%v)(iu3UguYgO7&A}E&{zE^8jqin5J6Ezye_wM+$>Z%B$bl^Aq zvhbLHyH@t21TDoY3Bk*>!o8n0%mf#a@ij2BMvPoE!4?)vzoS*ak}UpqqG&URB|va6 zGs{T!&_O2W9nAt;gCt{7?6NQL#^o!!*D%;0XgA9CaP%1NNn9qb;QL5~wypJbB4?=Y zXr2*5h-Nh8Okst_Hr3gbW5%4e4Y8W1wwQ?b9cB&mD%$IIj_MMqb3>Y>~i-q>U(9sk5cxd-Cqh1#JS@@fS81)ci{c*WkTBQ@3m+{^K&0`|8kY<^N zHM+~Yv?NZPuxn6`_HXxp@QdP#7lJ4`WQr=Uu`>0fA9bc(xPU7-jwICHI@;3(c7b-F zZs0O=P%8uT^VpSj&;ai<7QGDE0z4;XFgWjjL2JB4cqW(l?1gLF@|8VcZWF zUwrD;wJp)+<<(n?v(Gk5f$;fR4o(RCTS^9G8)V?a#Ko%L@;5vD(jv``CTeNjhZHRr zJ@8shc;4d0MjPxFTv{A;FHA;uu+i~(CGr! zYjql>vR{btJev6lN@l5}QC{WeDWjLLHwn)xH%dX^c?Dhde2{t)5gx`BOe4_@SC8o~ z{#iYz&+94uA${KHj@`ElW!fG35i=)ny?`tDPY}7P^`HYc|3-kYbqK~~?S1{NAM{L= zjL@6|n^U?CVu$9%VX1E3vU*m}?!|g>)!w&43s2a%Vqq+d5A1%NG&eKBs5VNlA;S^0 zdLqc8pG)J`O=9LRLs--}`{gw=_-*t`@*jo}k1!sB+572XugpMKBkawnKQ_>M4(i6C z&o71!L|b<6iWOY63EYL2?BJMDo9Y2?8H&k+z@0w+AUG5ZnQUo$Pv5*QEXNDX?il% zZnZW&w$&;%YvsuGq~VcrWr%hZ8!G*HP^&iEHKwE?76=HQ&*$h(r)U(j49Sa?Ivu~o z3P~j#4^V^Njr3Y%tOSwnL5#O>ZALn7o4D?*N=>5@lBFnKY4bZJ&PeEjhmdH71v#3A zG%Xo1{fxd~q;yAr5~VZxd3}LoD>Ia>;iJ2xyhidxyBWtNghlHq$FMOoKfjUqTyo3TWDzv7mP+_7um6E*NJLjr)(@fOdb4 zYA7kVq(nhX-}69C4>}rP2KkidtpgsY7EU|CpQePg7hgsar7&SpD>r=r9VVv|rH2}? z>^B;oxBp7$zsKo0q8ZO3AzBA1B#v(BmXR5AW({4olu&`SUZ zCOg97%z0Y}Xh<*@Fu`U=6-X$?6ml%a*)fS30UFo@%c4($5F+j_n_| zup$krJrLPY`+noY)IpfWpTJC(NBDxE`3PTpM?Z)!1Q+Xg>M4B=U=r=Zfb2Gp*w zLnvw}TFr|K2M9!}*?Z=D*&a|sKLJ%KpSTID{8{aF?F~{1R^Med@P=VQ;ZvE}PfH#IUA3$-2<_Fqu0=oe5413}^i~mUWOoSF%!Op-T>Cl3ipeNmn zn#hPT%A>}p>MVKBxP`ZRXs3YkfPEabzNGs&|!>E+nCUW7_ zw4iKS@Fpx)D+9BU$Hd9}MHXqOVuC6>>F!u<7!~*^rHT))r^F(&>ciGteeI=}UVJ^W zqz7a3_C||E$xeyG&yghMgs>u8=7DNUpg8<+)X?~W+!Lvvr26KM(Bw!9@&YANJrV*` z>YMO(l$8K>=o_unN&!Y0Lqoygd1^P|0q*mdWC&iN2E8I}^iXHwwt`xvI!XDyjw^Ty zi6&vAV>kef+qh4vF+Voo@O6^s&L9l`?SIebwkMDJfcX(S8 zE3xN<`uFj#+}tiE5YT37ScI#0(`wqo@kchBA}1r8{TnDqZiKQWT-qZ<1{7O0dnN-O zWEyf7P_w+`VZK*OY__^Y7~s~#WdEwbe?xPw4;{n!AigvIWegj4(R z&>83~j`4xs`VMd&5H8fSg)*t|1Sy&I^EWkts7nZ3I53zd5uCHkOPHf%^y+(m`QN8* zz4sr_RM($&fATw>e|tvS7s!ZF4Ww==q@)BzX1CVi89WzRl}4=-nYEUXY!{i$(k8!6 zEor#i$~EtBpYhA|76Kcbs9A6i5W<1)?gen#6>kaZ^vg&hBLMiS;M&BsRlA=k8|d>z zTv9t};4*St2ymU$GX`;8cj^#{_IRSaXUNHQA##!E1}!L;D*lFcSMOPHVlHE&HR-@S z*|S5t4&NL$?HY)JytJiH?dX)B(^|QAw08iBiMX&Es3SW8yFwNwD=fY#EVwi9#Suq< zt-NQFg=Fy~u!uPXomi|F6R~Yrrp;LqX9==lP_-Co2jldd^{)bmTYZQ6gz;I8xj7jy z3&};&q_s8p&qV^(4gsqV5V3&OQ};1>A7>M=tY9KoA@l;w$E;bFdWNy#-L5CuBx=Sn z|I}V@HG{j_4gz^bJXr`Y8Hk}-yAJ<{vQk$_7c zx=**iPn0Iz3gdI~FmsT8IN;uo4A2#5l^A^N4Fr?o(8DY3z?Z@x{TlzrKYmW)>0M%^ zU52D9Ls$7z&7jb=E}dHnKGgG3?4>JLU%M7WF(~;`Gw2$5)HNl%?b_#-7SC7YZK*;= zpY%P#XS|y_v3Rc14DzBaN{zwtXcjG5y_@~$_Ky@l0ohSp;ongpHs?hOk3nl1H%HK%=>B(3f!+Tp(chA3-#{r4c{G`)q1g3Zuri>8otv;tu1u;Z8pU-k~K(UIQ)J2TpT026ttnITI29F5-_DYq4522M6#Z)XJ9UE z%t0sj?H)o_p0z$to)1WqRN6|CXO}p%_9bW%MW`ths~6<&XU|l>`_fOlx$pkhGdCd2 zY3{FY)VLpbRbFC+F(t#lhW=8zl-0CWfXMdaAHbC*QHrc4!tDqlwyP?rCrSKudXnI7 zl(LR??qesOsOD89c#)?0)Cp+O3)N3fl^_wZ z3TZ_Mia+shA)#OqLLRFJsG#5A`zkc14ipsrv6_AffoRbtD}j(ko<@;F^(i-?M-28mtLQyc;E0qLdA-@6IV9i?^N@R z(w5JI#l^)u;$f{qW`AqsMn-XE%mPl6i!7oHPC{|n*+F}2oFk6qG9 zWdgMHqdN($Ts7?##pSU|W7`}C9pE(SJdKuusrLIFaZ04mN-$nx2x)#e=@tHalzfkp zKcR#`41bf7(WHhBsq#dNX!6*NJiJF|trJ2syvBJ;5qc z#SF|)x&{GL=qIEECSYx33cOyia8M!b6^uDFne+j!%JVq@3%Fy>JTP$x*9}Gox|$@8k}CD=e}=j{wv~cI9`@xr{=U7JP%*PcEjJpQjlkBDLns+r} z?3h6P2LFzT@0i2=H|0PdIk{q$6!Izz0B4EW|WaV{~jWrp`Kv|m^^(^yQ!`J zKu7FE*WN_#4O|d&M9tRV>cXXdG+UfiE*hs~hjRIAVyenHZUg8RY5MBeQLwemrz5h@-(bk*@GJ z40si$8n0?%G=p=TPtGDnn4*(NmhPom|9~EI_4zdixZa6B5VIn9EInl z%aE!QCdu!DFuSeaLXTtUVer!!bwT!-z)}6MkMxA(Y~~P`LnIJy7pBP5{NNeEE2D9$ zq)e0BI-RjH>}2a@jQXG)_0@wbXU-(i+HIXe`$Mw5et-KswL7X7yP@{q;NQaf9)|a5 z!h6ip{6s!XsTk(F6tT@W1=>vptqJLrlZ&j{- za>odhVK$s3jtwWglej*G>lChnarVMe03cI_Od_hl+s#OCadIp8J*rBScy)s!I)MsK zoj_$V!~Bj|^_m+EQR_7PV&+bb9Vjc5JWXSe&6jvNa#nD#v4Ydo$XfMFOhJNgqWO@m zAgwux>rmvAB8z*j=K)PLjC&HahE}?On`(TJavqXj;M(&#A2<-@`#5*=|8Eu)Jsr;C z|L_uoQQsYU*&ki%%UBTHVhc104p`{Xg5CXB$?#GahtEx%+u;CR68IzUzfLd|L>7et_?DqA^*0pu)U< z?Hd0h`NU^xo75j4RM=PAWgM|4UclE0fgB^f|Hup1uSLcS7l7<8+;}~*U${UcP@I#3 zBfxAzIVH*GOQO8G+~!RTNMCB;Xq8K!B}(El|d8obON=*f=2inCGR7NV*Vz+qQLv`A%*Z+As6XP$)Svbld3=n zlNF8Xodf5~F$HOPM>dzwtH8>i(Wqahs7>KdPMLDd zj^jQ}m*E&osGZg+l71RB6zR<9oZdudrb@cHw)~Wn_h`AIO+5`k~}2pst>1R z9)OQ_kT7_q1O-a!u+ix{XV0orb1A6Z6Xgw7%Bz|)`P!ntm|x1bd4B24xija_T%c^Z zvjHjiM~uY@9~Pd7;-1IaWgOc&P!N*k5op@N7ccbjl{(sp)2C>S+KM_h!2&1%FP~Tm z+6_AOx30W$^~K1dev)k>Jiy0IrH4m0$!tYA}<bWahH_pGDR4J0r)N+R_fneC3?0gdu3CC^YoaYTHL zM4wXZEBAf96*(8NlbFIKayf%bNGt^JDEO1Y7YtxVna`no+%%9P^lrFj_I&n>+Jy52 Qxh7e#GxZ0Xo8$Wb0*s^4qW}N^ literal 0 HcmV?d00001 diff --git a/models/__pycache__/yolo.cpython-38.pyc b/models/__pycache__/yolo.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ed98523898f7e7e8709d85510225a64a5214a253 GIT binary patch literal 10863 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