├── .github └── workflows │ ├── ci.yaml │ └── format_check.sh ├── .gitignore ├── .pre-commit-config.yaml ├── .readthedocs.yaml ├── LICENSE ├── MANIFEST.in ├── README.md ├── assets ├── assignment.png ├── demo.png ├── dog.jpg ├── git_fig.png ├── logo.png └── sunjian.png ├── datasets └── README.md ├── demo ├── MegEngine │ ├── cpp │ │ ├── README.md │ │ ├── build.sh │ │ └── yolox.cpp │ └── python │ │ ├── README.md │ │ ├── build.py │ │ ├── convert_weights.py │ │ ├── demo.py │ │ ├── dump.py │ │ └── models │ │ ├── __init__.py │ │ ├── darknet.py │ │ ├── network_blocks.py │ │ ├── yolo_fpn.py │ │ ├── yolo_head.py │ │ ├── yolo_pafpn.py │ │ └── yolox.py ├── ONNXRuntime │ ├── README.md │ └── onnx_inference.py ├── OpenVINO │ ├── README.md │ ├── cpp │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ └── yolox_openvino.cpp │ └── python │ │ ├── README.md │ │ └── openvino_inference.py ├── TensorRT │ ├── cpp │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── logging.h │ │ └── yolox.cpp │ └── python │ │ └── README.md ├── ncnn │ ├── README.md │ ├── android │ │ ├── README.md │ │ ├── app │ │ │ ├── build.gradle │ │ │ └── src │ │ │ │ └── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── assets │ │ │ │ └── yolox.param │ │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── megvii │ │ │ │ │ └── yoloXncnn │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ ├── YOLOXncnn.java │ │ │ │ │ └── yoloXncnn.java │ │ │ │ ├── jni │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── yoloXncnn_jni.cpp │ │ │ │ └── res │ │ │ │ ├── layout │ │ │ │ └── main.xml │ │ │ │ └── values │ │ │ │ └── strings.xml │ │ ├── build.gradle │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle │ └── cpp │ │ ├── README.md │ │ └── yolox.cpp └── nebullvm │ ├── README.md │ └── nebullvm_optimization.py ├── docs ├── .gitignore ├── Makefile ├── _static │ └── css │ │ └── custom.css ├── assignment_visualization.md ├── cache.md ├── conf.py ├── demo │ ├── megengine_cpp_readme.md │ ├── megengine_py_readme.md │ ├── ncnn_android_readme.md │ ├── ncnn_cpp_readme.md │ ├── onnx_readme.md │ ├── openvino_cpp_readme.md │ ├── openvino_py_readme.md │ ├── trt_cpp_readme.md │ └── trt_py_readme.md ├── freeze_module.md ├── index.rst ├── manipulate_training_image_size.md ├── mlflow_integration.md ├── model_zoo.md ├── quick_run.md ├── requirements-doc.txt ├── train_custom_data.md └── updates_note.md ├── exps ├── default │ ├── __init__.py │ ├── yolov3.py │ ├── yolox_l.py │ ├── yolox_m.py │ ├── yolox_nano.py │ ├── yolox_s.py │ ├── yolox_tiny.py │ └── yolox_x.py └── example │ ├── custom │ ├── nano.py │ └── yolox_s.py │ └── yolox_voc │ └── yolox_voc_s.py ├── hubconf.py ├── requirements.txt ├── setup.cfg ├── setup.py ├── tests ├── __init__.py └── utils │ └── test_model_utils.py ├── tools ├── __init__.py ├── demo.py ├── eval.py ├── export_onnx.py ├── export_torchscript.py ├── train.py ├── trt.py └── visualize_assign.py └── yolox ├── __init__.py ├── core ├── __init__.py ├── launch.py └── trainer.py ├── data ├── __init__.py ├── data_augment.py ├── data_prefetcher.py ├── dataloading.py ├── datasets │ ├── __init__.py │ ├── coco.py │ ├── coco_classes.py │ ├── datasets_wrapper.py │ ├── mosaicdetection.py │ ├── voc.py │ └── voc_classes.py └── samplers.py ├── evaluators ├── __init__.py ├── coco_evaluator.py ├── voc_eval.py └── voc_evaluator.py ├── exp ├── __init__.py ├── base_exp.py ├── build.py ├── default │ └── __init__.py └── yolox_base.py ├── layers ├── __init__.py ├── cocoeval │ ├── cocoeval.cpp │ └── cocoeval.h ├── fast_coco_eval_api.py └── jit_ops.py ├── models ├── __init__.py ├── build.py ├── darknet.py ├── losses.py ├── network_blocks.py ├── yolo_fpn.py ├── yolo_head.py ├── yolo_pafpn.py └── yolox.py ├── tools └── __init__.py └── utils ├── __init__.py ├── allreduce_norm.py ├── boxes.py ├── checkpoint.py ├── compat.py ├── demo_utils.py ├── dist.py ├── ema.py ├── logger.py ├── lr_scheduler.py ├── metric.py ├── mlflow_logger.py ├── model_utils.py ├── setup_env.py └── visualize.py /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI 4 | 5 | # Controls when the action will run. Triggers the workflow on push or pull request 6 | # events but only for the master branch 7 | on: 8 | push: 9 | pull_request: 10 | 11 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 12 | jobs: 13 | # This workflow contains a single job called "build" 14 | build: 15 | # The type of runner that the job will run on 16 | runs-on: ubuntu-20.04 17 | strategy: 18 | matrix: 19 | python-version: [3.7, 3.8] 20 | 21 | # Steps represent a sequence of tasks that will be executed as part of the job 22 | steps: 23 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 24 | - uses: actions/checkout@v2 25 | 26 | - name: Set up Python ${{ matrix.python-version }} 27 | uses: actions/setup-python@v1 28 | with: 29 | python-version: ${{ matrix.python-version }} 30 | 31 | - name: Install dependencies 32 | run: | 33 | python -m pip install --upgrade pip 34 | pip install -r requirements.txt 35 | pip install isort==4.3.21 36 | pip install flake8==3.8.3 37 | pip install "importlib-metadata<5.0" 38 | # Runs a set of commands using the runners shell 39 | - name: Format check 40 | run: ./.github/workflows/format_check.sh 41 | -------------------------------------------------------------------------------- /.github/workflows/format_check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | set -e 4 | 5 | export PYTHONPATH=$PWD:$PYTHONPATH 6 | 7 | flake8 yolox exps tools || flake8_ret=$? 8 | if [ "$flake8_ret" ]; then 9 | exit $flake8_ret 10 | fi 11 | echo "All flake check passed!" 12 | isort --check-only -rc yolox exps || isort_ret=$? 13 | if [ "$isort_ret" ]; then 14 | exit $isort_ret 15 | fi 16 | echo "All isort check passed!" 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Linux ### 2 | *~ 3 | 4 | # user experiments directory 5 | YOLOX_outputs/ 6 | datasets/ 7 | # do not ignore datasets under yolox/data 8 | !*yolox/data/datasets/ 9 | 10 | # temporary files which can be created if a process still has a handle open of a deleted file 11 | .fuse_hidden* 12 | 13 | # KDE directory preferences 14 | .directory 15 | 16 | # Linux trash folder which might appear on any partition or disk 17 | .Trash-* 18 | 19 | # .nfs files are created when an open file is removed but is still being accessed 20 | .nfs* 21 | 22 | ### PyCharm ### 23 | # User-specific stuff 24 | .idea 25 | 26 | # CMake 27 | cmake-build-*/ 28 | 29 | # Mongo Explorer plugin 30 | .idea/**/mongoSettings.xml 31 | 32 | # File-based project format 33 | *.iws 34 | 35 | # IntelliJ 36 | out/ 37 | 38 | # mpeltonen/sbt-idea plugin 39 | .idea_modules/ 40 | 41 | # JIRA plugin 42 | atlassian-ide-plugin.xml 43 | 44 | # Cursive Clojure plugin 45 | .idea/replstate.xml 46 | 47 | # Crashlytics plugin (for Android Studio and IntelliJ) 48 | com_crashlytics_export_strings.xml 49 | crashlytics.properties 50 | crashlytics-build.properties 51 | fabric.properties 52 | 53 | # Editor-based Rest Client 54 | .idea/httpRequests 55 | 56 | # Android studio 3.1+ serialized cache file 57 | .idea/caches/build_file_checksums.ser 58 | 59 | # JetBrains templates 60 | **___jb_tmp___ 61 | 62 | ### Python ### 63 | # Byte-compiled / optimized / DLL files 64 | __pycache__/ 65 | *.py[cod] 66 | *$py.class 67 | 68 | # C extensions 69 | *.so 70 | 71 | # Distribution / packaging 72 | .Python 73 | build/ 74 | develop-eggs/ 75 | dist/ 76 | downloads/ 77 | eggs/ 78 | .eggs/ 79 | lib/ 80 | lib64/ 81 | parts/ 82 | sdist/ 83 | var/ 84 | wheels/ 85 | pip-wheel-metadata/ 86 | share/python-wheels/ 87 | *.egg-info/ 88 | .installed.cfg 89 | *.egg 90 | MANIFEST 91 | 92 | # PyInstaller 93 | # Usually these files are written by a python script from a template 94 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 95 | *.manifest 96 | *.spec 97 | 98 | # Installer logs 99 | pip-log.txt 100 | pip-delete-this-directory.txt 101 | 102 | # Unit test / coverage reports 103 | htmlcov/ 104 | .tox/ 105 | .nox/ 106 | .coverage 107 | .coverage.* 108 | .cache 109 | nosetests.xml 110 | coverage.xml 111 | *.cover 112 | .hypothesis/ 113 | .pytest_cache/ 114 | 115 | # Translations 116 | *.mo 117 | *.pot 118 | 119 | # Django stuff: 120 | *.log 121 | local_settings.py 122 | db.sqlite3 123 | 124 | # Flask stuff: 125 | instance/ 126 | .webassets-cache 127 | 128 | # Scrapy stuff: 129 | .scrapy 130 | 131 | # Sphinx documentation 132 | docs/_build/ 133 | docs/build/ 134 | 135 | # PyBuilder 136 | target/ 137 | 138 | # Jupyter Notebook 139 | .ipynb_checkpoints 140 | 141 | # IPython 142 | profile_default/ 143 | ipython_config.py 144 | 145 | # pyenv 146 | .python-version 147 | 148 | # pipenv 149 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 150 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 151 | # having no cross-platform support, pipenv may install dependencies that don’t work, or not 152 | # install all needed dependencies. 153 | #Pipfile.lock 154 | 155 | # celery beat schedule file 156 | celerybeat-schedule 157 | 158 | # SageMath parsed files 159 | *.sage.py 160 | 161 | # Environments 162 | .env 163 | .venv 164 | env/ 165 | venv/ 166 | ENV/ 167 | env.bak/ 168 | venv.bak/ 169 | 170 | # Spyder project settings 171 | .spyderproject 172 | .spyproject 173 | 174 | # Rope project settings 175 | .ropeproject 176 | 177 | # mkdocs documentation 178 | /site 179 | 180 | # mypy 181 | .mypy_cache/ 182 | .dmypy.json 183 | dmypy.json 184 | 185 | # Pyre type checker 186 | .pyre/ 187 | 188 | ### Vim ### 189 | # Swap 190 | [._]*.s[a-v][a-z] 191 | [._]*.sw[a-p] 192 | [._]s[a-rt-v][a-z] 193 | [._]ss[a-gi-z] 194 | [._]sw[a-p] 195 | 196 | # Session 197 | Session.vim 198 | 199 | # Temporary 200 | .netrwhist 201 | # Auto-generated tag files 202 | tags 203 | # Persistent undo 204 | [._]*.un~ 205 | 206 | # output 207 | docs/api 208 | .code-workspace.code-workspace 209 | *.pkl 210 | *.npy 211 | *.pth 212 | *.onnx 213 | *.engine 214 | events.out.tfevents* 215 | 216 | # vscode 217 | *.code-workspace 218 | .vscode 219 | 220 | # vim 221 | .vim 222 | 223 | # OS generated files 224 | .DS_Store 225 | .DS_Store? 226 | .Trashes 227 | ehthumbs.db 228 | Thumbs.db 229 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pycqa/flake8 3 | rev: 3.8.3 4 | hooks: 5 | - id: flake8 6 | - repo: https://github.com/pre-commit/pre-commit-hooks 7 | rev: v3.1.0 8 | hooks: 9 | - id: check-added-large-files 10 | - id: check-docstring-first 11 | - id: check-executables-have-shebangs 12 | - id: check-json 13 | - id: check-yaml 14 | args: ["--unsafe"] 15 | - id: debug-statements 16 | - id: end-of-file-fixer 17 | - id: requirements-txt-fixer 18 | - id: trailing-whitespace 19 | - repo: https://github.com/jorisroovers/gitlint 20 | rev: v0.15.1 21 | hooks: 22 | - id: gitlint 23 | - repo: https://github.com/pycqa/isort 24 | rev: 4.3.21 25 | hooks: 26 | - id: isort 27 | 28 | - repo: https://github.com/PyCQA/autoflake 29 | rev: v1.4 30 | hooks: 31 | - id: autoflake 32 | name: Remove unused variables and imports 33 | entry: autoflake 34 | language: python 35 | args: 36 | [ 37 | "--in-place", 38 | "--remove-all-unused-imports", 39 | "--remove-unused-variables", 40 | "--expand-star-imports", 41 | "--ignore-init-module-imports", 42 | ] 43 | files: \.py$ 44 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # .readthedocs.yaml 2 | # Read the Docs configuration file 3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 4 | 5 | # Required 6 | version: 2 7 | 8 | # Build documentation in the docs/ directory with Sphinx 9 | sphinx: 10 | configuration: docs/conf.py 11 | 12 | # Optionally build your docs in additional formats such as PDF 13 | formats: 14 | - pdf 15 | 16 | # Optionally set the version of Python and requirements required to build your docs 17 | python: 18 | version: "3.7" 19 | install: 20 | - requirements: docs/requirements-doc.txt 21 | - requirements: requirements.txt 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include requirements.txt 2 | recursive-include yolox *.cpp *.h *.cu *.cuh *.cc 3 | -------------------------------------------------------------------------------- /assets/assignment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megvii-BaseDetection/YOLOX/d872c71bf63e1906ef7b7bb5a9d7a529c7a59e6a/assets/assignment.png -------------------------------------------------------------------------------- /assets/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megvii-BaseDetection/YOLOX/d872c71bf63e1906ef7b7bb5a9d7a529c7a59e6a/assets/demo.png -------------------------------------------------------------------------------- /assets/dog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megvii-BaseDetection/YOLOX/d872c71bf63e1906ef7b7bb5a9d7a529c7a59e6a/assets/dog.jpg -------------------------------------------------------------------------------- /assets/git_fig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megvii-BaseDetection/YOLOX/d872c71bf63e1906ef7b7bb5a9d7a529c7a59e6a/assets/git_fig.png -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megvii-BaseDetection/YOLOX/d872c71bf63e1906ef7b7bb5a9d7a529c7a59e6a/assets/logo.png -------------------------------------------------------------------------------- /assets/sunjian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Megvii-BaseDetection/YOLOX/d872c71bf63e1906ef7b7bb5a9d7a529c7a59e6a/assets/sunjian.png -------------------------------------------------------------------------------- /datasets/README.md: -------------------------------------------------------------------------------- 1 | # Prepare datasets 2 | 3 | If you have a dataset directory, you could use os environment variable named `YOLOX_DATADIR`. Under this directory, YOLOX will look for datasets in the structure described below, if needed. 4 | ``` 5 | $YOLOX_DATADIR/ 6 | COCO/ 7 | ``` 8 | You can set the location for builtin datasets by 9 | ```shell 10 | export YOLOX_DATADIR=/path/to/your/datasets 11 | ``` 12 | If `YOLOX_DATADIR` is not set, the default value of dataset directory is `./datasets` relative to your current working directory. 13 | 14 | ## Expected dataset structure for [COCO detection](https://cocodataset.org/#download): 15 | 16 | ``` 17 | COCO/ 18 | annotations/ 19 | instances_{train,val}2017.json 20 | {train,val}2017/ 21 | # image files that are mentioned in the corresponding json 22 | ``` 23 | 24 | You can use the 2014 version of the dataset as well. 25 | -------------------------------------------------------------------------------- /demo/MegEngine/cpp/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | if [ -z $CXX ];then 5 | echo "please export you c++ toolchain to CXX" 6 | echo "for example:" 7 | echo "build for host: export CXX=g++" 8 | echo "cross build for aarch64-android(always locate in NDK): export CXX=aarch64-linux-android21-clang++" 9 | echo "cross build for aarch64-linux: export CXX=aarch64-linux-gnu-g++" 10 | exit -1 11 | fi 12 | 13 | if [ -z $MGE_INSTALL_PATH ];then 14 | echo "please refsi ./README.md to init MGE_INSTALL_PATH env" 15 | exit -1 16 | fi 17 | 18 | if [ -z $OPENCV_INSTALL_INCLUDE_PATH ];then 19 | echo "please refs ./README.md to init OPENCV_INSTALL_INCLUDE_PATH env" 20 | exit -1 21 | fi 22 | 23 | if [ -z $OPENCV_INSTALL_LIB_PATH ];then 24 | echo "please refs ./README.md to init OPENCV_INSTALL_LIB_PATH env" 25 | exit -1 26 | fi 27 | 28 | INCLUDE_FLAG="-I$MGE_INSTALL_PATH/include -I$OPENCV_INSTALL_INCLUDE_PATH" 29 | LINK_FLAG="-L$MGE_INSTALL_PATH/lib/ -lmegengine -L$OPENCV_INSTALL_LIB_PATH -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs" 30 | BUILD_FLAG="-static-libstdc++ -O3 -pie -fPIE -g" 31 | 32 | if [[ $CXX =~ "android" ]]; then 33 | LINK_FLAG="${LINK_FLAG} -llog -lz" 34 | fi 35 | 36 | echo "CXX: $CXX" 37 | echo "MGE_INSTALL_PATH: $MGE_INSTALL_PATH" 38 | echo "INCLUDE_FLAG: $INCLUDE_FLAG" 39 | echo "LINK_FLAG: $LINK_FLAG" 40 | echo "BUILD_FLAG: $BUILD_FLAG" 41 | 42 | echo "[" > compile_commands.json 43 | echo "{" >> compile_commands.json 44 | echo "\"directory\": \"$PWD\"," >> compile_commands.json 45 | echo "\"command\": \"$CXX yolox.cpp -o yolox ${INCLUDE_FLAG} ${LINK_FLAG}\"," >> compile_commands.json 46 | echo "\"file\": \"$PWD/yolox.cpp\"," >> compile_commands.json 47 | echo "}," >> compile_commands.json 48 | echo "]" >> compile_commands.json 49 | $CXX yolox.cpp -o yolox ${INCLUDE_FLAG} ${LINK_FLAG} ${BUILD_FLAG} 50 | 51 | echo "build success, output file: yolox" 52 | if [[ $CXX =~ "android" ]]; then 53 | echo "try command to run:" 54 | echo "adb push/scp $MGE_INSTALL_PATH/lib/libmegengine.so android_phone" 55 | echo "adb push/scp $OPENCV_INSTALL_LIB_PATH/*.so android_phone" 56 | echo "adb push/scp ./yolox yolox_s.mge android_phone" 57 | echo "adb push/scp ../../../assets/dog.jpg android_phone" 58 | echo "adb/ssh to android_phone, then run: LD_LIBRARY_PATH=. ./yolox yolox_s.mge dog.jpg cpu/multithread " 59 | else 60 | echo "try command to run: LD_LIBRARY_PATH=$MGE_INSTALL_PATH/lib/:$OPENCV_INSTALL_LIB_PATH ./yolox yolox_s.mge ../../../assets/dog.jpg cuda/cpu/multithread " 61 | fi 62 | -------------------------------------------------------------------------------- /demo/MegEngine/python/README.md: -------------------------------------------------------------------------------- 1 | # YOLOX-Python-MegEngine 2 | 3 | Python version of YOLOX object detection base on [MegEngine](https://github.com/MegEngine/MegEngine). 4 | 5 | ## Tutorial 6 | 7 | ### Step1: install requirements 8 | 9 | ``` 10 | python3 -m pip install megengine -f https://megengine.org.cn/whl/mge.html 11 | ``` 12 | 13 | ### Step2: convert checkpoint weights from torch's path file 14 | 15 | ``` 16 | python3 convert_weights.py -w yolox_s.pth -o yolox_s_mge.pkl 17 | ``` 18 | 19 | ### Step3: run demo 20 | 21 | This part is the same as torch's python demo, but no need to specify device. 22 | 23 | ``` 24 | python3 demo.py image -n yolox-s -c yolox_s_mge.pkl --path ../../../assets/dog.jpg --conf 0.25 --nms 0.45 --tsize 640 --save_result 25 | ``` 26 | 27 | ### [Optional]Step4: dump model for cpp inference 28 | 29 | > **Note**: result model is dumped with `optimize_for_inference` and `enable_fuse_conv_bias_nonlinearity`. 30 | 31 | ``` 32 | python3 dump.py -n yolox-s -c yolox_s_mge.pkl --dump_path yolox_s.mge 33 | ``` 34 | -------------------------------------------------------------------------------- /demo/MegEngine/python/build.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | 4 | import megengine as mge 5 | import megengine.module as M 6 | 7 | from models.yolo_fpn import YOLOFPN 8 | from models.yolo_head import YOLOXHead 9 | from models.yolo_pafpn import YOLOPAFPN 10 | from models.yolox import YOLOX 11 | 12 | 13 | def build_yolox(name="yolox-s"): 14 | num_classes = 80 15 | 16 | # value meaning: depth, width 17 | param_dict = { 18 | "yolox-nano": (0.33, 0.25), 19 | "yolox-tiny": (0.33, 0.375), 20 | "yolox-s": (0.33, 0.50), 21 | "yolox-m": (0.67, 0.75), 22 | "yolox-l": (1.0, 1.0), 23 | "yolox-x": (1.33, 1.25), 24 | } 25 | if name == "yolov3": 26 | depth = 1.0 27 | width = 1.0 28 | backbone = YOLOFPN() 29 | head = YOLOXHead(num_classes, width, in_channels=[128, 256, 512], act="lrelu") 30 | model = YOLOX(backbone, head) 31 | else: 32 | assert name in param_dict 33 | kwargs = {} 34 | depth, width = param_dict[name] 35 | if name == "yolox-nano": 36 | kwargs["depthwise"] = True 37 | in_channels = [256, 512, 1024] 38 | backbone = YOLOPAFPN(depth, width, in_channels=in_channels, **kwargs) 39 | head = YOLOXHead(num_classes, width, in_channels=in_channels, **kwargs) 40 | model = YOLOX(backbone, head) 41 | 42 | for m in model.modules(): 43 | if isinstance(m, M.BatchNorm2d): 44 | m.eps = 1e-3 45 | 46 | return model 47 | 48 | 49 | def build_and_load(weight_file, name="yolox-s"): 50 | model = build_yolox(name) 51 | model_weights = mge.load(weight_file) 52 | model.load_state_dict(model_weights, strict=False) 53 | return model 54 | -------------------------------------------------------------------------------- /demo/MegEngine/python/convert_weights.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | import argparse 4 | from collections import OrderedDict 5 | 6 | import megengine as mge 7 | import torch 8 | 9 | 10 | def make_parser(): 11 | parser = argparse.ArgumentParser() 12 | parser.add_argument("-w", "--weights", type=str, help="path of weight file") 13 | parser.add_argument( 14 | "-o", 15 | "--output", 16 | default="weight_mge.pkl", 17 | type=str, 18 | help="path of weight file", 19 | ) 20 | return parser 21 | 22 | 23 | def numpy_weights(weight_file): 24 | torch_weights = torch.load(weight_file, map_location="cpu") 25 | if "model" in torch_weights: 26 | torch_weights = torch_weights["model"] 27 | new_dict = OrderedDict() 28 | for k, v in torch_weights.items(): 29 | new_dict[k] = v.cpu().numpy() 30 | return new_dict 31 | 32 | 33 | def map_weights(weight_file, output_file): 34 | torch_weights = numpy_weights(weight_file) 35 | 36 | new_dict = OrderedDict() 37 | for k, v in torch_weights.items(): 38 | if "num_batches_tracked" in k: 39 | print("drop: {}".format(k)) 40 | continue 41 | if k.endswith("bias"): 42 | print("bias key: {}".format(k)) 43 | v = v.reshape(1, -1, 1, 1) 44 | new_dict[k] = v 45 | elif "dconv" in k and "conv.weight" in k: 46 | print("depthwise conv key: {}".format(k)) 47 | cout, cin, k1, k2 = v.shape 48 | v = v.reshape(cout, 1, cin, k1, k2) 49 | new_dict[k] = v 50 | else: 51 | new_dict[k] = v 52 | 53 | mge.save(new_dict, output_file) 54 | print("save weights to {}".format(output_file)) 55 | 56 | 57 | def main(): 58 | parser = make_parser() 59 | args = parser.parse_args() 60 | map_weights(args.weights, args.output) 61 | 62 | 63 | if __name__ == "__main__": 64 | main() 65 | -------------------------------------------------------------------------------- /demo/MegEngine/python/dump.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | # Copyright (c) Megvii, Inc. and its affiliates. 4 | 5 | import argparse 6 | 7 | import megengine as mge 8 | import numpy as np 9 | from megengine import jit 10 | 11 | from build import build_and_load 12 | 13 | 14 | def make_parser(): 15 | parser = argparse.ArgumentParser("YOLOX Demo Dump") 16 | parser.add_argument("-n", "--name", type=str, default="yolox-s", help="model name") 17 | parser.add_argument("-c", "--ckpt", default=None, type=str, help="ckpt for eval") 18 | parser.add_argument( 19 | "--dump_path", default="model.mge", help="path to save the dumped model" 20 | ) 21 | return parser 22 | 23 | 24 | def dump_static_graph(model, graph_name="model.mge"): 25 | model.eval() 26 | model.head.decode_in_inference = False 27 | 28 | data = mge.Tensor(np.random.random((1, 3, 640, 640))) 29 | 30 | @jit.trace(capture_as_const=True) 31 | def pred_func(data): 32 | outputs = model(data) 33 | return outputs 34 | 35 | pred_func(data) 36 | pred_func.dump( 37 | graph_name, 38 | arg_names=["data"], 39 | optimize_for_inference=True, 40 | enable_fuse_conv_bias_nonlinearity=True, 41 | ) 42 | 43 | 44 | def main(args): 45 | model = build_and_load(args.ckpt, name=args.name) 46 | dump_static_graph(model, args.dump_path) 47 | 48 | 49 | if __name__ == "__main__": 50 | args = make_parser().parse_args() 51 | main(args) 52 | -------------------------------------------------------------------------------- /demo/MegEngine/python/models/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | # Copyright (c) Megvii Inc. All rights reserved. 4 | 5 | from .darknet import CSPDarknet, Darknet 6 | from .yolo_fpn import YOLOFPN 7 | from .yolo_head import YOLOXHead 8 | from .yolo_pafpn import YOLOPAFPN 9 | from .yolox import YOLOX 10 | -------------------------------------------------------------------------------- /demo/MegEngine/python/models/yolo_fpn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- encoding: utf-8 -*- 3 | # Copyright (c) Megvii Inc. All rights reserved. 4 | 5 | import megengine.functional as F 6 | import megengine.module as M 7 | 8 | from .darknet import Darknet 9 | from .network_blocks import BaseConv, UpSample 10 | 11 | 12 | class YOLOFPN(M.Module): 13 | """ 14 | YOLOFPN module. Darknet 53 is the default backbone of this model. 15 | """ 16 | 17 | def __init__( 18 | self, depth=53, in_features=["dark3", "dark4", "dark5"], 19 | ): 20 | super().__init__() 21 | 22 | self.backbone = Darknet(depth) 23 | self.in_features = in_features 24 | 25 | # out 1 26 | self.out1_cbl = self._make_cbl(512, 256, 1) 27 | self.out1 = self._make_embedding([256, 512], 512 + 256) 28 | 29 | # out 2 30 | self.out2_cbl = self._make_cbl(256, 128, 1) 31 | self.out2 = self._make_embedding([128, 256], 256 + 128) 32 | 33 | # upsample 34 | self.upsample = UpSample(scale_factor=2, mode="bilinear") 35 | 36 | def _make_cbl(self, _in, _out, ks): 37 | return BaseConv(_in, _out, ks, stride=1, act="lrelu") 38 | 39 | def _make_embedding(self, filters_list, in_filters): 40 | m = M.Sequential( 41 | *[ 42 | self._make_cbl(in_filters, filters_list[0], 1), 43 | self._make_cbl(filters_list[0], filters_list[1], 3), 44 | 45 | self._make_cbl(filters_list[1], filters_list[0], 1), 46 | 47 | self._make_cbl(filters_list[0], filters_list[1], 3), 48 | self._make_cbl(filters_list[1], filters_list[0], 1), 49 | ] 50 | ) 51 | return m 52 | 53 | def forward(self, inputs): 54 | """ 55 | Args: 56 | inputs (Tensor): input image. 57 | 58 | Returns: 59 | Tuple[Tensor]: FPN output features.. 60 | """ 61 | # backbone 62 | out_features = self.backbone(inputs) 63 | x2, x1, x0 = [out_features[f] for f in self.in_features] 64 | 65 | # yolo branch 1 66 | x1_in = self.out1_cbl(x0) 67 | x1_in = self.upsample(x1_in) 68 | x1_in = F.concat([x1_in, x1], 1) 69 | out_dark4 = self.out1(x1_in) 70 | 71 | # yolo branch 2 72 | x2_in = self.out2_cbl(out_dark4) 73 | x2_in = self.upsample(x2_in) 74 | x2_in = F.concat([x2_in, x2], 1) 75 | out_dark3 = self.out2(x2_in) 76 | 77 | outputs = (out_dark3, out_dark4, x0) 78 | return outputs 79 | -------------------------------------------------------------------------------- /demo/MegEngine/python/models/yolo_pafpn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- encoding: utf-8 -*- 3 | # Copyright (c) Megvii Inc. All rights reserved. 4 | 5 | import megengine.module as M 6 | import megengine.functional as F 7 | 8 | from .darknet import CSPDarknet 9 | from .network_blocks import BaseConv, CSPLayer, DWConv, UpSample 10 | 11 | 12 | class YOLOPAFPN(M.Module): 13 | """ 14 | YOLOv3 model. Darknet 53 is the default backbone of this model. 15 | """ 16 | 17 | def __init__( 18 | self, depth=1.0, width=1.0, in_features=("dark3", "dark4", "dark5"), 19 | in_channels=[256, 512, 1024], depthwise=False, act="silu", 20 | ): 21 | super().__init__() 22 | self.backbone = CSPDarknet(depth, width, depthwise=depthwise, act=act) 23 | self.in_features = in_features 24 | self.in_channels = in_channels 25 | Conv = DWConv if depthwise else BaseConv 26 | 27 | self.upsample = UpSample(scale_factor=2, mode="bilinear") 28 | self.lateral_conv0 = BaseConv( 29 | int(in_channels[2] * width), int(in_channels[1] * width), 1, 1, act=act 30 | ) 31 | self.C3_p4 = CSPLayer( 32 | int(2 * in_channels[1] * width), 33 | int(in_channels[1] * width), 34 | round(3 * depth), 35 | False, 36 | depthwise=depthwise, 37 | act=act, 38 | ) # cat 39 | 40 | self.reduce_conv1 = BaseConv( 41 | int(in_channels[1] * width), int(in_channels[0] * width), 1, 1, act=act 42 | ) 43 | self.C3_p3 = CSPLayer( 44 | int(2 * in_channels[0] * width), 45 | int(in_channels[0] * width), 46 | round(3 * depth), 47 | False, 48 | depthwise=depthwise, 49 | act=act, 50 | ) 51 | 52 | # bottom-up conv 53 | self.bu_conv2 = Conv( 54 | int(in_channels[0] * width), int(in_channels[0] * width), 3, 2, act=act 55 | ) 56 | self.C3_n3 = CSPLayer( 57 | int(2 * in_channels[0] * width), 58 | int(in_channels[1] * width), 59 | round(3 * depth), 60 | False, 61 | depthwise=depthwise, 62 | act=act, 63 | ) 64 | 65 | # bottom-up conv 66 | self.bu_conv1 = Conv( 67 | int(in_channels[1] * width), int(in_channels[1] * width), 3, 2, act=act 68 | ) 69 | self.C3_n4 = CSPLayer( 70 | int(2 * in_channels[1] * width), 71 | int(in_channels[2] * width), 72 | round(3 * depth), 73 | False, 74 | depthwise=depthwise, 75 | act=act, 76 | ) 77 | 78 | def forward(self, input): 79 | """ 80 | Args: 81 | inputs: input images. 82 | 83 | Returns: 84 | Tuple[Tensor]: FPN feature. 85 | """ 86 | 87 | # backbone 88 | out_features = self.backbone(input) 89 | features = [out_features[f] for f in self.in_features] 90 | [x2, x1, x0] = features 91 | 92 | fpn_out0 = self.lateral_conv0(x0) # 1024->512/32 93 | f_out0 = self.upsample(fpn_out0) # 512/16 94 | f_out0 = F.concat([f_out0, x1], 1) # 512->1024/16 95 | f_out0 = self.C3_p4(f_out0) # 1024->512/16 96 | 97 | fpn_out1 = self.reduce_conv1(f_out0) # 512->256/16 98 | f_out1 = self.upsample(fpn_out1) # 256/8 99 | f_out1 = F.concat([f_out1, x2], 1) # 256->512/8 100 | pan_out2 = self.C3_p3(f_out1) # 512->256/8 101 | 102 | p_out1 = self.bu_conv2(pan_out2) # 256->256/16 103 | p_out1 = F.concat([p_out1, fpn_out1], 1) # 256->512/16 104 | pan_out1 = self.C3_n3(p_out1) # 512->512/16 105 | 106 | p_out0 = self.bu_conv1(pan_out1) # 512->512/32 107 | p_out0 = F.concat([p_out0, fpn_out0], 1) # 512->1024/32 108 | pan_out0 = self.C3_n4(p_out0) # 1024->1024/32 109 | 110 | outputs = (pan_out2, pan_out1, pan_out0) 111 | return outputs 112 | -------------------------------------------------------------------------------- /demo/MegEngine/python/models/yolox.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- encoding: utf-8 -*- 3 | # Copyright (c) Megvii Inc. All rights reserved. 4 | 5 | import megengine.module as M 6 | 7 | from .yolo_head import YOLOXHead 8 | from .yolo_pafpn import YOLOPAFPN 9 | 10 | 11 | class YOLOX(M.Module): 12 | """ 13 | YOLOX model module. The module list is defined by create_yolov3_modules function. 14 | The network returns loss values from three YOLO layers during training 15 | and detection results during test. 16 | """ 17 | 18 | def __init__(self, backbone=None, head=None): 19 | super().__init__() 20 | if backbone is None: 21 | backbone = YOLOPAFPN() 22 | if head is None: 23 | head = YOLOXHead(80) 24 | 25 | self.backbone = backbone 26 | self.head = head 27 | 28 | def forward(self, x): 29 | # fpn output content features of [dark3, dark4, dark5] 30 | fpn_outs = self.backbone(x) 31 | assert not self.training 32 | outputs = self.head(fpn_outs) 33 | 34 | return outputs 35 | -------------------------------------------------------------------------------- /demo/ONNXRuntime/README.md: -------------------------------------------------------------------------------- 1 | ## YOLOX-ONNXRuntime in Python 2 | 3 | This doc introduces how to convert your pytorch model into onnx, and how to run an onnxruntime demo to verify your convertion. 4 | 5 | ### Step1: Install onnxruntime 6 | 7 | run the following command to install onnxruntime: 8 | ```shell 9 | pip install onnxruntime 10 | ``` 11 | 12 | ### Step2: Get ONNX models 13 | 14 | Users might download our pre-generated ONNX models or convert their own models to ONNX. 15 | 16 | #### Download ONNX models. 17 | 18 | | Model | Parameters | GFLOPs | Test Size | mAP | Weights | 19 | |:------| :----: | :----: | :---: | :---: | :---: | 20 | | YOLOX-Nano | 0.91M | 1.08 | 416x416 | 25.8 |[github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_nano.onnx) | 21 | | YOLOX-Tiny | 5.06M | 6.45 | 416x416 |32.8 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_tiny.onnx) | 22 | | YOLOX-S | 9.0M | 26.8 | 640x640 |40.5 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_s.onnx) | 23 | | YOLOX-M | 25.3M | 73.8 | 640x640 |47.2 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_m.onnx) | 24 | | YOLOX-L | 54.2M | 155.6 | 640x640 |50.1 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_l.onnx) | 25 | | YOLOX-Darknet53| 63.72M | 185.3 | 640x640 |48.0 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_darknet.onnx) | 26 | | YOLOX-X | 99.1M | 281.9 | 640x640 |51.5 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_x.onnx) | 27 | 28 | #### Convert Your Model to ONNX 29 | 30 | First, you should move to by: 31 | ```shell 32 | cd 33 | ``` 34 | Then, you can: 35 | 36 | 1. Convert a standard YOLOX model by -n: 37 | ```shell 38 | python3 tools/export_onnx.py --output-name yolox_s.onnx -n yolox-s -c yolox_s.pth 39 | ``` 40 | Notes: 41 | * -n: specify a model name. The model name must be one of the [yolox-s,m,l,x and yolox-nano, yolox-tiny, yolov3] 42 | * -c: the model you have trained 43 | * -o: opset version, default 11. **However, if you will further convert your onnx model to [OpenVINO](https://github.com/Megvii-BaseDetection/YOLOX/demo/OpenVINO/), please specify the opset version to 10.** 44 | * --no-onnxsim: disable onnxsim 45 | * To customize an input shape for onnx model, modify the following code in tools/export.py: 46 | 47 | ```python 48 | dummy_input = torch.randn(1, 3, exp.test_size[0], exp.test_size[1]) 49 | ``` 50 | 51 | 1. Convert a standard YOLOX model by -f. When using -f, the above command is equivalent to: 52 | 53 | ```shell 54 | python3 tools/export_onnx.py --output-name yolox_s.onnx -f exps/default/yolox_s.py -c yolox_s.pth 55 | ``` 56 | 57 | 3. To convert your customized model, please use -f: 58 | 59 | ```shell 60 | python3 tools/export_onnx.py --output-name your_yolox.onnx -f exps/your_dir/your_yolox.py -c your_yolox.pth 61 | ``` 62 | 63 | ### Step3: ONNXRuntime Demo 64 | 65 | Step1. 66 | ```shell 67 | cd /demo/ONNXRuntime 68 | ``` 69 | 70 | Step2. 71 | ```shell 72 | python3 onnx_inference.py -m -i -o -s 0.3 --input_shape 640,640 73 | ``` 74 | Notes: 75 | * -m: your converted onnx model 76 | * -i: input_image 77 | * -s: score threshold for visualization. 78 | * --input_shape: should be consistent with the shape you used for onnx convertion. 79 | -------------------------------------------------------------------------------- /demo/ONNXRuntime/onnx_inference.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Copyright (c) Megvii, Inc. and its affiliates. 3 | 4 | import argparse 5 | import os 6 | 7 | import cv2 8 | import numpy as np 9 | 10 | import onnxruntime 11 | 12 | from yolox.data.data_augment import preproc as preprocess 13 | from yolox.data.datasets import COCO_CLASSES 14 | from yolox.utils import mkdir, multiclass_nms, demo_postprocess, vis 15 | 16 | 17 | def make_parser(): 18 | parser = argparse.ArgumentParser("onnxruntime inference sample") 19 | parser.add_argument( 20 | "-m", 21 | "--model", 22 | type=str, 23 | default="yolox.onnx", 24 | help="Input your onnx model.", 25 | ) 26 | parser.add_argument( 27 | "-i", 28 | "--image_path", 29 | type=str, 30 | default='test_image.png', 31 | help="Path to your input image.", 32 | ) 33 | parser.add_argument( 34 | "-o", 35 | "--output_dir", 36 | type=str, 37 | default='demo_output', 38 | help="Path to your output directory.", 39 | ) 40 | parser.add_argument( 41 | "-s", 42 | "--score_thr", 43 | type=float, 44 | default=0.3, 45 | help="Score threshould to filter the result.", 46 | ) 47 | parser.add_argument( 48 | "--input_shape", 49 | type=str, 50 | default="640,640", 51 | help="Specify an input shape for inference.", 52 | ) 53 | return parser 54 | 55 | 56 | if __name__ == '__main__': 57 | args = make_parser().parse_args() 58 | 59 | input_shape = tuple(map(int, args.input_shape.split(','))) 60 | origin_img = cv2.imread(args.image_path) 61 | img, ratio = preprocess(origin_img, input_shape) 62 | 63 | session = onnxruntime.InferenceSession(args.model) 64 | 65 | ort_inputs = {session.get_inputs()[0].name: img[None, :, :, :]} 66 | output = session.run(None, ort_inputs) 67 | predictions = demo_postprocess(output[0], input_shape)[0] 68 | 69 | boxes = predictions[:, :4] 70 | scores = predictions[:, 4:5] * predictions[:, 5:] 71 | 72 | boxes_xyxy = np.ones_like(boxes) 73 | boxes_xyxy[:, 0] = boxes[:, 0] - boxes[:, 2]/2. 74 | boxes_xyxy[:, 1] = boxes[:, 1] - boxes[:, 3]/2. 75 | boxes_xyxy[:, 2] = boxes[:, 0] + boxes[:, 2]/2. 76 | boxes_xyxy[:, 3] = boxes[:, 1] + boxes[:, 3]/2. 77 | boxes_xyxy /= ratio 78 | dets = multiclass_nms(boxes_xyxy, scores, nms_thr=0.45, score_thr=0.1) 79 | if dets is not None: 80 | final_boxes, final_scores, final_cls_inds = dets[:, :4], dets[:, 4], dets[:, 5] 81 | origin_img = vis(origin_img, final_boxes, final_scores, final_cls_inds, 82 | conf=args.score_thr, class_names=COCO_CLASSES) 83 | 84 | mkdir(args.output_dir) 85 | output_path = os.path.join(args.output_dir, os.path.basename(args.image_path)) 86 | cv2.imwrite(output_path, origin_img) 87 | -------------------------------------------------------------------------------- /demo/OpenVINO/README.md: -------------------------------------------------------------------------------- 1 | ## YOLOX for OpenVINO 2 | 3 | * [C++ Demo](./cpp) 4 | * [Python Demo](./python) -------------------------------------------------------------------------------- /demo/OpenVINO/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.4.1) 2 | set(CMAKE_CXX_STANDARD 14) 3 | 4 | project(yolox_openvino_demo) 5 | 6 | find_package(OpenCV REQUIRED) 7 | find_package(InferenceEngine REQUIRED) 8 | find_package(ngraph REQUIRED) 9 | 10 | include_directories( 11 | ${OpenCV_INCLUDE_DIRS} 12 | ${CMAKE_CURRENT_SOURCE_DIR} 13 | ${CMAKE_CURRENT_BINARY_DIR} 14 | ) 15 | 16 | add_executable(yolox_openvino yolox_openvino.cpp) 17 | 18 | target_link_libraries( 19 | yolox_openvino 20 | ${InferenceEngine_LIBRARIES} 21 | ${NGRAPH_LIBRARIES} 22 | ${OpenCV_LIBS} 23 | ) -------------------------------------------------------------------------------- /demo/OpenVINO/cpp/README.md: -------------------------------------------------------------------------------- 1 | # YOLOX-OpenVINO in C++ 2 | 3 | This tutorial includes a C++ demo for OpenVINO, as well as some converted models. 4 | 5 | ### Download OpenVINO models. 6 | 7 | | Model | Parameters | GFLOPs | Test Size | mAP | Weights | 8 | |:------| :----: | :----: | :---: | :---: | :---: | 9 | | [YOLOX-Nano](../../../exps/default/nano.py) | 0.91M | 1.08 | 416x416 | 25.8 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_nano_openvino.tar.gz) | 10 | | [YOLOX-Tiny](../../../exps/default/yolox_tiny.py) | 5.06M | 6.45 | 416x416 |32.8 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_tiny_openvino.tar.gz) | 11 | | [YOLOX-S](../../../exps/default/yolox_s.py) | 9.0M | 26.8 | 640x640 |40.5 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_s_openvino.tar.gz) | 12 | | [YOLOX-M](../../../exps/default/yolox_m.py) | 25.3M | 73.8 | 640x640 |47.2 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_m_openvino.tar.gz) | 13 | | [YOLOX-L](../../../exps/default/yolox_l.py) | 54.2M | 155.6 | 640x640 |50.1 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_l_openvino.tar.gz) | 14 | | [YOLOX-Darknet53](../../../exps/default/yolov3.py) | 63.72M | 185.3 | 640x640 |48.0 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_dark_openvino.tar.gz) | 15 | | [YOLOX-X](../../../exps/default/yolox_x.py) | 99.1M | 281.9 | 640x640 |51.5 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_x_openvino.tar.gz) | 16 | 17 | ## Install OpenVINO Toolkit 18 | 19 | Please visit [Openvino Homepage](https://docs.openvinotoolkit.org/latest/get_started_guides.html) for more details. 20 | 21 | ## Set up the Environment 22 | 23 | ### For Linux 24 | 25 | **Option1. Set up the environment tempororally. You need to run this command everytime you start a new shell window.** 26 | 27 | ```shell 28 | source /opt/intel/openvino_2021/bin/setupvars.sh 29 | ``` 30 | 31 | **Option2. Set up the environment permenantly.** 32 | 33 | *Step1.* For Linux: 34 | ```shell 35 | vim ~/.bashrc 36 | ``` 37 | 38 | *Step2.* Add the following line into your file: 39 | 40 | ```shell 41 | source /opt/intel/openvino_2021/bin/setupvars.sh 42 | ``` 43 | 44 | *Step3.* Save and exit the file, then run: 45 | 46 | ```shell 47 | source ~/.bashrc 48 | ``` 49 | 50 | 51 | ## Convert model 52 | 53 | 1. Export ONNX model 54 | 55 | Please refer to the [ONNX tutorial](../../ONNXRuntime). **Note that you should set --opset to 10, otherwise your next step will fail.** 56 | 57 | 2. Convert ONNX to OpenVINO 58 | 59 | ``` shell 60 | cd /openvino_2021/deployment_tools/model_optimizer 61 | ``` 62 | 63 | Install requirements for convert tool 64 | 65 | ```shell 66 | sudo ./install_prerequisites/install_prerequisites_onnx.sh 67 | ``` 68 | 69 | Then convert model. 70 | ```shell 71 | python3 mo.py --input_model --input_shape [--data_type FP16] 72 | ``` 73 | For example: 74 | ```shell 75 | python3 mo.py --input_model yolox_tiny.onnx --input_shape [1,3,416,416] --data_type FP16 76 | ``` 77 | 78 | Make sure the input shape is consistent with [those](yolox_openvino.cpp#L24-L25) in cpp file. 79 | 80 | ## Build 81 | 82 | ### Linux 83 | ```shell 84 | source /opt/intel/openvino_2021/bin/setupvars.sh 85 | mkdir build 86 | cd build 87 | cmake .. 88 | make 89 | ``` 90 | 91 | ## Demo 92 | 93 | ### c++ 94 | 95 | ```shell 96 | ./yolox_openvino 97 | ``` 98 | -------------------------------------------------------------------------------- /demo/OpenVINO/python/README.md: -------------------------------------------------------------------------------- 1 | # YOLOX-OpenVINO in Python 2 | 3 | This tutorial includes a Python demo for OpenVINO, as well as some converted models. 4 | 5 | ### Download OpenVINO models. 6 | 7 | | Model | Parameters | GFLOPs | Test Size | mAP | Weights | 8 | |:------| :----: | :----: | :---: | :---: | :---: | 9 | | [YOLOX-Nano](../../../exps/default/nano.py) | 0.91M | 1.08 | 416x416 | 25.8 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_nano_openvino.tar.gz) | 10 | | [YOLOX-Tiny](../../../exps/default/yolox_tiny.py) | 5.06M | 6.45 | 416x416 |32.8 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_tiny_openvino.tar.gz) | 11 | | [YOLOX-S](../../../exps/default/yolox_s.py) | 9.0M | 26.8 | 640x640 |40.5 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_s_openvino.tar.gz) | 12 | | [YOLOX-M](../../../exps/default/yolox_m.py) | 25.3M | 73.8 | 640x640 |47.2 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_m_openvino.tar.gz) | 13 | | [YOLOX-L](../../../exps/default/yolox_l.py) | 54.2M | 155.6 | 640x640 |50.1 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_l_openvino.tar.gz) | 14 | | [YOLOX-Darknet53](../../../exps/default/yolov3.py) | 63.72M | 185.3 | 640x640 |48.0 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_dark_openvino.tar.gz) | 15 | | [YOLOX-X](../../../exps/default/yolox_x.py) | 99.1M | 281.9 | 640x640 |51.5 | [github](https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_x_openvino.tar.gz) | 16 | 17 | ## Install OpenVINO Toolkit 18 | 19 | Please visit [Openvino Homepage](https://docs.openvinotoolkit.org/latest/get_started_guides.html) for more details. 20 | 21 | ## Set up the Environment 22 | 23 | ### For Linux 24 | 25 | **Option1. Set up the environment tempororally. You need to run this command everytime you start a new shell window.** 26 | 27 | ```shell 28 | source /opt/intel/openvino_2021/bin/setupvars.sh 29 | ``` 30 | 31 | **Option2. Set up the environment permenantly.** 32 | 33 | *Step1.* For Linux: 34 | ```shell 35 | vim ~/.bashrc 36 | ``` 37 | 38 | *Step2.* Add the following line into your file: 39 | 40 | ```shell 41 | source /opt/intel/openvino_2021/bin/setupvars.sh 42 | ``` 43 | 44 | *Step3.* Save and exit the file, then run: 45 | 46 | ```shell 47 | source ~/.bashrc 48 | ``` 49 | 50 | 51 | ## Convert model 52 | 53 | 1. Export ONNX model 54 | 55 | Please refer to the [ONNX tutorial](https://github.com/Megvii-BaseDetection/YOLOX/demo/ONNXRuntime). **Note that you should set --opset to 10, otherwise your next step will fail.** 56 | 57 | 2. Convert ONNX to OpenVINO 58 | 59 | ``` shell 60 | cd /openvino_2021/deployment_tools/model_optimizer 61 | ``` 62 | 63 | Install requirements for convert tool 64 | 65 | ```shell 66 | sudo ./install_prerequisites/install_prerequisites_onnx.sh 67 | ``` 68 | 69 | Then convert model. 70 | ```shell 71 | python3 mo.py --input_model --input_shape [--data_type FP16] 72 | ``` 73 | For example: 74 | ```shell 75 | python3 mo.py --input_model yolox.onnx --input_shape [1,3,640,640] --data_type FP16 --output_dir converted_output 76 | ``` 77 | 78 | ## Demo 79 | 80 | ### python 81 | 82 | ```shell 83 | python openvino_inference.py -m -i 84 | ``` 85 | or 86 | ```shell 87 | python openvino_inference.py -m -i -o -s -d 88 | ``` 89 | 90 | -------------------------------------------------------------------------------- /demo/TensorRT/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6) 2 | 3 | project(yolox) 4 | 5 | add_definitions(-std=c++11) 6 | 7 | option(CUDA_USE_STATIC_CUDA_RUNTIME OFF) 8 | set(CMAKE_CXX_STANDARD 11) 9 | set(CMAKE_BUILD_TYPE Debug) 10 | 11 | find_package(CUDA REQUIRED) 12 | 13 | include_directories(${PROJECT_SOURCE_DIR}/include) 14 | # include and link dirs of cuda and tensorrt, you need adapt them if yours are different 15 | # cuda 16 | include_directories(/data/cuda/cuda-10.2/cuda/include) 17 | link_directories(/data/cuda/cuda-10.2/cuda/lib64) 18 | # cudnn 19 | include_directories(/data/cuda/cuda-10.2/cudnn/v8.0.4/include) 20 | link_directories(/data/cuda/cuda-10.2/cudnn/v8.0.4/lib64) 21 | # tensorrt 22 | include_directories(/data/cuda/cuda-10.2/TensorRT/v7.2.1.6/include) 23 | link_directories(/data/cuda/cuda-10.2/TensorRT/v7.2.1.6/lib) 24 | 25 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Ofast -Wfatal-errors -D_MWAITXINTRIN_H_INCLUDED") 26 | 27 | find_package(OpenCV) 28 | include_directories(${OpenCV_INCLUDE_DIRS}) 29 | 30 | add_executable(yolox ${PROJECT_SOURCE_DIR}/yolox.cpp) 31 | target_link_libraries(yolox nvinfer) 32 | target_link_libraries(yolox cudart) 33 | target_link_libraries(yolox ${OpenCV_LIBS}) 34 | 35 | add_definitions(-O2 -pthread) 36 | 37 | -------------------------------------------------------------------------------- /demo/TensorRT/cpp/README.md: -------------------------------------------------------------------------------- 1 | # YOLOX-TensorRT in C++ 2 | 3 | As YOLOX models are easy to convert to tensorrt using [torch2trt gitrepo](https://github.com/NVIDIA-AI-IOT/torch2trt), 4 | our C++ demo does not include the model converting or constructing like other tenorrt demos. 5 | 6 | 7 | ## Step 1: Prepare serialized engine file 8 | 9 | Follow the trt [python demo README](https://github.com/Megvii-BaseDetection/YOLOX/blob/main/demo/TensorRT/python/README.md) to convert and save the serialized engine file. 10 | 11 | Check the 'model_trt.engine' file generated from Step 1, which will be automatically saved at the current demo dir. 12 | 13 | 14 | ## Step 2: build the demo 15 | 16 | Please follow the [TensorRT Installation Guide](https://docs.nvidia.com/deeplearning/tensorrt/install-guide/index.html) to install TensorRT. 17 | 18 | And you should set the TensorRT path and CUDA path in CMakeLists.txt. 19 | 20 | If you train your custom dataset, you may need to modify the value of `num_class`. 21 | 22 | ```c++ 23 | const int num_class = 80; 24 | ``` 25 | 26 | Install opencv with ```sudo apt-get install libopencv-dev``` (we don't need a higher version of opencv like v3.3+). 27 | 28 | build the demo: 29 | 30 | ```shell 31 | mkdir build 32 | cd build 33 | cmake .. 34 | make 35 | ``` 36 | 37 | Then run the demo: 38 | 39 | ```shell 40 | ./yolox ../model_trt.engine -i ../../../../assets/dog.jpg 41 | ``` 42 | 43 | or 44 | 45 | ```shell 46 | ./yolox -i 47 | ``` 48 | 49 | NOTE: for `trtexec` users, modify `INPUT_BLOB_NAME` and `OUTPUT_BLOB_NAME` as the following code. 50 | ``` 51 | const char* INPUT_BLOB_NAME = "images"; 52 | const char* OUTPUT_BLOB_NAME = "output"; 53 | ``` 54 | 55 | Here is the command to convert the small onnx model to tensorrt engine file: 56 | ``` 57 | trtexec --onnx=yolox_s.onnx --saveEngine=yolox_s.trt 58 | ``` 59 | -------------------------------------------------------------------------------- /demo/TensorRT/python/README.md: -------------------------------------------------------------------------------- 1 | # YOLOX-TensorRT in Python 2 | 3 | This tutorial includes a Python demo for TensorRT. 4 | 5 | ## Install TensorRT Toolkit 6 | 7 | Please follow the [TensorRT Installation Guide](https://docs.nvidia.com/deeplearning/tensorrt/install-guide/index.html) and [torch2trt gitrepo](https://github.com/NVIDIA-AI-IOT/torch2trt) to install TensorRT and torch2trt. 8 | 9 | ## Convert model 10 | 11 | YOLOX models can be easily conveted to TensorRT models using torch2trt 12 | 13 | If you want to convert our model, use the flag -n to specify a model name: 14 | ```shell 15 | python tools/trt.py -n -c 16 | ``` 17 | For example: 18 | ```shell 19 | python tools/trt.py -n yolox-s -c your_ckpt.pth 20 | ``` 21 | can be: yolox-nano, yolox-tiny. yolox-s, yolox-m, yolox-l, yolox-x. 22 | 23 | If you want to convert your customized model, use the flag -f to specify you exp file: 24 | ```shell 25 | python tools/trt.py -f -c 26 | ``` 27 | For example: 28 | ```shell 29 | python tools/trt.py -f /path/to/your/yolox/exps/yolox_s.py -c your_ckpt.pth 30 | ``` 31 | *yolox_s.py* can be any exp file modified by you. 32 | 33 | The converted model and the serialized engine file (for C++ demo) will be saved on your experiment output dir. 34 | 35 | ## Demo 36 | 37 | The TensorRT python demo is merged on our pytorch demo file, so you can run the pytorch demo command with ```--trt```. 38 | 39 | ```shell 40 | python tools/demo.py image -n yolox-s --trt --save_result 41 | ``` 42 | or 43 | ```shell 44 | python tools/demo.py image -f exps/default/yolox_s.py --trt --save_result 45 | ``` 46 | 47 | -------------------------------------------------------------------------------- /demo/ncnn/README.md: -------------------------------------------------------------------------------- 1 | # YOLOX-ncnn 2 | 3 | Compile files of YOLOX object detection base on [ncnn](https://github.com/Tencent/ncnn). 4 | YOLOX is included in ncnn now, you could also try building from ncnn, it's better. 5 | 6 | ## Acknowledgement 7 | 8 | * [ncnn](https://github.com/Tencent/ncnn) 9 | -------------------------------------------------------------------------------- /demo/ncnn/android/README.md: -------------------------------------------------------------------------------- 1 | # YOLOX-Android-ncnn 2 | 3 | Andoird app of YOLOX object detection base on [ncnn](https://github.com/Tencent/ncnn) 4 | 5 | 6 | ## Tutorial 7 | 8 | ### Step1 9 | 10 | Download ncnn-android-vulkan.zip from [releases of ncnn](https://github.com/Tencent/ncnn/releases). This repo uses 11 | [20210525 release](https://github.com/Tencent/ncnn/releases/download/20210525/ncnn-20210525-android-vulkan.zip) for building. 12 | 13 | ### Step2 14 | 15 | After downloading, please extract your zip file. Then, there are two ways to finish this step: 16 | * put your extracted directory into **app/src/main/jni** 17 | * change the **ncnn_DIR** path in **app/src/main/jni/CMakeLists.txt** to your extracted directory 18 | 19 | ### Step3 20 | Download example param and bin file from [onedrive](https://megvii-my.sharepoint.cn/:u:/g/personal/gezheng_megvii_com/ESXBH_GSSmFMszWJ6YG2VkQB5cWDfqVWXgk0D996jH0rpQ?e=qzEqUh) or [github](https://github.com/Megvii-BaseDetection/storage/releases/download/0.0.1/yolox_s_ncnn.tar.gz). Unzip the file to **app/src/main/assets**. 21 | 22 | ### Step4 23 | Open this project with Android Studio, build it and enjoy! 24 | 25 | ## Reference 26 | 27 | * [ncnn-android-yolov5](https://github.com/nihui/ncnn-android-yolov5) 28 | -------------------------------------------------------------------------------- /demo/ncnn/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 24 5 | buildToolsVersion "29.0.2" 6 | 7 | defaultConfig { 8 | applicationId "com.megvii.yoloXncnn" 9 | archivesBaseName = "$applicationId" 10 | 11 | ndk { 12 | moduleName "ncnn" 13 | abiFilters "armeabi-v7a", "arm64-v8a" 14 | } 15 | minSdkVersion 24 16 | } 17 | 18 | externalNativeBuild { 19 | cmake { 20 | version "3.10.2" 21 | path file('src/main/jni/CMakeLists.txt') 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /demo/ncnn/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /demo/ncnn/android/app/src/main/java/com/megvii/yoloXncnn/YOLOXncnn.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) Megvii, Inc. and its affiliates. All rights reserved. 2 | 3 | package com.megvii.yoloXncnn; 4 | 5 | import android.content.res.AssetManager; 6 | import android.graphics.Bitmap; 7 | 8 | public class YOLOXncnn 9 | { 10 | public native boolean Init(AssetManager mgr); 11 | 12 | public class Obj 13 | { 14 | public float x; 15 | public float y; 16 | public float w; 17 | public float h; 18 | public String label; 19 | public float prob; 20 | } 21 | 22 | public native Obj[] Detect(Bitmap bitmap, boolean use_gpu); 23 | 24 | static { 25 | System.loadLibrary("yoloXncnn"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /demo/ncnn/android/app/src/main/java/com/megvii/yoloXncnn/yoloXncnn.java: -------------------------------------------------------------------------------- 1 | // Copyright (C) Megvii, Inc. and its affiliates. All rights reserved. 2 | 3 | package com.megvii.yoloXncnn; 4 | 5 | import android.content.res.AssetManager; 6 | import android.graphics.Bitmap; 7 | 8 | public class YOLOXncnn 9 | { 10 | public native boolean Init(AssetManager mgr); 11 | 12 | public class Obj 13 | { 14 | public float x; 15 | public float y; 16 | public float w; 17 | public float h; 18 | public String label; 19 | public float prob; 20 | } 21 | 22 | public native Obj[] Detect(Bitmap bitmap, boolean use_gpu); 23 | 24 | static { 25 | System.loadLibrary("yoloXncnn"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /demo/ncnn/android/app/src/main/jni/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(yoloXncnn) 2 | 3 | cmake_minimum_required(VERSION 3.4.1) 4 | 5 | set(ncnn_DIR ${CMAKE_SOURCE_DIR}/ncnn-20210525-android-vulkan/${ANDROID_ABI}/lib/cmake/ncnn) 6 | find_package(ncnn REQUIRED) 7 | 8 | add_library(yoloXncnn SHARED yoloXncnn_jni.cpp) 9 | 10 | target_link_libraries(yoloXncnn 11 | ncnn 12 | 13 | jnigraphics 14 | ) 15 | -------------------------------------------------------------------------------- /demo/ncnn/android/app/src/main/res/layout/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 |