├── .gitattributes ├── .github ├── FUNDING.yml └── workflows │ ├── ci.yml │ ├── package_testing.yml │ └── publish_pypi.yml ├── .gitignore ├── LICENSE ├── MANIFEST.in ├── README.md ├── requirements.txt ├── setup.py ├── tests ├── __init__.py ├── data │ ├── bus.jpg │ ├── coco_data.yaml │ └── zidane.jpg ├── download_test_coco_dataset.py ├── test_utils.py └── test_yolov5.py └── yolov5 ├── __init__.py ├── benchmarks.py ├── classify ├── __init__.py ├── predict.py ├── train.py └── val.py ├── cli.py ├── data ├── Argoverse.yaml ├── GlobalWheat2020.yaml ├── ImageNet.yaml ├── Objects365.yaml ├── SKU-110K.yaml ├── VOC.yaml ├── VisDrone.yaml ├── coco.yaml ├── coco128-seg.yaml ├── coco128.yaml ├── hyps │ ├── hyp.Objects365.yaml │ ├── hyp.VOC.yaml │ ├── hyp.no-augmentation.yaml │ ├── hyp.scratch-high.yaml │ ├── hyp.scratch-low.yaml │ └── hyp.scratch-med.yaml ├── images │ ├── bus.jpg │ └── zidane.jpg ├── scripts │ ├── download_weights.sh │ ├── get_coco.sh │ ├── get_coco128.sh │ └── get_imagenet.sh └── xView.yaml ├── detect.py ├── export.py ├── helpers.py ├── hubconf.py ├── models ├── __init__.py ├── common.py ├── experimental.py ├── hub │ ├── anchors.yaml │ ├── yolov3-spp.yaml │ ├── yolov3-tiny.yaml │ ├── yolov3.yaml │ ├── yolov5-bifpn.yaml │ ├── yolov5-fpn.yaml │ ├── yolov5-p2.yaml │ ├── yolov5-p34.yaml │ ├── yolov5-p6.yaml │ ├── yolov5-p7.yaml │ ├── yolov5-panet.yaml │ ├── yolov5l6.yaml │ ├── yolov5m6.yaml │ ├── yolov5n6.yaml │ ├── yolov5s-LeakyReLU.yaml │ ├── yolov5s-ghost.yaml │ ├── yolov5s-transformer.yaml │ ├── yolov5s6.yaml │ └── yolov5x6.yaml ├── segment │ ├── yolov5l-seg.yaml │ ├── yolov5m-seg.yaml │ ├── yolov5n-seg.yaml │ ├── yolov5s-seg.yaml │ └── yolov5x-seg.yaml ├── tf.py ├── yolo.py ├── yolov5l.yaml ├── yolov5m.yaml ├── yolov5n.yaml ├── yolov5s.yaml └── yolov5x.yaml ├── segment ├── __init__.py ├── predict.py ├── train.py └── val.py ├── train.py ├── utils ├── __init__.py ├── activations.py ├── augmentations.py ├── autoanchor.py ├── autobatch.py ├── aws.py ├── callbacks.py ├── dataloaders.py ├── downloads.py ├── general.py ├── loggers │ ├── __init__.py │ ├── clearml │ │ ├── README.md │ │ ├── __init__.py │ │ ├── clearml_utils.py │ │ └── hpo.py │ ├── comet │ │ ├── README.md │ │ ├── __init__.py │ │ ├── comet_utils.py │ │ └── hpo.py │ ├── neptune │ │ ├── __init__.py │ │ └── neptune_utils.py │ └── wandb │ │ ├── __init__.py │ │ ├── log_dataset.py │ │ ├── sweep.py │ │ ├── sweep.yaml │ │ └── wandb_utils.py ├── loss.py ├── metrics.py ├── plots.py ├── roboflow.py ├── segment │ ├── __init__.py │ ├── augmentations.py │ ├── dataloaders.py │ ├── general.py │ ├── loss.py │ ├── metrics.py │ └── plots.py ├── torch_utils.py └── triton.py └── val.py /.gitattributes: -------------------------------------------------------------------------------- 1 | # this drop notebooks from GitHub language stats 2 | *.ipynb linguist-vendored 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: fcakyon 2 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci testing 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | branches: [main] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | strategy: 14 | matrix: 15 | operating-system: [ubuntu-latest, windows-latest, macos-latest] 16 | python-version: [3.8, 3.9, "3.10", "3.11"] 17 | fail-fast: false 18 | 19 | steps: 20 | - name: Checkout 21 | uses: actions/checkout@v3 22 | 23 | - name: Set up Python 24 | uses: actions/setup-python@v4 25 | with: 26 | python-version: ${{ matrix.python-version }} 27 | 28 | - name: Update pip 29 | run: python -m pip install --upgrade pip 30 | 31 | - name: Get pip cache dir 32 | id: pip-cache 33 | run: | 34 | echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT 35 | 36 | - name: Restore pip cache 37 | uses: actions/cache@v3 38 | with: 39 | path: ${{ steps.pip-cache.outputs.dir }} 40 | key: ${{ matrix.os }}-${{ matrix.python-version }}-${{ hashFiles('**/setup.py') }} 41 | restore-keys: ${{ matrix.os }}-${{ matrix.python-version }}- 42 | 43 | - name: Install dependencies 44 | run: > 45 | pip install -r requirements.txt 46 | 47 | - name: Test with unittest 48 | run: | 49 | python -m unittest 50 | 51 | - name: Test yolov5 train 52 | shell: bash # for Windows compatibility 53 | run: | 54 | pip install -e . 55 | # donwload coco formatted testing data 56 | python tests/download_test_coco_dataset.py 57 | # train (dl base model from hf hub) 58 | yolov5 train --data tests/data/coco_data.yaml --img 128 --batch 16 --weights fcakyon/yolov5n-v7.0 --epochs 1 --device cpu --freeze 10 59 | python yolov5/train.py --img 128 --batch 16 --weights fcakyon/yolov5n-v7.0 --epochs 1 --device cpu 60 | yolov5 train --img 128 --batch 16 --weights fcakyon/yolov5n-v7.0 --epochs 1 --device cpu --freeze 10 61 | yolov5 train --img 128 --batch 16 --weights fcakyon/yolov5n-v7.0 --epochs 1 --device cpu --evolve 2 62 | # train 63 | yolov5 train --data tests/data/coco_data.yaml --img 128 --batch 16 --weights yolov5/weights/yolov5n.pt --epochs 1 --device cpu --freeze 10 64 | python yolov5/train.py --img 128 --batch 16 --weights yolov5/weights/yolov5n.pt --epochs 1 --device cpu 65 | yolov5 train --img 128 --batch 16 --weights yolov5/weights/yolov5n.pt --epochs 1 --device cpu --freeze 10 66 | yolov5 train --img 128 --batch 16 --weights yolov5/weights/yolov5n.pt --epochs 1 --device cpu --evolve 2 67 | 68 | - name: Test yolov5 detect 69 | shell: bash # for Windows compatibility 70 | run: | 71 | python yolov5/detect.py --weights yolov5/weights/yolov5n.pt --device cpu 72 | yolov5 detect --weights yolov5/weights/yolov5n.pt --device cpu 73 | python yolov5/detect.py --weights runs/train/exp/weights/last.pt --device cpu 74 | yolov5 detect --weights runs/train/exp/weights/last.pt --device cpu 75 | 76 | - name: Test yolov5 val 77 | shell: bash # for Windows compatibility 78 | run: | 79 | python yolov5/val.py --img 128 --batch 16 --weights yolov5/weights/yolov5n.pt --device cpu 80 | yolov5 val --data yolov5/data/coco128.yaml --img 128 --batch 16 --weights yolov5/weights/yolov5n.pt --device cpu 81 | python yolov5/val.py --img 128 --batch 16 --weights runs/train/exp/weights/last.pt --device cpu 82 | yolov5 val --data yolov5/data/coco128.yaml --img 128 --batch 16 --weights runs/train/exp/weights/last.pt --device cpu 83 | 84 | - name: Test yolov5 export 85 | shell: bash # for Windows compatibility 86 | run: | 87 | pip install onnx onnx-simplifier tensorflowjs 88 | python yolov5/export.py --weights yolov5/weights/yolov5n.pt --device cpu --include torchscript,onnx,tflite 89 | yolov5 export --weights yolov5/weights/yolov5n.pt --device cpu --simplify --include torchscript,onnx,saved_model,pb,tfjs 90 | 91 | - name: Test yolov5 benchmarks 92 | shell: bash # for Windows compatibility 93 | run: | 94 | yolov5 benchmarks --weights yolov5n.pt --img 128 --pt-only --device cpu 95 | 96 | - name: Test yolov5 classify 97 | shell: bash # for Windows compatibility 98 | run: | 99 | yolov5 classify train --img 128 --data mnist2560 --model yolov5n-cls.pt --epochs 1 --device cpu 100 | yolov5 classify train --img 128 --data mnist2560 --model fcakyon/yolov5n-cls-v7.0 --epochs 1 --device cpu 101 | yolov5 classify val --img 128 --data datasets/mnist2560 --weights yolov5n-cls.pt --device cpu 102 | yolov5 classify predict --img 128 --weights yolov5n-cls.pt --device cpu 103 | 104 | - name: Test yolov5 segment 105 | shell: bash # for Windows compatibility 106 | run: | 107 | yolov5 segment train --img 128 --weights yolov5n-seg.pt --epochs 1 --device cpu 108 | yolov5 segment train --img 128 --weights fcakyon/yolov5n-seg-v7.0 --epochs 1 --device cpu 109 | # yolov5 segment val --img 128 --weights yolov5n-seg.pt --device cpu 110 | yolov5 segment predict --img 128 --weights yolov5n-seg.pt --device cpu 111 | 112 | - name: Test roboflow train 113 | shell: bash # for Windows compatibility 114 | run: | 115 | yolov5 train --data https://universe.roboflow.com/gdit/aerial-airport/dataset/1 --weights yolov5/weights/yolov5n.pt --img 128 --epochs 1 --device cpu --roboflow_token ${{ secrets.ROBOFLOW_API_KEY }} 116 | # yolov5 classify train --data https://universe.roboflow.com/carlos-gabriel-da-silva-machado-siwvs/turtles-i1tlr/dataset/1 --img 128 --model yolov5n-cls.pt --epochs 1 --device cpu --roboflow_token ${{ secrets.ROBOFLOW_API_KEY }} 117 | yolov5 segment train --data https://universe.roboflow.com/aymane-outani-auooc/cable-fzjik/dataset/2 --img 128 --weights yolov5n-seg.pt --epochs 1 --device cpu --roboflow_token ${{ secrets.ROBOFLOW_API_KEY }} 118 | 119 | -------------------------------------------------------------------------------- /.github/workflows/package_testing.yml: -------------------------------------------------------------------------------- 1 | name: package testing 2 | 3 | on: 4 | schedule: 5 | - cron: '0 0 * * *' # Runs at 00:00 UTC every day 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | 11 | strategy: 12 | matrix: 13 | operating-system: [ubuntu-latest, windows-latest, macos-latest] 14 | python-version: [3.8, 3.9, "3.10", "3.11"] 15 | fail-fast: false 16 | 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v3 20 | 21 | - name: Set up Python 22 | uses: actions/setup-python@v4 23 | with: 24 | python-version: ${{ matrix.python-version }} 25 | 26 | - name: Update pip 27 | run: python -m pip install --upgrade pip 28 | 29 | - name: Get pip cache dir 30 | id: pip-cache 31 | run: | 32 | echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT 33 | 34 | - name: Restore pip cache 35 | uses: actions/cache@v3 36 | with: 37 | path: ${{ steps.pip-cache.outputs.dir }} 38 | key: ${{ matrix.os }}-${{ matrix.python-version }}-${{ hashFiles('**/setup.py') }} 39 | restore-keys: ${{ matrix.os }}-${{ matrix.python-version }}- 40 | 41 | - name: Install latest YOLOv5 package 42 | run: > 43 | pip install --upgrade --force-reinstall yolov5 44 | 45 | - name: Test with unittest 46 | run: | 47 | python -m unittest 48 | 49 | - name: Test yolov5 train 50 | shell: bash # for Windows compatibility 51 | run: | 52 | # donwload coco formatted testing data 53 | python tests/download_test_coco_dataset.py 54 | # train (dl base model from hf hub) 55 | yolov5 train --data tests/data/coco_data.yaml --img 128 --batch 16 --weights fcakyon/yolov5n-v7.0 --epochs 1 --device cpu --freeze 10 56 | python yolov5/train.py --img 128 --batch 16 --weights fcakyon/yolov5n-v7.0 --epochs 1 --device cpu 57 | yolov5 train --img 128 --batch 16 --weights fcakyon/yolov5n-v7.0 --epochs 1 --device cpu --freeze 10 58 | yolov5 train --img 128 --batch 16 --weights fcakyon/yolov5n-v7.0 --epochs 1 --device cpu --evolve 2 59 | # train 60 | yolov5 train --data tests/data/coco_data.yaml --img 128 --batch 16 --weights yolov5/weights/yolov5n.pt --epochs 1 --device cpu --freeze 10 61 | python yolov5/train.py --img 128 --batch 16 --weights yolov5/weights/yolov5n.pt --epochs 1 --device cpu 62 | yolov5 train --img 128 --batch 16 --weights yolov5/weights/yolov5n.pt --epochs 1 --device cpu --freeze 10 63 | yolov5 train --img 128 --batch 16 --weights yolov5/weights/yolov5n.pt --epochs 1 --device cpu --evolve 2 64 | - name: Test yolov5 detect 65 | shell: bash # for Windows compatibility 66 | run: | 67 | python yolov5/detect.py --weights yolov5/weights/yolov5n.pt --device cpu 68 | yolov5 detect --weights yolov5/weights/yolov5n.pt --device cpu 69 | python yolov5/detect.py --weights runs/train/exp/weights/last.pt --device cpu 70 | yolov5 detect --weights runs/train/exp/weights/last.pt --device cpu 71 | - name: Test yolov5 val 72 | shell: bash # for Windows compatibility 73 | run: | 74 | python yolov5/val.py --img 128 --batch 16 --weights yolov5/weights/yolov5n.pt --device cpu 75 | yolov5 val --data yolov5/data/coco128.yaml --img 128 --batch 16 --weights yolov5/weights/yolov5n.pt --device cpu 76 | python yolov5/val.py --img 128 --batch 16 --weights runs/train/exp/weights/last.pt --device cpu 77 | yolov5 val --data yolov5/data/coco128.yaml --img 128 --batch 16 --weights runs/train/exp/weights/last.pt --device cpu 78 | - name: Test yolov5 export 79 | shell: bash # for Windows compatibility 80 | run: | 81 | pip install onnx onnx-simplifier tensorflowjs 82 | python yolov5/export.py --weights yolov5/weights/yolov5n.pt --device cpu --include torchscript,onnx,tflite 83 | yolov5 export --weights yolov5/weights/yolov5n.pt --device cpu --simplify --include torchscript,onnx,saved_model,pb,tfjs 84 | - name: Test yolov5 benchmarks 85 | shell: bash # for Windows compatibility 86 | run: | 87 | yolov5 benchmarks --weights yolov5n.pt --img 128 --pt-only --device cpu 88 | - name: Test yolov5 classify 89 | shell: bash # for Windows compatibility 90 | run: | 91 | yolov5 classify train --img 128 --data mnist2560 --model yolov5n-cls.pt --epochs 1 --device cpu 92 | yolov5 classify train --img 128 --data mnist2560 --model fcakyon/yolov5n-cls-v7.0 --epochs 1 --device cpu 93 | yolov5 classify val --img 128 --data datasets/mnist2560 --weights yolov5n-cls.pt --device cpu 94 | yolov5 classify predict --img 128 --weights yolov5n-cls.pt --device cpu 95 | - name: Test yolov5 segment 96 | shell: bash # for Windows compatibility 97 | run: | 98 | yolov5 segment train --img 128 --weights yolov5n-seg.pt --epochs 1 --device cpu 99 | yolov5 segment train --img 128 --weights fcakyon/yolov5n-seg-v7.0 --epochs 1 --device cpu 100 | # yolov5 segment val --img 128 --weights yolov5n-seg.pt --device cpu 101 | yolov5 segment predict --img 128 --weights yolov5n-seg.pt --device cpu 102 | 103 | - name: Test roboflow train 104 | shell: bash # for Windows compatibility 105 | run: | 106 | yolov5 train --data https://universe.roboflow.com/gdit/aerial-airport/dataset/1 --weights yolov5/weights/yolov5n.pt --img 128 --epochs 1 --device cpu --roboflow_token ${{ secrets.ROBOFLOW_API_KEY }} 107 | # yolov5 classify train --data https://universe.roboflow.com/carlos-gabriel-da-silva-machado-siwvs/turtles-i1tlr/dataset/1 --img 128 --model yolov5n-cls.pt --epochs 1 --device cpu --roboflow_token ${{ secrets.ROBOFLOW_API_KEY }} 108 | yolov5 segment train --data https://universe.roboflow.com/aymane-outani-auooc/cable-fzjik/dataset/2 --img 128 --weights yolov5n-seg.pt --epochs 1 --device cpu --roboflow_token ${{ secrets.ROBOFLOW_API_KEY }} 109 | -------------------------------------------------------------------------------- /.github/workflows/publish_pypi.yml: -------------------------------------------------------------------------------- 1 | name: Publish Python Package 2 | 3 | on: 4 | release: 5 | types: [published, edited] 6 | 7 | jobs: 8 | publish: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v3 13 | - name: Set up Python 14 | uses: actions/setup-python@v4 15 | with: 16 | python-version: '3.x' 17 | - name: Install dependencies 18 | run: | 19 | python -m pip install --upgrade pip 20 | pip install setuptools wheel twine 21 | - name: Build and publish 22 | env: 23 | TWINE_USERNAME: __token__ 24 | TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} 25 | run: | 26 | python setup.py sdist bdist_wheel 27 | twine upload --verbose --skip-existing dist/* 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # vscode 2 | .vscode 3 | 4 | # Repo-specific GitIgnore ---------------------------------------------------------------------------------------------- 5 | *.jpg 6 | *.jpeg 7 | *.png 8 | *.bmp 9 | *.tif 10 | *.tiff 11 | *.heic 12 | *.JPG 13 | *.JPEG 14 | *.PNG 15 | *.BMP 16 | *.TIF 17 | *.TIFF 18 | *.HEIC 19 | *.mp4 20 | *.mov 21 | *.MOV 22 | *.avi 23 | *.data 24 | *.json 25 | 26 | *.cfg 27 | !cfg/yolov3*.cfg 28 | 29 | storage.googleapis.com 30 | runs/* 31 | data/* 32 | !tests/data/* 33 | !yolov5/data/images/zidane.jpg 34 | !yolov5/data/images/bus.jpg 35 | !data/coco.names 36 | !data/coco_paper.names 37 | !data/coco.data 38 | !data/coco_*.data 39 | !data/coco_*.txt 40 | !data/trainvalno5k.shapes 41 | !data/*.sh 42 | 43 | pycocotools/* 44 | results*.txt 45 | gcp_test*.sh 46 | .neptune 47 | *.bin 48 | *.pb 49 | *saved_model 50 | *.zip 51 | datasets/ 52 | 53 | # Datasets ------------------------------------------------------------------------------------------------------------- 54 | coco/ 55 | coco128/ 56 | VOC/ 57 | 58 | # MATLAB GitIgnore ----------------------------------------------------------------------------------------------------- 59 | *.m~ 60 | *.mat 61 | !targets*.mat 62 | 63 | # Neural Network weights ----------------------------------------------------------------------------------------------- 64 | *.weights 65 | *.pt 66 | *.onnx 67 | *.mlmodel 68 | *.torchscript 69 | darknet53.conv.74 70 | yolov3-tiny.conv.15 71 | 72 | # GitHub Python GitIgnore ---------------------------------------------------------------------------------------------- 73 | # Byte-compiled / optimized / DLL files 74 | __pycache__/ 75 | *.py[cod] 76 | *$py.class 77 | 78 | # C extensions 79 | *.so 80 | 81 | # Distribution / packaging 82 | .Python 83 | env/ 84 | build/ 85 | develop-eggs/ 86 | dist/ 87 | downloads/ 88 | eggs/ 89 | .eggs/ 90 | lib/ 91 | lib64/ 92 | parts/ 93 | sdist/ 94 | var/ 95 | wheels/ 96 | *.egg-info/ 97 | wandb/ 98 | !yolov5/utils/loggers/wandb 99 | .installed.cfg 100 | *.egg 101 | 102 | 103 | # PyInstaller 104 | # Usually these files are written by a python script from a template 105 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 106 | *.manifest 107 | *.spec 108 | 109 | # Installer logs 110 | pip-log.txt 111 | pip-delete-this-directory.txt 112 | 113 | # Unit test / coverage reports 114 | htmlcov/ 115 | .tox/ 116 | .coverage 117 | .coverage.* 118 | .cache 119 | nosetests.xml 120 | coverage.xml 121 | *.cover 122 | .hypothesis/ 123 | 124 | # Translations 125 | *.mo 126 | *.pot 127 | 128 | # Django stuff: 129 | *.log 130 | local_settings.py 131 | 132 | # Flask stuff: 133 | instance/ 134 | .webassets-cache 135 | 136 | # Scrapy stuff: 137 | .scrapy 138 | 139 | # Sphinx documentation 140 | docs/_build/ 141 | 142 | # PyBuilder 143 | target/ 144 | 145 | # Jupyter Notebook 146 | .ipynb_checkpoints 147 | 148 | # pyenv 149 | .python-version 150 | 151 | # celery beat schedule file 152 | celerybeat-schedule 153 | 154 | # SageMath parsed files 155 | *.sage.py 156 | 157 | # dotenv 158 | .env 159 | 160 | # virtualenv 161 | .venv* 162 | venv*/ 163 | ENV*/ 164 | 165 | # Spyder project settings 166 | .spyderproject 167 | .spyproject 168 | 169 | # Rope project settings 170 | .ropeproject 171 | 172 | # mkdocs documentation 173 | /site 174 | 175 | # mypy 176 | .mypy_cache/ 177 | 178 | 179 | # https://github.com/github/gitignore/blob/master/Global/macOS.gitignore ----------------------------------------------- 180 | 181 | # General 182 | .DS_Store 183 | .AppleDouble 184 | .LSOverride 185 | 186 | # Icon must end with two \r 187 | Icon 188 | Icon? 189 | 190 | # Thumbnails 191 | ._* 192 | 193 | # Files that might appear in the root of a volume 194 | .DocumentRevisions-V100 195 | .fseventsd 196 | .Spotlight-V100 197 | .TemporaryItems 198 | .Trashes 199 | .VolumeIcon.icns 200 | .com.apple.timemachine.donotpresent 201 | 202 | # Directories potentially created on remote AFP share 203 | .AppleDB 204 | .AppleDesktop 205 | Network Trash Folder 206 | Temporary Items 207 | .apdisk 208 | 209 | 210 | # https://github.com/github/gitignore/blob/master/Global/JetBrains.gitignore 211 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 212 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 213 | 214 | # User-specific stuff: 215 | .idea/* 216 | .idea/**/workspace.xml 217 | .idea/**/tasks.xml 218 | .idea/dictionaries 219 | .html # Bokeh Plots 220 | .pg # TensorFlow Frozen Graphs 221 | .avi # videos 222 | 223 | # Sensitive or high-churn files: 224 | .idea/**/dataSources/ 225 | .idea/**/dataSources.ids 226 | .idea/**/dataSources.local.xml 227 | .idea/**/sqlDataSources.xml 228 | .idea/**/dynamic.xml 229 | .idea/**/uiDesigner.xml 230 | 231 | # Gradle: 232 | .idea/**/gradle.xml 233 | .idea/**/libraries 234 | 235 | # CMake 236 | cmake-build-debug/ 237 | cmake-build-release/ 238 | 239 | # Mongo Explorer plugin: 240 | .idea/**/mongoSettings.xml 241 | 242 | ## File-based project format: 243 | *.iws 244 | 245 | ## Plugin-specific files: 246 | 247 | # IntelliJ 248 | out/ 249 | 250 | # mpeltonen/sbt-idea plugin 251 | .idea_modules/ 252 | 253 | # JIRA plugin 254 | atlassian-ide-plugin.xml 255 | 256 | # Cursive Clojure plugin 257 | .idea/replstate.xml 258 | 259 | # Crashlytics plugin (for Android Studio and IntelliJ) 260 | com_crashlytics_export_strings.xml 261 | crashlytics.properties 262 | crashlytics-build.properties 263 | fabric.properties 264 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | # Include the README 2 | include *.md 3 | 4 | # Include the license file 5 | include LICENSE 6 | 7 | # Include setup.py 8 | include setup.py 9 | 10 | # Include the data files 11 | recursive-include yolov5/data * 12 | 13 | # Include the yml files in models folder 14 | recursive-include yolov5/models * 15 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # YOLOv5 requirements 2 | # Usage: pip install -r requirements.txt 3 | 4 | # Base ------------------------------------------------------------------------ 5 | gitpython>=3.1.30 6 | matplotlib>=3.3 7 | numpy>=1.18.5 8 | opencv-python>=4.1.1 9 | Pillow>=7.1.2 10 | psutil # system resources 11 | PyYAML>=5.3.1 12 | requests>=2.23.0 13 | scipy>=1.4.1 14 | thop>=0.1.1 # FLOPs computation 15 | torch>=1.7.0 # see https://pytorch.org/get-started/locally (recommended) 16 | torchvision>=0.8.1 17 | tqdm>=4.64.0 18 | ultralytics>=8.0.100 19 | # protobuf<=3.20.1 # https://github.com/ultralytics/yolov5/issues/8012 20 | 21 | # Logging --------------------------------------------------------------------- 22 | tensorboard>=2.4.1 23 | # clearml>=1.2.0 24 | # comet 25 | 26 | # Plotting -------------------------------------------------------------------- 27 | pandas>=1.1.4 28 | seaborn>=0.11.0 29 | 30 | # Export ---------------------------------------------------------------------- 31 | # coremltools>=6.0 # CoreML export 32 | # onnx>=1.10.0 # ONNX export 33 | # onnx-simplifier>=0.4.1 # ONNX simplifier 34 | # nvidia-pyindex # TensorRT export 35 | # nvidia-tensorrt # TensorRT export 36 | # scikit-learn<=1.1.2 # CoreML quantization 37 | # tensorflow>=2.4.0 # TF exports (-cpu, -aarch64, -macos) 38 | # tensorflowjs>=3.9.0 # TF.js export 39 | # openvino-dev # OpenVINO export 40 | 41 | # Deploy ---------------------------------------------------------------------- 42 | setuptools>=65.5.1 # Snyk vulnerability fix 43 | # tritonclient[all]~=2.24.0 44 | 45 | # Extras ---------------------------------------------------------------------- 46 | # ipython # interactive notebook 47 | # mss # screenshots 48 | # albumentations>=1.0.3 49 | # pycocotools>=2.0.6 # COCO mAP 50 | 51 | 52 | # CLI 53 | fire 54 | # AWS 55 | boto3>=1.19.1 56 | # coco to yolov5 conversion 57 | sahi>=0.11.10 58 | # huggingface 59 | huggingface-hub>=0.12.0,<0.25.0 60 | # roboflow 61 | roboflow>=0.2.29 62 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import io 2 | import os 3 | import re 4 | 5 | import setuptools 6 | 7 | 8 | def get_long_description(): 9 | base_dir = os.path.abspath(os.path.dirname(__file__)) 10 | with io.open(os.path.join(base_dir, "README.md"), encoding="utf-8") as f: 11 | return f.read() 12 | 13 | 14 | def get_requirements(): 15 | with open("requirements.txt") as f: 16 | return f.read().splitlines() 17 | 18 | 19 | def get_version(): 20 | current_dir = os.path.abspath(os.path.dirname(__file__)) 21 | version_file = os.path.join(current_dir, "yolov5", "__init__.py") 22 | with io.open(version_file, encoding="utf-8") as f: 23 | return re.search(r'^__version__ = [\'"]([^\'"]*)[\'"]', f.read(), re.M).group(1) 24 | 25 | 26 | setuptools.setup( 27 | name="yolov5", 28 | version=get_version(), 29 | author="", 30 | license="GPL", 31 | description="Packaged version of the Yolov5 object detector", 32 | long_description=get_long_description(), 33 | long_description_content_type="text/markdown", 34 | url="https://github.com/fcakyon/yolov5-pip", 35 | packages=setuptools.find_packages(exclude=["tests"]), 36 | python_requires=">=3.7", 37 | install_requires=get_requirements(), 38 | include_package_data=True, 39 | options={'bdist_wheel':{'python_tag':'py37.py38.py39.py310'}}, 40 | classifiers=[ 41 | "Development Status :: 5 - Production/Stable", 42 | "License :: OSI Approved :: GNU General Public License (GPL)", 43 | "Operating System :: OS Independent", 44 | "Intended Audience :: Developers", 45 | "Intended Audience :: Science/Research", 46 | "Programming Language :: Python :: 3", 47 | "Programming Language :: Python :: 3.7", 48 | "Programming Language :: Python :: 3.8", 49 | "Programming Language :: Python :: 3.9", 50 | "Programming Language :: Python :: 3.10", 51 | "Topic :: Software Development :: Libraries", 52 | "Topic :: Software Development :: Libraries :: Python Modules", 53 | "Topic :: Education", 54 | "Topic :: Scientific/Engineering", 55 | "Topic :: Scientific/Engineering :: Artificial Intelligence", 56 | "Topic :: Scientific/Engineering :: Image Recognition", 57 | ], 58 | keywords="machine-learning, deep-learning, ml, pytorch, YOLO, object-detection, vision, YOLOv5, YOLOv7", 59 | entry_points={'console_scripts': [ 60 | "yolov5=yolov5.cli:app", 61 | ], 62 | } 63 | ) 64 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fcakyon/yolov5-pip/40a188792bca82b8285549edb2c318b9d73bcd47/tests/__init__.py -------------------------------------------------------------------------------- /tests/data/bus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fcakyon/yolov5-pip/40a188792bca82b8285549edb2c318b9d73bcd47/tests/data/bus.jpg -------------------------------------------------------------------------------- /tests/data/coco_data.yaml: -------------------------------------------------------------------------------- 1 | train_json_path: "tests/data/dataset.json" 2 | train_image_dir: "tests/data/images/" 3 | val_json_path: "tests/data/dataset.json" 4 | val_image_dir: "tests/data/images/" -------------------------------------------------------------------------------- /tests/data/zidane.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fcakyon/yolov5-pip/40a188792bca82b8285549edb2c318b9d73bcd47/tests/data/zidane.jpg -------------------------------------------------------------------------------- /tests/download_test_coco_dataset.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | 4 | import urllib.request 5 | 6 | TEST_COCO_DATASET_URL = "https://github.com/fcakyon/yolov5-pip/releases/download/0.6/test-coco-dataset.zip" 7 | TEST_COCO_DATASET_ZIP_PATH = "tests/data/test-coco-dataset.zip" 8 | 9 | 10 | def download_from_url(from_url: str, to_path: str): 11 | 12 | Path(to_path).parent.mkdir(parents=True, exist_ok=True) 13 | 14 | if not os.path.exists(to_path): 15 | urllib.request.urlretrieve( 16 | from_url, 17 | to_path, 18 | ) 19 | 20 | def download_test_coco_dataset_and_unzip(): 21 | if not os.path.exists(TEST_COCO_DATASET_ZIP_PATH): 22 | print("Downloading test coco dataset...") 23 | download_from_url(TEST_COCO_DATASET_URL, TEST_COCO_DATASET_ZIP_PATH) 24 | print("Download complete.") 25 | 26 | if not os.path.exists("tests/data/dataset.json"): 27 | print("Unzipping test coco dataset...") 28 | import zipfile 29 | with zipfile.ZipFile(TEST_COCO_DATASET_ZIP_PATH, "r") as zip_ref: 30 | zip_ref.extractall("tests/data") 31 | print("Unzip complete.") 32 | 33 | if __name__ == "__main__": 34 | download_test_coco_dataset_and_unzip() -------------------------------------------------------------------------------- /tests/test_utils.py: -------------------------------------------------------------------------------- 1 | class TestConstants: 2 | YOLOV5N_HUB_ID = "fcakyon/yolov5n-v7.0" 3 | YOLOV5S_HUB_ID = "fcakyon/yolov5s-v7.0" 4 | YOLOV5N_MODEL_PATH = "yolov5/weights/yolov5n.pt" 5 | YOLOV5S_MODEL_PATH = "yolov5/weights/yolov5s.pt" 6 | YOLOV5L_MODEL_PATH = "yolov5/weights/yolov5l.pt" 7 | ZIDANE_IMAGE_PATH = "tests/data/zidane.jpg" 8 | BUS_IMAGE_PATH = "tests/data/bus.jpg" 9 | -------------------------------------------------------------------------------- /tests/test_yolov5.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from tests.test_utils import TestConstants 4 | 5 | DEVICE = "cpu" 6 | 7 | class TestYolov5FromUltralytics(unittest.TestCase): 8 | def test_load_model(self): 9 | import yolov5 10 | 11 | # init model 12 | model_path = TestConstants.YOLOV5S_MODEL_PATH 13 | model = yolov5.load(model_path, device=DEVICE) 14 | 15 | # check if loaded 16 | self.assertNotEqual(model, None) 17 | 18 | def test_predict(self): 19 | from PIL import Image 20 | 21 | import yolov5 22 | 23 | # init yolov5s model 24 | model_path = TestConstants.YOLOV5S_MODEL_PATH 25 | model = yolov5.load(model_path, device=DEVICE) 26 | 27 | # prepare image 28 | image_path = TestConstants.ZIDANE_IMAGE_PATH 29 | image = Image.open(image_path) 30 | 31 | # perform inference 32 | results = model(image, size=640, augment=False) 33 | 34 | # compare 35 | self.assertEqual(results.n, 1) 36 | self.assertEqual(len(results.names), 80) 37 | self.assertEqual(len(results.pred[0]), 4) 38 | 39 | # init yolov5l model 40 | model_path = TestConstants.YOLOV5L_MODEL_PATH 41 | model = yolov5.load(model_path, device=DEVICE) 42 | 43 | # prepare image 44 | image_path = TestConstants.BUS_IMAGE_PATH 45 | image = Image.open(image_path) 46 | # perform inference 47 | results = model(image, size=1280, augment=False) 48 | 49 | # compare 50 | self.assertEqual(results.n, 1) 51 | self.assertEqual(len(results.names), 80) 52 | self.assertEqual(len(results.pred[0]), 6) 53 | 54 | # init yolov5s model 55 | model_path = TestConstants.YOLOV5S_MODEL_PATH 56 | model = yolov5.load(model_path, device=DEVICE) 57 | 58 | # prepare images 59 | image_path1 = TestConstants.ZIDANE_IMAGE_PATH 60 | image_path2 = TestConstants.BUS_IMAGE_PATH 61 | image1 = Image.open(image_path1) 62 | image2 = Image.open(image_path2) 63 | 64 | # perform inference with multiple images and test augmentation 65 | results = model([image1, image2], size=1280, augment=True) 66 | 67 | # compare 68 | self.assertEqual(results.n, 2) 69 | self.assertEqual(len(results.names), 80) 70 | self.assertEqual(len(results.pred[0]), 4) 71 | self.assertEqual(len(results.pred[1]), 5) 72 | 73 | 74 | class TestYolov5FromHuggingface(unittest.TestCase): 75 | def test_load_model(self): 76 | import yolov5 77 | 78 | # init model 79 | model_path = TestConstants.YOLOV5S_HUB_ID 80 | model = yolov5.load(model_path, device=DEVICE) 81 | 82 | # check if loaded 83 | self.assertNotEqual(model, None) 84 | 85 | def test_predict(self): 86 | from PIL import Image 87 | 88 | import yolov5 89 | 90 | # init yolov5s model 91 | model_path = TestConstants.YOLOV5S_HUB_ID 92 | model = yolov5.load(model_path, device=DEVICE) 93 | 94 | # prepare image 95 | image_path = TestConstants.ZIDANE_IMAGE_PATH 96 | image = Image.open(image_path) 97 | 98 | # perform inference 99 | results = model(image, size=640, augment=False) 100 | 101 | # compare 102 | self.assertEqual(results.n, 1) 103 | self.assertEqual(len(results.names), 80) 104 | self.assertEqual(len(results.pred[0]), 4) 105 | 106 | # init yolov5s model 107 | model_path = TestConstants.YOLOV5S_HUB_ID 108 | model = yolov5.load(model_path, device=DEVICE) 109 | 110 | # prepare images 111 | image_path1 = TestConstants.ZIDANE_IMAGE_PATH 112 | image_path2 = TestConstants.BUS_IMAGE_PATH 113 | image1 = Image.open(image_path1) 114 | image2 = Image.open(image_path2) 115 | 116 | # perform inference with multiple images and test augmentation 117 | results = model([image1, image2], size=1280, augment=True) 118 | 119 | # compare 120 | self.assertEqual(results.n, 2) 121 | self.assertEqual(len(results.names), 80) 122 | self.assertEqual(len(results.pred[0]), 4) 123 | self.assertEqual(len(results.pred[1]), 5) 124 | 125 | 126 | 127 | if __name__ == "__main__": 128 | unittest.main() 129 | -------------------------------------------------------------------------------- /yolov5/__init__.py: -------------------------------------------------------------------------------- 1 | from yolov5.helpers import YOLOv5 2 | from yolov5.helpers import load_model as load 3 | 4 | __version__ = "7.0.14" 5 | -------------------------------------------------------------------------------- /yolov5/classify/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fcakyon/yolov5-pip/40a188792bca82b8285549edb2c318b9d73bcd47/yolov5/classify/__init__.py -------------------------------------------------------------------------------- /yolov5/cli.py: -------------------------------------------------------------------------------- 1 | import fire 2 | 3 | from yolov5.benchmarks import run_cli as benchmarks 4 | from yolov5.classify.predict import run as classify_predict 5 | from yolov5.classify.train import run_cli as classify_train 6 | from yolov5.classify.val import run as classify_val 7 | from yolov5.detect import run as detect 8 | from yolov5.export import run as export 9 | from yolov5.segment.predict import run as segment_predict 10 | from yolov5.segment.train import run_cli as segment_train 11 | from yolov5.segment.val import run as segment_val 12 | from yolov5.train import run_cli as train 13 | from yolov5.val import run as val 14 | 15 | 16 | def app() -> None: 17 | """Cli app.""" 18 | fire.Fire( 19 | { 20 | "train": train, 21 | "val": val, 22 | "detect": detect, 23 | "export": export, 24 | "benchmarks": benchmarks, 25 | 'classify': {'train': classify_train, 'val': classify_val, 'predict': classify_predict}, 26 | 'segment': {'train': segment_train, 'val': segment_val, 'predict': segment_predict}, 27 | } 28 | ) 29 | 30 | if __name__ == "__main__": 31 | app() 32 | -------------------------------------------------------------------------------- /yolov5/data/Argoverse.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, GPL-3.0 license 2 | # Argoverse-HD dataset (ring-front-center camera) http://www.cs.cmu.edu/~mengtial/proj/streaming/ by Argo AI 3 | # Example usage: python train.py --data Argoverse.yaml 4 | # parent 5 | # ├── yolov5 6 | # └── datasets 7 | # └── Argoverse ← downloads here (31.3 GB) 8 | 9 | 10 | # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] 11 | path: ../datasets/Argoverse # dataset root dir 12 | train: Argoverse-1.1/images/train/ # train images (relative to 'path') 39384 images 13 | val: Argoverse-1.1/images/val/ # val images (relative to 'path') 15062 images 14 | test: Argoverse-1.1/images/test/ # test images (optional) https://eval.ai/web/challenges/challenge-page/800/overview 15 | 16 | # Classes 17 | names: 18 | 0: person 19 | 1: bicycle 20 | 2: car 21 | 3: motorcycle 22 | 4: bus 23 | 5: truck 24 | 6: traffic_light 25 | 7: stop_sign 26 | 27 | 28 | # Download script/URL (optional) --------------------------------------------------------------------------------------- 29 | download: | 30 | import json 31 | 32 | from tqdm import tqdm 33 | from yolov5.utils.general import download, Path 34 | 35 | 36 | def argoverse2yolo(set): 37 | labels = {} 38 | a = json.load(open(set, "rb")) 39 | for annot in tqdm(a['annotations'], desc=f"Converting {set} to YOLOv5 format..."): 40 | img_id = annot['image_id'] 41 | img_name = a['images'][img_id]['name'] 42 | img_label_name = f'{img_name[:-3]}txt' 43 | 44 | cls = annot['category_id'] # instance class id 45 | x_center, y_center, width, height = annot['bbox'] 46 | x_center = (x_center + width / 2) / 1920.0 # offset and scale 47 | y_center = (y_center + height / 2) / 1200.0 # offset and scale 48 | width /= 1920.0 # scale 49 | height /= 1200.0 # scale 50 | 51 | img_dir = set.parents[2] / 'Argoverse-1.1' / 'labels' / a['seq_dirs'][a['images'][annot['image_id']]['sid']] 52 | if not img_dir.exists(): 53 | img_dir.mkdir(parents=True, exist_ok=True) 54 | 55 | k = str(img_dir / img_label_name) 56 | if k not in labels: 57 | labels[k] = [] 58 | labels[k].append(f"{cls} {x_center} {y_center} {width} {height}\n") 59 | 60 | for k in labels: 61 | with open(k, "w") as f: 62 | f.writelines(labels[k]) 63 | 64 | 65 | # Download 66 | dir = Path(yaml['path']) # dataset root dir 67 | urls = ['https://argoverse-hd.s3.us-east-2.amazonaws.com/Argoverse-HD-Full.zip'] 68 | download(urls, dir=dir, delete=False) 69 | 70 | # Convert 71 | annotations_dir = 'Argoverse-HD/annotations/' 72 | (dir / 'Argoverse-1.1' / 'tracking').rename(dir / 'Argoverse-1.1' / 'images') # rename 'tracking' to 'images' 73 | for d in "train.json", "val.json": 74 | argoverse2yolo(dir / annotations_dir / d) # convert VisDrone annotations to YOLO labels 75 | -------------------------------------------------------------------------------- /yolov5/data/GlobalWheat2020.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, GPL-3.0 license 2 | # Global Wheat 2020 dataset http://www.global-wheat.com/ by University of Saskatchewan 3 | # Example usage: python train.py --data GlobalWheat2020.yaml 4 | # parent 5 | # ├── yolov5 6 | # └── datasets 7 | # └── GlobalWheat2020 ← downloads here (7.0 GB) 8 | 9 | 10 | # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] 11 | path: ../datasets/GlobalWheat2020 # dataset root dir 12 | train: # train images (relative to 'path') 3422 images 13 | - images/arvalis_1 14 | - images/arvalis_2 15 | - images/arvalis_3 16 | - images/ethz_1 17 | - images/rres_1 18 | - images/inrae_1 19 | - images/usask_1 20 | val: # val images (relative to 'path') 748 images (WARNING: train set contains ethz_1) 21 | - images/ethz_1 22 | test: # test images (optional) 1276 images 23 | - images/utokyo_1 24 | - images/utokyo_2 25 | - images/nau_1 26 | - images/uq_1 27 | 28 | # Classes 29 | names: 30 | 0: wheat_head 31 | 32 | 33 | # Download script/URL (optional) --------------------------------------------------------------------------------------- 34 | download: | 35 | from yolov5.utils.general import download, Path 36 | 37 | 38 | # Download 39 | dir = Path(yaml['path']) # dataset root dir 40 | urls = ['https://zenodo.org/record/4298502/files/global-wheat-codalab-official.zip', 41 | 'https://github.com/ultralytics/yolov5/releases/download/v1.0/GlobalWheat2020_labels.zip'] 42 | download(urls, dir=dir) 43 | 44 | # Make Directories 45 | for p in 'annotations', 'images', 'labels': 46 | (dir / p).mkdir(parents=True, exist_ok=True) 47 | 48 | # Move 49 | for p in 'arvalis_1', 'arvalis_2', 'arvalis_3', 'ethz_1', 'rres_1', 'inrae_1', 'usask_1', \ 50 | 'utokyo_1', 'utokyo_2', 'nau_1', 'uq_1': 51 | (dir / p).rename(dir / 'images' / p) # move to /images 52 | f = (dir / p).with_suffix('.json') # json file 53 | if f.exists(): 54 | f.rename((dir / 'annotations' / p).with_suffix('.json')) # move to /annotations 55 | -------------------------------------------------------------------------------- /yolov5/data/SKU-110K.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, GPL-3.0 license 2 | # SKU-110K retail items dataset https://github.com/eg4000/SKU110K_CVPR19 by Trax Retail 3 | # Example usage: python train.py --data SKU-110K.yaml 4 | # parent 5 | # ├── yolov5 6 | # └── datasets 7 | # └── SKU-110K ← downloads here (13.6 GB) 8 | 9 | 10 | # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] 11 | path: ../datasets/SKU-110K # dataset root dir 12 | train: train.txt # train images (relative to 'path') 8219 images 13 | val: val.txt # val images (relative to 'path') 588 images 14 | test: test.txt # test images (optional) 2936 images 15 | 16 | # Classes 17 | names: 18 | 0: object 19 | 20 | 21 | # Download script/URL (optional) --------------------------------------------------------------------------------------- 22 | download: | 23 | import shutil 24 | from tqdm import tqdm 25 | from yolov5.utils.general import np, pd, Path, download, xyxy2xywh 26 | 27 | 28 | # Download 29 | dir = Path(yaml['path']) # dataset root dir 30 | parent = Path(dir.parent) # download dir 31 | urls = ['http://trax-geometry.s3.amazonaws.com/cvpr_challenge/SKU110K_fixed.tar.gz'] 32 | download(urls, dir=parent, delete=False) 33 | 34 | # Rename directories 35 | if dir.exists(): 36 | shutil.rmtree(dir) 37 | (parent / 'SKU110K_fixed').rename(dir) # rename dir 38 | (dir / 'labels').mkdir(parents=True, exist_ok=True) # create labels dir 39 | 40 | # Convert labels 41 | names = 'image', 'x1', 'y1', 'x2', 'y2', 'class', 'image_width', 'image_height' # column names 42 | for d in 'annotations_train.csv', 'annotations_val.csv', 'annotations_test.csv': 43 | x = pd.read_csv(dir / 'annotations' / d, names=names).values # annotations 44 | images, unique_images = x[:, 0], np.unique(x[:, 0]) 45 | with open((dir / d).with_suffix('.txt').__str__().replace('annotations_', ''), 'w') as f: 46 | f.writelines(f'./images/{s}\n' for s in unique_images) 47 | for im in tqdm(unique_images, desc=f'Converting {dir / d}'): 48 | cls = 0 # single-class dataset 49 | with open((dir / 'labels' / im).with_suffix('.txt'), 'a') as f: 50 | for r in x[images == im]: 51 | w, h = r[6], r[7] # image width, height 52 | xywh = xyxy2xywh(np.array([[r[1] / w, r[2] / h, r[3] / w, r[4] / h]]))[0] # instance 53 | f.write(f"{cls} {xywh[0]:.5f} {xywh[1]:.5f} {xywh[2]:.5f} {xywh[3]:.5f}\n") # write label 54 | -------------------------------------------------------------------------------- /yolov5/data/VOC.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, GPL-3.0 license 2 | # PASCAL VOC dataset http://host.robots.ox.ac.uk/pascal/VOC by University of Oxford 3 | # Example usage: python train.py --data VOC.yaml 4 | # parent 5 | # ├── yolov5 6 | # └── datasets 7 | # └── VOC ← downloads here (2.8 GB) 8 | 9 | 10 | # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] 11 | path: ../datasets/VOC 12 | train: # train images (relative to 'path') 16551 images 13 | - images/train2012 14 | - images/train2007 15 | - images/val2012 16 | - images/val2007 17 | val: # val images (relative to 'path') 4952 images 18 | - images/test2007 19 | test: # test images (optional) 20 | - images/test2007 21 | 22 | # Classes 23 | names: 24 | 0: aeroplane 25 | 1: bicycle 26 | 2: bird 27 | 3: boat 28 | 4: bottle 29 | 5: bus 30 | 6: car 31 | 7: cat 32 | 8: chair 33 | 9: cow 34 | 10: diningtable 35 | 11: dog 36 | 12: horse 37 | 13: motorbike 38 | 14: person 39 | 15: pottedplant 40 | 16: sheep 41 | 17: sofa 42 | 18: train 43 | 19: tvmonitor 44 | 45 | 46 | # Download script/URL (optional) --------------------------------------------------------------------------------------- 47 | download: | 48 | import xml.etree.ElementTree as ET 49 | 50 | from tqdm import tqdm 51 | from yolov5.utils.general import download, Path 52 | 53 | 54 | def convert_label(path, lb_path, year, image_id): 55 | def convert_box(size, box): 56 | dw, dh = 1. / size[0], 1. / size[1] 57 | x, y, w, h = (box[0] + box[1]) / 2.0 - 1, (box[2] + box[3]) / 2.0 - 1, box[1] - box[0], box[3] - box[2] 58 | return x * dw, y * dh, w * dw, h * dh 59 | 60 | in_file = open(path / f'VOC{year}/Annotations/{image_id}.xml') 61 | out_file = open(lb_path, 'w') 62 | tree = ET.parse(in_file) 63 | root = tree.getroot() 64 | size = root.find('size') 65 | w = int(size.find('width').text) 66 | h = int(size.find('height').text) 67 | 68 | names = list(yaml['names'].values()) # names list 69 | for obj in root.iter('object'): 70 | cls = obj.find('name').text 71 | if cls in names and int(obj.find('difficult').text) != 1: 72 | xmlbox = obj.find('bndbox') 73 | bb = convert_box((w, h), [float(xmlbox.find(x).text) for x in ('xmin', 'xmax', 'ymin', 'ymax')]) 74 | cls_id = names.index(cls) # class id 75 | out_file.write(" ".join([str(a) for a in (cls_id, *bb)]) + '\n') 76 | 77 | 78 | # Download 79 | dir = Path(yaml['path']) # dataset root dir 80 | url = 'https://github.com/ultralytics/yolov5/releases/download/v1.0/' 81 | urls = [f'{url}VOCtrainval_06-Nov-2007.zip', # 446MB, 5012 images 82 | f'{url}VOCtest_06-Nov-2007.zip', # 438MB, 4953 images 83 | f'{url}VOCtrainval_11-May-2012.zip'] # 1.95GB, 17126 images 84 | download(urls, dir=dir / 'images', delete=False, curl=True, threads=3) 85 | 86 | # Convert 87 | path = dir / 'images/VOCdevkit' 88 | for year, image_set in ('2012', 'train'), ('2012', 'val'), ('2007', 'train'), ('2007', 'val'), ('2007', 'test'): 89 | imgs_path = dir / 'images' / f'{image_set}{year}' 90 | lbs_path = dir / 'labels' / f'{image_set}{year}' 91 | imgs_path.mkdir(exist_ok=True, parents=True) 92 | lbs_path.mkdir(exist_ok=True, parents=True) 93 | 94 | with open(path / f'VOC{year}/ImageSets/Main/{image_set}.txt') as f: 95 | image_ids = f.read().strip().split() 96 | for id in tqdm(image_ids, desc=f'{image_set}{year}'): 97 | f = path / f'VOC{year}/JPEGImages/{id}.jpg' # old img path 98 | lb_path = (lbs_path / f.name).with_suffix('.txt') # new label path 99 | f.rename(imgs_path / f.name) # move image 100 | convert_label(path, lb_path, year, id) # convert labels to YOLO format 101 | -------------------------------------------------------------------------------- /yolov5/data/VisDrone.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, GPL-3.0 license 2 | # VisDrone2019-DET dataset https://github.com/VisDrone/VisDrone-Dataset by Tianjin University 3 | # Example usage: python train.py --data VisDrone.yaml 4 | # parent 5 | # ├── yolov5 6 | # └── datasets 7 | # └── VisDrone ← downloads here (2.3 GB) 8 | 9 | 10 | # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] 11 | path: ../datasets/VisDrone # dataset root dir 12 | train: VisDrone2019-DET-train/images # train images (relative to 'path') 6471 images 13 | val: VisDrone2019-DET-val/images # val images (relative to 'path') 548 images 14 | test: VisDrone2019-DET-test-dev/images # test images (optional) 1610 images 15 | 16 | # Classes 17 | names: 18 | 0: pedestrian 19 | 1: people 20 | 2: bicycle 21 | 3: car 22 | 4: van 23 | 5: truck 24 | 6: tricycle 25 | 7: awning-tricycle 26 | 8: bus 27 | 9: motor 28 | 29 | 30 | # Download script/URL (optional) --------------------------------------------------------------------------------------- 31 | download: | 32 | from yolov5.utils.general import download, os, Path 33 | 34 | def visdrone2yolo(dir): 35 | from PIL import Image 36 | from tqdm import tqdm 37 | 38 | def convert_box(size, box): 39 | # Convert VisDrone box to YOLO xywh box 40 | dw = 1. / size[0] 41 | dh = 1. / size[1] 42 | return (box[0] + box[2] / 2) * dw, (box[1] + box[3] / 2) * dh, box[2] * dw, box[3] * dh 43 | 44 | (dir / 'labels').mkdir(parents=True, exist_ok=True) # make labels directory 45 | pbar = tqdm((dir / 'annotations').glob('*.txt'), desc=f'Converting {dir}') 46 | for f in pbar: 47 | img_size = Image.open((dir / 'images' / f.name).with_suffix('.jpg')).size 48 | lines = [] 49 | with open(f, 'r') as file: # read annotation.txt 50 | for row in [x.split(',') for x in file.read().strip().splitlines()]: 51 | if row[4] == '0': # VisDrone 'ignored regions' class 0 52 | continue 53 | cls = int(row[5]) - 1 54 | box = convert_box(img_size, tuple(map(int, row[:4]))) 55 | lines.append(f"{cls} {' '.join(f'{x:.6f}' for x in box)}\n") 56 | with open(str(f).replace(os.sep + 'annotations' + os.sep, os.sep + 'labels' + os.sep), 'w') as fl: 57 | fl.writelines(lines) # write label.txt 58 | 59 | 60 | # Download 61 | dir = Path(yaml['path']) # dataset root dir 62 | urls = ['https://github.com/ultralytics/yolov5/releases/download/v1.0/VisDrone2019-DET-train.zip', 63 | 'https://github.com/ultralytics/yolov5/releases/download/v1.0/VisDrone2019-DET-val.zip', 64 | 'https://github.com/ultralytics/yolov5/releases/download/v1.0/VisDrone2019-DET-test-dev.zip', 65 | 'https://github.com/ultralytics/yolov5/releases/download/v1.0/VisDrone2019-DET-test-challenge.zip'] 66 | download(urls, dir=dir, curl=True, threads=4) 67 | 68 | # Convert 69 | for d in 'VisDrone2019-DET-train', 'VisDrone2019-DET-val', 'VisDrone2019-DET-test-dev': 70 | visdrone2yolo(dir / d) # convert VisDrone annotations to YOLO labels 71 | -------------------------------------------------------------------------------- /yolov5/data/coco.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, GPL-3.0 license 2 | # COCO 2017 dataset http://cocodataset.org by Microsoft 3 | # Example usage: python train.py --data coco.yaml 4 | # parent 5 | # ├── yolov5 6 | # └── datasets 7 | # └── coco ← downloads here (20.1 GB) 8 | 9 | 10 | # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] 11 | path: ../datasets/coco # dataset root dir 12 | train: train2017.txt # train images (relative to 'path') 118287 images 13 | val: val2017.txt # val images (relative to 'path') 5000 images 14 | test: test-dev2017.txt # 20288 of 40670 images, submit to https://competitions.codalab.org/competitions/20794 15 | 16 | # Classes 17 | names: 18 | 0: person 19 | 1: bicycle 20 | 2: car 21 | 3: motorcycle 22 | 4: airplane 23 | 5: bus 24 | 6: train 25 | 7: truck 26 | 8: boat 27 | 9: traffic light 28 | 10: fire hydrant 29 | 11: stop sign 30 | 12: parking meter 31 | 13: bench 32 | 14: bird 33 | 15: cat 34 | 16: dog 35 | 17: horse 36 | 18: sheep 37 | 19: cow 38 | 20: elephant 39 | 21: bear 40 | 22: zebra 41 | 23: giraffe 42 | 24: backpack 43 | 25: umbrella 44 | 26: handbag 45 | 27: tie 46 | 28: suitcase 47 | 29: frisbee 48 | 30: skis 49 | 31: snowboard 50 | 32: sports ball 51 | 33: kite 52 | 34: baseball bat 53 | 35: baseball glove 54 | 36: skateboard 55 | 37: surfboard 56 | 38: tennis racket 57 | 39: bottle 58 | 40: wine glass 59 | 41: cup 60 | 42: fork 61 | 43: knife 62 | 44: spoon 63 | 45: bowl 64 | 46: banana 65 | 47: apple 66 | 48: sandwich 67 | 49: orange 68 | 50: broccoli 69 | 51: carrot 70 | 52: hot dog 71 | 53: pizza 72 | 54: donut 73 | 55: cake 74 | 56: chair 75 | 57: couch 76 | 58: potted plant 77 | 59: bed 78 | 60: dining table 79 | 61: toilet 80 | 62: tv 81 | 63: laptop 82 | 64: mouse 83 | 65: remote 84 | 66: keyboard 85 | 67: cell phone 86 | 68: microwave 87 | 69: oven 88 | 70: toaster 89 | 71: sink 90 | 72: refrigerator 91 | 73: book 92 | 74: clock 93 | 75: vase 94 | 76: scissors 95 | 77: teddy bear 96 | 78: hair drier 97 | 79: toothbrush 98 | 99 | 100 | # Download script/URL (optional) 101 | download: | 102 | from yolov5.utils.general import download, Path 103 | 104 | 105 | # Download labels 106 | segments = False # segment or box labels 107 | dir = Path(yaml['path']) # dataset root dir 108 | url = 'https://github.com/ultralytics/yolov5/releases/download/v1.0/' 109 | urls = [url + ('coco2017labels-segments.zip' if segments else 'coco2017labels.zip')] # labels 110 | download(urls, dir=dir.parent) 111 | 112 | # Download data 113 | urls = ['http://images.cocodataset.org/zips/train2017.zip', # 19G, 118k images 114 | 'http://images.cocodataset.org/zips/val2017.zip', # 1G, 5k images 115 | 'http://images.cocodataset.org/zips/test2017.zip'] # 7G, 41k images (optional) 116 | download(urls, dir=dir / 'images', threads=3) 117 | -------------------------------------------------------------------------------- /yolov5/data/coco128-seg.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, GPL-3.0 license 2 | # COCO128-seg dataset https://www.kaggle.com/ultralytics/coco128 (first 128 images from COCO train2017) by Ultralytics 3 | # Example usage: python train.py --data coco128.yaml 4 | # parent 5 | # ├── yolov5 6 | # └── datasets 7 | # └── coco128-seg ← downloads here (7 MB) 8 | 9 | 10 | # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] 11 | path: ../datasets/coco128-seg # dataset root dir 12 | train: images/train2017 # train images (relative to 'path') 128 images 13 | val: images/train2017 # val images (relative to 'path') 128 images 14 | test: # test images (optional) 15 | 16 | # Classes 17 | names: 18 | 0: person 19 | 1: bicycle 20 | 2: car 21 | 3: motorcycle 22 | 4: airplane 23 | 5: bus 24 | 6: train 25 | 7: truck 26 | 8: boat 27 | 9: traffic light 28 | 10: fire hydrant 29 | 11: stop sign 30 | 12: parking meter 31 | 13: bench 32 | 14: bird 33 | 15: cat 34 | 16: dog 35 | 17: horse 36 | 18: sheep 37 | 19: cow 38 | 20: elephant 39 | 21: bear 40 | 22: zebra 41 | 23: giraffe 42 | 24: backpack 43 | 25: umbrella 44 | 26: handbag 45 | 27: tie 46 | 28: suitcase 47 | 29: frisbee 48 | 30: skis 49 | 31: snowboard 50 | 32: sports ball 51 | 33: kite 52 | 34: baseball bat 53 | 35: baseball glove 54 | 36: skateboard 55 | 37: surfboard 56 | 38: tennis racket 57 | 39: bottle 58 | 40: wine glass 59 | 41: cup 60 | 42: fork 61 | 43: knife 62 | 44: spoon 63 | 45: bowl 64 | 46: banana 65 | 47: apple 66 | 48: sandwich 67 | 49: orange 68 | 50: broccoli 69 | 51: carrot 70 | 52: hot dog 71 | 53: pizza 72 | 54: donut 73 | 55: cake 74 | 56: chair 75 | 57: couch 76 | 58: potted plant 77 | 59: bed 78 | 60: dining table 79 | 61: toilet 80 | 62: tv 81 | 63: laptop 82 | 64: mouse 83 | 65: remote 84 | 66: keyboard 85 | 67: cell phone 86 | 68: microwave 87 | 69: oven 88 | 70: toaster 89 | 71: sink 90 | 72: refrigerator 91 | 73: book 92 | 74: clock 93 | 75: vase 94 | 76: scissors 95 | 77: teddy bear 96 | 78: hair drier 97 | 79: toothbrush 98 | 99 | 100 | # Download script/URL (optional) 101 | download: https://ultralytics.com/assets/coco128-seg.zip 102 | -------------------------------------------------------------------------------- /yolov5/data/coco128.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, GPL-3.0 license 2 | # COCO128 dataset https://www.kaggle.com/ultralytics/coco128 (first 128 images from COCO train2017) by Ultralytics 3 | # Example usage: python train.py --data coco128.yaml 4 | # parent 5 | # ├── yolov5 6 | # └── datasets 7 | # └── coco128 ← downloads here (7 MB) 8 | 9 | 10 | # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] 11 | path: ../datasets/coco128 # dataset root dir 12 | train: images/train2017 # train images (relative to 'path') 128 images 13 | val: images/train2017 # val images (relative to 'path') 128 images 14 | test: # test images (optional) 15 | 16 | # Classes 17 | names: 18 | 0: person 19 | 1: bicycle 20 | 2: car 21 | 3: motorcycle 22 | 4: airplane 23 | 5: bus 24 | 6: train 25 | 7: truck 26 | 8: boat 27 | 9: traffic light 28 | 10: fire hydrant 29 | 11: stop sign 30 | 12: parking meter 31 | 13: bench 32 | 14: bird 33 | 15: cat 34 | 16: dog 35 | 17: horse 36 | 18: sheep 37 | 19: cow 38 | 20: elephant 39 | 21: bear 40 | 22: zebra 41 | 23: giraffe 42 | 24: backpack 43 | 25: umbrella 44 | 26: handbag 45 | 27: tie 46 | 28: suitcase 47 | 29: frisbee 48 | 30: skis 49 | 31: snowboard 50 | 32: sports ball 51 | 33: kite 52 | 34: baseball bat 53 | 35: baseball glove 54 | 36: skateboard 55 | 37: surfboard 56 | 38: tennis racket 57 | 39: bottle 58 | 40: wine glass 59 | 41: cup 60 | 42: fork 61 | 43: knife 62 | 44: spoon 63 | 45: bowl 64 | 46: banana 65 | 47: apple 66 | 48: sandwich 67 | 49: orange 68 | 50: broccoli 69 | 51: carrot 70 | 52: hot dog 71 | 53: pizza 72 | 54: donut 73 | 55: cake 74 | 56: chair 75 | 57: couch 76 | 58: potted plant 77 | 59: bed 78 | 60: dining table 79 | 61: toilet 80 | 62: tv 81 | 63: laptop 82 | 64: mouse 83 | 65: remote 84 | 66: keyboard 85 | 67: cell phone 86 | 68: microwave 87 | 69: oven 88 | 70: toaster 89 | 71: sink 90 | 72: refrigerator 91 | 73: book 92 | 74: clock 93 | 75: vase 94 | 76: scissors 95 | 77: teddy bear 96 | 78: hair drier 97 | 79: toothbrush 98 | 99 | 100 | # Download script/URL (optional) 101 | download: https://ultralytics.com/assets/coco128.zip 102 | -------------------------------------------------------------------------------- /yolov5/data/hyps/hyp.Objects365.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, GPL-3.0 license 2 | # Hyperparameters for Objects365 training 3 | # python train.py --weights yolov5m.pt --data Objects365.yaml --evolve 4 | # See Hyperparameter Evolution tutorial for details https://github.com/ultralytics/yolov5#tutorials 5 | 6 | lr0: 0.00258 7 | lrf: 0.17 8 | momentum: 0.779 9 | weight_decay: 0.00058 10 | warmup_epochs: 1.33 11 | warmup_momentum: 0.86 12 | warmup_bias_lr: 0.0711 13 | box: 0.0539 14 | cls: 0.299 15 | cls_pw: 0.825 16 | obj: 0.632 17 | obj_pw: 1.0 18 | iou_t: 0.2 19 | anchor_t: 3.44 20 | anchors: 3.2 21 | fl_gamma: 0.0 22 | hsv_h: 0.0188 23 | hsv_s: 0.704 24 | hsv_v: 0.36 25 | degrees: 0.0 26 | translate: 0.0902 27 | scale: 0.491 28 | shear: 0.0 29 | perspective: 0.0 30 | flipud: 0.0 31 | fliplr: 0.5 32 | mosaic: 1.0 33 | mixup: 0.0 34 | copy_paste: 0.0 35 | -------------------------------------------------------------------------------- /yolov5/data/hyps/hyp.VOC.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, GPL-3.0 license 2 | # Hyperparameters for VOC training 3 | # python train.py --batch 128 --weights yolov5m6.pt --data VOC.yaml --epochs 50 --img 512 --hyp hyp.scratch-med.yaml --evolve 4 | # See Hyperparameter Evolution tutorial for details https://github.com/ultralytics/yolov5#tutorials 5 | 6 | # YOLOv5 Hyperparameter Evolution Results 7 | # Best generation: 467 8 | # Last generation: 996 9 | # metrics/precision, metrics/recall, metrics/mAP_0.5, metrics/mAP_0.5:0.95, val/box_loss, val/obj_loss, val/cls_loss 10 | # 0.87729, 0.85125, 0.91286, 0.72664, 0.0076739, 0.0042529, 0.0013865 11 | 12 | lr0: 0.00334 13 | lrf: 0.15135 14 | momentum: 0.74832 15 | weight_decay: 0.00025 16 | warmup_epochs: 3.3835 17 | warmup_momentum: 0.59462 18 | warmup_bias_lr: 0.18657 19 | box: 0.02 20 | cls: 0.21638 21 | cls_pw: 0.5 22 | obj: 0.51728 23 | obj_pw: 0.67198 24 | iou_t: 0.2 25 | anchor_t: 3.3744 26 | fl_gamma: 0.0 27 | hsv_h: 0.01041 28 | hsv_s: 0.54703 29 | hsv_v: 0.27739 30 | degrees: 0.0 31 | translate: 0.04591 32 | scale: 0.75544 33 | shear: 0.0 34 | perspective: 0.0 35 | flipud: 0.0 36 | fliplr: 0.5 37 | mosaic: 0.85834 38 | mixup: 0.04266 39 | copy_paste: 0.0 40 | anchors: 3.412 41 | -------------------------------------------------------------------------------- /yolov5/data/hyps/hyp.no-augmentation.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, GPL-3.0 license 2 | # Hyperparameters when using Albumentations frameworks 3 | # python train.py --hyp hyp.no-augmentation.yaml 4 | # See https://github.com/ultralytics/yolov5/pull/3882 for YOLOv5 + Albumentations Usage examples 5 | 6 | lr0: 0.01 # initial learning rate (SGD=1E-2, Adam=1E-3) 7 | lrf: 0.1 # final OneCycleLR learning rate (lr0 * lrf) 8 | momentum: 0.937 # SGD momentum/Adam beta1 9 | weight_decay: 0.0005 # optimizer weight decay 5e-4 10 | warmup_epochs: 3.0 # warmup epochs (fractions ok) 11 | warmup_momentum: 0.8 # warmup initial momentum 12 | warmup_bias_lr: 0.1 # warmup initial bias lr 13 | box: 0.05 # box loss gain 14 | cls: 0.3 # cls loss gain 15 | cls_pw: 1.0 # cls BCELoss positive_weight 16 | obj: 0.7 # obj loss gain (scale with pixels) 17 | obj_pw: 1.0 # obj BCELoss positive_weight 18 | iou_t: 0.20 # IoU training threshold 19 | anchor_t: 4.0 # anchor-multiple threshold 20 | # anchors: 3 # anchors per output layer (0 to ignore) 21 | # this parameters are all zero since we want to use albumentation framework 22 | fl_gamma: 0.0 # focal loss gamma (efficientDet default gamma=1.5) 23 | hsv_h: 0 # image HSV-Hue augmentation (fraction) 24 | hsv_s: 00 # image HSV-Saturation augmentation (fraction) 25 | hsv_v: 0 # image HSV-Value augmentation (fraction) 26 | degrees: 0.0 # image rotation (+/- deg) 27 | translate: 0 # image translation (+/- fraction) 28 | scale: 0 # image scale (+/- gain) 29 | shear: 0 # image shear (+/- deg) 30 | perspective: 0.0 # image perspective (+/- fraction), range 0-0.001 31 | flipud: 0.0 # image flip up-down (probability) 32 | fliplr: 0.0 # image flip left-right (probability) 33 | mosaic: 0.0 # image mosaic (probability) 34 | mixup: 0.0 # image mixup (probability) 35 | copy_paste: 0.0 # segment copy-paste (probability) 36 | -------------------------------------------------------------------------------- /yolov5/data/hyps/hyp.scratch-high.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, GPL-3.0 license 2 | # Hyperparameters for high-augmentation COCO training from scratch 3 | # python train.py --batch 32 --cfg yolov5m6.yaml --weights '' --data coco.yaml --img 1280 --epochs 300 4 | # See tutorials for hyperparameter evolution https://github.com/ultralytics/yolov5#tutorials 5 | 6 | lr0: 0.01 # initial learning rate (SGD=1E-2, Adam=1E-3) 7 | lrf: 0.1 # final OneCycleLR learning rate (lr0 * lrf) 8 | momentum: 0.937 # SGD momentum/Adam beta1 9 | weight_decay: 0.0005 # optimizer weight decay 5e-4 10 | warmup_epochs: 3.0 # warmup epochs (fractions ok) 11 | warmup_momentum: 0.8 # warmup initial momentum 12 | warmup_bias_lr: 0.1 # warmup initial bias lr 13 | box: 0.05 # box loss gain 14 | cls: 0.3 # cls loss gain 15 | cls_pw: 1.0 # cls BCELoss positive_weight 16 | obj: 0.7 # obj loss gain (scale with pixels) 17 | obj_pw: 1.0 # obj BCELoss positive_weight 18 | iou_t: 0.20 # IoU training threshold 19 | anchor_t: 4.0 # anchor-multiple threshold 20 | # anchors: 3 # anchors per output layer (0 to ignore) 21 | fl_gamma: 0.0 # focal loss gamma (efficientDet default gamma=1.5) 22 | hsv_h: 0.015 # image HSV-Hue augmentation (fraction) 23 | hsv_s: 0.7 # image HSV-Saturation augmentation (fraction) 24 | hsv_v: 0.4 # image HSV-Value augmentation (fraction) 25 | degrees: 0.0 # image rotation (+/- deg) 26 | translate: 0.1 # image translation (+/- fraction) 27 | scale: 0.9 # image scale (+/- gain) 28 | shear: 0.0 # image shear (+/- deg) 29 | perspective: 0.0 # image perspective (+/- fraction), range 0-0.001 30 | flipud: 0.0 # image flip up-down (probability) 31 | fliplr: 0.5 # image flip left-right (probability) 32 | mosaic: 1.0 # image mosaic (probability) 33 | mixup: 0.1 # image mixup (probability) 34 | copy_paste: 0.1 # segment copy-paste (probability) 35 | -------------------------------------------------------------------------------- /yolov5/data/hyps/hyp.scratch-low.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, GPL-3.0 license 2 | # Hyperparameters for low-augmentation COCO training from scratch 3 | # python train.py --batch 64 --cfg yolov5n6.yaml --weights '' --data coco.yaml --img 640 --epochs 300 --linear 4 | # See tutorials for hyperparameter evolution https://github.com/ultralytics/yolov5#tutorials 5 | 6 | lr0: 0.01 # initial learning rate (SGD=1E-2, Adam=1E-3) 7 | lrf: 0.01 # final OneCycleLR learning rate (lr0 * lrf) 8 | momentum: 0.937 # SGD momentum/Adam beta1 9 | weight_decay: 0.0005 # optimizer weight decay 5e-4 10 | warmup_epochs: 3.0 # warmup epochs (fractions ok) 11 | warmup_momentum: 0.8 # warmup initial momentum 12 | warmup_bias_lr: 0.1 # warmup initial bias lr 13 | box: 0.05 # box loss gain 14 | cls: 0.5 # cls loss gain 15 | cls_pw: 1.0 # cls BCELoss positive_weight 16 | obj: 1.0 # obj loss gain (scale with pixels) 17 | obj_pw: 1.0 # obj BCELoss positive_weight 18 | iou_t: 0.20 # IoU training threshold 19 | anchor_t: 4.0 # anchor-multiple threshold 20 | # anchors: 3 # anchors per output layer (0 to ignore) 21 | fl_gamma: 0.0 # focal loss gamma (efficientDet default gamma=1.5) 22 | hsv_h: 0.015 # image HSV-Hue augmentation (fraction) 23 | hsv_s: 0.7 # image HSV-Saturation augmentation (fraction) 24 | hsv_v: 0.4 # image HSV-Value augmentation (fraction) 25 | degrees: 0.0 # image rotation (+/- deg) 26 | translate: 0.1 # image translation (+/- fraction) 27 | scale: 0.5 # image scale (+/- gain) 28 | shear: 0.0 # image shear (+/- deg) 29 | perspective: 0.0 # image perspective (+/- fraction), range 0-0.001 30 | flipud: 0.0 # image flip up-down (probability) 31 | fliplr: 0.5 # image flip left-right (probability) 32 | mosaic: 1.0 # image mosaic (probability) 33 | mixup: 0.0 # image mixup (probability) 34 | copy_paste: 0.0 # segment copy-paste (probability) 35 | -------------------------------------------------------------------------------- /yolov5/data/hyps/hyp.scratch-med.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, GPL-3.0 license 2 | # Hyperparameters for medium-augmentation COCO training from scratch 3 | # python train.py --batch 32 --cfg yolov5m6.yaml --weights '' --data coco.yaml --img 1280 --epochs 300 4 | # See tutorials for hyperparameter evolution https://github.com/ultralytics/yolov5#tutorials 5 | 6 | lr0: 0.01 # initial learning rate (SGD=1E-2, Adam=1E-3) 7 | lrf: 0.1 # final OneCycleLR learning rate (lr0 * lrf) 8 | momentum: 0.937 # SGD momentum/Adam beta1 9 | weight_decay: 0.0005 # optimizer weight decay 5e-4 10 | warmup_epochs: 3.0 # warmup epochs (fractions ok) 11 | warmup_momentum: 0.8 # warmup initial momentum 12 | warmup_bias_lr: 0.1 # warmup initial bias lr 13 | box: 0.05 # box loss gain 14 | cls: 0.3 # cls loss gain 15 | cls_pw: 1.0 # cls BCELoss positive_weight 16 | obj: 0.7 # obj loss gain (scale with pixels) 17 | obj_pw: 1.0 # obj BCELoss positive_weight 18 | iou_t: 0.20 # IoU training threshold 19 | anchor_t: 4.0 # anchor-multiple threshold 20 | # anchors: 3 # anchors per output layer (0 to ignore) 21 | fl_gamma: 0.0 # focal loss gamma (efficientDet default gamma=1.5) 22 | hsv_h: 0.015 # image HSV-Hue augmentation (fraction) 23 | hsv_s: 0.7 # image HSV-Saturation augmentation (fraction) 24 | hsv_v: 0.4 # image HSV-Value augmentation (fraction) 25 | degrees: 0.0 # image rotation (+/- deg) 26 | translate: 0.1 # image translation (+/- fraction) 27 | scale: 0.9 # image scale (+/- gain) 28 | shear: 0.0 # image shear (+/- deg) 29 | perspective: 0.0 # image perspective (+/- fraction), range 0-0.001 30 | flipud: 0.0 # image flip up-down (probability) 31 | fliplr: 0.5 # image flip left-right (probability) 32 | mosaic: 1.0 # image mosaic (probability) 33 | mixup: 0.1 # image mixup (probability) 34 | copy_paste: 0.0 # segment copy-paste (probability) 35 | -------------------------------------------------------------------------------- /yolov5/data/images/bus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fcakyon/yolov5-pip/40a188792bca82b8285549edb2c318b9d73bcd47/yolov5/data/images/bus.jpg -------------------------------------------------------------------------------- /yolov5/data/images/zidane.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fcakyon/yolov5-pip/40a188792bca82b8285549edb2c318b9d73bcd47/yolov5/data/images/zidane.jpg -------------------------------------------------------------------------------- /yolov5/data/scripts/download_weights.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # YOLOv5 🚀 by Ultralytics, GPL-3.0 license 3 | # Download latest models from https://github.com/ultralytics/yolov5/releases 4 | # Example usage: bash data/scripts/download_weights.sh 5 | # parent 6 | # └── yolov5 7 | # ├── yolov5s.pt ← downloads here 8 | # ├── yolov5m.pt 9 | # └── ... 10 | 11 | python - <= cls >= 0, f'incorrect class index {cls}' 125 | 126 | # Write YOLO label 127 | if id not in shapes: 128 | shapes[id] = Image.open(file).size 129 | box = xyxy2xywhn(box[None].astype(np.float), w=shapes[id][0], h=shapes[id][1], clip=True) 130 | with open((labels / id).with_suffix('.txt'), 'a') as f: 131 | f.write(f"{cls} {' '.join(f'{x:.6f}' for x in box[0])}\n") # write label.txt 132 | except Exception as e: 133 | print(f'WARNING: skipping one label for {file}: {e}') 134 | 135 | 136 | # Download manually from https://challenge.xviewdataset.org 137 | dir = Path(yaml['path']) # dataset root dir 138 | # urls = ['https://d307kc0mrhucc3.cloudfront.net/train_labels.zip', # train labels 139 | # 'https://d307kc0mrhucc3.cloudfront.net/train_images.zip', # 15G, 847 train images 140 | # 'https://d307kc0mrhucc3.cloudfront.net/val_images.zip'] # 5G, 282 val images (no labels) 141 | # download(urls, dir=dir, delete=False) 142 | 143 | # Convert labels 144 | convert_labels(dir / 'xView_train.geojson') 145 | 146 | # Move images 147 | images = Path(dir / 'images') 148 | images.mkdir(parents=True, exist_ok=True) 149 | Path(dir / 'train_images').rename(dir / 'images' / 'train') 150 | Path(dir / 'val_images').rename(dir / 'images' / 'val') 151 | 152 | # Split 153 | autosplit(dir / 'images' / 'train') 154 | -------------------------------------------------------------------------------- /yolov5/models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fcakyon/yolov5-pip/40a188792bca82b8285549edb2c318b9d73bcd47/yolov5/models/__init__.py -------------------------------------------------------------------------------- /yolov5/models/experimental.py: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | """ 3 | Experimental modules 4 | """ 5 | import math 6 | 7 | import numpy as np 8 | import torch 9 | import torch.nn as nn 10 | 11 | from yolov5.utils.downloads import attempt_download 12 | 13 | 14 | class Sum(nn.Module): 15 | # Weighted sum of 2 or more layers https://arxiv.org/abs/1911.09070 16 | def __init__(self, n, weight=False): # n: number of inputs 17 | super().__init__() 18 | self.weight = weight # apply weights boolean 19 | self.iter = range(n - 1) # iter object 20 | if weight: 21 | self.w = nn.Parameter(-torch.arange(1.0, n) / 2, requires_grad=True) # layer weights 22 | 23 | def forward(self, x): 24 | y = x[0] # no weight 25 | if self.weight: 26 | w = torch.sigmoid(self.w) * 2 27 | for i in self.iter: 28 | y = y + x[i + 1] * w[i] 29 | else: 30 | for i in self.iter: 31 | y = y + x[i + 1] 32 | return y 33 | 34 | 35 | class MixConv2d(nn.Module): 36 | # Mixed Depth-wise Conv https://arxiv.org/abs/1907.09595 37 | def __init__(self, c1, c2, k=(1, 3), s=1, equal_ch=True): # ch_in, ch_out, kernel, stride, ch_strategy 38 | super().__init__() 39 | n = len(k) # number of convolutions 40 | if equal_ch: # equal c_ per group 41 | i = torch.linspace(0, n - 1E-6, c2).floor() # c2 indices 42 | c_ = [(i == g).sum() for g in range(n)] # intermediate channels 43 | else: # equal weight.numel() per group 44 | b = [c2] + [0] * n 45 | a = np.eye(n + 1, n, k=-1) 46 | a -= np.roll(a, 1, axis=1) 47 | a *= np.array(k) ** 2 48 | a[0] = 1 49 | c_ = np.linalg.lstsq(a, b, rcond=None)[0].round() # solve for equal weight indices, ax = b 50 | 51 | self.m = nn.ModuleList([ 52 | nn.Conv2d(c1, int(c_), k, s, k // 2, groups=math.gcd(c1, int(c_)), bias=False) for k, c_ in zip(k, c_)]) 53 | self.bn = nn.BatchNorm2d(c2) 54 | self.act = nn.SiLU() 55 | 56 | def forward(self, x): 57 | return self.act(self.bn(torch.cat([m(x) for m in self.m], 1))) 58 | 59 | 60 | class Ensemble(nn.ModuleList): 61 | # Ensemble of models 62 | def __init__(self): 63 | super().__init__() 64 | 65 | def forward(self, x, augment=False, profile=False, visualize=False): 66 | y = [module(x, augment, profile, visualize)[0] for module in self] 67 | # y = torch.stack(y).max(0)[0] # max ensemble 68 | # y = torch.stack(y).mean(0) # mean ensemble 69 | y = torch.cat(y, 1) # nms ensemble 70 | return y, None # inference, train output 71 | 72 | 73 | def attempt_load(weights, device=None, inplace=True, fuse=True): 74 | # Loads an ensemble of models weights=[a,b,c] or a single model weights=[a] or weights=a 75 | from models.yolo import Detect, Model 76 | 77 | model = Ensemble() 78 | for w in weights if isinstance(weights, list) else [weights]: 79 | ckpt = torch.load(attempt_download(w), map_location='cpu') # load 80 | ckpt = (ckpt.get('ema') or ckpt['model']).to(device).float() # FP32 model 81 | 82 | # Model compatibility updates 83 | if not hasattr(ckpt, 'stride'): 84 | ckpt.stride = torch.tensor([32.]) 85 | if hasattr(ckpt, 'names') and isinstance(ckpt.names, (list, tuple)): 86 | ckpt.names = dict(enumerate(ckpt.names)) # convert to dict 87 | 88 | model.append(ckpt.fuse().eval() if fuse and hasattr(ckpt, 'fuse') else ckpt.eval()) # model in eval mode 89 | 90 | # Module compatibility updates 91 | for m in model.modules(): 92 | t = type(m) 93 | if t in (nn.Hardswish, nn.LeakyReLU, nn.ReLU, nn.ReLU6, nn.SiLU, Detect, Model): 94 | m.inplace = inplace # torch 1.7.0 compatibility 95 | if t is Detect and not isinstance(m.anchor_grid, list): 96 | delattr(m, 'anchor_grid') 97 | setattr(m, 'anchor_grid', [torch.zeros(1)] * m.nl) 98 | elif t is nn.Upsample and not hasattr(m, 'recompute_scale_factor'): 99 | m.recompute_scale_factor = None # torch 1.11.0 compatibility 100 | 101 | # Return model 102 | if len(model) == 1: 103 | return model[-1] 104 | 105 | # Return detection ensemble 106 | print(f'Ensemble created with {weights}\n') 107 | for k in 'names', 'nc', 'yaml': 108 | setattr(model, k, getattr(model[0], k)) 109 | model.stride = model[torch.argmax(torch.tensor([m.stride.max() for m in model])).int()].stride # max stride 110 | assert all(model[0].nc == m.nc for m in model), f'Models have different class counts: {[m.nc for m in model]}' 111 | return model 112 | -------------------------------------------------------------------------------- /yolov5/models/hub/anchors.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | # Default anchors for COCO data 3 | 4 | 5 | # P5 ------------------------------------------------------------------------------------------------------------------- 6 | # P5-640: 7 | anchors_p5_640: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | 13 | # P6 ------------------------------------------------------------------------------------------------------------------- 14 | # P6-640: thr=0.25: 0.9964 BPR, 5.54 anchors past thr, n=12, img_size=640, metric_all=0.281/0.716-mean/best, past_thr=0.469-mean: 9,11, 21,19, 17,41, 43,32, 39,70, 86,64, 65,131, 134,130, 120,265, 282,180, 247,354, 512,387 15 | anchors_p6_640: 16 | - [9,11, 21,19, 17,41] # P3/8 17 | - [43,32, 39,70, 86,64] # P4/16 18 | - [65,131, 134,130, 120,265] # P5/32 19 | - [282,180, 247,354, 512,387] # P6/64 20 | 21 | # P6-1280: thr=0.25: 0.9950 BPR, 5.55 anchors past thr, n=12, img_size=1280, metric_all=0.281/0.714-mean/best, past_thr=0.468-mean: 19,27, 44,40, 38,94, 96,68, 86,152, 180,137, 140,301, 303,264, 238,542, 436,615, 739,380, 925,792 22 | anchors_p6_1280: 23 | - [19,27, 44,40, 38,94] # P3/8 24 | - [96,68, 86,152, 180,137] # P4/16 25 | - [140,301, 303,264, 238,542] # P5/32 26 | - [436,615, 739,380, 925,792] # P6/64 27 | 28 | # P6-1920: thr=0.25: 0.9950 BPR, 5.55 anchors past thr, n=12, img_size=1920, metric_all=0.281/0.714-mean/best, past_thr=0.468-mean: 28,41, 67,59, 57,141, 144,103, 129,227, 270,205, 209,452, 455,396, 358,812, 653,922, 1109,570, 1387,1187 29 | anchors_p6_1920: 30 | - [28,41, 67,59, 57,141] # P3/8 31 | - [144,103, 129,227, 270,205] # P4/16 32 | - [209,452, 455,396, 358,812] # P5/32 33 | - [653,922, 1109,570, 1387,1187] # P6/64 34 | 35 | 36 | # P7 ------------------------------------------------------------------------------------------------------------------- 37 | # P7-640: thr=0.25: 0.9962 BPR, 6.76 anchors past thr, n=15, img_size=640, metric_all=0.275/0.733-mean/best, past_thr=0.466-mean: 11,11, 13,30, 29,20, 30,46, 61,38, 39,92, 78,80, 146,66, 79,163, 149,150, 321,143, 157,303, 257,402, 359,290, 524,372 38 | anchors_p7_640: 39 | - [11,11, 13,30, 29,20] # P3/8 40 | - [30,46, 61,38, 39,92] # P4/16 41 | - [78,80, 146,66, 79,163] # P5/32 42 | - [149,150, 321,143, 157,303] # P6/64 43 | - [257,402, 359,290, 524,372] # P7/128 44 | 45 | # P7-1280: thr=0.25: 0.9968 BPR, 6.71 anchors past thr, n=15, img_size=1280, metric_all=0.273/0.732-mean/best, past_thr=0.463-mean: 19,22, 54,36, 32,77, 70,83, 138,71, 75,173, 165,159, 148,334, 375,151, 334,317, 251,626, 499,474, 750,326, 534,814, 1079,818 46 | anchors_p7_1280: 47 | - [19,22, 54,36, 32,77] # P3/8 48 | - [70,83, 138,71, 75,173] # P4/16 49 | - [165,159, 148,334, 375,151] # P5/32 50 | - [334,317, 251,626, 499,474] # P6/64 51 | - [750,326, 534,814, 1079,818] # P7/128 52 | 53 | # P7-1920: thr=0.25: 0.9968 BPR, 6.71 anchors past thr, n=15, img_size=1920, metric_all=0.273/0.732-mean/best, past_thr=0.463-mean: 29,34, 81,55, 47,115, 105,124, 207,107, 113,259, 247,238, 222,500, 563,227, 501,476, 376,939, 749,711, 1126,489, 801,1222, 1618,1227 54 | anchors_p7_1920: 55 | - [29,34, 81,55, 47,115] # P3/8 56 | - [105,124, 207,107, 113,259] # P4/16 57 | - [247,238, 222,500, 563,227] # P5/32 58 | - [501,476, 376,939, 749,711] # P6/64 59 | - [1126,489, 801,1222, 1618,1227] # P7/128 60 | -------------------------------------------------------------------------------- /yolov5/models/hub/yolov3-spp.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.0 # model depth multiple 6 | width_multiple: 1.0 # layer channel multiple 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # darknet53 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [32, 3, 1]], # 0 16 | [-1, 1, Conv, [64, 3, 2]], # 1-P1/2 17 | [-1, 1, Bottleneck, [64]], 18 | [-1, 1, Conv, [128, 3, 2]], # 3-P2/4 19 | [-1, 2, Bottleneck, [128]], 20 | [-1, 1, Conv, [256, 3, 2]], # 5-P3/8 21 | [-1, 8, Bottleneck, [256]], 22 | [-1, 1, Conv, [512, 3, 2]], # 7-P4/16 23 | [-1, 8, Bottleneck, [512]], 24 | [-1, 1, Conv, [1024, 3, 2]], # 9-P5/32 25 | [-1, 4, Bottleneck, [1024]], # 10 26 | ] 27 | 28 | # YOLOv3-SPP head 29 | head: 30 | [[-1, 1, Bottleneck, [1024, False]], 31 | [-1, 1, SPP, [512, [5, 9, 13]]], 32 | [-1, 1, Conv, [1024, 3, 1]], 33 | [-1, 1, Conv, [512, 1, 1]], 34 | [-1, 1, Conv, [1024, 3, 1]], # 15 (P5/32-large) 35 | 36 | [-2, 1, Conv, [256, 1, 1]], 37 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 38 | [[-1, 8], 1, Concat, [1]], # cat backbone P4 39 | [-1, 1, Bottleneck, [512, False]], 40 | [-1, 1, Bottleneck, [512, False]], 41 | [-1, 1, Conv, [256, 1, 1]], 42 | [-1, 1, Conv, [512, 3, 1]], # 22 (P4/16-medium) 43 | 44 | [-2, 1, Conv, [128, 1, 1]], 45 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 46 | [[-1, 6], 1, Concat, [1]], # cat backbone P3 47 | [-1, 1, Bottleneck, [256, False]], 48 | [-1, 2, Bottleneck, [256, False]], # 27 (P3/8-small) 49 | 50 | [[27, 22, 15], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 51 | ] 52 | -------------------------------------------------------------------------------- /yolov5/models/hub/yolov3-tiny.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.0 # model depth multiple 6 | width_multiple: 1.0 # layer channel multiple 7 | anchors: 8 | - [10,14, 23,27, 37,58] # P4/16 9 | - [81,82, 135,169, 344,319] # P5/32 10 | 11 | # YOLOv3-tiny backbone 12 | backbone: 13 | # [from, number, module, args] 14 | [[-1, 1, Conv, [16, 3, 1]], # 0 15 | [-1, 1, nn.MaxPool2d, [2, 2, 0]], # 1-P1/2 16 | [-1, 1, Conv, [32, 3, 1]], 17 | [-1, 1, nn.MaxPool2d, [2, 2, 0]], # 3-P2/4 18 | [-1, 1, Conv, [64, 3, 1]], 19 | [-1, 1, nn.MaxPool2d, [2, 2, 0]], # 5-P3/8 20 | [-1, 1, Conv, [128, 3, 1]], 21 | [-1, 1, nn.MaxPool2d, [2, 2, 0]], # 7-P4/16 22 | [-1, 1, Conv, [256, 3, 1]], 23 | [-1, 1, nn.MaxPool2d, [2, 2, 0]], # 9-P5/32 24 | [-1, 1, Conv, [512, 3, 1]], 25 | [-1, 1, nn.ZeroPad2d, [[0, 1, 0, 1]]], # 11 26 | [-1, 1, nn.MaxPool2d, [2, 1, 0]], # 12 27 | ] 28 | 29 | # YOLOv3-tiny head 30 | head: 31 | [[-1, 1, Conv, [1024, 3, 1]], 32 | [-1, 1, Conv, [256, 1, 1]], 33 | [-1, 1, Conv, [512, 3, 1]], # 15 (P5/32-large) 34 | 35 | [-2, 1, Conv, [128, 1, 1]], 36 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 37 | [[-1, 8], 1, Concat, [1]], # cat backbone P4 38 | [-1, 1, Conv, [256, 3, 1]], # 19 (P4/16-medium) 39 | 40 | [[19, 15], 1, Detect, [nc, anchors]], # Detect(P4, P5) 41 | ] 42 | -------------------------------------------------------------------------------- /yolov5/models/hub/yolov3.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.0 # model depth multiple 6 | width_multiple: 1.0 # layer channel multiple 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # darknet53 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [32, 3, 1]], # 0 16 | [-1, 1, Conv, [64, 3, 2]], # 1-P1/2 17 | [-1, 1, Bottleneck, [64]], 18 | [-1, 1, Conv, [128, 3, 2]], # 3-P2/4 19 | [-1, 2, Bottleneck, [128]], 20 | [-1, 1, Conv, [256, 3, 2]], # 5-P3/8 21 | [-1, 8, Bottleneck, [256]], 22 | [-1, 1, Conv, [512, 3, 2]], # 7-P4/16 23 | [-1, 8, Bottleneck, [512]], 24 | [-1, 1, Conv, [1024, 3, 2]], # 9-P5/32 25 | [-1, 4, Bottleneck, [1024]], # 10 26 | ] 27 | 28 | # YOLOv3 head 29 | head: 30 | [[-1, 1, Bottleneck, [1024, False]], 31 | [-1, 1, Conv, [512, 1, 1]], 32 | [-1, 1, Conv, [1024, 3, 1]], 33 | [-1, 1, Conv, [512, 1, 1]], 34 | [-1, 1, Conv, [1024, 3, 1]], # 15 (P5/32-large) 35 | 36 | [-2, 1, Conv, [256, 1, 1]], 37 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 38 | [[-1, 8], 1, Concat, [1]], # cat backbone P4 39 | [-1, 1, Bottleneck, [512, False]], 40 | [-1, 1, Bottleneck, [512, False]], 41 | [-1, 1, Conv, [256, 1, 1]], 42 | [-1, 1, Conv, [512, 3, 1]], # 22 (P4/16-medium) 43 | 44 | [-2, 1, Conv, [128, 1, 1]], 45 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 46 | [[-1, 6], 1, Concat, [1]], # cat backbone P3 47 | [-1, 1, Bottleneck, [256, False]], 48 | [-1, 2, Bottleneck, [256, False]], # 27 (P3/8-small) 49 | 50 | [[27, 22, 15], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 51 | ] 52 | -------------------------------------------------------------------------------- /yolov5/models/hub/yolov5-bifpn.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.0 # model depth multiple 6 | width_multiple: 1.0 # layer channel multiple 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # YOLOv5 v6.0 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 16 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 17 | [-1, 3, C3, [128]], 18 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 19 | [-1, 6, C3, [256]], 20 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 21 | [-1, 9, C3, [512]], 22 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 23 | [-1, 3, C3, [1024]], 24 | [-1, 1, SPPF, [1024, 5]], # 9 25 | ] 26 | 27 | # YOLOv5 v6.0 BiFPN head 28 | head: 29 | [[-1, 1, Conv, [512, 1, 1]], 30 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 31 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 32 | [-1, 3, C3, [512, False]], # 13 33 | 34 | [-1, 1, Conv, [256, 1, 1]], 35 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 36 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 37 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 38 | 39 | [-1, 1, Conv, [256, 3, 2]], 40 | [[-1, 14, 6], 1, Concat, [1]], # cat P4 <--- BiFPN change 41 | [-1, 3, C3, [512, False]], # 20 (P4/16-medium) 42 | 43 | [-1, 1, Conv, [512, 3, 2]], 44 | [[-1, 10], 1, Concat, [1]], # cat head P5 45 | [-1, 3, C3, [1024, False]], # 23 (P5/32-large) 46 | 47 | [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 48 | ] 49 | -------------------------------------------------------------------------------- /yolov5/models/hub/yolov5-fpn.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.0 # model depth multiple 6 | width_multiple: 1.0 # layer channel multiple 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # YOLOv5 v6.0 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 16 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 17 | [-1, 3, C3, [128]], 18 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 19 | [-1, 6, C3, [256]], 20 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 21 | [-1, 9, C3, [512]], 22 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 23 | [-1, 3, C3, [1024]], 24 | [-1, 1, SPPF, [1024, 5]], # 9 25 | ] 26 | 27 | # YOLOv5 v6.0 FPN head 28 | head: 29 | [[-1, 3, C3, [1024, False]], # 10 (P5/32-large) 30 | 31 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 32 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 33 | [-1, 1, Conv, [512, 1, 1]], 34 | [-1, 3, C3, [512, False]], # 14 (P4/16-medium) 35 | 36 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 37 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 38 | [-1, 1, Conv, [256, 1, 1]], 39 | [-1, 3, C3, [256, False]], # 18 (P3/8-small) 40 | 41 | [[18, 14, 10], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 42 | ] 43 | -------------------------------------------------------------------------------- /yolov5/models/hub/yolov5-p2.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.0 # model depth multiple 6 | width_multiple: 1.0 # layer channel multiple 7 | anchors: 3 # AutoAnchor evolves 3 anchors per P output layer 8 | 9 | # YOLOv5 v6.0 backbone 10 | backbone: 11 | # [from, number, module, args] 12 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 13 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 14 | [-1, 3, C3, [128]], 15 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 16 | [-1, 6, C3, [256]], 17 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 18 | [-1, 9, C3, [512]], 19 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 20 | [-1, 3, C3, [1024]], 21 | [-1, 1, SPPF, [1024, 5]], # 9 22 | ] 23 | 24 | # YOLOv5 v6.0 head with (P2, P3, P4, P5) outputs 25 | head: 26 | [[-1, 1, Conv, [512, 1, 1]], 27 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 28 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 29 | [-1, 3, C3, [512, False]], # 13 30 | 31 | [-1, 1, Conv, [256, 1, 1]], 32 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 33 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 34 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 35 | 36 | [-1, 1, Conv, [128, 1, 1]], 37 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 38 | [[-1, 2], 1, Concat, [1]], # cat backbone P2 39 | [-1, 1, C3, [128, False]], # 21 (P2/4-xsmall) 40 | 41 | [-1, 1, Conv, [128, 3, 2]], 42 | [[-1, 18], 1, Concat, [1]], # cat head P3 43 | [-1, 3, C3, [256, False]], # 24 (P3/8-small) 44 | 45 | [-1, 1, Conv, [256, 3, 2]], 46 | [[-1, 14], 1, Concat, [1]], # cat head P4 47 | [-1, 3, C3, [512, False]], # 27 (P4/16-medium) 48 | 49 | [-1, 1, Conv, [512, 3, 2]], 50 | [[-1, 10], 1, Concat, [1]], # cat head P5 51 | [-1, 3, C3, [1024, False]], # 30 (P5/32-large) 52 | 53 | [[21, 24, 27, 30], 1, Detect, [nc, anchors]], # Detect(P2, P3, P4, P5) 54 | ] 55 | -------------------------------------------------------------------------------- /yolov5/models/hub/yolov5-p34.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.33 # model depth multiple 6 | width_multiple: 0.50 # layer channel multiple 7 | anchors: 3 # AutoAnchor evolves 3 anchors per P output layer 8 | 9 | # YOLOv5 v6.0 backbone 10 | backbone: 11 | # [from, number, module, args] 12 | [ [ -1, 1, Conv, [ 64, 6, 2, 2 ] ], # 0-P1/2 13 | [ -1, 1, Conv, [ 128, 3, 2 ] ], # 1-P2/4 14 | [ -1, 3, C3, [ 128 ] ], 15 | [ -1, 1, Conv, [ 256, 3, 2 ] ], # 3-P3/8 16 | [ -1, 6, C3, [ 256 ] ], 17 | [ -1, 1, Conv, [ 512, 3, 2 ] ], # 5-P4/16 18 | [ -1, 9, C3, [ 512 ] ], 19 | [ -1, 1, Conv, [ 1024, 3, 2 ] ], # 7-P5/32 20 | [ -1, 3, C3, [ 1024 ] ], 21 | [ -1, 1, SPPF, [ 1024, 5 ] ], # 9 22 | ] 23 | 24 | # YOLOv5 v6.0 head with (P3, P4) outputs 25 | head: 26 | [ [ -1, 1, Conv, [ 512, 1, 1 ] ], 27 | [ -1, 1, nn.Upsample, [ None, 2, 'nearest' ] ], 28 | [ [ -1, 6 ], 1, Concat, [ 1 ] ], # cat backbone P4 29 | [ -1, 3, C3, [ 512, False ] ], # 13 30 | 31 | [ -1, 1, Conv, [ 256, 1, 1 ] ], 32 | [ -1, 1, nn.Upsample, [ None, 2, 'nearest' ] ], 33 | [ [ -1, 4 ], 1, Concat, [ 1 ] ], # cat backbone P3 34 | [ -1, 3, C3, [ 256, False ] ], # 17 (P3/8-small) 35 | 36 | [ -1, 1, Conv, [ 256, 3, 2 ] ], 37 | [ [ -1, 14 ], 1, Concat, [ 1 ] ], # cat head P4 38 | [ -1, 3, C3, [ 512, False ] ], # 20 (P4/16-medium) 39 | 40 | [ [ 17, 20 ], 1, Detect, [ nc, anchors ] ], # Detect(P3, P4) 41 | ] 42 | -------------------------------------------------------------------------------- /yolov5/models/hub/yolov5-p6.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.0 # model depth multiple 6 | width_multiple: 1.0 # layer channel multiple 7 | anchors: 3 # AutoAnchor evolves 3 anchors per P output layer 8 | 9 | # YOLOv5 v6.0 backbone 10 | backbone: 11 | # [from, number, module, args] 12 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 13 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 14 | [-1, 3, C3, [128]], 15 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 16 | [-1, 6, C3, [256]], 17 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 18 | [-1, 9, C3, [512]], 19 | [-1, 1, Conv, [768, 3, 2]], # 7-P5/32 20 | [-1, 3, C3, [768]], 21 | [-1, 1, Conv, [1024, 3, 2]], # 9-P6/64 22 | [-1, 3, C3, [1024]], 23 | [-1, 1, SPPF, [1024, 5]], # 11 24 | ] 25 | 26 | # YOLOv5 v6.0 head with (P3, P4, P5, P6) outputs 27 | head: 28 | [[-1, 1, Conv, [768, 1, 1]], 29 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 30 | [[-1, 8], 1, Concat, [1]], # cat backbone P5 31 | [-1, 3, C3, [768, False]], # 15 32 | 33 | [-1, 1, Conv, [512, 1, 1]], 34 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 35 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 36 | [-1, 3, C3, [512, False]], # 19 37 | 38 | [-1, 1, Conv, [256, 1, 1]], 39 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 40 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 41 | [-1, 3, C3, [256, False]], # 23 (P3/8-small) 42 | 43 | [-1, 1, Conv, [256, 3, 2]], 44 | [[-1, 20], 1, Concat, [1]], # cat head P4 45 | [-1, 3, C3, [512, False]], # 26 (P4/16-medium) 46 | 47 | [-1, 1, Conv, [512, 3, 2]], 48 | [[-1, 16], 1, Concat, [1]], # cat head P5 49 | [-1, 3, C3, [768, False]], # 29 (P5/32-large) 50 | 51 | [-1, 1, Conv, [768, 3, 2]], 52 | [[-1, 12], 1, Concat, [1]], # cat head P6 53 | [-1, 3, C3, [1024, False]], # 32 (P6/64-xlarge) 54 | 55 | [[23, 26, 29, 32], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5, P6) 56 | ] 57 | -------------------------------------------------------------------------------- /yolov5/models/hub/yolov5-p7.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.0 # model depth multiple 6 | width_multiple: 1.0 # layer channel multiple 7 | anchors: 3 # AutoAnchor evolves 3 anchors per P output layer 8 | 9 | # YOLOv5 v6.0 backbone 10 | backbone: 11 | # [from, number, module, args] 12 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 13 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 14 | [-1, 3, C3, [128]], 15 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 16 | [-1, 6, C3, [256]], 17 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 18 | [-1, 9, C3, [512]], 19 | [-1, 1, Conv, [768, 3, 2]], # 7-P5/32 20 | [-1, 3, C3, [768]], 21 | [-1, 1, Conv, [1024, 3, 2]], # 9-P6/64 22 | [-1, 3, C3, [1024]], 23 | [-1, 1, Conv, [1280, 3, 2]], # 11-P7/128 24 | [-1, 3, C3, [1280]], 25 | [-1, 1, SPPF, [1280, 5]], # 13 26 | ] 27 | 28 | # YOLOv5 v6.0 head with (P3, P4, P5, P6, P7) outputs 29 | head: 30 | [[-1, 1, Conv, [1024, 1, 1]], 31 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 32 | [[-1, 10], 1, Concat, [1]], # cat backbone P6 33 | [-1, 3, C3, [1024, False]], # 17 34 | 35 | [-1, 1, Conv, [768, 1, 1]], 36 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 37 | [[-1, 8], 1, Concat, [1]], # cat backbone P5 38 | [-1, 3, C3, [768, False]], # 21 39 | 40 | [-1, 1, Conv, [512, 1, 1]], 41 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 42 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 43 | [-1, 3, C3, [512, False]], # 25 44 | 45 | [-1, 1, Conv, [256, 1, 1]], 46 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 47 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 48 | [-1, 3, C3, [256, False]], # 29 (P3/8-small) 49 | 50 | [-1, 1, Conv, [256, 3, 2]], 51 | [[-1, 26], 1, Concat, [1]], # cat head P4 52 | [-1, 3, C3, [512, False]], # 32 (P4/16-medium) 53 | 54 | [-1, 1, Conv, [512, 3, 2]], 55 | [[-1, 22], 1, Concat, [1]], # cat head P5 56 | [-1, 3, C3, [768, False]], # 35 (P5/32-large) 57 | 58 | [-1, 1, Conv, [768, 3, 2]], 59 | [[-1, 18], 1, Concat, [1]], # cat head P6 60 | [-1, 3, C3, [1024, False]], # 38 (P6/64-xlarge) 61 | 62 | [-1, 1, Conv, [1024, 3, 2]], 63 | [[-1, 14], 1, Concat, [1]], # cat head P7 64 | [-1, 3, C3, [1280, False]], # 41 (P7/128-xxlarge) 65 | 66 | [[29, 32, 35, 38, 41], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5, P6, P7) 67 | ] 68 | -------------------------------------------------------------------------------- /yolov5/models/hub/yolov5-panet.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.0 # model depth multiple 6 | width_multiple: 1.0 # layer channel multiple 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # YOLOv5 v6.0 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 16 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 17 | [-1, 3, C3, [128]], 18 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 19 | [-1, 6, C3, [256]], 20 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 21 | [-1, 9, C3, [512]], 22 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 23 | [-1, 3, C3, [1024]], 24 | [-1, 1, SPPF, [1024, 5]], # 9 25 | ] 26 | 27 | # YOLOv5 v6.0 PANet head 28 | head: 29 | [[-1, 1, Conv, [512, 1, 1]], 30 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 31 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 32 | [-1, 3, C3, [512, False]], # 13 33 | 34 | [-1, 1, Conv, [256, 1, 1]], 35 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 36 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 37 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 38 | 39 | [-1, 1, Conv, [256, 3, 2]], 40 | [[-1, 14], 1, Concat, [1]], # cat head P4 41 | [-1, 3, C3, [512, False]], # 20 (P4/16-medium) 42 | 43 | [-1, 1, Conv, [512, 3, 2]], 44 | [[-1, 10], 1, Concat, [1]], # cat head P5 45 | [-1, 3, C3, [1024, False]], # 23 (P5/32-large) 46 | 47 | [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 48 | ] 49 | -------------------------------------------------------------------------------- /yolov5/models/hub/yolov5l6.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.0 # model depth multiple 6 | width_multiple: 1.0 # layer channel multiple 7 | anchors: 8 | - [19,27, 44,40, 38,94] # P3/8 9 | - [96,68, 86,152, 180,137] # P4/16 10 | - [140,301, 303,264, 238,542] # P5/32 11 | - [436,615, 739,380, 925,792] # P6/64 12 | 13 | # YOLOv5 v6.0 backbone 14 | backbone: 15 | # [from, number, module, args] 16 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 17 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 18 | [-1, 3, C3, [128]], 19 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 20 | [-1, 6, C3, [256]], 21 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 22 | [-1, 9, C3, [512]], 23 | [-1, 1, Conv, [768, 3, 2]], # 7-P5/32 24 | [-1, 3, C3, [768]], 25 | [-1, 1, Conv, [1024, 3, 2]], # 9-P6/64 26 | [-1, 3, C3, [1024]], 27 | [-1, 1, SPPF, [1024, 5]], # 11 28 | ] 29 | 30 | # YOLOv5 v6.0 head 31 | head: 32 | [[-1, 1, Conv, [768, 1, 1]], 33 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 34 | [[-1, 8], 1, Concat, [1]], # cat backbone P5 35 | [-1, 3, C3, [768, False]], # 15 36 | 37 | [-1, 1, Conv, [512, 1, 1]], 38 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 39 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 40 | [-1, 3, C3, [512, False]], # 19 41 | 42 | [-1, 1, Conv, [256, 1, 1]], 43 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 44 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 45 | [-1, 3, C3, [256, False]], # 23 (P3/8-small) 46 | 47 | [-1, 1, Conv, [256, 3, 2]], 48 | [[-1, 20], 1, Concat, [1]], # cat head P4 49 | [-1, 3, C3, [512, False]], # 26 (P4/16-medium) 50 | 51 | [-1, 1, Conv, [512, 3, 2]], 52 | [[-1, 16], 1, Concat, [1]], # cat head P5 53 | [-1, 3, C3, [768, False]], # 29 (P5/32-large) 54 | 55 | [-1, 1, Conv, [768, 3, 2]], 56 | [[-1, 12], 1, Concat, [1]], # cat head P6 57 | [-1, 3, C3, [1024, False]], # 32 (P6/64-xlarge) 58 | 59 | [[23, 26, 29, 32], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5, P6) 60 | ] 61 | -------------------------------------------------------------------------------- /yolov5/models/hub/yolov5m6.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.67 # model depth multiple 6 | width_multiple: 0.75 # layer channel multiple 7 | anchors: 8 | - [19,27, 44,40, 38,94] # P3/8 9 | - [96,68, 86,152, 180,137] # P4/16 10 | - [140,301, 303,264, 238,542] # P5/32 11 | - [436,615, 739,380, 925,792] # P6/64 12 | 13 | # YOLOv5 v6.0 backbone 14 | backbone: 15 | # [from, number, module, args] 16 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 17 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 18 | [-1, 3, C3, [128]], 19 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 20 | [-1, 6, C3, [256]], 21 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 22 | [-1, 9, C3, [512]], 23 | [-1, 1, Conv, [768, 3, 2]], # 7-P5/32 24 | [-1, 3, C3, [768]], 25 | [-1, 1, Conv, [1024, 3, 2]], # 9-P6/64 26 | [-1, 3, C3, [1024]], 27 | [-1, 1, SPPF, [1024, 5]], # 11 28 | ] 29 | 30 | # YOLOv5 v6.0 head 31 | head: 32 | [[-1, 1, Conv, [768, 1, 1]], 33 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 34 | [[-1, 8], 1, Concat, [1]], # cat backbone P5 35 | [-1, 3, C3, [768, False]], # 15 36 | 37 | [-1, 1, Conv, [512, 1, 1]], 38 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 39 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 40 | [-1, 3, C3, [512, False]], # 19 41 | 42 | [-1, 1, Conv, [256, 1, 1]], 43 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 44 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 45 | [-1, 3, C3, [256, False]], # 23 (P3/8-small) 46 | 47 | [-1, 1, Conv, [256, 3, 2]], 48 | [[-1, 20], 1, Concat, [1]], # cat head P4 49 | [-1, 3, C3, [512, False]], # 26 (P4/16-medium) 50 | 51 | [-1, 1, Conv, [512, 3, 2]], 52 | [[-1, 16], 1, Concat, [1]], # cat head P5 53 | [-1, 3, C3, [768, False]], # 29 (P5/32-large) 54 | 55 | [-1, 1, Conv, [768, 3, 2]], 56 | [[-1, 12], 1, Concat, [1]], # cat head P6 57 | [-1, 3, C3, [1024, False]], # 32 (P6/64-xlarge) 58 | 59 | [[23, 26, 29, 32], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5, P6) 60 | ] 61 | -------------------------------------------------------------------------------- /yolov5/models/hub/yolov5n6.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.33 # model depth multiple 6 | width_multiple: 0.25 # layer channel multiple 7 | anchors: 8 | - [19,27, 44,40, 38,94] # P3/8 9 | - [96,68, 86,152, 180,137] # P4/16 10 | - [140,301, 303,264, 238,542] # P5/32 11 | - [436,615, 739,380, 925,792] # P6/64 12 | 13 | # YOLOv5 v6.0 backbone 14 | backbone: 15 | # [from, number, module, args] 16 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 17 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 18 | [-1, 3, C3, [128]], 19 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 20 | [-1, 6, C3, [256]], 21 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 22 | [-1, 9, C3, [512]], 23 | [-1, 1, Conv, [768, 3, 2]], # 7-P5/32 24 | [-1, 3, C3, [768]], 25 | [-1, 1, Conv, [1024, 3, 2]], # 9-P6/64 26 | [-1, 3, C3, [1024]], 27 | [-1, 1, SPPF, [1024, 5]], # 11 28 | ] 29 | 30 | # YOLOv5 v6.0 head 31 | head: 32 | [[-1, 1, Conv, [768, 1, 1]], 33 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 34 | [[-1, 8], 1, Concat, [1]], # cat backbone P5 35 | [-1, 3, C3, [768, False]], # 15 36 | 37 | [-1, 1, Conv, [512, 1, 1]], 38 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 39 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 40 | [-1, 3, C3, [512, False]], # 19 41 | 42 | [-1, 1, Conv, [256, 1, 1]], 43 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 44 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 45 | [-1, 3, C3, [256, False]], # 23 (P3/8-small) 46 | 47 | [-1, 1, Conv, [256, 3, 2]], 48 | [[-1, 20], 1, Concat, [1]], # cat head P4 49 | [-1, 3, C3, [512, False]], # 26 (P4/16-medium) 50 | 51 | [-1, 1, Conv, [512, 3, 2]], 52 | [[-1, 16], 1, Concat, [1]], # cat head P5 53 | [-1, 3, C3, [768, False]], # 29 (P5/32-large) 54 | 55 | [-1, 1, Conv, [768, 3, 2]], 56 | [[-1, 12], 1, Concat, [1]], # cat head P6 57 | [-1, 3, C3, [1024, False]], # 32 (P6/64-xlarge) 58 | 59 | [[23, 26, 29, 32], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5, P6) 60 | ] 61 | -------------------------------------------------------------------------------- /yolov5/models/hub/yolov5s-LeakyReLU.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | activation: nn.LeakyReLU(0.1) # <----- Conv() activation used throughout entire YOLOv5 model 6 | depth_multiple: 0.33 # model depth multiple 7 | width_multiple: 0.50 # layer channel multiple 8 | anchors: 9 | - [10,13, 16,30, 33,23] # P3/8 10 | - [30,61, 62,45, 59,119] # P4/16 11 | - [116,90, 156,198, 373,326] # P5/32 12 | 13 | # YOLOv5 v6.0 backbone 14 | backbone: 15 | # [from, number, module, args] 16 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 17 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 18 | [-1, 3, C3, [128]], 19 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 20 | [-1, 6, C3, [256]], 21 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 22 | [-1, 9, C3, [512]], 23 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 24 | [-1, 3, C3, [1024]], 25 | [-1, 1, SPPF, [1024, 5]], # 9 26 | ] 27 | 28 | # YOLOv5 v6.0 head 29 | head: 30 | [[-1, 1, Conv, [512, 1, 1]], 31 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 32 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 33 | [-1, 3, C3, [512, False]], # 13 34 | 35 | [-1, 1, Conv, [256, 1, 1]], 36 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 37 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 38 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 39 | 40 | [-1, 1, Conv, [256, 3, 2]], 41 | [[-1, 14], 1, Concat, [1]], # cat head P4 42 | [-1, 3, C3, [512, False]], # 20 (P4/16-medium) 43 | 44 | [-1, 1, Conv, [512, 3, 2]], 45 | [[-1, 10], 1, Concat, [1]], # cat head P5 46 | [-1, 3, C3, [1024, False]], # 23 (P5/32-large) 47 | 48 | [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 49 | ] 50 | -------------------------------------------------------------------------------- /yolov5/models/hub/yolov5s-ghost.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.33 # model depth multiple 6 | width_multiple: 0.50 # layer channel multiple 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # YOLOv5 v6.0 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 16 | [-1, 1, GhostConv, [128, 3, 2]], # 1-P2/4 17 | [-1, 3, C3Ghost, [128]], 18 | [-1, 1, GhostConv, [256, 3, 2]], # 3-P3/8 19 | [-1, 6, C3Ghost, [256]], 20 | [-1, 1, GhostConv, [512, 3, 2]], # 5-P4/16 21 | [-1, 9, C3Ghost, [512]], 22 | [-1, 1, GhostConv, [1024, 3, 2]], # 7-P5/32 23 | [-1, 3, C3Ghost, [1024]], 24 | [-1, 1, SPPF, [1024, 5]], # 9 25 | ] 26 | 27 | # YOLOv5 v6.0 head 28 | head: 29 | [[-1, 1, GhostConv, [512, 1, 1]], 30 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 31 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 32 | [-1, 3, C3Ghost, [512, False]], # 13 33 | 34 | [-1, 1, GhostConv, [256, 1, 1]], 35 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 36 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 37 | [-1, 3, C3Ghost, [256, False]], # 17 (P3/8-small) 38 | 39 | [-1, 1, GhostConv, [256, 3, 2]], 40 | [[-1, 14], 1, Concat, [1]], # cat head P4 41 | [-1, 3, C3Ghost, [512, False]], # 20 (P4/16-medium) 42 | 43 | [-1, 1, GhostConv, [512, 3, 2]], 44 | [[-1, 10], 1, Concat, [1]], # cat head P5 45 | [-1, 3, C3Ghost, [1024, False]], # 23 (P5/32-large) 46 | 47 | [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 48 | ] 49 | -------------------------------------------------------------------------------- /yolov5/models/hub/yolov5s-transformer.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.33 # model depth multiple 6 | width_multiple: 0.50 # layer channel multiple 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # YOLOv5 v6.0 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 16 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 17 | [-1, 3, C3, [128]], 18 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 19 | [-1, 6, C3, [256]], 20 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 21 | [-1, 9, C3, [512]], 22 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 23 | [-1, 3, C3TR, [1024]], # 9 <--- C3TR() Transformer module 24 | [-1, 1, SPPF, [1024, 5]], # 9 25 | ] 26 | 27 | # YOLOv5 v6.0 head 28 | head: 29 | [[-1, 1, Conv, [512, 1, 1]], 30 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 31 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 32 | [-1, 3, C3, [512, False]], # 13 33 | 34 | [-1, 1, Conv, [256, 1, 1]], 35 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 36 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 37 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 38 | 39 | [-1, 1, Conv, [256, 3, 2]], 40 | [[-1, 14], 1, Concat, [1]], # cat head P4 41 | [-1, 3, C3, [512, False]], # 20 (P4/16-medium) 42 | 43 | [-1, 1, Conv, [512, 3, 2]], 44 | [[-1, 10], 1, Concat, [1]], # cat head P5 45 | [-1, 3, C3, [1024, False]], # 23 (P5/32-large) 46 | 47 | [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 48 | ] 49 | -------------------------------------------------------------------------------- /yolov5/models/hub/yolov5s6.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.33 # model depth multiple 6 | width_multiple: 0.50 # layer channel multiple 7 | anchors: 8 | - [19,27, 44,40, 38,94] # P3/8 9 | - [96,68, 86,152, 180,137] # P4/16 10 | - [140,301, 303,264, 238,542] # P5/32 11 | - [436,615, 739,380, 925,792] # P6/64 12 | 13 | # YOLOv5 v6.0 backbone 14 | backbone: 15 | # [from, number, module, args] 16 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 17 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 18 | [-1, 3, C3, [128]], 19 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 20 | [-1, 6, C3, [256]], 21 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 22 | [-1, 9, C3, [512]], 23 | [-1, 1, Conv, [768, 3, 2]], # 7-P5/32 24 | [-1, 3, C3, [768]], 25 | [-1, 1, Conv, [1024, 3, 2]], # 9-P6/64 26 | [-1, 3, C3, [1024]], 27 | [-1, 1, SPPF, [1024, 5]], # 11 28 | ] 29 | 30 | # YOLOv5 v6.0 head 31 | head: 32 | [[-1, 1, Conv, [768, 1, 1]], 33 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 34 | [[-1, 8], 1, Concat, [1]], # cat backbone P5 35 | [-1, 3, C3, [768, False]], # 15 36 | 37 | [-1, 1, Conv, [512, 1, 1]], 38 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 39 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 40 | [-1, 3, C3, [512, False]], # 19 41 | 42 | [-1, 1, Conv, [256, 1, 1]], 43 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 44 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 45 | [-1, 3, C3, [256, False]], # 23 (P3/8-small) 46 | 47 | [-1, 1, Conv, [256, 3, 2]], 48 | [[-1, 20], 1, Concat, [1]], # cat head P4 49 | [-1, 3, C3, [512, False]], # 26 (P4/16-medium) 50 | 51 | [-1, 1, Conv, [512, 3, 2]], 52 | [[-1, 16], 1, Concat, [1]], # cat head P5 53 | [-1, 3, C3, [768, False]], # 29 (P5/32-large) 54 | 55 | [-1, 1, Conv, [768, 3, 2]], 56 | [[-1, 12], 1, Concat, [1]], # cat head P6 57 | [-1, 3, C3, [1024, False]], # 32 (P6/64-xlarge) 58 | 59 | [[23, 26, 29, 32], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5, P6) 60 | ] 61 | -------------------------------------------------------------------------------- /yolov5/models/hub/yolov5x6.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.33 # model depth multiple 6 | width_multiple: 1.25 # layer channel multiple 7 | anchors: 8 | - [19,27, 44,40, 38,94] # P3/8 9 | - [96,68, 86,152, 180,137] # P4/16 10 | - [140,301, 303,264, 238,542] # P5/32 11 | - [436,615, 739,380, 925,792] # P6/64 12 | 13 | # YOLOv5 v6.0 backbone 14 | backbone: 15 | # [from, number, module, args] 16 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 17 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 18 | [-1, 3, C3, [128]], 19 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 20 | [-1, 6, C3, [256]], 21 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 22 | [-1, 9, C3, [512]], 23 | [-1, 1, Conv, [768, 3, 2]], # 7-P5/32 24 | [-1, 3, C3, [768]], 25 | [-1, 1, Conv, [1024, 3, 2]], # 9-P6/64 26 | [-1, 3, C3, [1024]], 27 | [-1, 1, SPPF, [1024, 5]], # 11 28 | ] 29 | 30 | # YOLOv5 v6.0 head 31 | head: 32 | [[-1, 1, Conv, [768, 1, 1]], 33 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 34 | [[-1, 8], 1, Concat, [1]], # cat backbone P5 35 | [-1, 3, C3, [768, False]], # 15 36 | 37 | [-1, 1, Conv, [512, 1, 1]], 38 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 39 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 40 | [-1, 3, C3, [512, False]], # 19 41 | 42 | [-1, 1, Conv, [256, 1, 1]], 43 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 44 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 45 | [-1, 3, C3, [256, False]], # 23 (P3/8-small) 46 | 47 | [-1, 1, Conv, [256, 3, 2]], 48 | [[-1, 20], 1, Concat, [1]], # cat head P4 49 | [-1, 3, C3, [512, False]], # 26 (P4/16-medium) 50 | 51 | [-1, 1, Conv, [512, 3, 2]], 52 | [[-1, 16], 1, Concat, [1]], # cat head P5 53 | [-1, 3, C3, [768, False]], # 29 (P5/32-large) 54 | 55 | [-1, 1, Conv, [768, 3, 2]], 56 | [[-1, 12], 1, Concat, [1]], # cat head P6 57 | [-1, 3, C3, [1024, False]], # 32 (P6/64-xlarge) 58 | 59 | [[23, 26, 29, 32], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5, P6) 60 | ] 61 | -------------------------------------------------------------------------------- /yolov5/models/segment/yolov5l-seg.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.0 # model depth multiple 6 | width_multiple: 1.0 # layer channel multiple 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # YOLOv5 v6.0 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 16 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 17 | [-1, 3, C3, [128]], 18 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 19 | [-1, 6, C3, [256]], 20 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 21 | [-1, 9, C3, [512]], 22 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 23 | [-1, 3, C3, [1024]], 24 | [-1, 1, SPPF, [1024, 5]], # 9 25 | ] 26 | 27 | # YOLOv5 v6.0 head 28 | head: 29 | [[-1, 1, Conv, [512, 1, 1]], 30 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 31 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 32 | [-1, 3, C3, [512, False]], # 13 33 | 34 | [-1, 1, Conv, [256, 1, 1]], 35 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 36 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 37 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 38 | 39 | [-1, 1, Conv, [256, 3, 2]], 40 | [[-1, 14], 1, Concat, [1]], # cat head P4 41 | [-1, 3, C3, [512, False]], # 20 (P4/16-medium) 42 | 43 | [-1, 1, Conv, [512, 3, 2]], 44 | [[-1, 10], 1, Concat, [1]], # cat head P5 45 | [-1, 3, C3, [1024, False]], # 23 (P5/32-large) 46 | 47 | [[17, 20, 23], 1, Segment, [nc, anchors, 32, 256]], # Detect(P3, P4, P5) 48 | ] 49 | -------------------------------------------------------------------------------- /yolov5/models/segment/yolov5m-seg.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.67 # model depth multiple 6 | width_multiple: 0.75 # layer channel multiple 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # YOLOv5 v6.0 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 16 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 17 | [-1, 3, C3, [128]], 18 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 19 | [-1, 6, C3, [256]], 20 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 21 | [-1, 9, C3, [512]], 22 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 23 | [-1, 3, C3, [1024]], 24 | [-1, 1, SPPF, [1024, 5]], # 9 25 | ] 26 | 27 | # YOLOv5 v6.0 head 28 | head: 29 | [[-1, 1, Conv, [512, 1, 1]], 30 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 31 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 32 | [-1, 3, C3, [512, False]], # 13 33 | 34 | [-1, 1, Conv, [256, 1, 1]], 35 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 36 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 37 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 38 | 39 | [-1, 1, Conv, [256, 3, 2]], 40 | [[-1, 14], 1, Concat, [1]], # cat head P4 41 | [-1, 3, C3, [512, False]], # 20 (P4/16-medium) 42 | 43 | [-1, 1, Conv, [512, 3, 2]], 44 | [[-1, 10], 1, Concat, [1]], # cat head P5 45 | [-1, 3, C3, [1024, False]], # 23 (P5/32-large) 46 | 47 | [[17, 20, 23], 1, Segment, [nc, anchors, 32, 256]], # Detect(P3, P4, P5) 48 | ] 49 | -------------------------------------------------------------------------------- /yolov5/models/segment/yolov5n-seg.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.33 # model depth multiple 6 | width_multiple: 0.25 # layer channel multiple 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # YOLOv5 v6.0 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 16 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 17 | [-1, 3, C3, [128]], 18 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 19 | [-1, 6, C3, [256]], 20 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 21 | [-1, 9, C3, [512]], 22 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 23 | [-1, 3, C3, [1024]], 24 | [-1, 1, SPPF, [1024, 5]], # 9 25 | ] 26 | 27 | # YOLOv5 v6.0 head 28 | head: 29 | [[-1, 1, Conv, [512, 1, 1]], 30 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 31 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 32 | [-1, 3, C3, [512, False]], # 13 33 | 34 | [-1, 1, Conv, [256, 1, 1]], 35 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 36 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 37 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 38 | 39 | [-1, 1, Conv, [256, 3, 2]], 40 | [[-1, 14], 1, Concat, [1]], # cat head P4 41 | [-1, 3, C3, [512, False]], # 20 (P4/16-medium) 42 | 43 | [-1, 1, Conv, [512, 3, 2]], 44 | [[-1, 10], 1, Concat, [1]], # cat head P5 45 | [-1, 3, C3, [1024, False]], # 23 (P5/32-large) 46 | 47 | [[17, 20, 23], 1, Segment, [nc, anchors, 32, 256]], # Detect(P3, P4, P5) 48 | ] 49 | -------------------------------------------------------------------------------- /yolov5/models/segment/yolov5s-seg.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.33 # model depth multiple 6 | width_multiple: 0.5 # layer channel multiple 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # YOLOv5 v6.0 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 16 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 17 | [-1, 3, C3, [128]], 18 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 19 | [-1, 6, C3, [256]], 20 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 21 | [-1, 9, C3, [512]], 22 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 23 | [-1, 3, C3, [1024]], 24 | [-1, 1, SPPF, [1024, 5]], # 9 25 | ] 26 | 27 | # YOLOv5 v6.0 head 28 | head: 29 | [[-1, 1, Conv, [512, 1, 1]], 30 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 31 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 32 | [-1, 3, C3, [512, False]], # 13 33 | 34 | [-1, 1, Conv, [256, 1, 1]], 35 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 36 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 37 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 38 | 39 | [-1, 1, Conv, [256, 3, 2]], 40 | [[-1, 14], 1, Concat, [1]], # cat head P4 41 | [-1, 3, C3, [512, False]], # 20 (P4/16-medium) 42 | 43 | [-1, 1, Conv, [512, 3, 2]], 44 | [[-1, 10], 1, Concat, [1]], # cat head P5 45 | [-1, 3, C3, [1024, False]], # 23 (P5/32-large) 46 | 47 | [[17, 20, 23], 1, Segment, [nc, anchors, 32, 256]], # Detect(P3, P4, P5) 48 | ] 49 | -------------------------------------------------------------------------------- /yolov5/models/segment/yolov5x-seg.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.33 # model depth multiple 6 | width_multiple: 1.25 # layer channel multiple 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # YOLOv5 v6.0 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 16 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 17 | [-1, 3, C3, [128]], 18 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 19 | [-1, 6, C3, [256]], 20 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 21 | [-1, 9, C3, [512]], 22 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 23 | [-1, 3, C3, [1024]], 24 | [-1, 1, SPPF, [1024, 5]], # 9 25 | ] 26 | 27 | # YOLOv5 v6.0 head 28 | head: 29 | [[-1, 1, Conv, [512, 1, 1]], 30 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 31 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 32 | [-1, 3, C3, [512, False]], # 13 33 | 34 | [-1, 1, Conv, [256, 1, 1]], 35 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 36 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 37 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 38 | 39 | [-1, 1, Conv, [256, 3, 2]], 40 | [[-1, 14], 1, Concat, [1]], # cat head P4 41 | [-1, 3, C3, [512, False]], # 20 (P4/16-medium) 42 | 43 | [-1, 1, Conv, [512, 3, 2]], 44 | [[-1, 10], 1, Concat, [1]], # cat head P5 45 | [-1, 3, C3, [1024, False]], # 23 (P5/32-large) 46 | 47 | [[17, 20, 23], 1, Segment, [nc, anchors, 32, 256]], # Detect(P3, P4, P5) 48 | ] 49 | -------------------------------------------------------------------------------- /yolov5/models/yolov5l.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.0 # model depth multiple 6 | width_multiple: 1.0 # layer channel multiple 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # YOLOv5 v6.0 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 16 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 17 | [-1, 3, C3, [128]], 18 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 19 | [-1, 6, C3, [256]], 20 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 21 | [-1, 9, C3, [512]], 22 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 23 | [-1, 3, C3, [1024]], 24 | [-1, 1, SPPF, [1024, 5]], # 9 25 | ] 26 | 27 | # YOLOv5 v6.0 head 28 | head: 29 | [[-1, 1, Conv, [512, 1, 1]], 30 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 31 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 32 | [-1, 3, C3, [512, False]], # 13 33 | 34 | [-1, 1, Conv, [256, 1, 1]], 35 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 36 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 37 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 38 | 39 | [-1, 1, Conv, [256, 3, 2]], 40 | [[-1, 14], 1, Concat, [1]], # cat head P4 41 | [-1, 3, C3, [512, False]], # 20 (P4/16-medium) 42 | 43 | [-1, 1, Conv, [512, 3, 2]], 44 | [[-1, 10], 1, Concat, [1]], # cat head P5 45 | [-1, 3, C3, [1024, False]], # 23 (P5/32-large) 46 | 47 | [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 48 | ] 49 | -------------------------------------------------------------------------------- /yolov5/models/yolov5m.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.67 # model depth multiple 6 | width_multiple: 0.75 # layer channel multiple 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # YOLOv5 v6.0 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 16 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 17 | [-1, 3, C3, [128]], 18 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 19 | [-1, 6, C3, [256]], 20 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 21 | [-1, 9, C3, [512]], 22 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 23 | [-1, 3, C3, [1024]], 24 | [-1, 1, SPPF, [1024, 5]], # 9 25 | ] 26 | 27 | # YOLOv5 v6.0 head 28 | head: 29 | [[-1, 1, Conv, [512, 1, 1]], 30 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 31 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 32 | [-1, 3, C3, [512, False]], # 13 33 | 34 | [-1, 1, Conv, [256, 1, 1]], 35 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 36 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 37 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 38 | 39 | [-1, 1, Conv, [256, 3, 2]], 40 | [[-1, 14], 1, Concat, [1]], # cat head P4 41 | [-1, 3, C3, [512, False]], # 20 (P4/16-medium) 42 | 43 | [-1, 1, Conv, [512, 3, 2]], 44 | [[-1, 10], 1, Concat, [1]], # cat head P5 45 | [-1, 3, C3, [1024, False]], # 23 (P5/32-large) 46 | 47 | [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 48 | ] 49 | -------------------------------------------------------------------------------- /yolov5/models/yolov5n.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.33 # model depth multiple 6 | width_multiple: 0.25 # layer channel multiple 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # YOLOv5 v6.0 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 16 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 17 | [-1, 3, C3, [128]], 18 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 19 | [-1, 6, C3, [256]], 20 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 21 | [-1, 9, C3, [512]], 22 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 23 | [-1, 3, C3, [1024]], 24 | [-1, 1, SPPF, [1024, 5]], # 9 25 | ] 26 | 27 | # YOLOv5 v6.0 head 28 | head: 29 | [[-1, 1, Conv, [512, 1, 1]], 30 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 31 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 32 | [-1, 3, C3, [512, False]], # 13 33 | 34 | [-1, 1, Conv, [256, 1, 1]], 35 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 36 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 37 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 38 | 39 | [-1, 1, Conv, [256, 3, 2]], 40 | [[-1, 14], 1, Concat, [1]], # cat head P4 41 | [-1, 3, C3, [512, False]], # 20 (P4/16-medium) 42 | 43 | [-1, 1, Conv, [512, 3, 2]], 44 | [[-1, 10], 1, Concat, [1]], # cat head P5 45 | [-1, 3, C3, [1024, False]], # 23 (P5/32-large) 46 | 47 | [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 48 | ] 49 | -------------------------------------------------------------------------------- /yolov5/models/yolov5s.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 0.33 # model depth multiple 6 | width_multiple: 0.50 # layer channel multiple 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # YOLOv5 v6.0 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 16 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 17 | [-1, 3, C3, [128]], 18 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 19 | [-1, 6, C3, [256]], 20 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 21 | [-1, 9, C3, [512]], 22 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 23 | [-1, 3, C3, [1024]], 24 | [-1, 1, SPPF, [1024, 5]], # 9 25 | ] 26 | 27 | # YOLOv5 v6.0 head 28 | head: 29 | [[-1, 1, Conv, [512, 1, 1]], 30 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 31 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 32 | [-1, 3, C3, [512, False]], # 13 33 | 34 | [-1, 1, Conv, [256, 1, 1]], 35 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 36 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 37 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 38 | 39 | [-1, 1, Conv, [256, 3, 2]], 40 | [[-1, 14], 1, Concat, [1]], # cat head P4 41 | [-1, 3, C3, [512, False]], # 20 (P4/16-medium) 42 | 43 | [-1, 1, Conv, [512, 3, 2]], 44 | [[-1, 10], 1, Concat, [1]], # cat head P5 45 | [-1, 3, C3, [1024, False]], # 23 (P5/32-large) 46 | 47 | [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 48 | ] 49 | -------------------------------------------------------------------------------- /yolov5/models/yolov5x.yaml: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | 3 | # Parameters 4 | nc: 80 # number of classes 5 | depth_multiple: 1.33 # model depth multiple 6 | width_multiple: 1.25 # layer channel multiple 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # YOLOv5 v6.0 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2 16 | [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 17 | [-1, 3, C3, [128]], 18 | [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 19 | [-1, 6, C3, [256]], 20 | [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 21 | [-1, 9, C3, [512]], 22 | [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 23 | [-1, 3, C3, [1024]], 24 | [-1, 1, SPPF, [1024, 5]], # 9 25 | ] 26 | 27 | # YOLOv5 v6.0 head 28 | head: 29 | [[-1, 1, Conv, [512, 1, 1]], 30 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 31 | [[-1, 6], 1, Concat, [1]], # cat backbone P4 32 | [-1, 3, C3, [512, False]], # 13 33 | 34 | [-1, 1, Conv, [256, 1, 1]], 35 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 36 | [[-1, 4], 1, Concat, [1]], # cat backbone P3 37 | [-1, 3, C3, [256, False]], # 17 (P3/8-small) 38 | 39 | [-1, 1, Conv, [256, 3, 2]], 40 | [[-1, 14], 1, Concat, [1]], # cat head P4 41 | [-1, 3, C3, [512, False]], # 20 (P4/16-medium) 42 | 43 | [-1, 1, Conv, [512, 3, 2]], 44 | [[-1, 10], 1, Concat, [1]], # cat head P5 45 | [-1, 3, C3, [1024, False]], # 23 (P5/32-large) 46 | 47 | [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 48 | ] 49 | -------------------------------------------------------------------------------- /yolov5/segment/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fcakyon/yolov5-pip/40a188792bca82b8285549edb2c318b9d73bcd47/yolov5/segment/__init__.py -------------------------------------------------------------------------------- /yolov5/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | """ 3 | utils/initialization 4 | """ 5 | 6 | import contextlib 7 | import platform 8 | import threading 9 | 10 | 11 | def emojis(str=''): 12 | # Return platform-dependent emoji-safe version of string 13 | return str.encode().decode('ascii', 'ignore') if platform.system() == 'Windows' else str 14 | 15 | 16 | class TryExcept(contextlib.ContextDecorator): 17 | # YOLOv5 TryExcept class. Usage: @TryExcept() decorator or 'with TryExcept():' context manager 18 | def __init__(self, msg=''): 19 | self.msg = msg 20 | 21 | def __enter__(self): 22 | pass 23 | 24 | def __exit__(self, exc_type, value, traceback): 25 | if value: 26 | print(emojis(f"{self.msg}{': ' if self.msg else ''}{value}")) 27 | return True 28 | 29 | 30 | def threaded(func): 31 | # Multi-threads a target function and returns thread. Usage: @threaded decorator 32 | def wrapper(*args, **kwargs): 33 | thread = threading.Thread(target=func, args=args, kwargs=kwargs, daemon=True) 34 | thread.start() 35 | return thread 36 | 37 | return wrapper 38 | 39 | 40 | def join_threads(verbose=False): 41 | # Join all daemon threads, i.e. atexit.register(lambda: join_threads()) 42 | main_thread = threading.current_thread() 43 | for t in threading.enumerate(): 44 | if t is not main_thread: 45 | if verbose: 46 | print(f'Joining thread {t.name}') 47 | t.join() 48 | 49 | 50 | def notebook_init(verbose=True): 51 | # Check system software and hardware 52 | print('Checking setup...') 53 | 54 | import os 55 | import shutil 56 | 57 | from yolov5.utils.general import check_font, check_requirements, is_colab 58 | from yolov5.utils.torch_utils import select_device # imports 59 | 60 | check_font() 61 | 62 | import psutil 63 | 64 | if is_colab(): 65 | shutil.rmtree('/content/sample_data', ignore_errors=True) # remove colab /sample_data directory 66 | 67 | # System info 68 | display = None 69 | if verbose: 70 | gb = 1 << 30 # bytes to GiB (1024 ** 3) 71 | ram = psutil.virtual_memory().total 72 | total, used, free = shutil.disk_usage('/') 73 | with contextlib.suppress(Exception): # clear display if ipython is installed 74 | from IPython import display 75 | display.clear_output() 76 | s = f'({os.cpu_count()} CPUs, {ram / gb:.1f} GB RAM, {(total - free) / gb:.1f}/{total / gb:.1f} GB disk)' 77 | else: 78 | s = '' 79 | 80 | select_device(newline=False) 81 | print(emojis(f'Setup complete ✅ {s}')) 82 | return display 83 | -------------------------------------------------------------------------------- /yolov5/utils/activations.py: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | """ 3 | Activation functions 4 | """ 5 | 6 | import torch 7 | import torch.nn as nn 8 | import torch.nn.functional as F 9 | 10 | 11 | class SiLU(nn.Module): 12 | # SiLU activation https://arxiv.org/pdf/1606.08415.pdf 13 | @staticmethod 14 | def forward(x): 15 | return x * torch.sigmoid(x) 16 | 17 | 18 | class Hardswish(nn.Module): 19 | # Hard-SiLU activation 20 | @staticmethod 21 | def forward(x): 22 | # return x * F.hardsigmoid(x) # for TorchScript and CoreML 23 | return x * F.hardtanh(x + 3, 0.0, 6.0) / 6.0 # for TorchScript, CoreML and ONNX 24 | 25 | 26 | class Mish(nn.Module): 27 | # Mish activation https://github.com/digantamisra98/Mish 28 | @staticmethod 29 | def forward(x): 30 | return x * F.softplus(x).tanh() 31 | 32 | 33 | class MemoryEfficientMish(nn.Module): 34 | # Mish activation memory-efficient 35 | class F(torch.autograd.Function): 36 | 37 | @staticmethod 38 | def forward(ctx, x): 39 | ctx.save_for_backward(x) 40 | return x.mul(torch.tanh(F.softplus(x))) # x * tanh(ln(1 + exp(x))) 41 | 42 | @staticmethod 43 | def backward(ctx, grad_output): 44 | x = ctx.saved_tensors[0] 45 | sx = torch.sigmoid(x) 46 | fx = F.softplus(x).tanh() 47 | return grad_output * (fx + x * sx * (1 - fx * fx)) 48 | 49 | def forward(self, x): 50 | return self.F.apply(x) 51 | 52 | 53 | class FReLU(nn.Module): 54 | # FReLU activation https://arxiv.org/abs/2007.11824 55 | def __init__(self, c1, k=3): # ch_in, kernel 56 | super().__init__() 57 | self.conv = nn.Conv2d(c1, c1, k, 1, 1, groups=c1, bias=False) 58 | self.bn = nn.BatchNorm2d(c1) 59 | 60 | def forward(self, x): 61 | return torch.max(x, self.bn(self.conv(x))) 62 | 63 | 64 | class AconC(nn.Module): 65 | r""" ACON activation (activate or not) 66 | AconC: (p1*x-p2*x) * sigmoid(beta*(p1*x-p2*x)) + p2*x, beta is a learnable parameter 67 | according to "Activate or Not: Learning Customized Activation" . 68 | """ 69 | 70 | def __init__(self, c1): 71 | super().__init__() 72 | self.p1 = nn.Parameter(torch.randn(1, c1, 1, 1)) 73 | self.p2 = nn.Parameter(torch.randn(1, c1, 1, 1)) 74 | self.beta = nn.Parameter(torch.ones(1, c1, 1, 1)) 75 | 76 | def forward(self, x): 77 | dpx = (self.p1 - self.p2) * x 78 | return dpx * torch.sigmoid(self.beta * dpx) + self.p2 * x 79 | 80 | 81 | class MetaAconC(nn.Module): 82 | r""" ACON activation (activate or not) 83 | MetaAconC: (p1*x-p2*x) * sigmoid(beta*(p1*x-p2*x)) + p2*x, beta is generated by a small network 84 | according to "Activate or Not: Learning Customized Activation" . 85 | """ 86 | 87 | def __init__(self, c1, k=1, s=1, r=16): # ch_in, kernel, stride, r 88 | super().__init__() 89 | c2 = max(r, c1 // r) 90 | self.p1 = nn.Parameter(torch.randn(1, c1, 1, 1)) 91 | self.p2 = nn.Parameter(torch.randn(1, c1, 1, 1)) 92 | self.fc1 = nn.Conv2d(c1, c2, k, s, bias=True) 93 | self.fc2 = nn.Conv2d(c2, c1, k, s, bias=True) 94 | # self.bn1 = nn.BatchNorm2d(c2) 95 | # self.bn2 = nn.BatchNorm2d(c1) 96 | 97 | def forward(self, x): 98 | y = x.mean(dim=2, keepdims=True).mean(dim=3, keepdims=True) 99 | # batch-size 1 bug/instabilities https://github.com/ultralytics/yolov5/issues/2891 100 | # beta = torch.sigmoid(self.bn2(self.fc2(self.bn1(self.fc1(y))))) # bug/unstable 101 | beta = torch.sigmoid(self.fc2(self.fc1(y))) # bug patch BN layers removed 102 | dpx = (self.p1 - self.p2) * x 103 | return dpx * torch.sigmoid(beta * dpx) + self.p2 * x 104 | -------------------------------------------------------------------------------- /yolov5/utils/autoanchor.py: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | """ 3 | AutoAnchor utils 4 | """ 5 | 6 | import random 7 | 8 | import numpy as np 9 | import torch 10 | import yaml 11 | from tqdm import tqdm 12 | 13 | from yolov5.utils import TryExcept 14 | from yolov5.utils.general import LOGGER, TQDM_BAR_FORMAT, colorstr 15 | 16 | PREFIX = colorstr('AutoAnchor: ') 17 | 18 | 19 | def check_anchor_order(m): 20 | # Check anchor order against stride order for YOLOv5 Detect() module m, and correct if necessary 21 | a = m.anchors.prod(-1).mean(-1).view(-1) # mean anchor area per output layer 22 | da = a[-1] - a[0] # delta a 23 | ds = m.stride[-1] - m.stride[0] # delta s 24 | if da and (da.sign() != ds.sign()): # same order 25 | LOGGER.info(f'{PREFIX}Reversing anchor order') 26 | m.anchors[:] = m.anchors.flip(0) 27 | 28 | 29 | @TryExcept(f'{PREFIX}ERROR') 30 | def check_anchors(dataset, model, thr=4.0, imgsz=640): 31 | # Check anchor fit to data, recompute if necessary 32 | m = model.module.model[-1] if hasattr(model, 'module') else model.model[-1] # Detect() 33 | shapes = imgsz * dataset.shapes / dataset.shapes.max(1, keepdims=True) 34 | scale = np.random.uniform(0.9, 1.1, size=(shapes.shape[0], 1)) # augment scale 35 | wh = torch.tensor(np.concatenate([l[:, 3:5] * s for s, l in zip(shapes * scale, dataset.labels)])).float() # wh 36 | 37 | def metric(k): # compute metric 38 | r = wh[:, None] / k[None] 39 | x = torch.min(r, 1 / r).min(2)[0] # ratio metric 40 | best = x.max(1)[0] # best_x 41 | aat = (x > 1 / thr).float().sum(1).mean() # anchors above threshold 42 | bpr = (best > 1 / thr).float().mean() # best possible recall 43 | return bpr, aat 44 | 45 | stride = m.stride.to(m.anchors.device).view(-1, 1, 1) # model strides 46 | anchors = m.anchors.clone() * stride # current anchors 47 | bpr, aat = metric(anchors.cpu().view(-1, 2)) 48 | s = f'\n{PREFIX}{aat:.2f} anchors/target, {bpr:.3f} Best Possible Recall (BPR). ' 49 | if bpr > 0.98: # threshold to recompute 50 | LOGGER.info(f'{s}Current anchors are a good fit to dataset ✅') 51 | else: 52 | LOGGER.info(f'{s}Anchors are a poor fit to dataset ⚠️, attempting to improve...') 53 | na = m.anchors.numel() // 2 # number of anchors 54 | anchors = kmean_anchors(dataset, n=na, img_size=imgsz, thr=thr, gen=1000, verbose=False) 55 | new_bpr = metric(anchors)[0] 56 | if new_bpr > bpr: # replace anchors 57 | anchors = torch.tensor(anchors, device=m.anchors.device).type_as(m.anchors) 58 | m.anchors[:] = anchors.clone().view_as(m.anchors) 59 | check_anchor_order(m) # must be in pixel-space (not grid-space) 60 | m.anchors /= stride 61 | s = f'{PREFIX}Done ✅ (optional: update model *.yaml to use these anchors in the future)' 62 | else: 63 | s = f'{PREFIX}Done ⚠️ (original anchors better than new anchors, proceeding with original anchors)' 64 | LOGGER.info(s) 65 | 66 | 67 | def kmean_anchors(dataset='./data/coco128.yaml', n=9, img_size=640, thr=4.0, gen=1000, verbose=True): 68 | """ Creates kmeans-evolved anchors from training dataset 69 | 70 | Arguments: 71 | dataset: path to data.yaml, or a loaded dataset 72 | n: number of anchors 73 | img_size: image size used for training 74 | thr: anchor-label wh ratio threshold hyperparameter hyp['anchor_t'] used for training, default=4.0 75 | gen: generations to evolve anchors using genetic algorithm 76 | verbose: print all results 77 | 78 | Return: 79 | k: kmeans evolved anchors 80 | 81 | Usage: 82 | from yolov5.utils.autoanchor import *; _ = kmean_anchors() 83 | """ 84 | from scipy.cluster.vq import kmeans 85 | 86 | npr = np.random 87 | thr = 1 / thr 88 | 89 | def metric(k, wh): # compute metrics 90 | r = wh[:, None] / k[None] 91 | x = torch.min(r, 1 / r).min(2)[0] # ratio metric 92 | # x = wh_iou(wh, torch.tensor(k)) # iou metric 93 | return x, x.max(1)[0] # x, best_x 94 | 95 | def anchor_fitness(k): # mutation fitness 96 | _, best = metric(torch.tensor(k, dtype=torch.float32), wh) 97 | return (best * (best > thr).float()).mean() # fitness 98 | 99 | def print_results(k, verbose=True): 100 | k = k[np.argsort(k.prod(1))] # sort small to large 101 | x, best = metric(k, wh0) 102 | bpr, aat = (best > thr).float().mean(), (x > thr).float().mean() * n # best possible recall, anch > thr 103 | s = f'{PREFIX}thr={thr:.2f}: {bpr:.4f} best possible recall, {aat:.2f} anchors past thr\n' \ 104 | f'{PREFIX}n={n}, img_size={img_size}, metric_all={x.mean():.3f}/{best.mean():.3f}-mean/best, ' \ 105 | f'past_thr={x[x > thr].mean():.3f}-mean: ' 106 | for x in k: 107 | s += '%i,%i, ' % (round(x[0]), round(x[1])) 108 | if verbose: 109 | LOGGER.info(s[:-2]) 110 | return k 111 | 112 | if isinstance(dataset, str): # *.yaml file 113 | with open(dataset, errors='ignore') as f: 114 | data_dict = yaml.safe_load(f) # model dict 115 | from yolov5.utils.dataloaders import LoadImagesAndLabels 116 | dataset = LoadImagesAndLabels(data_dict['train'], augment=True, rect=True) 117 | 118 | # Get label wh 119 | shapes = img_size * dataset.shapes / dataset.shapes.max(1, keepdims=True) 120 | wh0 = np.concatenate([l[:, 3:5] * s for s, l in zip(shapes, dataset.labels)]) # wh 121 | 122 | # Filter 123 | i = (wh0 < 3.0).any(1).sum() 124 | if i: 125 | LOGGER.info(f'{PREFIX}WARNING ⚠️ Extremely small objects found: {i} of {len(wh0)} labels are <3 pixels in size') 126 | wh = wh0[(wh0 >= 2.0).any(1)].astype(np.float32) # filter > 2 pixels 127 | # wh = wh * (npr.rand(wh.shape[0], 1) * 0.9 + 0.1) # multiply by random scale 0-1 128 | 129 | # Kmeans init 130 | try: 131 | LOGGER.info(f'{PREFIX}Running kmeans for {n} anchors on {len(wh)} points...') 132 | assert n <= len(wh) # apply overdetermined constraint 133 | s = wh.std(0) # sigmas for whitening 134 | k = kmeans(wh / s, n, iter=30)[0] * s # points 135 | assert n == len(k) # kmeans may return fewer points than requested if wh is insufficient or too similar 136 | except Exception: 137 | LOGGER.warning(f'{PREFIX}WARNING ⚠️ switching strategies from kmeans to random init') 138 | k = np.sort(npr.rand(n * 2)).reshape(n, 2) * img_size # random init 139 | wh, wh0 = (torch.tensor(x, dtype=torch.float32) for x in (wh, wh0)) 140 | k = print_results(k, verbose=False) 141 | 142 | # Plot 143 | # k, d = [None] * 20, [None] * 20 144 | # for i in tqdm(range(1, 21)): 145 | # k[i-1], d[i-1] = kmeans(wh / s, i) # points, mean distance 146 | # fig, ax = plt.subplots(1, 2, figsize=(14, 7), tight_layout=True) 147 | # ax = ax.ravel() 148 | # ax[0].plot(np.arange(1, 21), np.array(d) ** 2, marker='.') 149 | # fig, ax = plt.subplots(1, 2, figsize=(14, 7)) # plot wh 150 | # ax[0].hist(wh[wh[:, 0]<100, 0],400) 151 | # ax[1].hist(wh[wh[:, 1]<100, 1],400) 152 | # fig.savefig('wh.png', dpi=200) 153 | 154 | # Evolve 155 | f, sh, mp, s = anchor_fitness(k), k.shape, 0.9, 0.1 # fitness, generations, mutation prob, sigma 156 | pbar = tqdm(range(gen), bar_format=TQDM_BAR_FORMAT) # progress bar 157 | for _ in pbar: 158 | v = np.ones(sh) 159 | while (v == 1).all(): # mutate until a change occurs (prevent duplicates) 160 | v = ((npr.random(sh) < mp) * random.random() * npr.randn(*sh) * s + 1).clip(0.3, 3.0) 161 | kg = (k.copy() * v).clip(min=2.0) 162 | fg = anchor_fitness(kg) 163 | if fg > f: 164 | f, k = fg, kg.copy() 165 | pbar.desc = f'{PREFIX}Evolving anchors with Genetic Algorithm: fitness = {f:.4f}' 166 | if verbose: 167 | print_results(k, verbose) 168 | 169 | return print_results(k).astype(np.float32) 170 | -------------------------------------------------------------------------------- /yolov5/utils/autobatch.py: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | """ 3 | Auto-batch utils 4 | """ 5 | 6 | from copy import deepcopy 7 | 8 | import numpy as np 9 | import torch 10 | 11 | from yolov5.utils.general import LOGGER, colorstr 12 | from yolov5.utils.torch_utils import profile 13 | 14 | 15 | def check_train_batch_size(model, imgsz=640, amp=True): 16 | # Check YOLOv5 training batch size 17 | with torch.cuda.amp.autocast(amp): 18 | return autobatch(deepcopy(model).train(), imgsz) # compute optimal batch size 19 | 20 | 21 | def autobatch(model, imgsz=640, fraction=0.8, batch_size=16): 22 | # Automatically estimate best YOLOv5 batch size to use `fraction` of available CUDA memory 23 | # Usage: 24 | # import torch 25 | # from yolov5.utils.autobatch import autobatch 26 | # model = torch.hub.load('ultralytics/yolov5', 'yolov5s', autoshape=False) 27 | # print(autobatch(model)) 28 | 29 | # Check device 30 | prefix = colorstr('AutoBatch: ') 31 | LOGGER.info(f'{prefix}Computing optimal batch size for --imgsz {imgsz}') 32 | device = next(model.parameters()).device # get model device 33 | if device.type == 'cpu': 34 | LOGGER.info(f'{prefix}CUDA not detected, using default CPU batch-size {batch_size}') 35 | return batch_size 36 | if torch.backends.cudnn.benchmark: 37 | LOGGER.info(f'{prefix} ⚠️ Requires torch.backends.cudnn.benchmark=False, using default batch-size {batch_size}') 38 | return batch_size 39 | 40 | # Inspect CUDA memory 41 | gb = 1 << 30 # bytes to GiB (1024 ** 3) 42 | d = str(device).upper() # 'CUDA:0' 43 | properties = torch.cuda.get_device_properties(device) # device properties 44 | t = properties.total_memory / gb # GiB total 45 | r = torch.cuda.memory_reserved(device) / gb # GiB reserved 46 | a = torch.cuda.memory_allocated(device) / gb # GiB allocated 47 | f = t - (r + a) # GiB free 48 | LOGGER.info(f'{prefix}{d} ({properties.name}) {t:.2f}G total, {r:.2f}G reserved, {a:.2f}G allocated, {f:.2f}G free') 49 | 50 | # Profile batch sizes 51 | batch_sizes = [1, 2, 4, 8, 16] 52 | try: 53 | img = [torch.empty(b, 3, imgsz, imgsz) for b in batch_sizes] 54 | results = profile(img, model, n=3, device=device) 55 | except Exception as e: 56 | LOGGER.warning(f'{prefix}{e}') 57 | 58 | # Fit a solution 59 | y = [x[2] for x in results if x] # memory [2] 60 | p = np.polyfit(batch_sizes[:len(y)], y, deg=1) # first degree polynomial fit 61 | b = int((f * fraction - p[1]) / p[0]) # y intercept (optimal batch size) 62 | if None in results: # some sizes failed 63 | i = results.index(None) # first fail index 64 | if b >= batch_sizes[i]: # y intercept above failure point 65 | b = batch_sizes[max(i - 1, 0)] # select prior safe point 66 | if b < 1 or b > 1024: # b outside of safe range 67 | b = batch_size 68 | LOGGER.warning(f'{prefix}WARNING ⚠️ CUDA anomaly detected, recommend restart environment and retry command.') 69 | 70 | fraction = (np.polyval(p, b) + r + a) / t # actual fraction predicted 71 | LOGGER.info(f'{prefix}Using batch-size {b} for {d} {t * fraction:.2f}G/{t:.2f}G ({fraction * 100:.0f}%) ✅') 72 | return b 73 | -------------------------------------------------------------------------------- /yolov5/utils/aws.py: -------------------------------------------------------------------------------- 1 | import concurrent.futures 2 | import logging 3 | import os 4 | from pathlib import Path 5 | 6 | import boto3 7 | import numpy as np 8 | from botocore.exceptions import NoCredentialsError 9 | from tqdm import tqdm 10 | 11 | from yolov5.utils.general import colorstr 12 | 13 | AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID") 14 | AWS_SECRET_ACCESS_KEY = os.environ.get("AWS_SECRET_ACCESS_KEY") 15 | 16 | LOGGER = logging.getLogger(__name__) 17 | 18 | 19 | def parse_s3_uri(s3_uri): 20 | # strip 's3://' 21 | if s3_uri.startswith("s3://"): 22 | s3_uri = s3_uri[5:] 23 | # parse bucket and key 24 | s3_components = s3_uri.split("/") 25 | bucket = s3_components[0] 26 | s3_key = "" 27 | if len(s3_components) > 1: 28 | s3_key = "/".join(s3_components[1:]) 29 | return bucket, s3_key 30 | 31 | def upload_file_to_s3(local_file, s3_file): 32 | s3 = boto3.client('s3', aws_access_key_id=AWS_ACCESS_KEY_ID, 33 | aws_secret_access_key=AWS_SECRET_ACCESS_KEY) 34 | # parse s3 uri 35 | bucket, s3_key = parse_s3_uri(s3_file) 36 | # upload to s3 37 | try: 38 | s3.upload_file(local_file, bucket, s3_key) 39 | return True 40 | except FileNotFoundError: 41 | print(f"{colorstr('aws:')} S3 upload failed because local file not found: {local_file}") 42 | return False 43 | except NoCredentialsError: 44 | print(f"{colorstr('aws:')} AWS credentials are not set. Please configure aws via CLI or set required ENV variables.") 45 | return False 46 | 47 | def upload_single_file(client, bucket, local_path, s3_path): 48 | try: 49 | client.head_object(Bucket=bucket, Key=s3_path) 50 | return 1 51 | except: 52 | #print("Uploading %s..." % s3_path) 53 | client.upload_file(local_path, bucket, s3_path) 54 | return 0 55 | 56 | def upload_folder_to_s3(local_folder, s3_folder): 57 | client = boto3.client('s3', aws_access_key_id=AWS_ACCESS_KEY_ID, 58 | aws_secret_access_key=AWS_SECRET_ACCESS_KEY) 59 | # parse s3 uri 60 | bucket, s3_key = parse_s3_uri(s3_folder) 61 | # enumerate local files recursively 62 | client_list = [] 63 | bucket_list = [] 64 | local_path_list = [] 65 | s3_path_list = [] 66 | for root, dirs, files in os.walk(local_folder): 67 | for filename in files: 68 | # construct the full local path 69 | local_path = os.path.join(root, filename) 70 | 71 | # construct the full path 72 | s3_path = s3_key 73 | relative_path = os.path.relpath(local_path, local_folder) 74 | s3_path = os.path.join(s3_path, relative_path) 75 | 76 | # append 77 | client_list.append(client) 78 | bucket_list.append(bucket) 79 | local_path_list.append(local_path) 80 | s3_path_list.append(s3_path) 81 | 82 | with concurrent.futures.ThreadPoolExecutor(max_workers=10) as conc_exec: 83 | already_exist_list = list(tqdm( 84 | conc_exec.map(upload_single_file, client_list, bucket_list, local_path_list, s3_path_list), 85 | total=len(s3_path_list), 86 | desc=f"{colorstr('aws:')} Uploading dataset to S3" 87 | ) 88 | ) 89 | num_already_exist = np.sum(np.array(already_exist_list)) 90 | if num_already_exist > 0: 91 | LOGGER.warning(f"{colorstr('aws:')} Skipped {num_already_exist} items since they already exists.") 92 | -------------------------------------------------------------------------------- /yolov5/utils/callbacks.py: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | """ 3 | Callback utils 4 | """ 5 | 6 | import threading 7 | 8 | 9 | class Callbacks: 10 | """" 11 | Handles all registered callbacks for YOLOv5 Hooks 12 | """ 13 | 14 | def __init__(self): 15 | # Define the available callbacks 16 | self._callbacks = { 17 | 'on_pretrain_routine_start': [], 18 | 'on_pretrain_routine_end': [], 19 | 'on_train_start': [], 20 | 'on_train_epoch_start': [], 21 | 'on_train_batch_start': [], 22 | 'optimizer_step': [], 23 | 'on_before_zero_grad': [], 24 | 'on_train_batch_end': [], 25 | 'on_train_epoch_end': [], 26 | 'on_val_start': [], 27 | 'on_val_batch_start': [], 28 | 'on_val_image_end': [], 29 | 'on_val_batch_end': [], 30 | 'on_val_end': [], 31 | 'on_fit_epoch_end': [], # fit = train + val 32 | 'on_model_save': [], 33 | 'on_train_end': [], 34 | 'on_params_update': [], 35 | 'teardown': [],} 36 | self.stop_training = False # set True to interrupt training 37 | 38 | def register_action(self, hook, name='', callback=None): 39 | """ 40 | Register a new action to a callback hook 41 | 42 | Args: 43 | hook: The callback hook name to register the action to 44 | name: The name of the action for later reference 45 | callback: The callback to fire 46 | """ 47 | assert hook in self._callbacks, f"hook '{hook}' not found in callbacks {self._callbacks}" 48 | assert callable(callback), f"callback '{callback}' is not callable" 49 | self._callbacks[hook].append({'name': name, 'callback': callback}) 50 | 51 | def get_registered_actions(self, hook=None): 52 | """" 53 | Returns all the registered actions by callback hook 54 | 55 | Args: 56 | hook: The name of the hook to check, defaults to all 57 | """ 58 | return self._callbacks[hook] if hook else self._callbacks 59 | 60 | def run(self, hook, *args, thread=False, **kwargs): 61 | """ 62 | Loop through the registered actions and fire all callbacks on main thread 63 | 64 | Args: 65 | hook: The name of the hook to check, defaults to all 66 | args: Arguments to receive from YOLOv5 67 | thread: (boolean) Run callbacks in daemon thread 68 | kwargs: Keyword Arguments to receive from YOLOv5 69 | """ 70 | 71 | assert hook in self._callbacks, f"hook '{hook}' not found in callbacks {self._callbacks}" 72 | for logger in self._callbacks[hook]: 73 | if thread: 74 | threading.Thread(target=logger['callback'], args=args, kwargs=kwargs, daemon=True).start() 75 | else: 76 | logger['callback'](*args, **kwargs) 77 | -------------------------------------------------------------------------------- /yolov5/utils/downloads.py: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | """ 3 | Download utils 4 | """ 5 | 6 | import logging 7 | import os 8 | import subprocess 9 | import urllib 10 | from pathlib import Path 11 | 12 | import requests 13 | import torch 14 | 15 | 16 | def is_url(url, check=True): 17 | # Check if string is URL and check if URL exists 18 | try: 19 | url = str(url) 20 | result = urllib.parse.urlparse(url) 21 | assert all([result.scheme, result.netloc]) # check if is url 22 | return (urllib.request.urlopen(url).getcode() == 200) if check else True # check if exists online 23 | except (AssertionError, urllib.request.HTTPError): 24 | return False 25 | 26 | 27 | def gsutil_getsize(url=''): 28 | # gs://bucket/file size https://cloud.google.com/storage/docs/gsutil/commands/du 29 | output = subprocess.check_output(['gsutil', 'du', url], shell=True, encoding='utf-8') 30 | if output: 31 | return int(output.split()[0]) 32 | return 0 33 | 34 | 35 | def url_getsize(url='https://ultralytics.com/images/bus.jpg'): 36 | # Return downloadable file size in bytes 37 | response = requests.head(url, allow_redirects=True) 38 | return int(response.headers.get('content-length', -1)) 39 | 40 | 41 | def curl_download(url, filename, *, silent: bool = False) -> bool: 42 | """ 43 | Download a file from a url to a filename using curl. 44 | """ 45 | silent_option = 'sS' if silent else '' # silent 46 | proc = subprocess.run([ 47 | 'curl', 48 | '-#', 49 | f'-{silent_option}L', 50 | url, 51 | '--output', 52 | filename, 53 | '--retry', 54 | '9', 55 | '-C', 56 | '-',]) 57 | return proc.returncode == 0 58 | 59 | 60 | def safe_download(file, url, url2=None, min_bytes=1E0, error_msg=''): 61 | # Attempts to download file from url or url2, checks and removes incomplete downloads < min_bytes 62 | from yolov5.utils.general import LOGGER 63 | 64 | file = Path(file) 65 | assert_msg = f"Downloaded file '{file}' does not exist or size is < min_bytes={min_bytes}" 66 | try: # url1 67 | LOGGER.info(f'Downloading {url} to {file}...') 68 | torch.hub.download_url_to_file(url, str(file), progress=LOGGER.level <= logging.INFO) 69 | assert file.exists() and file.stat().st_size > min_bytes, assert_msg # check 70 | except Exception as e: # url2 71 | if file.exists(): 72 | file.unlink() # remove partial downloads 73 | LOGGER.info(f'ERROR: {e}\nRe-attempting {url2 or url} to {file}...') 74 | # curl download, retry and resume on fail 75 | curl_download(url2 or url, file) 76 | finally: 77 | if not file.exists() or file.stat().st_size < min_bytes: # check 78 | if file.exists(): 79 | file.unlink() # remove partial downloads 80 | LOGGER.info(f'ERROR: {assert_msg}\n{error_msg}') 81 | LOGGER.info('') 82 | 83 | 84 | def attempt_download(file, repo='ultralytics/yolov5', release='v7.0', hf_token=None): 85 | # Attempt file download from GitHub release assets if not found locally. release = 'latest', 'v7.0', etc. 86 | from yolov5.utils.general import LOGGER 87 | 88 | def github_assets(repository, version='latest'): 89 | # Return GitHub repo tag (i.e. 'v7.0') and assets (i.e. ['yolov5s.pt', 'yolov5m.pt', ...]) 90 | if version != 'latest': 91 | version = f'tags/{version}' # i.e. tags/v7.0 92 | response = requests.get(f'https://api.github.com/repos/{repository}/releases/{version}').json() # github api 93 | return response['tag_name'], [x['name'] for x in response['assets']] # tag, assets 94 | 95 | # try to download from hf hub 96 | result = attempt_download_from_hub(file, hf_token=hf_token) 97 | if result is not None: 98 | file = result 99 | 100 | file = Path(str(file).strip().replace("'", '')) 101 | if not file.exists(): 102 | # URL specified 103 | name = Path(urllib.parse.unquote(str(file))).name # decode '%2F' to '/' etc. 104 | if str(file).startswith(('http:/', 'https:/')): # download 105 | url = str(file).replace(':/', '://') # Pathlib turns :// -> :/ 106 | file = name.split('?')[0] # parse authentication https://url.com/file.txt?auth... 107 | if Path(file).is_file(): 108 | LOGGER.info(f'Found {url} locally at {file}') # file already exists 109 | else: 110 | safe_download(file=file, url=url, min_bytes=1E5) 111 | return file 112 | 113 | # GitHub assets 114 | assets = [f'yolov5{size}{suffix}.pt' for size in 'nsmlx' for suffix in ('', '6', '-cls', '-seg')] # default 115 | try: 116 | tag, assets = github_assets(repo, release) 117 | except Exception: 118 | try: 119 | tag, assets = github_assets(repo) # latest release 120 | except Exception: 121 | try: 122 | tag = subprocess.check_output('git tag', shell=True, stderr=subprocess.STDOUT).decode().split()[-1] 123 | except Exception: 124 | tag = release 125 | 126 | if name in assets: 127 | file.parent.mkdir(parents=True, exist_ok=True) # make parent dir (if required) 128 | safe_download(file, 129 | url=f'https://github.com/{repo}/releases/download/{tag}/{name}', 130 | min_bytes=1E5, 131 | error_msg=f'{file} missing, try downloading from https://github.com/{repo}/releases/{tag}') 132 | 133 | return str(file) 134 | 135 | def get_model_filename_from_hfhub(repo_id, hf_token=None): 136 | from huggingface_hub import list_repo_files 137 | from huggingface_hub.utils._errors import RepositoryNotFoundError 138 | from huggingface_hub.utils._validators import HFValidationError 139 | 140 | try: 141 | repo_files = list_repo_files(repo_id=repo_id, repo_type='model', token=hf_token) 142 | model_filename = [f for f in repo_files if f.endswith('.pt')][0] 143 | return model_filename 144 | except (RepositoryNotFoundError, HFValidationError): 145 | return None 146 | 147 | 148 | def attempt_download_from_hub(repo_id, hf_token=None, revision=None): 149 | from huggingface_hub import hf_hub_download, list_repo_files 150 | from huggingface_hub.utils._errors import RepositoryNotFoundError 151 | from huggingface_hub.utils._validators import HFValidationError 152 | 153 | try: 154 | repo_files = list_repo_files(repo_id=repo_id, repo_type='model', token=hf_token) 155 | 156 | # download config file for triggering download counter 157 | config_file = 'config.json' 158 | if config_file in repo_files: 159 | _ = hf_hub_download( 160 | repo_id=repo_id, 161 | filename=config_file, 162 | repo_type='model', 163 | token=hf_token, 164 | revision=revision, 165 | ) 166 | 167 | # download model file 168 | model_file = [f for f in repo_files if f.endswith('.pt')][0] 169 | file = hf_hub_download( 170 | repo_id=repo_id, 171 | filename=model_file, 172 | repo_type='model', 173 | token=hf_token, 174 | revision=revision, 175 | ) 176 | return file 177 | except (RepositoryNotFoundError, HFValidationError): 178 | return None 179 | -------------------------------------------------------------------------------- /yolov5/utils/loggers/clearml/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fcakyon/yolov5-pip/40a188792bca82b8285549edb2c318b9d73bcd47/yolov5/utils/loggers/clearml/__init__.py -------------------------------------------------------------------------------- /yolov5/utils/loggers/clearml/hpo.py: -------------------------------------------------------------------------------- 1 | from clearml import Task 2 | # Connecting ClearML with the current process, 3 | # from here on everything is logged automatically 4 | from clearml.automation import HyperParameterOptimizer, UniformParameterRange 5 | from clearml.automation.optuna import OptimizerOptuna 6 | 7 | task = Task.init(project_name='Hyper-Parameter Optimization', 8 | task_name='YOLOv5', 9 | task_type=Task.TaskTypes.optimizer, 10 | reuse_last_task_id=False) 11 | 12 | # Example use case: 13 | optimizer = HyperParameterOptimizer( 14 | # This is the experiment we want to optimize 15 | base_task_id='', 16 | # here we define the hyper-parameters to optimize 17 | # Notice: The parameter name should exactly match what you see in the UI: / 18 | # For Example, here we see in the base experiment a section Named: "General" 19 | # under it a parameter named "batch_size", this becomes "General/batch_size" 20 | # If you have `argparse` for example, then arguments will appear under the "Args" section, 21 | # and you should instead pass "Args/batch_size" 22 | hyper_parameters=[ 23 | UniformParameterRange('Hyperparameters/lr0', min_value=1e-5, max_value=1e-1), 24 | UniformParameterRange('Hyperparameters/lrf', min_value=0.01, max_value=1.0), 25 | UniformParameterRange('Hyperparameters/momentum', min_value=0.6, max_value=0.98), 26 | UniformParameterRange('Hyperparameters/weight_decay', min_value=0.0, max_value=0.001), 27 | UniformParameterRange('Hyperparameters/warmup_epochs', min_value=0.0, max_value=5.0), 28 | UniformParameterRange('Hyperparameters/warmup_momentum', min_value=0.0, max_value=0.95), 29 | UniformParameterRange('Hyperparameters/warmup_bias_lr', min_value=0.0, max_value=0.2), 30 | UniformParameterRange('Hyperparameters/box', min_value=0.02, max_value=0.2), 31 | UniformParameterRange('Hyperparameters/cls', min_value=0.2, max_value=4.0), 32 | UniformParameterRange('Hyperparameters/cls_pw', min_value=0.5, max_value=2.0), 33 | UniformParameterRange('Hyperparameters/obj', min_value=0.2, max_value=4.0), 34 | UniformParameterRange('Hyperparameters/obj_pw', min_value=0.5, max_value=2.0), 35 | UniformParameterRange('Hyperparameters/iou_t', min_value=0.1, max_value=0.7), 36 | UniformParameterRange('Hyperparameters/anchor_t', min_value=2.0, max_value=8.0), 37 | UniformParameterRange('Hyperparameters/fl_gamma', min_value=0.0, max_value=4.0), 38 | UniformParameterRange('Hyperparameters/hsv_h', min_value=0.0, max_value=0.1), 39 | UniformParameterRange('Hyperparameters/hsv_s', min_value=0.0, max_value=0.9), 40 | UniformParameterRange('Hyperparameters/hsv_v', min_value=0.0, max_value=0.9), 41 | UniformParameterRange('Hyperparameters/degrees', min_value=0.0, max_value=45.0), 42 | UniformParameterRange('Hyperparameters/translate', min_value=0.0, max_value=0.9), 43 | UniformParameterRange('Hyperparameters/scale', min_value=0.0, max_value=0.9), 44 | UniformParameterRange('Hyperparameters/shear', min_value=0.0, max_value=10.0), 45 | UniformParameterRange('Hyperparameters/perspective', min_value=0.0, max_value=0.001), 46 | UniformParameterRange('Hyperparameters/flipud', min_value=0.0, max_value=1.0), 47 | UniformParameterRange('Hyperparameters/fliplr', min_value=0.0, max_value=1.0), 48 | UniformParameterRange('Hyperparameters/mosaic', min_value=0.0, max_value=1.0), 49 | UniformParameterRange('Hyperparameters/mixup', min_value=0.0, max_value=1.0), 50 | UniformParameterRange('Hyperparameters/copy_paste', min_value=0.0, max_value=1.0)], 51 | # this is the objective metric we want to maximize/minimize 52 | objective_metric_title='metrics', 53 | objective_metric_series='mAP_0.5', 54 | # now we decide if we want to maximize it or minimize it (accuracy we maximize) 55 | objective_metric_sign='max', 56 | # let us limit the number of concurrent experiments, 57 | # this in turn will make sure we do dont bombard the scheduler with experiments. 58 | # if we have an auto-scaler connected, this, by proxy, will limit the number of machine 59 | max_number_of_concurrent_tasks=1, 60 | # this is the optimizer class (actually doing the optimization) 61 | # Currently, we can choose from GridSearch, RandomSearch or OptimizerBOHB (Bayesian optimization Hyper-Band) 62 | optimizer_class=OptimizerOptuna, 63 | # If specified only the top K performing Tasks will be kept, the others will be automatically archived 64 | save_top_k_tasks_only=5, # 5, 65 | compute_time_limit=None, 66 | total_max_jobs=20, 67 | min_iteration_per_job=None, 68 | max_iteration_per_job=None, 69 | ) 70 | 71 | # report every 10 seconds, this is way too often, but we are testing here 72 | optimizer.set_report_period(10 / 60) 73 | # You can also use the line below instead to run all the optimizer tasks locally, without using queues or agent 74 | # an_optimizer.start_locally(job_complete_callback=job_complete_callback) 75 | # set the time limit for the optimization process (2 hours) 76 | optimizer.set_time_limit(in_minutes=120.0) 77 | # Start the optimization process in the local environment 78 | optimizer.start_locally() 79 | # wait until process is done (notice we are controlling the optimization process in the background) 80 | optimizer.wait() 81 | # make sure background optimization stopped 82 | optimizer.stop() 83 | 84 | print('We are done, good bye') 85 | -------------------------------------------------------------------------------- /yolov5/utils/loggers/comet/comet_utils.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from urllib.parse import urlparse 4 | 5 | try: 6 | import comet_ml 7 | except (ModuleNotFoundError, ImportError): 8 | comet_ml = None 9 | 10 | import yaml 11 | 12 | logger = logging.getLogger(__name__) 13 | 14 | COMET_PREFIX = "comet://" 15 | COMET_MODEL_NAME = os.getenv("COMET_MODEL_NAME", "yolov5") 16 | COMET_DEFAULT_CHECKPOINT_FILENAME = os.getenv("COMET_DEFAULT_CHECKPOINT_FILENAME", "last.pt") 17 | 18 | 19 | def download_model_checkpoint(opt, experiment): 20 | model_dir = f"{opt.project}/{experiment.name}" 21 | os.makedirs(model_dir, exist_ok=True) 22 | 23 | model_name = COMET_MODEL_NAME 24 | model_asset_list = experiment.get_model_asset_list(model_name) 25 | 26 | if len(model_asset_list) == 0: 27 | logger.error(f"COMET ERROR: No checkpoints found for model name : {model_name}") 28 | return 29 | 30 | model_asset_list = sorted( 31 | model_asset_list, 32 | key=lambda x: x["step"], 33 | reverse=True, 34 | ) 35 | logged_checkpoint_map = {asset["fileName"]: asset["assetId"] for asset in model_asset_list} 36 | 37 | resource_url = urlparse(opt.weights) 38 | checkpoint_filename = resource_url.query 39 | 40 | if checkpoint_filename: 41 | asset_id = logged_checkpoint_map.get(checkpoint_filename) 42 | else: 43 | asset_id = logged_checkpoint_map.get(COMET_DEFAULT_CHECKPOINT_FILENAME) 44 | checkpoint_filename = COMET_DEFAULT_CHECKPOINT_FILENAME 45 | 46 | if asset_id is None: 47 | logger.error(f"COMET ERROR: Checkpoint {checkpoint_filename} not found in the given Experiment") 48 | return 49 | 50 | try: 51 | logger.info(f"COMET INFO: Downloading checkpoint {checkpoint_filename}") 52 | asset_filename = checkpoint_filename 53 | 54 | model_binary = experiment.get_asset(asset_id, return_type="binary", stream=False) 55 | model_download_path = f"{model_dir}/{asset_filename}" 56 | with open(model_download_path, "wb") as f: 57 | f.write(model_binary) 58 | 59 | opt.weights = model_download_path 60 | 61 | except Exception as e: 62 | logger.warning("COMET WARNING: Unable to download checkpoint from Comet") 63 | logger.exception(e) 64 | 65 | 66 | def set_opt_parameters(opt, experiment): 67 | """Update the opts Namespace with parameters 68 | from Comet's ExistingExperiment when resuming a run 69 | 70 | Args: 71 | opt (argparse.Namespace): Namespace of command line options 72 | experiment (comet_ml.APIExperiment): Comet API Experiment object 73 | """ 74 | asset_list = experiment.get_asset_list() 75 | resume_string = opt.resume 76 | 77 | for asset in asset_list: 78 | if asset["fileName"] == "opt.yaml": 79 | asset_id = asset["assetId"] 80 | asset_binary = experiment.get_asset(asset_id, return_type="binary", stream=False) 81 | opt_dict = yaml.safe_load(asset_binary) 82 | for key, value in opt_dict.items(): 83 | setattr(opt, key, value) 84 | opt.resume = resume_string 85 | 86 | # Save hyperparameters to YAML file 87 | # Necessary to pass checks in training script 88 | save_dir = f"{opt.project}/{experiment.name}" 89 | os.makedirs(save_dir, exist_ok=True) 90 | 91 | hyp_yaml_path = f"{save_dir}/hyp.yaml" 92 | with open(hyp_yaml_path, "w") as f: 93 | yaml.dump(opt.hyp, f) 94 | opt.hyp = hyp_yaml_path 95 | 96 | 97 | def check_comet_weights(opt): 98 | """Downloads model weights from Comet and updates the 99 | weights path to point to saved weights location 100 | 101 | Args: 102 | opt (argparse.Namespace): Command Line arguments passed 103 | to YOLOv5 training script 104 | 105 | Returns: 106 | None/bool: Return True if weights are successfully downloaded 107 | else return None 108 | """ 109 | if comet_ml is None: 110 | return 111 | 112 | if isinstance(opt.weights, str): 113 | if opt.weights.startswith(COMET_PREFIX): 114 | api = comet_ml.API() 115 | resource = urlparse(opt.weights) 116 | experiment_path = f"{resource.netloc}{resource.path}" 117 | experiment = api.get(experiment_path) 118 | download_model_checkpoint(opt, experiment) 119 | return True 120 | 121 | return None 122 | 123 | 124 | def check_comet_resume(opt): 125 | """Restores run parameters to its original state based on the model checkpoint 126 | and logged Experiment parameters. 127 | 128 | Args: 129 | opt (argparse.Namespace): Command Line arguments passed 130 | to YOLOv5 training script 131 | 132 | Returns: 133 | None/bool: Return True if the run is restored successfully 134 | else return None 135 | """ 136 | if comet_ml is None: 137 | return 138 | 139 | if isinstance(opt.resume, str): 140 | if opt.resume.startswith(COMET_PREFIX): 141 | api = comet_ml.API() 142 | resource = urlparse(opt.resume) 143 | experiment_path = f"{resource.netloc}{resource.path}" 144 | experiment = api.get(experiment_path) 145 | set_opt_parameters(opt, experiment) 146 | download_model_checkpoint(opt, experiment) 147 | 148 | return True 149 | 150 | return None 151 | -------------------------------------------------------------------------------- /yolov5/utils/loggers/comet/hpo.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import json 3 | import logging 4 | import os 5 | import sys 6 | from pathlib import Path 7 | 8 | import comet_ml 9 | 10 | logger = logging.getLogger(__name__) 11 | 12 | FILE = Path(__file__).resolve() 13 | ROOT = FILE.parents[3] # YOLOv5 root directory 14 | if str(ROOT) not in sys.path: 15 | sys.path.append(str(ROOT)) # add ROOT to PATH 16 | 17 | from yolov5.train import train 18 | from yolov5.utils.callbacks import Callbacks 19 | from yolov5.utils.general import increment_path 20 | from yolov5.utils.torch_utils import select_device 21 | 22 | # Project Configuration 23 | config = comet_ml.config.get_config() 24 | COMET_PROJECT_NAME = config.get_string(os.getenv("COMET_PROJECT_NAME"), "comet.project_name", default="yolov5") 25 | 26 | 27 | def get_args(known=False): 28 | parser = argparse.ArgumentParser() 29 | parser.add_argument('--weights', type=str, default='yolov5s.pt', help='initial weights path') 30 | parser.add_argument('--cfg', type=str, default='', help='model.yaml path') 31 | parser.add_argument('--data', type=str, default=ROOT / 'data/coco128.yaml', help='dataset.yaml path') 32 | parser.add_argument('--hyp', type=str, default=ROOT / 'data/hyps/hyp.scratch-low.yaml', help='hyperparameters path') 33 | parser.add_argument('--epochs', type=int, default=300, help='total training epochs') 34 | parser.add_argument('--batch-size', type=int, default=16, help='total batch size for all GPUs, -1 for autobatch') 35 | parser.add_argument('--imgsz', '--img', '--img-size', type=int, default=640, help='train, val image size (pixels)') 36 | parser.add_argument('--rect', action='store_true', help='rectangular training') 37 | parser.add_argument('--resume', nargs='?', const=True, default=False, help='resume most recent training') 38 | parser.add_argument('--nosave', action='store_true', help='only save final checkpoint') 39 | parser.add_argument('--noval', action='store_true', help='only validate final epoch') 40 | parser.add_argument('--noautoanchor', action='store_true', help='disable AutoAnchor') 41 | parser.add_argument('--noplots', action='store_true', help='save no plot files') 42 | parser.add_argument('--evolve', type=int, nargs='?', const=300, help='evolve hyperparameters for x generations') 43 | parser.add_argument('--bucket', type=str, default='', help='gsutil bucket') 44 | parser.add_argument('--cache', type=str, nargs='?', const='ram', help='--cache images in "ram" (default) or "disk"') 45 | parser.add_argument('--image-weights', action='store_true', help='use weighted image selection for training') 46 | parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu') 47 | parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%%') 48 | parser.add_argument('--single-cls', action='store_true', help='train multi-class data as single-class') 49 | parser.add_argument('--optimizer', type=str, choices=['SGD', 'Adam', 'AdamW'], default='SGD', help='optimizer') 50 | parser.add_argument('--sync-bn', action='store_true', help='use SyncBatchNorm, only available in DDP mode') 51 | parser.add_argument('--workers', type=int, default=8, help='max dataloader workers (per RANK in DDP mode)') 52 | parser.add_argument('--project', default=ROOT / 'runs/train', help='save to project/name') 53 | parser.add_argument('--name', default='exp', help='save to project/name') 54 | parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment') 55 | parser.add_argument('--quad', action='store_true', help='quad dataloader') 56 | parser.add_argument('--cos-lr', action='store_true', help='cosine LR scheduler') 57 | parser.add_argument('--label-smoothing', type=float, default=0.0, help='Label smoothing epsilon') 58 | parser.add_argument('--patience', type=int, default=100, help='EarlyStopping patience (epochs without improvement)') 59 | parser.add_argument('--freeze', nargs='+', type=int, default=[0], help='Freeze layers: backbone=10, first3=0 1 2') 60 | parser.add_argument('--save-period', type=int, default=-1, help='Save checkpoint every x epochs (disabled if < 1)') 61 | parser.add_argument('--seed', type=int, default=0, help='Global training seed') 62 | parser.add_argument('--local_rank', type=int, default=-1, help='Automatic DDP Multi-GPU argument, do not modify') 63 | 64 | # Weights & Biases arguments 65 | parser.add_argument('--entity', default=None, help='W&B: Entity') 66 | parser.add_argument('--upload_dataset', nargs='?', const=True, default=False, help='W&B: Upload data, "val" option') 67 | parser.add_argument('--bbox_interval', type=int, default=-1, help='W&B: Set bounding-box image logging interval') 68 | parser.add_argument('--artifact_alias', type=str, default='latest', help='W&B: Version of dataset artifact to use') 69 | 70 | # Comet Arguments 71 | parser.add_argument("--comet_optimizer_config", type=str, help="Comet: Path to a Comet Optimizer Config File.") 72 | parser.add_argument("--comet_optimizer_id", type=str, help="Comet: ID of the Comet Optimizer sweep.") 73 | parser.add_argument("--comet_optimizer_objective", type=str, help="Comet: Set to 'minimize' or 'maximize'.") 74 | parser.add_argument("--comet_optimizer_metric", type=str, help="Comet: Metric to Optimize.") 75 | parser.add_argument("--comet_optimizer_workers", 76 | type=int, 77 | default=1, 78 | help="Comet: Number of Parallel Workers to use with the Comet Optimizer.") 79 | 80 | return parser.parse_known_args()[0] if known else parser.parse_args() 81 | 82 | 83 | def run(parameters, opt): 84 | hyp_dict = {k: v for k, v in parameters.items() if k not in ["epochs", "batch_size"]} 85 | 86 | opt.save_dir = str(increment_path(Path(opt.project) / opt.name, exist_ok=opt.exist_ok or opt.evolve)) 87 | opt.batch_size = parameters.get("batch_size") 88 | opt.epochs = parameters.get("epochs") 89 | 90 | device = select_device(opt.device, batch_size=opt.batch_size) 91 | train(hyp_dict, opt, device, callbacks=Callbacks()) 92 | 93 | 94 | if __name__ == "__main__": 95 | opt = get_args(known=True) 96 | 97 | opt.weights = str(opt.weights) 98 | opt.cfg = str(opt.cfg) 99 | opt.data = str(opt.data) 100 | opt.project = str(opt.project) 101 | 102 | optimizer_id = os.getenv("COMET_OPTIMIZER_ID") 103 | if optimizer_id is None: 104 | with open(opt.comet_optimizer_config) as f: 105 | optimizer_config = json.load(f) 106 | optimizer = comet_ml.Optimizer(optimizer_config) 107 | else: 108 | optimizer = comet_ml.Optimizer(optimizer_id) 109 | 110 | opt.comet_optimizer_id = optimizer.id 111 | status = optimizer.status() 112 | 113 | opt.comet_optimizer_objective = status["spec"]["objective"] 114 | opt.comet_optimizer_metric = status["spec"]["metric"] 115 | 116 | logger.info("COMET INFO: Starting Hyperparameter Sweep") 117 | for parameter in optimizer.get_parameters(): 118 | run(parameter["parameters"], opt) 119 | -------------------------------------------------------------------------------- /yolov5/utils/loggers/neptune/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fcakyon/yolov5-pip/40a188792bca82b8285549edb2c318b9d73bcd47/yolov5/utils/loggers/neptune/__init__.py -------------------------------------------------------------------------------- /yolov5/utils/loggers/neptune/neptune_utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | 4 | import yaml 5 | from yolov5 import __version__ 6 | from yolov5.utils.general import colorstr 7 | 8 | try: 9 | import neptune as neptune 10 | except ImportError: 11 | neptune = None 12 | 13 | 14 | class NeptuneLogger: 15 | def __init__(self, opt, job_type='Training'): 16 | # Pre-training routine -- 17 | self.job_type = job_type 18 | with open(opt.data) as f: 19 | data_dict = yaml.safe_load(f) # data dict 20 | self.neptune, self.neptune_run = neptune, None 21 | 22 | if self.neptune and opt.neptune_token: 23 | if opt.resume: 24 | self.neptune_run = neptune.init_run(api_token=opt.neptune_token, 25 | project=opt.neptune_project, 26 | with_id=opt.neptune_resume_id) 27 | else: 28 | self.neptune_run = neptune.init_run(api_token=opt.neptune_token, 29 | project=opt.neptune_project, 30 | name=Path(opt.save_dir).stem) 31 | if self.neptune_run: 32 | if self.job_type == 'Training': 33 | if not opt.resume: 34 | opt_dict = vars(opt) 35 | for arg in opt_dict: 36 | try: 37 | iter(opt_dict[arg]) 38 | opt_dict[arg] = f"{opt_dict[arg]}" 39 | except: 40 | if opt_dict[arg] is None: 41 | opt_dict[arg] = "None" 42 | self.neptune_run["opt"] = opt_dict 43 | self.track_dataset(opt) 44 | self.data_dict = self.setup_training(data_dict) 45 | # log yolov5 package version 46 | self.neptune_run["yolov5-version"].log(__version__) 47 | 48 | prefix = colorstr('neptune: ') 49 | print(f"{prefix}NeptuneAI logging initiated successfully.") 50 | 51 | def track_dataset(self, opt): 52 | has_yolo_s3_data_dir = False 53 | with open(opt.data, errors='ignore') as f: 54 | data_dict = yaml.safe_load(f) # load data dict 55 | if data_dict.get("yolo_s3_data_dir") is not None: 56 | has_yolo_s3_data_dir = True 57 | 58 | if has_yolo_s3_data_dir: 59 | yolo_s3_data_dir = data_dict["yolo_s3_data_dir"] 60 | elif opt.upload_dataset and opt.s3_upload_dir: 61 | yolo_s3_data_dir = "s3://" + str(Path(opt.s3_upload_dir.replace("s3://","")) / Path(opt.save_dir).name / 'data').replace(os.sep, '/') 62 | else: 63 | yolo_s3_data_dir = None 64 | if yolo_s3_data_dir is not None: 65 | self.neptune_run["data"].track_files(yolo_s3_data_dir) 66 | 67 | 68 | def setup_training(self, data_dict): 69 | self.log_dict, self.current_epoch = {}, 0 # Logging Constants 70 | return data_dict 71 | 72 | def log(self, log_dict): 73 | if self.neptune_run: 74 | for key, value in log_dict.items(): 75 | self.log_dict[key] = value 76 | 77 | def end_epoch(self, best_result=False): 78 | if self.neptune_run: 79 | for key, value in self.log_dict.items(): 80 | self.neptune_run[key].log(value) 81 | self.log_dict = {} 82 | 83 | def finish_run(self): 84 | if self.neptune_run: 85 | if self.log_dict: 86 | for key, value in self.log_dict.items(): 87 | self.neptune_run[key].log(value) 88 | self.neptune_run.stop() 89 | -------------------------------------------------------------------------------- /yolov5/utils/loggers/wandb/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fcakyon/yolov5-pip/40a188792bca82b8285549edb2c318b9d73bcd47/yolov5/utils/loggers/wandb/__init__.py -------------------------------------------------------------------------------- /yolov5/utils/loggers/wandb/log_dataset.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | 3 | from wandb_utils import WandbLogger 4 | 5 | from yolov5.utils.general import LOGGER 6 | 7 | WANDB_ARTIFACT_PREFIX = 'wandb-artifact://' 8 | 9 | 10 | def create_dataset_artifact(opt): 11 | logger = WandbLogger(opt, None, job_type='Dataset Creation') # TODO: return value unused 12 | if not logger.wandb: 13 | LOGGER.info("install wandb using `pip install wandb` to log the dataset") 14 | 15 | 16 | if __name__ == '__main__': 17 | parser = argparse.ArgumentParser() 18 | parser.add_argument('--data', type=str, default='data/coco128.yaml', help='data.yaml path') 19 | parser.add_argument('--single-cls', action='store_true', help='train as single-class dataset') 20 | parser.add_argument('--project', type=str, default='YOLOv5', help='name of W&B Project') 21 | parser.add_argument('--entity', default=None, help='W&B entity') 22 | parser.add_argument('--name', type=str, default='log dataset', help='name of W&B run') 23 | 24 | opt = parser.parse_args() 25 | opt.resume = False # Explicitly disallow resume check for dataset upload job 26 | 27 | create_dataset_artifact(opt) 28 | -------------------------------------------------------------------------------- /yolov5/utils/loggers/wandb/sweep.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from pathlib import Path 3 | 4 | import wandb 5 | 6 | FILE = Path(__file__).resolve() 7 | ROOT = FILE.parents[3] # YOLOv5 root directory 8 | if str(ROOT) not in sys.path: 9 | sys.path.append(str(ROOT)) # add ROOT to PATH 10 | 11 | from yolov5.train import parse_opt, train 12 | from yolov5.utils.callbacks import Callbacks 13 | from yolov5.utils.general import increment_path 14 | from yolov5.utils.torch_utils import select_device 15 | 16 | 17 | def sweep(): 18 | wandb.init() 19 | # Get hyp dict from sweep agent. Copy because train() modifies parameters which confused wandb. 20 | hyp_dict = vars(wandb.config).get("_items").copy() 21 | 22 | # Workaround: get necessary opt args 23 | opt = parse_opt(known=True) 24 | opt.batch_size = hyp_dict.get("batch_size") 25 | opt.save_dir = str(increment_path(Path(opt.project) / opt.name, exist_ok=opt.exist_ok or opt.evolve)) 26 | opt.epochs = hyp_dict.get("epochs") 27 | opt.nosave = True 28 | opt.data = hyp_dict.get("data") 29 | opt.weights = str(opt.weights) 30 | opt.cfg = str(opt.cfg) 31 | opt.data = str(opt.data) 32 | opt.hyp = str(opt.hyp) 33 | opt.project = str(opt.project) 34 | device = select_device(opt.device, batch_size=opt.batch_size) 35 | 36 | # train 37 | train(hyp_dict, opt, device, callbacks=Callbacks()) 38 | 39 | 40 | if __name__ == "__main__": 41 | sweep() 42 | -------------------------------------------------------------------------------- /yolov5/utils/loggers/wandb/sweep.yaml: -------------------------------------------------------------------------------- 1 | # Hyperparameters for training 2 | # To set range- 3 | # Provide min and max values as: 4 | # parameter: 5 | # 6 | # min: scalar 7 | # max: scalar 8 | # OR 9 | # 10 | # Set a specific list of search space- 11 | # parameter: 12 | # values: [scalar1, scalar2, scalar3...] 13 | # 14 | # You can use grid, bayesian and hyperopt search strategy 15 | # For more info on configuring sweeps visit - https://docs.wandb.ai/guides/sweeps/configuration 16 | 17 | program: utils/loggers/wandb/sweep.py 18 | method: random 19 | metric: 20 | name: metrics/mAP_0.5 21 | goal: maximize 22 | 23 | parameters: 24 | # hyperparameters: set either min, max range or values list 25 | data: 26 | value: "data/coco128.yaml" 27 | batch_size: 28 | values: [64] 29 | epochs: 30 | values: [10] 31 | 32 | lr0: 33 | distribution: uniform 34 | min: 1e-5 35 | max: 1e-1 36 | lrf: 37 | distribution: uniform 38 | min: 0.01 39 | max: 1.0 40 | momentum: 41 | distribution: uniform 42 | min: 0.6 43 | max: 0.98 44 | weight_decay: 45 | distribution: uniform 46 | min: 0.0 47 | max: 0.001 48 | warmup_epochs: 49 | distribution: uniform 50 | min: 0.0 51 | max: 5.0 52 | warmup_momentum: 53 | distribution: uniform 54 | min: 0.0 55 | max: 0.95 56 | warmup_bias_lr: 57 | distribution: uniform 58 | min: 0.0 59 | max: 0.2 60 | box: 61 | distribution: uniform 62 | min: 0.02 63 | max: 0.2 64 | cls: 65 | distribution: uniform 66 | min: 0.2 67 | max: 4.0 68 | cls_pw: 69 | distribution: uniform 70 | min: 0.5 71 | max: 2.0 72 | obj: 73 | distribution: uniform 74 | min: 0.2 75 | max: 4.0 76 | obj_pw: 77 | distribution: uniform 78 | min: 0.5 79 | max: 2.0 80 | iou_t: 81 | distribution: uniform 82 | min: 0.1 83 | max: 0.7 84 | anchor_t: 85 | distribution: uniform 86 | min: 2.0 87 | max: 8.0 88 | fl_gamma: 89 | distribution: uniform 90 | min: 0.0 91 | max: 4.0 92 | hsv_h: 93 | distribution: uniform 94 | min: 0.0 95 | max: 0.1 96 | hsv_s: 97 | distribution: uniform 98 | min: 0.0 99 | max: 0.9 100 | hsv_v: 101 | distribution: uniform 102 | min: 0.0 103 | max: 0.9 104 | degrees: 105 | distribution: uniform 106 | min: 0.0 107 | max: 45.0 108 | translate: 109 | distribution: uniform 110 | min: 0.0 111 | max: 0.9 112 | scale: 113 | distribution: uniform 114 | min: 0.0 115 | max: 0.9 116 | shear: 117 | distribution: uniform 118 | min: 0.0 119 | max: 10.0 120 | perspective: 121 | distribution: uniform 122 | min: 0.0 123 | max: 0.001 124 | flipud: 125 | distribution: uniform 126 | min: 0.0 127 | max: 1.0 128 | fliplr: 129 | distribution: uniform 130 | min: 0.0 131 | max: 1.0 132 | mosaic: 133 | distribution: uniform 134 | min: 0.0 135 | max: 1.0 136 | mixup: 137 | distribution: uniform 138 | min: 0.0 139 | max: 1.0 140 | copy_paste: 141 | distribution: uniform 142 | min: 0.0 143 | max: 1.0 144 | -------------------------------------------------------------------------------- /yolov5/utils/roboflow.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | 4 | from roboflow import Roboflow 5 | from roboflow.core.version import Version 6 | from typing import Dict, Optional 7 | 8 | from yolov5.utils.plots import plot_results 9 | from yolov5.utils.general import LOGGER 10 | 11 | TASK2FORMAT: Dict[str, str] = { 12 | "detect": "yolov5", 13 | "segment": "yolov5", 14 | "classify": "folder" 15 | } 16 | 17 | 18 | def extract_roboflow_metadata(url: str) -> tuple: 19 | match = re.search(r'https://(?:app|universe)\.roboflow\.com/([^/]+)/([^/]+)(?:/dataset)?/([^/]+)', url) 20 | if match: 21 | workspace_name = match.group(1) 22 | project_name = match.group(2) 23 | project_version = match.group(3) 24 | return workspace_name, project_name, project_version 25 | else: 26 | raise ValueError(f"Invalid Roboflow dataset url ❌ " 27 | f"Expected: https://universe.roboflow.com/workspace_name/project_name/project_version. " 28 | f"Given: {url}") 29 | 30 | 31 | class RoboflowConnector: 32 | 33 | project_version: Optional[Version] = None 34 | 35 | @staticmethod 36 | def init(url: str, roboflow_token: Optional[str]) -> None: 37 | if roboflow_token is None: 38 | raise ValueError("roboflow_token not found ❌") 39 | 40 | workspace_name, project_name, project_version = extract_roboflow_metadata(url=url) 41 | 42 | rf = Roboflow(api_key=roboflow_token) 43 | project_version = rf.workspace(workspace_name).project(project_name).version(int(project_version)) 44 | RoboflowConnector.project_version = project_version 45 | 46 | @staticmethod 47 | def download_dataset(url: str, roboflow_token: Optional[str], task: str, location: Optional[str] = None) -> str: 48 | if roboflow_token is None: 49 | raise ValueError("roboflow_token not found ❌") 50 | 51 | if location: 52 | os.environ["DATASET_DIRECTORY"] = location 53 | RoboflowConnector.init(url=url, roboflow_token=roboflow_token) 54 | 55 | dataset = RoboflowConnector.project_version.download( 56 | model_format=TASK2FORMAT[task], 57 | overwrite=False 58 | ) 59 | if task == "classify": 60 | return dataset.location 61 | return f"{dataset.location}/data.yaml" 62 | 63 | @staticmethod 64 | def upload_model(model_path: str): 65 | if RoboflowConnector.project_version is None: 66 | raise ValueError("RoboflowConnector must be initiated before you upload_model ❌") 67 | 68 | plot_results(file=os.path.join(model_path, "results.csv")) 69 | LOGGER.info(f"Uploading model from local: {model_path} to Roboflow: {RoboflowConnector.project_version.id}") 70 | RoboflowConnector.project_version.deploy(model_type="yolov5", model_path=model_path) 71 | -------------------------------------------------------------------------------- /yolov5/utils/segment/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fcakyon/yolov5-pip/40a188792bca82b8285549edb2c318b9d73bcd47/yolov5/utils/segment/__init__.py -------------------------------------------------------------------------------- /yolov5/utils/segment/augmentations.py: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | """ 3 | Image augmentation functions 4 | """ 5 | 6 | import math 7 | import random 8 | 9 | import cv2 10 | import numpy as np 11 | 12 | from ..augmentations import box_candidates 13 | from ..general import resample_segments, segment2box 14 | 15 | 16 | def mixup(im, labels, segments, im2, labels2, segments2): 17 | # Applies MixUp augmentation https://arxiv.org/pdf/1710.09412.pdf 18 | r = np.random.beta(32.0, 32.0) # mixup ratio, alpha=beta=32.0 19 | im = (im * r + im2 * (1 - r)).astype(np.uint8) 20 | labels = np.concatenate((labels, labels2), 0) 21 | segments = np.concatenate((segments, segments2), 0) 22 | return im, labels, segments 23 | 24 | 25 | def random_perspective(im, 26 | targets=(), 27 | segments=(), 28 | degrees=10, 29 | translate=.1, 30 | scale=.1, 31 | shear=10, 32 | perspective=0.0, 33 | border=(0, 0)): 34 | # torchvision.transforms.RandomAffine(degrees=(-10, 10), translate=(.1, .1), scale=(.9, 1.1), shear=(-10, 10)) 35 | # targets = [cls, xyxy] 36 | 37 | height = im.shape[0] + border[0] * 2 # shape(h,w,c) 38 | width = im.shape[1] + border[1] * 2 39 | 40 | # Center 41 | C = np.eye(3) 42 | C[0, 2] = -im.shape[1] / 2 # x translation (pixels) 43 | C[1, 2] = -im.shape[0] / 2 # y translation (pixels) 44 | 45 | # Perspective 46 | P = np.eye(3) 47 | P[2, 0] = random.uniform(-perspective, perspective) # x perspective (about y) 48 | P[2, 1] = random.uniform(-perspective, perspective) # y perspective (about x) 49 | 50 | # Rotation and Scale 51 | R = np.eye(3) 52 | a = random.uniform(-degrees, degrees) 53 | # a += random.choice([-180, -90, 0, 90]) # add 90deg rotations to small rotations 54 | s = random.uniform(1 - scale, 1 + scale) 55 | # s = 2 ** random.uniform(-scale, scale) 56 | R[:2] = cv2.getRotationMatrix2D(angle=a, center=(0, 0), scale=s) 57 | 58 | # Shear 59 | S = np.eye(3) 60 | S[0, 1] = math.tan(random.uniform(-shear, shear) * math.pi / 180) # x shear (deg) 61 | S[1, 0] = math.tan(random.uniform(-shear, shear) * math.pi / 180) # y shear (deg) 62 | 63 | # Translation 64 | T = np.eye(3) 65 | T[0, 2] = (random.uniform(0.5 - translate, 0.5 + translate) * width) # x translation (pixels) 66 | T[1, 2] = (random.uniform(0.5 - translate, 0.5 + translate) * height) # y translation (pixels) 67 | 68 | # Combined rotation matrix 69 | M = T @ S @ R @ P @ C # order of operations (right to left) is IMPORTANT 70 | if (border[0] != 0) or (border[1] != 0) or (M != np.eye(3)).any(): # image changed 71 | if perspective: 72 | im = cv2.warpPerspective(im, M, dsize=(width, height), borderValue=(114, 114, 114)) 73 | else: # affine 74 | im = cv2.warpAffine(im, M[:2], dsize=(width, height), borderValue=(114, 114, 114)) 75 | 76 | # Visualize 77 | # import matplotlib.pyplot as plt 78 | # ax = plt.subplots(1, 2, figsize=(12, 6))[1].ravel() 79 | # ax[0].imshow(im[:, :, ::-1]) # base 80 | # ax[1].imshow(im2[:, :, ::-1]) # warped 81 | 82 | # Transform label coordinates 83 | n = len(targets) 84 | new_segments = [] 85 | if n: 86 | new = np.zeros((n, 4)) 87 | segments = resample_segments(segments) # upsample 88 | for i, segment in enumerate(segments): 89 | xy = np.ones((len(segment), 3)) 90 | xy[:, :2] = segment 91 | xy = xy @ M.T # transform 92 | xy = (xy[:, :2] / xy[:, 2:3] if perspective else xy[:, :2]) # perspective rescale or affine 93 | 94 | # clip 95 | new[i] = segment2box(xy, width, height) 96 | new_segments.append(xy) 97 | 98 | # filter candidates 99 | i = box_candidates(box1=targets[:, 1:5].T * s, box2=new.T, area_thr=0.01) 100 | targets = targets[i] 101 | targets[:, 1:5] = new[i] 102 | new_segments = np.array(new_segments)[i] 103 | 104 | return im, targets, new_segments 105 | -------------------------------------------------------------------------------- /yolov5/utils/segment/general.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import torch 4 | import torch.nn.functional as F 5 | 6 | 7 | def crop_mask(masks, boxes): 8 | """ 9 | "Crop" predicted masks by zeroing out everything not in the predicted bbox. 10 | Vectorized by Chong (thanks Chong). 11 | 12 | Args: 13 | - masks should be a size [n, h, w] tensor of masks 14 | - boxes should be a size [n, 4] tensor of bbox coords in relative point form 15 | """ 16 | 17 | n, h, w = masks.shape 18 | x1, y1, x2, y2 = torch.chunk(boxes[:, :, None], 4, 1) # x1 shape(1,1,n) 19 | r = torch.arange(w, device=masks.device, dtype=x1.dtype)[None, None, :] # rows shape(1,w,1) 20 | c = torch.arange(h, device=masks.device, dtype=x1.dtype)[None, :, None] # cols shape(h,1,1) 21 | 22 | return masks * ((r >= x1) * (r < x2) * (c >= y1) * (c < y2)) 23 | 24 | 25 | def process_mask_upsample(protos, masks_in, bboxes, shape): 26 | """ 27 | Crop after upsample. 28 | protos: [mask_dim, mask_h, mask_w] 29 | masks_in: [n, mask_dim], n is number of masks after nms 30 | bboxes: [n, 4], n is number of masks after nms 31 | shape: input_image_size, (h, w) 32 | 33 | return: h, w, n 34 | """ 35 | 36 | c, mh, mw = protos.shape # CHW 37 | masks = (masks_in @ protos.float().view(c, -1)).sigmoid().view(-1, mh, mw) 38 | masks = F.interpolate(masks[None], shape, mode='bilinear', align_corners=False)[0] # CHW 39 | masks = crop_mask(masks, bboxes) # CHW 40 | return masks.gt_(0.5) 41 | 42 | 43 | def process_mask(protos, masks_in, bboxes, shape, upsample=False): 44 | """ 45 | Crop before upsample. 46 | proto_out: [mask_dim, mask_h, mask_w] 47 | out_masks: [n, mask_dim], n is number of masks after nms 48 | bboxes: [n, 4], n is number of masks after nms 49 | shape:input_image_size, (h, w) 50 | 51 | return: h, w, n 52 | """ 53 | 54 | c, mh, mw = protos.shape # CHW 55 | ih, iw = shape 56 | masks = (masks_in @ protos.float().view(c, -1)).sigmoid().view(-1, mh, mw) # CHW 57 | 58 | downsampled_bboxes = bboxes.clone() 59 | downsampled_bboxes[:, 0] *= mw / iw 60 | downsampled_bboxes[:, 2] *= mw / iw 61 | downsampled_bboxes[:, 3] *= mh / ih 62 | downsampled_bboxes[:, 1] *= mh / ih 63 | 64 | masks = crop_mask(masks, downsampled_bboxes) # CHW 65 | if upsample: 66 | masks = F.interpolate(masks[None], shape, mode='bilinear', align_corners=False)[0] # CHW 67 | return masks.gt_(0.5) 68 | 69 | 70 | def process_mask_native(protos, masks_in, bboxes, shape): 71 | """ 72 | Crop after upsample. 73 | protos: [mask_dim, mask_h, mask_w] 74 | masks_in: [n, mask_dim], n is number of masks after nms 75 | bboxes: [n, 4], n is number of masks after nms 76 | shape: input_image_size, (h, w) 77 | 78 | return: h, w, n 79 | """ 80 | c, mh, mw = protos.shape # CHW 81 | masks = (masks_in @ protos.float().view(c, -1)).sigmoid().view(-1, mh, mw) 82 | gain = min(mh / shape[0], mw / shape[1]) # gain = old / new 83 | pad = (mw - shape[1] * gain) / 2, (mh - shape[0] * gain) / 2 # wh padding 84 | top, left = int(pad[1]), int(pad[0]) # y, x 85 | bottom, right = int(mh - pad[1]), int(mw - pad[0]) 86 | masks = masks[:, top:bottom, left:right] 87 | 88 | masks = F.interpolate(masks[None], shape, mode='bilinear', align_corners=False)[0] # CHW 89 | masks = crop_mask(masks, bboxes) # CHW 90 | return masks.gt_(0.5) 91 | 92 | 93 | def scale_image(im1_shape, masks, im0_shape, ratio_pad=None): 94 | """ 95 | img1_shape: model input shape, [h, w] 96 | img0_shape: origin pic shape, [h, w, 3] 97 | masks: [h, w, num] 98 | """ 99 | # Rescale coordinates (xyxy) from im1_shape to im0_shape 100 | if ratio_pad is None: # calculate from im0_shape 101 | gain = min(im1_shape[0] / im0_shape[0], im1_shape[1] / im0_shape[1]) # gain = old / new 102 | pad = (im1_shape[1] - im0_shape[1] * gain) / 2, (im1_shape[0] - im0_shape[0] * gain) / 2 # wh padding 103 | else: 104 | pad = ratio_pad[1] 105 | top, left = int(pad[1]), int(pad[0]) # y, x 106 | bottom, right = int(im1_shape[0] - pad[1]), int(im1_shape[1] - pad[0]) 107 | 108 | if len(masks.shape) < 2: 109 | raise ValueError(f'"len of masks shape" should be 2 or 3, but got {len(masks.shape)}') 110 | masks = masks[top:bottom, left:right] 111 | # masks = masks.permute(2, 0, 1).contiguous() 112 | # masks = F.interpolate(masks[None], im0_shape[:2], mode='bilinear', align_corners=False)[0] 113 | # masks = masks.permute(1, 2, 0).contiguous() 114 | masks = cv2.resize(masks, (im0_shape[1], im0_shape[0])) 115 | 116 | if len(masks.shape) == 2: 117 | masks = masks[:, :, None] 118 | return masks 119 | 120 | 121 | def mask_iou(mask1, mask2, eps=1e-7): 122 | """ 123 | mask1: [N, n] m1 means number of predicted objects 124 | mask2: [M, n] m2 means number of gt objects 125 | Note: n means image_w x image_h 126 | 127 | return: masks iou, [N, M] 128 | """ 129 | intersection = torch.matmul(mask1, mask2.t()).clamp(0) 130 | union = (mask1.sum(1)[:, None] + mask2.sum(1)[None]) - intersection # (area1 + area2) - intersection 131 | return intersection / (union + eps) 132 | 133 | 134 | def masks_iou(mask1, mask2, eps=1e-7): 135 | """ 136 | mask1: [N, n] m1 means number of predicted objects 137 | mask2: [N, n] m2 means number of gt objects 138 | Note: n means image_w x image_h 139 | 140 | return: masks iou, (N, ) 141 | """ 142 | intersection = (mask1 * mask2).sum(1).clamp(0) # (N, ) 143 | union = (mask1.sum(1) + mask2.sum(1))[None] - intersection # (area1 + area2) - intersection 144 | return intersection / (union + eps) 145 | 146 | 147 | def masks2segments(masks, strategy='largest'): 148 | # Convert masks(n,160,160) into segments(n,xy) 149 | segments = [] 150 | for x in masks.int().cpu().numpy().astype('uint8'): 151 | c = cv2.findContours(x, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0] 152 | if c: 153 | if strategy == 'concat': # concatenate all segments 154 | c = np.concatenate([x.reshape(-1, 2) for x in c]) 155 | elif strategy == 'largest': # select largest segment 156 | c = np.array(c[np.array([len(x) for x in c]).argmax()]).reshape(-1, 2) 157 | else: 158 | c = np.zeros((0, 2)) # no segments found 159 | segments.append(c.astype('float32')) 160 | return segments 161 | -------------------------------------------------------------------------------- /yolov5/utils/segment/metrics.py: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | """ 3 | Model validation metrics 4 | """ 5 | 6 | import numpy as np 7 | 8 | from ..metrics import ap_per_class 9 | 10 | 11 | def fitness(x): 12 | # Model fitness as a weighted combination of metrics 13 | w = [0.0, 0.0, 0.1, 0.9, 0.0, 0.0, 0.1, 0.9] 14 | return (x[:, :8] * w).sum(1) 15 | 16 | 17 | def ap_per_class_box_and_mask( 18 | tp_m, 19 | tp_b, 20 | conf, 21 | pred_cls, 22 | target_cls, 23 | plot=False, 24 | save_dir='.', 25 | names=(), 26 | ): 27 | """ 28 | Args: 29 | tp_b: tp of boxes. 30 | tp_m: tp of masks. 31 | other arguments see `func: ap_per_class`. 32 | """ 33 | results_boxes = ap_per_class(tp_b, 34 | conf, 35 | pred_cls, 36 | target_cls, 37 | plot=plot, 38 | save_dir=save_dir, 39 | names=names, 40 | prefix='Box')[2:] 41 | results_masks = ap_per_class(tp_m, 42 | conf, 43 | pred_cls, 44 | target_cls, 45 | plot=plot, 46 | save_dir=save_dir, 47 | names=names, 48 | prefix='Mask')[2:] 49 | 50 | results = { 51 | 'boxes': { 52 | 'p': results_boxes[0], 53 | 'r': results_boxes[1], 54 | 'ap': results_boxes[3], 55 | 'f1': results_boxes[2], 56 | 'ap_class': results_boxes[4]}, 57 | 'masks': { 58 | 'p': results_masks[0], 59 | 'r': results_masks[1], 60 | 'ap': results_masks[3], 61 | 'f1': results_masks[2], 62 | 'ap_class': results_masks[4]}} 63 | return results 64 | 65 | 66 | class Metric: 67 | 68 | def __init__(self) -> None: 69 | self.p = [] # (nc, ) 70 | self.r = [] # (nc, ) 71 | self.f1 = [] # (nc, ) 72 | self.all_ap = [] # (nc, 10) 73 | self.ap_class_index = [] # (nc, ) 74 | 75 | @property 76 | def ap50(self): 77 | """AP@0.5 of all classes. 78 | Return: 79 | (nc, ) or []. 80 | """ 81 | return self.all_ap[:, 0] if len(self.all_ap) else [] 82 | 83 | @property 84 | def ap(self): 85 | """AP@0.5:0.95 86 | Return: 87 | (nc, ) or []. 88 | """ 89 | return self.all_ap.mean(1) if len(self.all_ap) else [] 90 | 91 | @property 92 | def mp(self): 93 | """mean precision of all classes. 94 | Return: 95 | float. 96 | """ 97 | return self.p.mean() if len(self.p) else 0.0 98 | 99 | @property 100 | def mr(self): 101 | """mean recall of all classes. 102 | Return: 103 | float. 104 | """ 105 | return self.r.mean() if len(self.r) else 0.0 106 | 107 | @property 108 | def map50(self): 109 | """Mean AP@0.5 of all classes. 110 | Return: 111 | float. 112 | """ 113 | return self.all_ap[:, 0].mean() if len(self.all_ap) else 0.0 114 | 115 | @property 116 | def map(self): 117 | """Mean AP@0.5:0.95 of all classes. 118 | Return: 119 | float. 120 | """ 121 | return self.all_ap.mean() if len(self.all_ap) else 0.0 122 | 123 | def mean_results(self): 124 | """Mean of results, return mp, mr, map50, map""" 125 | return (self.mp, self.mr, self.map50, self.map) 126 | 127 | def class_result(self, i): 128 | """class-aware result, return p[i], r[i], ap50[i], ap[i]""" 129 | return (self.p[i], self.r[i], self.ap50[i], self.ap[i]) 130 | 131 | def get_maps(self, nc): 132 | maps = np.zeros(nc) + self.map 133 | for i, c in enumerate(self.ap_class_index): 134 | maps[c] = self.ap[i] 135 | return maps 136 | 137 | def update(self, results): 138 | """ 139 | Args: 140 | results: tuple(p, r, ap, f1, ap_class) 141 | """ 142 | p, r, all_ap, f1, ap_class_index = results 143 | self.p = p 144 | self.r = r 145 | self.all_ap = all_ap 146 | self.f1 = f1 147 | self.ap_class_index = ap_class_index 148 | 149 | 150 | class Metrics: 151 | """Metric for boxes and masks.""" 152 | 153 | def __init__(self) -> None: 154 | self.metric_box = Metric() 155 | self.metric_mask = Metric() 156 | 157 | def update(self, results): 158 | """ 159 | Args: 160 | results: Dict{'boxes': Dict{}, 'masks': Dict{}} 161 | """ 162 | self.metric_box.update(list(results['boxes'].values())) 163 | self.metric_mask.update(list(results['masks'].values())) 164 | 165 | def mean_results(self): 166 | return self.metric_box.mean_results() + self.metric_mask.mean_results() 167 | 168 | def class_result(self, i): 169 | return self.metric_box.class_result(i) + self.metric_mask.class_result(i) 170 | 171 | def get_maps(self, nc): 172 | return self.metric_box.get_maps(nc) + self.metric_mask.get_maps(nc) 173 | 174 | @property 175 | def ap_class_index(self): 176 | # boxes and masks have the same ap_class_index 177 | return self.metric_box.ap_class_index 178 | 179 | 180 | KEYS = [ 181 | 'train/box_loss', 182 | 'train/seg_loss', # train loss 183 | 'train/obj_loss', 184 | 'train/cls_loss', 185 | 'metrics/precision(B)', 186 | 'metrics/recall(B)', 187 | 'metrics/mAP_0.5(B)', 188 | 'metrics/mAP_0.5:0.95(B)', # metrics 189 | 'metrics/precision(M)', 190 | 'metrics/recall(M)', 191 | 'metrics/mAP_0.5(M)', 192 | 'metrics/mAP_0.5:0.95(M)', # metrics 193 | 'val/box_loss', 194 | 'val/seg_loss', # val loss 195 | 'val/obj_loss', 196 | 'val/cls_loss', 197 | 'x/lr0', 198 | 'x/lr1', 199 | 'x/lr2',] 200 | 201 | BEST_KEYS = [ 202 | 'best/epoch', 203 | 'best/precision(B)', 204 | 'best/recall(B)', 205 | 'best/mAP_0.5(B)', 206 | 'best/mAP_0.5:0.95(B)', 207 | 'best/precision(M)', 208 | 'best/recall(M)', 209 | 'best/mAP_0.5(M)', 210 | 'best/mAP_0.5:0.95(M)',] 211 | -------------------------------------------------------------------------------- /yolov5/utils/segment/plots.py: -------------------------------------------------------------------------------- 1 | import contextlib 2 | import math 3 | from pathlib import Path 4 | 5 | import cv2 6 | import matplotlib.pyplot as plt 7 | import numpy as np 8 | import pandas as pd 9 | import torch 10 | 11 | from .. import threaded 12 | from ..general import xywh2xyxy 13 | from ..plots import Annotator, colors 14 | 15 | 16 | @threaded 17 | def plot_images_and_masks(images, targets, masks, paths=None, fname='images.jpg', names=None): 18 | # Plot image grid with labels 19 | if isinstance(images, torch.Tensor): 20 | images = images.cpu().float().numpy() 21 | if isinstance(targets, torch.Tensor): 22 | targets = targets.cpu().numpy() 23 | if isinstance(masks, torch.Tensor): 24 | masks = masks.cpu().numpy().astype(int) 25 | 26 | max_size = 1920 # max image size 27 | max_subplots = 16 # max image subplots, i.e. 4x4 28 | bs, _, h, w = images.shape # batch size, _, height, width 29 | bs = min(bs, max_subplots) # limit plot images 30 | ns = np.ceil(bs ** 0.5) # number of subplots (square) 31 | if np.max(images[0]) <= 1: 32 | images *= 255 # de-normalise (optional) 33 | 34 | # Build Image 35 | mosaic = np.full((int(ns * h), int(ns * w), 3), 255, dtype=np.uint8) # init 36 | for i, im in enumerate(images): 37 | if i == max_subplots: # if last batch has fewer images than we expect 38 | break 39 | x, y = int(w * (i // ns)), int(h * (i % ns)) # block origin 40 | im = im.transpose(1, 2, 0) 41 | mosaic[y:y + h, x:x + w, :] = im 42 | 43 | # Resize (optional) 44 | scale = max_size / ns / max(h, w) 45 | if scale < 1: 46 | h = math.ceil(scale * h) 47 | w = math.ceil(scale * w) 48 | mosaic = cv2.resize(mosaic, tuple(int(x * ns) for x in (w, h))) 49 | 50 | # Annotate 51 | fs = int((h + w) * ns * 0.01) # font size 52 | annotator = Annotator(mosaic, line_width=round(fs / 10), font_size=fs, pil=True, example=names) 53 | for i in range(i + 1): 54 | x, y = int(w * (i // ns)), int(h * (i % ns)) # block origin 55 | annotator.rectangle([x, y, x + w, y + h], None, (255, 255, 255), width=2) # borders 56 | if paths: 57 | annotator.text((x + 5, y + 5), text=Path(paths[i]).name[:40], txt_color=(220, 220, 220)) # filenames 58 | if len(targets) > 0: 59 | idx = targets[:, 0] == i 60 | ti = targets[idx] # image targets 61 | 62 | boxes = xywh2xyxy(ti[:, 2:6]).T 63 | classes = ti[:, 1].astype('int') 64 | labels = ti.shape[1] == 6 # labels if no conf column 65 | conf = None if labels else ti[:, 6] # check for confidence presence (label vs pred) 66 | 67 | if boxes.shape[1]: 68 | if boxes.max() <= 1.01: # if normalized with tolerance 0.01 69 | boxes[[0, 2]] *= w # scale to pixels 70 | boxes[[1, 3]] *= h 71 | elif scale < 1: # absolute coords need scale if image scales 72 | boxes *= scale 73 | boxes[[0, 2]] += x 74 | boxes[[1, 3]] += y 75 | for j, box in enumerate(boxes.T.tolist()): 76 | cls = classes[j] 77 | color = colors(cls) 78 | cls = names[cls] if names else cls 79 | if labels or conf[j] > 0.25: # 0.25 conf thresh 80 | label = f'{cls}' if labels else f'{cls} {conf[j]:.1f}' 81 | annotator.box_label(box, label, color=color) 82 | 83 | # Plot masks 84 | if len(masks): 85 | if masks.max() > 1.0: # mean that masks are overlap 86 | image_masks = masks[[i]] # (1, 640, 640) 87 | nl = len(ti) 88 | index = np.arange(nl).reshape(nl, 1, 1) + 1 89 | image_masks = np.repeat(image_masks, nl, axis=0) 90 | image_masks = np.where(image_masks == index, 1.0, 0.0) 91 | else: 92 | image_masks = masks[idx] 93 | 94 | im = np.asarray(annotator.im).copy() 95 | for j, box in enumerate(boxes.T.tolist()): 96 | if labels or conf[j] > 0.25: # 0.25 conf thresh 97 | color = colors(classes[j]) 98 | mh, mw = image_masks[j].shape 99 | if mh != h or mw != w: 100 | mask = image_masks[j].astype(np.uint8) 101 | mask = cv2.resize(mask, (w, h)) 102 | mask = mask.astype(bool) 103 | else: 104 | mask = image_masks[j].astype(bool) 105 | with contextlib.suppress(Exception): 106 | im[y:y + h, x:x + w, :][mask] = im[y:y + h, x:x + w, :][mask] * 0.4 + np.array(color) * 0.6 107 | annotator.fromarray(im) 108 | annotator.im.save(fname) # save 109 | 110 | 111 | def plot_results_with_masks(file='path/to/results.csv', dir='', best=True): 112 | # Plot training results.csv. Usage: from utils.plots import *; plot_results('path/to/results.csv') 113 | save_dir = Path(file).parent if file else Path(dir) 114 | fig, ax = plt.subplots(2, 8, figsize=(18, 6), tight_layout=True) 115 | ax = ax.ravel() 116 | files = list(save_dir.glob('results*.csv')) 117 | assert len(files), f'No results.csv files found in {save_dir.resolve()}, nothing to plot.' 118 | for f in files: 119 | try: 120 | data = pd.read_csv(f) 121 | index = np.argmax(0.9 * data.values[:, 8] + 0.1 * data.values[:, 7] + 0.9 * data.values[:, 12] + 122 | 0.1 * data.values[:, 11]) 123 | s = [x.strip() for x in data.columns] 124 | x = data.values[:, 0] 125 | for i, j in enumerate([1, 2, 3, 4, 5, 6, 9, 10, 13, 14, 15, 16, 7, 8, 11, 12]): 126 | y = data.values[:, j] 127 | # y[y == 0] = np.nan # don't show zero values 128 | ax[i].plot(x, y, marker='.', label=f.stem, linewidth=2, markersize=2) 129 | if best: 130 | # best 131 | ax[i].scatter(index, y[index], color='r', label=f'best:{index}', marker='*', linewidth=3) 132 | ax[i].set_title(s[j] + f'\n{round(y[index], 5)}') 133 | else: 134 | # last 135 | ax[i].scatter(x[-1], y[-1], color='r', label='last', marker='*', linewidth=3) 136 | ax[i].set_title(s[j] + f'\n{round(y[-1], 5)}') 137 | # if j in [8, 9, 10]: # share train and val loss y axes 138 | # ax[i].get_shared_y_axes().join(ax[i], ax[i - 5]) 139 | except Exception as e: 140 | print(f'Warning: Plotting error for {f}: {e}') 141 | ax[1].legend() 142 | fig.savefig(save_dir / 'results.png', dpi=200) 143 | plt.close() 144 | -------------------------------------------------------------------------------- /yolov5/utils/triton.py: -------------------------------------------------------------------------------- 1 | # YOLOv5 🚀 by Ultralytics, AGPL-3.0 license 2 | """ Utils to interact with the Triton Inference Server 3 | """ 4 | 5 | import typing 6 | from urllib.parse import urlparse 7 | 8 | import torch 9 | 10 | 11 | class TritonRemoteModel: 12 | """ A wrapper over a model served by the Triton Inference Server. It can 13 | be configured to communicate over GRPC or HTTP. It accepts Torch Tensors 14 | as input and returns them as outputs. 15 | """ 16 | 17 | def __init__(self, url: str): 18 | """ 19 | Keyword arguments: 20 | url: Fully qualified address of the Triton server - for e.g. grpc://localhost:8000 21 | """ 22 | 23 | parsed_url = urlparse(url) 24 | if parsed_url.scheme == 'grpc': 25 | from tritonclient.grpc import InferenceServerClient, InferInput 26 | 27 | self.client = InferenceServerClient(parsed_url.netloc) # Triton GRPC client 28 | model_repository = self.client.get_model_repository_index() 29 | self.model_name = model_repository.models[0].name 30 | self.metadata = self.client.get_model_metadata(self.model_name, as_json=True) 31 | 32 | def create_input_placeholders() -> typing.List[InferInput]: 33 | return [ 34 | InferInput(i['name'], [int(s) for s in i['shape']], i['datatype']) for i in self.metadata['inputs']] 35 | 36 | else: 37 | from tritonclient.http import InferenceServerClient, InferInput 38 | 39 | self.client = InferenceServerClient(parsed_url.netloc) # Triton HTTP client 40 | model_repository = self.client.get_model_repository_index() 41 | self.model_name = model_repository[0]['name'] 42 | self.metadata = self.client.get_model_metadata(self.model_name) 43 | 44 | def create_input_placeholders() -> typing.List[InferInput]: 45 | return [ 46 | InferInput(i['name'], [int(s) for s in i['shape']], i['datatype']) for i in self.metadata['inputs']] 47 | 48 | self._create_input_placeholders_fn = create_input_placeholders 49 | 50 | @property 51 | def runtime(self): 52 | """Returns the model runtime""" 53 | return self.metadata.get('backend', self.metadata.get('platform')) 54 | 55 | def __call__(self, *args, **kwargs) -> typing.Union[torch.Tensor, typing.Tuple[torch.Tensor, ...]]: 56 | """ Invokes the model. Parameters can be provided via args or kwargs. 57 | args, if provided, are assumed to match the order of inputs of the model. 58 | kwargs are matched with the model input names. 59 | """ 60 | inputs = self._create_inputs(*args, **kwargs) 61 | response = self.client.infer(model_name=self.model_name, inputs=inputs) 62 | result = [] 63 | for output in self.metadata['outputs']: 64 | tensor = torch.as_tensor(response.as_numpy(output['name'])) 65 | result.append(tensor) 66 | return result[0] if len(result) == 1 else result 67 | 68 | def _create_inputs(self, *args, **kwargs): 69 | args_len, kwargs_len = len(args), len(kwargs) 70 | if not args_len and not kwargs_len: 71 | raise RuntimeError('No inputs provided.') 72 | if args_len and kwargs_len: 73 | raise RuntimeError('Cannot specify args and kwargs at the same time') 74 | 75 | placeholders = self._create_input_placeholders_fn() 76 | if args_len: 77 | if args_len != len(placeholders): 78 | raise RuntimeError(f'Expected {len(placeholders)} inputs, got {args_len}.') 79 | for input, value in zip(placeholders, args): 80 | input.set_data_from_numpy(value.cpu().numpy()) 81 | else: 82 | for input in placeholders: 83 | value = kwargs[input.name] 84 | input.set_data_from_numpy(value.cpu().numpy()) 85 | return placeholders 86 | --------------------------------------------------------------------------------