diff --git a/doc/yoloserv.odt b/doc/yoloserv.odt new file mode 100644 index 000000000..2056ff899 Binary files /dev/null and b/doc/yoloserv.odt differ diff --git a/downloads/ultralytics-main/.github/ISSUE_TEMPLATE/config.yml b/downloads/ultralytics-main/.github/ISSUE_TEMPLATE/config.yml index 28d4b8f51..9018a6213 100644 --- a/downloads/ultralytics-main/.github/ISSUE_TEMPLATE/config.yml +++ b/downloads/ultralytics-main/.github/ISSUE_TEMPLATE/config.yml @@ -7,5 +7,5 @@ contact_links: url: https://community.ultralytics.com/ about: Ask on Ultralytics Community Forum - name: 🎧 Discord - url: https://discord.gg/n6cFeSPZdD + url: https://ultralytics.com/discord about: Ask on Ultralytics Discord diff --git a/downloads/ultralytics-main/.github/workflows/ci.yaml b/downloads/ultralytics-main/.github/workflows/ci.yaml index 04717be6c..9411948ce 100644 --- a/downloads/ultralytics-main/.github/workflows/ci.yaml +++ b/downloads/ultralytics-main/.github/workflows/ci.yaml @@ -10,17 +10,30 @@ on: branches: [main] schedule: - cron: '0 0 * * *' # runs at 00:00 UTC every day + workflow_dispatch: + inputs: + hub: + description: 'Run HUB' + default: false + type: boolean + tests: + description: 'Run Tests' + default: false + type: boolean + benchmarks: + description: 'Run Benchmarks' + default: false + type: boolean jobs: HUB: - if: github.repository == 'ultralytics/ultralytics' && (github.event_name == 'schedule' || github.event_name == 'push') + if: github.repository == 'ultralytics/ultralytics' && (github.event_name == 'schedule' || github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.hub == 'true')) runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest] - python-version: ['3.10'] - model: [yolov5n] + python-version: ['3.11'] steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 @@ -56,8 +69,26 @@ jobs: hub.reset_model(model_id) model = YOLO('https://hub.ultralytics.com/models/' + model_id) model.train() + - name: Test HUB inference API + shell: python + env: + API_KEY: ${{ secrets.ULTRALYTICS_HUB_API_KEY }} + MODEL_ID: ${{ secrets.ULTRALYTICS_HUB_MODEL_ID }} + run: | + import os + import requests + import json + api_key, model_id = os.environ['API_KEY'], os.environ['MODEL_ID'] + url = f"https://api.ultralytics.com/v1/predict/{model_id}" + headers = {"x-api-key": api_key} + data = {"size": 320, "confidence": 0.25, "iou": 0.45} + with open("ultralytics/assets/zidane.jpg", "rb") as f: + response = requests.post(url, headers=headers, data=data, files={"image": f}) + assert response.status_code == 200, f'Status code {response.status_code}, Reason {response.reason}' + print(json.dumps(response.json(), indent=2)) Benchmarks: + if: github.event_name != 'workflow_dispatch' || github.event.inputs.benchmarks == 'true' runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -75,12 +106,8 @@ jobs: shell: bash # for Windows compatibility run: | python -m pip install --upgrade pip wheel - if [ "${{ matrix.os }}" == "macos-latest" ]; then - pip install -e '.[export]' --extra-index-url https://download.pytorch.org/whl/cpu - else - pip install -e '.[export]' --extra-index-url https://download.pytorch.org/whl/cpu - fi - yolo export format=tflite imgsz=32 + pip install -e ".[export]" coverage --extra-index-url https://download.pytorch.org/whl/cpu + yolo export format=tflite imgsz=32 || true - name: Check environment run: | echo "RUNNER_OS is ${{ runner.os }}" @@ -93,44 +120,44 @@ jobs: pip --version pip list - name: Benchmark DetectionModel - shell: python - run: | - from ultralytics.yolo.utils.benchmarks import benchmark - benchmark(model='${{ matrix.model }}.pt', imgsz=160, half=False, hard_fail=0.20) + shell: bash + run: coverage run -a --source=ultralytics -m ultralytics.cfg.__init__ benchmark model='path with spaces/${{ matrix.model }}.pt' imgsz=160 verbose=0.26 - name: Benchmark SegmentationModel - shell: python - run: | - from ultralytics.yolo.utils.benchmarks import benchmark - benchmark(model='${{ matrix.model }}-seg.pt', imgsz=160, half=False, hard_fail=0.14) + shell: bash + run: coverage run -a --source=ultralytics -m ultralytics.cfg.__init__ benchmark model='path with spaces/${{ matrix.model }}-seg.pt' imgsz=160 verbose=0.30 - name: Benchmark ClassificationModel - shell: python - run: | - from ultralytics.yolo.utils.benchmarks import benchmark - benchmark(model='${{ matrix.model }}-cls.pt', imgsz=160, half=False, hard_fail=0.61) + shell: bash + run: coverage run -a --source=ultralytics -m ultralytics.cfg.__init__ benchmark model='path with spaces/${{ matrix.model }}-cls.pt' imgsz=160 verbose=0.36 - name: Benchmark PoseModel - shell: python + shell: bash + run: coverage run -a --source=ultralytics -m ultralytics.cfg.__init__ benchmark model='path with spaces/${{ matrix.model }}-pose.pt' imgsz=160 verbose=0.17 + - name: Merge Coverage Reports run: | - from ultralytics.yolo.utils.benchmarks import benchmark - benchmark(model='${{ matrix.model }}-pose.pt', imgsz=160, half=False, hard_fail=0.0) + coverage xml -o coverage-benchmarks.xml + - name: Upload Coverage Reports to CodeCov + uses: codecov/codecov-action@v3 + with: + flags: Benchmarks + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - name: Benchmark Summary run: | cat benchmarks.log echo "$(cat benchmarks.log)" >> $GITHUB_STEP_SUMMARY Tests: + if: github.event_name != 'workflow_dispatch' || github.event.inputs.tests == 'true' timeout-minutes: 60 runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest] - python-version: ['3.7', '3.8', '3.9', '3.10'] - model: [yolov8n] + python-version: ['3.11'] torch: [latest] include: - os: ubuntu-latest - python-version: '3.8' # torch 1.7.0 requires python >=3.6, <=3.8 - model: yolov8n + python-version: '3.8' # torch 1.8.0 requires python >=3.6, <=3.8 torch: '1.8.0' # min torch version CI https://pypi.org/project/torchvision/ steps: - uses: actions/checkout@v3 @@ -140,12 +167,12 @@ jobs: cache: 'pip' # caching pip dependencies - name: Install requirements shell: bash # for Windows compatibility - run: | + run: | # CoreML must be installed before export due to protobuf error from AutoInstall python -m pip install --upgrade pip wheel if [ "${{ matrix.torch }}" == "1.8.0" ]; then - pip install -e . torch==1.8.0 torchvision==0.9.0 pytest --extra-index-url https://download.pytorch.org/whl/cpu + pip install -e . torch==1.8.0 torchvision==0.9.0 pytest-cov "coremltools>=7.0.b1" --extra-index-url https://download.pytorch.org/whl/cpu else - pip install -e . pytest --extra-index-url https://download.pytorch.org/whl/cpu + pip install -e . pytest-cov "coremltools>=7.0.b1" --extra-index-url https://download.pytorch.org/whl/cpu fi - name: Check environment run: | @@ -158,41 +185,16 @@ jobs: python --version pip --version pip list - - name: Test Detect - shell: bash # for Windows compatibility - run: | - yolo detect train data=coco8.yaml model=yolov8n.yaml epochs=1 imgsz=32 - yolo detect train data=coco8.yaml model=yolov8n.pt epochs=1 imgsz=32 - yolo detect val data=coco8.yaml model=runs/detect/train/weights/last.pt imgsz=32 - yolo detect predict model=runs/detect/train/weights/last.pt imgsz=32 source=ultralytics/assets/bus.jpg - yolo export model=runs/detect/train/weights/last.pt imgsz=32 format=torchscript - - name: Test Segment - shell: bash # for Windows compatibility - run: | - yolo segment train data=coco8-seg.yaml model=yolov8n-seg.yaml epochs=1 imgsz=32 - yolo segment train data=coco8-seg.yaml model=yolov8n-seg.pt epochs=1 imgsz=32 - yolo segment val data=coco8-seg.yaml model=runs/segment/train/weights/last.pt imgsz=32 - yolo segment predict model=runs/segment/train/weights/last.pt imgsz=32 source=ultralytics/assets/bus.jpg - yolo export model=runs/segment/train/weights/last.pt imgsz=32 format=torchscript - - name: Test Classify - shell: bash # for Windows compatibility - run: | - yolo classify train data=imagenet10 model=yolov8n-cls.yaml epochs=1 imgsz=32 - yolo classify train data=imagenet10 model=yolov8n-cls.pt epochs=1 imgsz=32 - yolo classify val data=imagenet10 model=runs/classify/train/weights/last.pt imgsz=32 - yolo classify predict model=runs/classify/train/weights/last.pt imgsz=32 source=ultralytics/assets/bus.jpg - yolo export model=runs/classify/train/weights/last.pt imgsz=32 format=torchscript - - name: Test Pose - shell: bash # for Windows compatibility - run: | - yolo pose train data=coco8-pose.yaml model=yolov8n-pose.yaml epochs=1 imgsz=32 - yolo pose train data=coco8-pose.yaml model=yolov8n-pose.pt epochs=1 imgsz=32 - yolo pose val data=coco8-pose.yaml model=runs/pose/train/weights/last.pt imgsz=32 - yolo pose predict model=runs/pose/train/weights/last.pt imgsz=32 source=ultralytics/assets/bus.jpg - yolo export model=runs/pose/train/weights/last.pt imgsz=32 format=torchscript - name: Pytest tests shell: bash # for Windows compatibility - run: pytest tests + run: pytest --cov=ultralytics/ --cov-report xml tests/ + - name: Upload Coverage Reports to CodeCov + if: github.repository == 'ultralytics/ultralytics' && matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11' + uses: codecov/codecov-action@v3 + with: + flags: Tests + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} Summary: runs-on: ubuntu-latest @@ -201,7 +203,7 @@ jobs: steps: - name: Check for failure and notify if: (needs.HUB.result == 'failure' || needs.Benchmarks.result == 'failure' || needs.Tests.result == 'failure') && github.repository == 'ultralytics/ultralytics' && (github.event_name == 'schedule' || github.event_name == 'push') - uses: slackapi/slack-github-action@v1.23.0 + uses: slackapi/slack-github-action@v1.24.0 with: payload: | {"text": " GitHub Actions error for ${{ github.workflow }} ❌\n\n\n*Repository:* https://github.com/${{ github.repository }}\n*Action:* https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\n*Author:* ${{ github.actor }}\n*Event:* ${{ github.event_name }}\n"} diff --git a/downloads/ultralytics-main/.github/workflows/docker.yaml b/downloads/ultralytics-main/.github/workflows/docker.yaml index 58389207c..ee1d220c6 100644 --- a/downloads/ultralytics-main/.github/workflows/docker.yaml +++ b/downloads/ultralytics-main/.github/workflows/docker.yaml @@ -6,12 +6,47 @@ name: Publish Docker Images on: push: branches: [main] + workflow_dispatch: + inputs: + dockerfile: + type: choice + description: Select Dockerfile + options: + - Dockerfile-arm64 + - Dockerfile-jetson + - Dockerfile-python + - Dockerfile-cpu + - Dockerfile + push: + type: boolean + description: Push image to Docker Hub + default: true jobs: docker: if: github.repository == 'ultralytics/ultralytics' - name: Push Docker image to Docker Hub + name: Push runs-on: ubuntu-latest + strategy: + fail-fast: false + max-parallel: 5 + matrix: + include: + - dockerfile: "Dockerfile-arm64" + tags: "latest-arm64" + platforms: "linux/arm64" + - dockerfile: "Dockerfile-jetson" + tags: "latest-jetson" + platforms: "linux/arm64" + - dockerfile: "Dockerfile-python" + tags: "latest-python" + platforms: "linux/amd64" + - dockerfile: "Dockerfile-cpu" + tags: "latest-cpu" + platforms: "linux/amd64" + - dockerfile: "Dockerfile" + tags: "latest" + platforms: "linux/amd64" steps: - name: Checkout repo uses: actions/checkout@v3 @@ -28,40 +63,66 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build and push arm64 image - uses: docker/build-push-action@v4 - continue-on-error: true - with: - context: . - platforms: linux/arm64 - file: docker/Dockerfile-arm64 - push: true - tags: ultralytics/ultralytics:latest-arm64 + - name: Retrieve Ultralytics version + id: get_version + run: | + VERSION=$(grep "^__version__ =" ultralytics/__init__.py | awk -F"'" '{print $2}') + echo "Retrieved Ultralytics version: $VERSION" + echo "version=$VERSION" >> $GITHUB_OUTPUT - - name: Build and push Jetson image - uses: docker/build-push-action@v4 - continue-on-error: true - with: - context: . - platforms: linux/arm64 - file: docker/Dockerfile-jetson - push: true - tags: ultralytics/ultralytics:latest-jetson + VERSION_TAG=$(echo "${{ matrix.tags }}" | sed "s/latest/${VERSION}/") + echo "Intended version tag: $VERSION_TAG" + echo "version_tag=$VERSION_TAG" >> $GITHUB_OUTPUT - - name: Build and push CPU image - uses: docker/build-push-action@v4 - continue-on-error: true - with: - context: . - file: docker/Dockerfile-cpu - push: true - tags: ultralytics/ultralytics:latest-cpu + - name: Check if version tag exists on DockerHub + id: check_tag + run: | + RESPONSE=$(curl -s https://hub.docker.com/v2/repositories/ultralytics/ultralytics/tags/$VERSION_TAG) + MESSAGE=$(echo $RESPONSE | jq -r '.message') + if [[ "$MESSAGE" == "null" ]]; then + echo "Tag $VERSION_TAG already exists on DockerHub." + echo "exists=true" >> $GITHUB_OUTPUT + elif [[ "$MESSAGE" == *"404"* ]]; then + echo "Tag $VERSION_TAG does not exist on DockerHub." + echo "exists=false" >> $GITHUB_OUTPUT + else + echo "Unexpected response from DockerHub. Please check manually." + echo "exists=false" >> $GITHUB_OUTPUT + fi + env: + VERSION_TAG: ${{ steps.get_version.outputs.version_tag }} - - name: Build and push GPU image - uses: docker/build-push-action@v4 - continue-on-error: true + - name: Build Image + if: github.event_name == 'push' || github.event.inputs.dockerfile == matrix.dockerfile + run: | + docker build --platform ${{ matrix.platforms }} -f docker/${{ matrix.dockerfile }} \ + -t ultralytics/ultralytics:${{ matrix.tags }} \ + -t ultralytics/ultralytics:${{ steps.get_version.outputs.version_tag }} . + + - name: Run Tests + if: (github.event_name == 'push' || github.event.inputs.dockerfile == matrix.dockerfile) && matrix.platforms == 'linux/amd64' # arm64 images not supported on GitHub CI runners + run: docker run ultralytics/ultralytics:${{ matrix.tags }} /bin/bash -c "pip install pytest && pytest tests" + + - name: Run Benchmarks + # WARNING: Dockerfile (GPU) error on TF.js export 'module 'numpy' has no attribute 'object'. + if: (github.event_name == 'push' || github.event.inputs.dockerfile == matrix.dockerfile) && matrix.platforms == 'linux/amd64' && matrix.dockerfile != 'Dockerfile' # arm64 images not supported on GitHub CI runners + run: docker run ultralytics/ultralytics:${{ matrix.tags }} yolo benchmark model=yolov8n.pt imgsz=160 verbose=0.26 + + - name: Push Docker Image with Ultralytics version tag + if: (github.event_name == 'push' || (github.event.inputs.dockerfile == matrix.dockerfile && github.event.inputs.push == 'true')) && steps.check_tag.outputs.exists == 'false' + run: | + docker push ultralytics/ultralytics:${{ steps.get_version.outputs.version_tag }} + + - name: Push Docker Image with latest tag + if: github.event_name == 'push' || (github.event.inputs.dockerfile == matrix.dockerfile && github.event.inputs.push == 'true') + run: | + docker push ultralytics/ultralytics:${{ matrix.tags }} + + - name: Notify on failure + if: github.event_name == 'push' && failure() # do not notify on cancelled() as cancelling is performed by hand + uses: slackapi/slack-github-action@v1.24.0 with: - context: . - file: docker/Dockerfile - push: true - tags: ultralytics/ultralytics:latest + payload: | + {"text": " GitHub Actions error for ${{ github.workflow }} ❌\n\n\n*Repository:* https://github.com/${{ github.repository }}\n*Action:* https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\n*Author:* ${{ github.actor }}\n*Event:* ${{ github.event_name }}\n"} + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL_YOLO }} diff --git a/downloads/ultralytics-main/.github/workflows/greetings.yml b/downloads/ultralytics-main/.github/workflows/greetings.yml index 9813f3364..5f0289a5f 100644 --- a/downloads/ultralytics-main/.github/workflows/greetings.yml +++ b/downloads/ultralytics-main/.github/workflows/greetings.yml @@ -32,9 +32,11 @@ jobs: If this is a custom training ❓ Question, please provide as much information as possible, including dataset image examples and training logs, and verify you are following our [Tips for Best Training Results](https://docs.ultralytics.com/yolov5/tutorials/tips_for_best_training_results/). + Join the vibrant [Ultralytics Discord](https://ultralytics.com/discord) 🎧 community for real-time conversations and collaborations. This platform offers a perfect space to inquire, showcase your work, and connect with fellow Ultralytics users. + ## Install - Pip install the `ultralytics` package including all [requirements](https://github.com/ultralytics/ultralytics/blob/main/requirements.txt) in a [**Python>=3.7**](https://www.python.org/) environment with [**PyTorch>=1.7**](https://pytorch.org/get-started/locally/). + Pip install the `ultralytics` package including all [requirements](https://github.com/ultralytics/ultralytics/blob/main/requirements.txt) in a [**Python>=3.8**](https://www.python.org/) environment with [**PyTorch>=1.8**](https://pytorch.org/get-started/locally/). ```bash pip install ultralytics diff --git a/downloads/ultralytics-main/.github/workflows/links.yml b/downloads/ultralytics-main/.github/workflows/links.yml index cd65b961f..98803c7e1 100644 --- a/downloads/ultralytics-main/.github/workflows/links.yml +++ b/downloads/ultralytics-main/.github/workflows/links.yml @@ -28,7 +28,7 @@ jobs: timeout_minutes: 5 retry_wait_seconds: 60 max_attempts: 3 - command: lychee --accept 429,999 --exclude-loopback --exclude 'https?://(www\.)?(twitter\.com|instagram\.com)' --exclude-path '**/ci.yaml' --exclude-mail --github-token ${{ secrets.GITHUB_TOKEN }} './**/*.md' './**/*.html' + command: lychee --accept 429,999 --exclude-loopback --exclude 'https?://(www\.)?(linkedin\.com|twitter\.com|instagram\.com)' --exclude-path '**/ci.yaml' --exclude-mail --github-token ${{ secrets.GITHUB_TOKEN }} './**/*.md' './**/*.html' - name: Test Markdown, HTML, YAML, Python and Notebook links with retry if: github.event_name == 'workflow_dispatch' @@ -37,4 +37,4 @@ jobs: timeout_minutes: 5 retry_wait_seconds: 60 max_attempts: 3 - command: lychee --accept 429,999 --exclude-loopback --exclude 'https?://(www\.)?(twitter\.com|instagram\.com|url\.com)' --exclude-path '**/ci.yaml' --exclude-mail --github-token ${{ secrets.GITHUB_TOKEN }} './**/*.md' './**/*.html' './**/*.yml' './**/*.yaml' './**/*.py' './**/*.ipynb' + command: lychee --accept 429,999 --exclude-loopback --exclude 'https?://(www\.)?(linkedin\.com|twitter\.com|instagram\.com|url\.com)' --exclude-path '**/ci.yaml' --exclude-mail --github-token ${{ secrets.GITHUB_TOKEN }} './**/*.md' './**/*.html' './**/*.yml' './**/*.yaml' './**/*.py' './**/*.ipynb' diff --git a/downloads/ultralytics-main/.github/workflows/publish.yml b/downloads/ultralytics-main/.github/workflows/publish.yml index 38f92d24e..4e590afba 100644 --- a/downloads/ultralytics-main/.github/workflows/publish.yml +++ b/downloads/ultralytics-main/.github/workflows/publish.yml @@ -33,14 +33,14 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip wheel build twine - pip install -e '.[dev]' --extra-index-url https://download.pytorch.org/whl/cpu + pip install -e ".[dev]" --extra-index-url https://download.pytorch.org/whl/cpu - name: Check PyPI version shell: python run: | import os import pkg_resources as pkg import ultralytics - from ultralytics.yolo.utils.checks import check_latest_pypi_version + from ultralytics.utils.checks import check_latest_pypi_version v_local = pkg.parse_version(ultralytics.__version__).release v_pypi = pkg.parse_version(check_latest_pypi_version()).release @@ -63,7 +63,7 @@ jobs: python -m twine upload dist/* -u __token__ -p $PYPI_TOKEN - name: Deploy Docs continue-on-error: true - if: (github.event_name == 'push' && steps.check_pypi.outputs.increment == 'True') || github.event.inputs.docs == 'true' + if: (github.event_name == 'push' || github.event.inputs.docs == 'true') && github.repository == 'ultralytics/ultralytics' && github.actor == 'glenn-jocher' env: PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} run: | @@ -94,7 +94,7 @@ jobs: echo "PR_TITLE=$PR_TITLE" >> $GITHUB_ENV - name: Notify on Slack (Success) if: success() && github.event_name == 'push' && steps.check_pypi.outputs.increment == 'True' - uses: slackapi/slack-github-action@v1.23.0 + uses: slackapi/slack-github-action@v1.24.0 with: payload: | {"text": " GitHub Actions success for ${{ github.workflow }} ✅\n\n\n*Repository:* https://github.com/${{ github.repository }}\n*Action:* https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\n*Author:* ${{ github.actor }}\n*Event:* NEW 'ultralytics ${{ steps.check_pypi.outputs.version }}' pip package published 😃\n*Job Status:* ${{ job.status }}\n*Pull Request:* ${{ env.PR_TITLE }}\n"} @@ -102,7 +102,7 @@ jobs: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL_YOLO }} - name: Notify on Slack (Failure) if: failure() - uses: slackapi/slack-github-action@v1.23.0 + uses: slackapi/slack-github-action@v1.24.0 with: payload: | {"text": " GitHub Actions error for ${{ github.workflow }} ❌\n\n\n*Repository:* https://github.com/${{ github.repository }}\n*Action:* https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\n*Author:* ${{ github.actor }}\n*Event:* ${{ github.event_name }}\n*Job Status:* ${{ job.status }}\n*Pull Request:* ${{ env.PR_TITLE }}\n"} diff --git a/downloads/ultralytics-main/.gitignore b/downloads/ultralytics-main/.gitignore index f8dcff976..d197c74d7 100644 --- a/downloads/ultralytics-main/.gitignore +++ b/downloads/ultralytics-main/.gitignore @@ -118,11 +118,15 @@ venv.bak/ .spyderproject .spyproject +# VSCode project settings +.vscode/ + # Rope project settings .ropeproject # mkdocs documentation /site +mkdocs_github_authors.yaml # mypy .mypy_cache/ @@ -136,7 +140,6 @@ dmypy.json datasets/ runs/ wandb/ - .DS_Store # Neural Network weights ----------------------------------------------------------------------------------------------- @@ -147,6 +150,7 @@ weights/ *.onnx *.engine *.mlmodel +*.mlpackage *.torchscript *.tflite *.h5 @@ -154,3 +158,6 @@ weights/ *_web_model/ *_openvino_model/ *_paddle_model/ + +# Autogenerated files for tests +/ultralytics/assets/ diff --git a/downloads/ultralytics-main/.pre-commit-config.yaml b/downloads/ultralytics-main/.pre-commit-config.yaml index 60b2b305c..efbdd7c65 100644 --- a/downloads/ultralytics-main/.pre-commit-config.yaml +++ b/downloads/ultralytics-main/.pre-commit-config.yaml @@ -22,7 +22,7 @@ repos: - id: detect-private-key - repo: https://github.com/asottile/pyupgrade - rev: v3.3.2 + rev: v3.10.1 hooks: - id: pyupgrade name: Upgrade code @@ -34,7 +34,7 @@ repos: name: Sort imports - repo: https://github.com/google/yapf - rev: v0.33.0 + rev: v0.40.0 hooks: - id: yapf name: YAPF formatting @@ -50,17 +50,17 @@ repos: # exclude: "README.md|README.zh-CN.md|CONTRIBUTING.md" - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 6.1.0 hooks: - id: flake8 name: PEP8 - repo: https://github.com/codespell-project/codespell - rev: v2.2.4 + rev: v2.2.5 hooks: - id: codespell args: - - --ignore-words-list=crate,nd,strack,dota + - --ignore-words-list=crate,nd,strack,dota,ane,segway,fo # - repo: https://github.com/asottile/yesqa # rev: v1.4.0 diff --git a/downloads/ultralytics-main/CONTRIBUTING.md b/downloads/ultralytics-main/CONTRIBUTING.md index 932690664..a4f12c6a4 100644 --- a/downloads/ultralytics-main/CONTRIBUTING.md +++ b/downloads/ultralytics-main/CONTRIBUTING.md @@ -65,7 +65,7 @@ Here is an example: ```python """ - What the function does. Performs NMS on given detection predictions. + What the function does. Performs NMS on given detection predictions. Args: arg1: The description of the 1st argument diff --git a/downloads/ultralytics-main/README.md b/downloads/ultralytics-main/README.md index c376b7b20..83e6d35e2 100644 --- a/downloads/ultralytics-main/README.md +++ b/downloads/ultralytics-main/README.md @@ -9,6 +9,7 @@
Ultralytics CI + Ultralytics Code Coverage YOLOv8 Citation Docker Pulls
@@ -20,7 +21,7 @@ [Ultralytics](https://ultralytics.com) [YOLOv8](https://github.com/ultralytics/ultralytics) is a cutting-edge, state-of-the-art (SOTA) model that builds upon the success of previous YOLO versions and introduces new features and improvements to further boost performance and flexibility. YOLOv8 is designed to be fast, accurate, and easy to use, making it an excellent choice for a wide range of object detection and tracking, instance segmentation, image classification and pose estimation tasks. -We hope that the resources here will help you get the most out of YOLOv8. Please browse the YOLOv8 Docs for details, raise an issue on GitHub for support, and join our Discord community for questions and discussions! +We hope that the resources here will help you get the most out of YOLOv8. Please browse the YOLOv8 Docs for details, raise an issue on GitHub for support, and join our Discord community for questions and discussions! To request an Enterprise License please complete the form at [Ultralytics Licensing](https://ultralytics.com/license). @@ -30,7 +31,7 @@ To request an Enterprise License please complete the form at [Ultralytics Licens - + @@ -45,7 +46,7 @@ To request an Enterprise License please complete the form at [Ultralytics Licens - +
@@ -57,12 +58,16 @@ See below for a quickstart installation and usage example, and see the [YOLOv8 D
Install -Pip install the ultralytics package including all [requirements](https://github.com/ultralytics/ultralytics/blob/main/requirements.txt) in a [**Python>=3.7**](https://www.python.org/) environment with [**PyTorch>=1.7**](https://pytorch.org/get-started/locally/). +Pip install the ultralytics package including all [requirements](https://github.com/ultralytics/ultralytics/blob/main/requirements.txt) in a [**Python>=3.8**](https://www.python.org/) environment with [**PyTorch>=1.8**](https://pytorch.org/get-started/locally/). + +[![PyPI version](https://badge.fury.io/py/ultralytics.svg)](https://badge.fury.io/py/ultralytics) [![Downloads](https://static.pepy.tech/badge/ultralytics)](https://pepy.tech/project/ultralytics) ```bash pip install ultralytics ``` +For alternative installation methods including [Conda](https://anaconda.org/conda-forge/ultralytics), [Docker](https://hub.docker.com/r/ultralytics/ultralytics), and Git, please refer to the [Quickstart Guide](https://docs.ultralytics.com/quickstart). +
@@ -93,18 +98,20 @@ model = YOLO("yolov8n.pt") # load a pretrained model (recommended for training) model.train(data="coco128.yaml", epochs=3) # train the model metrics = model.val() # evaluate model performance on the validation set results = model("https://ultralytics.com/images/bus.jpg") # predict on an image -success = model.export(format="onnx") # export the model to ONNX format +path = model.export(format="onnx") # export the model to ONNX format ``` -[Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models) download automatically from the latest Ultralytics [release](https://github.com/ultralytics/assets/releases). See YOLOv8 [Python Docs](https://docs.ultralytics.com/usage/python) for more examples. +[Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models) download automatically from the latest Ultralytics [release](https://github.com/ultralytics/assets/releases). See YOLOv8 [Python Docs](https://docs.ultralytics.com/usage/python) for more examples.
##
Models
-All YOLOv8 pretrained models are available here. Detect, Segment and Pose models are pretrained on the [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/coco.yaml) dataset, while Classify models are pretrained on the [ImageNet](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/ImageNet.yaml) dataset. +YOLOv8 [Detect](https://docs.ultralytics.com/tasks/detect), [Segment](https://docs.ultralytics.com/tasks/segment) and [Pose](https://docs.ultralytics.com/tasks/pose) models pretrained on the [COCO](https://docs.ultralytics.com/datasets/detect/coco) dataset are available here, as well as YOLOv8 [Classify](https://docs.ultralytics.com/tasks/classify) models pretrained on the [ImageNet](https://docs.ultralytics.com/datasets/classify/imagenet) dataset. [Track](https://docs.ultralytics.com/modes/track) mode is available for all Detect, Segment and Pose models. -[Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models) download automatically from the latest Ultralytics [release](https://github.com/ultralytics/assets/releases) on first use. + + +All [Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models) download automatically from the latest Ultralytics [release](https://github.com/ultralytics/assets/releases) on first use.
Detection @@ -186,6 +193,8 @@ See [Pose Docs](https://docs.ultralytics.com/tasks/pose) for usage examples with ##
Integrations
+Our key integrations with leading AI platforms extend the functionality of Ultralytics' offerings, enhancing tasks like dataset labeling, training, visualization, and model management. Discover how Ultralytics, in collaboration with [Roboflow](https://roboflow.com/?ref=ultralytics), ClearML, [Comet](https://bit.ly/yolov8-readme-comet), Neural Magic and [OpenVINO](https://docs.ultralytics.com/integrations/openvino), can optimize your AI workflow. +
@@ -228,21 +237,21 @@ We love your input! YOLOv5 and YOLOv8 would not be possible without help from ou ##
License
-YOLOv8 is available under two different licenses: +Ultralytics offers two licensing options to accommodate diverse use cases: -- **AGPL-3.0 License**: See [LICENSE](https://github.com/ultralytics/ultralytics/blob/main/LICENSE) file for details. -- **Enterprise License**: Provides greater flexibility for commercial product development without the open-source requirements of AGPL-3.0. Typical use cases are embedding Ultralytics software and AI models in commercial products and applications. Request an Enterprise License at [Ultralytics Licensing](https://ultralytics.com/license). +- **AGPL-3.0 License**: This [OSI-approved](https://opensource.org/licenses/) open-source license is ideal for students and enthusiasts, promoting open collaboration and knowledge sharing. See the [LICENSE](https://github.com/ultralytics/ultralytics/blob/main/LICENSE) file for more details. +- **Enterprise License**: Designed for commercial use, this license permits seamless integration of Ultralytics software and AI models into commercial goods and services, bypassing the open-source requirements of AGPL-3.0. If your scenario involves embedding our solutions into a commercial offering, reach out through [Ultralytics Licensing](https://ultralytics.com/license). ##
Contact
-For YOLOv8 bug reports and feature requests please visit [GitHub Issues](https://github.com/ultralytics/ultralytics/issues), and join our [Discord](https://discord.gg/n6cFeSPZdD) community for questions and discussions! +For Ultralytics bug reports and feature requests please visit [GitHub Issues](https://github.com/ultralytics/ultralytics/issues), and join our [Discord](https://ultralytics.com/discord) community for questions and discussions!
- + @@ -257,6 +266,6 @@ For YOLOv8 bug reports and feature requests please visit [GitHub Issues](https:/ - +
diff --git a/downloads/ultralytics-main/README.zh-CN.md b/downloads/ultralytics-main/README.zh-CN.md index 8b85887e8..a11868afa 100644 --- a/downloads/ultralytics-main/README.zh-CN.md +++ b/downloads/ultralytics-main/README.zh-CN.md @@ -9,6 +9,7 @@
Ultralytics CI + Ultralytics Code Coverage YOLOv8 Citation Docker Pulls
@@ -20,7 +21,7 @@ [Ultralytics](https://ultralytics.com) [YOLOv8](https://github.com/ultralytics/ultralytics) 是一款前沿、最先进(SOTA)的模型,基于先前 YOLO 版本的成功,引入了新功能和改进,进一步提升性能和灵活性。YOLOv8 设计快速、准确且易于使用,使其成为各种物体检测与跟踪、实例分割、图像分类和姿态估计任务的绝佳选择。 -我们希望这里的资源能帮助您充分利用 YOLOv8。请浏览 YOLOv8 文档 了解详细信息,在 GitHub 上提交问题以获得支持,并加入我们的 Discord 社区进行问题和讨论! +我们希望这里的资源能帮助您充分利用 YOLOv8。请浏览 YOLOv8 文档 了解详细信息,在 GitHub 上提交问题以获得支持,并加入我们的 Discord 社区进行问题和讨论! 如需申请企业许可,请在 [Ultralytics Licensing](https://ultralytics.com/license) 处填写表格 @@ -30,7 +31,7 @@ - + @@ -45,7 +46,7 @@ - +
@@ -57,12 +58,16 @@
安装 -在一个 [**Python>=3.7**](https://www.python.org/) 环境中,使用 [**PyTorch>=1.7**](https://pytorch.org/get-started/locally/),通过 pip 安装 ultralytics 软件包以及所有[依赖项](https://github.com/ultralytics/ultralytics/blob/main/requirements.txt)。 +使用Pip在一个[**Python>=3.8**](https://www.python.org/)环境中安装`ultralytics`包,此环境还需包含[**PyTorch>=1.8**](https://pytorch.org/get-started/locally/)。这也会安装所有必要的[依赖项](https://github.com/ultralytics/ultralytics/blob/main/requirements.txt)。 + +[![PyPI version](https://badge.fury.io/py/ultralytics.svg)](https://badge.fury.io/py/ultralytics) [![Downloads](https://static.pepy.tech/badge/ultralytics)](https://pepy.tech/project/ultralytics) ```bash pip install ultralytics ``` +如需使用包括[Conda](https://anaconda.org/conda-forge/ultralytics)、[Docker](https://hub.docker.com/r/ultralytics/ultralytics)和Git在内的其他安装方法,请参考[快速入门指南](https://docs.ultralytics.com/quickstart)。 +
@@ -96,15 +101,17 @@ results = model("https://ultralytics.com/images/bus.jpg") # 对图像进行预 success = model.export(format="onnx") # 将模型导出为 ONNX 格式 ``` -[模型](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models) 会自动从最新的 Ultralytics [发布版本](https://github.com/ultralytics/assets/releases)中下载。查看 YOLOv8 [Python 文档](https://docs.ultralytics.com/usage/python)以获取更多示例。 +[模型](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models) 会自动从最新的 Ultralytics [发布版本](https://github.com/ultralytics/assets/releases)中下载。查看 YOLOv8 [Python 文档](https://docs.ultralytics.com/usage/python)以获取更多示例。
##
模型
-所有的 YOLOv8 预训练模型都可以在此找到。检测、分割和姿态模型在 [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/coco.yaml) 数据集上进行预训练,而分类模型在 [ImageNet](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/ImageNet.yaml) 数据集上进行预训练。 +在[COCO](https://docs.ultralytics.com/datasets/detect/coco)数据集上预训练的YOLOv8 [检测](https://docs.ultralytics.com/tasks/detect),[分割](https://docs.ultralytics.com/tasks/segment)和[姿态](https://docs.ultralytics.com/tasks/pose)模型可以在这里找到,以及在[ImageNet](https://docs.ultralytics.com/datasets/classify/imagenet)数据集上预训练的YOLOv8 [分类](https://docs.ultralytics.com/tasks/classify)模型。所有的检测,分割和姿态模型都支持[追踪](https://docs.ultralytics.com/modes/track)模式。 -在首次使用时,[模型](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models) 会自动从最新的 Ultralytics [发布版本](https://github.com/ultralytics/assets/releases)中下载。 + + +所有[模型](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models)在首次使用时会自动从最新的Ultralytics [发布版本](https://github.com/ultralytics/assets/releases)下载。
检测 @@ -185,6 +192,8 @@ success = model.export(format="onnx") # 将模型导出为 ONNX 格式 ##
集成
+我们与领先的AI平台的关键整合扩展了Ultralytics产品的功能,增强了数据集标签化、训练、可视化和模型管理等任务。探索Ultralytics如何与[Roboflow](https://roboflow.com/?ref=ultralytics)、ClearML、[Comet](https://bit.ly/yolov8-readme-comet)、Neural Magic以及[OpenVINO](https://docs.ultralytics.com/integrations/openvino)合作,优化您的AI工作流程。 +
@@ -227,21 +236,21 @@ success = model.export(format="onnx") # 将模型导出为 ONNX 格式 ##
许可证
-YOLOv8 提供两种不同的许可证: +Ultralytics 提供两种许可证选项以适应各种使用场景: -- **AGPL-3.0 许可证**:详细信息请参阅 [LICENSE](https://github.com/ultralytics/ultralytics/blob/main/LICENSE) 文件。 -- **企业许可证**:为商业产品开发提供更大的灵活性,无需遵循 AGPL-3.0 的开源要求。典型的用例是将 Ultralytics 软件和 AI 模型嵌入商业产品和应用中。在 [Ultralytics 授权](https://ultralytics.com/license) 处申请企业许可证。 +- **AGPL-3.0 许可证**:这个[OSI 批准](https://opensource.org/licenses/)的开源许可证非常适合学生和爱好者,可以推动开放的协作和知识分享。请查看[LICENSE](https://github.com/ultralytics/ultralytics/blob/main/LICENSE) 文件以了解更多细节。 +- **企业许可证**:专为商业用途设计,该许可证允许将 Ultralytics 的软件和 AI 模型无缝集成到商业产品和服务中,从而绕过 AGPL-3.0 的开源要求。如果您的场景涉及将我们的解决方案嵌入到商业产品中,请通过 [Ultralytics Licensing](https://ultralytics.com/license)与我们联系。 ##
联系方式
-对于 YOLOv8 的错误报告和功能请求,请访问 [GitHub Issues](https://github.com/ultralytics/ultralytics/issues),并加入我们的 [Discord](https://discord.gg/n6cFeSPZdD) 社区进行问题和讨论! +对于 Ultralytics 的错误报告和功能请求,请访问 [GitHub Issues](https://github.com/ultralytics/ultralytics/issues),并加入我们的 [Discord](https://ultralytics.com/discord) 社区进行问题和讨论!
- + @@ -255,6 +264,6 @@ YOLOv8 提供两种不同的许可证: - +
diff --git a/downloads/ultralytics-main/docker/Dockerfile b/downloads/ultralytics-main/docker/Dockerfile index 656c0742b..81b9f9956 100644 --- a/downloads/ultralytics-main/docker/Dockerfile +++ b/downloads/ultralytics-main/docker/Dockerfile @@ -3,15 +3,16 @@ # Image is CUDA-optimized for YOLOv8 single/multi-GPU training and inference # Start FROM PyTorch image https://hub.docker.com/r/pytorch/pytorch or nvcr.io/nvidia/pytorch:23.03-py3 -FROM pytorch/pytorch:2.0.0-cuda11.7-cudnn8-runtime +FROM pytorch/pytorch:2.0.1-cuda11.7-cudnn8-runtime +RUN pip install --no-cache nvidia-tensorrt --index-url https://pypi.ngc.nvidia.com # Downloads to user config dir ADD https://ultralytics.com/assets/Arial.ttf https://ultralytics.com/assets/Arial.Unicode.ttf /root/.config/Ultralytics/ # Install linux packages -# g++ required to build 'tflite_support' package +# g++ required to build 'tflite_support' and 'lap' packages, libusb-1.0-0 required for 'tflite_support' package RUN apt update \ - && apt install --no-install-recommends -y gcc git zip curl htop libgl1-mesa-glx libglib2.0-0 libpython3-dev gnupg g++ + && apt install --no-install-recommends -y gcc git zip curl htop libgl1-mesa-glx libglib2.0-0 libpython3-dev gnupg g++ libusb-1.0-0 # RUN alias python=python3 # Security updates @@ -19,7 +20,6 @@ RUN apt update \ RUN apt upgrade --no-install-recommends -y openssl tar # Create working directory -RUN mkdir -p /usr/src/ultralytics WORKDIR /usr/src/ultralytics # Copy contents @@ -29,10 +29,22 @@ ADD https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n.pt /u # Install pip packages RUN python3 -m pip install --upgrade pip wheel -RUN pip install --no-cache -e . albumentations comet tensorboard +RUN pip install --no-cache -e ".[export]" thop albumentations comet pycocotools + +# Run exports to AutoInstall packages +RUN yolo export model=tmp/yolov8n.pt format=edgetpu imgsz=32 +RUN yolo export model=tmp/yolov8n.pt format=ncnn imgsz=32 +# Requires <= Python 3.10, bug with paddlepaddle==2.5.0 +RUN pip install --no-cache paddlepaddle==2.4.2 x2paddle +# Fix error: `np.bool` was a deprecated alias for the builtin `bool` +RUN pip install --no-cache numpy==1.23.5 +# Remove exported models +RUN rm -rf tmp # Set environment variables ENV OMP_NUM_THREADS=1 +# Avoid DDP error "MKL_THREADING_LAYER=INTEL is incompatible with libgomp.so.1 library" https://github.com/pytorch/pytorch/issues/37377 +ENV MKL_THREADING_LAYER=GNU # Usage Examples ------------------------------------------------------------------------------------------------------- diff --git a/downloads/ultralytics-main/docker/Dockerfile-arm64 b/downloads/ultralytics-main/docker/Dockerfile-arm64 index c11dba444..e4c7be4a8 100644 --- a/downloads/ultralytics-main/docker/Dockerfile-arm64 +++ b/downloads/ultralytics-main/docker/Dockerfile-arm64 @@ -9,12 +9,12 @@ FROM arm64v8/ubuntu:22.10 ADD https://ultralytics.com/assets/Arial.ttf https://ultralytics.com/assets/Arial.Unicode.ttf /root/.config/Ultralytics/ # Install linux packages +# g++ required to build 'tflite_support' and 'lap' packages, libusb-1.0-0 required for 'tflite_support' package RUN apt update \ - && apt install --no-install-recommends -y python3-pip git zip curl htop gcc libgl1-mesa-glx libglib2.0-0 libpython3-dev + && apt install --no-install-recommends -y python3-pip git zip curl htop gcc libgl1-mesa-glx libglib2.0-0 libpython3-dev gnupg g++ libusb-1.0-0 # RUN alias python=python3 # Create working directory -RUN mkdir -p /usr/src/ultralytics WORKDIR /usr/src/ultralytics # Copy contents @@ -24,7 +24,7 @@ ADD https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n.pt /u # Install pip packages RUN python3 -m pip install --upgrade pip wheel -RUN pip install --no-cache -e . +RUN pip install --no-cache -e . thop # Usage Examples ------------------------------------------------------------------------------------------------------- @@ -32,5 +32,8 @@ RUN pip install --no-cache -e . # Build and Push # t=ultralytics/ultralytics:latest-arm64 && sudo docker build --platform linux/arm64 -f docker/Dockerfile-arm64 -t $t . && sudo docker push $t -# Pull and Run +# Run +# t=ultralytics/ultralytics:latest-arm64 && sudo docker run -it --ipc=host $t + +# Pull and Run with local volume mounted # t=ultralytics/ultralytics:latest-arm64 && sudo docker pull $t && sudo docker run -it --ipc=host -v "$(pwd)"/datasets:/usr/src/datasets $t diff --git a/downloads/ultralytics-main/docker/Dockerfile-cpu b/downloads/ultralytics-main/docker/Dockerfile-cpu index fa6ec12c6..3e635963b 100644 --- a/downloads/ultralytics-main/docker/Dockerfile-cpu +++ b/downloads/ultralytics-main/docker/Dockerfile-cpu @@ -3,19 +3,18 @@ # Image is CPU-optimized for ONNX, OpenVINO and PyTorch YOLOv8 deployments # Start FROM Ubuntu image https://hub.docker.com/_/ubuntu -FROM ubuntu:22.10 +FROM ubuntu:lunar-20230615 # Downloads to user config dir ADD https://ultralytics.com/assets/Arial.ttf https://ultralytics.com/assets/Arial.Unicode.ttf /root/.config/Ultralytics/ # Install linux packages -# g++ required to build 'tflite_support' package +# g++ required to build 'tflite_support' and 'lap' packages, libusb-1.0-0 required for 'tflite_support' package RUN apt update \ - && apt install --no-install-recommends -y python3-pip git zip curl htop libgl1-mesa-glx libglib2.0-0 libpython3-dev gnupg g++ + && apt install --no-install-recommends -y python3-pip git zip curl htop libgl1-mesa-glx libglib2.0-0 libpython3-dev gnupg g++ libusb-1.0-0 # RUN alias python=python3 # Create working directory -RUN mkdir -p /usr/src/ultralytics WORKDIR /usr/src/ultralytics # Copy contents @@ -23,15 +22,28 @@ WORKDIR /usr/src/ultralytics RUN git clone https://github.com/ultralytics/ultralytics /usr/src/ultralytics ADD https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n.pt /usr/src/ultralytics/ +# Remove python3.11/EXTERNALLY-MANAGED or use 'pip install --break-system-packages' avoid 'externally-managed-environment' Ubuntu nightly error +RUN rm -rf /usr/lib/python3.11/EXTERNALLY-MANAGED + # Install pip packages RUN python3 -m pip install --upgrade pip wheel -RUN pip install --no-cache -e . --extra-index-url https://download.pytorch.org/whl/cpu +RUN pip install --no-cache -e ".[export]" thop --extra-index-url https://download.pytorch.org/whl/cpu +# Run exports to AutoInstall packages +RUN yolo export model=tmp/yolov8n.pt format=edgetpu imgsz=32 +RUN yolo export model=tmp/yolov8n.pt format=ncnn imgsz=32 +# Requires <= Python 3.10, bug with paddlepaddle==2.5.0 +# RUN pip install --no-cache paddlepaddle==2.4.2 x2paddle +# Remove exported models +RUN rm -rf tmp # Usage Examples ------------------------------------------------------------------------------------------------------- # Build and Push # t=ultralytics/ultralytics:latest-cpu && sudo docker build -f docker/Dockerfile-cpu -t $t . && sudo docker push $t -# Pull and Run +# Run +# t=ultralytics/ultralytics:latest-cpu && sudo docker run -it --ipc=host $t + +# Pull and Run with local volume mounted # t=ultralytics/ultralytics:latest-cpu && sudo docker pull $t && sudo docker run -it --ipc=host -v "$(pwd)"/datasets:/usr/src/datasets $t diff --git a/downloads/ultralytics-main/docker/Dockerfile-jetson b/downloads/ultralytics-main/docker/Dockerfile-jetson index fc4971cd2..11f92f2ec 100644 --- a/downloads/ultralytics-main/docker/Dockerfile-jetson +++ b/downloads/ultralytics-main/docker/Dockerfile-jetson @@ -9,13 +9,12 @@ FROM nvcr.io/nvidia/l4t-pytorch:r35.2.1-pth2.0-py3 ADD https://ultralytics.com/assets/Arial.ttf https://ultralytics.com/assets/Arial.Unicode.ttf /root/.config/Ultralytics/ # Install linux packages -# g++ required to build 'tflite_support' package +# g++ required to build 'tflite_support' and 'lap' packages, libusb-1.0-0 required for 'tflite_support' package RUN apt update \ - && apt install --no-install-recommends -y gcc git zip curl htop libgl1-mesa-glx libglib2.0-0 libpython3-dev gnupg g++ + && apt install --no-install-recommends -y gcc git zip curl htop libgl1-mesa-glx libglib2.0-0 libpython3-dev gnupg g++ libusb-1.0-0 # RUN alias python=python3 # Create working directory -RUN mkdir -p /usr/src/ultralytics WORKDIR /usr/src/ultralytics # Copy contents @@ -23,9 +22,12 @@ WORKDIR /usr/src/ultralytics RUN git clone https://github.com/ultralytics/ultralytics /usr/src/ultralytics ADD https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n.pt /usr/src/ultralytics/ +# Remove opencv-python from requirements.txt as it conflicts with opencv-python installed in base image +RUN grep -v '^opencv-python' requirements.txt > tmp.txt && mv tmp.txt requirements.txt + # Install pip packages manually for TensorRT compatibility https://github.com/NVIDIA/TensorRT/issues/2567 RUN python3 -m pip install --upgrade pip wheel -RUN pip install --no-cache tqdm matplotlib pyyaml psutil pandas onnx "numpy==1.23" +RUN pip install --no-cache tqdm matplotlib pyyaml psutil pandas onnx thop "numpy==1.23" RUN pip install --no-cache -e . # Set environment variables @@ -37,5 +39,8 @@ ENV OMP_NUM_THREADS=1 # Build and Push # t=ultralytics/ultralytics:latest-jetson && sudo docker build --platform linux/arm64 -f docker/Dockerfile-jetson -t $t . && sudo docker push $t -# Pull and Run -# t=ultralytics/ultralytics:jetson && sudo docker pull $t && sudo docker run -it --runtime=nvidia $t +# Run +# t=ultralytics/ultralytics:latest-jetson && sudo docker run -it --ipc=host $t + +# Pull and Run with NVIDIA runtime +# t=ultralytics/ultralytics:latest-jetson && sudo docker pull $t && sudo docker run -it --ipc=host --runtime=nvidia $t diff --git a/downloads/ultralytics-main/docker/Dockerfile-python b/downloads/ultralytics-main/docker/Dockerfile-python new file mode 100644 index 000000000..ecb2f651b --- /dev/null +++ b/downloads/ultralytics-main/docker/Dockerfile-python @@ -0,0 +1,49 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license +# Builds ultralytics/ultralytics:latest-cpu image on DockerHub https://hub.docker.com/r/ultralytics/ultralytics +# Image is CPU-optimized for ONNX, OpenVINO and PyTorch YOLOv8 deployments + +# Use the official Python 3.10 slim-bookworm as base image +FROM python:3.10-slim-bookworm + +# Downloads to user config dir +ADD https://ultralytics.com/assets/Arial.ttf https://ultralytics.com/assets/Arial.Unicode.ttf /root/.config/Ultralytics/ + +# Install linux packages +# g++ required to build 'tflite_support' and 'lap' packages, libusb-1.0-0 required for 'tflite_support' package +RUN apt update \ + && apt install --no-install-recommends -y python3-pip git zip curl htop libgl1-mesa-glx libglib2.0-0 libpython3-dev gnupg g++ libusb-1.0-0 +# RUN alias python=python3 + +# Create working directory +WORKDIR /usr/src/ultralytics + +# Copy contents +# COPY . /usr/src/app (issues as not a .git directory) +RUN git clone https://github.com/ultralytics/ultralytics /usr/src/ultralytics +ADD https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n.pt /usr/src/ultralytics/ + +# Remove python3.11/EXTERNALLY-MANAGED or use 'pip install --break-system-packages' avoid 'externally-managed-environment' Ubuntu nightly error +# RUN rm -rf /usr/lib/python3.11/EXTERNALLY-MANAGED + +# Install pip packages +RUN python3 -m pip install --upgrade pip wheel +RUN pip install --no-cache -e ".[export]" thop --extra-index-url https://download.pytorch.org/whl/cpu + +# Run exports to AutoInstall packages +RUN yolo export model=tmp/yolov8n.pt format=edgetpu imgsz=32 +RUN yolo export model=tmp/yolov8n.pt format=ncnn imgsz=32 +# Requires <= Python 3.10, bug with paddlepaddle==2.5.0 +RUN pip install --no-cache paddlepaddle==2.4.2 x2paddle +# Remove exported models +RUN rm -rf tmp + +# Usage Examples ------------------------------------------------------------------------------------------------------- + +# Build and Push +# t=ultralytics/ultralytics:latest-python && sudo docker build -f docker/Dockerfile-python -t $t . && sudo docker push $t + +# Run +# t=ultralytics/ultralytics:latest-python && sudo docker run -it --ipc=host $t + +# Pull and Run with local volume mounted +# t=ultralytics/ultralytics:latest-python && sudo docker pull $t && sudo docker run -it --ipc=host -v "$(pwd)"/datasets:/usr/src/datasets $t diff --git a/downloads/ultralytics-main/docs/CNAME b/downloads/ultralytics-main/docs/CNAME index 773aac86c..339382a7a 100644 --- a/downloads/ultralytics-main/docs/CNAME +++ b/downloads/ultralytics-main/docs/CNAME @@ -1 +1 @@ -docs.ultralytics.com \ No newline at end of file +docs.ultralytics.com diff --git a/downloads/ultralytics-main/docs/README.md b/downloads/ultralytics-main/docs/README.md index de9d2a1e4..44dece6bc 100644 --- a/downloads/ultralytics-main/docs/README.md +++ b/downloads/ultralytics-main/docs/README.md @@ -1,5 +1,6 @@ --- -description: Learn how to install the Ultralytics package in developer mode and build/serve locally using MkDocs. Deploy your project to your host easily. +description: Learn how to install Ultralytics in developer mode, build and serve it locally for testing, and deploy your documentation site on platforms like GitHub Pages, GitLab Pages, and Amazon S3. +keywords: Ultralytics, documentation, mkdocs, installation, developer mode, building, deployment, local server, GitHub Pages, GitLab Pages, Amazon S3 --- # Ultralytics Docs @@ -26,7 +27,7 @@ cd ultralytics 3. Install the package in developer mode using pip: ```bash -pip install -e '.[dev]' +pip install -e ".[dev]" ``` This will install the ultralytics package and its dependencies in developer mode, allowing you to make changes to the @@ -86,4 +87,4 @@ for your repository and updating the "Custom domain" field in the "GitHub Pages" ![196814117-fc16e711-d2be-4722-9536-b7c6d78fd167](https://user-images.githubusercontent.com/26833433/210150206-9e86dcd7-10af-43e4-9eb2-9518b3799eac.png) For more information on deploying your MkDocs documentation site, see -the [MkDocs documentation](https://www.mkdocs.org/user-guide/deploying-your-docs/). \ No newline at end of file +the [MkDocs documentation](https://www.mkdocs.org/user-guide/deploying-your-docs/). diff --git a/downloads/ultralytics-main/docs/SECURITY.md b/downloads/ultralytics-main/docs/SECURITY.md index afbbf28ce..b7320e352 100644 --- a/downloads/ultralytics-main/docs/SECURITY.md +++ b/downloads/ultralytics-main/docs/SECURITY.md @@ -1,32 +1,26 @@ --- -description: Learn how Ultralytics prioritize security. Get insights into Snyk and GitHub CodeQL scans, and how to report security issues in YOLOv8. +description: Discover how Ultralytics ensures the safety of user data and systems. Check out the measures we have implemented, including Snyk and GitHub CodeQL Scanning. +keywords: Ultralytics, Security Policy, data security, open-source projects, Snyk scanning, CodeQL scanning, vulnerability detection, threat prevention --- # Security Policy -At [Ultralytics](https://ultralytics.com), the security of our users' data and systems is of utmost importance. To -ensure the safety and security of our [open-source projects](https://github.com/ultralytics), we have implemented -several measures to detect and prevent security vulnerabilities. - -[![ultralytics](https://snyk.io/advisor/python/ultralytics/badge.svg)](https://snyk.io/advisor/python/ultralytics) +At [Ultralytics](https://ultralytics.com), the security of our users' data and systems is of utmost importance. To ensure the safety and security of our [open-source projects](https://github.com/ultralytics), we have implemented several measures to detect and prevent security vulnerabilities. ## Snyk Scanning -We use [Snyk](https://snyk.io/advisor/python/ultralytics) to regularly scan the YOLOv8 repository for vulnerabilities -and security issues. Our goal is to identify and remediate any potential threats as soon as possible, to minimize any -risks to our users. +We use [Snyk](https://snyk.io/advisor/python/ultralytics) to regularly scan all Ultralytics repositories for vulnerabilities and security issues. Our goal is to identify and remediate any potential threats as soon as possible, to minimize any risks to our users. + +[![ultralytics](https://snyk.io/advisor/python/ultralytics/badge.svg)](https://snyk.io/advisor/python/ultralytics) ## GitHub CodeQL Scanning -In addition to our Snyk scans, we also use -GitHub's [CodeQL](https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/about-code-scanning-with-codeql) -scans to proactively identify and address security vulnerabilities. +In addition to our Snyk scans, we also use GitHub's [CodeQL](https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/about-code-scanning-with-codeql) scans to proactively identify and address security vulnerabilities across all Ultralytics repositories. + +[![CodeQL](https://github.com/ultralytics/ultralytics/actions/workflows/codeql.yaml/badge.svg)](https://github.com/ultralytics/ultralytics/actions/workflows/codeql.yaml) ## Reporting Security Issues -If you suspect or discover a security vulnerability in the YOLOv8 repository, please let us know immediately. You can -reach out to us directly via our [contact form](https://ultralytics.com/contact) or -via [security@ultralytics.com](mailto:security@ultralytics.com). Our security team will investigate and respond as soon -as possible. +If you suspect or discover a security vulnerability in any of our repositories, please let us know immediately. You can reach out to us directly via our [contact form](https://ultralytics.com/contact) or via [security@ultralytics.com](mailto:security@ultralytics.com). Our security team will investigate and respond as soon as possible. -We appreciate your help in keeping the YOLOv8 repository secure and safe for everyone. \ No newline at end of file +We appreciate your help in keeping all Ultralytics open-source projects secure and safe for everyone. diff --git a/downloads/ultralytics-main/docs/build_reference.py b/downloads/ultralytics-main/docs/build_reference.py index b75822ab7..3641b132e 100644 --- a/downloads/ultralytics-main/docs/build_reference.py +++ b/downloads/ultralytics-main/docs/build_reference.py @@ -10,7 +10,8 @@ import os import re from collections import defaultdict from pathlib import Path -from ultralytics.yolo.utils import ROOT + +from ultralytics.utils import ROOT NEW_YAML_DIR = ROOT.parent CODE_DIR = ROOT @@ -21,8 +22,8 @@ def extract_classes_and_functions(filepath): with open(filepath, 'r') as file: content = file.read() - class_pattern = r"(?:^|\n)class\s(\w+)(?:\(|:)" - func_pattern = r"(?:^|\n)def\s(\w+)\(" + class_pattern = r'(?:^|\n)class\s(\w+)(?:\(|:)' + func_pattern = r'(?:^|\n)def\s(\w+)\(' classes = re.findall(class_pattern, content) functions = re.findall(func_pattern, content) @@ -34,17 +35,26 @@ def create_markdown(py_filepath, module_path, classes, functions): md_filepath = py_filepath.with_suffix('.md') # Read existing content and keep header content between first two --- - header_content = "" + header_content = '' if md_filepath.exists(): with open(md_filepath, 'r') as file: existing_content = file.read() - header_parts = existing_content.split('---', 2) - if len(header_parts) >= 3: - header_content = f"{header_parts[0]}---{header_parts[1]}---\n\n" + header_parts = existing_content.split('---') + for part in header_parts: + if 'description:' in part or 'comments:' in part: + header_content += f'---{part}---\n\n' - md_content = [f"# {class_name}\n---\n:::{module_path}.{class_name}\n

\n" for class_name in classes] - md_content.extend(f"# {func_name}\n---\n:::{module_path}.{func_name}\n

\n" for func_name in functions) - md_content = header_content + "\n".join(md_content) + module_name = module_path.replace('.__init__', '') + module_path = module_path.replace(".", "/") + url = f'https://github.com/ultralytics/ultralytics/blob/main/{module_path}.py' + title_content = (f'# Reference for `{module_path}.py`\n\n' + f'!!! note\n\n' + f' Full source code for this file is available at [{url}]({url}). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏!\n\n') + md_content = [f'---\n## ::: {module_name}.{class_name}\n

\n' for class_name in classes] + md_content.extend(f'---\n## ::: {module_name}.{func_name}\n

\n' for func_name in functions) + md_content = header_content + title_content + '\n'.join(md_content) + if not md_content.endswith('\n'): + md_content += '\n' os.makedirs(os.path.dirname(md_filepath), exist_ok=True) with open(md_filepath, 'w') as file: @@ -80,11 +90,11 @@ def create_nav_menu_yaml(nav_items): nav_tree_sorted = sort_nested_dict(nav_tree) def _dict_to_yaml(d, level=0): - yaml_str = "" - indent = " " * level + yaml_str = '' + indent = ' ' * level for k, v in d.items(): if isinstance(v, dict): - yaml_str += f"{indent}- {k}:\n{_dict_to_yaml(v, level + 1)}" + yaml_str += f'{indent}- {k}:\n{_dict_to_yaml(v, level + 1)}' else: yaml_str += f"{indent}- {k}: {str(v).replace('docs/', '')}\n" return yaml_str @@ -98,7 +108,7 @@ def main(): nav_items = [] for root, _, files in os.walk(CODE_DIR): for file in files: - if file.endswith(".py") and file != "__init__.py": + if file.endswith('.py'): py_filepath = Path(root) / file classes, functions = extract_classes_and_functions(py_filepath) @@ -112,5 +122,5 @@ def main(): create_nav_menu_yaml(nav_items) -if __name__ == "__main__": +if __name__ == '__main__': main() diff --git a/downloads/ultralytics-main/docs/guides/index.md b/downloads/ultralytics-main/docs/guides/index.md new file mode 100644 index 000000000..2443b57e6 --- /dev/null +++ b/downloads/ultralytics-main/docs/guides/index.md @@ -0,0 +1,19 @@ +--- +comments: true +description: In-depth exploration of Ultralytics' YOLO. Learn about the YOLO object detection model, how to train it on custom data, multi-GPU training, exporting, predicting, deploying, and more. +keywords: Ultralytics, YOLO, Deep Learning, Object detection, PyTorch, Tutorial, Multi-GPU training, Custom data training +--- + +# Comprehensive Tutorials to Ultralytics YOLO + +Welcome to the Ultralytics' YOLO 🚀 Guides! Our comprehensive tutorials cover various aspects of the YOLO object detection model, ranging from training and prediction to deployment. Built on PyTorch, YOLO stands out for its exceptional speed and accuracy in real-time object detection tasks. + +Whether you're a beginner or an expert in deep learning, our tutorials offer valuable insights into the implementation and optimization of YOLO for your computer vision projects. Let's dive in! + +## Guides + +Here's a compilation of in-depth guides to help you master different aspects of Ultralytics YOLO. + +* [K-Fold Cross Validation](kfold-cross-validation.md) 🚀 NEW: Learn how to improve model generalization using K-Fold cross-validation technique. + +Note: More guides about training, exporting, predicting, and deploying with Ultralytics YOLO are coming soon. Stay tuned! diff --git a/downloads/ultralytics-main/docs/guides/kfold-cross-validation.md b/downloads/ultralytics-main/docs/guides/kfold-cross-validation.md new file mode 100644 index 000000000..423836c82 --- /dev/null +++ b/downloads/ultralytics-main/docs/guides/kfold-cross-validation.md @@ -0,0 +1,265 @@ +--- +comments: true +description: An in-depth guide demonstrating the implementation of K-Fold Cross Validation with the Ultralytics ecosystem for object detection datasets, leveraging Python, YOLO, and sklearn. +keywords: K-Fold cross validation, Ultralytics, YOLO detection format, Python, sklearn, object detection +--- + +# K-Fold Cross Validation with Ultralytics + +## Introduction + +This comprehensive guide illustrates the implementation of K-Fold Cross Validation for object detection datasets within the Ultralytics ecosystem. We'll leverage the YOLO detection format and key Python libraries such as sklearn, pandas, and PyYaml to guide you through the necessary setup, the process of generating feature vectors, and the execution of a K-Fold dataset split. + +

+ K-Fold Cross Validation Overview +

+ +Whether your project involves the Fruit Detection dataset or a custom data source, this tutorial aims to help you comprehend and apply K-Fold Cross Validation to bolster the reliability and robustness of your machine learning models. While we're applying `k=5` folds for this tutorial, keep in mind that the optimal number of folds can vary depending on your dataset and the specifics of your project. + +Without further ado, let's dive in! + +## Setup + +- Your annotations should be in the [YOLO detection format](https://docs.ultralytics.com/datasets/detect/). + +- This guide assumes that annotation files are locally available. + + - For our demonstration, we use the [Fruit Detection](https://www.kaggle.com/datasets/lakshaytyagi01/fruit-detection/code) dataset. + + - This dataset contains a total of 8479 images. + - It includes 6 class labels, each with its total instance counts listed below. + + | Class Label | Instance Count | + |:------------|:--------------:| + | Apple | 7049 | + | Grapes | 7202 | + | Pineapple | 1613 | + | Orange | 15549 | + | Banana | 3536 | + | Watermelon | 1976 | + +- Necessary Python packages include: + + - `ultralytics` + - `sklearn` + - `pandas` + - `pyyaml` + +- This tutorial operates with `k=5` folds. However, you should determine the best number of folds for your specific dataset. + +1. Initiate a new Python virtual environment (`venv`) for your project and activate it. Use `pip` (or your preferred package manager) to install: + + - The Ultralytics library: `pip install -U ultralytics`. Alternatively, you can clone the official [repo](https://github.com/ultralytics/ultralytics). + - Scikit-learn, pandas, and PyYAML: `pip install -U scikit-learn pandas pyyaml`. + +2. Verify that your annotations are in the [YOLO detection format](https://docs.ultralytics.com/datasets/detect/). + + - For this tutorial, all annotation files are found in the `Fruit-Detection/labels` directory. + +## Generating Feature Vectors for Object Detection Dataset + +1. Start by creating a new Python file and import the required libraries. + + ```python + import datetime + import shutil + from pathlib import Path + from collections import Counter + + import yaml + import numpy as np + import pandas as pd + from ultralytics import YOLO + from sklearn.model_selection import KFold + ``` + +2. Proceed to retrieve all label files for your dataset. + + ```python + dataset_path = Path('./Fruit-detection') # replace with 'path/to/dataset' for your custom data + labels = sorted(dataset_path.rglob("*labels/*.txt")) # all data in 'labels' + ``` + +3. Now, read the contents of the dataset YAML file and extract the indices of the class labels. + + ```python + with open(yaml_file, 'r', encoding="utf8") as y: + classes = yaml.safe_load(y)['names'] + cls_idx = sorted(classes.keys()) + ``` + +4. Initialize an empty `pandas` DataFrame. + + ```python + indx = [l.stem for l in labels] # uses base filename as ID (no extension) + labels_df = pd.DataFrame([], columns=cls_idx, index=indx) + ``` + +5. Count the instances of each class-label present in the annotation files. + + ```python + for label in labels: + lbl_counter = Counter() + + with open(label,'r') as lf: + lines = lf.readlines() + + for l in lines: + # classes for YOLO label uses integer at first position of each line + lbl_counter[int(l.split(' ')[0])] += 1 + + labels_df.loc[label.stem] = lbl_counter + + labels_df = labels_df.fillna(0.0) # replace `nan` values with `0.0` + ``` + +6. The following is a sample view of the populated DataFrame: + + ```pandas + 0 1 2 3 4 5 + '0000a16e4b057580_jpg.rf.00ab48988370f64f5ca8ea4...' 0.0 0.0 0.0 0.0 0.0 7.0 + '0000a16e4b057580_jpg.rf.7e6dce029fb67f01eb19aa7...' 0.0 0.0 0.0 0.0 0.0 7.0 + '0000a16e4b057580_jpg.rf.bc4d31cdcbe229dd022957a...' 0.0 0.0 0.0 0.0 0.0 7.0 + '00020ebf74c4881c_jpg.rf.508192a0a97aa6c4a3b6882...' 0.0 0.0 0.0 1.0 0.0 0.0 + '00020ebf74c4881c_jpg.rf.5af192a2254c8ecc4188a25...' 0.0 0.0 0.0 1.0 0.0 0.0 + ... ... ... ... ... ... ... + 'ff4cd45896de38be_jpg.rf.c4b5e967ca10c7ced3b9e97...' 0.0 0.0 0.0 0.0 0.0 2.0 + 'ff4cd45896de38be_jpg.rf.ea4c1d37d2884b3e3cbce08...' 0.0 0.0 0.0 0.0 0.0 2.0 + 'ff5fd9c3c624b7dc_jpg.rf.bb519feaa36fc4bf630a033...' 1.0 0.0 0.0 0.0 0.0 0.0 + 'ff5fd9c3c624b7dc_jpg.rf.f0751c9c3aa4519ea3c9d6a...' 1.0 0.0 0.0 0.0 0.0 0.0 + 'fffe28b31f2a70d4_jpg.rf.7ea16bd637ba0711c53b540...' 0.0 6.0 0.0 0.0 0.0 0.0 + ``` + +The rows index the label files, each corresponding to an image in your dataset, and the columns correspond to your class-label indices. Each row represents a pseudo feature-vector, with the count of each class-label present in your dataset. This data structure enables the application of K-Fold Cross Validation to an object detection dataset. + +## K-Fold Dataset Split + +1. Now we will use the `KFold` class from `sklearn.model_selection` to generate `k` splits of the dataset. + + - Important: + - Setting `shuffle=True` ensures a randomized distribution of classes in your splits. + - By setting `random_state=M` where `M` is a chosen integer, you can obtain repeatable results. + + ```python + ksplit = 5 + kf = KFold(n_splits=ksplit, shuffle=True, random_state=20) # setting random_state for repeatable results + + kfolds = list(kf.split(labels_df)) + ``` + +2. The dataset has now been split into `k` folds, each having a list of `train` and `val` indices. We will construct a DataFrame to display these results more clearly. + + ```python + folds = [f'split_{n}' for n in range(1, ksplit + 1)] + folds_df = pd.DataFrame(index=indx, columns=folds) + + for idx, (train, val) in enumerate(kfolds, start=1): + folds_df[f'split_{idx}'].loc[labels_df.iloc[train].index] = 'train' + folds_df[f'split_{idx}'].loc[labels_df.iloc[val].index] = 'val' + ``` + +3. Now we will calculate the distribution of class labels for each fold as a ratio of the classes present in `val` to those present in `train`. + + ```python + fold_lbl_distrb = pd.DataFrame(index=folds, columns=cls_idx) + + for n, (train_indices, val_indices) in enumerate(kfolds, start=1): + train_totals = labels_df.iloc[train_indices].sum() + val_totals = labels_df.iloc[val_indices].sum() + + # To avoid division by zero, we add a small value (1E-7) to the denominator + ratio = val_totals / (train_totals + 1E-7) + fold_lbl_distrb.loc[f'split_{n}'] = ratio + ``` + +The ideal scenario is for all class ratios to be reasonably similar for each split and across classes. This, however, will be subject to the specifics of your dataset. + +4. Next, we create the directories and dataset YAML files for each split. + + ```python + save_path = Path(dataset_path / f'{datetime.date.today().isoformat()}_{ksplit}-Fold_Cross-val') + save_path.mkdir(parents=True, exist_ok=True) + + images = sorted((dataset_path / 'images').rglob("*.jpg")) # change file extension as needed + ds_yamls = [] + + for split in folds_df.columns: + # Create directories + split_dir = save_path / split + split_dir.mkdir(parents=True, exist_ok=True) + (split_dir / 'train' / 'images').mkdir(parents=True, exist_ok=True) + (split_dir / 'train' / 'labels').mkdir(parents=True, exist_ok=True) + (split_dir / 'val' / 'images').mkdir(parents=True, exist_ok=True) + (split_dir / 'val' / 'labels').mkdir(parents=True, exist_ok=True) + + # Create dataset YAML files + dataset_yaml = split_dir / f'{split}_dataset.yaml' + ds_yamls.append(dataset_yaml) + + with open(dataset_yaml, 'w') as ds_y: + yaml.safe_dump({ + 'path': split_dir.as_posix(), + 'train': 'train', + 'val': 'val', + 'names': classes + }, ds_y) + ``` + +5. Lastly, copy images and labels into the respective directory ('train' or 'val') for each split. + + - __NOTE:__ The time required for this portion of the code will vary based on the size of your dataset and your system hardware. + + ```python + for image, label in zip(images, labels): + for split, k_split in folds_df.loc[image.stem].items(): + # Destination directory + img_to_path = save_path / split / k_split / 'images' + lbl_to_path = save_path / split / k_split / 'labels' + + # Copy image and label files to new directory + # Might throw a SamefileError if file already exists + shutil.copy(image, img_to_path / image.name) + shutil.copy(label, lbl_to_path / label.name) + ``` + +## Save Records (Optional) + +Optionally, you can save the records of the K-Fold split and label distribution DataFrames as CSV files for future reference. + +```python +folds_df.to_csv(save_path / "kfold_datasplit.csv") +fold_lbl_distrb.to_csv(save_path / "kfold_label_distribution.csv") +``` + +## Train YOLO using K-Fold Data Splits + +1. First, load the YOLO model. + + ```python + weights_path = 'path/to/weights.pt' + model = YOLO(weights_path, task='detect') + ``` + +2. Next, iterate over the dataset YAML files to run training. The results will be saved to a directory specified by the `project` and `name` arguments. By default, this directory is 'exp/runs#' where # is an integer index. + + ```python + results = {} + for k in range(ksplit): + dataset_yaml = ds_yamls[k] + model.train(data=dataset_yaml, *args, **kwargs) # Include any training arguments + results[k] = model.metrics # save output metrics for further analysis + ``` + +## Conclusion + +In this guide, we have explored the process of using K-Fold cross-validation for training the YOLO object detection model. We learned how to split our dataset into K partitions, ensuring a balanced class distribution across the different folds. + +We also explored the procedure for creating report DataFrames to visualize the data splits and label distributions across these splits, providing us a clear insight into the structure of our training and validation sets. + +Optionally, we saved our records for future reference, which could be particularly useful in large-scale projects or when troubleshooting model performance. + +Finally, we implemented the actual model training using each split in a loop, saving our training results for further analysis and comparison. + +This technique of K-Fold cross-validation is a robust way of making the most out of your available data, and it helps to ensure that your model performance is reliable and consistent across different data subsets. This results in a more generalizable and reliable model that is less likely to overfit to specific data patterns. + +Remember that although we used YOLO in this guide, these steps are mostly transferable to other machine learning models. Understanding these steps allows you to apply cross-validation effectively in your own machine learning projects. Happy coding! diff --git a/downloads/ultralytics-main/docs/help/CI.md b/downloads/ultralytics-main/docs/help/CI.md new file mode 100644 index 000000000..55e5dc9fd --- /dev/null +++ b/downloads/ultralytics-main/docs/help/CI.md @@ -0,0 +1,62 @@ +--- +comments: true +description: Learn how Ultralytics leverages Continuous Integration (CI) for maintaining high-quality code. Explore our CI tests and the status of these tests for our repositories. +keywords: continuous integration, software development, CI tests, Ultralytics repositories, high-quality code, Docker Deployment, Broken Links, CodeQL, PyPi Publishing +--- + +# Continuous Integration (CI) + +Continuous Integration (CI) is an essential aspect of software development which involves integrating changes and testing them automatically. CI allows us to maintain high-quality code by catching issues early and often in the development process. At Ultralytics, we use various CI tests to ensure the quality and integrity of our codebase. + +## CI Actions + +Here's a brief description of our CI actions: + +- **CI:** This is our primary CI test that involves running unit tests, linting checks, and sometimes more comprehensive tests depending on the repository. +- **Docker Deployment:** This test checks the deployment of the project using Docker to ensure the Dockerfile and related scripts are working correctly. +- **Broken Links:** This test scans the codebase for any broken or dead links in our markdown or HTML files. +- **CodeQL:** CodeQL is a tool from GitHub that performs semantic analysis on our code, helping to find potential security vulnerabilities and maintain high-quality code. +- **PyPi Publishing:** This test checks if the project can be packaged and published to PyPi without any errors. + +### CI Results + +Below is the table showing the status of these CI tests for our main repositories: + +| Repository | CI | Docker Deployment | Broken Links | CodeQL | PyPi and Docs Publishing | +|-----------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [yolov3](https://github.com/ultralytics/yolov3) | [![YOLOv3 CI](https://github.com/ultralytics/yolov3/actions/workflows/ci-testing.yml/badge.svg)](https://github.com/ultralytics/yolov3/actions/workflows/ci-testing.yml) | [![Publish Docker Images](https://github.com/ultralytics/yolov3/actions/workflows/docker.yml/badge.svg)](https://github.com/ultralytics/yolov3/actions/workflows/docker.yml) | [![Check Broken links](https://github.com/ultralytics/yolov3/actions/workflows/links.yml/badge.svg)](https://github.com/ultralytics/yolov3/actions/workflows/links.yml) | [![CodeQL](https://github.com/ultralytics/yolov3/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/ultralytics/yolov3/actions/workflows/codeql-analysis.yml) | | +| [yolov5](https://github.com/ultralytics/yolov5) | [![YOLOv5 CI](https://github.com/ultralytics/yolov5/actions/workflows/ci-testing.yml/badge.svg)](https://github.com/ultralytics/yolov5/actions/workflows/ci-testing.yml) | [![Publish Docker Images](https://github.com/ultralytics/yolov5/actions/workflows/docker.yml/badge.svg)](https://github.com/ultralytics/yolov5/actions/workflows/docker.yml) | [![Check Broken links](https://github.com/ultralytics/yolov5/actions/workflows/links.yml/badge.svg)](https://github.com/ultralytics/yolov5/actions/workflows/links.yml) | [![CodeQL](https://github.com/ultralytics/yolov5/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/ultralytics/yolov5/actions/workflows/codeql-analysis.yml) | | +| [ultralytics](https://github.com/ultralytics/ultralytics) | [![ultralytics CI](https://github.com/ultralytics/ultralytics/actions/workflows/ci.yaml/badge.svg)](https://github.com/ultralytics/ultralytics/actions/workflows/ci.yaml) | [![Publish Docker Images](https://github.com/ultralytics/ultralytics/actions/workflows/docker.yaml/badge.svg)](https://github.com/ultralytics/ultralytics/actions/workflows/docker.yaml) | [![Check Broken links](https://github.com/ultralytics/ultralytics/actions/workflows/links.yml/badge.svg)](https://github.com/ultralytics/ultralytics/actions/workflows/links.yml) | [![CodeQL](https://github.com/ultralytics/ultralytics/actions/workflows/codeql.yaml/badge.svg)](https://github.com/ultralytics/ultralytics/actions/workflows/codeql.yaml) | [![Publish to PyPI and Deploy Docs](https://github.com/ultralytics/ultralytics/actions/workflows/publish.yml/badge.svg)](https://github.com/ultralytics/ultralytics/actions/workflows/publish.yml) | +| [hub](https://github.com/ultralytics/hub) | [![HUB CI](https://github.com/ultralytics/hub/actions/workflows/ci.yaml/badge.svg)](https://github.com/ultralytics/hub/actions/workflows/ci.yaml) | | [![Check Broken links](https://github.com/ultralytics/hub/actions/workflows/links.yml/badge.svg)](https://github.com/ultralytics/hub/actions/workflows/links.yml) | | | +| [docs](https://github.com/ultralytics/docs) | | | | | [![pages-build-deployment](https://github.com/ultralytics/docs/actions/workflows/pages/pages-build-deployment/badge.svg)](https://github.com/ultralytics/docs/actions/workflows/pages/pages-build-deployment) | + +Each badge shows the status of the last run of the corresponding CI test on the `main` branch of the respective repository. If a test fails, the badge will display a "failing" status, and if it passes, it will display a "passing" status. + +If you notice a test failing, it would be a great help if you could report it through a GitHub issue in the respective repository. + +Remember, a successful CI test does not mean that everything is perfect. It is always recommended to manually review the code before deployment or merging changes. + +## Code Coverage + +Code coverage is a metric that represents the percentage of your codebase that is executed when your tests run. It provides insight into how well your tests exercise your code and can be crucial in identifying untested parts of your application. A high code coverage percentage is often associated with a lower likelihood of bugs. However, it's essential to understand that code coverage doesn't guarantee the absence of defects. It merely indicates which parts of the code have been executed by the tests. + +### Integration with [codecov.io](https://codecov.io/) + +At Ultralytics, we have integrated our repositories with [codecov.io](https://codecov.io/), a popular online platform for measuring and visualizing code coverage. Codecov provides detailed insights, coverage comparisons between commits, and visual overlays directly on your code, indicating which lines were covered. + +By integrating with Codecov, we aim to maintain and improve the quality of our code by focusing on areas that might be prone to errors or need further testing. + +### Coverage Results + +To quickly get a glimpse of the code coverage status of the `ultralytics` python package, we have included a badge and and sunburst visual of the `ultralytics` coverage results. These images show the percentage of code covered by our tests, offering an at-a-glance metric of our testing efforts. For full details please see https://codecov.io/github/ultralytics/ultralytics. + +| Repository | Code Coverage | +|-----------------------------------------------------------|----------------------------------------------------------------------| +| [ultralytics](https://github.com/ultralytics/ultralytics) | [![codecov](https://codecov.io/gh/ultralytics/ultralytics/branch/main/graph/badge.svg?token=HHW7IIVFVY)](https://codecov.io/gh/ultralytics/ultralytics) | + +In the sunburst graphic below, the inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively. + + + Ultralytics Codecov Image + + diff --git a/downloads/ultralytics-main/docs/help/CLA.md b/downloads/ultralytics-main/docs/help/CLA.md index e998bb763..6edc4e37e 100644 --- a/downloads/ultralytics-main/docs/help/CLA.md +++ b/downloads/ultralytics-main/docs/help/CLA.md @@ -1,5 +1,6 @@ --- -description: Individual Contributor License Agreement. Settle Intellectual Property issues for Contributions made to anything open source released by Ultralytics. +description: Understand terms governing contributions to Ultralytics projects including source code, bug fixes, documentation and more. Read our Contributor License Agreement. +keywords: Ultralytics, Contributor License Agreement, Open Source Software, Contributions, Copyright License, Patent License, Moral Rights --- # Ultralytics Individual Contributor License Agreement @@ -66,4 +67,4 @@ that any of the provisions of this Agreement shall be held by a court or other t to be unenforceable, the remaining portions hereof shall remain in full force and effect. **Assignment.** You agree that Ultralytics may assign this Agreement, and all of its rights, obligations and licenses -hereunder. \ No newline at end of file +hereunder. diff --git a/downloads/ultralytics-main/docs/help/FAQ.md b/downloads/ultralytics-main/docs/help/FAQ.md index 0a0e70a37..8e4430a80 100644 --- a/downloads/ultralytics-main/docs/help/FAQ.md +++ b/downloads/ultralytics-main/docs/help/FAQ.md @@ -1,6 +1,7 @@ --- comments: true -description: 'Get quick answers to common Ultralytics YOLO questions: Hardware requirements, fine-tuning, conversion, real-time detection, and accuracy tips.' +description: Find solutions to your common Ultralytics YOLO related queries. Learn about hardware requirements, fine-tuning YOLO models, conversion to ONNX/TensorFlow, and more. +keywords: Ultralytics, YOLO, FAQ, hardware requirements, ONNX, TensorFlow, real-time detection, YOLO accuracy --- # Ultralytics YOLO Frequently Asked Questions (FAQ) @@ -35,4 +36,4 @@ Improving the accuracy of a YOLO model may involve several strategies, such as: Remember that there's often a trade-off between accuracy and inference speed, so finding the right balance is crucial for your specific application. -If you have any more questions or need assistance, don't hesitate to consult the Ultralytics documentation or reach out to the community through GitHub Issues or the official discussion forum. \ No newline at end of file +If you have any more questions or need assistance, don't hesitate to consult the Ultralytics documentation or reach out to the community through GitHub Issues or the official discussion forum. diff --git a/downloads/ultralytics-main/docs/help/code_of_conduct.md b/downloads/ultralytics-main/docs/help/code_of_conduct.md index 291581000..cad1daed7 100644 --- a/downloads/ultralytics-main/docs/help/code_of_conduct.md +++ b/downloads/ultralytics-main/docs/help/code_of_conduct.md @@ -1,6 +1,7 @@ --- comments: true -description: Read the Ultralytics Contributor Covenant Code of Conduct. Learn ways to create a welcoming community & consequences for inappropriate conduct. +description: Explore Ultralytics community’s Code of Conduct, ensuring a supportive, inclusive environment for contributors & members at all levels. Find our guidelines on acceptable behavior & enforcement. +keywords: Ultralytics, code of conduct, community, contribution, behavior guidelines, enforcement, open source contributions --- # Ultralytics Contributor Covenant Code of Conduct @@ -130,4 +131,4 @@ For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations. -[homepage]: https://www.contributor-covenant.org \ No newline at end of file +[homepage]: https://www.contributor-covenant.org diff --git a/downloads/ultralytics-main/docs/help/contributing.md b/downloads/ultralytics-main/docs/help/contributing.md index b26f6ffba..36a765334 100644 --- a/downloads/ultralytics-main/docs/help/contributing.md +++ b/downloads/ultralytics-main/docs/help/contributing.md @@ -1,11 +1,12 @@ --- comments: true -description: Learn how to contribute to Ultralytics Open-Source YOLO Repositories with contributions guidelines, pull requests requirements, and GitHub CI tests. +description: Learn how to contribute to Ultralytics YOLO projects – guidelines for pull requests, reporting bugs, code conduct and CLA signing. +keywords: Ultralytics, YOLO, open-source, contribute, pull request, bug report, coding guidelines, CLA, code of conduct, GitHub --- # Contributing to Ultralytics Open-Source YOLO Repositories -First of all, thank you for your interest in contributing to Ultralytics open-source YOLO repositories! Your contributions will help improve the project and benefit the community. This document provides guidelines and best practices for contributing to Ultralytics YOLO repositories. +First of all, thank you for your interest in contributing to Ultralytics open-source YOLO repositories! Your contributions will help improve the project and benefit the community. This document provides guidelines and best practices to get you started. ## Table of Contents @@ -71,4 +72,4 @@ def example_function(arg1: int, arg2: str) -> bool: ### GitHub Actions CI Tests -Before your pull request can be merged, all GitHub Actions Continuous Integration (CI) tests must pass. These tests include linting, unit tests, and other checks to ensure that your changes meet the quality standards of the project. Make sure to review the output of the GitHub Actions and fix any issues \ No newline at end of file +Before your pull request can be merged, all GitHub Actions Continuous Integration (CI) tests must pass. These tests include linting, unit tests, and other checks to ensure that your changes meet the quality standards of the project. Make sure to review the output of the GitHub Actions and fix any issues diff --git a/downloads/ultralytics-main/docs/help/environmental-health-safety.md b/downloads/ultralytics-main/docs/help/environmental-health-safety.md new file mode 100644 index 000000000..9fee240b4 --- /dev/null +++ b/downloads/ultralytics-main/docs/help/environmental-health-safety.md @@ -0,0 +1,37 @@ +--- +comments: false +description: Discover Ultralytics’ EHS policy principles and implementation measures. Committed to safety, environment, and continuous improvement for a sustainable future. +keywords: Ultralytics policy, EHS, environment, health and safety, compliance, prevention, continuous improvement, risk management, emergency preparedness, resource allocation, communication +--- + +# Ultralytics Environmental, Health and Safety (EHS) Policy + +At Ultralytics, we recognize that the long-term success of our company relies not only on the products and services we offer, but also the manner in which we conduct our business. We are committed to ensuring the safety and well-being of our employees, stakeholders, and the environment, and we will continuously strive to mitigate our impact on the environment while promoting health and safety. + +## Policy Principles + +1. **Compliance**: We will comply with all applicable laws, regulations, and standards related to EHS, and we will strive to exceed these standards where possible. + +2. **Prevention**: We will work to prevent accidents, injuries, and environmental harm by implementing risk management measures and ensuring all our operations and procedures are safe. + +3. **Continuous Improvement**: We will continuously improve our EHS performance by setting measurable objectives, monitoring our performance, auditing our operations, and revising our policies and procedures as needed. + +4. **Communication**: We will communicate openly about our EHS performance and will engage with stakeholders to understand and address their concerns and expectations. + +5. **Education and Training**: We will educate and train our employees and contractors in appropriate EHS procedures and practices. + +## Implementation Measures + +1. **Responsibility and Accountability**: Every employee and contractor working at or with Ultralytics is responsible for adhering to this policy. Managers and supervisors are accountable for ensuring this policy is implemented within their areas of control. + +2. **Risk Management**: We will identify, assess, and manage EHS risks associated with our operations and activities to prevent accidents, injuries, and environmental harm. + +3. **Resource Allocation**: We will allocate the necessary resources to ensure the effective implementation of our EHS policy, including the necessary equipment, personnel, and training. + +4. **Emergency Preparedness and Response**: We will develop, maintain, and test emergency preparedness and response plans to ensure we can respond effectively to EHS incidents. + +5. **Monitoring and Review**: We will monitor and review our EHS performance regularly to identify opportunities for improvement and ensure we are meeting our objectives. + +This policy reflects our commitment to minimizing our environmental footprint, ensuring the safety and well-being of our employees, and continuously improving our performance. + +Please remember that the implementation of an effective EHS policy requires the involvement and commitment of everyone working at or with Ultralytics. We encourage you to take personal responsibility for your safety and the safety of others, and to take care of the environment in which we live and work. diff --git a/downloads/ultralytics-main/docs/help/index.md b/downloads/ultralytics-main/docs/help/index.md index 25e3ebcef..468a8d58c 100644 --- a/downloads/ultralytics-main/docs/help/index.md +++ b/downloads/ultralytics-main/docs/help/index.md @@ -1,15 +1,18 @@ --- comments: true -description: Get comprehensive resources for Ultralytics YOLO repositories. Find guides, FAQs, MRE creation, CLA & more. Join the supportive community now! +description: Find comprehensive guides and documents on Ultralytics YOLO tasks. Includes FAQs, contributing guides, CI guide, CLA, MRE guide, code of conduct & more. +keywords: Ultralytics, YOLO, guides, documents, FAQ, contributing, CI guide, CLA, MRE guide, code of conduct, EHS policy, security policy --- Welcome to the Ultralytics Help page! We are committed to providing you with comprehensive resources to make your experience with Ultralytics YOLO repositories as smooth and enjoyable as possible. On this page, you'll find essential links to guides and documents that will help you navigate through common tasks and address any questions you might have while using our repositories. - [Frequently Asked Questions (FAQ)](FAQ.md): Find answers to common questions and issues faced by users and contributors of Ultralytics YOLO repositories. - [Contributing Guide](contributing.md): Learn the best practices for submitting pull requests, reporting bugs, and contributing to the development of our repositories. +- [Continuous Integration (CI) Guide](CI.md): Understand the CI tests we perform for each Ultralytics repository and see their current statuses. - [Contributor License Agreement (CLA)](CLA.md): Familiarize yourself with our CLA to understand the terms and conditions for contributing to Ultralytics projects. - [Minimum Reproducible Example (MRE) Guide](minimum_reproducible_example.md): Understand how to create an MRE when submitting bug reports to ensure that our team can quickly and efficiently address the issue. - [Code of Conduct](code_of_conduct.md): Learn about our community guidelines and expectations to ensure a welcoming and inclusive environment for all participants. +- [Environmental, Health and Safety (EHS) Policy](environmental-health-safety.md): Explore Ultralytics' dedicated approach towards maintaining a sustainable, safe, and healthy work environment for all our stakeholders. - [Security Policy](../SECURITY.md): Understand our security practices and how to report security vulnerabilities responsibly. -We highly recommend going through these guides to make the most of your collaboration with the Ultralytics community. Our goal is to maintain a welcoming and supportive environment for all users and contributors. If you need further assistance, don't hesitate to reach out to us through GitHub Issues or the official discussion forum. Happy coding! \ No newline at end of file +We highly recommend going through these guides to make the most of your collaboration with the Ultralytics community. Our goal is to maintain a welcoming and supportive environment for all users and contributors. If you need further assistance, don't hesitate to reach out to us through GitHub Issues or the official discussion forum. Happy coding! diff --git a/downloads/ultralytics-main/docs/help/minimum_reproducible_example.md b/downloads/ultralytics-main/docs/help/minimum_reproducible_example.md index 03335437d..47a0cdf0e 100644 --- a/downloads/ultralytics-main/docs/help/minimum_reproducible_example.md +++ b/downloads/ultralytics-main/docs/help/minimum_reproducible_example.md @@ -1,11 +1,12 @@ --- comments: true -description: Learn how to create a Minimum Reproducible Example (MRE) for Ultralytics YOLO bug reports to help maintainers and contributors understand your issue better. +description: Learn how to create minimum reproducible examples (MRE) for efficient bug reporting in Ultralytics YOLO repositories with this step-by-step guide. +keywords: Ultralytics, YOLO, minimum reproducible example, MRE, bug reports, guide, dependencies, code, troubleshooting --- # Creating a Minimum Reproducible Example for Bug Reports in Ultralytics YOLO Repositories -When submitting a bug report for Ultralytics YOLO repositories, it's essential to provide a [minimum reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) (MRE). An MRE is a small, self-contained piece of code that demonstrates the problem you're experiencing. Providing an MRE helps maintainers and contributors understand the issue and work on a fix more efficiently. This guide explains how to create an MRE when submitting bug reports to Ultralytics YOLO repositories. +When submitting a bug report for Ultralytics YOLO repositories, it's essential to provide a [minimum reproducible example](https://docs.ultralytics.com/help/minimum_reproducible_example/) (MRE). An MRE is a small, self-contained piece of code that demonstrates the problem you're experiencing. Providing an MRE helps maintainers and contributors understand the issue and work on a fix more efficiently. This guide explains how to create an MRE when submitting bug reports to Ultralytics YOLO repositories. ## 1. Isolate the Problem @@ -74,4 +75,4 @@ RuntimeError: Expected input[1, 0, 640, 640] to have 3 channels, but got 0 chann In this example, the MRE demonstrates the issue with a minimal amount of code, uses a public model ('yolov8n.pt'), includes all necessary dependencies, and provides a clear description of the problem along with the error message. -By following these guidelines, you'll help the maintainers and contributors of Ultralytics YOLO repositories to understand and resolve your issue more efficiently. \ No newline at end of file +By following these guidelines, you'll help the maintainers and contributors of Ultralytics YOLO repositories to understand and resolve your issue more efficiently. diff --git a/downloads/ultralytics-main/docs/hub/app/android.md b/downloads/ultralytics-main/docs/hub/app/android.md index bcb95c07e..20ab090af 100644 --- a/downloads/ultralytics-main/docs/hub/app/android.md +++ b/downloads/ultralytics-main/docs/hub/app/android.md @@ -1,6 +1,7 @@ --- comments: true -description: Run YOLO models on your Android device for real-time object detection with Ultralytics Android App. Utilizes TensorFlow Lite and hardware delegates. +description: Learn about the Ultralytics Android App, enabling real-time object detection using YOLO models. Discover in-app features, quantization methods, and delegate options for optimal performance. +keywords: Ultralytics, Android App, real-time object detection, YOLO models, TensorFlow Lite, FP16 quantization, INT8 quantization, CPU, GPU, Hexagon, NNAPI --- # Ultralytics Android App: Real-time Object Detection with YOLO Models @@ -62,4 +63,4 @@ To get started with the Ultralytics Android App, follow these steps: 6. Explore the app's settings to adjust the detection threshold, enable or disable specific object classes, and more. -With the Ultralytics Android App, you now have the power of real-time object detection using YOLO models right at your fingertips. Enjoy exploring the app's features and optimizing its settings to suit your specific use cases. \ No newline at end of file +With the Ultralytics Android App, you now have the power of real-time object detection using YOLO models right at your fingertips. Enjoy exploring the app's features and optimizing its settings to suit your specific use cases. diff --git a/downloads/ultralytics-main/docs/hub/app/index.md b/downloads/ultralytics-main/docs/hub/app/index.md index 96b7f9d30..dd44d9549 100644 --- a/downloads/ultralytics-main/docs/hub/app/index.md +++ b/downloads/ultralytics-main/docs/hub/app/index.md @@ -1,6 +1,7 @@ --- comments: true -description: Experience the power of YOLOv5 and YOLOv8 models with Ultralytics HUB app. Download from Google Play and App Store now. +description: Explore the Ultralytics HUB App, offering the ability to run YOLOv5 and YOLOv8 models on your iOS and Android devices with optimized performance. +keywords: Ultralytics, HUB App, YOLOv5, YOLOv8, mobile AI, real-time object detection, image recognition, mobile device, hardware acceleration, Apple Neural Engine, Android GPU, NNAPI, custom model training --- # Ultralytics HUB App @@ -12,7 +13,7 @@ description: Experience the power of YOLOv5 and YOLOv8 models with Ultralytics H - + @@ -48,4 +49,4 @@ Welcome to the Ultralytics HUB App! We are excited to introduce this powerful mo - [**iOS**](./ios.md): Learn about YOLO CoreML models accelerated on Apple's Neural Engine for iPhones and iPads. - [**Android**](./android.md): Explore TFLite acceleration on Android mobile devices. -Get started today by downloading the Ultralytics HUB App on your mobile device and unlock the potential of YOLOv5 and YOLOv8 models on-the-go. Don't forget to check out our comprehensive [HUB Docs](../) for more information on training, deploying, and using your custom models with the Ultralytics HUB platform. \ No newline at end of file +Get started today by downloading the Ultralytics HUB App on your mobile device and unlock the potential of YOLOv5 and YOLOv8 models on-the-go. Don't forget to check out our comprehensive [HUB Docs](../index.md) for more information on training, deploying, and using your custom models with the Ultralytics HUB platform. diff --git a/downloads/ultralytics-main/docs/hub/app/ios.md b/downloads/ultralytics-main/docs/hub/app/ios.md index 2c134f661..c202eec8b 100644 --- a/downloads/ultralytics-main/docs/hub/app/ios.md +++ b/downloads/ultralytics-main/docs/hub/app/ios.md @@ -1,6 +1,7 @@ --- comments: true -description: Get started with the Ultralytics iOS app and run YOLO models in real-time for object detection on your iPhone or iPad with the Apple Neural Engine. +description: Execute object detection in real-time on your iOS devices utilizing YOLO models. Leverage the power of the Apple Neural Engine and Core ML for fast and efficient object detection. +keywords: Ultralytics, iOS app, object detection, YOLO models, real time, Apple Neural Engine, Core ML, FP16, INT8, quantization --- # Ultralytics iOS App: Real-time Object Detection with YOLO Models @@ -52,4 +53,4 @@ To get started with the Ultralytics iOS App, follow these steps: 6. Explore the app's settings to adjust the detection threshold, enable or disable specific object classes, and more. -With the Ultralytics iOS App, you can now leverage the power of YOLO models for real-time object detection on your iPhone or iPad, powered by the Apple Neural Engine and optimized with FP16 or INT8 quantization. \ No newline at end of file +With the Ultralytics iOS App, you can now leverage the power of YOLO models for real-time object detection on your iPhone or iPad, powered by the Apple Neural Engine and optimized with FP16 or INT8 quantization. diff --git a/downloads/ultralytics-main/docs/hub/datasets.md b/downloads/ultralytics-main/docs/hub/datasets.md index c4f06582d..e2ac46540 100644 --- a/downloads/ultralytics-main/docs/hub/datasets.md +++ b/downloads/ultralytics-main/docs/hub/datasets.md @@ -1,50 +1,159 @@ --- comments: true -description: Upload custom datasets to Ultralytics HUB for YOLOv5 and YOLOv8 models. Follow YAML structure, zip and upload. Scan & train new models. +description: Learn how Ultralytics HUB datasets streamline your ML workflow. Upload, format, validate, access, share, edit or delete datasets for Ultralytics YOLO model training. +keywords: Ultralytics, HUB datasets, YOLO model training, upload datasets, dataset validation, ML workflow, share datasets --- # HUB Datasets -## 1. Upload a Dataset +Ultralytics HUB datasets are a practical solution for managing and leveraging your custom datasets. -Ultralytics HUB datasets are just like YOLOv5 and YOLOv8 🚀 datasets, they use the same structure and the same label formats to keep +Once uploaded, datasets can be immediately utilized for model training. This integrated approach facilitates a seamless transition from dataset management to model training, significantly simplifying the entire process. + +## Upload Dataset + +Ultralytics HUB datasets are just like YOLOv5 and YOLOv8 🚀 datasets. They use the same structure and the same label formats to keep everything simple. -When you upload a dataset to Ultralytics HUB, make sure to **place your dataset YAML inside the dataset root directory** -as in the example shown below, and then zip for upload to [https://hub.ultralytics.com](https://hub.ultralytics.com/). Your **dataset YAML, directory -and zip** should all share the same name. For example, if your dataset is called 'coco8' as in our -example [ultralytics/hub/example_datasets/coco8.zip](https://github.com/ultralytics/hub/blob/master/example_datasets/coco8.zip), then you should have a `coco8.yaml` inside your `coco8/` directory, which should zip to create `coco8.zip` for upload: +Before you upload a dataset to Ultralytics HUB, make sure to **place your dataset YAML file inside the dataset root directory** and that **your dataset YAML, directory and ZIP have the same name**, as shown in the example below, and then zip the dataset directory. + +For example, if your dataset is called "coco8", as our [COCO8](https://docs.ultralytics.com/datasets/detect/coco8) example dataset, then you should have a `coco8.yaml` inside your `coco8/` directory, which will create a `coco8.zip` when zipped: ```bash zip -r coco8.zip coco8 ``` -The [example_datasets/coco8.zip](https://github.com/ultralytics/hub/blob/master/example_datasets/coco8.zip) dataset in this repository can be downloaded and unzipped to see exactly how to structure your custom dataset. +You can download our [COCO8](https://github.com/ultralytics/hub/blob/master/example_datasets/coco8.zip) example dataset and unzip it to see exactly how to structure your dataset.

- + COCO8 Dataset Structure

-The dataset YAML is the same standard YOLOv5 and YOLOv8 YAML format. See -the [YOLOv5 and YOLOv8 Train Custom Data tutorial](https://docs.ultralytics.com/yolov5/tutorials/train_custom_data/) for full details. +The dataset YAML is the same standard YOLOv5 and YOLOv8 YAML format. -```yaml -# 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, ..] -path: # dataset root dir (leave empty for HUB) -train: images/train # train images (relative to 'path') 8 images -val: images/val # val images (relative to 'path') 8 images -test: # test images (optional) +!!! example "coco8.yaml" -# Classes -names: - 0: person - 1: bicycle - 2: car - 3: motorcycle - ... + ```yaml + --8<-- "ultralytics/cfg/datasets/coco8.yaml" + ``` + +After zipping your dataset, you should validate it before uploading it to Ultralytics HUB. Ultralytics HUB conducts the dataset validation check post-upload, so by ensuring your dataset is correctly formatted and error-free ahead of time, you can forestall any setbacks due to dataset rejection. + +```py +from ultralytics.hub import check_dataset +check_dataset('path/to/coco8.zip') ``` -After zipping your dataset, sign in to [Ultralytics HUB](https://bit.ly/ultralytics_hub) and click the Datasets tab. -Click 'Upload Dataset' to upload, scan and visualize your new dataset before training new YOLOv5 or YOLOv8 models on it! +Once your dataset ZIP is ready, navigate to the [Datasets](https://hub.ultralytics.com/datasets) page by clicking on the **Datasets** button in the sidebar. -HUB Dataset Upload \ No newline at end of file +![Ultralytics HUB screenshot of the Home page with an arrow pointing to the Datasets button in the sidebar](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_upload_dataset_2.jpg) + +??? tip "Tip" + + You can also upload a dataset directly from the [Home](https://hub.ultralytics.com/home) page. + + ![Ultralytics HUB screenshot of the Home page with an arrow pointing to the Upload Dataset card](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_upload_dataset_3.jpg) + +Click on the **Upload Dataset** button on the top right of the page. This action will trigger the **Upload Dataset** dialog. + +![Ultralytics HUB screenshot of the Dataset page with an arrow pointing to the Upload Dataset button](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_upload_dataset_4.jpg) + +Upload your dataset in the _Dataset .zip file_ field. + +You have the additional option to set a custom name and description for your Ultralytics HUB dataset. + +When you're happy with your dataset configuration, click **Upload**. + +![Ultralytics HUB screenshot of the Upload Dataset dialog with an arrow pointing to the Upload button](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_upload_dataset_5.jpg) + +After your dataset is uploaded and processed, you will be able to access it from the Datasets page. + +![Ultralytics HUB screenshot of the Datasets page with an arrow pointing to one of the datasets](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_upload_dataset_6.jpg) + +You can view the images in your dataset grouped by splits (Train, Validation, Test). + +![Ultralytics HUB screenshot of the Dataset page with an arrow pointing to the Images tab](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_upload_dataset_7.jpg) + +??? tip "Tip" + + Each image can be enlarged for better visualization. + + ![Ultralytics HUB screenshot of the Images tab inside the Dataset page with an arrow pointing to the expand icon](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_upload_dataset_8.jpg) + + ![Ultralytics HUB screenshot of the Images tab inside the Dataset page with one of the images expanded](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_upload_dataset_9.jpg) + +Also, you can analyze your dataset by click on the **Overview** tab. + +![Ultralytics HUB screenshot of the Dataset page with an arrow pointing to the Overview tab](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_upload_dataset_10.jpg) + +Next, [train a model](https://docs.ultralytics.com/hub/models/#train-model) on your dataset. + +![Ultralytics HUB screenshot of the Dataset page with an arrow pointing to the Train Model button](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_upload_dataset_11.jpg) + +## Share Dataset + +!!! info "Info" + + Ultralytics HUB's sharing functionality provides a convenient way to share datasets with others. This feature is designed to accommodate both existing Ultralytics HUB users and those who have yet to create an account. + +??? note "Note" + + You have control over the general access of your datasets. + + You can choose to set the general access to "Private", in which case, only you will have access to it. Alternatively, you can set the general access to "Unlisted" which grants viewing access to anyone who has the direct link to the dataset, regardless of whether they have an Ultralytics HUB account or not. + +Navigate to the Dataset page of the dataset you want to share, open the dataset actions dropdown and click on the **Share** option. This action will trigger the **Share Dataset** dialog. + +![Ultralytics HUB screenshot of the Dataset page with an arrow pointing to the Share option](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_share_dataset_1.jpg) + +??? tip "Tip" + + You can also share a dataset directly from the [Datasets](https://hub.ultralytics.com/datasets) page. + + ![Ultralytics HUB screenshot of the Datasets page with an arrow pointing to the Share option of one of the datasets](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_share_dataset_2.jpg) + +Set the general access to "Unlisted" and click **Save**. + +![Ultralytics HUB screenshot of the Share Dataset dialog with an arrow pointing to the dropdown and one to the Save button](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_share_dataset_3.jpg) + +Now, anyone who has the direct link to your dataset can view it. + +??? tip "Tip" + + You can easily click on the dataset's link shown in the **Share Dataset** dialog to copy it. + + ![Ultralytics HUB screenshot of the Share Dataset dialog with an arrow pointing to the dataset's link](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_share_dataset_4.jpg) + +## Edit Dataset + +Navigate to the Dataset page of the dataset you want to edit, open the dataset actions dropdown and click on the **Edit** option. This action will trigger the **Update Dataset** dialog. + +![Ultralytics HUB screenshot of the Dataset page with an arrow pointing to the Edit option](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_edit_dataset_1.jpg) + +??? tip "Tip" + + You can also edit a dataset directly from the [Datasets](https://hub.ultralytics.com/datasets) page. + + ![Ultralytics HUB screenshot of the Datasets page with an arrow pointing to the Edit option of one of the datasets](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_edit_dataset_2.jpg) + +Apply the desired modifications to your dataset and then confirm the changes by clicking **Save**. + +![Ultralytics HUB screenshot of the Update Dataset dialog with an arrow pointing to the Save button](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_edit_dataset_3.jpg) + +## Delete Dataset + +Navigate to the Dataset page of the dataset you want to delete, open the dataset actions dropdown and click on the **Delete** option. This action will delete the dataset. + +![Ultralytics HUB screenshot of the Dataset page with an arrow pointing to the Delete option](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_delete_dataset_1.jpg) + +??? tip "Tip" + + You can also delete a dataset directly from the [Datasets](https://hub.ultralytics.com/datasets) page. + + ![Ultralytics HUB screenshot of the Datasets page with an arrow pointing to the Delete option of one of the datasets](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_delete_dataset_2.jpg) + +??? note "Note" + + If you change your mind, you can restore the dataset from the [Trash](https://hub.ultralytics.com/trash) page. + + ![Ultralytics HUB screenshot of the Trash page with an arrow pointing to the Restore option of one of the datasets](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/datasets/hub_delete_dataset_3.jpg) diff --git a/downloads/ultralytics-main/docs/hub/index.md b/downloads/ultralytics-main/docs/hub/index.md index 5ff95f140..c4276939a 100644 --- a/downloads/ultralytics-main/docs/hub/index.md +++ b/downloads/ultralytics-main/docs/hub/index.md @@ -1,6 +1,7 @@ --- comments: true -description: 'Ultralytics HUB: Train & deploy YOLO models from one spot! Use drag-and-drop interface with templates & pre-training models. Check quickstart, datasets, and more.' +description: Gain seamless experience in training and deploying your YOLOv5 and YOLOv8 models with Ultralytics HUB. Explore pre-trained models, templates and various integrations. +keywords: Ultralytics HUB, YOLOv5, YOLOv8, model training, model deployment, pretrained models, model integrations --- # Ultralytics HUB @@ -28,7 +29,7 @@ easily upload their data and train new models quickly. It offers a range of pre- templates to choose from, making it easy for users to get started with training their own models. Once a model is trained, it can be easily deployed and used for real-time object detection, instance segmentation and classification tasks. -We hope that the resources here will help you get the most out of HUB. Please browse the HUB
Docs for details, raise an issue on GitHub for support, and join our Discord community for questions and discussions! +We hope that the resources here will help you get the most out of HUB. Please browse the HUB Docs for details, raise an issue on GitHub for support, and join our Discord community for questions and discussions! - [**Quickstart**](./quickstart.md). Start training and deploying YOLO models with HUB in seconds. - [**Datasets: Preparing and Uploading**](./datasets.md). Learn how to prepare and upload your datasets to HUB in YOLO format. @@ -38,4 +39,4 @@ We hope that the resources here will help you get the most out of HUB. Please br - [**Ultralytics HUB App**](./app/index.md). Learn about the Ultralytics App for iOS and Android, which allows you to run models directly on your mobile device. * [**iOS**](./app/ios.md). Learn about YOLO CoreML models accelerated on Apple's Neural Engine on iPhones and iPads. * [**Android**](./app/android.md). Explore TFLite acceleration on mobile devices. -- [**Inference API**](./inference_api.md). Understand how to use the Inference API for running your trained models in the cloud to generate predictions. \ No newline at end of file +- [**Inference API**](./inference_api.md). Understand how to use the Inference API for running your trained models in the cloud to generate predictions. diff --git a/downloads/ultralytics-main/docs/hub/inference_api.md b/downloads/ultralytics-main/docs/hub/inference_api.md index b69b13af0..4cc62bfbb 100644 --- a/downloads/ultralytics-main/docs/hub/inference_api.md +++ b/downloads/ultralytics-main/docs/hub/inference_api.md @@ -1,15 +1,16 @@ --- comments: true +description: Access object detection capabilities of YOLOv8 via our RESTful API. Learn how to use the YOLO Inference API with Python or CLI for swift object detection. +keywords: Ultralytics, YOLOv8, Inference API, object detection, RESTful API, Python, CLI, Quickstart --- -# 🚧 Page Under Construction ⚒ - -This page is currently under construction!️ 👷Please check back later for updates. 😃🔜 - # YOLO Inference API The YOLO Inference API allows you to access the YOLOv8 object detection capabilities via a RESTful API. This enables you to run object detection on images without the need to install and set up the YOLOv8 environment locally. +![Inference API Screenshot](https://github.com/ultralytics/ultralytics/assets/26833433/c0109ec0-7bb0-46e1-b0d2-bae687960a01) +Screenshot of the Inference API section in the trained model Preview tab. + ## API URL The API URL is the address used to access the YOLO Inference API. In this case, the base URL is: @@ -110,7 +111,7 @@ YOLO detection models, such as `yolov8n.pt`, can return JSON responses from loca === "Local" ```python from ultralytics import YOLO - + # Load model model = YOLO('yolov8n.pt') @@ -118,12 +119,12 @@ YOLO detection models, such as `yolov8n.pt`, can return JSON responses from loca results = model('image.jpg') # Print image.jpg results in JSON format - print(results[0].tojson()) + print(results[0].tojson()) ``` === "CLI API" ```bash - curl -X POST "https://api.ultralytics.com/v1/predict/MODEL_ID" \ + curl -X POST "https://api.ultralytics.com/v1/predict/MODEL_ID" \ -H "x-api-key: API_KEY" \ -F "image=@/path/to/image.jpg" \ -F "size=640" \ @@ -134,21 +135,21 @@ YOLO detection models, such as `yolov8n.pt`, can return JSON responses from loca === "Python API" ```python import requests - + # API URL, use actual MODEL_ID url = f"https://api.ultralytics.com/v1/predict/MODEL_ID" - + # Headers, use actual API_KEY headers = {"x-api-key": "API_KEY"} - + # Inference arguments (optional) data = {"size": 640, "confidence": 0.25, "iou": 0.45} - + # Load image and send request with open("path/to/image.jpg", "rb") as image_file: files = {"image": image_file} response = requests.post(url, headers=headers, files=files, data=data) - + print(response.json()) ``` @@ -204,7 +205,7 @@ YOLO segmentation models, such as `yolov8n-seg.pt`, can return JSON responses fr === "Local" ```python from ultralytics import YOLO - + # Load model model = YOLO('yolov8n-seg.pt') @@ -212,12 +213,12 @@ YOLO segmentation models, such as `yolov8n-seg.pt`, can return JSON responses fr results = model('image.jpg') # Print image.jpg results in JSON format - print(results[0].tojson()) + print(results[0].tojson()) ``` === "CLI API" ```bash - curl -X POST "https://api.ultralytics.com/v1/predict/MODEL_ID" \ + curl -X POST "https://api.ultralytics.com/v1/predict/MODEL_ID" \ -H "x-api-key: API_KEY" \ -F "image=@/path/to/image.jpg" \ -F "size=640" \ @@ -228,21 +229,21 @@ YOLO segmentation models, such as `yolov8n-seg.pt`, can return JSON responses fr === "Python API" ```python import requests - + # API URL, use actual MODEL_ID url = f"https://api.ultralytics.com/v1/predict/MODEL_ID" - + # Headers, use actual API_KEY headers = {"x-api-key": "API_KEY"} - + # Inference arguments (optional) data = {"size": 640, "confidence": 0.25, "iou": 0.45} - + # Load image and send request with open("path/to/image.jpg", "rb") as image_file: files = {"image": image_file} response = requests.post(url, headers=headers, files=files, data=data) - + print(response.json()) ``` @@ -341,7 +342,7 @@ YOLO pose models, such as `yolov8n-pose.pt`, can return JSON responses from loca === "Local" ```python from ultralytics import YOLO - + # Load model model = YOLO('yolov8n-seg.pt') @@ -349,12 +350,12 @@ YOLO pose models, such as `yolov8n-pose.pt`, can return JSON responses from loca results = model('image.jpg') # Print image.jpg results in JSON format - print(results[0].tojson()) + print(results[0].tojson()) ``` === "CLI API" ```bash - curl -X POST "https://api.ultralytics.com/v1/predict/MODEL_ID" \ + curl -X POST "https://api.ultralytics.com/v1/predict/MODEL_ID" \ -H "x-api-key: API_KEY" \ -F "image=@/path/to/image.jpg" \ -F "size=640" \ @@ -365,21 +366,21 @@ YOLO pose models, such as `yolov8n-pose.pt`, can return JSON responses from loca === "Python API" ```python import requests - + # API URL, use actual MODEL_ID url = f"https://api.ultralytics.com/v1/predict/MODEL_ID" - + # Headers, use actual API_KEY headers = {"x-api-key": "API_KEY"} - + # Inference arguments (optional) data = {"size": 640, "confidence": 0.25, "iou": 0.45} - + # Load image and send request with open("path/to/image.jpg", "rb") as image_file: files = {"image": image_file} response = requests.post(url, headers=headers, files=files, data=data) - + print(response.json()) ``` @@ -454,4 +455,4 @@ YOLO pose models, such as `yolov8n-pose.pt`, can return JSON responses from loca } ] } - ``` \ No newline at end of file + ``` diff --git a/downloads/ultralytics-main/docs/hub/models.md b/downloads/ultralytics-main/docs/hub/models.md index 1d73d4530..a8bb36a37 100644 --- a/downloads/ultralytics-main/docs/hub/models.md +++ b/downloads/ultralytics-main/docs/hub/models.md @@ -1,20 +1,213 @@ --- comments: true -description: Train and Deploy your Model to 13 different formats, including TensorFlow, ONNX, OpenVINO, CoreML, Paddle or directly on Mobile. +description: Learn how to use Ultralytics HUB models for efficient and user-friendly AI model training. For easy model creation, training, evaluation and deployment, follow our detailed guide. +keywords: Ultralytics, HUB Models, AI model training, model creation, model training, model evaluation, model deployment --- -# HUB Models +# Ultralytics HUB Models -## Train a Model +Ultralytics HUB models provide a streamlined solution for training vision AI models on your custom datasets. -Connect to the Ultralytics HUB notebook and use your model API key to begin training! +The process is user-friendly and efficient, involving a simple three-step creation and accelerated training powered by Utralytics YOLOv8. During training, real-time updates on model metrics are available so that you can monitor each step of the progress. Once training is completed, you can preview your model and easily deploy it to real-world applications. Therefore, Ultralytics HUB offers a comprehensive yet straightforward system for model creation, training, evaluation, and deployment. + +## Train Model + +Navigate to the [Models](https://hub.ultralytics.com/models) page by clicking on the **Models** button in the sidebar. + +![Ultralytics HUB screenshot of the Home page with an arrow pointing to the Models button in the sidebar](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_train_model_1.jpg) + +??? tip "Tip" + + You can also train a model directly from the [Home](https://hub.ultralytics.com/home) page. + + ![Ultralytics HUB screenshot of the Home page with an arrow pointing to the Train Model card](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_train_model_2.jpg) + +Click on the **Train Model** button on the top right of the page. This action will trigger the **Train Model** dialog. + +![Ultralytics HUB screenshot of the Models page with an arrow pointing to the Train Model button](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_train_model_3.jpg) + +The **Train Model** dialog has three simple steps, explained below. + +### 1. Dataset + +In this step, you have to select the dataset you want to train your model on. After you selected a dataset, click **Continue**. + +![Ultralytics HUB screenshot of the Train Model dialog with an arrow pointing to a dataset and one to the Continue button](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_train_model_4.jpg) + +??? tip "Tip" + + You can skip this step if you train a model directly from the Dataset page. + + ![Ultralytics HUB screenshot of the Dataset page with an arrow pointing to the Train Model button](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_train_model_5.jpg) + +### 2. Model + +In this step, you have to choose the project in which you want to create your model, the name of your model and your model's architecture. + +??? note "Note" + + Ultralytics HUB will try to pre-select the project. + + If you opened the **Train Model** dialog as described above, Ultralytics HUB will pre-select the last project you used. + + If you opened the **Train Model** dialog from the Project page, Ultralytics HUB will pre-select the project you were inside of. + + ![Ultralytics HUB screenshot of the Project page with an arrow pointing to the Train Model button](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_train_model_6.jpg) + + In case you don't have a project created yet, you can set the name of your project in this step and it will be created together with your model. + + ![Ultralytics HUB screenshot of the Train Model dialog with an arrow pointing to the project name](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_train_model_7.jpg) + +!!! info "Info" + + You can read more about the available [YOLOv8](https://docs.ultralytics.com/models/yolov8) (and [YOLOv5](https://docs.ultralytics.com/models/yolov5)) architectures in our documentation. + +When you're happy with your model configuration, click **Continue**. + +![Ultralytics HUB screenshot of the Train Model dialog with an arrow pointing to a model architecture and one to the Continue button](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_train_model_8.jpg) + +??? note "Note" + + By default, your model will use a pre-trained model (trained on the [COCO](https://docs.ultralytics.com/datasets/detect/coco) dataset) to reduce training time. + + You can change this behaviour by opening the **Advanced Options** accordion. + +### 3. Train + +In this step, you will start training you model. + +Ultralytics HUB offers three training options: + +- Ultralytics Cloud **(COMING SOON)** +- Google Colab +- Bring your own agent + +In order to start training your model, follow the instructions presented in this step. + +![Ultralytics HUB screenshot of the Train Model dialog with an arrow pointing to each step](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_train_model_9.jpg) + +??? note "Note" + + When you are on this step, before the training starts, you can change the default training configuration by opening the **Advanced Options** accordion. + + ![Ultralytics HUB screenshot of the Train Model dialog with an arrow pointing to the Train Advanced Options](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_train_model_10.jpg) + +??? note "Note" + + When you are on this step, you have the option to close the **Train Model** dialog and start training your model from the Model page later. + + ![Ultralytics HUB screenshot of the Model page with an arrow pointing to the Start Training card](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_train_model_11.jpg) + +To start training your model using Google Colab, simply follow the instructions shown above or on the Google Colab notebook. -Open In Colab + Open In Colab + -## Deploy to Real World +When the training starts, you can click **Done** and monitor the training progress on the Model page. -Export your model to 13 different formats, including TensorFlow, ONNX, OpenVINO, CoreML, Paddle and many others. Run -models directly on your [iOS](https://apps.apple.com/xk/app/ultralytics/id1583935240) or -[Android](https://play.google.com/store/apps/details?id=com.ultralytics.ultralytics_app) mobile device by downloading -the [Ultralytics App](https://ultralytics.com/app_install)! \ No newline at end of file +![Ultralytics HUB screenshot of the Train Model dialog with an arrow pointing to the Done button](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_train_model_12.jpg) + +![Ultralytics HUB screenshot of the Model page of a model that is currently training](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_train_model_13.jpg) + +??? note "Note" + + In case the training stops and a checkpoint was saved, you can resume training your model from the Model page. + + ![Ultralytics HUB screenshot of the Model page with an arrow pointing to the Resume Training card](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_train_model_14.jpg) + +## Preview Model + +Ultralytics HUB offers a variety of ways to preview your trained model. + +You can preview your model if you click on the **Preview** tab and upload an image in the **Test** card. + +![Ultralytics HUB screenshot of the Preview tab (Test card) inside the Model page](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_preview_model_1.jpg) + +You can also use our Ultralytics Cloud API to effortlessly [run inference](https://docs.ultralytics.com/hub/inference_api) with your custom model. + +![Ultralytics HUB screenshot of the Preview tab (Ultralytics Cloud API card) inside the Model page](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_preview_model_2.jpg) + +Furthermore, you can preview your model in real-time directly on your [iOS](https://apps.apple.com/xk/app/ultralytics/id1583935240) or [Android](https://play.google.com/store/apps/details?id=com.ultralytics.ultralytics_app) mobile device by [downloading](https://ultralytics.com/app_install) our [Ultralytics HUB Mobile Application](./app/index.md). + +![Ultralytics HUB screenshot of the Deploy tab inside the Model page with arrow pointing to the Real-Time Preview card](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_preview_model_3.jpg) + +## Deploy Model + +You can export your model to 13 different formats, including ONNX, OpenVINO, CoreML, TensorFlow, Paddle and many others. + +![Ultralytics HUB screenshot of the Deploy tab inside the Model page with all formats exported](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_deploy_model_1.jpg) + +??? tip "Tip" + + You can customize the export options of each format if you open the export actions dropdown and click on the **Advanced** option. + + ![Ultralytics HUB screenshot of the Deploy tab inside the Model page with an arrow pointing to the Advanced option](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_deploy_model_2.jpg) + +## Share Model + +!!! info "Info" + + Ultralytics HUB's sharing functionality provides a convenient way to share models with others. This feature is designed to accommodate both existing Ultralytics HUB users and those who have yet to create an account. + +??? note "Note" + + You have control over the general access of your models. + + You can choose to set the general access to "Private", in which case, only you will have access to it. Alternatively, you can set the general access to "Unlisted" which grants viewing access to anyone who has the direct link to the model, regardless of whether they have an Ultralytics HUB account or not. + +Navigate to the Model page of the model you want to share, open the model actions dropdown and click on the **Share** option. This action will trigger the **Share Model** dialog. + +![Ultralytics HUB screenshot of the Model page with an arrow pointing to the Share option](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_share_model_1.jpg) + +??? tip "Tip" + + You can also share a model directly from the [Models](https://hub.ultralytics.com/models) page or from the Project page of the project where your model is located. + + ![Ultralytics HUB screenshot of the Models page with an arrow pointing to the Share option of one of the models](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_share_model_2.jpg) + +Set the general access to "Unlisted" and click **Save**. + +![Ultralytics HUB screenshot of the Share Model dialog with an arrow pointing to the dropdown and one to the Save button](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_share_model_3.jpg) + +Now, anyone who has the direct link to your model can view it. + +??? tip "Tip" + + You can easily click on the models's link shown in the **Share Model** dialog to copy it. + + ![Ultralytics HUB screenshot of the Share Model dialog with an arrow pointing to the model's link](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_share_model_4.jpg) + +## Edit Model + +Navigate to the Model page of the model you want to edit, open the model actions dropdown and click on the **Edit** option. This action will trigger the **Update Model** dialog. + +![Ultralytics HUB screenshot of the Model page with an arrow pointing to the Edit option](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_edit_model_1.jpg) + +??? tip "Tip" + + You can also edit a model directly from the [Models](https://hub.ultralytics.com/models) page or from the Project page of the project where your model is located. + + ![Ultralytics HUB screenshot of the Models page with an arrow pointing to the Edit option of one of the models](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_edit_model_2.jpg) + +Apply the desired modifications to your model and then confirm the changes by clicking **Save**. + +![Ultralytics HUB screenshot of the Update Model dialog with an arrow pointing to the Save button](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_edit_model_3.jpg) + +## Delete Model + +Navigate to the Model page of the model you want to delete, open the model actions dropdown and click on the **Delete** option. This action will delete the model. + +![Ultralytics HUB screenshot of the Model page with an arrow pointing to the Delete option](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_delete_model_1.jpg) + +??? tip "Tip" + + You can also delete a model directly from the [Models](https://hub.ultralytics.com/models) page or from the Project page of the project where your model is located. + + ![Ultralytics HUB screenshot of the Models page with an arrow pointing to the Delete option of one of the models](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_delete_model_2.jpg) + +??? note "Note" + + If you change your mind, you can restore the model from the [Trash](https://hub.ultralytics.com/trash) page. + + ![Ultralytics HUB screenshot of the Trash page with an arrow pointing to the Restore option of one of the models](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/models/hub_delete_model_3.jpg) diff --git a/downloads/ultralytics-main/docs/hub/projects.md b/downloads/ultralytics-main/docs/hub/projects.md index 19480d27d..41c7732eb 100644 --- a/downloads/ultralytics-main/docs/hub/projects.md +++ b/downloads/ultralytics-main/docs/hub/projects.md @@ -1,7 +1,169 @@ --- comments: true +description: Learn how to manage Ultralytics HUB projects. Understand effective strategies to create, share, edit, delete, and compare models in an organized workspace. +keywords: Ultralytics, HUB projects, Create project, Edit project, Share project, Delete project, Compare Models, Model Management --- -# 🚧 Page Under Construction ⚒ +# Ultralytics HUB Projects -This page is currently under construction!️ 👷Please check back later for updates. 😃🔜 +Ultralytics HUB projects provide an effective solution for consolidating and managing your models. If you are working with several models that perform similar tasks or have related purposes, Ultralytics HUB projects allow you to group these models together. + +This creates a unified and organized workspace that facilitates easier model management, comparison and development. Having similar models or various iterations together can facilitate rapid benchmarking, as you can compare their effectiveness. This can lead to faster, more insightful iterative development and refinement of your models. + +## Create Project + +Navigate to the [Projects](https://hub.ultralytics.com/projects) page by clicking on the **Projects** button in the sidebar. + +![Ultralytics HUB screenshot of the Home page with an arrow pointing to the Projects button in the sidebar](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_create_project_1.jpg) + +??? tip "Tip" + + You can also create a project directly from the [Home](https://hub.ultralytics.com/home) page. + + ![Ultralytics HUB screenshot of the Home page with an arrow pointing to the Create Project card](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_create_project_2.jpg) + +Click on the **Create Project** button on the top right of the page. This action will trigger the **Create Project** dialog, opening up a suite of options for tailoring your project to your needs. + +![Ultralytics HUB screenshot of the Projects page with an arrow pointing to the Create Project button](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_create_project_3.jpg) + +Type the name of your project in the _Project name_ field or keep the default name and finalize the project creation with a single click. + +You have the additional option to enrich your project with a description and a unique image, enhancing its recognizability on the Projects page. + +When you're happy with your project configuration, click **Create**. + +![Ultralytics HUB screenshot of the Create Project dialog with an arrow pointing to the Create button](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_create_project_4.jpg) + +After your project is created, you will be able to access it from the Projects page. + +![Ultralytics HUB screenshot of the Projects page with an arrow pointing to one of the projects](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_create_project_5.jpg) + +Next, [train a model](https://docs.ultralytics.com/hub/models/#train-model) inside your project. + +![Ultralytics HUB screenshot of the Project page with an arrow pointing to the Train Model button](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_create_project_6.jpg) + +## Share Project + +!!! info "Info" + + Ultralytics HUB's sharing functionality provides a convenient way to share projects with others. This feature is designed to accommodate both existing Ultralytics HUB users and those who have yet to create an account. + +??? note "Note" + + You have control over the general access of your projects. + + You can choose to set the general access to "Private", in which case, only you will have access to it. Alternatively, you can set the general access to "Unlisted" which grants viewing access to anyone who has the direct link to the project, regardless of whether they have an Ultralytics HUB account or not. + +Navigate to the Project page of the project you want to share, open the project actions dropdown and click on the **Share** option. This action will trigger the **Share Project** dialog. + +![Ultralytics HUB screenshot of the Project page with an arrow pointing to the Share option](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_share_project_1.jpg) + +??? tip "Tip" + + You can also share a project directly from the [Projects](https://hub.ultralytics.com/projects) page. + + ![Ultralytics HUB screenshot of the Projects page with an arrow pointing to the Share option of one of the projects](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_share_project_2.jpg) + +Set the general access to "Unlisted" and click **Save**. + +![Ultralytics HUB screenshot of the Share Project dialog with an arrow pointing to the dropdown and one to the Save button](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_share_project_3.jpg) + +!!! warning "Warning" + + When changing the general access of a project, the general access of the models inside the project will be changed as well. + +Now, anyone who has the direct link to your project can view it. + +??? tip "Tip" + + You can easily click on the project's link shown in the **Share Project** dialog to copy it. + + ![Ultralytics HUB screenshot of the Share Project dialog with an arrow pointing to the project's link](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_share_project_4.jpg) + +## Edit Project + +Navigate to the Project page of the project you want to edit, open the project actions dropdown and click on the **Edit** option. This action will trigger the **Update Project** dialog. + +![Ultralytics HUB screenshot of the Project page with an arrow pointing to the Edit option](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_edit_project_1.jpg) + +??? tip "Tip" + + You can also edit a project directly from the [Projects](https://hub.ultralytics.com/projects) page. + + ![Ultralytics HUB screenshot of the Projects page with an arrow pointing to the Edit option of one of the projects](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_edit_project_2.jpg) + +Apply the desired modifications to your project and then confirm the changes by clicking **Save**. + +![Ultralytics HUB screenshot of the Update Project dialog with an arrow pointing to the Save button](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_edit_project_3.jpg) + +## Delete Project + +Navigate to the Project page of the project you want to delete, open the project actions dropdown and click on the **Delete** option. This action will delete the project. + +![Ultralytics HUB screenshot of the Project page with an arrow pointing to the Delete option](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_delete_project_1.jpg) + +??? tip "Tip" + + You can also delete a project directly from the [Projects](https://hub.ultralytics.com/projects) page. + + ![Ultralytics HUB screenshot of the Projects page with an arrow pointing to the Delete option of one of the projects](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_delete_project_2.jpg) + +!!! warning "Warning" + + When deleting a project, the the models inside the project will be deleted as well. + +??? note "Note" + + If you change your mind, you can restore the project from the [Trash](https://hub.ultralytics.com/trash) page. + + ![Ultralytics HUB screenshot of the Trash page with an arrow pointing to the Restore option of one of the projects](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_delete_project_3.jpg) + +## Compare Models + +Navigate to the Project page of the project where the models you want to compare are located. To use the model comparison feature, click on the **Charts** tab. + +![Ultralytics HUB screenshot of the Project page with an arrow pointing to the Charts tab](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_compare_models_1.jpg) + +This will display all the relevant charts. Each chart corresponds to a different metric and contains the performance of each model for that metric. The models are represented by different colors and you can hover over each data point to get more information. + +![Ultralytics HUB screenshot of the Charts tab inside the Project page](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_compare_models_2.jpg) + +??? tip "Tip" + + Each chart can be enlarged for better visualization. + + ![Ultralytics HUB screenshot of the Charts tab inside the Project page with an arrow pointing to the expand icon](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_compare_models_3.jpg) + + ![Ultralytics HUB screenshot of the Charts tab inside the Project page with one of the charts expanded](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_compare_models_4.jpg) + +??? tip "Tip" + + You have the flexibility to customize your view by selectively hiding certain models. This feature allows you to concentrate on the models of interest. + + ![Ultralytics HUB screenshot of the Charts tab inside the Project page with an arrow pointing to the hide/unhide icon of one of the model](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_compare_models_5.jpg) + +## Reorder Models + +??? note "Note" + + Ultralytics HUB's reordering functionality works only inside projects you own. + +Navigate to the Project page of the project where the models you want to reorder are located. Click on the designated reorder icon of the model you want to move and drag it to the desired location. + +![Ultralytics HUB screenshot of the Project page with an arrow pointing to the reorder icon](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_reorder_models_1.jpg) + +## Transfer Models + +Navigate to the Project page of the project where the model you want to mode is located, open the project actions dropdown and click on the **Transfer** option. This action will trigger the **Transfer Model** dialog. + +![Ultralytics HUB screenshot of the Project page with an arrow pointing to the Transfer option of one of the models](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_transfer_models_1.jpg) + +??? tip "Tip" + + You can also transfer a model directly from the [Models](https://hub.ultralytics.com/models) page. + + ![Ultralytics HUB screenshot of the Models page with an arrow pointing to the Transfer option of one of the models](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_transfer_models_2.jpg) + +Select the project you want to transfer the model to and click **Save**. + +![Ultralytics HUB screenshot of the Transfer Model dialog with an arrow pointing to the dropdown and one to the Save button](https://raw.githubusercontent.com/ultralytics/assets/main/docs/hub/projects/hub_transfer_models_3.jpg) diff --git a/downloads/ultralytics-main/docs/index.md b/downloads/ultralytics-main/docs/index.md index 73212a770..4d256489e 100644 --- a/downloads/ultralytics-main/docs/index.md +++ b/downloads/ultralytics-main/docs/index.md @@ -1,6 +1,7 @@ --- comments: true -description: Explore Ultralytics YOLOv8, a cutting-edge real-time object detection and image segmentation model for various applications and hardware platforms. +description: Explore a complete guide to Ultralytics YOLOv8, a high-speed, high-accuracy object detection & image segmentation model. Installation, prediction, training tutorials and more. +keywords: Ultralytics, YOLOv8, object detection, image segmentation, machine learning, deep learning, computer vision, YOLOv8 installation, YOLOv8 prediction, YOLOv8 training, YOLO history, YOLO licenses ---
@@ -9,6 +10,7 @@ description: Explore Ultralytics YOLOv8, a cutting-edge real-time object detecti

Ultralytics CI + Ultralytics Code Coverage YOLOv8 Citation Docker Pulls
@@ -38,4 +40,13 @@ Explore the YOLOv8 Docs, a comprehensive resource designed to help you understan - [YOLOv5](https://github.com/ultralytics/yolov5) further improved the model's performance and added new features such as hyperparameter optimization, integrated experiment tracking and automatic export to popular export formats. - [YOLOv6](https://github.com/meituan/YOLOv6) was open-sourced by [Meituan](https://about.meituan.com/) in 2022 and is in use in many of the company's autonomous delivery robots. - [YOLOv7](https://github.com/WongKinYiu/yolov7) added additional tasks such as pose estimation on the COCO keypoints dataset. -- [YOLOv8](https://github.com/ultralytics/ultralytics) is the latest version of YOLO by Ultralytics. As a cutting-edge, state-of-the-art (SOTA) model, YOLOv8 builds on the success of previous versions, introducing new features and improvements for enhanced performance, flexibility, and efficiency. YOLOv8 supports a full range of vision AI tasks, including [detection](tasks/detect.md), [segmentation](tasks/segment.md), [pose estimation](tasks/pose.md), [tracking](modes/track.md), and [classification](tasks/classify.md). This versatility allows users to leverage YOLOv8's capabilities across diverse applications and domains. \ No newline at end of file +- [YOLOv8](https://github.com/ultralytics/ultralytics) is the latest version of YOLO by Ultralytics. As a cutting-edge, state-of-the-art (SOTA) model, YOLOv8 builds on the success of previous versions, introducing new features and improvements for enhanced performance, flexibility, and efficiency. YOLOv8 supports a full range of vision AI tasks, including [detection](tasks/detect.md), [segmentation](tasks/segment.md), [pose estimation](tasks/pose.md), [tracking](modes/track.md), and [classification](tasks/classify.md). This versatility allows users to leverage YOLOv8's capabilities across diverse applications and domains. + +## YOLO Licenses: How is Ultralytics YOLO licensed? + +Ultralytics offers two licensing options to accommodate diverse use cases: + +- **AGPL-3.0 License**: This [OSI-approved](https://opensource.org/licenses/) open-source license is ideal for students and enthusiasts, promoting open collaboration and knowledge sharing. See the [LICENSE](https://github.com/ultralytics/ultralytics/blob/main/LICENSE) file for more details. +- **Enterprise License**: Designed for commercial use, this license permits seamless integration of Ultralytics software and AI models into commercial goods and services, bypassing the open-source requirements of AGPL-3.0. If your scenario involves embedding our solutions into a commercial offering, reach out through [Ultralytics Licensing](https://ultralytics.com/license). + +Our licensing strategy is designed to ensure that any improvements to our open-source projects are returned to the community. We hold the principles of open source close to our hearts ❤️, and our mission is to guarantee that our contributions can be utilized and expanded upon in ways that are beneficial to all. diff --git a/downloads/ultralytics-main/docs/integrations/index.md b/downloads/ultralytics-main/docs/integrations/index.md new file mode 100644 index 000000000..31e795ae2 --- /dev/null +++ b/downloads/ultralytics-main/docs/integrations/index.md @@ -0,0 +1,61 @@ +--- +comments: true +description: Explore Ultralytics integrations with tools for dataset management, model optimization, ML workflows automation, experiment tracking, version control, and more. Learn about our support for various model export formats for deployment. +keywords: Ultralytics integrations, Roboflow, Neural Magic, ClearML, Comet ML, DVC, Ultralytics HUB, MLFlow, Neptune, Ray Tune, TensorBoard, W&B, model export formats, PyTorch, TorchScript, ONNX, OpenVINO, TensorRT, CoreML, TF SavedModel, TF GraphDef, TF Lite, TF Edge TPU, TF.js, PaddlePaddle, NCNN +--- + +# Ultralytics Integrations + +Welcome to the Ultralytics Integrations page! This page provides an overview of our partnerships with various tools and platforms, designed to streamline your machine learning workflows, enhance dataset management, simplify model training, and facilitate efficient deployment. + + + +## Datasets Integrations + +- [Roboflow](https://roboflow.com/?ref=ultralytics): Facilitate seamless dataset management for Ultralytics models, offering robust annotation, preprocessing, and augmentation capabilities. + +## Training Integrations + +- [Comet ML](https://www.comet.ml/): Enhance your model development with Ultralytics by tracking, comparing, and optimizing your machine learning experiments. + +- [ClearML](https://clear.ml/): Automate your Ultralytics ML workflows, monitor experiments, and foster team collaboration. + +- [DVC](https://dvc.org/): Implement version control for your Ultralytics machine learning projects, synchronizing data, code, and models effectively. + +- [Ultralytics HUB](https://hub.ultralytics.com): Access and contribute to a community of pre-trained Ultralytics models. + +- [MLFlow](https://mlflow.org/): Streamline the entire ML lifecycle of Ultralytics models, from experimentation and reproducibility to deployment. + +- [Neptune](https://neptune.ai/): Maintain a comprehensive log of your ML experiments with Ultralytics in this metadata store designed for MLOps. + +- [Ray Tune](ray-tune.md): Optimize the hyperparameters of your Ultralytics models at any scale. + +- [TensorBoard](https://tensorboard.dev/): Visualize your Ultralytics ML workflows, monitor model metrics, and foster team collaboration. + +- [Weights & Biases (W&B)](https://wandb.ai/site): Monitor experiments, visualize metrics, and foster reproducibility and collaboration on Ultralytics projects. + +## Deployment Integrations + +- [Neural Magic](https://neuralmagic.com/): Leverage Quantization Aware Training (QAT) and pruning techniques to optimize Ultralytics models for superior performance and leaner size. + +### Export Formats + +We also support a variety of model export formats for deployment in different environments. Here are the available formats: + +| Format | `format` Argument | Model | Metadata | Arguments | +|--------------------------------------------------------------------|-------------------|---------------------------|----------|-----------------------------------------------------| +| [PyTorch](https://pytorch.org/) | - | `yolov8n.pt` | ✅ | - | +| [TorchScript](https://pytorch.org/docs/stable/jit.html) | `torchscript` | `yolov8n.torchscript` | ✅ | `imgsz`, `optimize` | +| [ONNX](https://onnx.ai/) | `onnx` | `yolov8n.onnx` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `opset` | +| [OpenVINO](openvino.md) | `openvino` | `yolov8n_openvino_model/` | ✅ | `imgsz`, `half` | +| [TensorRT](https://developer.nvidia.com/tensorrt) | `engine` | `yolov8n.engine` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `workspace` | +| [CoreML](https://github.com/apple/coremltools) | `coreml` | `yolov8n.mlpackage` | ✅ | `imgsz`, `half`, `int8`, `nms` | +| [TF SavedModel](https://www.tensorflow.org/guide/saved_model) | `saved_model` | `yolov8n_saved_model/` | ✅ | `imgsz`, `keras` | +| [TF GraphDef](https://www.tensorflow.org/api_docs/python/tf/Graph) | `pb` | `yolov8n.pb` | ❌ | `imgsz` | +| [TF Lite](https://www.tensorflow.org/lite) | `tflite` | `yolov8n.tflite` | ✅ | `imgsz`, `half`, `int8` | +| [TF Edge TPU](https://coral.ai/docs/edgetpu/models-intro/) | `edgetpu` | `yolov8n_edgetpu.tflite` | ✅ | `imgsz` | +| [TF.js](https://www.tensorflow.org/js) | `tfjs` | `yolov8n_web_model/` | ✅ | `imgsz` | +| [PaddlePaddle](https://github.com/PaddlePaddle) | `paddle` | `yolov8n_paddle_model/` | ✅ | `imgsz` | +| [NCNN](https://github.com/Tencent/ncnn) | `ncnn` | `yolov8n_ncnn_model/` | ✅ | `imgsz`, `half` | + +Explore the links to learn more about each integration and how to get the most out of them with Ultralytics. diff --git a/downloads/ultralytics-main/docs/integrations/openvino.md b/downloads/ultralytics-main/docs/integrations/openvino.md new file mode 100644 index 000000000..02108de4e --- /dev/null +++ b/downloads/ultralytics-main/docs/integrations/openvino.md @@ -0,0 +1,271 @@ +--- +comments: true +description: Discover the power of deploying your Ultralytics YOLOv8 model using OpenVINO format for up to 10x speedup vs PyTorch. +keywords: ultralytics docs, YOLOv8, export YOLOv8, YOLOv8 model deployment, exporting YOLOv8, OpenVINO, OpenVINO format +--- + +OpenVINO Ecosystem + +**Export mode** is used for exporting a YOLOv8 model to a format that can be used for deployment. In this guide, we specifically cover exporting to OpenVINO, which can provide up to 3x [CPU](https://docs.openvino.ai/2023.0/openvino_docs_OV_UG_supported_plugins_CPU.html) speedup as well as accelerating on other Intel hardware ([iGPU](https://docs.openvino.ai/2023.0/openvino_docs_OV_UG_supported_plugins_GPU.html), [dGPU](https://docs.openvino.ai/2023.0/openvino_docs_OV_UG_supported_plugins_GPU.html), [VPU](https://docs.openvino.ai/2022.3/openvino_docs_OV_UG_supported_plugins_VPU.html), etc.). + +OpenVINO, short for Open Visual Inference & Neural Network Optimization toolkit, is a comprehensive toolkit for optimizing and deploying AI inference models. Even though the name contains Visual, OpenVINO also supports various additional tasks including language, audio, time series, etc. + +## Usage Examples + +Export a YOLOv8n model to OpenVINO format and run inference with the exported model. + +!!! example "" + + === "Python" + + ```python + from ultralytics import YOLO + + # Load a YOLOv8n PyTorch model + model = YOLO('yolov8n.pt') + + # Export the model + model.export(format='openvino') # creates 'yolov8n_openvino_model/' + + # Load the exported OpenVINO model + ov_model = YOLO('yolov8n_openvino_model/') + + # Run inference + results = ov_model('https://ultralytics.com/images/bus.jpg') + ``` + === "CLI" + + ```bash + # Export a YOLOv8n PyTorch model to OpenVINO format + yolo export model=yolov8n.pt format=openvino # creates 'yolov8n_openvino_model/' + + # Run inference with the exported model + yolo predict model=yolov8n_openvino_model source='https://ultralytics.com/images/bus.jpg' + ``` + +## Arguments + +| Key | Value | Description | +|----------|--------------|------------------------------------------------------| +| `format` | `'openvino'` | format to export to | +| `imgsz` | `640` | image size as scalar or (h, w) list, i.e. (640, 480) | +| `half` | `False` | FP16 quantization | + +## Benefits of OpenVINO + +1. **Performance**: OpenVINO delivers high-performance inference by utilizing the power of Intel CPUs, integrated and discrete GPUs, and FPGAs. +2. **Support for Heterogeneous Execution**: OpenVINO provides an API to write once and deploy on any supported Intel hardware (CPU, GPU, FPGA, VPU, etc.). +3. **Model Optimizer**: OpenVINO provides a Model Optimizer that imports, converts, and optimizes models from popular deep learning frameworks such as PyTorch, TensorFlow, TensorFlow Lite, Keras, ONNX, PaddlePaddle, and Caffe. +4. **Ease of Use**: The toolkit comes with more than [80 tutorial notebooks](https://github.com/openvinotoolkit/openvino_notebooks) (including [YOLOv8 optimization](https://github.com/openvinotoolkit/openvino_notebooks/tree/main/notebooks/230-yolov8-optimization)) teaching different aspects of the toolkit. + +## OpenVINO Export Structure + +When you export a model to OpenVINO format, it results in a directory containing the following: + +1. **XML file**: Describes the network topology. +2. **BIN file**: Contains the weights and biases binary data. +3. **Mapping file**: Holds mapping of original model output tensors to OpenVINO tensor names. + +You can use these files to run inference with the OpenVINO Inference Engine. + +## Using OpenVINO Export in Deployment + +Once you have the OpenVINO files, you can use the OpenVINO Runtime to run the model. The Runtime provides a unified API to inference across all supported Intel hardware. It also provides advanced capabilities like load balancing across Intel hardware and asynchronous execution. For more information on running the inference, refer to the [Inference with OpenVINO Runtime Guide](https://docs.openvino.ai/2023.0/openvino_docs_OV_UG_OV_Runtime_User_Guide.html). + +Remember, you'll need the XML and BIN files as well as any application-specific settings like input size, scale factor for normalization, etc., to correctly set up and use the model with the Runtime. + +In your deployment application, you would typically do the following steps: + +1. Initialize OpenVINO by creating `core = Core()`. +2. Load the model using the `core.read_model()` method. +3. Compile the model using the `core.compile_model()` function. +4. Prepare the input (image, text, audio, etc.). +5. Run inference using `compiled_model(input_data)`. + +For more detailed steps and code snippets, refer to the [OpenVINO documentation](https://docs.openvino.ai/) or [API tutorial](https://github.com/openvinotoolkit/openvino_notebooks/blob/main/notebooks/002-openvino-api/002-openvino-api.ipynb). + +## OpenVINO YOLOv8 Benchmarks + +YOLOv8 benchmarks below were run by the Ultralytics team on 4 different model formats measuring speed and accuracy: PyTorch, TorchScript, ONNX and OpenVINO. Benchmarks were run on Intel Flex and Arc GPUs, and on Intel Xeon CPUs at FP32 precision (with the `half=False` argument). + +!!! note + + The benchmarking results below are for reference and might vary based on the exact hardware and software configuration of a system, as well as the current workload of the system at the time the benchmarks are run. + + All benchmarks run with `openvino` python package version [2023.0.1](https://pypi.org/project/openvino/2023.0.1/). + +### Intel Flex GPU + +The Intel® Data Center GPU Flex Series is a versatile and robust solution designed for the intelligent visual cloud. This GPU supports a wide array of workloads including media streaming, cloud gaming, AI visual inference, and virtual desktop Infrastructure workloads. It stands out for its open architecture and built-in support for the AV1 encode, providing a standards-based software stack for high-performance, cross-architecture applications. The Flex Series GPU is optimized for density and quality, offering high reliability, availability, and scalability. + +Benchmarks below run on Intel® Data Center GPU Flex 170 at FP32 precision. + +
+ +
+ +| Model | Format | Status | Size (MB) | mAP50-95(B) | Inference time (ms/im) | +|---------|-------------|--------|-----------|-------------|------------------------| +| YOLOv8n | PyTorch | ✅ | 6.2 | 0.3709 | 21.79 | +| YOLOv8n | TorchScript | ✅ | 12.4 | 0.3704 | 23.24 | +| YOLOv8n | ONNX | ✅ | 12.2 | 0.3704 | 37.22 | +| YOLOv8n | OpenVINO | ✅ | 12.3 | 0.3703 | 3.29 | +| YOLOv8s | PyTorch | ✅ | 21.5 | 0.4471 | 31.89 | +| YOLOv8s | TorchScript | ✅ | 42.9 | 0.4472 | 32.71 | +| YOLOv8s | ONNX | ✅ | 42.8 | 0.4472 | 43.42 | +| YOLOv8s | OpenVINO | ✅ | 42.9 | 0.4470 | 3.92 | +| YOLOv8m | PyTorch | ✅ | 49.7 | 0.5013 | 50.75 | +| YOLOv8m | TorchScript | ✅ | 99.2 | 0.4999 | 47.90 | +| YOLOv8m | ONNX | ✅ | 99.0 | 0.4999 | 63.16 | +| YOLOv8m | OpenVINO | ✅ | 49.8 | 0.4997 | 7.11 | +| YOLOv8l | PyTorch | ✅ | 83.7 | 0.5293 | 77.45 | +| YOLOv8l | TorchScript | ✅ | 167.2 | 0.5268 | 85.71 | +| YOLOv8l | ONNX | ✅ | 166.8 | 0.5268 | 88.94 | +| YOLOv8l | OpenVINO | ✅ | 167.0 | 0.5264 | 9.37 | +| YOLOv8x | PyTorch | ✅ | 130.5 | 0.5404 | 100.09 | +| YOLOv8x | TorchScript | ✅ | 260.7 | 0.5371 | 114.64 | +| YOLOv8x | ONNX | ✅ | 260.4 | 0.5371 | 110.32 | +| YOLOv8x | OpenVINO | ✅ | 260.6 | 0.5367 | 15.02 | + +This table represents the benchmark results for five different models (YOLOv8n, YOLOv8s, YOLOv8m, YOLOv8l, YOLOv8x) across four different formats (PyTorch, TorchScript, ONNX, OpenVINO), giving us the status, size, mAP50-95(B) metric, and inference time for each combination. + +### Intel Arc GPU + +Intel® Arc™ represents Intel's foray into the dedicated GPU market. The Arc™ series, designed to compete with leading GPU manufacturers like AMD and Nvidia, caters to both the laptop and desktop markets. The series includes mobile versions for compact devices like laptops, and larger, more powerful versions for desktop computers. + +The Arc™ series is divided into three categories: Arc™ 3, Arc™ 5, and Arc™ 7, with each number indicating the performance level. Each category includes several models, and the 'M' in the GPU model name signifies a mobile, integrated variant. + +Early reviews have praised the Arc™ series, particularly the integrated A770M GPU, for its impressive graphics performance. The availability of the Arc™ series varies by region, and additional models are expected to be released soon. Intel® Arc™ GPUs offer high-performance solutions for a range of computing needs, from gaming to content creation. + +Benchmarks below run on Intel® Arc 770 GPU at FP32 precision. + +
+ +
+ +| Model | Format | Status | Size (MB) | metrics/mAP50-95(B) | Inference time (ms/im) | +|---------|-------------|--------|-----------|---------------------|------------------------| +| YOLOv8n | PyTorch | ✅ | 6.2 | 0.3709 | 88.79 | +| YOLOv8n | TorchScript | ✅ | 12.4 | 0.3704 | 102.66 | +| YOLOv8n | ONNX | ✅ | 12.2 | 0.3704 | 57.98 | +| YOLOv8n | OpenVINO | ✅ | 12.3 | 0.3703 | 8.52 | +| YOLOv8s | PyTorch | ✅ | 21.5 | 0.4471 | 189.83 | +| YOLOv8s | TorchScript | ✅ | 42.9 | 0.4472 | 227.58 | +| YOLOv8s | ONNX | ✅ | 42.7 | 0.4472 | 142.03 | +| YOLOv8s | OpenVINO | ✅ | 42.9 | 0.4469 | 9.19 | +| YOLOv8m | PyTorch | ✅ | 49.7 | 0.5013 | 411.64 | +| YOLOv8m | TorchScript | ✅ | 99.2 | 0.4999 | 517.12 | +| YOLOv8m | ONNX | ✅ | 98.9 | 0.4999 | 298.68 | +| YOLOv8m | OpenVINO | ✅ | 99.1 | 0.4996 | 12.55 | +| YOLOv8l | PyTorch | ✅ | 83.7 | 0.5293 | 725.73 | +| YOLOv8l | TorchScript | ✅ | 167.1 | 0.5268 | 892.83 | +| YOLOv8l | ONNX | ✅ | 166.8 | 0.5268 | 576.11 | +| YOLOv8l | OpenVINO | ✅ | 167.0 | 0.5262 | 17.62 | +| YOLOv8x | PyTorch | ✅ | 130.5 | 0.5404 | 988.92 | +| YOLOv8x | TorchScript | ✅ | 260.7 | 0.5371 | 1186.42 | +| YOLOv8x | ONNX | ✅ | 260.4 | 0.5371 | 768.90 | +| YOLOv8x | OpenVINO | ✅ | 260.6 | 0.5367 | 19 | + +### Intel Xeon CPU + +The Intel® Xeon® CPU is a high-performance, server-grade processor designed for complex and demanding workloads. From high-end cloud computing and virtualization to artificial intelligence and machine learning applications, Xeon® CPUs provide the power, reliability, and flexibility required for today's data centers. + +Notably, Xeon® CPUs deliver high compute density and scalability, making them ideal for both small businesses and large enterprises. By choosing Intel® Xeon® CPUs, organizations can confidently handle their most demanding computing tasks and foster innovation while maintaining cost-effectiveness and operational efficiency. + +Benchmarks below run on 4th Gen Intel® Xeon® Scalable CPU at FP32 precision. + +
+ +
+ +| Model | Format | Status | Size (MB) | metrics/mAP50-95(B) | Inference time (ms/im) | +|---------|-------------|--------|-----------|---------------------|------------------------| +| YOLOv8n | PyTorch | ✅ | 6.2 | 0.3709 | 24.36 | +| YOLOv8n | TorchScript | ✅ | 12.4 | 0.3704 | 23.93 | +| YOLOv8n | ONNX | ✅ | 12.2 | 0.3704 | 39.86 | +| YOLOv8n | OpenVINO | ✅ | 12.3 | 0.3704 | 11.34 | +| YOLOv8s | PyTorch | ✅ | 21.5 | 0.4471 | 33.77 | +| YOLOv8s | TorchScript | ✅ | 42.9 | 0.4472 | 34.84 | +| YOLOv8s | ONNX | ✅ | 42.8 | 0.4472 | 43.23 | +| YOLOv8s | OpenVINO | ✅ | 42.9 | 0.4471 | 13.86 | +| YOLOv8m | PyTorch | ✅ | 49.7 | 0.5013 | 53.91 | +| YOLOv8m | TorchScript | ✅ | 99.2 | 0.4999 | 53.51 | +| YOLOv8m | ONNX | ✅ | 99.0 | 0.4999 | 64.16 | +| YOLOv8m | OpenVINO | ✅ | 99.1 | 0.4996 | 28.79 | +| YOLOv8l | PyTorch | ✅ | 83.7 | 0.5293 | 75.78 | +| YOLOv8l | TorchScript | ✅ | 167.2 | 0.5268 | 79.13 | +| YOLOv8l | ONNX | ✅ | 166.8 | 0.5268 | 88.45 | +| YOLOv8l | OpenVINO | ✅ | 167.0 | 0.5263 | 56.23 | +| YOLOv8x | PyTorch | ✅ | 130.5 | 0.5404 | 96.60 | +| YOLOv8x | TorchScript | ✅ | 260.7 | 0.5371 | 114.28 | +| YOLOv8x | ONNX | ✅ | 260.4 | 0.5371 | 111.02 | +| YOLOv8x | OpenVINO | ✅ | 260.6 | 0.5371 | 83.28 | + +### Intel Core CPU + +The Intel® Core® series is a range of high-performance processors by Intel. The lineup includes Core i3 (entry-level), Core i5 (mid-range), Core i7 (high-end), and Core i9 (extreme performance). Each series caters to different computing needs and budgets, from everyday tasks to demanding professional workloads. With each new generation, improvements are made to performance, energy efficiency, and features. + +Benchmarks below run on 13th Gen Intel® Core® i7-13700H CPU at FP32 precision. + +
+ +
+ +| Model | Format | Status | Size (MB) | metrics/mAP50-95(B) | Inference time (ms/im) | +|---------|-------------|--------|-----------|---------------------|------------------------| +| YOLOv8n | PyTorch | ✅ | 6.2 | 0.4478 | 104.61 | +| YOLOv8n | TorchScript | ✅ | 12.4 | 0.4525 | 112.39 | +| YOLOv8n | ONNX | ✅ | 12.2 | 0.4525 | 28.02 | +| YOLOv8n | OpenVINO | ✅ | 12.3 | 0.4504 | 23.53 | +| YOLOv8s | PyTorch | ✅ | 21.5 | 0.5885 | 194.83 | +| YOLOv8s | TorchScript | ✅ | 43.0 | 0.5962 | 202.01 | +| YOLOv8s | ONNX | ✅ | 42.8 | 0.5962 | 65.74 | +| YOLOv8s | OpenVINO | ✅ | 42.9 | 0.5966 | 38.66 | +| YOLOv8m | PyTorch | ✅ | 49.7 | 0.6101 | 355.23 | +| YOLOv8m | TorchScript | ✅ | 99.2 | 0.6120 | 424.78 | +| YOLOv8m | ONNX | ✅ | 99.0 | 0.6120 | 173.39 | +| YOLOv8m | OpenVINO | ✅ | 99.1 | 0.6091 | 69.80 | +| YOLOv8l | PyTorch | ✅ | 83.7 | 0.6591 | 593.00 | +| YOLOv8l | TorchScript | ✅ | 167.2 | 0.6580 | 697.54 | +| YOLOv8l | ONNX | ✅ | 166.8 | 0.6580 | 342.15 | +| YOLOv8l | OpenVINO | ✅ | 167.0 | 0.0708 | 117.69 | +| YOLOv8x | PyTorch | ✅ | 130.5 | 0.6651 | 804.65 | +| YOLOv8x | TorchScript | ✅ | 260.8 | 0.6650 | 921.46 | +| YOLOv8x | ONNX | ✅ | 260.4 | 0.6650 | 526.66 | +| YOLOv8x | OpenVINO | ✅ | 260.6 | 0.6619 | 158.73 | + +## Reproduce Our Results + +To reproduce the Ultralytics benchmarks above on all export [formats](../modes/export.md) run this code: + +!!! example "" + + === "Python" + + ```python + from ultralytics import YOLO + + # Load a YOLOv8n PyTorch model + model = YOLO('yolov8n.pt') + + # Benchmark YOLOv8n speed and accuracy on the COCO128 dataset for all all export formats + results= model.benchmarks(data='coco128.yaml') + ``` + === "CLI" + + ```bash + # Benchmark YOLOv8n speed and accuracy on the COCO128 dataset for all all export formats + yolo benchmark model=yolov8n.pt data=coco128.yaml + ``` + + Note that benchmarking results might vary based on the exact hardware and software configuration of a system, as well as the current workload of the system at the time the benchmarks are run. For the most reliable results use a dataset with a large number of images, i.e. `data='coco128.yaml' (128 val images), or `data='coco.yaml'` (5000 val images). + +## Conclusion + +The benchmarking results clearly demonstrate the benefits of exporting the YOLOv8 model to the OpenVINO format. Across different models and hardware platforms, the OpenVINO format consistently outperforms other formats in terms of inference speed while maintaining comparable accuracy. + +For the Intel® Data Center GPU Flex Series, the OpenVINO format was able to deliver inference speeds almost 10 times faster than the original PyTorch format. On the Xeon CPU, the OpenVINO format was twice as fast as the PyTorch format. The accuracy of the models remained nearly identical across the different formats. + +The benchmarks underline the effectiveness of OpenVINO as a tool for deploying deep learning models. By converting models to the OpenVINO format, developers can achieve significant performance improvements, making it easier to deploy these models in real-world applications. + +For more detailed information and instructions on using OpenVINO, refer to the [official OpenVINO documentation](https://docs.openvinotoolkit.org/latest/index.html). diff --git a/downloads/ultralytics-main/docs/integrations/ray-tune.md b/downloads/ultralytics-main/docs/integrations/ray-tune.md new file mode 100644 index 000000000..06f7db902 --- /dev/null +++ b/downloads/ultralytics-main/docs/integrations/ray-tune.md @@ -0,0 +1,174 @@ +--- +comments: true +description: Discover how to streamline hyperparameter tuning for YOLOv8 models with Ray Tune. Learn to accelerate tuning, integrate with Weights & Biases, and analyze results. +keywords: Ultralytics, YOLOv8, Ray Tune, hyperparameter tuning, machine learning optimization, Weights & Biases integration, result analysis +--- + +# Efficient Hyperparameter Tuning with Ray Tune and YOLOv8 + +Hyperparameter tuning is vital in achieving peak model performance by discovering the optimal set of hyperparameters. This involves running trials with different hyperparameters and evaluating each trial’s performance. + +## Accelerate Tuning with Ultralytics YOLOv8 and Ray Tune + +[Ultralytics YOLOv8](https://ultralytics.com) incorporates Ray Tune for hyperparameter tuning, streamlining the optimization of YOLOv8 model hyperparameters. With Ray Tune, you can utilize advanced search strategies, parallelism, and early stopping to expedite the tuning process. + +### Ray Tune + +

+ Ray Tune Overview +

+ +[Ray Tune](https://docs.ray.io/en/latest/tune/index.html) is a hyperparameter tuning library designed for efficiency and flexibility. It supports various search strategies, parallelism, and early stopping strategies, and seamlessly integrates with popular machine learning frameworks, including Ultralytics YOLOv8. + +### Integration with Weights & Biases + +YOLOv8 also allows optional integration with [Weights & Biases](https://wandb.ai/site) for monitoring the tuning process. + +## Installation + +To install the required packages, run: + +!!! tip "Installation" + + ```bash + # Install and update Ultralytics and Ray Tune packages + pip install -U ultralytics "ray[tune]" + + # Optionally install W&B for logging + pip install wandb + ``` + +## Usage + +!!! example "Usage" + + ```python + from ultralytics import YOLO + + # Load a YOLOv8n model + model = YOLO("yolov8n.pt") + + # Start tuning hyperparameters for YOLOv8n training on the COCO128 dataset + result_grid = model.tune(data="coco128.yaml") + ``` + +## `tune()` Method Parameters + +The `tune()` method in YOLOv8 provides an easy-to-use interface for hyperparameter tuning with Ray Tune. It accepts several arguments that allow you to customize the tuning process. Below is a detailed explanation of each parameter: + +| Parameter | Type | Description | Default Value | +|-----------------|------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------| +| `data` | `str` | The dataset configuration file (in YAML format) to run the tuner on. This file should specify the training and validation data paths, as well as other dataset-specific settings. | | +| `space` | `dict, optional` | A dictionary defining the hyperparameter search space for Ray Tune. Each key corresponds to a hyperparameter name, and the value specifies the range of values to explore during tuning. If not provided, YOLOv8 uses a default search space with various hyperparameters. | | +| `grace_period` | `int, optional` | The grace period in epochs for the [ASHA scheduler](https://docs.ray.io/en/latest/tune/api/schedulers.html) in Ray Tune. The scheduler will not terminate any trial before this number of epochs, allowing the model to have some minimum training before making a decision on early stopping. | 10 | +| `gpu_per_trial` | `int, optional` | The number of GPUs to allocate per trial during tuning. This helps manage GPU usage, particularly in multi-GPU environments. If not provided, the tuner will use all available GPUs. | None | +| `max_samples` | `int, optional` | The maximum number of trials to run during tuning. This parameter helps control the total number of hyperparameter combinations tested, ensuring the tuning process does not run indefinitely. | 10 | +| `**train_args` | `dict, optional` | Additional arguments to pass to the `train()` method during tuning. These arguments can include settings like the number of training epochs, batch size, and other training-specific configurations. | {} | + +By customizing these parameters, you can fine-tune the hyperparameter optimization process to suit your specific needs and available computational resources. + +## Default Search Space Description + +The following table lists the default search space parameters for hyperparameter tuning in YOLOv8 with Ray Tune. Each parameter has a specific value range defined by `tune.uniform()`. + +| Parameter | Value Range | Description | +|-------------------|----------------------------|------------------------------------------| +| `lr0` | `tune.uniform(1e-5, 1e-1)` | Initial learning rate | +| `lrf` | `tune.uniform(0.01, 1.0)` | Final learning rate factor | +| `momentum` | `tune.uniform(0.6, 0.98)` | Momentum | +| `weight_decay` | `tune.uniform(0.0, 0.001)` | Weight decay | +| `warmup_epochs` | `tune.uniform(0.0, 5.0)` | Warmup epochs | +| `warmup_momentum` | `tune.uniform(0.0, 0.95)` | Warmup momentum | +| `box` | `tune.uniform(0.02, 0.2)` | Box loss weight | +| `cls` | `tune.uniform(0.2, 4.0)` | Class loss weight | +| `hsv_h` | `tune.uniform(0.0, 0.1)` | Hue augmentation range | +| `hsv_s` | `tune.uniform(0.0, 0.9)` | Saturation augmentation range | +| `hsv_v` | `tune.uniform(0.0, 0.9)` | Value (brightness) augmentation range | +| `degrees` | `tune.uniform(0.0, 45.0)` | Rotation augmentation range (degrees) | +| `translate` | `tune.uniform(0.0, 0.9)` | Translation augmentation range | +| `scale` | `tune.uniform(0.0, 0.9)` | Scaling augmentation range | +| `shear` | `tune.uniform(0.0, 10.0)` | Shear augmentation range (degrees) | +| `perspective` | `tune.uniform(0.0, 0.001)` | Perspective augmentation range | +| `flipud` | `tune.uniform(0.0, 1.0)` | Vertical flip augmentation probability | +| `fliplr` | `tune.uniform(0.0, 1.0)` | Horizontal flip augmentation probability | +| `mosaic` | `tune.uniform(0.0, 1.0)` | Mosaic augmentation probability | +| `mixup` | `tune.uniform(0.0, 1.0)` | Mixup augmentation probability | +| `copy_paste` | `tune.uniform(0.0, 1.0)` | Copy-paste augmentation probability | + +## Custom Search Space Example + +In this example, we demonstrate how to use a custom search space for hyperparameter tuning with Ray Tune and YOLOv8. By providing a custom search space, you can focus the tuning process on specific hyperparameters of interest. + +!!! example "Usage" + + ```python + from ultralytics import YOLO + + # Define a YOLO model + model = YOLO("yolov8n.pt") + + # Run Ray Tune on the model + result_grid = model.tune(data="coco128.yaml", + space={"lr0": tune.uniform(1e-5, 1e-1)}, + epochs=50) + ``` + +In the code snippet above, we create a YOLO model with the "yolov8n.pt" pretrained weights. Then, we call the `tune()` method, specifying the dataset configuration with "coco128.yaml". We provide a custom search space for the initial learning rate `lr0` using a dictionary with the key "lr0" and the value `tune.uniform(1e-5, 1e-1)`. Finally, we pass additional training arguments, such as the number of epochs directly to the tune method as `epochs=50`. + +# Processing Ray Tune Results + +After running a hyperparameter tuning experiment with Ray Tune, you might want to perform various analyses on the obtained results. This guide will take you through common workflows for processing and analyzing these results. + +## Loading Tune Experiment Results from a Directory + +After running the tuning experiment with `tuner.fit()`, you can load the results from a directory. This is useful, especially if you're performing the analysis after the initial training script has exited. + +```python +experiment_path = f"{storage_path}/{exp_name}" +print(f"Loading results from {experiment_path}...") + +restored_tuner = tune.Tuner.restore(experiment_path, trainable=train_mnist) +result_grid = restored_tuner.get_results() +``` + +## Basic Experiment-Level Analysis + +Get an overview of how trials performed. You can quickly check if there were any errors during the trials. + +```python +if result_grid.errors: + print("One or more trials failed!") +else: + print("No errors!") +``` + +## Basic Trial-Level Analysis + +Access individual trial hyperparameter configurations and the last reported metrics. + +```python +for i, result in enumerate(result_grid): + print(f"Trial #{i}: Configuration: {result.config}, Last Reported Metrics: {result.metrics}") +``` + +## Plotting the Entire History of Reported Metrics for a Trial + +You can plot the history of reported metrics for each trial to see how the metrics evolved over time. + +```python +import matplotlib.pyplot as plt + +for result in result_grid: + plt.plot(result.metrics_dataframe["training_iteration"], result.metrics_dataframe["mean_accuracy"], label=f"Trial {i}") + +plt.xlabel('Training Iterations') +plt.ylabel('Mean Accuracy') +plt.legend() +plt.show() +``` + +## Summary + +In this documentation, we covered common workflows to analyze the results of experiments run with Ray Tune using Ultralytics. The key steps include loading the experiment results from a directory, performing basic experiment-level and trial-level analysis and plotting metrics. + +Explore further by looking into Ray Tune’s [Analyze Results](https://docs.ray.io/en/latest/tune/examples/tune_analyze_results.html) docs page to get the most out of your hyperparameter tuning experiments. diff --git a/downloads/ultralytics-main/docs/models/fast-sam.md b/downloads/ultralytics-main/docs/models/fast-sam.md new file mode 100644 index 000000000..d41ca4797 --- /dev/null +++ b/downloads/ultralytics-main/docs/models/fast-sam.md @@ -0,0 +1,186 @@ +--- +comments: true +description: Explore FastSAM, a CNN-based solution for real-time object segmentation in images. Enhanced user interaction, computational efficiency and adaptable across vision tasks. +keywords: FastSAM, machine learning, CNN-based solution, object segmentation, real-time solution, Ultralytics, vision tasks, image processing, industrial applications, user interaction +--- + +# Fast Segment Anything Model (FastSAM) + +The Fast Segment Anything Model (FastSAM) is a novel, real-time CNN-based solution for the Segment Anything task. This task is designed to segment any object within an image based on various possible user interaction prompts. FastSAM significantly reduces computational demands while maintaining competitive performance, making it a practical choice for a variety of vision tasks. + +![Fast Segment Anything Model (FastSAM) architecture overview](https://user-images.githubusercontent.com/26833433/248551984-d98f0f6d-7535-45d0-b380-2e1440b52ad7.jpg) + +## Overview + +FastSAM is designed to address the limitations of the [Segment Anything Model (SAM)](sam.md), a heavy Transformer model with substantial computational resource requirements. The FastSAM decouples the segment anything task into two sequential stages: all-instance segmentation and prompt-guided selection. The first stage uses [YOLOv8-seg](../tasks/segment.md) to produce the segmentation masks of all instances in the image. In the second stage, it outputs the region-of-interest corresponding to the prompt. + +## Key Features + +1. **Real-time Solution:** By leveraging the computational efficiency of CNNs, FastSAM provides a real-time solution for the segment anything task, making it valuable for industrial applications that require quick results. + +2. **Efficiency and Performance:** FastSAM offers a significant reduction in computational and resource demands without compromising on performance quality. It achieves comparable performance to SAM but with drastically reduced computational resources, enabling real-time application. + +3. **Prompt-guided Segmentation:** FastSAM can segment any object within an image guided by various possible user interaction prompts, providing flexibility and adaptability in different scenarios. + +4. **Based on YOLOv8-seg:** FastSAM is based on [YOLOv8-seg](../tasks/segment.md), an object detector equipped with an instance segmentation branch. This allows it to effectively produce the segmentation masks of all instances in an image. + +5. **Competitive Results on Benchmarks:** On the object proposal task on MS COCO, FastSAM achieves high scores at a significantly faster speed than [SAM](sam.md) on a single NVIDIA RTX 3090, demonstrating its efficiency and capability. + +6. **Practical Applications:** The proposed approach provides a new, practical solution for a large number of vision tasks at a really high speed, tens or hundreds of times faster than current methods. + +7. **Model Compression Feasibility:** FastSAM demonstrates the feasibility of a path that can significantly reduce the computational effort by introducing an artificial prior to the structure, thus opening new possibilities for large model architecture for general vision tasks. + +## Usage + +### Python API + +The FastSAM models are easy to integrate into your Python applications. Ultralytics provides a user-friendly Python API to streamline the process. + +#### Predict Usage + +To perform object detection on an image, use the `predict` method as shown below: + +!!! example "" + + === "Python" + ```python + from ultralytics import FastSAM + from ultralytics.models.fastsam import FastSAMPrompt + + # Define an inference source + source = 'path/to/bus.jpg' + + # Create a FastSAM model + model = FastSAM('FastSAM-s.pt') # or FastSAM-x.pt + + # Run inference on an image + everything_results = model(source, device='cpu', retina_masks=True, imgsz=1024, conf=0.4, iou=0.9) + + # Prepare a Prompt Process object + prompt_process = FastSAMPrompt(source, everything_results, device='cpu') + + # Everything prompt + ann = prompt_process.everything_prompt() + + # Bbox default shape [0,0,0,0] -> [x1,y1,x2,y2] + ann = prompt_process.box_prompt(bbox=[200, 200, 300, 300]) + + # Text prompt + ann = prompt_process.text_prompt(text='a photo of a dog') + + # Point prompt + # points default [[0,0]] [[x1,y1],[x2,y2]] + # point_label default [0] [1,0] 0:background, 1:foreground + ann = prompt_process.point_prompt(points=[[200, 200]], pointlabel=[1]) + prompt_process.plot(annotations=ann, output='./') + ``` + + === "CLI" + ```bash + # Load a FastSAM model and segment everything with it + yolo segment predict model=FastSAM-s.pt source=path/to/bus.jpg imgsz=640 + ``` + +This snippet demonstrates the simplicity of loading a pre-trained model and running a prediction on an image. + +#### Val Usage + +Validation of the model on a dataset can be done as follows: + +!!! example "" + + === "Python" + ```python + from ultralytics import FastSAM + + # Create a FastSAM model + model = FastSAM('FastSAM-s.pt') # or FastSAM-x.pt + + # Validate the model + results = model.val(data='coco8-seg.yaml') + ``` + + === "CLI" + ```bash + # Load a FastSAM model and validate it on the COCO8 example dataset at image size 640 + yolo segment val model=FastSAM-s.pt data=coco8.yaml imgsz=640 + ``` + +Please note that FastSAM only supports detection and segmentation of a single class of object. This means it will recognize and segment all objects as the same class. Therefore, when preparing the dataset, you need to convert all object category IDs to 0. + +### FastSAM official Usage + +FastSAM is also available directly from the [https://github.com/CASIA-IVA-Lab/FastSAM](https://github.com/CASIA-IVA-Lab/FastSAM) repository. Here is a brief overview of the typical steps you might take to use FastSAM: + +#### Installation + +1. Clone the FastSAM repository: + ```shell + git clone https://github.com/CASIA-IVA-Lab/FastSAM.git + ``` + +2. Create and activate a Conda environment with Python 3.9: + ```shell + conda create -n FastSAM python=3.9 + conda activate FastSAM + ``` + +3. Navigate to the cloned repository and install the required packages: + ```shell + cd FastSAM + pip install -r requirements.txt + ``` + +4. Install the CLIP model: + ```shell + pip install git+https://github.com/openai/CLIP.git + ``` + +#### Example Usage + +1. Download a [model checkpoint](https://drive.google.com/file/d/1m1sjY4ihXBU1fZXdQ-Xdj-mDltW-2Rqv/view?usp=sharing). + +2. Use FastSAM for inference. Example commands: + + - Segment everything in an image: + ```shell + python Inference.py --model_path ./weights/FastSAM.pt --img_path ./images/dogs.jpg + ``` + + - Segment specific objects using text prompt: + ```shell + python Inference.py --model_path ./weights/FastSAM.pt --img_path ./images/dogs.jpg --text_prompt "the yellow dog" + ``` + + - Segment objects within a bounding box (provide box coordinates in xywh format): + ```shell + python Inference.py --model_path ./weights/FastSAM.pt --img_path ./images/dogs.jpg --box_prompt "[570,200,230,400]" + ``` + + - Segment objects near specific points: + ```shell + python Inference.py --model_path ./weights/FastSAM.pt --img_path ./images/dogs.jpg --point_prompt "[[520,360],[620,300]]" --point_label "[1,0]" + ``` + +Additionally, you can try FastSAM through a [Colab demo](https://colab.research.google.com/drive/1oX14f6IneGGw612WgVlAiy91UHwFAvr9?usp=sharing) or on the [HuggingFace web demo](https://huggingface.co/spaces/An-619/FastSAM) for a visual experience. + +## Citations and Acknowledgements + +We would like to acknowledge the FastSAM authors for their significant contributions in the field of real-time instance segmentation: + +!!! note "" + + === "BibTeX" + + ```bibtex + @misc{zhao2023fast, + title={Fast Segment Anything}, + author={Xu Zhao and Wenchao Ding and Yongqi An and Yinglong Du and Tao Yu and Min Li and Ming Tang and Jinqiao Wang}, + year={2023}, + eprint={2306.12156}, + archivePrefix={arXiv}, + primaryClass={cs.CV} + } + ``` + +The original FastSAM paper can be found on [arXiv](https://arxiv.org/abs/2306.12156). The authors have made their work publicly available, and the codebase can be accessed on [GitHub](https://github.com/CASIA-IVA-Lab/FastSAM). We appreciate their efforts in advancing the field and making their work accessible to the broader community. diff --git a/downloads/ultralytics-main/docs/models/index.md b/downloads/ultralytics-main/docs/models/index.md index e579b3972..afd8e871d 100644 --- a/downloads/ultralytics-main/docs/models/index.md +++ b/downloads/ultralytics-main/docs/models/index.md @@ -1,6 +1,7 @@ --- comments: true -description: Learn about the supported models and architectures, such as YOLOv3, YOLOv5, and YOLOv8, and how to contribute your own model to Ultralytics. +description: Learn about the YOLO family, SAM, MobileSAM, FastSAM, YOLO-NAS, and RT-DETR models supported by Ultralytics, with examples on how to use them via CLI and Python. +keywords: Ultralytics, documentation, YOLO, SAM, MobileSAM, FastSAM, YOLO-NAS, RT-DETR, models, architectures, Python, CLI --- # Models @@ -9,29 +10,56 @@ Ultralytics supports many models and architectures with more to come in the futu In this documentation, we provide information on four major models: -1. [YOLOv3](./yolov3.md): The third iteration of the YOLO model family, known for its efficient real-time object detection capabilities. -2. [YOLOv5](./yolov5.md): An improved version of the YOLO architecture, offering better performance and speed tradeoffs compared to previous versions. -3. [YOLOv8](./yolov8.md): The latest version of the YOLO family, featuring enhanced capabilities such as instance segmentation, pose/keypoints estimation, and classification. -4. [Segment Anything Model (SAM)](./sam.md): Meta's Segment Anything Model (SAM). -5. [Realtime Detection Transformers (RT-DETR)](./rtdetr.md): Baidu's RT-DETR model. +1. [YOLOv3](./yolov3.md): The third iteration of the YOLO model family originally by Joseph Redmon, known for its efficient real-time object detection capabilities. +2. [YOLOv4](./yolov3.md): A darknet-native update to YOLOv3 released by Alexey Bochkovskiy in 2020. +3. [YOLOv5](./yolov5.md): An improved version of the YOLO architecture by Ultralytics, offering better performance and speed tradeoffs compared to previous versions. +4. [YOLOv6](./yolov6.md): Released by [Meituan](https://about.meituan.com/) in 2022 and is in use in many of the company's autonomous delivery robots. +5. [YOLOv7](./yolov7.md): Updated YOLO models released in 2022 by the authors of YOLOv4. +6. [YOLOv8](./yolov8.md): The latest version of the YOLO family, featuring enhanced capabilities such as instance segmentation, pose/keypoints estimation, and classification. +7. [Segment Anything Model (SAM)](./sam.md): Meta's Segment Anything Model (SAM). +8. [Mobile Segment Anything Model (MobileSAM)](./mobile-sam.md): MobileSAM for mobile applications by Kyung Hee University. +9. [Fast Segment Anything Model (FastSAM)](./fast-sam.md): FastSAM by Image & Video Analysis Group, Institute of Automation, Chinese Academy of Sciences. +10. [YOLO-NAS](./yolo-nas.md): YOLO Neural Architecture Search (NAS) Models. +11. [Realtime Detection Transformers (RT-DETR)](./rtdetr.md): Baidu's PaddlePaddle Realtime Detection Transformer (RT-DETR) models. -You can use these models directly in the Command Line Interface (CLI) or in a Python environment. Below are examples of how to use the models with CLI and Python: +You can use many of these models directly in the Command Line Interface (CLI) or in a Python environment. Below are examples of how to use the models with CLI and Python: -## CLI Example +## Usage -```bash -yolo task=detect mode=train model=yolov8n.yaml data=coco128.yaml epochs=100 -``` +This example provides simple inference code for YOLO, SAM and RTDETR models. For more options including handling inference results see [Predict](../modes/predict.md) mode. For using models with additional modes see [Train](../modes/train.md), [Val](../modes/val.md) and [Export](../modes/export.md). -## Python Example +!!! example "" -```python -from ultralytics import YOLO + === "Python" -model = YOLO("model.yaml") # build a YOLOv8n model from scratch -# YOLO("model.pt") use pre-trained model if available -model.info() # display model information -model.train(data="coco128.yaml", epochs=100) # train the model -``` + PyTorch pretrained `*.pt` models as well as configuration `*.yaml` files can be passed to the `YOLO()`, `SAM()`, `NAS()` and `RTDETR()` classes to create a model instance in python: -For more details on each model, their supported tasks, modes, and performance, please visit their respective documentation pages linked above. \ No newline at end of file + ```python + from ultralytics import YOLO + + # Load a COCO-pretrained YOLOv8n model + model = YOLO('yolov8n.pt') + + # Display model information (optional) + model.info() + + # Train the model on the COCO8 example dataset for 100 epochs + results = model.train(data='coco8.yaml', epochs=100, imgsz=640) + + # Run inference with the YOLOv8n model on the 'bus.jpg' image + results = model('path/to/bus.jpg') + ``` + + === "CLI" + + CLI commands are available to directly run the models: + + ```bash + # Load a COCO-pretrained YOLOv8n model and train it on the COCO8 example dataset for 100 epochs + yolo train model=yolov8n.pt data=coco8.yaml epochs=100 imgsz=640 + + # Load a COCO-pretrained YOLOv8n model and run inference on the 'bus.jpg' image + yolo predict model=yolov8n.pt source=path/to/bus.jpg + ``` + +For more details on each model, their supported tasks, modes, and performance, please visit their respective documentation pages linked above. diff --git a/downloads/ultralytics-main/docs/models/mobile-sam.md b/downloads/ultralytics-main/docs/models/mobile-sam.md new file mode 100644 index 000000000..e224046db --- /dev/null +++ b/downloads/ultralytics-main/docs/models/mobile-sam.md @@ -0,0 +1,109 @@ +--- +comments: true +description: Learn more about MobileSAM, its implementation, comparison with the original SAM, and how to download and test it in the Ultralytics framework. Improve your mobile applications today. +keywords: MobileSAM, Ultralytics, SAM, mobile applications, Arxiv, GPU, API, image encoder, mask decoder, model download, testing method +--- + +![MobileSAM Logo](https://github.com/ChaoningZhang/MobileSAM/blob/master/assets/logo2.png?raw=true) + +# Mobile Segment Anything (MobileSAM) + +The MobileSAM paper is now available on [arXiv](https://arxiv.org/pdf/2306.14289.pdf). + +A demonstration of MobileSAM running on a CPU can be accessed at this [demo link](https://huggingface.co/spaces/dhkim2810/MobileSAM). The performance on a Mac i5 CPU takes approximately 3 seconds. On the Hugging Face demo, the interface and lower-performance CPUs contribute to a slower response, but it continues to function effectively. + +MobileSAM is implemented in various projects including [Grounding-SAM](https://github.com/IDEA-Research/Grounded-Segment-Anything), [AnyLabeling](https://github.com/vietanhdev/anylabeling), and [Segment Anything in 3D](https://github.com/Jumpat/SegmentAnythingin3D). + +MobileSAM is trained on a single GPU with a 100k dataset (1% of the original images) in less than a day. The code for this training will be made available in the future. + +## Adapting from SAM to MobileSAM + +Since MobileSAM retains the same pipeline as the original SAM, we have incorporated the original's pre-processing, post-processing, and all other interfaces. Consequently, those currently using the original SAM can transition to MobileSAM with minimal effort. + +MobileSAM performs comparably to the original SAM and retains the same pipeline except for a change in the image encoder. Specifically, we replace the original heavyweight ViT-H encoder (632M) with a smaller Tiny-ViT (5M). On a single GPU, MobileSAM operates at about 12ms per image: 8ms on the image encoder and 4ms on the mask decoder. + +The following table provides a comparison of ViT-based image encoders: + +| Image Encoder | Original SAM | MobileSAM | +|---------------|--------------|-----------| +| Parameters | 611M | 5M | +| Speed | 452ms | 8ms | + +Both the original SAM and MobileSAM utilize the same prompt-guided mask decoder: + +| Mask Decoder | Original SAM | MobileSAM | +|--------------|--------------|-----------| +| Parameters | 3.876M | 3.876M | +| Speed | 4ms | 4ms | + +Here is the comparison of the whole pipeline: + +| Whole Pipeline (Enc+Dec) | Original SAM | MobileSAM | +|--------------------------|--------------|-----------| +| Parameters | 615M | 9.66M | +| Speed | 456ms | 12ms | + +The performance of MobileSAM and the original SAM are demonstrated using both a point and a box as prompts. + +![Image with Point as Prompt](https://raw.githubusercontent.com/ChaoningZhang/MobileSAM/master/assets/mask_box.jpg?raw=true) + +![Image with Box as Prompt](https://raw.githubusercontent.com/ChaoningZhang/MobileSAM/master/assets/mask_box.jpg?raw=true) + +With its superior performance, MobileSAM is approximately 5 times smaller and 7 times faster than the current FastSAM. More details are available at the [MobileSAM project page](https://github.com/ChaoningZhang/MobileSAM). + +## Testing MobileSAM in Ultralytics + +Just like the original SAM, we offer a straightforward testing method in Ultralytics, including modes for both Point and Box prompts. + +### Model Download + +You can download the model [here](https://github.com/ChaoningZhang/MobileSAM/blob/master/weights/mobile_sam.pt). + +### Point Prompt + +!!! example "" + + === "Python" + ```python + from ultralytics import SAM + + # Load the model + model = SAM('mobile_sam.pt') + + # Predict a segment based on a point prompt + model.predict('ultralytics/assets/zidane.jpg', points=[900, 370], labels=[1]) + ``` + +### Box Prompt + +!!! example "" + + === "Python" + ```python + from ultralytics import SAM + + # Load the model + model = SAM('mobile_sam.pt') + + # Predict a segment based on a box prompt + model.predict('ultralytics/assets/zidane.jpg', bboxes=[439, 437, 524, 709]) + ``` + +We have implemented `MobileSAM` and `SAM` using the same API. For more usage information, please see the [SAM page](./sam.md). + +## Citations and Acknowledgements + +If you find MobileSAM useful in your research or development work, please consider citing our paper: + +!!! note "" + + === "BibTeX" + + ```bibtex + @article{mobile_sam, + title={Faster Segment Anything: Towards Lightweight SAM for Mobile Applications}, + author={Zhang, Chaoning and Han, Dongshen and Qiao, Yu and Kim, Jung Uk and Bae, Sung Ho and Lee, Seungkyu and Hong, Choong Seon}, + journal={arXiv preprint arXiv:2306.14289}, + year={2023} + } + ``` diff --git a/downloads/ultralytics-main/docs/models/rtdetr.md b/downloads/ultralytics-main/docs/models/rtdetr.md index aa1ea63ca..608e7aa6b 100644 --- a/downloads/ultralytics-main/docs/models/rtdetr.md +++ b/downloads/ultralytics-main/docs/models/rtdetr.md @@ -1,44 +1,66 @@ --- comments: true -description: Explore RT-DETR, a high-performance real-time object detector. Learn how to use pre-trained models with Ultralytics Python API for various tasks. +description: Discover the features and benefits of RT-DETR, Baidu’s efficient and adaptable real-time object detector powered by Vision Transformers, including pre-trained models. +keywords: RT-DETR, Baidu, Vision Transformers, object detection, real-time performance, CUDA, TensorRT, IoU-aware query selection, Ultralytics, Python API, PaddlePaddle --- -# RT-DETR +# Baidu's RT-DETR: A Vision Transformer-Based Real-Time Object Detector ## Overview -Real-Time Detection Transformer (RT-DETR) is an end-to-end object detector that provides real-time performance while maintaining high accuracy. It efficiently processes multi-scale features by decoupling intra-scale interaction and cross-scale fusion, and supports flexible adjustment of inference speed using different decoder layers without retraining. RT-DETR outperforms many real-time object detectors on accelerated backends like CUDA with TensorRT. +Real-Time Detection Transformer (RT-DETR), developed by Baidu, is a cutting-edge end-to-end object detector that provides real-time performance while maintaining high accuracy. It leverages the power of Vision Transformers (ViT) to efficiently process multiscale features by decoupling intra-scale interaction and cross-scale fusion. RT-DETR is highly adaptable, supporting flexible adjustment of inference speed using different decoder layers without retraining. The model excels on accelerated backends like CUDA with TensorRT, outperforming many other real-time object detectors. ![Model example image](https://user-images.githubusercontent.com/26833433/238963168-90e8483f-90aa-4eb6-a5e1-0d408b23dd33.png) -**Overview of RT-DETR.** Model architecture diagram showing the last three stages of the backbone {S3, S4, S5} as the input -to the encoder. The efficient hybrid encoder transforms multiscale features into a sequence of image features through intrascale feature interaction (AIFI) and cross-scale feature-fusion module (CCFM). The IoU-aware query selection is employed -to select a fixed number of image features to serve as initial object queries for the decoder. Finally, the decoder with auxiliary -prediction heads iteratively optimizes object queries to generate boxes and confidence scores ([source](https://arxiv.org/pdf/2304.08069.pdf)). +**Overview of Baidu's RT-DETR.** The RT-DETR model architecture diagram shows the last three stages of the backbone {S3, S4, S5} as the input to the encoder. The efficient hybrid encoder transforms multiscale features into a sequence of image features through intrascale feature interaction (AIFI) and cross-scale feature-fusion module (CCFM). The IoU-aware query selection is employed to select a fixed number of image features to serve as initial object queries for the decoder. Finally, the decoder with auxiliary prediction heads iteratively optimizes object queries to generate boxes and confidence scores ([source](https://arxiv.org/pdf/2304.08069.pdf)). ### Key Features -- **Efficient Hybrid Encoder:** RT-DETR uses an efficient hybrid encoder that processes multi-scale features by decoupling intra-scale interaction and cross-scale fusion. This design reduces computational costs and allows for real-time object detection. -- **IoU-aware Query Selection:** RT-DETR improves object query initialization by utilizing IoU-aware query selection. This allows the model to focus on the most relevant objects in the scene. -- **Adaptable Inference Speed:** RT-DETR supports flexible adjustments of inference speed by using different decoder layers without the need for retraining. This adaptability facilitates practical application in various real-time object detection scenarios. +- **Efficient Hybrid Encoder:** Baidu's RT-DETR uses an efficient hybrid encoder that processes multiscale features by decoupling intra-scale interaction and cross-scale fusion. This unique Vision Transformers-based design reduces computational costs and allows for real-time object detection. +- **IoU-aware Query Selection:** Baidu's RT-DETR improves object query initialization by utilizing IoU-aware query selection. This allows the model to focus on the most relevant objects in the scene, enhancing the detection accuracy. +- **Adaptable Inference Speed:** Baidu's RT-DETR supports flexible adjustments of inference speed by using different decoder layers without the need for retraining. This adaptability facilitates practical application in various real-time object detection scenarios. ## Pre-trained Models -Ultralytics RT-DETR provides several pre-trained models with different scales: +The Ultralytics Python API provides pre-trained PaddlePaddle RT-DETR models with different scales: - RT-DETR-L: 53.0% AP on COCO val2017, 114 FPS on T4 GPU - RT-DETR-X: 54.8% AP on COCO val2017, 74 FPS on T4 GPU ## Usage -### Python API +You can use RT-DETR for object detection tasks using the `ultralytics` pip package. The following is a sample code snippet showing how to use RT-DETR models for training and inference: -```python -from ultralytics import RTDETR +!!! example "" -model = RTDETR("rtdetr-l.pt") -model.info() # display model information -model.predict("path/to/image.jpg") # predict -``` + This example provides simple inference code for RT-DETR. For more options including handling inference results see [Predict](../modes/predict.md) mode. For using RT-DETR with additional modes see [Train](../modes/train.md), [Val](../modes/val.md) and [Export](../modes/export.md). + + === "Python" + + ```python + from ultralytics import RTDETR + + # Load a COCO-pretrained RT-DETR-l model + model = RTDETR('rtdetr-l.pt') + + # Display model information (optional) + model.info() + + # Train the model on the COCO8 example dataset for 100 epochs + results = model.train(data='coco8.yaml', epochs=100, imgsz=640) + + # Run inference with the RT-DETR-l model on the 'bus.jpg' image + results = model('path/to/bus.jpg') + ``` + + === "CLI" + + ```bash + # Load a COCO-pretrained RT-DETR-l model and train it on the COCO8 example dataset for 100 epochs + yolo train model=rtdetr-l.pt data=coco8.yaml epochs=100 imgsz=640 + + # Load a COCO-pretrained RT-DETR-l model and run inference on the 'bus.jpg' image + yolo predict model=rtdetr-l.pt source=path/to/bus.jpg + ``` ### Supported Tasks @@ -53,21 +75,27 @@ model.predict("path/to/image.jpg") # predict |------------|--------------------| | Inference | :heavy_check_mark: | | Validation | :heavy_check_mark: | -| Training | :x: (Coming soon) | +| Training | :heavy_check_mark: | -# Citations and Acknowledgements +## Citations and Acknowledgements -If you use RT-DETR in your research or development work, please cite the [original paper](https://arxiv.org/abs/2304.08069): +If you use Baidu's RT-DETR in your research or development work, please cite the [original paper](https://arxiv.org/abs/2304.08069): -```bibtex -@misc{lv2023detrs, - title={DETRs Beat YOLOs on Real-time Object Detection}, - author={Wenyu Lv and Shangliang Xu and Yian Zhao and Guanzhong Wang and Jinman Wei and Cheng Cui and Yuning Du and Qingqing Dang and Yi Liu}, - year={2023}, - eprint={2304.08069}, - archivePrefix={arXiv}, - primaryClass={cs.CV} -} -``` +!!! note "" -We would like to acknowledge Baidu's [PaddlePaddle](https://github.com/PaddlePaddle/PaddleDetection) team for creating and maintaining this valuable resource for the computer vision community. + === "BibTeX" + + ```bibtex + @misc{lv2023detrs, + title={DETRs Beat YOLOs on Real-time Object Detection}, + author={Wenyu Lv and Shangliang Xu and Yian Zhao and Guanzhong Wang and Jinman Wei and Cheng Cui and Yuning Du and Qingqing Dang and Yi Liu}, + year={2023}, + eprint={2304.08069}, + archivePrefix={arXiv}, + primaryClass={cs.CV} + } + ``` + +We would like to acknowledge Baidu and the [PaddlePaddle](https://github.com/PaddlePaddle/PaddleDetection) team for creating and maintaining this valuable resource for the computer vision community. Their contribution to the field with the development of the Vision Transformers-based real-time object detector, RT-DETR, is greatly appreciated. + +*Keywords: RT-DETR, Transformer, ViT, Vision Transformers, Baidu RT-DETR, PaddlePaddle, Paddle Paddle RT-DETR, real-time object detection, Vision Transformers-based object detection, pre-trained PaddlePaddle RT-DETR models, Baidu's RT-DETR usage, Ultralytics Python API* diff --git a/downloads/ultralytics-main/docs/models/sam.md b/downloads/ultralytics-main/docs/models/sam.md index 93079dcf5..d6ffd4d85 100644 --- a/downloads/ultralytics-main/docs/models/sam.md +++ b/downloads/ultralytics-main/docs/models/sam.md @@ -1,46 +1,135 @@ --- comments: true -description: Learn about the Segment Anything Model (SAM) and how it provides promptable image segmentation through an advanced architecture and the SA-1B dataset. +description: Explore the cutting-edge Segment Anything Model (SAM) from Ultralytics that allows real-time image segmentation. Learn about its promptable segmentation, zero-shot performance, and how to use it. +keywords: Ultralytics, image segmentation, Segment Anything Model, SAM, SA-1B dataset, real-time performance, zero-shot transfer, object detection, image analysis, machine learning --- # Segment Anything Model (SAM) -## Overview +Welcome to the frontier of image segmentation with the Segment Anything Model, or SAM. This revolutionary model has changed the game by introducing promptable image segmentation with real-time performance, setting new standards in the field. -The Segment Anything Model (SAM) is a groundbreaking image segmentation model that enables promptable segmentation with real-time performance. It forms the foundation for the Segment Anything project, which introduces a new task, model, and dataset for image segmentation. SAM is designed to be promptable, allowing it to transfer zero-shot to new image distributions and tasks. The model is trained on the [SA-1B dataset](https://ai.facebook.com/datasets/segment-anything/), which contains over 1 billion masks on 11 million licensed and privacy-respecting images. SAM has demonstrated impressive zero-shot performance, often surpassing prior fully supervised results. +## Introduction to SAM: The Segment Anything Model + +The Segment Anything Model, or SAM, is a cutting-edge image segmentation model that allows for promptable segmentation, providing unparalleled versatility in image analysis tasks. SAM forms the heart of the Segment Anything initiative, a groundbreaking project that introduces a novel model, task, and dataset for image segmentation. + +SAM's advanced design allows it to adapt to new image distributions and tasks without prior knowledge, a feature known as zero-shot transfer. Trained on the expansive [SA-1B dataset](https://ai.facebook.com/datasets/segment-anything/), which contains more than 1 billion masks spread over 11 million carefully curated images, SAM has displayed impressive zero-shot performance, surpassing previous fully supervised results in many cases. ![Dataset sample image](https://user-images.githubusercontent.com/26833433/238056229-0e8ffbeb-f81a-477e-a490-aff3d82fd8ce.jpg) Example images with overlaid masks from our newly introduced dataset, SA-1B. SA-1B contains 11M diverse, high-resolution, licensed, and privacy protecting images and 1.1B high-quality segmentation masks. These masks were annotated fully automatically by SAM, and as verified by human ratings and numerous experiments, are of high quality and diversity. Images are grouped by number of masks per image for visualization (there are ∼100 masks per image on average). -## Key Features +## Key Features of the Segment Anything Model (SAM) -- **Promptable Segmentation Task:** SAM is designed for a promptable segmentation task, enabling it to return a valid segmentation mask given any segmentation prompt, such as spatial or text information identifying an object. -- **Advanced Architecture:** SAM utilizes a powerful image encoder, a prompt encoder, and a lightweight mask decoder. This architecture enables flexible prompting, real-time mask computation, and ambiguity awareness in segmentation. -- **SA-1B Dataset:** The Segment Anything project introduces the SA-1B dataset, which contains over 1 billion masks on 11 million images. This dataset is the largest segmentation dataset to date, providing SAM with a diverse and large-scale source of data for training. -- **Zero-Shot Performance:** SAM demonstrates remarkable zero-shot performance across a range of segmentation tasks, allowing it to be used out-of-the-box with prompt engineering for various applications. +- **Promptable Segmentation Task:** SAM was designed with a promptable segmentation task in mind, allowing it to generate valid segmentation masks from any given prompt, such as spatial or text clues identifying an object. +- **Advanced Architecture:** The Segment Anything Model employs a powerful image encoder, a prompt encoder, and a lightweight mask decoder. This unique architecture enables flexible prompting, real-time mask computation, and ambiguity awareness in segmentation tasks. +- **The SA-1B Dataset:** Introduced by the Segment Anything project, the SA-1B dataset features over 1 billion masks on 11 million images. As the largest segmentation dataset to date, it provides SAM with a diverse and large-scale training data source. +- **Zero-Shot Performance:** SAM displays outstanding zero-shot performance across various segmentation tasks, making it a ready-to-use tool for diverse applications with minimal need for prompt engineering. -For more information about the Segment Anything Model and the SA-1B dataset, please refer to the [Segment Anything website](https://segment-anything.com) and the research paper [Segment Anything](https://arxiv.org/abs/2304.02643). +For an in-depth look at the Segment Anything Model and the SA-1B dataset, please visit the [Segment Anything website](https://segment-anything.com) and check out the research paper [Segment Anything](https://arxiv.org/abs/2304.02643). -## Usage +## How to Use SAM: Versatility and Power in Image Segmentation -SAM can be used for a variety of downstream tasks involving object and image distributions beyond its training data. Examples include edge detection, object proposal generation, instance segmentation, and preliminary text-to-mask prediction. By employing prompt engineering, SAM can adapt to new tasks and data distributions in a zero-shot manner, making it a versatile and powerful tool for image segmentation tasks. +The Segment Anything Model can be employed for a multitude of downstream tasks that go beyond its training data. This includes edge detection, object proposal generation, instance segmentation, and preliminary text-to-mask prediction. With prompt engineering, SAM can swiftly adapt to new tasks and data distributions in a zero-shot manner, establishing it as a versatile and potent tool for all your image segmentation needs. -```python -from ultralytics.vit import SAM +### SAM prediction example -model = SAM('sam_b.pt') -model.info() # display model information -model.predict('path/to/image.jpg') # predict -``` +!!! example "Segment with prompts" -## Supported Tasks + Segment image with given prompts. + + === "Python" + + ```python + from ultralytics import SAM + + # Load a model + model = SAM('sam_b.pt') + + # Display model information (optional) + model.info() + + # Run inference with bboxes prompt + model('ultralytics/assets/zidane.jpg', bboxes=[439, 437, 524, 709]) + + # Run inference with points prompt + model.predict('ultralytics/assets/zidane.jpg', points=[900, 370], labels=[1]) + ``` + +!!! example "Segment everything" + + Segment the whole image. + + === "Python" + + ```python + from ultralytics import SAM + + # Load a model + model = SAM('sam_b.pt') + + # Display model information (optional) + model.info() + + # Run inference + model('path/to/image.jpg') + ``` + + === "CLI" + + ```bash + # Run inference with a SAM model + yolo predict model=sam_b.pt source=path/to/image.jpg + ``` + +- The logic here is to segment the whole image if you don't pass any prompts(bboxes/points/masks). + +!!! example "SAMPredictor example" + + This way you can set image once and run prompts inference multiple times without running image encoder multiple times. + + === "Prompt inference" + + ```python + from ultralytics.models.sam import Predictor as SAMPredictor + + # Create SAMPredictor + overrides = dict(conf=0.25, task='segment', mode='predict', imgsz=1024, model="mobile_sam.pt") + predictor = SAMPredictor(overrides=overrides) + + # Set image + predictor.set_image("ultralytics/assets/zidane.jpg") # set with image file + predictor.set_image(cv2.imread("ultralytics/assets/zidane.jpg")) # set with np.ndarray + results = predictor(bboxes=[439, 437, 524, 709]) + results = predictor(points=[900, 370], labels=[1]) + + # Reset image + predictor.reset_image() + ``` + + Segment everything with additional args. + + === "Segment everything" + + ```python + from ultralytics.models.sam import Predictor as SAMPredictor + + # Create SAMPredictor + overrides = dict(conf=0.25, task='segment', mode='predict', imgsz=1024, model="mobile_sam.pt") + predictor = SAMPredictor(overrides=overrides) + + # Segment with additional args + results = predictor(source="ultralytics/assets/zidane.jpg", crop_n_layers=1, points_stride=64) + ``` + +- More additional args for `Segment everything` see [`Predictor/generate` Reference](../reference/models/sam/predict.md). + +## Available Models and Supported Tasks | Model Type | Pre-trained Weights | Tasks Supported | |------------|---------------------|-----------------------| -| sam base | `sam_b.pt` | Instance Segmentation | -| sam large | `sam_l.pt` | Instance Segmentation | +| SAM base | `sam_b.pt` | Instance Segmentation | +| SAM large | `sam_l.pt` | Instance Segmentation | -## Supported Modes +## Operating Modes | Mode | Supported | |------------|--------------------| @@ -48,19 +137,65 @@ model.predict('path/to/image.jpg') # predict | Validation | :x: | | Training | :x: | -## Auto-Annotation +## SAM comparison vs YOLOv8 -Auto-annotation is an essential feature that allows you to generate a [segmentation dataset](https://docs.ultralytics.com/datasets/segment) using a pre-trained detection model. It enables you to quickly and accurately annotate a large number of images without the need for manual labeling, saving time and effort. +Here we compare Meta's smallest SAM model, SAM-b, with Ultralytics smallest segmentation model, [YOLOv8n-seg](../tasks/segment.md): -### Generate Segmentation Dataset Using a Detection Model +| Model | Size | Parameters | Speed (CPU) | +|------------------------------------------------|----------------------------|------------------------|----------------------------| +| Meta's SAM-b | 358 MB | 94.7 M | 51096 ms/im | +| [MobileSAM](mobile-sam.md) | 40.7 MB | 10.1 M | 46122 ms/im | +| [FastSAM-s](fast-sam.md) with YOLOv8 backbone | 23.7 MB | 11.8 M | 115 ms/im | +| Ultralytics [YOLOv8n-seg](../tasks/segment.md) | **6.7 MB** (53.4x smaller) | **3.4 M** (27.9x less) | **59 ms/im** (866x faster) | -To auto-annotate your dataset using the Ultralytics framework, you can use the `auto_annotate` function as shown below: +This comparison shows the order-of-magnitude differences in the model sizes and speeds between models. Whereas SAM presents unique capabilities for automatic segmenting, it is not a direct competitor to YOLOv8 segment models, which are smaller, faster and more efficient. -```python -from ultralytics.yolo.data.annotator import auto_annotate +Tests run on a 2023 Apple M2 Macbook with 16GB of RAM. To reproduce this test: -auto_annotate(data="path/to/images", det_model="yolov8x.pt", sam_model='sam_b.pt') -``` + +!!! example "" + + === "Python" + ```python + from ultralytics import FastSAM, SAM, YOLO + + # Profile SAM-b + model = SAM('sam_b.pt') + model.info() + model('ultralytics/assets') + + # Profile MobileSAM + model = SAM('mobile_sam.pt') + model.info() + model('ultralytics/assets') + + # Profile FastSAM-s + model = FastSAM('FastSAM-s.pt') + model.info() + model('ultralytics/assets') + + # Profile YOLOv8n-seg + model = YOLO('yolov8n-seg.pt') + model.info() + model('ultralytics/assets') + ``` + +## Auto-Annotation: A Quick Path to Segmentation Datasets + +Auto-annotation is a key feature of SAM, allowing users to generate a [segmentation dataset](https://docs.ultralytics.com/datasets/segment) using a pre-trained detection model. This feature enables rapid and accurate annotation of a large number of images, bypassing the need for time-consuming manual labeling. + +### Generate Your Segmentation Dataset Using a Detection Model + +To auto-annotate your dataset with the Ultralytics framework, use the `auto_annotate` function as shown below: + +!!! example "" + + === "Python" + ```python + from ultralytics.data.annotator import auto_annotate + + auto_annotate(data="path/to/images", det_model="yolov8x.pt", sam_model='sam_b.pt') + ``` | Argument | Type | Description | Default | |------------|---------------------|---------------------------------------------------------------------------------------------------------|--------------| @@ -70,23 +205,29 @@ auto_annotate(data="path/to/images", det_model="yolov8x.pt", sam_model='sam_b.pt | device | str, optional | Device to run the models on. Defaults to an empty string (CPU or GPU, if available). | | | output_dir | str, None, optional | Directory to save the annotated results. Defaults to a 'labels' folder in the same directory as 'data'. | None | -The `auto_annotate` function takes the path to your images, along with optional arguments for specifying the pre-trained detection and SAM segmentation models, the device to run the models on, and the output directory for saving the annotated results. +The `auto_annotate` function takes the path to your images, with optional arguments for specifying the pre-trained detection and SAM segmentation models, the device to run the models on, and the output directory for saving the annotated results. -By leveraging the power of pre-trained models, auto-annotation can significantly reduce the time and effort required for creating high-quality segmentation datasets. This feature is particularly useful for researchers and developers working with large image collections, as it allows them to focus on model development and evaluation rather than manual annotation. +Auto-annotation with pre-trained models can dramatically cut down the time and effort required for creating high-quality segmentation datasets. This feature is especially beneficial for researchers and developers dealing with large image collections, as it allows them to focus on model development and evaluation rather than manual annotation. ## Citations and Acknowledgements -If you use SAM in your research or development work, please cite the following paper: +If you find SAM useful in your research or development work, please consider citing our paper: -```bibtex -@misc{kirillov2023segment, - title={Segment Anything}, - author={Alexander Kirillov and Eric Mintun and Nikhila Ravi and Hanzi Mao and Chloe Rolland and Laura Gustafson and Tete Xiao and Spencer Whitehead and Alexander C. Berg and Wan-Yen Lo and Piotr Dollár and Ross Girshick}, - year={2023}, - eprint={2304.02643}, - archivePrefix={arXiv}, - primaryClass={cs.CV} -} -``` +!!! note "" -We would like to acknowledge Meta AI for creating and maintaining this valuable resource for the computer vision community. \ No newline at end of file + === "BibTeX" + + ```bibtex + @misc{kirillov2023segment, + title={Segment Anything}, + author={Alexander Kirillov and Eric Mintun and Nikhila Ravi and Hanzi Mao and Chloe Rolland and Laura Gustafson and Tete Xiao and Spencer Whitehead and Alexander C. Berg and Wan-Yen Lo and Piotr Dollár and Ross Girshick}, + year={2023}, + eprint={2304.02643}, + archivePrefix={arXiv}, + primaryClass={cs.CV} + } + ``` + +We would like to express our gratitude to Meta AI for creating and maintaining this valuable resource for the computer vision community. + +*keywords: Segment Anything, Segment Anything Model, SAM, Meta SAM, image segmentation, promptable segmentation, zero-shot performance, SA-1B dataset, advanced architecture, auto-annotation, Ultralytics, pre-trained models, SAM base, SAM large, instance segmentation, computer vision, AI, artificial intelligence, machine learning, data annotation, segmentation masks, detection model, YOLO detection model, bibtex, Meta AI.* diff --git a/downloads/ultralytics-main/docs/models/yolo-nas.md b/downloads/ultralytics-main/docs/models/yolo-nas.md new file mode 100644 index 000000000..e589884fa --- /dev/null +++ b/downloads/ultralytics-main/docs/models/yolo-nas.md @@ -0,0 +1,127 @@ +--- +comments: true +description: Explore detailed documentation of YOLO-NAS, a superior object detection model. Learn about its features, pre-trained models, usage with Ultralytics Python API, and more. +keywords: YOLO-NAS, Deci AI, object detection, deep learning, neural architecture search, Ultralytics Python API, YOLO model, pre-trained models, quantization, optimization, COCO, Objects365, Roboflow 100 +--- + +# YOLO-NAS + +## Overview + +Developed by Deci AI, YOLO-NAS is a groundbreaking object detection foundational model. It is the product of advanced Neural Architecture Search technology, meticulously designed to address the limitations of previous YOLO models. With significant improvements in quantization support and accuracy-latency trade-offs, YOLO-NAS represents a major leap in object detection. + +![Model example image](https://learnopencv.com/wp-content/uploads/2023/05/yolo-nas_COCO_map_metrics.png) +**Overview of YOLO-NAS.** YOLO-NAS employs quantization-aware blocks and selective quantization for optimal performance. The model, when converted to its INT8 quantized version, experiences a minimal precision drop, a significant improvement over other models. These advancements culminate in a superior architecture with unprecedented object detection capabilities and outstanding performance. + +### Key Features + +- **Quantization-Friendly Basic Block:** YOLO-NAS introduces a new basic block that is friendly to quantization, addressing one of the significant limitations of previous YOLO models. +- **Sophisticated Training and Quantization:** YOLO-NAS leverages advanced training schemes and post-training quantization to enhance performance. +- **AutoNAC Optimization and Pre-training:** YOLO-NAS utilizes AutoNAC optimization and is pre-trained on prominent datasets such as COCO, Objects365, and Roboflow 100. This pre-training makes it extremely suitable for downstream object detection tasks in production environments. + +## Pre-trained Models + +Experience the power of next-generation object detection with the pre-trained YOLO-NAS models provided by Ultralytics. These models are designed to deliver top-notch performance in terms of both speed and accuracy. Choose from a variety of options tailored to your specific needs: + +| Model | mAP | Latency (ms) | +|------------------|-------|--------------| +| YOLO-NAS S | 47.5 | 3.21 | +| YOLO-NAS M | 51.55 | 5.85 | +| YOLO-NAS L | 52.22 | 7.87 | +| YOLO-NAS S INT-8 | 47.03 | 2.36 | +| YOLO-NAS M INT-8 | 51.0 | 3.78 | +| YOLO-NAS L INT-8 | 52.1 | 4.78 | + +Each model variant is designed to offer a balance between Mean Average Precision (mAP) and latency, helping you optimize your object detection tasks for both performance and speed. + +## Usage + +Ultralytics has made YOLO-NAS models easy to integrate into your Python applications via our `ultralytics` python package. The package provides a user-friendly Python API to streamline the process. + +The following examples show how to use YOLO-NAS models with the `ultralytics` package for inference and validation: + +### Inference and Validation Examples + +In this example we validate YOLO-NAS-s on the COCO8 dataset. + +!!! example "" + + This example provides simple inference and validation code for YOLO-NAS. For handling inference results see [Predict](../modes/predict.md) mode. For using YOLO-NAS with additional modes see [Val](../modes/val.md) and [Export](../modes/export.md). YOLO-NAS on the `ultralytics` package does not support training. + + === "Python" + + PyTorch pretrained `*.pt` models files can be passed to the `NAS()` class to create a model instance in python: + + ```python + from ultralytics import NAS + + # Load a COCO-pretrained YOLO-NAS-s model + model = NAS('yolo_nas_s.pt') + + # Display model information (optional) + model.info() + + # Validate the model on the COCO8 example dataset + results = model.val(data='coco8.yaml') + + # Run inference with the YOLO-NAS-s model on the 'bus.jpg' image + results = model('path/to/bus.jpg') + ``` + + === "CLI" + + CLI commands are available to directly run the models: + + ```bash + # Load a COCO-pretrained YOLO-NAS-s model and validate it's performance on the COCO8 example dataset + yolo val model=yolo_nas_s.pt data=coco8.yaml + + # Load a COCO-pretrained YOLO-NAS-s model and run inference on the 'bus.jpg' image + yolo predict model=yolo_nas_s.pt source=path/to/bus.jpg + ``` + +### Supported Tasks + +The YOLO-NAS models are primarily designed for object detection tasks. You can download the pre-trained weights for each variant of the model as follows: + +| Model Type | Pre-trained Weights | Tasks Supported | +|------------|-----------------------------------------------------------------------------------------------|------------------| +| YOLO-NAS-s | [yolo_nas_s.pt](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolo_nas_s.pt) | Object Detection | +| YOLO-NAS-m | [yolo_nas_m.pt](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolo_nas_m.pt) | Object Detection | +| YOLO-NAS-l | [yolo_nas_l.pt](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolo_nas_l.pt) | Object Detection | + +### Supported Modes + +The YOLO-NAS models support both inference and validation modes, allowing you to predict and validate results with ease. Training mode, however, is currently not supported. + +| Mode | Supported | +|------------|--------------------| +| Inference | :heavy_check_mark: | +| Validation | :heavy_check_mark: | +| Training | :x: | + +Harness the power of the YOLO-NAS models to drive your object detection tasks to new heights of performance and speed. + +## Citations and Acknowledgements + +If you employ YOLO-NAS in your research or development work, please cite SuperGradients: + +!!! note "" + + === "BibTeX" + + ```bibtex + @misc{supergradients, + doi = {10.5281/ZENODO.7789328}, + url = {https://zenodo.org/record/7789328}, + author = {Aharon, Shay and {Louis-Dupont} and {Ofri Masad} and Yurkova, Kate and {Lotem Fridman} and {Lkdci} and Khvedchenya, Eugene and Rubin, Ran and Bagrov, Natan and Tymchenko, Borys and Keren, Tomer and Zhilko, Alexander and {Eran-Deci}}, + title = {Super-Gradients}, + publisher = {GitHub}, + journal = {GitHub repository}, + year = {2021}, + } + ``` + +We express our gratitude to Deci AI's [SuperGradients](https://github.com/Deci-AI/super-gradients/) team for their efforts in creating and maintaining this valuable resource for the computer vision community. We believe YOLO-NAS, with its innovative architecture and superior object detection capabilities, will become a critical tool for developers and researchers alike. + +*Keywords: YOLO-NAS, Deci AI, object detection, deep learning, neural architecture search, Ultralytics Python API, YOLO model, SuperGradients, pre-trained models, quantization-friendly basic block, advanced training schemes, post-training quantization, AutoNAC optimization, COCO, Objects365, Roboflow 100* diff --git a/downloads/ultralytics-main/docs/models/yolov3.md b/downloads/ultralytics-main/docs/models/yolov3.md index 7b7f76dab..a7f3148d3 100644 --- a/downloads/ultralytics-main/docs/models/yolov3.md +++ b/downloads/ultralytics-main/docs/models/yolov3.md @@ -1,7 +1,107 @@ --- comments: true +description: Get an overview of YOLOv3, YOLOv3-Ultralytics and YOLOv3u. Learn about their key features, usage, and supported tasks for object detection. +keywords: YOLOv3, YOLOv3-Ultralytics, YOLOv3u, Object Detection, Inference, Training, Ultralytics --- -# 🚧Page Under Construction ⚒ +# YOLOv3, YOLOv3-Ultralytics, and YOLOv3u -This page is currently under construction!️👷Please check back later for updates. 😃🔜 +## Overview + +This document presents an overview of three closely related object detection models, namely [YOLOv3](https://pjreddie.com/darknet/yolo/), [YOLOv3-Ultralytics](https://github.com/ultralytics/yolov3), and [YOLOv3u](https://github.com/ultralytics/ultralytics). + +1. **YOLOv3:** This is the third version of the You Only Look Once (YOLO) object detection algorithm. Originally developed by Joseph Redmon, YOLOv3 improved on its predecessors by introducing features such as multiscale predictions and three different sizes of detection kernels. + +2. **YOLOv3-Ultralytics:** This is Ultralytics' implementation of the YOLOv3 model. It reproduces the original YOLOv3 architecture and offers additional functionalities, such as support for more pre-trained models and easier customization options. + +3. **YOLOv3u:** This is an updated version of YOLOv3-Ultralytics that incorporates the anchor-free, objectness-free split head used in YOLOv8 models. YOLOv3u maintains the same backbone and neck architecture as YOLOv3 but with the updated detection head from YOLOv8. + +![Ultralytics YOLOv3](https://raw.githubusercontent.com/ultralytics/assets/main/yolov3/banner-yolov3.png) + +## Key Features + +- **YOLOv3:** Introduced the use of three different scales for detection, leveraging three different sizes of detection kernels: 13x13, 26x26, and 52x52. This significantly improved detection accuracy for objects of different sizes. Additionally, YOLOv3 added features such as multi-label predictions for each bounding box and a better feature extractor network. + +- **YOLOv3-Ultralytics:** Ultralytics' implementation of YOLOv3 provides the same performance as the original model but comes with added support for more pre-trained models, additional training methods, and easier customization options. This makes it more versatile and user-friendly for practical applications. + +- **YOLOv3u:** This updated model incorporates the anchor-free, objectness-free split head from YOLOv8. By eliminating the need for pre-defined anchor boxes and objectness scores, this detection head design can improve the model's ability to detect objects of varying sizes and shapes. This makes YOLOv3u more robust and accurate for object detection tasks. + +## Supported Tasks + +YOLOv3, YOLOv3-Ultralytics, and YOLOv3u all support the following tasks: + +- Object Detection + +## Supported Modes + +All three models support the following modes: + +- Inference +- Validation +- Training +- Export + +## Performance + +Below is a comparison of the performance of the three models. The performance is measured in terms of the Mean Average Precision (mAP) on the COCO dataset: + +TODO + +## Usage + +You can use YOLOv3 for object detection tasks using the Ultralytics repository. The following is a sample code snippet showing how to use YOLOv3 model for inference: + +!!! example "" + + This example provides simple inference code for YOLOv3. For more options including handling inference results see [Predict](../modes/predict.md) mode. For using YOLOv3 with additional modes see [Train](../modes/train.md), [Val](../modes/val.md) and [Export](../modes/export.md). + + === "Python" + + PyTorch pretrained `*.pt` models as well as configuration `*.yaml` files can be passed to the `YOLO()` class to create a model instance in python: + + ```python + from ultralytics import YOLO + + # Load a COCO-pretrained YOLOv3n model + model = YOLO('yolov3n.pt') + + # Display model information (optional) + model.info() + + # Train the model on the COCO8 example dataset for 100 epochs + results = model.train(data='coco8.yaml', epochs=100, imgsz=640) + + # Run inference with the YOLOv3n model on the 'bus.jpg' image + results = model('path/to/bus.jpg') + ``` + + === "CLI" + + CLI commands are available to directly run the models: + + ```bash + # Load a COCO-pretrained YOLOv3n model and train it on the COCO8 example dataset for 100 epochs + yolo train model=yolov3n.pt data=coco8.yaml epochs=100 imgsz=640 + + # Load a COCO-pretrained YOLOv3n model and run inference on the 'bus.jpg' image + yolo predict model=yolov3n.pt source=path/to/bus.jpg + ``` + +## Citations and Acknowledgements + +If you use YOLOv3 in your research, please cite the original YOLO papers and the Ultralytics YOLOv3 repository: + +!!! note "" + + === "BibTeX" + + ```bibtex + @article{redmon2018yolov3, + title={YOLOv3: An Incremental Improvement}, + author={Redmon, Joseph and Farhadi, Ali}, + journal={arXiv preprint arXiv:1804.02767}, + year={2018} + } + ``` + +Thank you to Joseph Redmon and Ali Farhadi for developing the original YOLOv3. diff --git a/downloads/ultralytics-main/docs/models/yolov4.md b/downloads/ultralytics-main/docs/models/yolov4.md new file mode 100644 index 000000000..1af7ccdbb --- /dev/null +++ b/downloads/ultralytics-main/docs/models/yolov4.md @@ -0,0 +1,71 @@ +--- +comments: true +description: Explore our detailed guide on YOLOv4, a state-of-the-art real-time object detector. Understand its architectural highlights, innovative features, and application examples. +keywords: ultralytics, YOLOv4, object detection, neural network, real-time detection, object detector, machine learning +--- + +# YOLOv4: High-Speed and Precise Object Detection + +Welcome to the Ultralytics documentation page for YOLOv4, a state-of-the-art, real-time object detector launched in 2020 by Alexey Bochkovskiy at [https://github.com/AlexeyAB/darknet](https://github.com/AlexeyAB/darknet). YOLOv4 is designed to provide the optimal balance between speed and accuracy, making it an excellent choice for many applications. + +![YOLOv4 architecture diagram](https://user-images.githubusercontent.com/26833433/246185689-530b7fe8-737b-4bb0-b5dd-de10ef5aface.png) +**YOLOv4 architecture diagram**. Showcasing the intricate network design of YOLOv4, including the backbone, neck, and head components, and their interconnected layers for optimal real-time object detection. + +## Introduction + +YOLOv4 stands for You Only Look Once version 4. It is a real-time object detection model developed to address the limitations of previous YOLO versions like [YOLOv3](./yolov3.md) and other object detection models. Unlike other convolutional neural network (CNN) based object detectors, YOLOv4 is not only applicable for recommendation systems but also for standalone process management and human input reduction. Its operation on conventional graphics processing units (GPUs) allows for mass usage at an affordable price, and it is designed to work in real-time on a conventional GPU while requiring only one such GPU for training. + +## Architecture + +YOLOv4 makes use of several innovative features that work together to optimize its performance. These include Weighted-Residual-Connections (WRC), Cross-Stage-Partial-connections (CSP), Cross mini-Batch Normalization (CmBN), Self-adversarial-training (SAT), Mish-activation, Mosaic data augmentation, DropBlock regularization, and CIoU loss. These features are combined to achieve state-of-the-art results. + +A typical object detector is composed of several parts including the input, the backbone, the neck, and the head. The backbone of YOLOv4 is pre-trained on ImageNet and is used to predict classes and bounding boxes of objects. The backbone could be from several models including VGG, ResNet, ResNeXt, or DenseNet. The neck part of the detector is used to collect feature maps from different stages and usually includes several bottom-up paths and several top-down paths. The head part is what is used to make the final object detections and classifications. + +## Bag of Freebies + +YOLOv4 also makes use of methods known as "bag of freebies," which are techniques that improve the accuracy of the model during training without increasing the cost of inference. Data augmentation is a common bag of freebies technique used in object detection, which increases the variability of the input images to improve the robustness of the model. Some examples of data augmentation include photometric distortions (adjusting the brightness, contrast, hue, saturation, and noise of an image) and geometric distortions (adding random scaling, cropping, flipping, and rotating). These techniques help the model to generalize better to different types of images. + +## Features and Performance + +YOLOv4 is designed for optimal speed and accuracy in object detection. The architecture of YOLOv4 includes CSPDarknet53 as the backbone, PANet as the neck, and YOLOv3 as the detection head. This design allows YOLOv4 to perform object detection at an impressive speed, making it suitable for real-time applications. YOLOv4 also excels in accuracy, achieving state-of-the-art results in object detection benchmarks. + +## Usage Examples + +As of the time of writing, Ultralytics does not currently support YOLOv4 models. Therefore, any users interested in using YOLOv4 will need to refer directly to the YOLOv4 GitHub repository for installation and usage instructions. + +Here is a brief overview of the typical steps you might take to use YOLOv4: + +1. Visit the YOLOv4 GitHub repository: [https://github.com/AlexeyAB/darknet](https://github.com/AlexeyAB/darknet). + +2. Follow the instructions provided in the README file for installation. This typically involves cloning the repository, installing necessary dependencies, and setting up any necessary environment variables. + +3. Once installation is complete, you can train and use the model as per the usage instructions provided in the repository. This usually involves preparing your dataset, configuring the model parameters, training the model, and then using the trained model to perform object detection. + +Please note that the specific steps may vary depending on your specific use case and the current state of the YOLOv4 repository. Therefore, it is strongly recommended to refer directly to the instructions provided in the YOLOv4 GitHub repository. + +We regret any inconvenience this may cause and will strive to update this document with usage examples for Ultralytics once support for YOLOv4 is implemented. + +## Conclusion + +YOLOv4 is a powerful and efficient object detection model that strikes a balance between speed and accuracy. Its use of unique features and bag of freebies techniques during training allows it to perform excellently in real-time object detection tasks. YOLOv4 can be trained and used by anyone with a conventional GPU, making it accessible and practical for a wide range of applications. + +## Citations and Acknowledgements + +We would like to acknowledge the YOLOv4 authors for their significant contributions in the field of real-time object detection: + +!!! note "" + + === "BibTeX" + + ```bibtex + @misc{bochkovskiy2020yolov4, + title={YOLOv4: Optimal Speed and Accuracy of Object Detection}, + author={Alexey Bochkovskiy and Chien-Yao Wang and Hong-Yuan Mark Liao}, + year={2020}, + eprint={2004.10934}, + archivePrefix={arXiv}, + primaryClass={cs.CV} + } + ``` + +The original YOLOv4 paper can be found on [arXiv](https://arxiv.org/pdf/2004.10934.pdf). The authors have made their work publicly available, and the codebase can be accessed on [GitHub](https://github.com/AlexeyAB/darknet). We appreciate their efforts in advancing the field and making their work accessible to the broader community. diff --git a/downloads/ultralytics-main/docs/models/yolov5.md b/downloads/ultralytics-main/docs/models/yolov5.md index 00a0a4b66..e20b9b889 100644 --- a/downloads/ultralytics-main/docs/models/yolov5.md +++ b/downloads/ultralytics-main/docs/models/yolov5.md @@ -1,19 +1,24 @@ --- comments: true -description: Detect objects faster and more accurately using Ultralytics YOLOv5u. Find pre-trained models for each task, including Inference, Validation and Training. +description: Discover YOLOv5u, a boosted version of the YOLOv5 model featuring an improved accuracy-speed tradeoff and numerous pre-trained models for various object detection tasks. +keywords: YOLOv5u, object detection, pre-trained models, Ultralytics, Inference, Validation, YOLOv5, YOLOv8, anchor-free, objectness-free, real-time applications, machine learning --- -# YOLOv5u +# YOLOv5 ## Overview -YOLOv5u is an updated version of YOLOv5 that incorporates the anchor-free split Ultralytics head used in the YOLOv8 models. It retains the same backbone and neck architecture as YOLOv5 but offers improved accuracy-speed tradeoff for object detection tasks. +YOLOv5u represents an advancement in object detection methodologies. Originating from the foundational architecture of the [YOLOv5](https://github.com/ultralytics/yolov5) model developed by Ultralytics, YOLOv5u integrates the anchor-free, objectness-free split head, a feature previously introduced in the [YOLOv8](./yolov8.md) models. This adaptation refines the model's architecture, leading to an improved accuracy-speed tradeoff in object detection tasks. Given the empirical results and its derived features, YOLOv5u provides an efficient alternative for those seeking robust solutions in both research and practical applications. + +![Ultralytics YOLOv5](https://raw.githubusercontent.com/ultralytics/assets/main/yolov5/v70/splash.png) ## Key Features -- **Anchor-free Split Ultralytics Head:** YOLOv5u replaces the traditional anchor-based detection head with an anchor-free split Ultralytics head, resulting in improved performance. -- **Optimized Accuracy-Speed Tradeoff:** The updated model offers a better balance between accuracy and speed, making it more suitable for a wider range of applications. -- **Variety of Pre-trained Models:** YOLOv5u offers a range of pre-trained models tailored for various tasks, including Inference, Validation, and Training. +- **Anchor-free Split Ultralytics Head:** Traditional object detection models rely on predefined anchor boxes to predict object locations. However, YOLOv5u modernizes this approach. By adopting an anchor-free split Ultralytics head, it ensures a more flexible and adaptive detection mechanism, consequently enhancing the performance in diverse scenarios. + +- **Optimized Accuracy-Speed Tradeoff:** Speed and accuracy often pull in opposite directions. But YOLOv5u challenges this tradeoff. It offers a calibrated balance, ensuring real-time detections without compromising on accuracy. This feature is particularly invaluable for applications that demand swift responses, such as autonomous vehicles, robotics, and real-time video analytics. + +- **Variety of Pre-trained Models:** Understanding that different tasks require different toolsets, YOLOv5u provides a plethora of pre-trained models. Whether you're focusing on Inference, Validation, or Training, there's a tailor-made model awaiting you. This variety ensures you're not just using a one-size-fits-all solution, but a model specifically fine-tuned for your unique challenge. ## Supported Tasks @@ -29,20 +34,82 @@ YOLOv5u is an updated version of YOLOv5 that incorporates the anchor-free split | Validation | :heavy_check_mark: | | Training | :heavy_check_mark: | -??? Performance +!!! Performance === "Detection" - | Model | size
(pixels) | mAPval
50-95 | Speed
CPU ONNX
(ms) | Speed
A100 TensorRT
(ms) | params
(M) | FLOPs
(B) | - | ---------------------------------------------------------------------------------------- | --------------------- | -------------------- | ------------------------------ | ----------------------------------- | ------------------ | ----------------- | - | [YOLOv5nu](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5nu.pt) | 640 | 34.3 | 73.6 | 1.06 | 2.6 | 7.7 | - | [YOLOv5su](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5su.pt) | 640 | 43.0 | 120.7 | 1.27 | 9.1 | 24.0 | - | [YOLOv5mu](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5mu.pt) | 640 | 49.0 | 233.9 | 1.86 | 25.1 | 64.2 | - | [YOLOv5lu](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5lu.pt) | 640 | 52.2 | 408.4 | 2.50 | 53.2 | 135.0 | - | [YOLOv5xu](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5xu.pt) | 640 | 53.2 | 763.2 | 3.81 | 97.2 | 246.4 | - | | | | | | | | - | [YOLOv5n6u](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5n6u.pt) | 1280 | 42.1 | - | - | 4.3 | 7.8 | - | [YOLOv5s6u](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5s6u.pt) | 1280 | 48.6 | - | - | 15.3 | 24.6 | - | [YOLOv5m6u](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5m6u.pt) | 1280 | 53.6 | - | - | 41.2 | 65.7 | - | [YOLOv5l6u](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5l6u.pt) | 1280 | 55.7 | - | - | 86.1 | 137.4 | - | [YOLOv5x6u](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5x6u.pt) | 1280 | 56.8 | - | - | 155.4 | 250.7 | \ No newline at end of file + | Model | YAML | size
(pixels) | mAPval
50-95 | Speed
CPU ONNX
(ms) | Speed
A100 TensorRT
(ms) | params
(M) | FLOPs
(B) | + |---------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|-----------------------|----------------------|--------------------------------|-------------------------------------|--------------------|-------------------| + | [yolov5nu.pt](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5nu.pt) | [yolov5n.yaml](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/models/v5/yolov5.yaml) | 640 | 34.3 | 73.6 | 1.06 | 2.6 | 7.7 | + | [yolov5su.pt](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5su.pt) | [yolov5s.yaml](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/models/v5/yolov5.yaml) | 640 | 43.0 | 120.7 | 1.27 | 9.1 | 24.0 | + | [yolov5mu.pt](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5mu.pt) | [yolov5m.yaml](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/models/v5/yolov5.yaml) | 640 | 49.0 | 233.9 | 1.86 | 25.1 | 64.2 | + | [yolov5lu.pt](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5lu.pt) | [yolov5l.yaml](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/models/v5/yolov5.yaml) | 640 | 52.2 | 408.4 | 2.50 | 53.2 | 135.0 | + | [yolov5xu.pt](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5xu.pt) | [yolov5x.yaml](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/models/v5/yolov5.yaml) | 640 | 53.2 | 763.2 | 3.81 | 97.2 | 246.4 | + | | | | | | | | | + | [yolov5n6u.pt](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5n6u.pt) | [yolov5n6.yaml](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/models/v5/yolov5-p6.yaml) | 1280 | 42.1 | 211.0 | 1.83 | 4.3 | 7.8 | + | [yolov5s6u.pt](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5s6u.pt) | [yolov5s6.yaml](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/models/v5/yolov5-p6.yaml) | 1280 | 48.6 | 422.6 | 2.34 | 15.3 | 24.6 | + | [yolov5m6u.pt](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5m6u.pt) | [yolov5m6.yaml](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/models/v5/yolov5-p6.yaml) | 1280 | 53.6 | 810.9 | 4.36 | 41.2 | 65.7 | + | [yolov5l6u.pt](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5l6u.pt) | [yolov5l6.yaml](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/models/v5/yolov5-p6.yaml) | 1280 | 55.7 | 1470.9 | 5.47 | 86.1 | 137.4 | + | [yolov5x6u.pt](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov5x6u.pt) | [yolov5x6.yaml](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/models/v5/yolov5-p6.yaml) | 1280 | 56.8 | 2436.5 | 8.98 | 155.4 | 250.7 | + +## Usage + +You can use YOLOv5u for object detection tasks using the Ultralytics repository. The following is a sample code snippet showing how to use YOLOv5u model for inference: + +!!! example "" + + This example provides simple inference code for YOLOv5. For more options including handling inference results see [Predict](../modes/predict.md) mode. For using YOLOv5 with additional modes see [Train](../modes/train.md), [Val](../modes/val.md) and [Export](../modes/export.md). + + === "Python" + + PyTorch pretrained `*.pt` models as well as configuration `*.yaml` files can be passed to the `YOLO()` class to create a model instance in python: + + ```python + from ultralytics import YOLO + + # Load a COCO-pretrained YOLOv5n model + model = YOLO('yolov5n.pt') + + # Display model information (optional) + model.info() + + # Train the model on the COCO8 example dataset for 100 epochs + results = model.train(data='coco8.yaml', epochs=100, imgsz=640) + + # Run inference with the YOLOv5n model on the 'bus.jpg' image + results = model('path/to/bus.jpg') + ``` + + === "CLI" + + CLI commands are available to directly run the models: + + ```bash + # Load a COCO-pretrained YOLOv5n model and train it on the COCO8 example dataset for 100 epochs + yolo train model=yolov5n.pt data=coco8.yaml epochs=100 imgsz=640 + + # Load a COCO-pretrained YOLOv5n model and run inference on the 'bus.jpg' image + yolo predict model=yolov5n.pt source=path/to/bus.jpg + ``` + +## Citations and Acknowledgements + +If you use YOLOv5 or YOLOv5u in your research, please cite the Ultralytics YOLOv5 repository as follows: + +!!! note "" + + === "BibTeX" + ```bibtex + @software{yolov5, + title = {Ultralytics YOLOv5}, + author = {Glenn Jocher}, + year = {2020}, + version = {7.0}, + license = {AGPL-3.0}, + url = {https://github.com/ultralytics/yolov5}, + doi = {10.5281/zenodo.3908559}, + orcid = {0000-0001-5950-6979} + } + ``` + +Special thanks to Glenn Jocher and the Ultralytics team for their work on developing and maintaining the YOLOv5 and YOLOv5u models. diff --git a/downloads/ultralytics-main/docs/models/yolov6.md b/downloads/ultralytics-main/docs/models/yolov6.md new file mode 100644 index 000000000..047b9d6ca --- /dev/null +++ b/downloads/ultralytics-main/docs/models/yolov6.md @@ -0,0 +1,114 @@ +--- +comments: true +description: Explore Meituan YOLOv6, a state-of-the-art object detection model striking a balance between speed and accuracy. Dive into features, pre-trained models, and Python usage. +keywords: Meituan YOLOv6, object detection, Ultralytics, YOLOv6 docs, Bi-directional Concatenation, Anchor-Aided Training, pretrained models, real-time applications +--- + +# Meituan YOLOv6 + +## Overview + +[Meituan](https://about.meituan.com/) YOLOv6 is a cutting-edge object detector that offers remarkable balance between speed and accuracy, making it a popular choice for real-time applications. This model introduces several notable enhancements on its architecture and training scheme, including the implementation of a Bi-directional Concatenation (BiC) module, an anchor-aided training (AAT) strategy, and an improved backbone and neck design for state-of-the-art accuracy on the COCO dataset. + +![Meituan YOLOv6](https://user-images.githubusercontent.com/26833433/240750495-4da954ce-8b3b-41c4-8afd-ddb74361d3c2.png) +![Model example image](https://user-images.githubusercontent.com/26833433/240750557-3e9ec4f0-0598-49a8-83ea-f33c91eb6d68.png) +**Overview of YOLOv6.** Model architecture diagram showing the redesigned network components and training strategies that have led to significant performance improvements. (a) The neck of YOLOv6 (N and S are shown). Note for M/L, RepBlocks is replaced with CSPStackRep. (b) The +structure of a BiC module. (c) A SimCSPSPPF block. ([source](https://arxiv.org/pdf/2301.05586.pdf)). + +### Key Features + +- **Bidirectional Concatenation (BiC) Module:** YOLOv6 introduces a BiC module in the neck of the detector, enhancing localization signals and delivering performance gains with negligible speed degradation. +- **Anchor-Aided Training (AAT) Strategy:** This model proposes AAT to enjoy the benefits of both anchor-based and anchor-free paradigms without compromising inference efficiency. +- **Enhanced Backbone and Neck Design:** By deepening YOLOv6 to include another stage in the backbone and neck, this model achieves state-of-the-art performance on the COCO dataset at high-resolution input. +- **Self-Distillation Strategy:** A new self-distillation strategy is implemented to boost the performance of smaller models of YOLOv6, enhancing the auxiliary regression branch during training and removing it at inference to avoid a marked speed decline. + +## Pre-trained Models + +YOLOv6 provides various pre-trained models with different scales: + +- YOLOv6-N: 37.5% AP on COCO val2017 at 1187 FPS with NVIDIA Tesla T4 GPU. +- YOLOv6-S: 45.0% AP at 484 FPS. +- YOLOv6-M: 50.0% AP at 226 FPS. +- YOLOv6-L: 52.8% AP at 116 FPS. +- YOLOv6-L6: State-of-the-art accuracy in real-time. + +YOLOv6 also provides quantized models for different precisions and models optimized for mobile platforms. + +## Usage + +You can use YOLOv6 for object detection tasks using the Ultralytics pip package. The following is a sample code snippet showing how to use YOLOv6 models for training: + +!!! example "" + + This example provides simple training code for YOLOv6. For more options including training settings see [Train](../modes/train.md) mode. For using YOLOv6 with additional modes see [Predict](../modes/predict.md), [Val](../modes/val.md) and [Export](../modes/export.md). + + === "Python" + + PyTorch pretrained `*.pt` models as well as configuration `*.yaml` files can be passed to the `YOLO()` class to create a model instance in python: + + ```python + from ultralytics import YOLO + + # Build a YOLOv6n model from scratch + model = YOLO('yolov6n.yaml') + + # Display model information (optional) + model.info() + + # Train the model on the COCO8 example dataset for 100 epochs + results = model.train(data='coco8.yaml', epochs=100, imgsz=640) + + # Run inference with the YOLOv6n model on the 'bus.jpg' image + results = model('path/to/bus.jpg') + ``` + + === "CLI" + + CLI commands are available to directly run the models: + + ```bash + # Build a YOLOv6n model from scratch and train it on the COCO8 example dataset for 100 epochs + yolo train model=yolov6n.yaml data=coco8.yaml epochs=100 imgsz=640 + + # Build a YOLOv6n model from scratch and run inference on the 'bus.jpg' image + yolo predict model=yolov6n.yaml source=path/to/bus.jpg + ``` + +### Supported Tasks + +| Model Type | Pre-trained Weights | Tasks Supported | +|------------|---------------------|------------------| +| YOLOv6-N | `yolov6-n.pt` | Object Detection | +| YOLOv6-S | `yolov6-s.pt` | Object Detection | +| YOLOv6-M | `yolov6-m.pt` | Object Detection | +| YOLOv6-L | `yolov6-l.pt` | Object Detection | +| YOLOv6-L6 | `yolov6-l6.pt` | Object Detection | + +## Supported Modes + +| Mode | Supported | +|------------|--------------------| +| Inference | :heavy_check_mark: | +| Validation | :heavy_check_mark: | +| Training | :heavy_check_mark: | + +## Citations and Acknowledgements + +We would like to acknowledge the authors for their significant contributions in the field of real-time object detection: + +!!! note "" + + === "BibTeX" + + ```bibtex + @misc{li2023yolov6, + title={YOLOv6 v3.0: A Full-Scale Reloading}, + author={Chuyi Li and Lulu Li and Yifei Geng and Hongliang Jiang and Meng Cheng and Bo Zhang and Zaidan Ke and Xiaoming Xu and Xiangxiang Chu}, + year={2023}, + eprint={2301.05586}, + archivePrefix={arXiv}, + primaryClass={cs.CV} + } + ``` + +The original YOLOv6 paper can be found on [arXiv](https://arxiv.org/abs/2301.05586). The authors have made their work publicly available, and the codebase can be accessed on [GitHub](https://github.com/meituan/YOLOv6). We appreciate their efforts in advancing the field and making their work accessible to the broader community. diff --git a/downloads/ultralytics-main/docs/models/yolov7.md b/downloads/ultralytics-main/docs/models/yolov7.md new file mode 100644 index 000000000..4f4a035cd --- /dev/null +++ b/downloads/ultralytics-main/docs/models/yolov7.md @@ -0,0 +1,65 @@ +--- +comments: true +description: Explore the YOLOv7, a real-time object detector. Understand its superior speed, impressive accuracy, and unique trainable bag-of-freebies optimization focus. +keywords: YOLOv7, real-time object detector, state-of-the-art, Ultralytics, MS COCO dataset, model re-parameterization, dynamic label assignment, extended scaling, compound scaling +--- + +# YOLOv7: Trainable Bag-of-Freebies + +YOLOv7 is a state-of-the-art real-time object detector that surpasses all known object detectors in both speed and accuracy in the range from 5 FPS to 160 FPS. It has the highest accuracy (56.8% AP) among all known real-time object detectors with 30 FPS or higher on GPU V100. Moreover, YOLOv7 outperforms other object detectors such as YOLOR, YOLOX, Scaled-YOLOv4, YOLOv5, and many others in speed and accuracy. The model is trained on the MS COCO dataset from scratch without using any other datasets or pre-trained weights. Source code for YOLOv7 is available on GitHub. + +![YOLOv7 comparison with SOTA object detectors](https://github.com/ultralytics/ultralytics/assets/26833433/5e1e0420-8122-4c79-b8d0-2860aa79af92) +**Comparison of state-of-the-art object detectors.** From the results in Table 2 we know that the proposed method has the best speed-accuracy trade-off comprehensively. If we compare YOLOv7-tiny-SiLU with YOLOv5-N (r6.1), our method is 127 fps faster and 10.7% more accurate on AP. In addition, YOLOv7 has 51.4% AP at frame rate of 161 fps, while PPYOLOE-L with the same AP has only 78 fps frame rate. In terms of parameter usage, YOLOv7 is 41% less than PPYOLOE-L. If we compare YOLOv7-X with 114 fps inference speed to YOLOv5-L (r6.1) with 99 fps inference speed, YOLOv7-X can improve AP by 3.9%. If YOLOv7-X is compared with YOLOv5-X (r6.1) of similar scale, the inference speed of YOLOv7-X is 31 fps faster. In addition, in terms the amount of parameters and computation, YOLOv7-X reduces 22% of parameters and 8% of computation compared to YOLOv5-X (r6.1), but improves AP by 2.2% ([Source](https://arxiv.org/pdf/2207.02696.pdf)). + +## Overview + +Real-time object detection is an important component in many computer vision systems, including multi-object tracking, autonomous driving, robotics, and medical image analysis. In recent years, real-time object detection development has focused on designing efficient architectures and improving the inference speed of various CPUs, GPUs, and neural processing units (NPUs). YOLOv7 supports both mobile GPU and GPU devices, from the edge to the cloud. + +Unlike traditional real-time object detectors that focus on architecture optimization, YOLOv7 introduces a focus on the optimization of the training process. This includes modules and optimization methods designed to improve the accuracy of object detection without increasing the inference cost, a concept known as the "trainable bag-of-freebies". + +## Key Features + +YOLOv7 introduces several key features: + +1. **Model Re-parameterization**: YOLOv7 proposes a planned re-parameterized model, which is a strategy applicable to layers in different networks with the concept of gradient propagation path. + +2. **Dynamic Label Assignment**: The training of the model with multiple output layers presents a new issue: "How to assign dynamic targets for the outputs of different branches?" To solve this problem, YOLOv7 introduces a new label assignment method called coarse-to-fine lead guided label assignment. + +3. **Extended and Compound Scaling**: YOLOv7 proposes "extend" and "compound scaling" methods for the real-time object detector that can effectively utilize parameters and computation. + +4. **Efficiency**: The method proposed by YOLOv7 can effectively reduce about 40% parameters and 50% computation of state-of-the-art real-time object detector, and has faster inference speed and higher detection accuracy. + +## Usage Examples + +As of the time of writing, Ultralytics does not currently support YOLOv7 models. Therefore, any users interested in using YOLOv7 will need to refer directly to the YOLOv7 GitHub repository for installation and usage instructions. + +Here is a brief overview of the typical steps you might take to use YOLOv7: + +1. Visit the YOLOv7 GitHub repository: [https://github.com/WongKinYiu/yolov7](https://github.com/WongKinYiu/yolov7). + +2. Follow the instructions provided in the README file for installation. This typically involves cloning the repository, installing necessary dependencies, and setting up any necessary environment variables. + +3. Once installation is complete, you can train and use the model as per the usage instructions provided in the repository. This usually involves preparing your dataset, configuring the model parameters, training the model, and then using the trained model to perform object detection. + +Please note that the specific steps may vary depending on your specific use case and the current state of the YOLOv7 repository. Therefore, it is strongly recommended to refer directly to the instructions provided in the YOLOv7 GitHub repository. + +We regret any inconvenience this may cause and will strive to update this document with usage examples for Ultralytics once support for YOLOv7 is implemented. + +## Citations and Acknowledgements + +We would like to acknowledge the YOLOv7 authors for their significant contributions in the field of real-time object detection: + +!!! note "" + + === "BibTeX" + + ```bibtex + @article{wang2022yolov7, + title={{YOLOv7}: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors}, + author={Wang, Chien-Yao and Bochkovskiy, Alexey and Liao, Hong-Yuan Mark}, + journal={arXiv preprint arXiv:2207.02696}, + year={2022} + } + ``` + +The original YOLOv7 paper can be found on [arXiv](https://arxiv.org/pdf/2207.02696.pdf). The authors have made their work publicly available, and the codebase can be accessed on [GitHub](https://github.com/WongKinYiu/yolov7). We appreciate their efforts in advancing the field and making their work accessible to the broader community. diff --git a/downloads/ultralytics-main/docs/models/yolov8.md b/downloads/ultralytics-main/docs/models/yolov8.md index 53df59c90..049822472 100644 --- a/downloads/ultralytics-main/docs/models/yolov8.md +++ b/downloads/ultralytics-main/docs/models/yolov8.md @@ -1,6 +1,7 @@ --- comments: true -description: Learn about YOLOv8's pre-trained weights supporting detection, instance segmentation, pose, and classification tasks. Get performance details. +description: Explore the thrilling features of YOLOv8, the latest version of our real-time object detector! Learn how advanced architectures, pre-trained models and optimal balance between accuracy & speed make YOLOv8 the perfect choice for your object detection tasks. +keywords: YOLOv8, Ultralytics, real-time object detector, pre-trained models, documentation, object detection, YOLO series, advanced architectures, accuracy, speed --- # YOLOv8 @@ -9,6 +10,8 @@ description: Learn about YOLOv8's pre-trained weights supporting detection, inst YOLOv8 is the latest iteration in the YOLO series of real-time object detectors, offering cutting-edge performance in terms of accuracy and speed. Building upon the advancements of previous YOLO versions, YOLOv8 introduces new features and optimizations that make it an ideal choice for various object detection tasks in a wide range of applications. +![Ultralytics YOLOv8](https://raw.githubusercontent.com/ultralytics/assets/main/yolov8/yolo-comparison-plots.png) + ## Key Features - **Advanced Backbone and Neck Architectures:** YOLOv8 employs state-of-the-art backbone and neck architectures, resulting in improved feature extraction and object detection performance. @@ -18,12 +21,12 @@ YOLOv8 is the latest iteration in the YOLO series of real-time object detectors, ## Supported Tasks -| Model Type | Pre-trained Weights | Task | -|-------------|------------------------------------------------------------------------------------------------------------------|-----------------------| -| YOLOv8 | `yolov8n.pt`, `yolov8s.pt`, `yolov8m.pt`, `yolov8l.pt`, `yolov8x.pt` | Detection | -| YOLOv8-seg | `yolov8n-seg.pt`, `yolov8s-seg.pt`, `yolov8m-seg.pt`, `yolov8l-seg.pt`, `yolov8x-seg.pt` | Instance Segmentation | -| YOLOv8-pose | `yolov8n-pose.pt`, `yolov8s-pose.pt`, `yolov8m-pose.pt`, `yolov8l-pose.pt`, `yolov8x-pose.pt` ,`yolov8x-pose-p6` | Pose/Keypoints | -| YOLOv8-cls | `yolov8n-cls.pt`, `yolov8s-cls.pt`, `yolov8m-cls.pt`, `yolov8l-cls.pt`, `yolov8x-cls.pt` | Classification | +| Model Type | Pre-trained Weights | Task | +|-------------|---------------------------------------------------------------------------------------------------------------------|-----------------------| +| YOLOv8 | `yolov8n.pt`, `yolov8s.pt`, `yolov8m.pt`, `yolov8l.pt`, `yolov8x.pt` | Detection | +| YOLOv8-seg | `yolov8n-seg.pt`, `yolov8s-seg.pt`, `yolov8m-seg.pt`, `yolov8l-seg.pt`, `yolov8x-seg.pt` | Instance Segmentation | +| YOLOv8-pose | `yolov8n-pose.pt`, `yolov8s-pose.pt`, `yolov8m-pose.pt`, `yolov8l-pose.pt`, `yolov8x-pose.pt`, `yolov8x-pose-p6.pt` | Pose/Keypoints | +| YOLOv8-cls | `yolov8n-cls.pt`, `yolov8s-cls.pt`, `yolov8m-cls.pt`, `yolov8l-cls.pt`, `yolov8x-cls.pt` | Classification | ## Supported Modes @@ -33,7 +36,7 @@ YOLOv8 is the latest iteration in the YOLO series of real-time object detectors, | Validation | :heavy_check_mark: | | Training | :heavy_check_mark: | -??? Performance +!!! Performance === "Detection" @@ -74,4 +77,66 @@ YOLOv8 is the latest iteration in the YOLO series of real-time object detectors, | [YOLOv8m-pose](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8m-pose.pt) | 640 | 65.0 | 88.8 | 456.3 | 2.00 | 26.4 | 81.0 | | [YOLOv8l-pose](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8l-pose.pt) | 640 | 67.6 | 90.0 | 784.5 | 2.59 | 44.4 | 168.6 | | [YOLOv8x-pose](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8x-pose.pt) | 640 | 69.2 | 90.2 | 1607.1 | 3.73 | 69.4 | 263.2 | - | [YOLOv8x-pose-p6](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8x-pose-p6.pt) | 1280 | 71.6 | 91.2 | 4088.7 | 10.04 | 99.1 | 1066.4 | \ No newline at end of file + | [YOLOv8x-pose-p6](https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8x-pose-p6.pt) | 1280 | 71.6 | 91.2 | 4088.7 | 10.04 | 99.1 | 1066.4 | + +## Usage + +You can use YOLOv8 for object detection tasks using the Ultralytics pip package. The following is a sample code snippet showing how to use YOLOv8 models for inference: + +!!! example "" + + This example provides simple inference code for YOLOv8. For more options including handling inference results see [Predict](../modes/predict.md) mode. For using YOLOv8 with additional modes see [Train](../modes/train.md), [Val](../modes/val.md) and [Export](../modes/export.md). + + === "Python" + + PyTorch pretrained `*.pt` models as well as configuration `*.yaml` files can be passed to the `YOLO()` class to create a model instance in python: + + ```python + from ultralytics import YOLO + + # Load a COCO-pretrained YOLOv8n model + model = YOLO('yolov8n.pt') + + # Display model information (optional) + model.info() + + # Train the model on the COCO8 example dataset for 100 epochs + results = model.train(data='coco8.yaml', epochs=100, imgsz=640) + + # Run inference with the YOLOv8n model on the 'bus.jpg' image + results = model('path/to/bus.jpg') + ``` + + === "CLI" + + CLI commands are available to directly run the models: + + ```bash + # Load a COCO-pretrained YOLOv8n model and train it on the COCO8 example dataset for 100 epochs + yolo train model=yolov8n.pt data=coco8.yaml epochs=100 imgsz=640 + + # Load a COCO-pretrained YOLOv8n model and run inference on the 'bus.jpg' image + yolo predict model=yolov8n.pt source=path/to/bus.jpg + ``` + +## Citations and Acknowledgements + +If you use the YOLOv8 model or any other software from this repository in your work, please cite it using the following format: + +!!! note "" + + === "BibTeX" + + ```bibtex + @software{yolov8_ultralytics, + author = {Glenn Jocher and Ayush Chaurasia and Jing Qiu}, + title = {Ultralytics YOLOv8}, + version = {8.0.0}, + year = {2023}, + url = {https://github.com/ultralytics/ultralytics}, + orcid = {0000-0001-5950-6979, 0000-0002-7603-6750, 0000-0003-3783-7069}, + license = {AGPL-3.0} + } + ``` + +Please note that the DOI is pending and will be added to the citation once it is available. The usage of the software is in accordance with the AGPL-3.0 license. diff --git a/downloads/ultralytics-main/docs/modes/benchmark.md b/downloads/ultralytics-main/docs/modes/benchmark.md index a7600e055..1792277b8 100644 --- a/downloads/ultralytics-main/docs/modes/benchmark.md +++ b/downloads/ultralytics-main/docs/modes/benchmark.md @@ -1,6 +1,7 @@ --- comments: true -description: Benchmark mode compares speed and accuracy of various YOLOv8 export formats like ONNX or OpenVINO. Optimize formats for speed or accuracy. +description: Learn how to profile speed and accuracy of YOLOv8 across various export formats; get insights on mAP50-95, accuracy_top5 metrics, and more. +keywords: Ultralytics, YOLOv8, benchmarking, speed profiling, accuracy profiling, mAP50-95, accuracy_top5, ONNX, OpenVINO, TensorRT, YOLO export formats --- @@ -24,50 +25,52 @@ full list of export arguments. !!! example "" === "Python" - + ```python - from ultralytics.yolo.utils.benchmarks import benchmark - + from ultralytics.utils.benchmarks import benchmark + # Benchmark on GPU - benchmark(model='yolov8n.pt', imgsz=640, half=False, device=0) + benchmark(model='yolov8n.pt', data='coco8.yaml', imgsz=640, half=False, device=0) ``` === "CLI" - + ```bash - yolo benchmark model=yolov8n.pt imgsz=640 half=False device=0 + yolo benchmark model=yolov8n.pt data='coco8.yaml' imgsz=640 half=False device=0 ``` ## Arguments -Arguments such as `model`, `imgsz`, `half`, `device`, and `hard_fail` provide users with the flexibility to fine-tune +Arguments such as `model`, `data`, `imgsz`, `half`, `device`, and `verbose` provide users with the flexibility to fine-tune the benchmarks to their specific needs and compare the performance of different export formats with ease. -| Key | Value | Description | -|-------------|---------|----------------------------------------------------------------------| -| `model` | `None` | path to model file, i.e. yolov8n.pt, yolov8n.yaml | -| `imgsz` | `640` | image size as scalar or (h, w) list, i.e. (640, 480) | -| `half` | `False` | FP16 quantization | -| `int8` | `False` | INT8 quantization | -| `device` | `None` | device to run on, i.e. cuda device=0 or device=0,1,2,3 or device=cpu | -| `hard_fail` | `False` | do not continue on error (bool), or val floor threshold (float) | +| Key | Value | Description | +|-----------|---------|-----------------------------------------------------------------------| +| `model` | `None` | path to model file, i.e. yolov8n.pt, yolov8n.yaml | +| `data` | `None` | path to YAML referencing the benchmarking dataset (under `val` label) | +| `imgsz` | `640` | image size as scalar or (h, w) list, i.e. (640, 480) | +| `half` | `False` | FP16 quantization | +| `int8` | `False` | INT8 quantization | +| `device` | `None` | device to run on, i.e. cuda device=0 or device=0,1,2,3 or device=cpu | +| `verbose` | `False` | do not continue on error (bool), or val floor threshold (float) | ## Export Formats Benchmarks will attempt to run automatically on all possible export formats below. -| Format | `format` Argument | Model | Metadata | -|--------------------------------------------------------------------|-------------------|---------------------------|----------| -| [PyTorch](https://pytorch.org/) | - | `yolov8n.pt` | ✅ | -| [TorchScript](https://pytorch.org/docs/stable/jit.html) | `torchscript` | `yolov8n.torchscript` | ✅ | -| [ONNX](https://onnx.ai/) | `onnx` | `yolov8n.onnx` | ✅ | -| [OpenVINO](https://docs.openvino.ai/latest/index.html) | `openvino` | `yolov8n_openvino_model/` | ✅ | -| [TensorRT](https://developer.nvidia.com/tensorrt) | `engine` | `yolov8n.engine` | ✅ | -| [CoreML](https://github.com/apple/coremltools) | `coreml` | `yolov8n.mlmodel` | ✅ | -| [TF SavedModel](https://www.tensorflow.org/guide/saved_model) | `saved_model` | `yolov8n_saved_model/` | ✅ | -| [TF GraphDef](https://www.tensorflow.org/api_docs/python/tf/Graph) | `pb` | `yolov8n.pb` | ❌ | -| [TF Lite](https://www.tensorflow.org/lite) | `tflite` | `yolov8n.tflite` | ✅ | -| [TF Edge TPU](https://coral.ai/docs/edgetpu/models-intro/) | `edgetpu` | `yolov8n_edgetpu.tflite` | ✅ | -| [TF.js](https://www.tensorflow.org/js) | `tfjs` | `yolov8n_web_model/` | ✅ | -| [PaddlePaddle](https://github.com/PaddlePaddle) | `paddle` | `yolov8n_paddle_model/` | ✅ | +| Format | `format` Argument | Model | Metadata | Arguments | +|--------------------------------------------------------------------|-------------------|---------------------------|----------|-----------------------------------------------------| +| [PyTorch](https://pytorch.org/) | - | `yolov8n.pt` | ✅ | - | +| [TorchScript](https://pytorch.org/docs/stable/jit.html) | `torchscript` | `yolov8n.torchscript` | ✅ | `imgsz`, `optimize` | +| [ONNX](https://onnx.ai/) | `onnx` | `yolov8n.onnx` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `opset` | +| [OpenVINO](https://docs.openvino.ai/latest/index.html) | `openvino` | `yolov8n_openvino_model/` | ✅ | `imgsz`, `half` | +| [TensorRT](https://developer.nvidia.com/tensorrt) | `engine` | `yolov8n.engine` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `workspace` | +| [CoreML](https://github.com/apple/coremltools) | `coreml` | `yolov8n.mlpackage` | ✅ | `imgsz`, `half`, `int8`, `nms` | +| [TF SavedModel](https://www.tensorflow.org/guide/saved_model) | `saved_model` | `yolov8n_saved_model/` | ✅ | `imgsz`, `keras` | +| [TF GraphDef](https://www.tensorflow.org/api_docs/python/tf/Graph) | `pb` | `yolov8n.pb` | ❌ | `imgsz` | +| [TF Lite](https://www.tensorflow.org/lite) | `tflite` | `yolov8n.tflite` | ✅ | `imgsz`, `half`, `int8` | +| [TF Edge TPU](https://coral.ai/docs/edgetpu/models-intro/) | `edgetpu` | `yolov8n_edgetpu.tflite` | ✅ | `imgsz` | +| [TF.js](https://www.tensorflow.org/js) | `tfjs` | `yolov8n_web_model/` | ✅ | `imgsz` | +| [PaddlePaddle](https://github.com/PaddlePaddle) | `paddle` | `yolov8n_paddle_model/` | ✅ | `imgsz` | +| [ncnn](https://github.com/Tencent/ncnn) | `ncnn` | `yolov8n_ncnn_model/` | ✅ | `imgsz`, `half` | -See full `export` details in the [Export](https://docs.ultralytics.com/modes/export/) page. \ No newline at end of file +See full `export` details in the [Export](https://docs.ultralytics.com/modes/export/) page. diff --git a/downloads/ultralytics-main/docs/modes/export.md b/downloads/ultralytics-main/docs/modes/export.md index 2352cf491..76a2505f8 100644 --- a/downloads/ultralytics-main/docs/modes/export.md +++ b/downloads/ultralytics-main/docs/modes/export.md @@ -1,6 +1,7 @@ --- comments: true -description: 'Export mode: Create a deployment-ready YOLOv8 model by converting it to various formats. Export to ONNX or OpenVINO for up to 3x CPU speedup.' +description: Step-by-step guide on exporting your YOLOv8 models to various format like ONNX, TensorRT, CoreML and more for deployment. Explore now!. +keywords: YOLO, YOLOv8, Ultralytics, Model export, ONNX, TensorRT, CoreML, TensorFlow SavedModel, OpenVINO, PyTorch, export model --- @@ -22,19 +23,19 @@ export arguments. !!! example "" === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n.pt') # load an official model model = YOLO('path/to/best.pt') # load a custom trained - + # Export the model model.export(format='onnx') ``` === "CLI" - + ```bash yolo export model=yolov8n.pt format=onnx # export official model yolo export model=path/to/best.pt format=onnx # export custom trained model @@ -77,10 +78,11 @@ i.e. `format='onnx'` or `format='engine'`. | [ONNX](https://onnx.ai/) | `onnx` | `yolov8n.onnx` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `opset` | | [OpenVINO](https://docs.openvino.ai/latest/index.html) | `openvino` | `yolov8n_openvino_model/` | ✅ | `imgsz`, `half` | | [TensorRT](https://developer.nvidia.com/tensorrt) | `engine` | `yolov8n.engine` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `workspace` | -| [CoreML](https://github.com/apple/coremltools) | `coreml` | `yolov8n.mlmodel` | ✅ | `imgsz`, `half`, `int8`, `nms` | +| [CoreML](https://github.com/apple/coremltools) | `coreml` | `yolov8n.mlpackage` | ✅ | `imgsz`, `half`, `int8`, `nms` | | [TF SavedModel](https://www.tensorflow.org/guide/saved_model) | `saved_model` | `yolov8n_saved_model/` | ✅ | `imgsz`, `keras` | | [TF GraphDef](https://www.tensorflow.org/api_docs/python/tf/Graph) | `pb` | `yolov8n.pb` | ❌ | `imgsz` | | [TF Lite](https://www.tensorflow.org/lite) | `tflite` | `yolov8n.tflite` | ✅ | `imgsz`, `half`, `int8` | | [TF Edge TPU](https://coral.ai/docs/edgetpu/models-intro/) | `edgetpu` | `yolov8n_edgetpu.tflite` | ✅ | `imgsz` | | [TF.js](https://www.tensorflow.org/js) | `tfjs` | `yolov8n_web_model/` | ✅ | `imgsz` | -| [PaddlePaddle](https://github.com/PaddlePaddle) | `paddle` | `yolov8n_paddle_model/` | ✅ | `imgsz` | \ No newline at end of file +| [PaddlePaddle](https://github.com/PaddlePaddle) | `paddle` | `yolov8n_paddle_model/` | ✅ | `imgsz` | +| [ncnn](https://github.com/Tencent/ncnn) | `ncnn` | `yolov8n_ncnn_model/` | ✅ | `imgsz`, `half` | diff --git a/downloads/ultralytics-main/docs/modes/index.md b/downloads/ultralytics-main/docs/modes/index.md index 8e729bafc..1d0e7c41a 100644 --- a/downloads/ultralytics-main/docs/modes/index.md +++ b/downloads/ultralytics-main/docs/modes/index.md @@ -1,6 +1,7 @@ --- comments: true -description: Use Ultralytics YOLOv8 Modes (Train, Val, Predict, Export, Track, Benchmark) to train, validate, predict, track, export or benchmark. +description: From training to tracking, make the most of YOLOv8 with Ultralytics. Get insights and examples for each supported mode including validation, export, and benchmarking. +keywords: Ultralytics, YOLOv8, Machine Learning, Object Detection, Training, Validation, Prediction, Export, Tracking, Benchmarking --- # Ultralytics YOLOv8 Modes @@ -9,12 +10,12 @@ description: Use Ultralytics YOLOv8 Modes (Train, Val, Predict, Export, Track, B Ultralytics YOLOv8 supports several **modes** that can be used to perform different tasks. These modes are: -**Train**: For training a YOLOv8 model on a custom dataset. -**Val**: For validating a YOLOv8 model after it has been trained. -**Predict**: For making predictions using a trained YOLOv8 model on new images or videos. -**Export**: For exporting a YOLOv8 model to a format that can be used for deployment. -**Track**: For tracking objects in real-time using a YOLOv8 model. -**Benchmark**: For benchmarking YOLOv8 exports (ONNX, TensorRT, etc.) speed and accuracy. +- **Train**: For training a YOLOv8 model on a custom dataset. +- **Val**: For validating a YOLOv8 model after it has been trained. +- **Predict**: For making predictions using a trained YOLOv8 model on new images or videos. +- **Export**: For exporting a YOLOv8 model to a format that can be used for deployment. +- **Track**: For tracking objects in real-time using a YOLOv8 model. +- **Benchmark**: For benchmarking YOLOv8 exports (ONNX, TensorRT, etc.) speed and accuracy. ## [Train](train.md) @@ -64,4 +65,4 @@ or `accuracy_top5` metrics (for classification), and the inference time in milli formats like ONNX, OpenVINO, TensorRT and others. This information can help users choose the optimal export format for their specific use case based on their requirements for speed and accuracy. -[Benchmark Examples](benchmark.md){ .md-button .md-button--primary} \ No newline at end of file +[Benchmark Examples](benchmark.md){ .md-button .md-button--primary} diff --git a/downloads/ultralytics-main/docs/modes/predict.md b/downloads/ultralytics-main/docs/modes/predict.md index 51cb92113..e373d01a6 100644 --- a/downloads/ultralytics-main/docs/modes/predict.md +++ b/downloads/ultralytics-main/docs/modes/predict.md @@ -1,106 +1,336 @@ --- comments: true -description: Get started with YOLOv8 Predict mode and input sources. Accepts various input sources such as images, videos, and directories. +description: Discover how to use YOLOv8 predict mode for various tasks. Learn about different inference sources like images, videos, and data formats. +keywords: Ultralytics, YOLOv8, predict mode, inference sources, prediction tasks, streaming mode, image processing, video processing, machine learning, AI --- -YOLOv8 **predict mode** can generate predictions for various tasks, returning either a list of `Results` objects or a -memory-efficient generator of `Results` objects when using the streaming mode. Enable streaming mode by -passing `stream=True` in the predictor's call method. +YOLOv8 **predict mode** can generate predictions for various tasks, returning either a list of `Results` objects or a memory-efficient generator of `Results` objects when using the streaming mode. Enable streaming mode by passing `stream=True` in the predictor's call method. !!! example "Predict" - === "Return a list with `Stream=False`" + === "Return a list with `stream=False`" ```python - inputs = [img, img] # list of numpy arrays - results = model(inputs) # list of Results objects - + from ultralytics import YOLO + + # Load a model + model = YOLO('yolov8n.pt') # pretrained YOLOv8n model + + # Run batched inference on a list of images + results = model(['im1.jpg', 'im2.jpg']) # return a list of Results objects + + # Process results list for result in results: boxes = result.boxes # Boxes object for bbox outputs masks = result.masks # Masks object for segmentation masks outputs - probs = result.probs # Class probabilities for classification outputs + keypoints = result.keypoints # Keypoints object for pose outputs + probs = result.probs # Probs object for classification outputs ``` - === "Return a generator with `Stream=True`" + === "Return a generator with `stream=True`" ```python - inputs = [img, img] # list of numpy arrays - results = model(inputs, stream=True) # generator of Results objects - + from ultralytics import YOLO + + # Load a model + model = YOLO('yolov8n.pt') # pretrained YOLOv8n model + + # Run batched inference on a list of images + results = model(['im1.jpg', 'im2.jpg'], stream=True) # return a generator of Results objects + + # Process results generator for result in results: boxes = result.boxes # Boxes object for bbox outputs masks = result.masks # Masks object for segmentation masks outputs - probs = result.probs # Class probabilities for classification outputs + keypoints = result.keypoints # Keypoints object for pose outputs + probs = result.probs # Probs object for classification outputs ``` +## Inference Sources + +YOLOv8 can process different types of input sources for inference, as shown in the table below. The sources include static images, video streams, and various data formats. The table also indicates whether each source can be used in streaming mode with the argument `stream=True` ✅. Streaming mode is beneficial for processing videos or live streams as it creates a generator of results instead of loading all frames into memory. + !!! tip "Tip" - Streaming mode with `stream=True` should be used for long videos or large predict sources, otherwise results will accumuate in memory and will eventually cause out-of-memory errors. + Use `stream=True` for processing long videos or large datasets to efficiently manage memory. When `stream=False`, the results for all frames or data points are stored in memory, which can quickly add up and cause out-of-memory errors for large inputs. In contrast, `stream=True` utilizes a generator, which only keeps the results of the current frame or data point in memory, significantly reducing memory consumption and preventing out-of-memory issues. -## Sources +| Source | Argument | Type | Notes | +|---------------|--------------------------------------------|-----------------|---------------------------------------------------------------------------------------------| +| image | `'image.jpg'` | `str` or `Path` | Single image file. | +| URL | `'https://ultralytics.com/images/bus.jpg'` | `str` | URL to an image. | +| screenshot | `'screen'` | `str` | Capture a screenshot. | +| PIL | `Image.open('im.jpg')` | `PIL.Image` | HWC format with RGB channels. | +| OpenCV | `cv2.imread('im.jpg')` | `np.ndarray` | HWC format with BGR channels `uint8 (0-255)`. | +| numpy | `np.zeros((640,1280,3))` | `np.ndarray` | HWC format with BGR channels `uint8 (0-255)`. | +| torch | `torch.zeros(16,3,320,640)` | `torch.Tensor` | BCHW format with RGB channels `float32 (0.0-1.0)`. | +| CSV | `'sources.csv'` | `str` or `Path` | CSV file containing paths to images, videos, or directories. | +| video ✅ | `'video.mp4'` | `str` or `Path` | Video file in formats like MP4, AVI, etc. | +| directory ✅ | `'path/'` | `str` or `Path` | Path to a directory containing images or videos. | +| glob ✅ | `'path/*.jpg'` | `str` | Glob pattern to match multiple files. Use the `*` character as a wildcard. | +| YouTube ✅ | `'https://youtu.be/Zgi9g1ksQHc'` | `str` | URL to a YouTube video. | +| stream ✅ | `'rtsp://example.com/media.mp4'` | `str` | URL for streaming protocols such as RTSP, RTMP, or an IP address. | +| multi-stream ✅ | `'list.streams'` | `str` or `Path` | `*.streams` text file with one stream URL per row, i.e. 8 streams will run at batch-size 8. | -YOLOv8 can accept various input sources, as shown in the table below. This includes images, URLs, PIL images, OpenCV, -numpy arrays, torch tensors, CSV files, videos, directories, globs, YouTube videos, and streams. The table indicates -whether each source can be used in streaming mode with `stream=True` ✅ and an example argument for each source. +Below are code examples for using each source type: -| source | model(arg) | type | notes | -|-------------|--------------------------------------------|----------------|------------------| -| image | `'im.jpg'` | `str`, `Path` | | -| URL | `'https://ultralytics.com/images/bus.jpg'` | `str` | | -| screenshot | `'screen'` | `str` | | -| PIL | `Image.open('im.jpg')` | `PIL.Image` | HWC, RGB | -| OpenCV | `cv2.imread('im.jpg')` | `np.ndarray` | HWC, BGR | -| numpy | `np.zeros((640,1280,3))` | `np.ndarray` | HWC | -| torch | `torch.zeros(16,3,320,640)` | `torch.Tensor` | BCHW, RGB | -| CSV | `'sources.csv'` | `str`, `Path` | RTSP, RTMP, HTTP | -| video ✅ | `'vid.mp4'` | `str`, `Path` | | -| directory ✅ | `'path/'` | `str`, `Path` | | -| glob ✅ | `'path/*.jpg'` | `str` | Use `*` operator | -| YouTube ✅ | `'https://youtu.be/Zgi9g1ksQHc'` | `str` | | -| stream ✅ | `'rtsp://example.com/media.mp4'` | `str` | RTSP, RTMP, HTTP | +!!! example "Prediction sources" -## Arguments + === "image" + Run inference on an image file. + ```python + from ultralytics import YOLO + + # Load a pretrained YOLOv8n model + model = YOLO('yolov8n.pt') + + # Define path to the image file + source = 'path/to/image.jpg' + + # Run inference on the source + results = model(source) # list of Results objects + ``` + + === "screenshot" + Run inference on the current screen content as a screenshot. + ```python + from ultralytics import YOLO + + # Load a pretrained YOLOv8n model + model = YOLO('yolov8n.pt') + + # Define current screenshot as source + source = 'screen' + + # Run inference on the source + results = model(source) # list of Results objects + ``` + + === "URL" + Run inference on an image or video hosted remotely via URL. + ```python + from ultralytics import YOLO + + # Load a pretrained YOLOv8n model + model = YOLO('yolov8n.pt') + + # Define remote image or video URL + source = 'https://ultralytics.com/images/bus.jpg' + + # Run inference on the source + results = model(source) # list of Results objects + ``` + + === "PIL" + Run inference on an image opened with Python Imaging Library (PIL). + ```python + from PIL import Image + from ultralytics import YOLO + + # Load a pretrained YOLOv8n model + model = YOLO('yolov8n.pt') + + # Open an image using PIL + source = Image.open('path/to/image.jpg') + + # Run inference on the source + results = model(source) # list of Results objects + ``` + + === "OpenCV" + Run inference on an image read with OpenCV. + ```python + import cv2 + from ultralytics import YOLO + + # Load a pretrained YOLOv8n model + model = YOLO('yolov8n.pt') + + # Read an image using OpenCV + source = cv2.imread('path/to/image.jpg') + + # Run inference on the source + results = model(source) # list of Results objects + ``` + + === "numpy" + Run inference on an image represented as a numpy array. + ```python + import numpy as np + from ultralytics import YOLO + + # Load a pretrained YOLOv8n model + model = YOLO('yolov8n.pt') + + # Create a random numpy array of HWC shape (640, 640, 3) with values in range [0, 255] and type uint8 + source = np.random.randint(low=0, high=255, size=(640, 640, 3), dtype='uint8') + + # Run inference on the source + results = model(source) # list of Results objects + ``` + + === "torch" + Run inference on an image represented as a PyTorch tensor. + ```python + import torch + from ultralytics import YOLO + + # Load a pretrained YOLOv8n model + model = YOLO('yolov8n.pt') + + # Create a random torch tensor of BCHW shape (1, 3, 640, 640) with values in range [0, 1] and type float32 + source = torch.rand(1, 3, 640, 640, dtype=torch.float32) + + # Run inference on the source + results = model(source) # list of Results objects + ``` + + === "CSV" + Run inference on a collection of images, URLs, videos and directories listed in a CSV file. + ```python + import torch + from ultralytics import YOLO + + # Load a pretrained YOLOv8n model + model = YOLO('yolov8n.pt') + + # Define a path to a CSV file with images, URLs, videos and directories + source = 'path/to/file.csv' + + # Run inference on the source + results = model(source) # list of Results objects + ``` + + === "video" + Run inference on a video file. By using `stream=True`, you can create a generator of Results objects to reduce memory usage. + ```python + from ultralytics import YOLO + + # Load a pretrained YOLOv8n model + model = YOLO('yolov8n.pt') + + # Define path to video file + source = 'path/to/video.mp4' + + # Run inference on the source + results = model(source, stream=True) # generator of Results objects + ``` + + === "directory" + Run inference on all images and videos in a directory. To also capture images and videos in subdirectories use a glob pattern, i.e. `path/to/dir/**/*`. + ```python + from ultralytics import YOLO + + # Load a pretrained YOLOv8n model + model = YOLO('yolov8n.pt') + + # Define path to directory containing images and videos for inference + source = 'path/to/dir' + + # Run inference on the source + results = model(source, stream=True) # generator of Results objects + ``` + + === "glob" + Run inference on all images and videos that match a glob expression with `*` characters. + ```python + from ultralytics import YOLO + + # Load a pretrained YOLOv8n model + model = YOLO('yolov8n.pt') + + # Define a glob search for all JPG files in a directory + source = 'path/to/dir/*.jpg' + + # OR define a recursive glob search for all JPG files including subdirectories + source = 'path/to/dir/**/*.jpg' + + # Run inference on the source + results = model(source, stream=True) # generator of Results objects + ``` + + === "YouTube" + Run inference on a YouTube video. By using `stream=True`, you can create a generator of Results objects to reduce memory usage for long videos. + ```python + from ultralytics import YOLO + + # Load a pretrained YOLOv8n model + model = YOLO('yolov8n.pt') + + # Define source as YouTube video URL + source = 'https://youtu.be/Zgi9g1ksQHc' + + # Run inference on the source + results = model(source, stream=True) # generator of Results objects + ``` + + === "Streams" + Run inference on remote streaming sources using RTSP, RTMP, and IP address protocols. If mutliple streams are provided in a `*.streams` text file then batched inference will run, i.e. 8 streams will run at batch-size 8, otherwise single streams will run at batch-size 1. + ```python + from ultralytics import YOLO + + # Load a pretrained YOLOv8n model + model = YOLO('yolov8n.pt') + + # Single stream with batch-size 1 inference + source = 'rtsp://example.com/media.mp4' # RTSP, RTMP or IP streaming address + + # Multiple streams with batched inference (i.e. batch-size 8 for 8 streams) + source = 'path/to/list.streams' # *.streams text file with one streaming address per row + + # Run inference on the source + results = model(source, stream=True) # generator of Results objects + ``` + +## Inference Arguments + +`model.predict()` accepts multiple arguments that can be passed at inference time to override defaults: -`model.predict` accepts multiple arguments that control the prediction operation. These arguments can be passed directly to `model.predict`: !!! example - ``` - model.predict(source, save=True, imgsz=320, conf=0.5) + ```python + from ultralytics import YOLO + + # Load a pretrained YOLOv8n model + model = YOLO('yolov8n.pt') + + # Run inference on 'bus.jpg' with arguments + model.predict('bus.jpg', save=True, imgsz=320, conf=0.5) ``` All supported arguments: -| Key | Value | Description | -|----------------|------------------------|--------------------------------------------------------------------------------| -| `source` | `'ultralytics/assets'` | source directory for images or videos | -| `conf` | `0.25` | object confidence threshold for detection | -| `iou` | `0.7` | intersection over union (IoU) threshold for NMS | -| `half` | `False` | use half precision (FP16) | -| `device` | `None` | device to run on, i.e. cuda device=0/1/2/3 or device=cpu | -| `show` | `False` | show results if possible | -| `save` | `False` | save images with results | -| `save_txt` | `False` | save results as .txt file | -| `save_conf` | `False` | save results with confidence scores | -| `save_crop` | `False` | save cropped images with results | -| `hide_labels` | `False` | hide labels | -| `hide_conf` | `False` | hide confidence scores | -| `max_det` | `300` | maximum number of detections per image | -| `vid_stride` | `False` | video frame-rate stride | -| `line_width` | `None` | The line width of the bounding boxes. If None, it is scaled to the image size. | -| `visualize` | `False` | visualize model features | -| `augment` | `False` | apply image augmentation to prediction sources | -| `agnostic_nms` | `False` | class-agnostic NMS | -| `retina_masks` | `False` | use high-resolution segmentation masks | -| `classes` | `None` | filter results by class, i.e. class=0, or class=[0,2,3] | -| `boxes` | `True` | Show boxes in segmentation predictions | +| Name | Type | Default | Description | +|----------------|----------------|------------------------|--------------------------------------------------------------------------------| +| `source` | `str` | `'ultralytics/assets'` | source directory for images or videos | +| `conf` | `float` | `0.25` | object confidence threshold for detection | +| `iou` | `float` | `0.7` | intersection over union (IoU) threshold for NMS | +| `imgsz` | `int or tuple` | `640` | image size as scalar or (h, w) list, i.e. (640, 480) | +| `half` | `bool` | `False` | use half precision (FP16) | +| `device` | `None or str` | `None` | device to run on, i.e. cuda device=0/1/2/3 or device=cpu | +| `show` | `bool` | `False` | show results if possible | +| `save` | `bool` | `False` | save images with results | +| `save_txt` | `bool` | `False` | save results as .txt file | +| `save_conf` | `bool` | `False` | save results with confidence scores | +| `save_crop` | `bool` | `False` | save cropped images with results | +| `hide_labels` | `bool` | `False` | hide labels | +| `hide_conf` | `bool` | `False` | hide confidence scores | +| `max_det` | `int` | `300` | maximum number of detections per image | +| `vid_stride` | `bool` | `False` | video frame-rate stride | +| `line_width` | `None or int` | `None` | The line width of the bounding boxes. If None, it is scaled to the image size. | +| `visualize` | `bool` | `False` | visualize model features | +| `augment` | `bool` | `False` | apply image augmentation to prediction sources | +| `agnostic_nms` | `bool` | `False` | class-agnostic NMS | +| `retina_masks` | `bool` | `False` | use high-resolution segmentation masks | +| `classes` | `None or list` | `None` | filter results by class, i.e. classes=0, or classes=[0,2,3] | +| `boxes` | `bool` | `True` | Show boxes in segmentation predictions | ## Image and Video Formats -YOLOv8 supports various image and video formats, as specified -in [yolo/data/utils.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/yolo/data/utils.py). See the -tables below for the valid suffixes and example predict commands. +YOLOv8 supports various image and video formats, as specified in [data/utils.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/data/utils.py). See the tables below for the valid suffixes and example predict commands. -### Image Suffixes +### Images + +The below table contains valid Ultralytics image formats. | Image Suffixes | Example Predict Command | Reference | |----------------|----------------------------------|-------------------------------------------------------------------------------| @@ -115,7 +345,9 @@ tables below for the valid suffixes and example predict commands. | .webp | `yolo predict source=image.webp` | [WebP](https://en.wikipedia.org/wiki/WebP) | | .pfm | `yolo predict source=image.pfm` | [Portable FloatMap](https://en.wikipedia.org/wiki/Netpbm#File_formats) | -### Video Suffixes +### Videos + +The below table contains valid Ultralytics video formats. | Video Suffixes | Example Predict Command | Reference | |----------------|----------------------------------|----------------------------------------------------------------------------------| @@ -134,149 +366,280 @@ tables below for the valid suffixes and example predict commands. ## Working with Results -The `Results` object contains the following components: - -- `Results.boxes`: `Boxes` object with properties and methods for manipulating bounding boxes -- `Results.masks`: `Masks` object for indexing masks or getting segment coordinates -- `Results.probs`: `torch.Tensor` containing class probabilities or logits -- `Results.orig_img`: Original image loaded in memory -- `Results.path`: `Path` containing the path to the input image - -Each result is composed of a `torch.Tensor` by default, which allows for easy manipulation: +All Ultralytics `predict()` calls will return a list of `Results` objects: !!! example "Results" ```python - results = results.cuda() - results = results.cpu() - results = results.to('cpu') - results = results.numpy() + from ultralytics import YOLO + + # Load a pretrained YOLOv8n model + model = YOLO('yolov8n.pt') + + # Run inference on an image + results = model('bus.jpg') # list of 1 Results object + results = model(['bus.jpg', 'zidane.jpg']) # list of 2 Results objects ``` +`Results` objects have the following attributes: + +| Attribute | Type | Description | +|--------------|-----------------------|------------------------------------------------------------------------------------------| +| `orig_img` | `numpy.ndarray` | The original image as a numpy array. | +| `orig_shape` | `tuple` | The original image shape in (height, width) format. | +| `boxes` | `Boxes, optional` | A Boxes object containing the detection bounding boxes. | +| `masks` | `Masks, optional` | A Masks object containing the detection masks. | +| `probs` | `Probs, optional` | A Probs object containing probabilities of each class for classification task. | +| `keypoints` | `Keypoints, optional` | A Keypoints object containing detected keypoints for each object. | +| `speed` | `dict` | A dictionary of preprocess, inference, and postprocess speeds in milliseconds per image. | +| `names` | `dict` | A dictionary of class names. | +| `path` | `str` | The path to the image file. | + +`Results` objects have the following methods: + +| Method | Return Type | Description | +|-----------------|-----------------|-------------------------------------------------------------------------------------| +| `__getitem__()` | `Results` | Return a Results object for the specified index. | +| `__len__()` | `int` | Return the number of detections in the Results object. | +| `update()` | `None` | Update the boxes, masks, and probs attributes of the Results object. | +| `cpu()` | `Results` | Return a copy of the Results object with all tensors on CPU memory. | +| `numpy()` | `Results` | Return a copy of the Results object with all tensors as numpy arrays. | +| `cuda()` | `Results` | Return a copy of the Results object with all tensors on GPU memory. | +| `to()` | `Results` | Return a copy of the Results object with tensors on the specified device and dtype. | +| `new()` | `Results` | Return a new Results object with the same image, path, and names. | +| `keys()` | `List[str]` | Return a list of non-empty attribute names. | +| `plot()` | `numpy.ndarray` | Plots the detection results. Returns a numpy array of the annotated image. | +| `verbose()` | `str` | Return log string for each task. | +| `save_txt()` | `None` | Save predictions into a txt file. | +| `save_crop()` | `None` | Save cropped predictions to `save_dir/cls/file_name.jpg`. | +| `tojson()` | `None` | Convert the object to JSON format. | + +For more details see the `Results` class [documentation](../reference/engine/results.md). + ### Boxes -`Boxes` object can be used to index, manipulate, and convert bounding boxes to different formats. Box format conversion -operations are cached, meaning they're only calculated once per object, and those values are reused for future calls. - -- Indexing a `Boxes` object returns a `Boxes` object: +`Boxes` object can be used to index, manipulate, and convert bounding boxes to different formats. !!! example "Boxes" ```python - results = model(img) - boxes = results[0].boxes - box = boxes[0] # returns one box - box.xyxy + from ultralytics import YOLO + + # Load a pretrained YOLOv8n model + model = YOLO('yolov8n.pt') + + # Run inference on an image + results = model('bus.jpg') # results list + + # View results + for r in results: + print(r.boxes) # print the Boxes object containing the detection bounding boxes ``` -- Properties and conversions +Here is a table for the `Boxes` class methods and properties, including their name, type, and description: -!!! example "Boxes Properties" +| Name | Type | Description | +|-----------|---------------------------|--------------------------------------------------------------------| +| `cpu()` | Method | Move the object to CPU memory. | +| `numpy()` | Method | Convert the object to a numpy array. | +| `cuda()` | Method | Move the object to CUDA memory. | +| `to()` | Method | Move the object to the specified device. | +| `xyxy` | Property (`torch.Tensor`) | Return the boxes in xyxy format. | +| `conf` | Property (`torch.Tensor`) | Return the confidence values of the boxes. | +| `cls` | Property (`torch.Tensor`) | Return the class values of the boxes. | +| `id` | Property (`torch.Tensor`) | Return the track IDs of the boxes (if available). | +| `xywh` | Property (`torch.Tensor`) | Return the boxes in xywh format. | +| `xyxyn` | Property (`torch.Tensor`) | Return the boxes in xyxy format normalized by original image size. | +| `xywhn` | Property (`torch.Tensor`) | Return the boxes in xywh format normalized by original image size. | - ```python - boxes.xyxy # box with xyxy format, (N, 4) - boxes.xywh # box with xywh format, (N, 4) - boxes.xyxyn # box with xyxy format but normalized, (N, 4) - boxes.xywhn # box with xywh format but normalized, (N, 4) - boxes.conf # confidence score, (N, 1) - boxes.cls # cls, (N, 1) - boxes.data # raw bboxes tensor, (N, 6) or boxes.boxes - ``` +For more details see the `Boxes` class [documentation](../reference/engine/results.md). ### Masks -`Masks` object can be used index, manipulate and convert masks to segments. The segment conversion operation is cached. +`Masks` object can be used index, manipulate and convert masks to segments. !!! example "Masks" ```python - results = model(inputs) - masks = results[0].masks # Masks object - masks.xy # x, y segments (pixels), List[segment] * N - masks.xyn # x, y segments (normalized), List[segment] * N - masks.data # raw masks tensor, (N, H, W) or masks.masks + from ultralytics import YOLO + + # Load a pretrained YOLOv8n-seg Segment model + model = YOLO('yolov8n-seg.pt') + + # Run inference on an image + results = model('bus.jpg') # results list + + # View results + for r in results: + print(r.masks) # print the Masks object containing the detected instance masks ``` -### probs +Here is a table for the `Masks` class methods and properties, including their name, type, and description: -`probs` attribute of `Results` class is a `Tensor` containing class probabilities of a classification operation. +| Name | Type | Description | +|-----------|---------------------------|-----------------------------------------------------------------| +| `cpu()` | Method | Returns the masks tensor on CPU memory. | +| `numpy()` | Method | Returns the masks tensor as a numpy array. | +| `cuda()` | Method | Returns the masks tensor on GPU memory. | +| `to()` | Method | Returns the masks tensor with the specified device and dtype. | +| `xyn` | Property (`torch.Tensor`) | A list of normalized segments represented as tensors. | +| `xy` | Property (`torch.Tensor`) | A list of segments in pixel coordinates represented as tensors. | + +For more details see the `Masks` class [documentation](../reference/engine/results.md). + +### Keypoints + +`Keypoints` object can be used index, manipulate and normalize coordinates. + +!!! example "Keypoints" + + ```python + from ultralytics import YOLO + + # Load a pretrained YOLOv8n-pose Pose model + model = YOLO('yolov8n-pose.pt') + + # Run inference on an image + results = model('bus.jpg') # results list + + # View results + for r in results: + print(r.keypoints) # print the Keypoints object containing the detected keypoints + ``` + +Here is a table for the `Keypoints` class methods and properties, including their name, type, and description: + +| Name | Type | Description | +|-----------|---------------------------|-------------------------------------------------------------------| +| `cpu()` | Method | Returns the keypoints tensor on CPU memory. | +| `numpy()` | Method | Returns the keypoints tensor as a numpy array. | +| `cuda()` | Method | Returns the keypoints tensor on GPU memory. | +| `to()` | Method | Returns the keypoints tensor with the specified device and dtype. | +| `xyn` | Property (`torch.Tensor`) | A list of normalized keypoints represented as tensors. | +| `xy` | Property (`torch.Tensor`) | A list of keypoints in pixel coordinates represented as tensors. | +| `conf` | Property (`torch.Tensor`) | Returns confidence values of keypoints if available, else None. | + +For more details see the `Keypoints` class [documentation](../reference/engine/results.md). + +### Probs + +`Probs` object can be used index, get `top1` and `top5` indices and scores of classification. !!! example "Probs" ```python - results = model(inputs) - results[0].probs # cls prob, (num_class, ) + from ultralytics import YOLO + + # Load a pretrained YOLOv8n-cls Classify model + model = YOLO('yolov8n-cls.pt') + + # Run inference on an image + results = model('bus.jpg') # results list + + # View results + for r in results: + print(r.probs) # print the Probs object containing the detected class probabilities ``` -Class reference documentation for `Results` module and its components can be found [here](../reference/yolo/engine/results.md) +Here's a table summarizing the methods and properties for the `Probs` class: -## Plotting results +| Name | Type | Description | +|------------|---------------------------|-------------------------------------------------------------------------| +| `cpu()` | Method | Returns a copy of the probs tensor on CPU memory. | +| `numpy()` | Method | Returns a copy of the probs tensor as a numpy array. | +| `cuda()` | Method | Returns a copy of the probs tensor on GPU memory. | +| `to()` | Method | Returns a copy of the probs tensor with the specified device and dtype. | +| `top1` | Property (`int`) | Index of the top 1 class. | +| `top5` | Property (`list[int]`) | Indices of the top 5 classes. | +| `top1conf` | Property (`torch.Tensor`) | Confidence of the top 1 class. | +| `top5conf` | Property (`torch.Tensor`) | Confidences of the top 5 classes. | -You can use `plot()` function of `Result` object to plot results on in image object. It plots all components(boxes, -masks, classification logits, etc.) found in the results object +For more details see the `Probs` class [documentation](../reference/engine/results.md). + +## Plotting Results + +You can use the `plot()` method of a `Result` objects to visualize predictions. It plots all prediction types (boxes, masks, keypoints, probabilities, etc.) contained in the `Results` object onto a numpy array that can then be shown or saved. !!! example "Plotting" ```python - res = model(img) - res_plotted = res[0].plot() - cv2.imshow("result", res_plotted) - ``` + from PIL import Image + from ultralytics import YOLO -| Argument | Description | -|-------------------------------|----------------------------------------------------------------------------------------| -| `conf (bool)` | Whether to plot the detection confidence score. | -| `line_width (int, optional)` | The line width of the bounding boxes. If None, it is scaled to the image size. | -| `font_size (float, optional)` | The font size of the text. If None, it is scaled to the image size. | -| `font (str)` | The font to use for the text. | -| `pil (bool)` | Whether to use PIL for image plotting. | -| `example (str)` | An example string to display. Useful for indicating the expected format of the output. | -| `img (numpy.ndarray)` | Plot to another image. if not, plot to original image. | -| `labels (bool)` | Whether to plot the label of bounding boxes. | -| `boxes (bool)` | Whether to plot the bounding boxes. | -| `masks (bool)` | Whether to plot the masks. | -| `probs (bool)` | Whether to plot classification probability. | + # Load a pretrained YOLOv8n model + model = YOLO('yolov8n.pt') + + # Run inference on 'bus.jpg' + results = model('bus.jpg') # results list + + # Show the results + for r in results: + im_array = r.plot() # plot a BGR numpy array of predictions + im = Image.fromarray(im_array[..., ::-1]) # RGB PIL image + im.show() # show image + im.save('results.jpg') # save image + ``` + + The `plot()` method supports the following arguments: + + | Argument | Type | Description | Default | + |--------------|-----------------|--------------------------------------------------------------------------------|---------------| + | `conf` | `bool` | Whether to plot the detection confidence score. | `True` | + | `line_width` | `float` | The line width of the bounding boxes. If None, it is scaled to the image size. | `None` | + | `font_size` | `float` | The font size of the text. If None, it is scaled to the image size. | `None` | + | `font` | `str` | The font to use for the text. | `'Arial.ttf'` | + | `pil` | `bool` | Whether to return the image as a PIL Image. | `False` | + | `img` | `numpy.ndarray` | Plot to another image. if not, plot to original image. | `None` | + | `im_gpu` | `torch.Tensor` | Normalized image in gpu with shape (1, 3, 640, 640), for faster mask plotting. | `None` | + | `kpt_radius` | `int` | Radius of the drawn keypoints. Default is 5. | `5` | + | `kpt_line` | `bool` | Whether to draw lines connecting keypoints. | `True` | + | `labels` | `bool` | Whether to plot the label of bounding boxes. | `True` | + | `boxes` | `bool` | Whether to plot the bounding boxes. | `True` | + | `masks` | `bool` | Whether to plot the masks. | `True` | + | `probs` | `bool` | Whether to plot classification probability | `True` | ## Streaming Source `for`-loop -Here's a Python script using OpenCV (cv2) and YOLOv8 to run inference on video frames. This script assumes you have already installed the necessary packages (opencv-python and ultralytics). +Here's a Python script using OpenCV (`cv2`) and YOLOv8 to run inference on video frames. This script assumes you have already installed the necessary packages (`opencv-python` and `ultralytics`). !!! example "Streaming for-loop" ```python import cv2 from ultralytics import YOLO - + # Load the YOLOv8 model model = YOLO('yolov8n.pt') - + # Open the video file video_path = "path/to/your/video/file.mp4" cap = cv2.VideoCapture(video_path) - + # Loop through the video frames while cap.isOpened(): # Read a frame from the video success, frame = cap.read() - + if success: # Run YOLOv8 inference on the frame results = model(frame) - + # Visualize the results on the frame annotated_frame = results[0].plot() - + # Display the annotated frame cv2.imshow("YOLOv8 Inference", annotated_frame) - + # Break the loop if 'q' is pressed if cv2.waitKey(1) & 0xFF == ord("q"): break else: # Break the loop if the end of the video is reached break - + # Release the video capture object and close the display window cap.release() cv2.destroyAllWindows() ``` + +This script will run predictions on each frame of the video, visualize the results, and display them in a window. The loop can be exited by pressing 'q'. diff --git a/downloads/ultralytics-main/docs/modes/track.md b/downloads/ultralytics-main/docs/modes/track.md index 80c477f20..a8fa2129d 100644 --- a/downloads/ultralytics-main/docs/modes/track.md +++ b/downloads/ultralytics-main/docs/modes/track.md @@ -1,101 +1,286 @@ --- comments: true -description: Explore YOLOv8n-based object tracking with Ultralytics' BoT-SORT and ByteTrack. Learn configuration, usage, and customization tips. +description: Learn how to use Ultralytics YOLO for object tracking in video streams. Guides to use different trackers and customise tracker configurations. +keywords: Ultralytics, YOLO, object tracking, video streams, BoT-SORT, ByteTrack, Python guide, CLI guide --- - + -Object tracking is a task that involves identifying the location and class of objects, then assigning a unique ID to -that detection in video streams. +Object tracking is a task that involves identifying the location and class of objects, then assigning a unique ID to that detection in video streams. The output of tracker is the same as detection with an added object ID. ## Available Trackers -The following tracking algorithms have been implemented and can be enabled by passing `tracker=tracker_type.yaml` +Ultralytics YOLO supports the following tracking algorithms. They can be enabled by passing the relevant YAML configuration file such as `tracker=tracker_type.yaml`: -* [BoT-SORT](https://github.com/NirAharon/BoT-SORT) - `botsort.yaml` -* [ByteTrack](https://github.com/ifzhang/ByteTrack) - `bytetrack.yaml` +* [BoT-SORT](https://github.com/NirAharon/BoT-SORT) - Use `botsort.yaml` to enable this tracker. +* [ByteTrack](https://github.com/ifzhang/ByteTrack) - Use `bytetrack.yaml` to enable this tracker. The default tracker is BoT-SORT. ## Tracking -Use a trained YOLOv8n/YOLOv8n-seg model to run tracker on video streams. +To run the tracker on video streams, use a trained Detect, Segment or Pose model such as YOLOv8n, YOLOv8n-seg and YOLOv8n-pose. !!! example "" === "Python" - + ```python from ultralytics import YOLO - - # Load a model - model = YOLO('yolov8n.pt') # load an official detection model - model = YOLO('yolov8n-seg.pt') # load an official segmentation model - model = YOLO('path/to/best.pt') # load a custom model - - # Track with the model - results = model.track(source="https://youtu.be/Zgi9g1ksQHc", show=True) - results = model.track(source="https://youtu.be/Zgi9g1ksQHc", show=True, tracker="bytetrack.yaml") + + # Load an official or custom model + model = YOLO('yolov8n.pt') # Load an official Detect model + model = YOLO('yolov8n-seg.pt') # Load an official Segment model + model = YOLO('yolov8n-pose.pt') # Load an official Pose model + model = YOLO('path/to/best.pt') # Load a custom trained model + + # Perform tracking with the model + results = model.track(source="https://youtu.be/Zgi9g1ksQHc", show=True) # Tracking with default tracker + results = model.track(source="https://youtu.be/Zgi9g1ksQHc", show=True, tracker="bytetrack.yaml") # Tracking with ByteTrack tracker ``` + === "CLI" - - ```bash - yolo track model=yolov8n.pt source="https://youtu.be/Zgi9g1ksQHc" # official detection model - yolo track model=yolov8n-seg.pt source=... # official segmentation model - yolo track model=path/to/best.pt source=... # custom model - yolo track model=path/to/best.pt tracker="bytetrack.yaml" # bytetrack tracker + ```bash + # Perform tracking with various models using the command line interface + yolo track model=yolov8n.pt source="https://youtu.be/Zgi9g1ksQHc" # Official Detect model + yolo track model=yolov8n-seg.pt source="https://youtu.be/Zgi9g1ksQHc" # Official Segment model + yolo track model=yolov8n-pose.pt source="https://youtu.be/Zgi9g1ksQHc" # Official Pose model + yolo track model=path/to/best.pt source="https://youtu.be/Zgi9g1ksQHc" # Custom trained model + + # Track using ByteTrack tracker + yolo track model=path/to/best.pt tracker="bytetrack.yaml" ``` -As in the above usage, we support both the detection and segmentation models for tracking and the only thing you need to -do is loading the corresponding (detection or segmentation) model. +As can be seen in the above usage, tracking is available for all Detect, Segment and Pose models run on videos or streaming sources. ## Configuration -### Tracking +### Tracking Arguments + +Tracking configuration shares properties with Predict mode, such as `conf`, `iou`, and `show`. For further configurations, refer to the [Predict](https://docs.ultralytics.com/modes/predict/) model page. -Tracking shares the configuration with predict, i.e `conf`, `iou`, `show`. More configurations please refer -to [predict page](https://docs.ultralytics.com/modes/predict/). !!! example "" === "Python" - + ```python from ultralytics import YOLO - + + # Configure the tracking parameters and run the tracker model = YOLO('yolov8n.pt') - results = model.track(source="https://youtu.be/Zgi9g1ksQHc", conf=0.3, iou=0.5, show=True) + results = model.track(source="https://youtu.be/Zgi9g1ksQHc", conf=0.3, iou=0.5, show=True) ``` + === "CLI" - + ```bash + # Configure tracking parameters and run the tracker using the command line interface yolo track model=yolov8n.pt source="https://youtu.be/Zgi9g1ksQHc" conf=0.3, iou=0.5 show - ``` -### Tracker +### Tracker Selection + +Ultralytics also allows you to use a modified tracker configuration file. To do this, simply make a copy of a tracker config file (for example, `custom_tracker.yaml`) from [ultralytics/cfg/trackers](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/trackers) and modify any configurations (except the `tracker_type`) as per your needs. -We also support using a modified tracker config file, just copy a config file i.e `custom_tracker.yaml` -from [ultralytics/tracker/cfg](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/tracker/cfg) and modify -any configurations(expect the `tracker_type`) you need to. !!! example "" === "Python" - + ```python from ultralytics import YOLO - + + # Load the model and run the tracker with a custom configuration file model = YOLO('yolov8n.pt') - results = model.track(source="https://youtu.be/Zgi9g1ksQHc", tracker='custom_tracker.yaml') + results = model.track(source="https://youtu.be/Zgi9g1ksQHc", tracker='custom_tracker.yaml') ``` + === "CLI" - + ```bash + # Load the model and run the tracker with a custom configuration file using the command line interface yolo track model=yolov8n.pt source="https://youtu.be/Zgi9g1ksQHc" tracker='custom_tracker.yaml' ``` -Please refer to [ultralytics/tracker/cfg](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/tracker/cfg) -page +For a comprehensive list of tracking arguments, refer to the [ultralytics/cfg/trackers](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/trackers) page. +## Python Examples + +### Persisting Tracks Loop + +Here is a Python script using OpenCV (`cv2`) and YOLOv8 to run object tracking on video frames. This script still assumes you have already installed the necessary packages (`opencv-python` and `ultralytics`). + +!!! example "Streaming for-loop with tracking" + + ```python + import cv2 + from ultralytics import YOLO + + # Load the YOLOv8 model + model = YOLO('yolov8n.pt') + + # Open the video file + video_path = "path/to/video.mp4" + cap = cv2.VideoCapture(video_path) + + # Loop through the video frames + while cap.isOpened(): + # Read a frame from the video + success, frame = cap.read() + + if success: + # Run YOLOv8 tracking on the frame, persisting tracks between frames + results = model.track(frame, persist=True) + + # Visualize the results on the frame + annotated_frame = results[0].plot() + + # Display the annotated frame + cv2.imshow("YOLOv8 Tracking", annotated_frame) + + # Break the loop if 'q' is pressed + if cv2.waitKey(1) & 0xFF == ord("q"): + break + else: + # Break the loop if the end of the video is reached + break + + # Release the video capture object and close the display window + cap.release() + cv2.destroyAllWindows() + ``` + +Please note the change from `model(frame)` to `model.track(frame)`, which enables object tracking instead of simple detection. This modified script will run the tracker on each frame of the video, visualize the results, and display them in a window. The loop can be exited by pressing 'q'. + +### Plotting Tracks Over Time + +Visualizing object tracks over consecutive frames can provide valuable insights into the movement patterns and behavior of detected objects within a video. With Ultralytics YOLOv8, plotting these tracks is a seamless and efficient process. + +In the following example, we demonstrate how to utilize YOLOv8's tracking capabilities to plot the movement of detected objects across multiple video frames. This script involves opening a video file, reading it frame by frame, and utilizing the YOLO model to identify and track various objects. By retaining the center points of the detected bounding boxes and connecting them, we can draw lines that represent the paths followed by the tracked objects. + +!!! example "Plotting tracks over multiple video frames" + + ```python + from collections import defaultdict + + import cv2 + import numpy as np + + from ultralytics import YOLO + + # Load the YOLOv8 model + model = YOLO('yolov8n.pt') + + # Open the video file + video_path = "path/to/video.mp4" + cap = cv2.VideoCapture(video_path) + + # Store the track history + track_history = defaultdict(lambda: []) + + # Loop through the video frames + while cap.isOpened(): + # Read a frame from the video + success, frame = cap.read() + + if success: + # Run YOLOv8 tracking on the frame, persisting tracks between frames + results = model.track(frame, persist=True) + + # Get the boxes and track IDs + boxes = results[0].boxes.xywh.cpu() + track_ids = results[0].boxes.id.int().cpu().tolist() + + # Visualize the results on the frame + annotated_frame = results[0].plot() + + # Plot the tracks + for box, track_id in zip(boxes, track_ids): + x, y, w, h = box + track = track_history[track_id] + track.append((float(x), float(y))) # x, y center point + if len(track) > 30: # retain 90 tracks for 90 frames + track.pop(0) + + # Draw the tracking lines + points = np.hstack(track).astype(np.int32).reshape((-1, 1, 2)) + cv2.polylines(annotated_frame, [points], isClosed=False, color=(230, 230, 230), thickness=10) + + # Display the annotated frame + cv2.imshow("YOLOv8 Tracking", annotated_frame) + + # Break the loop if 'q' is pressed + if cv2.waitKey(1) & 0xFF == ord("q"): + break + else: + # Break the loop if the end of the video is reached + break + + # Release the video capture object and close the display window + cap.release() + cv2.destroyAllWindows() + ``` + +### Multithreaded Tracking + +Multithreaded tracking provides the capability to run object tracking on multiple video streams simultaneously. This is particularly useful when handling multiple video inputs, such as from multiple surveillance cameras, where concurrent processing can greatly enhance efficiency and performance. + +In the provided Python script, we make use of Python's `threading` module to run multiple instances of the tracker concurrently. Each thread is responsible for running the tracker on one video file, and all the threads run simultaneously in the background. + +To ensure that each thread receives the correct parameters (the video file and the model to use), we define a function `run_tracker_in_thread` that accepts these parameters and contains the main tracking loop. This function reads the video frame by frame, runs the tracker, and displays the results. + +Two different models are used in this example: `yolov8n.pt` and `yolov8n-seg.pt`, each tracking objects in a different video file. The video files are specified in `video_file1` and `video_file2`. + +The `daemon=True` parameter in `threading.Thread` means that these threads will be closed as soon as the main program finishes. We then start the threads with `start()` and use `join()` to make the main thread wait until both tracker threads have finished. + +Finally, after all threads have completed their task, the windows displaying the results are closed using `cv2.destroyAllWindows()`. + +!!! example "Streaming for-loop with tracking" + + ```python + import threading + + import cv2 + from ultralytics import YOLO + + + def run_tracker_in_thread(filename, model): + video = cv2.VideoCapture(filename) + frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT)) + for _ in range(frames): + ret, frame = video.read() + if ret: + results = model.track(source=frame, persist=True) + res_plotted = results[0].plot() + cv2.imshow('p', res_plotted) + if cv2.waitKey(1) == ord('q'): + break + + + # Load the models + model1 = YOLO('yolov8n.pt') + model2 = YOLO('yolov8n-seg.pt') + + # Define the video files for the trackers + video_file1 = 'path/to/video1.mp4' + video_file2 = 'path/to/video2.mp4' + + # Create the tracker threads + tracker_thread1 = threading.Thread(target=run_tracker_in_thread, args=(video_file1, model1), daemon=True) + tracker_thread2 = threading.Thread(target=run_tracker_in_thread, args=(video_file2, model2), daemon=True) + + # Start the tracker threads + tracker_thread1.start() + tracker_thread2.start() + + # Wait for the tracker threads to finish + tracker_thread1.join() + tracker_thread2.join() + + # Clean up and close windows + cv2.destroyAllWindows() + ``` + +This example can easily be extended to handle more video files and models by creating more threads and applying the same methodology. diff --git a/downloads/ultralytics-main/docs/modes/train.md b/downloads/ultralytics-main/docs/modes/train.md index 32186cddb..ad3b4642c 100644 --- a/downloads/ultralytics-main/docs/modes/train.md +++ b/downloads/ultralytics-main/docs/modes/train.md @@ -1,13 +1,12 @@ --- comments: true -description: Learn how to train custom YOLOv8 models on various datasets, configure hyperparameters, and use Ultralytics' YOLO for seamless training. +description: Step-by-step guide to train YOLOv8 models with Ultralytics YOLO with examples of single-GPU and multi-GPU training. Efficient way for object detection training. +keywords: Ultralytics, YOLOv8, YOLO, object detection, train mode, custom dataset, GPU training, multi-GPU, hyperparameters, CLI examples, Python examples --- -**Train mode** is used for training a YOLOv8 model on a custom dataset. In this mode, the model is trained using the -specified dataset and hyperparameters. The training process involves optimizing the model's parameters so that it can -accurately predict the classes and locations of objects in an image. +**Train mode** is used for training a YOLOv8 model on a custom dataset. In this mode, the model is trained using the specified dataset and hyperparameters. The training process involves optimizing the model's parameters so that it can accurately predict the classes and locations of objects in an image. !!! tip "Tip" @@ -15,26 +14,28 @@ accurately predict the classes and locations of objects in an image. ## Usage Examples -Train YOLOv8n on the COCO128 dataset for 100 epochs at image size 640. See Arguments section below for a full list of -training arguments. +Train YOLOv8n on the COCO128 dataset for 100 epochs at image size 640. See Arguments section below for a full list of training arguments. -!!! example "" +!!! example "Single-GPU and CPU Training Example" + + Device is determined automatically. If a GPU is available then it will be used, otherwise training will start on CPU. === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n.yaml') # build a new model from YAML model = YOLO('yolov8n.pt') # load a pretrained model (recommended for training) model = YOLO('yolov8n.yaml').load('yolov8n.pt') # build from YAML and transfer weights - + # Train the model - model.train(data='coco128.yaml', epochs=100, imgsz=640) + results = model.train(data='coco128.yaml', epochs=100, imgsz=640) ``` + === "CLI" - + ```bash # Build a new model from YAML and start training from scratch yolo detect train data=coco128.yaml model=yolov8n.yaml epochs=100 imgsz=640 @@ -46,57 +47,213 @@ training arguments. yolo detect train data=coco128.yaml model=yolov8n.yaml pretrained=yolov8n.pt epochs=100 imgsz=640 ``` +### Multi-GPU Training + +The training device can be specified using the `device` argument. If no argument is passed GPU `device=0` will be used if available, otherwise `device=cpu` will be used. + +!!! example "Multi-GPU Training Example" + + === "Python" + + ```python + from ultralytics import YOLO + + # Load a model + model = YOLO('yolov8n.pt') # load a pretrained model (recommended for training) + + # Train the model with 2 GPUs + results = model.train(data='coco128.yaml', epochs=100, imgsz=640, device=[0, 1]) + ``` + + === "CLI" + + ```bash + # Start training from a pretrained *.pt model using GPUs 0 and 1 + yolo detect train data=coco128.yaml model=yolov8n.pt epochs=100 imgsz=640 device=0,1 + ``` + +### Apple M1 and M2 MPS Training + +With the support for Apple M1 and M2 chips integrated in the Ultralytics YOLO models, it's now possible to train your models on devices utilizing the powerful Metal Performance Shaders (MPS) framework. The MPS offers a high-performance way of executing computation and image processing tasks on Apple's custom silicon. + +To enable training on Apple M1 and M2 chips, you should specify 'mps' as your device when initiating the training process. Below is an example of how you could do this in Python and via the command line: + +!!! example "MPS Training Example" + + === "Python" + + ```python + from ultralytics import YOLO + + # Load a model + model = YOLO('yolov8n.pt') # load a pretrained model (recommended for training) + + # Train the model with 2 GPUs + results = model.train(data='coco128.yaml', epochs=100, imgsz=640, device='mps') + ``` + + === "CLI" + + ```bash + # Start training from a pretrained *.pt model using GPUs 0 and 1 + yolo detect train data=coco128.yaml model=yolov8n.pt epochs=100 imgsz=640 device=mps + ``` + +While leveraging the computational power of the M1/M2 chips, this enables more efficient processing of the training tasks. For more detailed guidance and advanced configuration options, please refer to the [PyTorch MPS documentation](https://pytorch.org/docs/stable/notes/mps.html). + +### Resuming Interrupted Trainings + +Resuming training from a previously saved state is a crucial feature when working with deep learning models. This can come in handy in various scenarios, like when the training process has been unexpectedly interrupted, or when you wish to continue training a model with new data or for more epochs. + +When training is resumed, Ultralytics YOLO loads the weights from the last saved model and also restores the optimizer state, learning rate scheduler, and the epoch number. This allows you to continue the training process seamlessly from where it was left off. + +You can easily resume training in Ultralytics YOLO by setting the `resume` argument to `True` when calling the `train` method, and specifying the path to the `.pt` file containing the partially trained model weights. + +Below is an example of how to resume an interrupted training using Python and via the command line: + +!!! example "Resume Training Example" + + === "Python" + + ```python + from ultralytics import YOLO + + # Load a model + model = YOLO('path/to/last.pt') # load a partially trained model + + # Resume training + results = model.train(resume=True) + ``` + + === "CLI" + + ```bash + # Resume an interrupted training + yolo train resume model=path/to/last.pt + ``` + +By setting `resume=True`, the `train` function will continue training from where it left off, using the state stored in the 'path/to/last.pt' file. If the `resume` argument is omitted or set to `False`, the `train` function will start a new training session. + +Remember that checkpoints are saved at the end of every epoch by default, or at fixed interval using the `save_period` argument, so you must complete at least 1 epoch to resume a training run. + ## Arguments -Training settings for YOLO models refer to the various hyperparameters and configurations used to train the model on a -dataset. These settings can affect the model's performance, speed, and accuracy. Some common YOLO training settings -include the batch size, learning rate, momentum, and weight decay. Other factors that may affect the training process -include the choice of optimizer, the choice of loss function, and the size and composition of the training dataset. It -is important to carefully tune and experiment with these settings to achieve the best possible performance for a given -task. +Training settings for YOLO models refer to the various hyperparameters and configurations used to train the model on a dataset. These settings can affect the model's performance, speed, and accuracy. Some common YOLO training settings include the batch size, learning rate, momentum, and weight decay. Other factors that may affect the training process include the choice of optimizer, the choice of loss function, and the size and composition of the training dataset. It is important to carefully tune and experiment with these settings to achieve the best possible performance for a given task. -| Key | Value | Description | -|-------------------|----------|-----------------------------------------------------------------------------| -| `model` | `None` | path to model file, i.e. yolov8n.pt, yolov8n.yaml | -| `data` | `None` | path to data file, i.e. coco128.yaml | -| `epochs` | `100` | number of epochs to train for | -| `patience` | `50` | epochs to wait for no observable improvement for early stopping of training | -| `batch` | `16` | number of images per batch (-1 for AutoBatch) | -| `imgsz` | `640` | size of input images as integer or w,h | -| `save` | `True` | save train checkpoints and predict results | -| `save_period` | `-1` | Save checkpoint every x epochs (disabled if < 1) | -| `cache` | `False` | True/ram, disk or False. Use cache for data loading | -| `device` | `None` | device to run on, i.e. cuda device=0 or device=0,1,2,3 or device=cpu | -| `workers` | `8` | number of worker threads for data loading (per RANK if DDP) | -| `project` | `None` | project name | -| `name` | `None` | experiment name | -| `exist_ok` | `False` | whether to overwrite existing experiment | -| `pretrained` | `False` | whether to use a pretrained model | -| `optimizer` | `'SGD'` | optimizer to use, choices=['SGD', 'Adam', 'AdamW', 'RMSProp'] | -| `verbose` | `False` | whether to print verbose output | -| `seed` | `0` | random seed for reproducibility | -| `deterministic` | `True` | whether to enable deterministic mode | -| `single_cls` | `False` | train multi-class data as single-class | -| `rect` | `False` | rectangular training with each batch collated for minimum padding | -| `cos_lr` | `False` | use cosine learning rate scheduler | -| `close_mosaic` | `0` | (int) disable mosaic augmentation for final epochs | -| `resume` | `False` | resume training from last checkpoint | -| `amp` | `True` | Automatic Mixed Precision (AMP) training, choices=[True, False] | -| `lr0` | `0.01` | initial learning rate (i.e. SGD=1E-2, Adam=1E-3) | -| `lrf` | `0.01` | final learning rate (lr0 * lrf) | -| `momentum` | `0.937` | SGD momentum/Adam beta1 | -| `weight_decay` | `0.0005` | optimizer weight decay 5e-4 | -| `warmup_epochs` | `3.0` | warmup epochs (fractions ok) | -| `warmup_momentum` | `0.8` | warmup initial momentum | -| `warmup_bias_lr` | `0.1` | warmup initial bias lr | -| `box` | `7.5` | box loss gain | -| `cls` | `0.5` | cls loss gain (scale with pixels) | -| `dfl` | `1.5` | dfl loss gain | -| `pose` | `12.0` | pose loss gain (pose-only) | -| `kobj` | `2.0` | keypoint obj loss gain (pose-only) | -| `label_smoothing` | `0.0` | label smoothing (fraction) | -| `nbs` | `64` | nominal batch size | -| `overlap_mask` | `True` | masks should overlap during training (segment train only) | -| `mask_ratio` | `4` | mask downsample ratio (segment train only) | -| `dropout` | `0.0` | use dropout regularization (classify train only) | -| `val` | `True` | validate/test during training | +| Key | Value | Description | +|-------------------|----------|------------------------------------------------------------------------------------------------| +| `model` | `None` | path to model file, i.e. yolov8n.pt, yolov8n.yaml | +| `data` | `None` | path to data file, i.e. coco128.yaml | +| `epochs` | `100` | number of epochs to train for | +| `patience` | `50` | epochs to wait for no observable improvement for early stopping of training | +| `batch` | `16` | number of images per batch (-1 for AutoBatch) | +| `imgsz` | `640` | size of input images as integer | +| `save` | `True` | save train checkpoints and predict results | +| `save_period` | `-1` | Save checkpoint every x epochs (disabled if < 1) | +| `cache` | `False` | True/ram, disk or False. Use cache for data loading | +| `device` | `None` | device to run on, i.e. cuda device=0 or device=0,1,2,3 or device=cpu | +| `workers` | `8` | number of worker threads for data loading (per RANK if DDP) | +| `project` | `None` | project name | +| `name` | `None` | experiment name | +| `exist_ok` | `False` | whether to overwrite existing experiment | +| `pretrained` | `False` | whether to use a pretrained model | +| `optimizer` | `'auto'` | optimizer to use, choices=[SGD, Adam, Adamax, AdamW, NAdam, RAdam, RMSProp, auto] | +| `verbose` | `False` | whether to print verbose output | +| `seed` | `0` | random seed for reproducibility | +| `deterministic` | `True` | whether to enable deterministic mode | +| `single_cls` | `False` | train multi-class data as single-class | +| `rect` | `False` | rectangular training with each batch collated for minimum padding | +| `cos_lr` | `False` | use cosine learning rate scheduler | +| `close_mosaic` | `10` | (int) disable mosaic augmentation for final epochs (0 to disable) | +| `resume` | `False` | resume training from last checkpoint | +| `amp` | `True` | Automatic Mixed Precision (AMP) training, choices=[True, False] | +| `fraction` | `1.0` | dataset fraction to train on (default is 1.0, all images in train set) | +| `profile` | `False` | profile ONNX and TensorRT speeds during training for loggers | +| `freeze` | `None` | (int or list, optional) freeze first n layers, or freeze list of layer indices during training | +| `lr0` | `0.01` | initial learning rate (i.e. SGD=1E-2, Adam=1E-3) | +| `lrf` | `0.01` | final learning rate (lr0 * lrf) | +| `momentum` | `0.937` | SGD momentum/Adam beta1 | +| `weight_decay` | `0.0005` | optimizer weight decay 5e-4 | +| `warmup_epochs` | `3.0` | warmup epochs (fractions ok) | +| `warmup_momentum` | `0.8` | warmup initial momentum | +| `warmup_bias_lr` | `0.1` | warmup initial bias lr | +| `box` | `7.5` | box loss gain | +| `cls` | `0.5` | cls loss gain (scale with pixels) | +| `dfl` | `1.5` | dfl loss gain | +| `pose` | `12.0` | pose loss gain (pose-only) | +| `kobj` | `2.0` | keypoint obj loss gain (pose-only) | +| `label_smoothing` | `0.0` | label smoothing (fraction) | +| `nbs` | `64` | nominal batch size | +| `overlap_mask` | `True` | masks should overlap during training (segment train only) | +| `mask_ratio` | `4` | mask downsample ratio (segment train only) | +| `dropout` | `0.0` | use dropout regularization (classify train only) | +| `val` | `True` | validate/test during training | + +## Logging + +In training a YOLOv8 model, you might find it valuable to keep track of the model's performance over time. This is where logging comes into play. Ultralytics' YOLO provides support for three types of loggers - Comet, ClearML, and TensorBoard. + +To use a logger, select it from the dropdown menu in the code snippet above and run it. The chosen logger will be installed and initialized. + +### Comet + +[Comet](https://www.comet.ml/site/) is a platform that allows data scientists and developers to track, compare, explain and optimize experiments and models. It provides functionalities such as real-time metrics, code diffs, and hyperparameters tracking. + +To use Comet: + +!!! example "" + + === "Python" + ```python + # pip install comet_ml + import comet_ml + + comet_ml.init() + ``` + +Remember to sign in to your Comet account on their website and get your API key. You will need to add this to your environment variables or your script to log your experiments. + +### ClearML + +[ClearML](https://www.clear.ml/) is an open-source platform that automates tracking of experiments and helps with efficient sharing of resources. It is designed to help teams manage, execute, and reproduce their ML work more efficiently. + +To use ClearML: + +!!! example "" + + === "Python" + ```python + # pip install clearml + import clearml + + clearml.browser_login() + ``` + +After running this script, you will need to sign in to your ClearML account on the browser and authenticate your session. + +### TensorBoard + +[TensorBoard](https://www.tensorflow.org/tensorboard) is a visualization toolkit for TensorFlow. It allows you to visualize your TensorFlow graph, plot quantitative metrics about the execution of your graph, and show additional data like images that pass through it. + +To use TensorBoard in [Google Colab](https://colab.research.google.com/github/ultralytics/ultralytics/blob/main/examples/tutorial.ipynb): + +!!! example "" + + === "CLI" + ```bash + load_ext tensorboard + tensorboard --logdir ultralytics/runs # replace with 'runs' directory + ``` + +To use TensorBoard locally run the below command and view results at http://localhost:6006/. + +!!! example "" + + === "CLI" + ```bash + tensorboard --logdir ultralytics/runs # replace with 'runs' directory + ``` + +This will load TensorBoard and direct it to the directory where your training logs are saved. + +After setting up your logger, you can then proceed with your model training. All training metrics will be automatically logged in your chosen platform, and you can access these logs to monitor your model's performance over time, compare different models, and identify areas for improvement. diff --git a/downloads/ultralytics-main/docs/modes/val.md b/downloads/ultralytics-main/docs/modes/val.md index bc294ecbf..7677267cd 100644 --- a/downloads/ultralytics-main/docs/modes/val.md +++ b/downloads/ultralytics-main/docs/modes/val.md @@ -1,13 +1,12 @@ --- comments: true -description: Validate and improve YOLOv8n model accuracy on COCO128 and other datasets using hyperparameter & configuration tuning, in Val mode. +description: 'Guide for Validating YOLOv8 Models: Learn how to evaluate the performance of your YOLO models using validation settings and metrics with Python and CLI examples.' +keywords: Ultralytics, YOLO Docs, YOLOv8, validation, model evaluation, hyperparameters, accuracy, metrics, Python, CLI --- -**Val mode** is used for validating a YOLOv8 model after it has been trained. In this mode, the model is evaluated on a -validation set to measure its accuracy and generalization performance. This mode can be used to tune the hyperparameters -of the model to improve its performance. +**Val mode** is used for validating a YOLOv8 model after it has been trained. In this mode, the model is evaluated on a validation set to measure its accuracy and generalization performance. This mode can be used to tune the hyperparameters of the model to improve its performance. !!! tip "Tip" @@ -15,20 +14,19 @@ of the model to improve its performance. ## Usage Examples -Validate trained YOLOv8n model accuracy on the COCO128 dataset. No argument need to passed as the `model` retains it's -training `data` and arguments as model attributes. See Arguments section below for a full list of export arguments. +Validate trained YOLOv8n model accuracy on the COCO128 dataset. No argument need to passed as the `model` retains it's training `data` and arguments as model attributes. See Arguments section below for a full list of export arguments. !!! example "" === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n.pt') # load an official model model = YOLO('path/to/best.pt') # load a custom model - + # Validate the model metrics = model.val() # no arguments needed, dataset and settings remembered metrics.box.map # map50-95 @@ -37,7 +35,7 @@ training `data` and arguments as model attributes. See Arguments section below f metrics.box.maps # a list contains map50-95 of each category ``` === "CLI" - + ```bash yolo detect val model=yolov8n.pt # val official model yolo detect val model=path/to/best.pt # val custom model @@ -45,18 +43,12 @@ training `data` and arguments as model attributes. See Arguments section below f ## Arguments -Validation settings for YOLO models refer to the various hyperparameters and configurations used to -evaluate the model's performance on a validation dataset. These settings can affect the model's performance, speed, and -accuracy. Some common YOLO validation settings include the batch size, the frequency with which validation is performed -during training, and the metrics used to evaluate the model's performance. Other factors that may affect the validation -process include the size and composition of the validation dataset and the specific task the model is being used for. It -is important to carefully tune and experiment with these settings to ensure that the model is performing well on the -validation dataset and to detect and prevent overfitting. +Validation settings for YOLO models refer to the various hyperparameters and configurations used to evaluate the model's performance on a validation dataset. These settings can affect the model's performance, speed, and accuracy. Some common YOLO validation settings include the batch size, the frequency with which validation is performed during training, and the metrics used to evaluate the model's performance. Other factors that may affect the validation process include the size and composition of the validation dataset and the specific task the model is being used for. It is important to carefully tune and experiment with these settings to ensure that the model is performing well on the validation dataset and to detect and prevent overfitting. | Key | Value | Description | |---------------|---------|--------------------------------------------------------------------| | `data` | `None` | path to data file, i.e. coco128.yaml | -| `imgsz` | `640` | image size as scalar or (h, w) list, i.e. (640, 480) | +| `imgsz` | `640` | size of input images as integer | | `batch` | `16` | number of images per batch (-1 for AutoBatch) | | `save_json` | `False` | save results to JSON file | | `save_hybrid` | `False` | save hybrid version of labels (labels + additional predictions) | @@ -69,23 +61,4 @@ validation dataset and to detect and prevent overfitting. | `plots` | `False` | show plots during training | | `rect` | `False` | rectangular val with each batch collated for minimum padding | | `split` | `val` | dataset split to use for validation, i.e. 'val', 'test' or 'train' | - -## Export Formats - -Available YOLOv8 export formats are in the table below. You can export to any format using the `format` argument, -i.e. `format='onnx'` or `format='engine'`. - -| Format | `format` Argument | Model | Metadata | Arguments | -|--------------------------------------------------------------------|-------------------|---------------------------|----------|-----------------------------------------------------| -| [PyTorch](https://pytorch.org/) | - | `yolov8n.pt` | ✅ | - | -| [TorchScript](https://pytorch.org/docs/stable/jit.html) | `torchscript` | `yolov8n.torchscript` | ✅ | `imgsz`, `optimize` | -| [ONNX](https://onnx.ai/) | `onnx` | `yolov8n.onnx` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `opset` | -| [OpenVINO](https://docs.openvino.ai/latest/index.html) | `openvino` | `yolov8n_openvino_model/` | ✅ | `imgsz`, `half` | -| [TensorRT](https://developer.nvidia.com/tensorrt) | `engine` | `yolov8n.engine` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `workspace` | -| [CoreML](https://github.com/apple/coremltools) | `coreml` | `yolov8n.mlmodel` | ✅ | `imgsz`, `half`, `int8`, `nms` | -| [TF SavedModel](https://www.tensorflow.org/guide/saved_model) | `saved_model` | `yolov8n_saved_model/` | ✅ | `imgsz`, `keras` | -| [TF GraphDef](https://www.tensorflow.org/api_docs/python/tf/Graph) | `pb` | `yolov8n.pb` | ❌ | `imgsz` | -| [TF Lite](https://www.tensorflow.org/lite) | `tflite` | `yolov8n.tflite` | ✅ | `imgsz`, `half`, `int8` | -| [TF Edge TPU](https://coral.ai/docs/edgetpu/models-intro/) | `edgetpu` | `yolov8n_edgetpu.tflite` | ✅ | `imgsz` | -| [TF.js](https://www.tensorflow.org/js) | `tfjs` | `yolov8n_web_model/` | ✅ | `imgsz` | -| [PaddlePaddle](https://github.com/PaddlePaddle) | `paddle` | `yolov8n_paddle_model/` | ✅ | `imgsz` | \ No newline at end of file +| diff --git a/downloads/ultralytics-main/docs/overrides/partials/comments.html b/downloads/ultralytics-main/docs/overrides/partials/comments.html index ff1455b25..dcee5a9f1 100644 --- a/downloads/ultralytics-main/docs/overrides/partials/comments.html +++ b/downloads/ultralytics-main/docs/overrides/partials/comments.html @@ -11,7 +11,7 @@ data-strict="0" data-reactions-enabled="1" data-emit-metadata="0" - data-input-position="bottom" + data-input-position="top" data-theme="preferred_color_scheme" data-lang="en" crossorigin="anonymous" diff --git a/downloads/ultralytics-main/docs/quickstart.md b/downloads/ultralytics-main/docs/quickstart.md index b1fe2afc5..3ce7f2b8d 100644 --- a/downloads/ultralytics-main/docs/quickstart.md +++ b/downloads/ultralytics-main/docs/quickstart.md @@ -1,29 +1,85 @@ --- comments: true -description: Install and use YOLOv8 via CLI or Python. Run single-line commands or integrate with Python projects for object detection, segmentation, and classification. +description: Explore various methods to install Ultralytics using pip, conda, git and Docker. Learn how to use Ultralytics with command line interface or within your Python projects. +keywords: Ultralytics installation, pip install Ultralytics, Docker install Ultralytics, Ultralytics command line interface, Ultralytics Python interface --- -## Install +## Install Ultralytics -Install YOLOv8 via the `ultralytics` pip package for the latest stable release or by cloning -the [https://github.com/ultralytics/ultralytics](https://github.com/ultralytics/ultralytics) repository for the most -up-to-date version. +Ultralytics provides various installation methods including pip, conda, and Docker. Install YOLOv8 via the `ultralytics` pip package for the latest stable release or by cloning the [Ultralytics GitHub repository](https://github.com/ultralytics/ultralytics) for the most up-to-date version. Docker can be used to execute the package in an isolated container, avoiding local installation. !!! example "Install" - === "pip install (recommended)" + === "Pip install (recommended)" + Install the `ultralytics` package using pip, or update an existing installation by running `pip install -U ultralytics`. Visit the Python Package Index (PyPI) for more details on the `ultralytics` package: [https://pypi.org/project/ultralytics/](https://pypi.org/project/ultralytics/). + + [![PyPI version](https://badge.fury.io/py/ultralytics.svg)](https://badge.fury.io/py/ultralytics) [![Downloads](https://static.pepy.tech/badge/ultralytics)](https://pepy.tech/project/ultralytics) + ```bash + # Install the ultralytics package using pip pip install ultralytics ``` - === "git clone (for development)" + === "Conda install" + Conda is an alternative package manager to pip which may also be used for installation. Visit Anaconda for more details at [https://anaconda.org/conda-forge/ultralytics](https://anaconda.org/conda-forge/ultralytics). Ultralytics feedstock repository for updating the conda package is at [https://github.com/conda-forge/ultralytics-feedstock/](https://github.com/conda-forge/ultralytics-feedstock/). + + + [![Conda Recipe](https://img.shields.io/badge/recipe-ultralytics-green.svg)](https://anaconda.org/conda-forge/ultralytics) [![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/ultralytics.svg)](https://anaconda.org/conda-forge/ultralytics) [![Conda Version](https://img.shields.io/conda/vn/conda-forge/ultralytics.svg)](https://anaconda.org/conda-forge/ultralytics) [![Conda Platforms](https://img.shields.io/conda/pn/conda-forge/ultralytics.svg)](https://anaconda.org/conda-forge/ultralytics) + ```bash + # Install the ultralytics package using conda + conda install -c conda-forge ultralytics + ``` + + !!! note + + If you are installing in a CUDA environment best practice is to install `ultralytics`, `pytorch` and `pytorch-cuda` in the same command to allow the conda package manager to resolve any conflicts, or else to install `pytorch-cuda` last to allow it override the CPU-specific `pytorch` package if necesary. + ```bash + # Install all packages together using conda + conda install -c conda-forge -c pytorch -c nvidia ultralytics pytorch torchvision pytorch-cuda=11.8 + ``` + + === "Git clone" + Clone the `ultralytics` repository if you are interested in contributing to the development or wish to experiment with the latest source code. After cloning, navigate into the directory and install the package in editable mode `-e` using pip. + ```bash + # Clone the ultralytics repository git clone https://github.com/ultralytics/ultralytics + + # Navigate to the cloned directory cd ultralytics + + # Install the package in editable mode for development pip install -e . ``` -See the `ultralytics` [requirements.txt](https://github.com/ultralytics/ultralytics/blob/main/requirements.txt) file for a list of dependencies. Note that `pip` automatically installs all required dependencies. + === "Docker" + Utilize Docker to execute the `ultralytics` package in an isolated container. By employing the official `ultralytics` image from [Docker Hub](https://hub.docker.com/r/ultralytics/ultralytics), you can avoid local installation. Below are the commands to get the latest image and execute it: + + Docker Pulls + + ```bash + # Set image name as a variable + t=ultralytics/ultralytics:latest + + # Pull the latest ultralytics image from Docker Hub + sudo docker pull $t + + # Run the ultralytics image in a container with GPU support + sudo docker run -it --ipc=host --gpus all $t + ``` + + The above command initializes a Docker container with the latest `ultralytics` image. The `-it` flag assigns a pseudo-TTY and maintains stdin open, enabling you to interact with the container. The `--ipc=host` flag sets the IPC (Inter-Process Communication) namespace to the host, which is essential for sharing memory between processes. The `--gpus all` flag enables access to all available GPUs inside the container, which is crucial for tasks that require GPU computation. + + Note: To work with files on your local machine within the container, use Docker volumes for mounting a local directory into the container: + + ```bash + # Mount local directory to a directory inside the container + sudo docker run -it --ipc=host --gpus all -v /path/on/host:/path/in/container $t + ``` + + Alter `/path/on/host` with the directory path on your local machine, and `/path/in/container` with the desired path inside the Docker container for accessibility. + +See the `ultralytics` [requirements.txt](https://github.com/ultralytics/ultralytics/blob/main/requirements.txt) file for a list of dependencies. Note that all examples above install all required dependencies. !!! tip "Tip" @@ -33,9 +89,9 @@ See the `ultralytics` [requirements.txt](https://github.com/ultralytics/ultralyt PyTorch Installation Instructions -## Use with CLI +## Use Ultralytics with CLI -The YOLO command line interface (CLI) allows for simple single-line commands without the need for a Python environment. +The Ultralytics command line interface (CLI) allows for simple single-line commands without the need for a Python environment. CLI requires no customization or Python code. You can simply run all tasks from the terminal with the `yolo` command. Check out the [CLI Guide](usage/cli.md) to learn more about using YOLOv8 from the command line. !!! example @@ -102,7 +158,7 @@ CLI requires no customization or Python code. You can simply run all tasks from [CLI Guide](usage/cli.md){ .md-button .md-button--primary} -## Use with Python +## Use Ultralytics with Python YOLOv8's Python interface allows for seamless integration into your Python projects, making it easy to load, run, and process the model's output. Designed with simplicity and ease of use in mind, the Python interface enables users to quickly implement object detection, segmentation, and classification in their projects. This makes YOLOv8's Python interface an invaluable tool for anyone looking to incorporate these functionalities into their Python projects. @@ -112,24 +168,111 @@ For example, users can load a model, train it, evaluate its performance on a val ```python from ultralytics import YOLO - + # Create a new YOLO model from scratch model = YOLO('yolov8n.yaml') - + # Load a pretrained YOLO model (recommended for training) model = YOLO('yolov8n.pt') - + # Train the model using the 'coco128.yaml' dataset for 3 epochs results = model.train(data='coco128.yaml', epochs=3) - + # Evaluate the model's performance on the validation set results = model.val() - + # Perform object detection on an image using the model results = model('https://ultralytics.com/images/bus.jpg') - + # Export the model to ONNX format success = model.export(format='onnx') ``` -[Python Guide](usage/python.md){.md-button .md-button--primary} \ No newline at end of file +[Python Guide](usage/python.md){.md-button .md-button--primary} + +## Ultralytics Settings + +The Ultralytics library provides a powerful settings management system to enable fine-grained control over your experiments. By making use of the `SettingsManager` housed within the `ultralytics.utils` module, users can readily access and alter their settings. These are stored in a YAML file and can be viewed or modified either directly within the Python environment or via the Command-Line Interface (CLI). + +### Inspecting Settings + +To gain insight into the current configuration of your settings, you can view them directly: + +!!! example "View settings" + + === "Python" + You can use Python to view your settings. Start by importing the `settings` object from the `ultralytics` module. Print and return settings using the following commands: + ```python + from ultralytics import settings + + # View all settings + print(settings) + + # Return a specific setting + value = settings['runs_dir'] + ``` + + === "CLI" + Alternatively, the command-line interface allows you to check your settings with a simple command: + ```bash + yolo settings + ``` + +### Modifying Settings + +Ultralytics allows users to easily modify their settings. Changes can be performed in the following ways: + +!!! example "Update settings" + + === "Python" + Within the Python environment, call the `update` method on the `settings` object to change your settings: + ```python + from ultralytics import settings + + # Update a setting + settings.update({'runs_dir': '/path/to/runs'}) + + # Update multiple settings + settings.update({'runs_dir': '/path/to/runs', 'tensorboard': False}) + + # Reset settings to default values + settings.reset() + ``` + + === "CLI" + If you prefer using the command-line interface, the following commands will allow you to modify your settings: + ```bash + # Update a setting + yolo settings runs_dir='/path/to/runs' + + # Update multiple settings + yolo settings runs_dir='/path/to/runs' tensorboard=False + + # Reset settings to default values + yolo settings reset + ``` + +### Understanding Settings + +The table below provides an overview of the settings available for adjustment within Ultralytics. Each setting is outlined along with an example value, the data type, and a brief description. + +| Name | Example Value | Data Type | Description | +|--------------------|-----------------------|-----------|------------------------------------------------------------------------------------------------------------------| +| `settings_version` | `'0.0.4'` | `str` | Ultralytics _settings_ version (different from Ultralytics [pip](https://pypi.org/project/ultralytics/) version) | +| `datasets_dir` | `'/path/to/datasets'` | `str` | The directory where the datasets are stored | +| `weights_dir` | `'/path/to/weights'` | `str` | The directory where the model weights are stored | +| `runs_dir` | `'/path/to/runs'` | `str` | The directory where the experiment runs are stored | +| `uuid` | `'a1b2c3d4'` | `str` | The unique identifier for the current settings | +| `sync` | `True` | `bool` | Whether to sync analytics and crashes to HUB | +| `api_key` | `''` | `str` | Ultralytics HUB [API Key](https://hub.ultralytics.com/settings?tab=api+keys) | +| `clearml` | `True` | `bool` | Whether to use ClearML logging | +| `comet` | `True` | `bool` | Whether to use [Comet ML](https://bit.ly/yolov8-readme-comet) for experiment tracking and visualization | +| `dvc` | `True` | `bool` | Whether to use [DVC for experiment tracking](https://dvc.org/doc/dvclive/ml-frameworks/yolo) and version control | +| `hub` | `True` | `bool` | Whether to use [Ultralytics HUB](https://hub.ultralytics.com) integration | +| `mlflow` | `True` | `bool` | Whether to use MLFlow for experiment tracking | +| `neptune` | `True` | `bool` | Whether to use Neptune for experiment tracking | +| `raytune` | `True` | `bool` | Whether to use Ray Tune for hyperparameter tuning | +| `tensorboard` | `True` | `bool` | Whether to use TensorBoard for visualization | +| `wandb` | `True` | `bool` | Whether to use Weights & Biases logging | + +As you navigate through your projects or experiments, be sure to revisit these settings to ensure that they are optimally configured for your needs. diff --git a/downloads/ultralytics-main/docs/reference/cfg/__init__.md b/downloads/ultralytics-main/docs/reference/cfg/__init__.md new file mode 100644 index 000000000..d8d5f5323 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/cfg/__init__.md @@ -0,0 +1,54 @@ +--- +description: Explore Ultralytics cfg functions like cfg2dict, handle_deprecation, merge_equal_args & more to handle YOLO settings and configurations efficiently. +keywords: Ultralytics, YOLO, Configuration, cfg2dict, handle_deprecation, merge_equals_args, handle_yolo_settings, copy_default_cfg, Image Detection +--- + +# Reference for `ultralytics/cfg/__init__.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/__init__.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/__init__.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.cfg.cfg2dict +

+ +--- +## ::: ultralytics.cfg.get_cfg +

+ +--- +## ::: ultralytics.cfg._handle_deprecation +

+ +--- +## ::: ultralytics.cfg.check_dict_alignment +

+ +--- +## ::: ultralytics.cfg.merge_equals_args +

+ +--- +## ::: ultralytics.cfg.handle_yolo_hub +

+ +--- +## ::: ultralytics.cfg.handle_yolo_settings +

+ +--- +## ::: ultralytics.cfg.parse_key_value_pair +

+ +--- +## ::: ultralytics.cfg.smart_value +

+ +--- +## ::: ultralytics.cfg.entrypoint +

+ +--- +## ::: ultralytics.cfg.copy_default_cfg +

diff --git a/downloads/ultralytics-main/docs/reference/data/annotator.md b/downloads/ultralytics-main/docs/reference/data/annotator.md new file mode 100644 index 000000000..5b8398bac --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/data/annotator.md @@ -0,0 +1,14 @@ +--- +description: Enhance your machine learning model with Ultralytics’ auto_annotate function. Simplify data annotation for improved model training. +keywords: Ultralytics, Auto-Annotate, Machine Learning, AI, Annotation, Data Processing, Model Training +--- + +# Reference for `ultralytics/data/annotator.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/data/annotator.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/data/annotator.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.data.annotator.auto_annotate +

diff --git a/downloads/ultralytics-main/docs/reference/data/augment.md b/downloads/ultralytics-main/docs/reference/data/augment.md new file mode 100644 index 000000000..6b6a1a717 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/data/augment.md @@ -0,0 +1,86 @@ +--- +description: Detailed exploration into Ultralytics data augmentation methods including BaseTransform, MixUp, LetterBox, ToTensor, and more for enhancing model performance. +keywords: Ultralytics, Data Augmentation, BaseTransform, MixUp, RandomHSV, LetterBox, Albumentations, classify_transforms, classify_albumentations +--- + +# Reference for `ultralytics/data/augment.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/data/augment.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/data/augment.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.data.augment.BaseTransform +

+ +--- +## ::: ultralytics.data.augment.Compose +

+ +--- +## ::: ultralytics.data.augment.BaseMixTransform +

+ +--- +## ::: ultralytics.data.augment.Mosaic +

+ +--- +## ::: ultralytics.data.augment.MixUp +

+ +--- +## ::: ultralytics.data.augment.RandomPerspective +

+ +--- +## ::: ultralytics.data.augment.RandomHSV +

+ +--- +## ::: ultralytics.data.augment.RandomFlip +

+ +--- +## ::: ultralytics.data.augment.LetterBox +

+ +--- +## ::: ultralytics.data.augment.CopyPaste +

+ +--- +## ::: ultralytics.data.augment.Albumentations +

+ +--- +## ::: ultralytics.data.augment.Format +

+ +--- +## ::: ultralytics.data.augment.ClassifyLetterBox +

+ +--- +## ::: ultralytics.data.augment.CenterCrop +

+ +--- +## ::: ultralytics.data.augment.ToTensor +

+ +--- +## ::: ultralytics.data.augment.v8_transforms +

+ +--- +## ::: ultralytics.data.augment.classify_transforms +

+ +--- +## ::: ultralytics.data.augment.hsv2colorjitter +

+ +--- +## ::: ultralytics.data.augment.classify_albumentations +

diff --git a/downloads/ultralytics-main/docs/reference/data/base.md b/downloads/ultralytics-main/docs/reference/data/base.md new file mode 100644 index 000000000..25bd73bfb --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/data/base.md @@ -0,0 +1,14 @@ +--- +description: Explore BaseDataset in Ultralytics docs. Learn how this implementation simplifies dataset creation and manipulation. +keywords: Ultralytics, docs, BaseDataset, data manipulation, dataset creation +--- + +# Reference for `ultralytics/data/base.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/data/base.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/data/base.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.data.base.BaseDataset +

diff --git a/downloads/ultralytics-main/docs/reference/data/build.md b/downloads/ultralytics-main/docs/reference/data/build.md new file mode 100644 index 000000000..d49da96ea --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/data/build.md @@ -0,0 +1,38 @@ +--- +description: Explore the Ultralytics YOLO v3 data build procedures, including the InfiniteDataLoader, seed_worker, build_dataloader, and load_inference_source. +keywords: Ultralytics, YOLO v3, Data build, DataLoader, InfiniteDataLoader, seed_worker, build_dataloader, load_inference_source +--- + +# Reference for `ultralytics/data/build.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/data/build.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/data/build.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.data.build.InfiniteDataLoader +

+ +--- +## ::: ultralytics.data.build._RepeatSampler +

+ +--- +## ::: ultralytics.data.build.seed_worker +

+ +--- +## ::: ultralytics.data.build.build_yolo_dataset +

+ +--- +## ::: ultralytics.data.build.build_dataloader +

+ +--- +## ::: ultralytics.data.build.check_source +

+ +--- +## ::: ultralytics.data.build.load_inference_source +

diff --git a/downloads/ultralytics-main/docs/reference/data/converter.md b/downloads/ultralytics-main/docs/reference/data/converter.md new file mode 100644 index 000000000..266441908 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/data/converter.md @@ -0,0 +1,38 @@ +--- +description: Explore Ultralytics data converter functions like coco91_to_coco80_class, merge_multi_segment, rle2polygon for efficient data handling. +keywords: Ultralytics, Data Converter, coco91_to_coco80_class, merge_multi_segment, rle2polygon +--- + +# Reference for `ultralytics/data/converter.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/data/converter.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/data/converter.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.data.converter.coco91_to_coco80_class +

+ +--- +## ::: ultralytics.data.converter.coco80_to_coco91_class +

+ +--- +## ::: ultralytics.data.converter.convert_coco +

+ +--- +## ::: ultralytics.data.converter.convert_dota_to_yolo_obb +

+ +--- +## ::: ultralytics.data.converter.rle2polygon +

+ +--- +## ::: ultralytics.data.converter.min_index +

+ +--- +## ::: ultralytics.data.converter.merge_multi_segment +

diff --git a/downloads/ultralytics-main/docs/reference/data/dataset.md b/downloads/ultralytics-main/docs/reference/data/dataset.md new file mode 100644 index 000000000..182dfdede --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/data/dataset.md @@ -0,0 +1,22 @@ +--- +description: Explore the YOLODataset and SemanticDataset classes in YOLO data. Learn how to efficiently handle and manipulate your data with Ultralytics. +keywords: Ultralytics, YOLO, YOLODataset, SemanticDataset, data handling, data manipulation +--- + +# Reference for `ultralytics/data/dataset.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/data/dataset.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/data/dataset.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.data.dataset.YOLODataset +

+ +--- +## ::: ultralytics.data.dataset.ClassificationDataset +

+ +--- +## ::: ultralytics.data.dataset.SemanticDataset +

diff --git a/downloads/ultralytics-main/docs/reference/data/loaders.md b/downloads/ultralytics-main/docs/reference/data/loaders.md new file mode 100644 index 000000000..e52ed783d --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/data/loaders.md @@ -0,0 +1,42 @@ +--- +description: Find detailed guides on Ultralytics YOLO data loaders, including LoadStreams, LoadImages and LoadTensor. Learn how to get the best YouTube URLs. +keywords: Ultralytics, data loaders, LoadStreams, LoadImages, LoadTensor, YOLO, YouTube URLs +--- + +# Reference for `ultralytics/data/loaders.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/data/loaders.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/data/loaders.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.data.loaders.SourceTypes +

+ +--- +## ::: ultralytics.data.loaders.LoadStreams +

+ +--- +## ::: ultralytics.data.loaders.LoadScreenshots +

+ +--- +## ::: ultralytics.data.loaders.LoadImages +

+ +--- +## ::: ultralytics.data.loaders.LoadPilAndNumpy +

+ +--- +## ::: ultralytics.data.loaders.LoadTensor +

+ +--- +## ::: ultralytics.data.loaders.autocast_list +

+ +--- +## ::: ultralytics.data.loaders.get_best_youtube_url +

diff --git a/downloads/ultralytics-main/docs/reference/data/utils.md b/downloads/ultralytics-main/docs/reference/data/utils.md new file mode 100644 index 000000000..e514114af --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/data/utils.md @@ -0,0 +1,58 @@ +--- +description: Uncover a detailed guide to Ultralytics data utilities. Learn functions from img2label_paths to autosplit, all boosting your YOLO model’s efficiency. +keywords: Ultralytics, data utils, YOLO, img2label_paths, exif_size, polygon2mask, polygons2masks_overlap, check_cls_dataset, delete_dsstore, autosplit +--- + +# Reference for `ultralytics/data/utils.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/data/utils.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/data/utils.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.data.utils.HUBDatasetStats +

+ +--- +## ::: ultralytics.data.utils.img2label_paths +

+ +--- +## ::: ultralytics.data.utils.get_hash +

+ +--- +## ::: ultralytics.data.utils.exif_size +

+ +--- +## ::: ultralytics.data.utils.verify_image_label +

+ +--- +## ::: ultralytics.data.utils.polygon2mask +

+ +--- +## ::: ultralytics.data.utils.polygons2masks +

+ +--- +## ::: ultralytics.data.utils.polygons2masks_overlap +

+ +--- +## ::: ultralytics.data.utils.check_det_dataset +

+ +--- +## ::: ultralytics.data.utils.check_cls_dataset +

+ +--- +## ::: ultralytics.data.utils.compress_one_image +

+ +--- +## ::: ultralytics.data.utils.autosplit +

diff --git a/downloads/ultralytics-main/docs/reference/engine/exporter.md b/downloads/ultralytics-main/docs/reference/engine/exporter.md new file mode 100644 index 000000000..6650f8c9f --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/engine/exporter.md @@ -0,0 +1,30 @@ +--- +description: Explore the exporter functionality of Ultralytics. Learn about exporting formats, IOSDetectModel, and try exporting with examples. +keywords: Ultralytics, Exporter, IOSDetectModel, Export Formats, Try export +--- + +# Reference for `ultralytics/engine/exporter.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/engine/exporter.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/engine/exporter.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.engine.exporter.Exporter +

+ +--- +## ::: ultralytics.engine.exporter.IOSDetectModel +

+ +--- +## ::: ultralytics.engine.exporter.export_formats +

+ +--- +## ::: ultralytics.engine.exporter.gd_outputs +

+ +--- +## ::: ultralytics.engine.exporter.try_export +

diff --git a/downloads/ultralytics-main/docs/reference/engine/model.md b/downloads/ultralytics-main/docs/reference/engine/model.md new file mode 100644 index 000000000..934065ca6 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/engine/model.md @@ -0,0 +1,14 @@ +--- +description: Explore the detailed guide on using the Ultralytics YOLO Engine Model. Learn better ways to implement, train and evaluate YOLO models. +keywords: Ultralytics, YOLO, engine model, documentation, guide, implementation, training, evaluation +--- + +# Reference for `ultralytics/engine/model.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/engine/model.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/engine/model.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.engine.model.Model +

diff --git a/downloads/ultralytics-main/docs/reference/engine/predictor.md b/downloads/ultralytics-main/docs/reference/engine/predictor.md new file mode 100644 index 000000000..324bf0002 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/engine/predictor.md @@ -0,0 +1,14 @@ +--- +description: Learn about Ultralytics BasePredictor, an essential component of our engine that serves as the foundation for all prediction operations. +keywords: Ultralytics, BasePredictor, YOLO, prediction, engine +--- + +# Reference for `ultralytics/engine/predictor.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/engine/predictor.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/engine/predictor.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.engine.predictor.BasePredictor +

diff --git a/downloads/ultralytics-main/docs/reference/engine/results.md b/downloads/ultralytics-main/docs/reference/engine/results.md new file mode 100644 index 000000000..505efd97d --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/engine/results.md @@ -0,0 +1,34 @@ +--- +description: Master Ultralytics engine results including base tensors, boxes, and keypoints with our thorough documentation. +keywords: Ultralytics, engine, results, base tensor, boxes, keypoints +--- + +# Reference for `ultralytics/engine/results.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/engine/results.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/engine/results.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.engine.results.BaseTensor +

+ +--- +## ::: ultralytics.engine.results.Results +

+ +--- +## ::: ultralytics.engine.results.Boxes +

+ +--- +## ::: ultralytics.engine.results.Masks +

+ +--- +## ::: ultralytics.engine.results.Keypoints +

+ +--- +## ::: ultralytics.engine.results.Probs +

diff --git a/downloads/ultralytics-main/docs/reference/engine/trainer.md b/downloads/ultralytics-main/docs/reference/engine/trainer.md new file mode 100644 index 000000000..be007923d --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/engine/trainer.md @@ -0,0 +1,14 @@ +--- +description: Learn about the BaseTrainer class in the Ultralytics library. From training control, customization to advanced usage. +keywords: Ultralytics, BaseTrainer, Machine Learning, Training Control, Python library +--- + +# Reference for `ultralytics/engine/trainer.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/engine/trainer.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/engine/trainer.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.engine.trainer.BaseTrainer +

diff --git a/downloads/ultralytics-main/docs/reference/engine/validator.md b/downloads/ultralytics-main/docs/reference/engine/validator.md new file mode 100644 index 000000000..40493ef76 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/engine/validator.md @@ -0,0 +1,14 @@ +--- +description: Learn about the Ultralytics BaseValidator module. Understand its principles, uses, and how it interacts with other components. +keywords: Ultralytics, BaseValidator, Ultralytics engine, module, components +--- + +# Reference for `ultralytics/engine/validator.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/engine/validator.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/engine/validator.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.engine.validator.BaseValidator +

diff --git a/downloads/ultralytics-main/docs/reference/hub/__init__.md b/downloads/ultralytics-main/docs/reference/hub/__init__.md new file mode 100644 index 000000000..401936913 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/hub/__init__.md @@ -0,0 +1,38 @@ +--- +description: Explore Ultralytics hub functions for model resetting, checking datasets, model exporting and more. Easy-to-follow instructions provided. +keywords: Ultralytics, hub functions, model export, dataset check, reset model, YOLO Docs +--- + +# Reference for `ultralytics/hub/__init__.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/hub/__init__.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/hub/__init__.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.hub.login +

+ +--- +## ::: ultralytics.hub.logout +

+ +--- +## ::: ultralytics.hub.reset_model +

+ +--- +## ::: ultralytics.hub.export_fmts_hub +

+ +--- +## ::: ultralytics.hub.export_model +

+ +--- +## ::: ultralytics.hub.get_export +

+ +--- +## ::: ultralytics.hub.check_dataset +

diff --git a/downloads/ultralytics-main/docs/reference/hub/auth.md b/downloads/ultralytics-main/docs/reference/hub/auth.md index 6c1903070..b3609b10c 100644 --- a/downloads/ultralytics-main/docs/reference/hub/auth.md +++ b/downloads/ultralytics-main/docs/reference/hub/auth.md @@ -1,8 +1,14 @@ --- -description: Learn how to use Ultralytics hub authentication in your projects with examples and guidelines from the Auth page on Ultralytics Docs. +description: Dive into the Ultralytics Auth API documentation & learn how to manage authentication in your AI & ML projects easily and effectively. +keywords: Ultralytics, Auth, API documentation, User Authentication, AI, Machine Learning --- -# Auth +# Reference for `ultralytics/hub/auth.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/hub/auth.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/hub/auth.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + --- -:::ultralytics.hub.auth.Auth +## ::: ultralytics.hub.auth.Auth

diff --git a/downloads/ultralytics-main/docs/reference/hub/session.md b/downloads/ultralytics-main/docs/reference/hub/session.md index 2d7033340..2995dbc26 100644 --- a/downloads/ultralytics-main/docs/reference/hub/session.md +++ b/downloads/ultralytics-main/docs/reference/hub/session.md @@ -1,8 +1,14 @@ --- -description: Accelerate your AI development with the Ultralytics HUB Training Session. High-performance training of object detection models. +description: Explore details about the HUBTrainingSession in Ultralytics framework. Learn to utilize this functionality for effective model training. +keywords: Ultralytics, HUBTrainingSession, Documentation, Model Training, AI, Machine Learning, YOLO --- -# HUBTrainingSession +# Reference for `ultralytics/hub/session.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/hub/session.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/hub/session.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + --- -:::ultralytics.hub.session.HUBTrainingSession +## ::: ultralytics.hub.session.HUBTrainingSession

diff --git a/downloads/ultralytics-main/docs/reference/hub/utils.md b/downloads/ultralytics-main/docs/reference/hub/utils.md index 5b710580c..4dba9128d 100644 --- a/downloads/ultralytics-main/docs/reference/hub/utils.md +++ b/downloads/ultralytics-main/docs/reference/hub/utils.md @@ -1,23 +1,26 @@ --- -description: Explore Ultralytics events, including 'request_with_credentials' and 'smart_request', to improve your project's performance and efficiency. +description: Explore Ultralytics docs for various Events, including "request_with_credentials" and "requests_with_progress". Also, understand the use of the "smart_request". +keywords: Ultralytics, Events, request_with_credentials, smart_request, Ultralytics hub utils, requests_with_progress --- -# Events +# Reference for `ultralytics/hub/utils.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/hub/utils.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/hub/utils.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + --- -:::ultralytics.hub.utils.Events +## ::: ultralytics.hub.utils.Events

-# request_with_credentials --- -:::ultralytics.hub.utils.request_with_credentials +## ::: ultralytics.hub.utils.request_with_credentials

-# requests_with_progress --- -:::ultralytics.hub.utils.requests_with_progress +## ::: ultralytics.hub.utils.requests_with_progress

-# smart_request --- -:::ultralytics.hub.utils.smart_request +## ::: ultralytics.hub.utils.smart_request

diff --git a/downloads/ultralytics-main/docs/reference/models/fastsam/model.md b/downloads/ultralytics-main/docs/reference/models/fastsam/model.md new file mode 100644 index 000000000..692680290 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/fastsam/model.md @@ -0,0 +1,14 @@ +--- +description: Learn all about Ultralytics FastSAM model. Dive into our comprehensive guide for seamless integration and efficient model training. +keywords: Ultralytics, FastSAM model, Model documentation, Efficient model training +--- + +# Reference for `ultralytics/models/fastsam/model.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/fastsam/model.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/fastsam/model.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.fastsam.model.FastSAM +

diff --git a/downloads/ultralytics-main/docs/reference/models/fastsam/predict.md b/downloads/ultralytics-main/docs/reference/models/fastsam/predict.md new file mode 100644 index 000000000..8e984f35f --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/fastsam/predict.md @@ -0,0 +1,14 @@ +--- +description: Get detailed insights about Ultralytics FastSAMPredictor. Learn to predict and optimize your AI models with our properly documented guidelines. +keywords: Ultralytics, FastSAMPredictor, predictive modeling, AI optimization, machine learning, deep learning, Ultralytics documentation +--- + +# Reference for `ultralytics/models/fastsam/predict.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/fastsam/predict.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/fastsam/predict.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.fastsam.predict.FastSAMPredictor +

diff --git a/downloads/ultralytics-main/docs/reference/models/fastsam/prompt.md b/downloads/ultralytics-main/docs/reference/models/fastsam/prompt.md new file mode 100644 index 000000000..2952c32b3 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/fastsam/prompt.md @@ -0,0 +1,14 @@ +--- +description: Learn to effectively utilize FastSAMPrompt model from Ultralytics. Detailed guide to help you get the most out of your machine learning models. +keywords: Ultralytics, FastSAMPrompt, machine learning, model, guide, documentation +--- + +# Reference for `ultralytics/models/fastsam/prompt.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/fastsam/prompt.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/fastsam/prompt.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.fastsam.prompt.FastSAMPrompt +

diff --git a/downloads/ultralytics-main/docs/reference/models/fastsam/utils.md b/downloads/ultralytics-main/docs/reference/models/fastsam/utils.md new file mode 100644 index 000000000..cf2a6580c --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/fastsam/utils.md @@ -0,0 +1,18 @@ +--- +description: Learn how to adjust bounding boxes to image borders in Ultralytics models using the bbox_iou utility. Enhance your object detection performance. +keywords: Ultralytics, bounding boxes, Bboxes, image borders, object detection, bbox_iou, model utilities +--- + +# Reference for `ultralytics/models/fastsam/utils.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/fastsam/utils.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/fastsam/utils.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.fastsam.utils.adjust_bboxes_to_image_border +

+ +--- +## ::: ultralytics.models.fastsam.utils.bbox_iou +

diff --git a/downloads/ultralytics-main/docs/reference/models/fastsam/val.md b/downloads/ultralytics-main/docs/reference/models/fastsam/val.md new file mode 100644 index 000000000..956e68fde --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/fastsam/val.md @@ -0,0 +1,14 @@ +--- +description: Learn about FastSAMValidator in Ultralytics models. Comprehensive guide to enhancing AI capabilities with Ultralytics. +keywords: Ultralytics, FastSAMValidator, model, synthetic, AI, machine learning, validation +--- + +# Reference for `ultralytics/models/fastsam/val.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/fastsam/val.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/fastsam/val.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.fastsam.val.FastSAMValidator +

diff --git a/downloads/ultralytics-main/docs/reference/models/nas/model.md b/downloads/ultralytics-main/docs/reference/models/nas/model.md new file mode 100644 index 000000000..fa608ef07 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/nas/model.md @@ -0,0 +1,14 @@ +--- +description: Learn how our NAS model operates in Ultralytics. Comprehensive guide with detailed examples. Master the nuances of Ultralytics NAS model. +keywords: Ultralytics, NAS model, NAS guide, machine learning, model documentation +--- + +# Reference for `ultralytics/models/nas/model.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/nas/model.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/nas/model.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.nas.model.NAS +

diff --git a/downloads/ultralytics-main/docs/reference/models/nas/predict.md b/downloads/ultralytics-main/docs/reference/models/nas/predict.md new file mode 100644 index 000000000..884ceb2c5 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/nas/predict.md @@ -0,0 +1,14 @@ +--- +description: Explore Ultralytics NASPredictor. Understand high-level architecture of the model for effective implementation and efficient predictions. +keywords: NASPredictor, Ultralytics, Ultralytics model, model architecture, efficient predictions +--- + +# Reference for `ultralytics/models/nas/predict.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/nas/predict.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/nas/predict.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.nas.predict.NASPredictor +

diff --git a/downloads/ultralytics-main/docs/reference/models/nas/val.md b/downloads/ultralytics-main/docs/reference/models/nas/val.md new file mode 100644 index 000000000..5c46cba48 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/nas/val.md @@ -0,0 +1,14 @@ +--- +description: Explore the utilities and functions of the Ultralytics NASValidator. Find out how it benefits allocation and optimization in AI models. +keywords: Ultralytics, NASValidator, models.nas.val.NASValidator, AI models, allocation, optimization +--- + +# Reference for `ultralytics/models/nas/val.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/nas/val.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/nas/val.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.nas.val.NASValidator +

diff --git a/downloads/ultralytics-main/docs/reference/models/rtdetr/model.md b/downloads/ultralytics-main/docs/reference/models/rtdetr/model.md new file mode 100644 index 000000000..7b126e968 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/rtdetr/model.md @@ -0,0 +1,14 @@ +--- +description: Explore the specifics of using the RTDETR model in Ultralytics. Detailed documentation layered with explanations and examples. +keywords: Ultralytics, RTDETR model, Ultralytics models, object detection, Ultralytics documentation +--- + +# Reference for `ultralytics/models/rtdetr/model.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/rtdetr/model.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/rtdetr/model.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.rtdetr.model.RTDETR +

diff --git a/downloads/ultralytics-main/docs/reference/models/rtdetr/predict.md b/downloads/ultralytics-main/docs/reference/models/rtdetr/predict.md new file mode 100644 index 000000000..918b762b6 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/rtdetr/predict.md @@ -0,0 +1,14 @@ +--- +description: Learn how to use the RTDETRPredictor model of the Ultralytics package. Detailed documentation, usage instructions, and advice. +keywords: Ultralytics, RTDETRPredictor, model documentation, guide, real-time object detection +--- + +# Reference for `ultralytics/models/rtdetr/predict.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/rtdetr/predict.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/rtdetr/predict.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.rtdetr.predict.RTDETRPredictor +

diff --git a/downloads/ultralytics-main/docs/reference/models/rtdetr/train.md b/downloads/ultralytics-main/docs/reference/models/rtdetr/train.md new file mode 100644 index 000000000..f7f288175 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/rtdetr/train.md @@ -0,0 +1,14 @@ +--- +description: Get insights into RTDETRTrainer, a crucial component of Ultralytics for effective model training. Explore detailed documentation at Ultralytics. +keywords: Ultralytics, RTDETRTrainer, model training, Ultralytics models, PyTorch models, neural networks, machine learning, deep learning +--- + +# Reference for `ultralytics/models/rtdetr/train.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/rtdetr/train.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/rtdetr/train.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.rtdetr.train.RTDETRTrainer +

diff --git a/downloads/ultralytics-main/docs/reference/models/rtdetr/val.md b/downloads/ultralytics-main/docs/reference/models/rtdetr/val.md new file mode 100644 index 000000000..c4f44fd06 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/rtdetr/val.md @@ -0,0 +1,18 @@ +--- +description: Explore RTDETRDataset in Ultralytics Models. Learn about the RTDETRValidator function, understand its usage in real-time object detection. +keywords: Ultralytics, RTDETRDataset, RTDETRValidator, real-time object detection, models documentation +--- + +# Reference for `ultralytics/models/rtdetr/val.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/rtdetr/val.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/rtdetr/val.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.rtdetr.val.RTDETRDataset +

+ +--- +## ::: ultralytics.models.rtdetr.val.RTDETRValidator +

diff --git a/downloads/ultralytics-main/docs/reference/models/sam/amg.md b/downloads/ultralytics-main/docs/reference/models/sam/amg.md new file mode 100644 index 000000000..1ec59eb70 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/sam/amg.md @@ -0,0 +1,54 @@ +--- +description: Explore Ultralytics methods for mask data processing, transformation and encoding. Deepen your understanding of RLE encoding, image cropping and more. +keywords: Ultralytics, Mask Data, Transformation, Encoding, RLE encoding, Image cropping, Pytorch, SAM, AMG, Ultralytics model +--- + +# Reference for `ultralytics/models/sam/amg.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/amg.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/amg.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.sam.amg.is_box_near_crop_edge +

+ +--- +## ::: ultralytics.models.sam.amg.batch_iterator +

+ +--- +## ::: ultralytics.models.sam.amg.calculate_stability_score +

+ +--- +## ::: ultralytics.models.sam.amg.build_point_grid +

+ +--- +## ::: ultralytics.models.sam.amg.build_all_layer_point_grids +

+ +--- +## ::: ultralytics.models.sam.amg.generate_crop_boxes +

+ +--- +## ::: ultralytics.models.sam.amg.uncrop_boxes_xyxy +

+ +--- +## ::: ultralytics.models.sam.amg.uncrop_points +

+ +--- +## ::: ultralytics.models.sam.amg.uncrop_masks +

+ +--- +## ::: ultralytics.models.sam.amg.remove_small_regions +

+ +--- +## ::: ultralytics.models.sam.amg.batched_mask_to_box +

diff --git a/downloads/ultralytics-main/docs/reference/models/sam/build.md b/downloads/ultralytics-main/docs/reference/models/sam/build.md new file mode 100644 index 000000000..ceb00fc8b --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/sam/build.md @@ -0,0 +1,34 @@ +--- +description: Master building SAM ViT models with Ultralytics. Discover steps to leverage the power of SAM and Vision Transformer sessions. +keywords: Ultralytics, SAM, build sam, vision transformer, vits, build_sam_vit_l, build_sam_vit_b, build_sam +--- + +# Reference for `ultralytics/models/sam/build.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/build.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/build.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.sam.build.build_sam_vit_h +

+ +--- +## ::: ultralytics.models.sam.build.build_sam_vit_l +

+ +--- +## ::: ultralytics.models.sam.build.build_sam_vit_b +

+ +--- +## ::: ultralytics.models.sam.build.build_mobile_sam +

+ +--- +## ::: ultralytics.models.sam.build._build_sam +

+ +--- +## ::: ultralytics.models.sam.build.build_sam +

diff --git a/downloads/ultralytics-main/docs/reference/models/sam/model.md b/downloads/ultralytics-main/docs/reference/models/sam/model.md new file mode 100644 index 000000000..7d7d1c800 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/sam/model.md @@ -0,0 +1,14 @@ +--- +description: Dive into the SAM model details in the Ultralytics YOLO documentation. Understand, implement, and optimize your model use. +keywords: Ultralytics, YOLO, SAM Model, Documentations, Machine Learning, AI, Convolutional neural network +--- + +# Reference for `ultralytics/models/sam/model.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/model.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/model.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.sam.model.SAM +

diff --git a/downloads/ultralytics-main/docs/reference/models/sam/modules/decoders.md b/downloads/ultralytics-main/docs/reference/models/sam/modules/decoders.md new file mode 100644 index 000000000..6e9851458 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/sam/modules/decoders.md @@ -0,0 +1,18 @@ +--- +description: Explore MaskDecoder, a part of the Ultralytics models. Gain insights on how to utilize it effectively in the SAM modules decoders MLP. +keywords: Ultralytics, MaskDecoder, SAM modules, decoders, MLP, YOLO, machine learning, image recognition +--- + +# Reference for `ultralytics/models/sam/modules/decoders.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/modules/decoders.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/modules/decoders.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.sam.modules.decoders.MaskDecoder +

+ +--- +## ::: ultralytics.models.sam.modules.decoders.MLP +

diff --git a/downloads/ultralytics-main/docs/reference/models/sam/modules/encoders.md b/downloads/ultralytics-main/docs/reference/models/sam/modules/encoders.md new file mode 100644 index 000000000..40b99e442 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/sam/modules/encoders.md @@ -0,0 +1,50 @@ +--- +description: Discover detailed information on ImageEncoderViT, PositionEmbeddingRandom, Attention, window_partition, get_rel_pos and more in Ultralytics models encoders documentation. +keywords: Ultralytics, Encoders, Modules, Documentation, ImageEncoderViT, PositionEmbeddingRandom, Attention, window_partition, get_rel_pos +--- + +# Reference for `ultralytics/models/sam/modules/encoders.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/modules/encoders.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/modules/encoders.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.sam.modules.encoders.ImageEncoderViT +

+ +--- +## ::: ultralytics.models.sam.modules.encoders.PromptEncoder +

+ +--- +## ::: ultralytics.models.sam.modules.encoders.PositionEmbeddingRandom +

+ +--- +## ::: ultralytics.models.sam.modules.encoders.Block +

+ +--- +## ::: ultralytics.models.sam.modules.encoders.Attention +

+ +--- +## ::: ultralytics.models.sam.modules.encoders.PatchEmbed +

+ +--- +## ::: ultralytics.models.sam.modules.encoders.window_partition +

+ +--- +## ::: ultralytics.models.sam.modules.encoders.window_unpartition +

+ +--- +## ::: ultralytics.models.sam.modules.encoders.get_rel_pos +

+ +--- +## ::: ultralytics.models.sam.modules.encoders.add_decomposed_rel_pos +

diff --git a/downloads/ultralytics-main/docs/reference/models/sam/modules/sam.md b/downloads/ultralytics-main/docs/reference/models/sam/modules/sam.md new file mode 100644 index 000000000..a0f678717 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/sam/modules/sam.md @@ -0,0 +1,14 @@ +--- +description: Explore the Sam module of Ultralytics. Discover detailed methods, classes, and information for efficient deep-learning model training!. +keywords: Ultralytics, Sam module, deep learning, model training, Ultralytics documentation +--- + +# Reference for `ultralytics/models/sam/modules/sam.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/modules/sam.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/modules/sam.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.sam.modules.sam.Sam +

diff --git a/downloads/ultralytics-main/docs/reference/models/sam/modules/tiny_encoder.md b/downloads/ultralytics-main/docs/reference/models/sam/modules/tiny_encoder.md new file mode 100644 index 000000000..69ec6efa1 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/sam/modules/tiny_encoder.md @@ -0,0 +1,54 @@ +--- +description: Get in-depth insights about Ultralytics Tiny Encoder Modules such as Conv2d_BN, MBConv, ConvLayer, Attention, BasicLayer, and TinyViT. Improve your understanding of machine learning model components. +keywords: Ultralytics, Tiny Encoder, Conv2d_BN, MBConv, ConvLayer, Attention, BasicLayer, TinyViT, Machine learning modules, Ultralytics models +--- + +# Reference for `ultralytics/models/sam/modules/tiny_encoder.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/modules/tiny_encoder.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/modules/tiny_encoder.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.sam.modules.tiny_encoder.Conv2d_BN +

+ +--- +## ::: ultralytics.models.sam.modules.tiny_encoder.PatchEmbed +

+ +--- +## ::: ultralytics.models.sam.modules.tiny_encoder.MBConv +

+ +--- +## ::: ultralytics.models.sam.modules.tiny_encoder.PatchMerging +

+ +--- +## ::: ultralytics.models.sam.modules.tiny_encoder.ConvLayer +

+ +--- +## ::: ultralytics.models.sam.modules.tiny_encoder.Mlp +

+ +--- +## ::: ultralytics.models.sam.modules.tiny_encoder.Attention +

+ +--- +## ::: ultralytics.models.sam.modules.tiny_encoder.TinyViTBlock +

+ +--- +## ::: ultralytics.models.sam.modules.tiny_encoder.BasicLayer +

+ +--- +## ::: ultralytics.models.sam.modules.tiny_encoder.LayerNorm2d +

+ +--- +## ::: ultralytics.models.sam.modules.tiny_encoder.TinyViT +

diff --git a/downloads/ultralytics-main/docs/reference/models/sam/modules/transformer.md b/downloads/ultralytics-main/docs/reference/models/sam/modules/transformer.md new file mode 100644 index 000000000..490ee1d28 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/sam/modules/transformer.md @@ -0,0 +1,22 @@ +--- +description: Learn about TwoWayTransformer and Attention modules in Ultralytics. Leverage these tools to enhance your AI models. +keywords: Ultralytics, TwoWayTransformer, Attention, AI models, transformers +--- + +# Reference for `ultralytics/models/sam/modules/transformer.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/modules/transformer.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/modules/transformer.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.sam.modules.transformer.TwoWayTransformer +

+ +--- +## ::: ultralytics.models.sam.modules.transformer.TwoWayAttentionBlock +

+ +--- +## ::: ultralytics.models.sam.modules.transformer.Attention +

diff --git a/downloads/ultralytics-main/docs/reference/models/sam/predict.md b/downloads/ultralytics-main/docs/reference/models/sam/predict.md new file mode 100644 index 000000000..6e3b81778 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/sam/predict.md @@ -0,0 +1,14 @@ +--- +description: Master the ultralytics.models.sam.predict.Predictor class with our comprehensive guide. Discover techniques to enhance your model predictions. +keywords: Ultralytics, predictor, models, sam.predict.Predictor, AI, machine learning, predictive models +--- + +# Reference for `ultralytics/models/sam/predict.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/predict.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/predict.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.sam.predict.Predictor +

diff --git a/downloads/ultralytics-main/docs/reference/models/utils/loss.md b/downloads/ultralytics-main/docs/reference/models/utils/loss.md new file mode 100644 index 000000000..5223f99dc --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/utils/loss.md @@ -0,0 +1,18 @@ +--- +description: Learn to use the DETRLoss function provided by Ultralytics YOLO. Understand how to utilize loss in RTDETR detection models to improve accuracy. +keywords: Ultralytics, YOLO, Documentation, DETRLoss, Detection Loss, Loss function, DETR, RTDETR Detection Models +--- + +# Reference for `ultralytics/models/utils/loss.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/utils/loss.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/utils/loss.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.utils.loss.DETRLoss +

+ +--- +## ::: ultralytics.models.utils.loss.RTDETRDetectionLoss +

diff --git a/downloads/ultralytics-main/docs/reference/models/utils/ops.md b/downloads/ultralytics-main/docs/reference/models/utils/ops.md new file mode 100644 index 000000000..9538ee483 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/utils/ops.md @@ -0,0 +1,22 @@ +--- +description: Discover details for "HungarianMatcher" & "inverse_sigmoid" functions in Ultralytics YOLO, advanced tools supporting detection models. +keywords: Ultralytics, YOLO, HungarianMatcher, inverse_sigmoid, detection models, model utilities, ops +--- + +# Reference for `ultralytics/models/utils/ops.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/utils/ops.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/utils/ops.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.utils.ops.HungarianMatcher +

+ +--- +## ::: ultralytics.models.utils.ops.get_cdn_group +

+ +--- +## ::: ultralytics.models.utils.ops.inverse_sigmoid +

diff --git a/downloads/ultralytics-main/docs/reference/models/yolo/classify/predict.md b/downloads/ultralytics-main/docs/reference/models/yolo/classify/predict.md new file mode 100644 index 000000000..4b2485dee --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/yolo/classify/predict.md @@ -0,0 +1,14 @@ +--- +description: Explore the Ultralytics ClassificationPredictor guide for model prediction and visualization. Build powerful AI models with YOLO. +keywords: Ultralytics, classification predictor, predict, YOLO, AI models, model visualization +--- + +# Reference for `ultralytics/models/yolo/classify/predict.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/classify/predict.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/classify/predict.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.yolo.classify.predict.ClassificationPredictor +

diff --git a/downloads/ultralytics-main/docs/reference/models/yolo/classify/train.md b/downloads/ultralytics-main/docs/reference/models/yolo/classify/train.md new file mode 100644 index 000000000..42e14a93e --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/yolo/classify/train.md @@ -0,0 +1,14 @@ +--- +description: Delve into Classification Trainer at Ultralytics YOLO docs and optimize your model's training process with insights from the masters!. +keywords: Ultralytics, YOLO, Classification Trainer, deep learning, training process, AI models, documentation +--- + +# Reference for `ultralytics/models/yolo/classify/train.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/classify/train.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/classify/train.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.yolo.classify.train.ClassificationTrainer +

diff --git a/downloads/ultralytics-main/docs/reference/models/yolo/classify/val.md b/downloads/ultralytics-main/docs/reference/models/yolo/classify/val.md new file mode 100644 index 000000000..df505ec47 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/yolo/classify/val.md @@ -0,0 +1,14 @@ +--- +description: Explore YOLO ClassificationValidator, a key element of Ultralytics YOLO models. Learn how it validates and fine-tunes model outputs. +keywords: Ultralytics, YOLO, ClassificationValidator, model validation, model fine-tuning, deep learning, computer vision +--- + +# Reference for `ultralytics/models/yolo/classify/val.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/classify/val.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/classify/val.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.yolo.classify.val.ClassificationValidator +

diff --git a/downloads/ultralytics-main/docs/reference/models/yolo/detect/predict.md b/downloads/ultralytics-main/docs/reference/models/yolo/detect/predict.md new file mode 100644 index 000000000..15191e43b --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/yolo/detect/predict.md @@ -0,0 +1,14 @@ +--- +description: Explore the guide to using the DetectionPredictor in Ultralytics YOLO. Learn how to predict, detect and analyze objects accurately. +keywords: Ultralytics, YOLO, DetectionPredictor, detect, predict, object detection, analysis +--- + +# Reference for `ultralytics/models/yolo/detect/predict.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/detect/predict.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/detect/predict.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.yolo.detect.predict.DetectionPredictor +

diff --git a/downloads/ultralytics-main/docs/reference/models/yolo/detect/train.md b/downloads/ultralytics-main/docs/reference/models/yolo/detect/train.md new file mode 100644 index 000000000..57092a398 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/yolo/detect/train.md @@ -0,0 +1,14 @@ +--- +description: Maximize your model's potential with Ultralytics YOLO Detection Trainer. Learn advanced techniques, tips, and tricks for training. +keywords: Ultralytics YOLO, YOLO, Detection Trainer, Model Training, Machine Learning, Deep Learning, Computer Vision +--- + +# Reference for `ultralytics/models/yolo/detect/train.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/detect/train.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/detect/train.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.yolo.detect.train.DetectionTrainer +

diff --git a/downloads/ultralytics-main/docs/reference/models/yolo/detect/val.md b/downloads/ultralytics-main/docs/reference/models/yolo/detect/val.md new file mode 100644 index 000000000..1afe42e83 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/yolo/detect/val.md @@ -0,0 +1,14 @@ +--- +description: Discover function valuation of your YOLO models with the Ultralytics Detection Validator. Enhance precision and recall rates today. +keywords: Ultralytics, YOLO, Detection Validator, model valuation, precision, recall +--- + +# Reference for `ultralytics/models/yolo/detect/val.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/detect/val.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/detect/val.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.yolo.detect.val.DetectionValidator +

diff --git a/downloads/ultralytics-main/docs/reference/models/yolo/model.md b/downloads/ultralytics-main/docs/reference/models/yolo/model.md new file mode 100644 index 000000000..ad7bf6998 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/yolo/model.md @@ -0,0 +1,14 @@ +--- +description: Discover the Ultralytics YOLO model class. Learn advanced techniques, tips, and tricks for training. +keywords: Ultralytics YOLO, YOLO, YOLO model, Model Training, Machine Learning, Deep Learning, Computer Vision +--- + +# Reference for `ultralytics/models/yolo/model.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/model.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/model.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.yolo.model.YOLO +

diff --git a/downloads/ultralytics-main/docs/reference/models/yolo/pose/predict.md b/downloads/ultralytics-main/docs/reference/models/yolo/pose/predict.md new file mode 100644 index 000000000..e5ea33c80 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/yolo/pose/predict.md @@ -0,0 +1,14 @@ +--- +description: Discover how to use PosePredictor in the Ultralytics YOLO model. Includes detailed guides, code examples, and explanations. +keywords: Ultralytics, YOLO, PosePredictor, machine learning, AI, predictive models +--- + +# Reference for `ultralytics/models/yolo/pose/predict.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/pose/predict.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/pose/predict.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.yolo.pose.predict.PosePredictor +

diff --git a/downloads/ultralytics-main/docs/reference/models/yolo/pose/train.md b/downloads/ultralytics-main/docs/reference/models/yolo/pose/train.md new file mode 100644 index 000000000..972edd411 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/yolo/pose/train.md @@ -0,0 +1,14 @@ +--- +description: Explore Ultralytics PoseTrainer for YOLO models. Get a step-by-step guide on how to train on custom pose data for more accurate AI modeling. +keywords: Ultralytics, YOLO, PoseTrainer, pose training, AI modeling, custom data training +--- + +# Reference for `ultralytics/models/yolo/pose/train.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/pose/train.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/pose/train.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.yolo.pose.train.PoseTrainer +

diff --git a/downloads/ultralytics-main/docs/reference/models/yolo/pose/val.md b/downloads/ultralytics-main/docs/reference/models/yolo/pose/val.md new file mode 100644 index 000000000..a826bc320 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/yolo/pose/val.md @@ -0,0 +1,14 @@ +--- +description: Explore the PoseValidator—review how Ultralytics YOLO validates poses for object detection. Improve your understanding of YOLO. +keywords: PoseValidator, Ultralytics, YOLO, Object detection, Pose validation +--- + +# Reference for `ultralytics/models/yolo/pose/val.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/pose/val.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/pose/val.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.yolo.pose.val.PoseValidator +

diff --git a/downloads/ultralytics-main/docs/reference/models/yolo/segment/predict.md b/downloads/ultralytics-main/docs/reference/models/yolo/segment/predict.md new file mode 100644 index 000000000..acfcc1a62 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/yolo/segment/predict.md @@ -0,0 +1,14 @@ +--- +description: Discover how to utilize the YOLO Segmentation Predictor in Ultralytics. Enhance your objects detection skills with us. +keywords: YOLO, Ultralytics, object detection, segmentation predictor +--- + +# Reference for `ultralytics/models/yolo/segment/predict.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/segment/predict.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/segment/predict.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.yolo.segment.predict.SegmentationPredictor +

diff --git a/downloads/ultralytics-main/docs/reference/models/yolo/segment/train.md b/downloads/ultralytics-main/docs/reference/models/yolo/segment/train.md new file mode 100644 index 000000000..74434a56f --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/yolo/segment/train.md @@ -0,0 +1,14 @@ +--- +description: Maximize your YOLO model's performance with our SegmentationTrainer. Explore comprehensive guides and tutorials on ultralytics.com. +keywords: Ultralytics, YOLO, SegmentationTrainer, image segmentation, object detection, model training, YOLO model +--- + +# Reference for `ultralytics/models/yolo/segment/train.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/segment/train.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/segment/train.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.yolo.segment.train.SegmentationTrainer +

diff --git a/downloads/ultralytics-main/docs/reference/models/yolo/segment/val.md b/downloads/ultralytics-main/docs/reference/models/yolo/segment/val.md new file mode 100644 index 000000000..58d8b9d3d --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/models/yolo/segment/val.md @@ -0,0 +1,14 @@ +--- +description: Get practical insights about our SegmentationValidator in YOLO Ultralytics models. Discover functionality details, methods, inputs, and outputs. +keywords: Ultralytics, YOLO, SegmentationValidator, model segmentation, image classification, object detection +--- + +# Reference for `ultralytics/models/yolo/segment/val.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/segment/val.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/yolo/segment/val.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.models.yolo.segment.val.SegmentationValidator +

diff --git a/downloads/ultralytics-main/docs/reference/nn/autobackend.md b/downloads/ultralytics-main/docs/reference/nn/autobackend.md index 2166e7c80..1b0e02263 100644 --- a/downloads/ultralytics-main/docs/reference/nn/autobackend.md +++ b/downloads/ultralytics-main/docs/reference/nn/autobackend.md @@ -1,13 +1,18 @@ --- -description: Ensure class names match filenames for easy imports. Use AutoBackend to automatically rename and refactor model files. +description: Get to know more about Ultralytics nn.autobackend.check_class_names functionality. Optimize your YOLO models seamlessly. +keywords: Ultralytics, AutoBackend, check_class_names, YOLO, YOLO models, optimization --- -# AutoBackend +# Reference for `ultralytics/nn/autobackend.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/nn/autobackend.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/nn/autobackend.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + --- -:::ultralytics.nn.autobackend.AutoBackend +## ::: ultralytics.nn.autobackend.AutoBackend

-# check_class_names --- -:::ultralytics.nn.autobackend.check_class_names +## ::: ultralytics.nn.autobackend.check_class_names

diff --git a/downloads/ultralytics-main/docs/reference/nn/modules/block.md b/downloads/ultralytics-main/docs/reference/nn/modules/block.md index 58a23ed63..df3369855 100644 --- a/downloads/ultralytics-main/docs/reference/nn/modules/block.md +++ b/downloads/ultralytics-main/docs/reference/nn/modules/block.md @@ -1,88 +1,78 @@ --- -description: Explore ultralytics.nn.modules.block to build powerful YOLO object detection models. Master DFL, HGStem, SPP, CSP components and more. +description: Explore Ultralytics YOLO neural network modules, Proto to BottleneckCSP. Detailed explanation of each module with easy-to-follow code examples. +keywords: YOLO, Ultralytics, neural network, nn.modules.block, Proto, HGBlock, SPPF, C2, C3, RepC3, C3Ghost, Bottleneck, BottleneckCSP --- -# DFL +# Reference for `ultralytics/nn/modules/block.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/nn/modules/block.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/nn/modules/block.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + --- -:::ultralytics.nn.modules.block.DFL +## ::: ultralytics.nn.modules.block.DFL

-# Proto --- -:::ultralytics.nn.modules.block.Proto +## ::: ultralytics.nn.modules.block.Proto

-# HGStem --- -:::ultralytics.nn.modules.block.HGStem +## ::: ultralytics.nn.modules.block.HGStem

-# HGBlock --- -:::ultralytics.nn.modules.block.HGBlock +## ::: ultralytics.nn.modules.block.HGBlock

-# SPP --- -:::ultralytics.nn.modules.block.SPP +## ::: ultralytics.nn.modules.block.SPP

-# SPPF --- -:::ultralytics.nn.modules.block.SPPF +## ::: ultralytics.nn.modules.block.SPPF

-# C1 --- -:::ultralytics.nn.modules.block.C1 +## ::: ultralytics.nn.modules.block.C1

-# C2 --- -:::ultralytics.nn.modules.block.C2 +## ::: ultralytics.nn.modules.block.C2

-# C2f --- -:::ultralytics.nn.modules.block.C2f +## ::: ultralytics.nn.modules.block.C2f

-# C3 --- -:::ultralytics.nn.modules.block.C3 +## ::: ultralytics.nn.modules.block.C3

-# C3x --- -:::ultralytics.nn.modules.block.C3x +## ::: ultralytics.nn.modules.block.C3x

-# RepC3 --- -:::ultralytics.nn.modules.block.RepC3 +## ::: ultralytics.nn.modules.block.RepC3

-# C3TR --- -:::ultralytics.nn.modules.block.C3TR +## ::: ultralytics.nn.modules.block.C3TR

-# C3Ghost --- -:::ultralytics.nn.modules.block.C3Ghost +## ::: ultralytics.nn.modules.block.C3Ghost

-# GhostBottleneck --- -:::ultralytics.nn.modules.block.GhostBottleneck +## ::: ultralytics.nn.modules.block.GhostBottleneck

-# Bottleneck --- -:::ultralytics.nn.modules.block.Bottleneck +## ::: ultralytics.nn.modules.block.Bottleneck

-# BottleneckCSP --- -:::ultralytics.nn.modules.block.BottleneckCSP +## ::: ultralytics.nn.modules.block.BottleneckCSP

diff --git a/downloads/ultralytics-main/docs/reference/nn/modules/conv.md b/downloads/ultralytics-main/docs/reference/nn/modules/conv.md index 70591f69b..a1853842c 100644 --- a/downloads/ultralytics-main/docs/reference/nn/modules/conv.md +++ b/downloads/ultralytics-main/docs/reference/nn/modules/conv.md @@ -1,68 +1,66 @@ --- -description: Explore convolutional neural network modules & techniques such as LightConv, DWConv, ConvTranspose, GhostConv, CBAM & autopad with Ultralytics Docs. +description: Explore various Ultralytics convolution modules including Conv2, DWConv, ConvTranspose, GhostConv, Channel Attention and more. +keywords: Ultralytics, Convolution Modules, Conv2, DWConv, ConvTranspose, GhostConv, ChannelAttention, CBAM, autopad --- -# Conv +# Reference for `ultralytics/nn/modules/conv.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/nn/modules/conv.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/nn/modules/conv.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + --- -:::ultralytics.nn.modules.conv.Conv +## ::: ultralytics.nn.modules.conv.Conv

-# LightConv --- -:::ultralytics.nn.modules.conv.LightConv +## ::: ultralytics.nn.modules.conv.Conv2

-# DWConv --- -:::ultralytics.nn.modules.conv.DWConv +## ::: ultralytics.nn.modules.conv.LightConv

-# DWConvTranspose2d --- -:::ultralytics.nn.modules.conv.DWConvTranspose2d +## ::: ultralytics.nn.modules.conv.DWConv

-# ConvTranspose --- -:::ultralytics.nn.modules.conv.ConvTranspose +## ::: ultralytics.nn.modules.conv.DWConvTranspose2d

-# Focus --- -:::ultralytics.nn.modules.conv.Focus +## ::: ultralytics.nn.modules.conv.ConvTranspose

-# GhostConv --- -:::ultralytics.nn.modules.conv.GhostConv +## ::: ultralytics.nn.modules.conv.Focus

-# RepConv --- -:::ultralytics.nn.modules.conv.RepConv +## ::: ultralytics.nn.modules.conv.GhostConv

-# ChannelAttention --- -:::ultralytics.nn.modules.conv.ChannelAttention +## ::: ultralytics.nn.modules.conv.RepConv

-# SpatialAttention --- -:::ultralytics.nn.modules.conv.SpatialAttention +## ::: ultralytics.nn.modules.conv.ChannelAttention

-# CBAM --- -:::ultralytics.nn.modules.conv.CBAM +## ::: ultralytics.nn.modules.conv.SpatialAttention

-# Concat --- -:::ultralytics.nn.modules.conv.Concat +## ::: ultralytics.nn.modules.conv.CBAM

-# autopad --- -:::ultralytics.nn.modules.conv.autopad +## ::: ultralytics.nn.modules.conv.Concat +

+ +--- +## ::: ultralytics.nn.modules.conv.autopad

diff --git a/downloads/ultralytics-main/docs/reference/nn/modules/head.md b/downloads/ultralytics-main/docs/reference/nn/modules/head.md index 17488da73..ce87dbc8a 100644 --- a/downloads/ultralytics-main/docs/reference/nn/modules/head.md +++ b/downloads/ultralytics-main/docs/reference/nn/modules/head.md @@ -1,28 +1,30 @@ --- -description: 'Learn about Ultralytics YOLO modules: Segment, Classify, and RTDETRDecoder. Optimize object detection and classification in your project.' +description: Explore docs covering Ultralytics YOLO detection, pose & RTDETRDecoder. Comprehensive guides to help you understand Ultralytics nn modules. +keywords: Ultralytics, YOLO, Detection, Pose, RTDETRDecoder, nn modules, guides --- -# Detect +# Reference for `ultralytics/nn/modules/head.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/nn/modules/head.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/nn/modules/head.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + --- -:::ultralytics.nn.modules.head.Detect +## ::: ultralytics.nn.modules.head.Detect

-# Segment --- -:::ultralytics.nn.modules.head.Segment +## ::: ultralytics.nn.modules.head.Segment

-# Pose --- -:::ultralytics.nn.modules.head.Pose +## ::: ultralytics.nn.modules.head.Pose

-# Classify --- -:::ultralytics.nn.modules.head.Classify +## ::: ultralytics.nn.modules.head.Classify

-# RTDETRDecoder --- -:::ultralytics.nn.modules.head.RTDETRDecoder +## ::: ultralytics.nn.modules.head.RTDETRDecoder

diff --git a/downloads/ultralytics-main/docs/reference/nn/modules/transformer.md b/downloads/ultralytics-main/docs/reference/nn/modules/transformer.md index 654917d82..0a8558f41 100644 --- a/downloads/ultralytics-main/docs/reference/nn/modules/transformer.md +++ b/downloads/ultralytics-main/docs/reference/nn/modules/transformer.md @@ -1,53 +1,50 @@ --- -description: Explore the Ultralytics nn modules pages on Transformer and MLP blocks, LayerNorm2d, and Deformable Transformer Decoder Layer. +description: Learn about Ultralytics transformer encoder, layer, MLP block, LayerNorm2d and the deformable transformer decoder layer. Expand your understanding of these crucial AI modules. +keywords: Ultralytics, Ultralytics documentation, TransformerEncoderLayer, TransformerLayer, MLPBlock, LayerNorm2d, DeformableTransformerDecoderLayer --- -# TransformerEncoderLayer +# Reference for `ultralytics/nn/modules/transformer.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/nn/modules/transformer.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/nn/modules/transformer.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + --- -:::ultralytics.nn.modules.transformer.TransformerEncoderLayer +## ::: ultralytics.nn.modules.transformer.TransformerEncoderLayer

-# AIFI --- -:::ultralytics.nn.modules.transformer.AIFI +## ::: ultralytics.nn.modules.transformer.AIFI

-# TransformerLayer --- -:::ultralytics.nn.modules.transformer.TransformerLayer +## ::: ultralytics.nn.modules.transformer.TransformerLayer

-# TransformerBlock --- -:::ultralytics.nn.modules.transformer.TransformerBlock +## ::: ultralytics.nn.modules.transformer.TransformerBlock

-# MLPBlock --- -:::ultralytics.nn.modules.transformer.MLPBlock +## ::: ultralytics.nn.modules.transformer.MLPBlock

-# MLP --- -:::ultralytics.nn.modules.transformer.MLP +## ::: ultralytics.nn.modules.transformer.MLP

-# LayerNorm2d --- -:::ultralytics.nn.modules.transformer.LayerNorm2d +## ::: ultralytics.nn.modules.transformer.LayerNorm2d

-# MSDeformAttn --- -:::ultralytics.nn.modules.transformer.MSDeformAttn +## ::: ultralytics.nn.modules.transformer.MSDeformAttn

-# DeformableTransformerDecoderLayer --- -:::ultralytics.nn.modules.transformer.DeformableTransformerDecoderLayer +## ::: ultralytics.nn.modules.transformer.DeformableTransformerDecoderLayer

-# DeformableTransformerDecoder --- -:::ultralytics.nn.modules.transformer.DeformableTransformerDecoder +## ::: ultralytics.nn.modules.transformer.DeformableTransformerDecoder

diff --git a/downloads/ultralytics-main/docs/reference/nn/modules/utils.md b/downloads/ultralytics-main/docs/reference/nn/modules/utils.md index 877c52c01..322ec8a04 100644 --- a/downloads/ultralytics-main/docs/reference/nn/modules/utils.md +++ b/downloads/ultralytics-main/docs/reference/nn/modules/utils.md @@ -1,28 +1,30 @@ --- -description: 'Learn about Ultralytics NN modules: get_clones, linear_init_, and multi_scale_deformable_attn_pytorch. Code examples and usage tips.' +description: Explore Ultralytics neural network utils, such as bias_init_with_prob, inverse_sigmoid and multi_scale_deformable_attn_pytorch functions. +keywords: Ultralytics, neural network, nn.modules.utils, bias_init_with_prob, inverse_sigmoid, multi_scale_deformable_attn_pytorch --- -# _get_clones +# Reference for `ultralytics/nn/modules/utils.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/nn/modules/utils.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/nn/modules/utils.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + --- -:::ultralytics.nn.modules.utils._get_clones +## ::: ultralytics.nn.modules.utils._get_clones

-# bias_init_with_prob --- -:::ultralytics.nn.modules.utils.bias_init_with_prob +## ::: ultralytics.nn.modules.utils.bias_init_with_prob

-# linear_init_ --- -:::ultralytics.nn.modules.utils.linear_init_ +## ::: ultralytics.nn.modules.utils.linear_init_

-# inverse_sigmoid --- -:::ultralytics.nn.modules.utils.inverse_sigmoid +## ::: ultralytics.nn.modules.utils.inverse_sigmoid

-# multi_scale_deformable_attn_pytorch --- -:::ultralytics.nn.modules.utils.multi_scale_deformable_attn_pytorch +## ::: ultralytics.nn.modules.utils.multi_scale_deformable_attn_pytorch

diff --git a/downloads/ultralytics-main/docs/reference/nn/tasks.md b/downloads/ultralytics-main/docs/reference/nn/tasks.md index bf1fa05dd..6bca3a79f 100644 --- a/downloads/ultralytics-main/docs/reference/nn/tasks.md +++ b/downloads/ultralytics-main/docs/reference/nn/tasks.md @@ -1,68 +1,65 @@ ---- -description: Learn how to work with Ultralytics YOLO Detection, Segmentation & Classification Models, load weights and parse models in PyTorch. ---- +# Reference for `ultralytics/nn/tasks.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/nn/tasks.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/nn/tasks.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! -# BaseModel --- -:::ultralytics.nn.tasks.BaseModel +## ::: ultralytics.nn.tasks.BaseModel

-# DetectionModel --- -:::ultralytics.nn.tasks.DetectionModel +## ::: ultralytics.nn.tasks.DetectionModel

-# SegmentationModel --- -:::ultralytics.nn.tasks.SegmentationModel +## ::: ultralytics.nn.tasks.SegmentationModel

-# PoseModel --- -:::ultralytics.nn.tasks.PoseModel +## ::: ultralytics.nn.tasks.PoseModel

-# ClassificationModel --- -:::ultralytics.nn.tasks.ClassificationModel +## ::: ultralytics.nn.tasks.ClassificationModel

-# Ensemble --- -:::ultralytics.nn.tasks.Ensemble +## ::: ultralytics.nn.tasks.RTDETRDetectionModel

-# torch_safe_load --- -:::ultralytics.nn.tasks.torch_safe_load +## ::: ultralytics.nn.tasks.Ensemble

-# attempt_load_weights --- -:::ultralytics.nn.tasks.attempt_load_weights +## ::: ultralytics.nn.tasks.temporary_modules

-# attempt_load_one_weight --- -:::ultralytics.nn.tasks.attempt_load_one_weight +## ::: ultralytics.nn.tasks.torch_safe_load

-# parse_model --- -:::ultralytics.nn.tasks.parse_model +## ::: ultralytics.nn.tasks.attempt_load_weights

-# yaml_model_load --- -:::ultralytics.nn.tasks.yaml_model_load +## ::: ultralytics.nn.tasks.attempt_load_one_weight

-# guess_model_scale --- -:::ultralytics.nn.tasks.guess_model_scale +## ::: ultralytics.nn.tasks.parse_model

-# guess_model_task --- -:::ultralytics.nn.tasks.guess_model_task +## ::: ultralytics.nn.tasks.yaml_model_load +

+ +--- +## ::: ultralytics.nn.tasks.guess_model_scale +

+ +--- +## ::: ultralytics.nn.tasks.guess_model_task

diff --git a/downloads/ultralytics-main/docs/reference/trackers/basetrack.md b/downloads/ultralytics-main/docs/reference/trackers/basetrack.md new file mode 100644 index 000000000..f8f5b5c43 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/trackers/basetrack.md @@ -0,0 +1,18 @@ +--- +description: Get familiar with TrackState in Ultralytics. Learn how it is used in the BaseTrack of the Ultralytics tracker for enhanced functionality. +keywords: Ultralytics, TrackState, BaseTrack, Ultralytics tracker, Ultralytics documentation +--- + +# Reference for `ultralytics/trackers/basetrack.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/trackers/basetrack.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/trackers/basetrack.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.trackers.basetrack.TrackState +

+ +--- +## ::: ultralytics.trackers.basetrack.BaseTrack +

diff --git a/downloads/ultralytics-main/docs/reference/trackers/bot_sort.md b/downloads/ultralytics-main/docs/reference/trackers/bot_sort.md new file mode 100644 index 000000000..298d1f787 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/trackers/bot_sort.md @@ -0,0 +1,18 @@ +--- +description: Master the use of Ultralytics BOTrack, a key component of the powerful Ultralytics tracking system. Learn to integrate and use BOTSORT in your projects. +keywords: Ultralytics, BOTSORT, BOTrack, tracking system, official documentation, machine learning, AI tracking +--- + +# Reference for `ultralytics/trackers/bot_sort.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/trackers/bot_sort.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/trackers/bot_sort.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.trackers.bot_sort.BOTrack +

+ +--- +## ::: ultralytics.trackers.bot_sort.BOTSORT +

diff --git a/downloads/ultralytics-main/docs/reference/trackers/byte_tracker.md b/downloads/ultralytics-main/docs/reference/trackers/byte_tracker.md new file mode 100644 index 000000000..c927ae0c0 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/trackers/byte_tracker.md @@ -0,0 +1,18 @@ +--- +description: Step-in to explore in-depth the functionalities of Ultralytics BYTETracker under STrack. Gain advanced feature insights to streamline your operations. +keywords: STrack, Ultralytics, BYTETracker, documentation, Ultralytics tracker, object tracking, YOLO +--- + +# Reference for `ultralytics/trackers/byte_tracker.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/trackers/byte_tracker.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/trackers/byte_tracker.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.trackers.byte_tracker.STrack +

+ +--- +## ::: ultralytics.trackers.byte_tracker.BYTETracker +

diff --git a/downloads/ultralytics-main/docs/reference/trackers/track.md b/downloads/ultralytics-main/docs/reference/trackers/track.md new file mode 100644 index 000000000..3858a2e7f --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/trackers/track.md @@ -0,0 +1,22 @@ +--- +description: Explore Ultralytics documentation on prediction function starters & register trackers. Understand our code & its applications better. +keywords: Ultralytics, YOLO, on predict start, register tracker, prediction functions, documentation +--- + +# Reference for `ultralytics/trackers/track.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/trackers/track.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/trackers/track.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.trackers.track.on_predict_start +

+ +--- +## ::: ultralytics.trackers.track.on_predict_postprocess_end +

+ +--- +## ::: ultralytics.trackers.track.register_tracker +

diff --git a/downloads/ultralytics-main/docs/reference/trackers/utils/gmc.md b/downloads/ultralytics-main/docs/reference/trackers/utils/gmc.md new file mode 100644 index 000000000..e8db81a00 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/trackers/utils/gmc.md @@ -0,0 +1,14 @@ +--- +description: Explore the Ultralytics GMC tool in our comprehensive documentation. Learn how it works, best practices, and implementation advice. +keywords: Ultralytics, GMC utility, Ultralytics documentation, Ultralytics tracker, machine learning tools +--- + +# Reference for `ultralytics/trackers/utils/gmc.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/trackers/utils/gmc.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/trackers/utils/gmc.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.trackers.utils.gmc.GMC +

diff --git a/downloads/ultralytics-main/docs/reference/trackers/utils/kalman_filter.md b/downloads/ultralytics-main/docs/reference/trackers/utils/kalman_filter.md new file mode 100644 index 000000000..c24bcfbc7 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/trackers/utils/kalman_filter.md @@ -0,0 +1,18 @@ +--- +description: Explore KalmanFilterXYAH, a key component of Ultralytics trackers. Understand its utilities and learn to leverage it in your own projects. +keywords: Ultralytics, KalmanFilterXYAH, tracker, documentation, guide +--- + +# Reference for `ultralytics/trackers/utils/kalman_filter.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/trackers/utils/kalman_filter.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/trackers/utils/kalman_filter.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.trackers.utils.kalman_filter.KalmanFilterXYAH +

+ +--- +## ::: ultralytics.trackers.utils.kalman_filter.KalmanFilterXYWH +

diff --git a/downloads/ultralytics-main/docs/reference/trackers/utils/matching.md b/downloads/ultralytics-main/docs/reference/trackers/utils/matching.md new file mode 100644 index 000000000..8a4ca9042 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/trackers/utils/matching.md @@ -0,0 +1,26 @@ +--- +description: Explore in-depth guidance for using Ultralytics trackers utils matching, including merge_matches, linear_assignment, iou_distance, embedding_distance, fuse_motion, and fuse_score. +keywords: Ultralytics, Trackers Utils, Matching, merge_matches, linear_assignment, iou_distance, embedding_distance, fuse_motion, fuse_score, documentation +--- + +# Reference for `ultralytics/trackers/utils/matching.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/trackers/utils/matching.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/trackers/utils/matching.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.trackers.utils.matching.linear_assignment +

+ +--- +## ::: ultralytics.trackers.utils.matching.iou_distance +

+ +--- +## ::: ultralytics.trackers.utils.matching.embedding_distance +

+ +--- +## ::: ultralytics.trackers.utils.matching.fuse_score +

diff --git a/downloads/ultralytics-main/docs/reference/utils/__init__.md b/downloads/ultralytics-main/docs/reference/utils/__init__.md new file mode 100644 index 000000000..6369acbad --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/__init__.md @@ -0,0 +1,150 @@ +--- +description: Explore the Ultralytics Utils package, with handy functions like colorstr, yaml_save, set_logging & more, designed to enhance your coding experience. +keywords: Ultralytics, Utils, utilitarian functions, colorstr, yaml_save, set_logging, is_kaggle, is_docker, clean_url +--- + +# Reference for `ultralytics/utils/__init__.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/__init__.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/__init__.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.SimpleClass +

+ +--- +## ::: ultralytics.utils.IterableSimpleNamespace +

+ +--- +## ::: ultralytics.utils.EmojiFilter +

+ +--- +## ::: ultralytics.utils.ThreadingLocked +

+ +--- +## ::: ultralytics.utils.TryExcept +

+ +--- +## ::: ultralytics.utils.SettingsManager +

+ +--- +## ::: ultralytics.utils.plt_settings +

+ +--- +## ::: ultralytics.utils.set_logging +

+ +--- +## ::: ultralytics.utils.emojis +

+ +--- +## ::: ultralytics.utils.yaml_save +

+ +--- +## ::: ultralytics.utils.yaml_load +

+ +--- +## ::: ultralytics.utils.yaml_print +

+ +--- +## ::: ultralytics.utils.is_ubuntu +

+ +--- +## ::: ultralytics.utils.is_colab +

+ +--- +## ::: ultralytics.utils.is_kaggle +

+ +--- +## ::: ultralytics.utils.is_jupyter +

+ +--- +## ::: ultralytics.utils.is_docker +

+ +--- +## ::: ultralytics.utils.is_online +

+ +--- +## ::: ultralytics.utils.is_pip_package +

+ +--- +## ::: ultralytics.utils.is_dir_writeable +

+ +--- +## ::: ultralytics.utils.is_pytest_running +

+ +--- +## ::: ultralytics.utils.is_github_actions_ci +

+ +--- +## ::: ultralytics.utils.is_git_dir +

+ +--- +## ::: ultralytics.utils.get_git_dir +

+ +--- +## ::: ultralytics.utils.get_git_origin_url +

+ +--- +## ::: ultralytics.utils.get_git_branch +

+ +--- +## ::: ultralytics.utils.get_default_args +

+ +--- +## ::: ultralytics.utils.get_ubuntu_version +

+ +--- +## ::: ultralytics.utils.get_user_config_dir +

+ +--- +## ::: ultralytics.utils.colorstr +

+ +--- +## ::: ultralytics.utils.threaded +

+ +--- +## ::: ultralytics.utils.set_sentry +

+ +--- +## ::: ultralytics.utils.deprecation_warn +

+ +--- +## ::: ultralytics.utils.clean_url +

+ +--- +## ::: ultralytics.utils.url2file +

diff --git a/downloads/ultralytics-main/docs/reference/utils/autobatch.md b/downloads/ultralytics-main/docs/reference/utils/autobatch.md new file mode 100644 index 000000000..630d5a37e --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/autobatch.md @@ -0,0 +1,18 @@ +--- +description: Explore Ultralytics documentation for check_train_batch_size utility in the autobatch module. Understand how it could improve your machine learning process. +keywords: Ultralytics, check_train_batch_size, autobatch, utility, machine learning, documentation +--- + +# Reference for `ultralytics/utils/autobatch.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/autobatch.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/autobatch.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.autobatch.check_train_batch_size +

+ +--- +## ::: ultralytics.utils.autobatch.autobatch +

diff --git a/downloads/ultralytics-main/docs/reference/utils/benchmarks.md b/downloads/ultralytics-main/docs/reference/utils/benchmarks.md new file mode 100644 index 000000000..63158b30a --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/benchmarks.md @@ -0,0 +1,18 @@ +--- +description: Discover how to profile your models using Ultralytics utilities. Enhance performance, optimize your benchmarks, and learn best practices. +keywords: Ultralytics, ProfileModels, benchmarks, model profiling, performance optimization +--- + +# Reference for `ultralytics/utils/benchmarks.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/benchmarks.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/benchmarks.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.benchmarks.ProfileModels +

+ +--- +## ::: ultralytics.utils.benchmarks.benchmark +

diff --git a/downloads/ultralytics-main/docs/reference/utils/callbacks/base.md b/downloads/ultralytics-main/docs/reference/utils/callbacks/base.md new file mode 100644 index 000000000..da304b03e --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/callbacks/base.md @@ -0,0 +1,118 @@ +--- +description: Explore how to use the on-train, on-validation, on-pretrain, and on-predict callbacks in Ultralytics. Learn to update params, save models, and add integration callbacks. +keywords: Ultralytics, Callbacks, On-train, On-validation, On-pretrain, On-predict, Parameters update, Model saving, Integration callbacks +--- + +# Reference for `ultralytics/utils/callbacks/base.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/base.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/base.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.callbacks.base.on_pretrain_routine_start +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_pretrain_routine_end +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_train_start +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_train_epoch_start +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_train_batch_start +

+ +--- +## ::: ultralytics.utils.callbacks.base.optimizer_step +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_before_zero_grad +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_train_batch_end +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_train_epoch_end +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_fit_epoch_end +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_model_save +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_train_end +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_params_update +

+ +--- +## ::: ultralytics.utils.callbacks.base.teardown +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_val_start +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_val_batch_start +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_val_batch_end +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_val_end +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_predict_start +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_predict_batch_start +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_predict_batch_end +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_predict_postprocess_end +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_predict_end +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_export_start +

+ +--- +## ::: ultralytics.utils.callbacks.base.on_export_end +

+ +--- +## ::: ultralytics.utils.callbacks.base.get_default_callbacks +

+ +--- +## ::: ultralytics.utils.callbacks.base.add_integration_callbacks +

diff --git a/downloads/ultralytics-main/docs/reference/utils/callbacks/clearml.md b/downloads/ultralytics-main/docs/reference/utils/callbacks/clearml.md new file mode 100644 index 000000000..5c81396ee --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/callbacks/clearml.md @@ -0,0 +1,38 @@ +--- +description: Uncover the specifics of Ultralytics ClearML callbacks, from pretrain routine start to training end. Boost your ML model performance. +keywords: Ultralytics, clearML, callbacks, pretrain routine start, validation end, train epoch end, training end +--- + +# Reference for `ultralytics/utils/callbacks/clearml.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/clearml.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/clearml.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.callbacks.clearml._log_debug_samples +

+ +--- +## ::: ultralytics.utils.callbacks.clearml._log_plot +

+ +--- +## ::: ultralytics.utils.callbacks.clearml.on_pretrain_routine_start +

+ +--- +## ::: ultralytics.utils.callbacks.clearml.on_train_epoch_end +

+ +--- +## ::: ultralytics.utils.callbacks.clearml.on_fit_epoch_end +

+ +--- +## ::: ultralytics.utils.callbacks.clearml.on_val_end +

+ +--- +## ::: ultralytics.utils.callbacks.clearml.on_train_end +

diff --git a/downloads/ultralytics-main/docs/reference/utils/callbacks/comet.md b/downloads/ultralytics-main/docs/reference/utils/callbacks/comet.md new file mode 100644 index 000000000..69ad9e33e --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/callbacks/comet.md @@ -0,0 +1,106 @@ +--- +description: Explore comprehensive documentation for utilising Comet Callbacks in Ultralytics. Learn to optimise training, logging, and experiment workflows. +keywords: Ultralytics, Comet Callbacks, Training optimisation, Logging, Experiment Workflows +--- + +# Reference for `ultralytics/utils/callbacks/comet.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/comet.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/comet.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.callbacks.comet._get_comet_mode +

+ +--- +## ::: ultralytics.utils.callbacks.comet._get_comet_model_name +

+ +--- +## ::: ultralytics.utils.callbacks.comet._get_eval_batch_logging_interval +

+ +--- +## ::: ultralytics.utils.callbacks.comet._get_max_image_predictions_to_log +

+ +--- +## ::: ultralytics.utils.callbacks.comet._scale_confidence_score +

+ +--- +## ::: ultralytics.utils.callbacks.comet._should_log_confusion_matrix +

+ +--- +## ::: ultralytics.utils.callbacks.comet._should_log_image_predictions +

+ +--- +## ::: ultralytics.utils.callbacks.comet._get_experiment_type +

+ +--- +## ::: ultralytics.utils.callbacks.comet._create_experiment +

+ +--- +## ::: ultralytics.utils.callbacks.comet._fetch_trainer_metadata +

+ +--- +## ::: ultralytics.utils.callbacks.comet._scale_bounding_box_to_original_image_shape +

+ +--- +## ::: ultralytics.utils.callbacks.comet._format_ground_truth_annotations_for_detection +

+ +--- +## ::: ultralytics.utils.callbacks.comet._format_prediction_annotations_for_detection +

+ +--- +## ::: ultralytics.utils.callbacks.comet._fetch_annotations +

+ +--- +## ::: ultralytics.utils.callbacks.comet._create_prediction_metadata_map +

+ +--- +## ::: ultralytics.utils.callbacks.comet._log_confusion_matrix +

+ +--- +## ::: ultralytics.utils.callbacks.comet._log_images +

+ +--- +## ::: ultralytics.utils.callbacks.comet._log_image_predictions +

+ +--- +## ::: ultralytics.utils.callbacks.comet._log_plots +

+ +--- +## ::: ultralytics.utils.callbacks.comet._log_model +

+ +--- +## ::: ultralytics.utils.callbacks.comet.on_pretrain_routine_start +

+ +--- +## ::: ultralytics.utils.callbacks.comet.on_train_epoch_end +

+ +--- +## ::: ultralytics.utils.callbacks.comet.on_fit_epoch_end +

+ +--- +## ::: ultralytics.utils.callbacks.comet.on_train_end +

diff --git a/downloads/ultralytics-main/docs/reference/utils/callbacks/dvc.md b/downloads/ultralytics-main/docs/reference/utils/callbacks/dvc.md new file mode 100644 index 000000000..634740d16 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/callbacks/dvc.md @@ -0,0 +1,46 @@ +--- +description: Browse through Ultralytics YOLO docs to learn about important logging and callback functions used in training and pretraining models. +keywords: Ultralytics, YOLO, callbacks, logger, training, pretraining, machine learning, models +--- + +# Reference for `ultralytics/utils/callbacks/dvc.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/dvc.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/dvc.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.callbacks.dvc._log_images +

+ +--- +## ::: ultralytics.utils.callbacks.dvc._log_plots +

+ +--- +## ::: ultralytics.utils.callbacks.dvc._log_confusion_matrix +

+ +--- +## ::: ultralytics.utils.callbacks.dvc.on_pretrain_routine_start +

+ +--- +## ::: ultralytics.utils.callbacks.dvc.on_pretrain_routine_end +

+ +--- +## ::: ultralytics.utils.callbacks.dvc.on_train_start +

+ +--- +## ::: ultralytics.utils.callbacks.dvc.on_train_epoch_start +

+ +--- +## ::: ultralytics.utils.callbacks.dvc.on_fit_epoch_end +

+ +--- +## ::: ultralytics.utils.callbacks.dvc.on_train_end +

diff --git a/downloads/ultralytics-main/docs/reference/utils/callbacks/hub.md b/downloads/ultralytics-main/docs/reference/utils/callbacks/hub.md new file mode 100644 index 000000000..db7f9144a --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/callbacks/hub.md @@ -0,0 +1,42 @@ +--- +description: Explore the detailed information on key Ultralytics callbacks such as on_pretrain_routine_end, on_model_save, on_train_start, and on_predict_start. +keywords: Ultralytics, callbacks, on_pretrain_routine_end, on_model_save, on_train_start, on_predict_start, hub, training +--- + +# Reference for `ultralytics/utils/callbacks/hub.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/hub.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/hub.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.callbacks.hub.on_pretrain_routine_end +

+ +--- +## ::: ultralytics.utils.callbacks.hub.on_fit_epoch_end +

+ +--- +## ::: ultralytics.utils.callbacks.hub.on_model_save +

+ +--- +## ::: ultralytics.utils.callbacks.hub.on_train_end +

+ +--- +## ::: ultralytics.utils.callbacks.hub.on_train_start +

+ +--- +## ::: ultralytics.utils.callbacks.hub.on_val_start +

+ +--- +## ::: ultralytics.utils.callbacks.hub.on_predict_start +

+ +--- +## ::: ultralytics.utils.callbacks.hub.on_export_start +

diff --git a/downloads/ultralytics-main/docs/reference/utils/callbacks/mlflow.md b/downloads/ultralytics-main/docs/reference/utils/callbacks/mlflow.md new file mode 100644 index 000000000..6b5d01e38 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/callbacks/mlflow.md @@ -0,0 +1,22 @@ +--- +description: Understand routines at the end of pre-training and training in Ultralytics. Elevate your MLflow callbacks expertise. +keywords: Ultralytics, MLflow, Callbacks, on_pretrain_routine_end, on_train_end, Machine Learning, Training +--- + +# Reference for `ultralytics/utils/callbacks/mlflow.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/mlflow.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/mlflow.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.callbacks.mlflow.on_pretrain_routine_end +

+ +--- +## ::: ultralytics.utils.callbacks.mlflow.on_fit_epoch_end +

+ +--- +## ::: ultralytics.utils.callbacks.mlflow.on_train_end +

diff --git a/downloads/ultralytics-main/docs/reference/utils/callbacks/neptune.md b/downloads/ultralytics-main/docs/reference/utils/callbacks/neptune.md new file mode 100644 index 000000000..08cfccc5f --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/callbacks/neptune.md @@ -0,0 +1,42 @@ +--- +description: Explore exhaustive details about Ultralytics callbacks in Neptune, with specifics about scalar logging, routine start, and more. +keywords: Ultralytics, Neptune callbacks, on_train_epoch_end, on_val_end, _log_plot, _log_images, on_pretrain_routine_start, on_fit_epoch_end, on_train_end +--- + +# Reference for `ultralytics/utils/callbacks/neptune.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/neptune.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/neptune.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.callbacks.neptune._log_scalars +

+ +--- +## ::: ultralytics.utils.callbacks.neptune._log_images +

+ +--- +## ::: ultralytics.utils.callbacks.neptune._log_plot +

+ +--- +## ::: ultralytics.utils.callbacks.neptune.on_pretrain_routine_start +

+ +--- +## ::: ultralytics.utils.callbacks.neptune.on_train_epoch_end +

+ +--- +## ::: ultralytics.utils.callbacks.neptune.on_fit_epoch_end +

+ +--- +## ::: ultralytics.utils.callbacks.neptune.on_val_end +

+ +--- +## ::: ultralytics.utils.callbacks.neptune.on_train_end +

diff --git a/downloads/ultralytics-main/docs/reference/utils/callbacks/raytune.md b/downloads/ultralytics-main/docs/reference/utils/callbacks/raytune.md new file mode 100644 index 000000000..a58ae7929 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/callbacks/raytune.md @@ -0,0 +1,14 @@ +--- +description: Discover the functionality of the on_fit_epoch_end callback in the Ultralytics YOLO framework. Learn how to end an epoch in your deep learning projects. +keywords: Ultralytics, YOLO, on_fit_epoch_end, callbacks, documentation, deep learning, YOLO framework +--- + +# Reference for `ultralytics/utils/callbacks/raytune.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/raytune.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/raytune.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.callbacks.raytune.on_fit_epoch_end +

diff --git a/downloads/ultralytics-main/docs/reference/utils/callbacks/tensorboard.md b/downloads/ultralytics-main/docs/reference/utils/callbacks/tensorboard.md new file mode 100644 index 000000000..95db26859 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/callbacks/tensorboard.md @@ -0,0 +1,30 @@ +--- +description: Explore Ultralytics YOLO Docs for a deep understanding of log_scalars, on_batch_end & other callback utilities embedded in the tensorboard module. +keywords: Ultralytics, YOLO, documentation, callback utilities, log_scalars, on_batch_end, tensorboard +--- + +# Reference for `ultralytics/utils/callbacks/tensorboard.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/tensorboard.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/tensorboard.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.callbacks.tensorboard._log_scalars +

+ +--- +## ::: ultralytics.utils.callbacks.tensorboard._log_tensorboard_graph +

+ +--- +## ::: ultralytics.utils.callbacks.tensorboard.on_pretrain_routine_start +

+ +--- +## ::: ultralytics.utils.callbacks.tensorboard.on_batch_end +

+ +--- +## ::: ultralytics.utils.callbacks.tensorboard.on_fit_epoch_end +

diff --git a/downloads/ultralytics-main/docs/reference/utils/callbacks/wb.md b/downloads/ultralytics-main/docs/reference/utils/callbacks/wb.md new file mode 100644 index 000000000..a5869a5e5 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/callbacks/wb.md @@ -0,0 +1,30 @@ +--- +description: Deep dive into Ultralytics callbacks. Learn how to use the _log_plots, on_fit_epoch_end, and on_train_end functions effectively. +keywords: Ultralytics, callbacks, _log_plots, on_fit_epoch_end, on_train_end +--- + +# Reference for `ultralytics/utils/callbacks/wb.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/wb.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/wb.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.callbacks.wb._log_plots +

+ +--- +## ::: ultralytics.utils.callbacks.wb.on_pretrain_routine_start +

+ +--- +## ::: ultralytics.utils.callbacks.wb.on_fit_epoch_end +

+ +--- +## ::: ultralytics.utils.callbacks.wb.on_train_epoch_end +

+ +--- +## ::: ultralytics.utils.callbacks.wb.on_train_end +

diff --git a/downloads/ultralytics-main/docs/reference/utils/checks.md b/downloads/ultralytics-main/docs/reference/utils/checks.md new file mode 100644 index 000000000..96c45080b --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/checks.md @@ -0,0 +1,82 @@ +--- +description: Learn about our routine checks that safeguard Ultralytics operations including ASCII, font, YOLO file, YAML, Python and torchvision checks. +keywords: Ultralytics, utility checks, ASCII, check_version, pip_update, check_python, check_torchvision, check_yaml, YOLO filename +--- + +# Reference for `ultralytics/utils/checks.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/checks.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/checks.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.checks.is_ascii +

+ +--- +## ::: ultralytics.utils.checks.check_imgsz +

+ +--- +## ::: ultralytics.utils.checks.check_version +

+ +--- +## ::: ultralytics.utils.checks.check_latest_pypi_version +

+ +--- +## ::: ultralytics.utils.checks.check_pip_update_available +

+ +--- +## ::: ultralytics.utils.checks.check_font +

+ +--- +## ::: ultralytics.utils.checks.check_python +

+ +--- +## ::: ultralytics.utils.checks.check_requirements +

+ +--- +## ::: ultralytics.utils.checks.check_torchvision +

+ +--- +## ::: ultralytics.utils.checks.check_suffix +

+ +--- +## ::: ultralytics.utils.checks.check_yolov5u_filename +

+ +--- +## ::: ultralytics.utils.checks.check_file +

+ +--- +## ::: ultralytics.utils.checks.check_yaml +

+ +--- +## ::: ultralytics.utils.checks.check_imshow +

+ +--- +## ::: ultralytics.utils.checks.check_yolo +

+ +--- +## ::: ultralytics.utils.checks.check_amp +

+ +--- +## ::: ultralytics.utils.checks.git_describe +

+ +--- +## ::: ultralytics.utils.checks.print_args +

diff --git a/downloads/ultralytics-main/docs/reference/utils/dist.md b/downloads/ultralytics-main/docs/reference/utils/dist.md new file mode 100644 index 000000000..3beef943b --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/dist.md @@ -0,0 +1,26 @@ +--- +description: Discover the role of dist.find_free_network_port & dist.generate_ddp_command in Ultralytics DDP utilities. Use our guide for efficient deployment. +keywords: Ultralytics, DDP, DDP utility functions, Distributed Data Processing, find free network port, generate DDP command +--- + +# Reference for `ultralytics/utils/dist.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/dist.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/dist.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.dist.find_free_network_port +

+ +--- +## ::: ultralytics.utils.dist.generate_ddp_file +

+ +--- +## ::: ultralytics.utils.dist.generate_ddp_command +

+ +--- +## ::: ultralytics.utils.dist.ddp_cleanup +

diff --git a/downloads/ultralytics-main/docs/reference/utils/downloads.md b/downloads/ultralytics-main/docs/reference/utils/downloads.md new file mode 100644 index 000000000..502322c92 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/downloads.md @@ -0,0 +1,50 @@ +--- +description: Learn about the download utilities in Ultralytics YOLO, featuring functions like is_url, check_disk_space, get_github_assets, and download. +keywords: Ultralytics, YOLO, download utilities, is_url, check_disk_space, get_github_assets, download, documentation +--- + +# Reference for `ultralytics/utils/downloads.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/downloads.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/downloads.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.downloads.is_url +

+ +--- +## ::: ultralytics.utils.downloads.delete_dsstore +

+ +--- +## ::: ultralytics.utils.downloads.zip_directory +

+ +--- +## ::: ultralytics.utils.downloads.unzip_file +

+ +--- +## ::: ultralytics.utils.downloads.check_disk_space +

+ +--- +## ::: ultralytics.utils.downloads.get_google_drive_file_info +

+ +--- +## ::: ultralytics.utils.downloads.safe_download +

+ +--- +## ::: ultralytics.utils.downloads.get_github_assets +

+ +--- +## ::: ultralytics.utils.downloads.attempt_download_asset +

+ +--- +## ::: ultralytics.utils.downloads.download +

diff --git a/downloads/ultralytics-main/docs/reference/utils/errors.md b/downloads/ultralytics-main/docs/reference/utils/errors.md new file mode 100644 index 000000000..dfa9c188d --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/errors.md @@ -0,0 +1,14 @@ +--- +description: Learn about the HUBModelError in Ultralytics. Enhance your understanding, troubleshoot errors and optimize your machine learning projects. +keywords: Ultralytics, HUBModelError, Machine Learning, Error troubleshooting, Ultralytics documentation +--- + +# Reference for `ultralytics/utils/errors.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/errors.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/errors.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.errors.HUBModelError +

diff --git a/downloads/ultralytics-main/docs/reference/utils/files.md b/downloads/ultralytics-main/docs/reference/utils/files.md new file mode 100644 index 000000000..0a65bee0c --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/files.md @@ -0,0 +1,38 @@ +--- +description: Discover how to use Ultralytics utility functions for file-related operations including incrementing paths, finding file age, checking file size and creating directories. +keywords: Ultralytics, utility functions, file operations, working directory, file age, file size, create directories +--- + +# Reference for `ultralytics/utils/files.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/files.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/files.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.files.WorkingDirectory +

+ +--- +## ::: ultralytics.utils.files.spaces_in_path +

+ +--- +## ::: ultralytics.utils.files.increment_path +

+ +--- +## ::: ultralytics.utils.files.file_age +

+ +--- +## ::: ultralytics.utils.files.file_date +

+ +--- +## ::: ultralytics.utils.files.file_size +

+ +--- +## ::: ultralytics.utils.files.get_latest_run +

diff --git a/downloads/ultralytics-main/docs/reference/utils/instance.md b/downloads/ultralytics-main/docs/reference/utils/instance.md new file mode 100644 index 000000000..8b78f51d5 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/instance.md @@ -0,0 +1,22 @@ +--- +description: Dive into Ultralytics detailed utility guide. Learn about Bboxes, _ntuple and more from Ultralytics utils.instance module. +keywords: Ultralytics, Bboxes, _ntuple, utility, ultralytics utils.instance +--- + +# Reference for `ultralytics/utils/instance.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/instance.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/instance.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.instance.Bboxes +

+ +--- +## ::: ultralytics.utils.instance.Instances +

+ +--- +## ::: ultralytics.utils.instance._ntuple +

diff --git a/downloads/ultralytics-main/docs/reference/utils/loss.md b/downloads/ultralytics-main/docs/reference/utils/loss.md new file mode 100644 index 000000000..ea391cd75 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/loss.md @@ -0,0 +1,42 @@ +--- +description: Explore Ultralytics' versatile loss functions - VarifocalLoss, BboxLoss, v8DetectionLoss, v8PoseLoss. Improve your accuracy on YOLO implementations. +keywords: Ultralytics, Loss functions, VarifocalLoss, BboxLoss, v8DetectionLoss, v8PoseLoss, YOLO, Ultralytics Documentation +--- + +# Reference for `ultralytics/utils/loss.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/loss.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/loss.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.loss.VarifocalLoss +

+ +--- +## ::: ultralytics.utils.loss.FocalLoss +

+ +--- +## ::: ultralytics.utils.loss.BboxLoss +

+ +--- +## ::: ultralytics.utils.loss.KeypointLoss +

+ +--- +## ::: ultralytics.utils.loss.v8DetectionLoss +

+ +--- +## ::: ultralytics.utils.loss.v8SegmentationLoss +

+ +--- +## ::: ultralytics.utils.loss.v8PoseLoss +

+ +--- +## ::: ultralytics.utils.loss.v8ClassificationLoss +

diff --git a/downloads/ultralytics-main/docs/reference/utils/metrics.md b/downloads/ultralytics-main/docs/reference/utils/metrics.md new file mode 100644 index 000000000..9b762404c --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/metrics.md @@ -0,0 +1,78 @@ +--- +description: Explore Ultralytics YOLO metrics tools - from confusion matrix, detection metrics, pose metrics to box IOU. Learn how to compute and plot precision-recall curves. +keywords: Ultralytics, YOLO, YOLOv3, YOLOv4, metrics, confusion matrix, detection metrics, pose metrics, box IOU, mask IOU, plot precision-recall curves, compute average precision +--- + +# Reference for `ultralytics/utils/metrics.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/metrics.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/metrics.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.metrics.ConfusionMatrix +

+ +--- +## ::: ultralytics.utils.metrics.Metric +

+ +--- +## ::: ultralytics.utils.metrics.DetMetrics +

+ +--- +## ::: ultralytics.utils.metrics.SegmentMetrics +

+ +--- +## ::: ultralytics.utils.metrics.PoseMetrics +

+ +--- +## ::: ultralytics.utils.metrics.ClassifyMetrics +

+ +--- +## ::: ultralytics.utils.metrics.bbox_ioa +

+ +--- +## ::: ultralytics.utils.metrics.box_iou +

+ +--- +## ::: ultralytics.utils.metrics.bbox_iou +

+ +--- +## ::: ultralytics.utils.metrics.mask_iou +

+ +--- +## ::: ultralytics.utils.metrics.kpt_iou +

+ +--- +## ::: ultralytics.utils.metrics.smooth_BCE +

+ +--- +## ::: ultralytics.utils.metrics.smooth +

+ +--- +## ::: ultralytics.utils.metrics.plot_pr_curve +

+ +--- +## ::: ultralytics.utils.metrics.plot_mc_curve +

+ +--- +## ::: ultralytics.utils.metrics.compute_ap +

+ +--- +## ::: ultralytics.utils.metrics.ap_per_class +

diff --git a/downloads/ultralytics-main/docs/reference/utils/ops.md b/downloads/ultralytics-main/docs/reference/utils/ops.md new file mode 100644 index 000000000..9595f5ee0 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/ops.md @@ -0,0 +1,122 @@ +--- +description: Explore detailed documentation for Ultralytics utility operations. Learn about methods like segment2box, make_divisible, clip_boxes, and many more. +keywords: Ultralytics YOLO, Utility Operations, segment2box, make_divisible, clip_boxes, scale_image, xywh2xyxy, xyxy2xywhn, xywh2ltwh, ltwh2xywh, segments2boxes, crop_mask, process_mask, scale_masks, masks2segments +--- + +# Reference for `ultralytics/utils/ops.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/ops.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/ops.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.ops.Profile +

+ +--- +## ::: ultralytics.utils.ops.segment2box +

+ +--- +## ::: ultralytics.utils.ops.scale_boxes +

+ +--- +## ::: ultralytics.utils.ops.make_divisible +

+ +--- +## ::: ultralytics.utils.ops.non_max_suppression +

+ +--- +## ::: ultralytics.utils.ops.clip_boxes +

+ +--- +## ::: ultralytics.utils.ops.clip_coords +

+ +--- +## ::: ultralytics.utils.ops.scale_image +

+ +--- +## ::: ultralytics.utils.ops.xyxy2xywh +

+ +--- +## ::: ultralytics.utils.ops.xywh2xyxy +

+ +--- +## ::: ultralytics.utils.ops.xywhn2xyxy +

+ +--- +## ::: ultralytics.utils.ops.xyxy2xywhn +

+ +--- +## ::: ultralytics.utils.ops.xywh2ltwh +

+ +--- +## ::: ultralytics.utils.ops.xyxy2ltwh +

+ +--- +## ::: ultralytics.utils.ops.ltwh2xywh +

+ +--- +## ::: ultralytics.utils.ops.xyxyxyxy2xywhr +

+ +--- +## ::: ultralytics.utils.ops.xywhr2xyxyxyxy +

+ +--- +## ::: ultralytics.utils.ops.ltwh2xyxy +

+ +--- +## ::: ultralytics.utils.ops.segments2boxes +

+ +--- +## ::: ultralytics.utils.ops.resample_segments +

+ +--- +## ::: ultralytics.utils.ops.crop_mask +

+ +--- +## ::: ultralytics.utils.ops.process_mask_upsample +

+ +--- +## ::: ultralytics.utils.ops.process_mask +

+ +--- +## ::: ultralytics.utils.ops.process_mask_native +

+ +--- +## ::: ultralytics.utils.ops.scale_masks +

+ +--- +## ::: ultralytics.utils.ops.scale_coords +

+ +--- +## ::: ultralytics.utils.ops.masks2segments +

+ +--- +## ::: ultralytics.utils.ops.clean_str +

diff --git a/downloads/ultralytics-main/docs/reference/utils/patches.md b/downloads/ultralytics-main/docs/reference/utils/patches.md new file mode 100644 index 000000000..49a2480de --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/patches.md @@ -0,0 +1,26 @@ +--- +description: Learn about Ultralytics utils patches including imread, imshow and torch_save. Enhance your image processing skills. +keywords: Ultralytics, Utils, Patches, imread, imshow, torch_save, image processing +--- + +# Reference for `ultralytics/utils/patches.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/patches.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/patches.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.patches.imread +

+ +--- +## ::: ultralytics.utils.patches.imwrite +

+ +--- +## ::: ultralytics.utils.patches.imshow +

+ +--- +## ::: ultralytics.utils.patches.torch_save +

diff --git a/downloads/ultralytics-main/docs/reference/utils/plotting.md b/downloads/ultralytics-main/docs/reference/utils/plotting.md new file mode 100644 index 000000000..a0c28b13c --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/plotting.md @@ -0,0 +1,42 @@ +--- +description: Master advanced plotting utils from Ultralytics including color annotations, label and image plotting, and feature visualization. +keywords: Ultralytics, plotting, utils, color annotation, label plotting, image plotting, feature visualization +--- + +# Reference for `ultralytics/utils/plotting.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/plotting.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/plotting.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.plotting.Colors +

+ +--- +## ::: ultralytics.utils.plotting.Annotator +

+ +--- +## ::: ultralytics.utils.plotting.plot_labels +

+ +--- +## ::: ultralytics.utils.plotting.save_one_box +

+ +--- +## ::: ultralytics.utils.plotting.plot_images +

+ +--- +## ::: ultralytics.utils.plotting.plot_results +

+ +--- +## ::: ultralytics.utils.plotting.output_to_target +

+ +--- +## ::: ultralytics.utils.plotting.feature_visualization +

diff --git a/downloads/ultralytics-main/docs/reference/utils/tal.md b/downloads/ultralytics-main/docs/reference/utils/tal.md new file mode 100644 index 000000000..23d2be719 --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/tal.md @@ -0,0 +1,34 @@ +--- +description: Explore Ultralytics utilities for optimized task assignment, bounding box creation, and distance calculation. Learn more about algorithm implementations. +keywords: Ultralytics, task aligned assigner, select highest overlaps, make anchors, dist2bbox, bbox2dist, utilities, algorithm +--- + +# Reference for `ultralytics/utils/tal.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/tal.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/tal.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.tal.TaskAlignedAssigner +

+ +--- +## ::: ultralytics.utils.tal.select_candidates_in_gts +

+ +--- +## ::: ultralytics.utils.tal.select_highest_overlaps +

+ +--- +## ::: ultralytics.utils.tal.make_anchors +

+ +--- +## ::: ultralytics.utils.tal.dist2bbox +

+ +--- +## ::: ultralytics.utils.tal.bbox2dist +

diff --git a/downloads/ultralytics-main/docs/reference/utils/torch_utils.md b/downloads/ultralytics-main/docs/reference/utils/torch_utils.md new file mode 100644 index 000000000..d2fdde00a --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/torch_utils.md @@ -0,0 +1,118 @@ +--- +description: Explore Ultralytics-tailored torch utility features like Model EMA, early stopping, smart inference, image scaling, get_flops, and many more. +keywords: Ultralytics, Torch Utils, Model EMA, Early Stopping, Smart Inference, Get CPU Info, Time Sync, Fuse Deconv and bn, Get num params, Get FLOPs, Scale img, Copy attr, Intersect dicts, De_parallel, Init seeds, Profile +--- + +# Reference for `ultralytics/utils/torch_utils.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/torch_utils.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/torch_utils.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.torch_utils.ModelEMA +

+ +--- +## ::: ultralytics.utils.torch_utils.EarlyStopping +

+ +--- +## ::: ultralytics.utils.torch_utils.torch_distributed_zero_first +

+ +--- +## ::: ultralytics.utils.torch_utils.smart_inference_mode +

+ +--- +## ::: ultralytics.utils.torch_utils.get_cpu_info +

+ +--- +## ::: ultralytics.utils.torch_utils.select_device +

+ +--- +## ::: ultralytics.utils.torch_utils.time_sync +

+ +--- +## ::: ultralytics.utils.torch_utils.fuse_conv_and_bn +

+ +--- +## ::: ultralytics.utils.torch_utils.fuse_deconv_and_bn +

+ +--- +## ::: ultralytics.utils.torch_utils.model_info +

+ +--- +## ::: ultralytics.utils.torch_utils.get_num_params +

+ +--- +## ::: ultralytics.utils.torch_utils.get_num_gradients +

+ +--- +## ::: ultralytics.utils.torch_utils.model_info_for_loggers +

+ +--- +## ::: ultralytics.utils.torch_utils.get_flops +

+ +--- +## ::: ultralytics.utils.torch_utils.get_flops_with_torch_profiler +

+ +--- +## ::: ultralytics.utils.torch_utils.initialize_weights +

+ +--- +## ::: ultralytics.utils.torch_utils.scale_img +

+ +--- +## ::: ultralytics.utils.torch_utils.make_divisible +

+ +--- +## ::: ultralytics.utils.torch_utils.copy_attr +

+ +--- +## ::: ultralytics.utils.torch_utils.get_latest_opset +

+ +--- +## ::: ultralytics.utils.torch_utils.intersect_dicts +

+ +--- +## ::: ultralytics.utils.torch_utils.is_parallel +

+ +--- +## ::: ultralytics.utils.torch_utils.de_parallel +

+ +--- +## ::: ultralytics.utils.torch_utils.one_cycle +

+ +--- +## ::: ultralytics.utils.torch_utils.init_seeds +

+ +--- +## ::: ultralytics.utils.torch_utils.strip_optimizer +

+ +--- +## ::: ultralytics.utils.torch_utils.profile +

diff --git a/downloads/ultralytics-main/docs/reference/utils/tuner.md b/downloads/ultralytics-main/docs/reference/utils/tuner.md new file mode 100644 index 000000000..fc9c8a06e --- /dev/null +++ b/downloads/ultralytics-main/docs/reference/utils/tuner.md @@ -0,0 +1,14 @@ +--- +description: Learn to utilize the run_ray_tune function with Ultralytics. Make your machine learning tuning process easier and more efficient. +keywords: Ultralytics, run_ray_tune, machine learning tuning, machine learning efficiency +--- + +# Reference for `ultralytics/utils/tuner.py` + +!!! note + + Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/tuner.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/tuner.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏! + +--- +## ::: ultralytics.utils.tuner.run_ray_tune +

diff --git a/downloads/ultralytics-main/docs/stylesheets/style.css b/downloads/ultralytics-main/docs/stylesheets/style.css index 8a13d2bc8..31a529ba0 100644 --- a/downloads/ultralytics-main/docs/stylesheets/style.css +++ b/downloads/ultralytics-main/docs/stylesheets/style.css @@ -33,6 +33,7 @@ th, td { /* Table format like GitHub ----------------------------------------------------------------------------------------- */ /* Code block vertical scroll */ -.md-typeset pre > code { +div.highlight { max-height: 20rem; -} \ No newline at end of file + overflow-y: auto; /* for adding a scrollbar when needed */ +} diff --git a/downloads/ultralytics-main/docs/tasks/classify.md b/downloads/ultralytics-main/docs/tasks/classify.md index 8411e2b25..1abd86c32 100644 --- a/downloads/ultralytics-main/docs/tasks/classify.md +++ b/downloads/ultralytics-main/docs/tasks/classify.md @@ -1,12 +1,13 @@ --- comments: true -description: Check YOLO class label with only one class for the whole image, using image classification. Get strategies for training and validation models. +description: Learn about YOLOv8 Classify models for image classification. Get detailed information on List of Pretrained Models & how to Train, Validate, Predict & Export models. +keywords: Ultralytics, YOLOv8, Image Classification, Pretrained Models, YOLOv8n-cls, Training, Validation, Prediction, Model Export --- Image classification is the simplest of the three tasks and involves classifying an entire image into one of a set of predefined classes. - + The output of an image classifier is a single class label and a confidence score. Image classification is useful when you need to know only what class an image belongs to and don't need to know where objects @@ -14,16 +15,16 @@ of that class are located or what their exact shape is. !!! tip "Tip" - YOLOv8 Classify models use the `-cls` suffix, i.e. `yolov8n-cls.pt` and are pretrained on [ImageNet](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/ImageNet.yaml). + YOLOv8 Classify models use the `-cls` suffix, i.e. `yolov8n-cls.pt` and are pretrained on [ImageNet](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/datasets/ImageNet.yaml). -## [Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models/v8) +## [Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models/v8) YOLOv8 pretrained Classify models are shown here. Detect, Segment and Pose models are pretrained on -the [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/coco.yaml) dataset, while Classify +the [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/datasets/coco.yaml) dataset, while Classify models are pretrained on -the [ImageNet](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/ImageNet.yaml) dataset. +the [ImageNet](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/datasets/ImageNet.yaml) dataset. -[Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models) download automatically from the latest +[Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models) download automatically from the latest Ultralytics [release](https://github.com/ultralytics/assets/releases) on first use. | Model | size
(pixels) | acc
top1 | acc
top5 | Speed
CPU ONNX
(ms) | Speed
A100 TensorRT
(ms) | params
(M) | FLOPs
(B) at 640 | @@ -48,17 +49,17 @@ see the [Configuration](../usage/cfg.md) page. !!! example "" === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n-cls.yaml') # build a new model from YAML model = YOLO('yolov8n-cls.pt') # load a pretrained model (recommended for training) model = YOLO('yolov8n-cls.yaml').load('yolov8n-cls.pt') # build from YAML and transfer weights - + # Train the model - model.train(data='mnist160', epochs=100, imgsz=64) + results = model.train(data='mnist160', epochs=100, imgsz=64) ``` === "CLI" @@ -76,21 +77,7 @@ see the [Configuration](../usage/cfg.md) page. ### Dataset format -The YOLO classification dataset format is same as the torchvision format. Each class of images has its own folder and you have to simply pass the path of the dataset folder, i.e, `yolo classify train data="path/to/dataset"` - -``` -dataset/ -├── train/ -├──── class1/ -├──── class2/ -├──── class3/ -├──── ... -├── val/ -├──── class1/ -├──── class2/ -├──── class3/ -├──── ... -``` +YOLO classification dataset format can be found in detail in the [Dataset Guide](../datasets/classify/index.md). ## Val @@ -100,21 +87,21 @@ it's training `data` and arguments as model attributes. !!! example "" === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n-cls.pt') # load an official model model = YOLO('path/to/best.pt') # load a custom model - + # Validate the model metrics = model.val() # no arguments needed, dataset and settings remembered metrics.top1 # top1 accuracy metrics.top5 # top5 accuracy ``` === "CLI" - + ```bash yolo classify val model=yolov8n-cls.pt # val official model yolo classify val model=path/to/best.pt # val custom model @@ -127,19 +114,19 @@ Use a trained YOLOv8n-cls model to run predictions on images. !!! example "" === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n-cls.pt') # load an official model model = YOLO('path/to/best.pt') # load a custom model - + # Predict with the model results = model('https://ultralytics.com/images/bus.jpg') # predict on an image ``` === "CLI" - + ```bash yolo classify predict model=yolov8n-cls.pt source='https://ultralytics.com/images/bus.jpg' # predict with official model yolo classify predict model=path/to/best.pt source='https://ultralytics.com/images/bus.jpg' # predict with custom model @@ -154,19 +141,19 @@ Export a YOLOv8n-cls model to a different format like ONNX, CoreML, etc. !!! example "" === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n-cls.pt') # load an official model model = YOLO('path/to/best.pt') # load a custom trained - + # Export the model model.export(format='onnx') ``` === "CLI" - + ```bash yolo export model=yolov8n-cls.pt format=onnx # export official model yolo export model=path/to/best.pt format=onnx # export custom trained model @@ -182,12 +169,13 @@ i.e. `yolo predict model=yolov8n-cls.onnx`. Usage examples are shown for your mo | [ONNX](https://onnx.ai/) | `onnx` | `yolov8n-cls.onnx` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `opset` | | [OpenVINO](https://docs.openvino.ai/latest/index.html) | `openvino` | `yolov8n-cls_openvino_model/` | ✅ | `imgsz`, `half` | | [TensorRT](https://developer.nvidia.com/tensorrt) | `engine` | `yolov8n-cls.engine` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `workspace` | -| [CoreML](https://github.com/apple/coremltools) | `coreml` | `yolov8n-cls.mlmodel` | ✅ | `imgsz`, `half`, `int8`, `nms` | +| [CoreML](https://github.com/apple/coremltools) | `coreml` | `yolov8n-cls.mlpackage` | ✅ | `imgsz`, `half`, `int8`, `nms` | | [TF SavedModel](https://www.tensorflow.org/guide/saved_model) | `saved_model` | `yolov8n-cls_saved_model/` | ✅ | `imgsz`, `keras` | | [TF GraphDef](https://www.tensorflow.org/api_docs/python/tf/Graph) | `pb` | `yolov8n-cls.pb` | ❌ | `imgsz` | | [TF Lite](https://www.tensorflow.org/lite) | `tflite` | `yolov8n-cls.tflite` | ✅ | `imgsz`, `half`, `int8` | | [TF Edge TPU](https://coral.ai/docs/edgetpu/models-intro/) | `edgetpu` | `yolov8n-cls_edgetpu.tflite` | ✅ | `imgsz` | | [TF.js](https://www.tensorflow.org/js) | `tfjs` | `yolov8n-cls_web_model/` | ✅ | `imgsz` | | [PaddlePaddle](https://github.com/PaddlePaddle) | `paddle` | `yolov8n-cls_paddle_model/` | ✅ | `imgsz` | +| [ncnn](https://github.com/Tencent/ncnn) | `ncnn` | `yolov8n-cls_ncnn_model/` | ✅ | `imgsz`, `half` | -See full `export` details in the [Export](https://docs.ultralytics.com/modes/export/) page. \ No newline at end of file +See full `export` details in the [Export](https://docs.ultralytics.com/modes/export/) page. diff --git a/downloads/ultralytics-main/docs/tasks/detect.md b/downloads/ultralytics-main/docs/tasks/detect.md index a3e5728c3..29609e6c6 100644 --- a/downloads/ultralytics-main/docs/tasks/detect.md +++ b/downloads/ultralytics-main/docs/tasks/detect.md @@ -1,23 +1,24 @@ --- comments: true -description: Learn how to use YOLOv8, an object detection model pre-trained with COCO and about the different YOLOv8 models and how to train and export them. +description: Official documentation for YOLOv8 by Ultralytics. Learn how to train, validate, predict and export models in various formats. Including detailed performance stats. +keywords: YOLOv8, Ultralytics, object detection, pretrained models, training, validation, prediction, export models, COCO, ImageNet, PyTorch, ONNX, CoreML --- Object detection is a task that involves identifying the location and class of objects in an image or video stream. - + The output of an object detector is a set of bounding boxes that enclose the objects in the image, along with class labels and confidence scores for each box. Object detection is a good choice when you need to identify objects of interest in a scene, but don't need to know exactly where the object is or its exact shape. !!! tip "Tip" - YOLOv8 Detect models are the default YOLOv8 models, i.e. `yolov8n.pt` and are pretrained on [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/coco.yaml). + YOLOv8 Detect models are the default YOLOv8 models, i.e. `yolov8n.pt` and are pretrained on [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/datasets/coco.yaml). -## [Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models/v8) +## [Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models/v8) -YOLOv8 pretrained Detect models are shown here. Detect, Segment and Pose models are pretrained on the [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/coco.yaml) dataset, while Classify models are pretrained on the [ImageNet](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/ImageNet.yaml) dataset. +YOLOv8 pretrained Detect models are shown here. Detect, Segment and Pose models are pretrained on the [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/datasets/coco.yaml) dataset, while Classify models are pretrained on the [ImageNet](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/datasets/ImageNet.yaml) dataset. -[Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models) download automatically from the latest Ultralytics [release](https://github.com/ultralytics/assets/releases) on first use. +[Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models) download automatically from the latest Ultralytics [release](https://github.com/ultralytics/assets/releases) on first use. | Model | size
(pixels) | mAPval
50-95 | Speed
CPU ONNX
(ms) | Speed
A100 TensorRT
(ms) | params
(M) | FLOPs
(B) | |--------------------------------------------------------------------------------------|-----------------------|----------------------|--------------------------------|-------------------------------------|--------------------|-------------------| @@ -40,20 +41,20 @@ Train YOLOv8n on the COCO128 dataset for 100 epochs at image size 640. For a ful !!! example "" === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n.yaml') # build a new model from YAML model = YOLO('yolov8n.pt') # load a pretrained model (recommended for training) model = YOLO('yolov8n.yaml').load('yolov8n.pt') # build from YAML and transfer weights - + # Train the model - model.train(data='coco128.yaml', epochs=100, imgsz=640) + results = model.train(data='coco128.yaml', epochs=100, imgsz=640) ``` === "CLI" - + ```bash # Build a new model from YAML and start training from scratch yolo detect train data=coco128.yaml model=yolov8n.yaml epochs=100 imgsz=640 @@ -67,7 +68,7 @@ Train YOLOv8n on the COCO128 dataset for 100 epochs at image size 640. For a ful ### Dataset format -YOLO detection dataset format can be found in detail in the [Dataset Guide](../yolov5/tutorials/train_custom_data.md). To convert your existing dataset from other formats( like COCO, VOC etc.) to YOLO format, please use [json2yolo tool](https://github.com/ultralytics/JSON2YOLO) by Ultralytics. +YOLO detection dataset format can be found in detail in the [Dataset Guide](../datasets/detect/index.md). To convert your existing dataset from other formats( like COCO etc.) to YOLO format, please use [json2yolo tool](https://github.com/ultralytics/JSON2YOLO) by Ultralytics. ## Val @@ -76,14 +77,14 @@ Validate trained YOLOv8n model accuracy on the COCO128 dataset. No argument need !!! example "" === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n.pt') # load an official model model = YOLO('path/to/best.pt') # load a custom model - + # Validate the model metrics = model.val() # no arguments needed, dataset and settings remembered metrics.box.map # map50-95 @@ -92,7 +93,7 @@ Validate trained YOLOv8n model accuracy on the COCO128 dataset. No argument need metrics.box.maps # a list contains map50-95 of each category ``` === "CLI" - + ```bash yolo detect val model=yolov8n.pt # val official model yolo detect val model=path/to/best.pt # val custom model @@ -105,19 +106,19 @@ Use a trained YOLOv8n model to run predictions on images. !!! example "" === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n.pt') # load an official model model = YOLO('path/to/best.pt') # load a custom model - + # Predict with the model results = model('https://ultralytics.com/images/bus.jpg') # predict on an image ``` === "CLI" - + ```bash yolo detect predict model=yolov8n.pt source='https://ultralytics.com/images/bus.jpg' # predict with official model yolo detect predict model=path/to/best.pt source='https://ultralytics.com/images/bus.jpg' # predict with custom model @@ -132,19 +133,19 @@ Export a YOLOv8n model to a different format like ONNX, CoreML, etc. !!! example "" === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n.pt') # load an official model model = YOLO('path/to/best.pt') # load a custom trained - + # Export the model model.export(format='onnx') ``` === "CLI" - + ```bash yolo export model=yolov8n.pt format=onnx # export official model yolo export model=path/to/best.pt format=onnx # export custom trained model @@ -159,12 +160,13 @@ Available YOLOv8 export formats are in the table below. You can predict or valid | [ONNX](https://onnx.ai/) | `onnx` | `yolov8n.onnx` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `opset` | | [OpenVINO](https://docs.openvino.ai/latest/index.html) | `openvino` | `yolov8n_openvino_model/` | ✅ | `imgsz`, `half` | | [TensorRT](https://developer.nvidia.com/tensorrt) | `engine` | `yolov8n.engine` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `workspace` | -| [CoreML](https://github.com/apple/coremltools) | `coreml` | `yolov8n.mlmodel` | ✅ | `imgsz`, `half`, `int8`, `nms` | +| [CoreML](https://github.com/apple/coremltools) | `coreml` | `yolov8n.mlpackage` | ✅ | `imgsz`, `half`, `int8`, `nms` | | [TF SavedModel](https://www.tensorflow.org/guide/saved_model) | `saved_model` | `yolov8n_saved_model/` | ✅ | `imgsz`, `keras` | | [TF GraphDef](https://www.tensorflow.org/api_docs/python/tf/Graph) | `pb` | `yolov8n.pb` | ❌ | `imgsz` | | [TF Lite](https://www.tensorflow.org/lite) | `tflite` | `yolov8n.tflite` | ✅ | `imgsz`, `half`, `int8` | | [TF Edge TPU](https://coral.ai/docs/edgetpu/models-intro/) | `edgetpu` | `yolov8n_edgetpu.tflite` | ✅ | `imgsz` | | [TF.js](https://www.tensorflow.org/js) | `tfjs` | `yolov8n_web_model/` | ✅ | `imgsz` | | [PaddlePaddle](https://github.com/PaddlePaddle) | `paddle` | `yolov8n_paddle_model/` | ✅ | `imgsz` | +| [ncnn](https://github.com/Tencent/ncnn) | `ncnn` | `yolov8n_ncnn_model/` | ✅ | `imgsz`, `half` | -See full `export` details in the [Export](https://docs.ultralytics.com/modes/export/) page. \ No newline at end of file +See full `export` details in the [Export](https://docs.ultralytics.com/modes/export/) page. diff --git a/downloads/ultralytics-main/docs/tasks/index.md b/downloads/ultralytics-main/docs/tasks/index.md index 0931a3f5e..43cdb3707 100644 --- a/downloads/ultralytics-main/docs/tasks/index.md +++ b/downloads/ultralytics-main/docs/tasks/index.md @@ -1,6 +1,7 @@ --- comments: true -description: Learn how Ultralytics YOLOv8 AI framework supports detection, segmentation, classification, and pose/keypoint estimation tasks. +description: Learn about the cornerstone computer vision tasks YOLOv8 can perform including detection, segmentation, classification, and pose estimation. Understand their uses in your AI projects. +keywords: Ultralytics, YOLOv8, Detection, Segmentation, Classification, Pose Estimation, AI Framework, Computer Vision Tasks --- # Ultralytics YOLOv8 Tasks @@ -9,7 +10,8 @@ YOLOv8 is an AI framework that supports multiple computer vision **tasks**. The perform [detection](detect.md), [segmentation](segment.md), [classification](classify.md), and [pose](pose.md) estimation. Each of these tasks has a different objective and use case. - +
+ ## [Detection](detect.md) @@ -46,4 +48,4 @@ video frame with high accuracy and speed. YOLOv8 supports multiple tasks, including detection, segmentation, classification, and keypoints detection. Each of these tasks has different objectives and use cases. By understanding the differences between these tasks, you can choose -the appropriate task for your computer vision application. \ No newline at end of file +the appropriate task for your computer vision application. diff --git a/downloads/ultralytics-main/docs/tasks/pose.md b/downloads/ultralytics-main/docs/tasks/pose.md index 6c43d6cfd..f6bde385d 100644 --- a/downloads/ultralytics-main/docs/tasks/pose.md +++ b/downloads/ultralytics-main/docs/tasks/pose.md @@ -1,6 +1,7 @@ --- comments: true -description: Learn how to use YOLOv8 pose estimation models to identify the position of keypoints on objects in an image, and how to train, validate, predict, and export these models for use with various formats such as ONNX or CoreML. +description: Learn how to use Ultralytics YOLOv8 for pose estimation tasks. Find pretrained models, learn how to train, validate, predict, and export your own. +keywords: Ultralytics, YOLO, YOLOv8, pose estimation, keypoints detection, object detection, pre-trained models, machine learning, artificial intelligence --- Pose estimation is a task that involves identifying the location of specific points in an image, usually referred @@ -8,7 +9,7 @@ to as keypoints. The keypoints can represent various parts of the object such as features. The locations of the keypoints are usually represented as a set of 2D `[x, y]` or 3D `[x, y, visible]` coordinates. - + The output of a pose estimation model is a set of points that represent the keypoints on an object in the image, usually along with the confidence scores for each point. Pose estimation is a good choice when you need to identify specific @@ -16,16 +17,16 @@ parts of an object in a scene, and their location in relation to each other. !!! tip "Tip" - YOLOv8 _pose_ models use the `-pose` suffix, i.e. `yolov8n-pose.pt`. These models are trained on the [COCO keypoints](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/coco-pose.yaml) dataset and are suitable for a variety of pose estimation tasks. + YOLOv8 _pose_ models use the `-pose` suffix, i.e. `yolov8n-pose.pt`. These models are trained on the [COCO keypoints](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/datasets/coco-pose.yaml) dataset and are suitable for a variety of pose estimation tasks. -## [Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models/v8) +## [Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models/v8) YOLOv8 pretrained Pose models are shown here. Detect, Segment and Pose models are pretrained on -the [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/coco.yaml) dataset, while Classify +the [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/datasets/coco.yaml) dataset, while Classify models are pretrained on -the [ImageNet](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/ImageNet.yaml) dataset. +the [ImageNet](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/datasets/ImageNet.yaml) dataset. -[Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models) download automatically from the latest +[Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models) download automatically from the latest Ultralytics [release](https://github.com/ultralytics/assets/releases) on first use. | Model | size
(pixels) | mAPpose
50-95 | mAPpose
50 | Speed
CPU ONNX
(ms) | Speed
A100 TensorRT
(ms) | params
(M) | FLOPs
(B) | @@ -51,20 +52,20 @@ Train a YOLOv8-pose model on the COCO128-pose dataset. !!! example "" === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n-pose.yaml') # build a new model from YAML model = YOLO('yolov8n-pose.pt') # load a pretrained model (recommended for training) model = YOLO('yolov8n-pose.yaml').load('yolov8n-pose.pt') # build from YAML and transfer weights - + # Train the model - model.train(data='coco8-pose.yaml', epochs=100, imgsz=640) + results = model.train(data='coco8-pose.yaml', epochs=100, imgsz=640) ``` === "CLI" - + ```bash # Build a new model from YAML and start training from scratch yolo pose train data=coco8-pose.yaml model=yolov8n-pose.yaml epochs=100 imgsz=640 @@ -76,6 +77,10 @@ Train a YOLOv8-pose model on the COCO128-pose dataset. yolo pose train data=coco8-pose.yaml model=yolov8n-pose.yaml pretrained=yolov8n-pose.pt epochs=100 imgsz=640 ``` +### Dataset format + +YOLO pose dataset format can be found in detail in the [Dataset Guide](../datasets/pose/index.md). To convert your existing dataset from other formats( like COCO etc.) to YOLO format, please use [json2yolo tool](https://github.com/ultralytics/JSON2YOLO) by Ultralytics. + ## Val Validate trained YOLOv8n-pose model accuracy on the COCO128-pose dataset. No argument need to passed as the `model` @@ -85,14 +90,14 @@ training `data` and arguments as model attributes. !!! example "" === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n-pose.pt') # load an official model model = YOLO('path/to/best.pt') # load a custom model - + # Validate the model metrics = model.val() # no arguments needed, dataset and settings remembered metrics.box.map # map50-95 @@ -101,7 +106,7 @@ training `data` and arguments as model attributes. metrics.box.maps # a list contains map50-95 of each category ``` === "CLI" - + ```bash yolo pose val model=yolov8n-pose.pt # val official model yolo pose val model=path/to/best.pt # val custom model @@ -114,19 +119,19 @@ Use a trained YOLOv8n-pose model to run predictions on images. !!! example "" === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n-pose.pt') # load an official model model = YOLO('path/to/best.pt') # load a custom model - + # Predict with the model results = model('https://ultralytics.com/images/bus.jpg') # predict on an image ``` === "CLI" - + ```bash yolo pose predict model=yolov8n-pose.pt source='https://ultralytics.com/images/bus.jpg' # predict with official model yolo pose predict model=path/to/best.pt source='https://ultralytics.com/images/bus.jpg' # predict with custom model @@ -141,19 +146,19 @@ Export a YOLOv8n Pose model to a different format like ONNX, CoreML, etc. !!! example "" === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n-pose.pt') # load an official model model = YOLO('path/to/best.pt') # load a custom trained - + # Export the model model.export(format='onnx') ``` === "CLI" - + ```bash yolo export model=yolov8n-pose.pt format=onnx # export official model yolo export model=path/to/best.pt format=onnx # export custom trained model @@ -169,12 +174,13 @@ i.e. `yolo predict model=yolov8n-pose.onnx`. Usage examples are shown for your m | [ONNX](https://onnx.ai/) | `onnx` | `yolov8n-pose.onnx` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `opset` | | [OpenVINO](https://docs.openvino.ai/latest/index.html) | `openvino` | `yolov8n-pose_openvino_model/` | ✅ | `imgsz`, `half` | | [TensorRT](https://developer.nvidia.com/tensorrt) | `engine` | `yolov8n-pose.engine` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `workspace` | -| [CoreML](https://github.com/apple/coremltools) | `coreml` | `yolov8n-pose.mlmodel` | ✅ | `imgsz`, `half`, `int8`, `nms` | +| [CoreML](https://github.com/apple/coremltools) | `coreml` | `yolov8n-pose.mlpackage` | ✅ | `imgsz`, `half`, `int8`, `nms` | | [TF SavedModel](https://www.tensorflow.org/guide/saved_model) | `saved_model` | `yolov8n-pose_saved_model/` | ✅ | `imgsz`, `keras` | | [TF GraphDef](https://www.tensorflow.org/api_docs/python/tf/Graph) | `pb` | `yolov8n-pose.pb` | ❌ | `imgsz` | | [TF Lite](https://www.tensorflow.org/lite) | `tflite` | `yolov8n-pose.tflite` | ✅ | `imgsz`, `half`, `int8` | | [TF Edge TPU](https://coral.ai/docs/edgetpu/models-intro/) | `edgetpu` | `yolov8n-pose_edgetpu.tflite` | ✅ | `imgsz` | | [TF.js](https://www.tensorflow.org/js) | `tfjs` | `yolov8n-pose_web_model/` | ✅ | `imgsz` | | [PaddlePaddle](https://github.com/PaddlePaddle) | `paddle` | `yolov8n-pose_paddle_model/` | ✅ | `imgsz` | +| [ncnn](https://github.com/Tencent/ncnn) | `ncnn` | `yolov8n-pose_ncnn_model/` | ✅ | `imgsz`, `half` | -See full `export` details in the [Export](https://docs.ultralytics.com/modes/export/) page. \ No newline at end of file +See full `export` details in the [Export](https://docs.ultralytics.com/modes/export/) page. diff --git a/downloads/ultralytics-main/docs/tasks/segment.md b/downloads/ultralytics-main/docs/tasks/segment.md index 0b9d4d26f..4abea007a 100644 --- a/downloads/ultralytics-main/docs/tasks/segment.md +++ b/downloads/ultralytics-main/docs/tasks/segment.md @@ -1,12 +1,13 @@ --- comments: true -description: Learn what Instance segmentation is. Get pretrained YOLOv8 segment models, and how to train and export them to segments masks. Check the preformance metrics! +description: Learn how to use instance segmentation models with Ultralytics YOLO. Instructions on training, validation, image prediction, and model export. +keywords: yolov8, instance segmentation, Ultralytics, COCO dataset, image segmentation, object detection, model training, model validation, image prediction, model export --- Instance segmentation goes a step further than object detection and involves identifying individual objects in an image and segmenting them from the rest of the image. - + The output of an instance segmentation model is a set of masks or contours that outline each object in the image, along with class labels and confidence scores for each object. Instance @@ -14,16 +15,16 @@ segmentation is useful when you need to know not only where objects are in an im !!! tip "Tip" - YOLOv8 Segment models use the `-seg` suffix, i.e. `yolov8n-seg.pt` and are pretrained on [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/coco.yaml). + YOLOv8 Segment models use the `-seg` suffix, i.e. `yolov8n-seg.pt` and are pretrained on [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/datasets/coco.yaml). -## [Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models/v8) +## [Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models/v8) YOLOv8 pretrained Segment models are shown here. Detect, Segment and Pose models are pretrained on -the [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/coco.yaml) dataset, while Classify +the [COCO](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/datasets/coco.yaml) dataset, while Classify models are pretrained on -the [ImageNet](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/datasets/ImageNet.yaml) dataset. +the [ImageNet](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/datasets/ImageNet.yaml) dataset. -[Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/models) download automatically from the latest +[Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models) download automatically from the latest Ultralytics [release](https://github.com/ultralytics/assets/releases) on first use. | Model | size
(pixels) | mAPbox
50-95 | mAPmask
50-95 | Speed
CPU ONNX
(ms) | Speed
A100 TensorRT
(ms) | params
(M) | FLOPs
(B) | @@ -48,20 +49,20 @@ arguments see the [Configuration](../usage/cfg.md) page. !!! example "" === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n-seg.yaml') # build a new model from YAML model = YOLO('yolov8n-seg.pt') # load a pretrained model (recommended for training) model = YOLO('yolov8n-seg.yaml').load('yolov8n.pt') # build from YAML and transfer weights - + # Train the model - model.train(data='coco128-seg.yaml', epochs=100, imgsz=640) + results = model.train(data='coco128-seg.yaml', epochs=100, imgsz=640) ``` === "CLI" - + ```bash # Build a new model from YAML and start training from scratch yolo segment train data=coco128-seg.yaml model=yolov8n-seg.yaml epochs=100 imgsz=640 @@ -75,11 +76,7 @@ arguments see the [Configuration](../usage/cfg.md) page. ### Dataset format -YOLO segmentation dataset label format extends detection format with segment points. - -`cls x1 y1 x2 y2 p1 p2 ... pn` - -To convert your existing dataset from other formats( like COCO, VOC etc.) to YOLO format, please use [json2yolo tool](https://github.com/ultralytics/JSON2YOLO) by Ultralytics. +YOLO segmentation dataset format can be found in detail in the [Dataset Guide](../datasets/segment/index.md). To convert your existing dataset from other formats( like COCO etc.) to YOLO format, please use [json2yolo tool](https://github.com/ultralytics/JSON2YOLO) by Ultralytics. ## Val @@ -89,14 +86,14 @@ retains it's training `data` and arguments as model attributes. !!! example "" === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n-seg.pt') # load an official model model = YOLO('path/to/best.pt') # load a custom model - + # Validate the model metrics = model.val() # no arguments needed, dataset and settings remembered metrics.box.map # map50-95(B) @@ -109,7 +106,7 @@ retains it's training `data` and arguments as model attributes. metrics.seg.maps # a list contains map50-95(M) of each category ``` === "CLI" - + ```bash yolo segment val model=yolov8n-seg.pt # val official model yolo segment val model=path/to/best.pt # val custom model @@ -122,19 +119,19 @@ Use a trained YOLOv8n-seg model to run predictions on images. !!! example "" === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n-seg.pt') # load an official model model = YOLO('path/to/best.pt') # load a custom model - + # Predict with the model results = model('https://ultralytics.com/images/bus.jpg') # predict on an image ``` === "CLI" - + ```bash yolo segment predict model=yolov8n-seg.pt source='https://ultralytics.com/images/bus.jpg' # predict with official model yolo segment predict model=path/to/best.pt source='https://ultralytics.com/images/bus.jpg' # predict with custom model @@ -149,19 +146,19 @@ Export a YOLOv8n-seg model to a different format like ONNX, CoreML, etc. !!! example "" === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n-seg.pt') # load an official model model = YOLO('path/to/best.pt') # load a custom trained - + # Export the model model.export(format='onnx') ``` === "CLI" - + ```bash yolo export model=yolov8n-seg.pt format=onnx # export official model yolo export model=path/to/best.pt format=onnx # export custom trained model @@ -177,12 +174,13 @@ i.e. `yolo predict model=yolov8n-seg.onnx`. Usage examples are shown for your mo | [ONNX](https://onnx.ai/) | `onnx` | `yolov8n-seg.onnx` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `opset` | | [OpenVINO](https://docs.openvino.ai/latest/index.html) | `openvino` | `yolov8n-seg_openvino_model/` | ✅ | `imgsz`, `half` | | [TensorRT](https://developer.nvidia.com/tensorrt) | `engine` | `yolov8n-seg.engine` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `workspace` | -| [CoreML](https://github.com/apple/coremltools) | `coreml` | `yolov8n-seg.mlmodel` | ✅ | `imgsz`, `half`, `int8`, `nms` | +| [CoreML](https://github.com/apple/coremltools) | `coreml` | `yolov8n-seg.mlpackage` | ✅ | `imgsz`, `half`, `int8`, `nms` | | [TF SavedModel](https://www.tensorflow.org/guide/saved_model) | `saved_model` | `yolov8n-seg_saved_model/` | ✅ | `imgsz`, `keras` | | [TF GraphDef](https://www.tensorflow.org/api_docs/python/tf/Graph) | `pb` | `yolov8n-seg.pb` | ❌ | `imgsz` | | [TF Lite](https://www.tensorflow.org/lite) | `tflite` | `yolov8n-seg.tflite` | ✅ | `imgsz`, `half`, `int8` | | [TF Edge TPU](https://coral.ai/docs/edgetpu/models-intro/) | `edgetpu` | `yolov8n-seg_edgetpu.tflite` | ✅ | `imgsz` | | [TF.js](https://www.tensorflow.org/js) | `tfjs` | `yolov8n-seg_web_model/` | ✅ | `imgsz` | | [PaddlePaddle](https://github.com/PaddlePaddle) | `paddle` | `yolov8n-seg_paddle_model/` | ✅ | `imgsz` | +| [ncnn](https://github.com/Tencent/ncnn) | `ncnn` | `yolov8n-seg_ncnn_model/` | ✅ | `imgsz`, `half` | -See full `export` details in the [Export](https://docs.ultralytics.com/modes/export/) page. \ No newline at end of file +See full `export` details in the [Export](https://docs.ultralytics.com/modes/export/) page. diff --git a/downloads/ultralytics-main/docs/usage/callbacks.md b/downloads/ultralytics-main/docs/usage/callbacks.md index 031d64488..e2e68857b 100644 --- a/downloads/ultralytics-main/docs/usage/callbacks.md +++ b/downloads/ultralytics-main/docs/usage/callbacks.md @@ -1,6 +1,7 @@ --- comments: true -description: Learn how to leverage callbacks in Ultralytics YOLO framework to perform custom tasks in trainer, validator, predictor and exporter modes. +description: Learn how to utilize callbacks in the Ultralytics framework during train, val, export, and predict modes for enhanced functionality. +keywords: Ultralytics, YOLO, callbacks guide, training callback, validation callback, export callback, prediction callback --- ## Callbacks @@ -19,10 +20,10 @@ In this example, we want to return the original frame with each result object. H def on_predict_batch_end(predictor): # Retrieve the batch data _, im0s, _, _ = predictor.batch - + # Ensure that im0s is a list im0s = im0s if isinstance(im0s, list) else [im0s] - + # Combine the prediction results with the corresponding frames predictor.results = zip(predictor.results, im0s) @@ -39,7 +40,7 @@ for (result, frame) in model.track/predict(): ## All callbacks -Here are all supported callbacks. See callbacks [source code](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/yolo/utils/callbacks/base.py) for additional details. +Here are all supported callbacks. See callbacks [source code](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/utils/callbacks/base.py) for additional details. ### Trainer Callbacks @@ -84,4 +85,4 @@ Here are all supported callbacks. See callbacks [source code](https://github.com | Callback | Description | |-------------------|------------------------------------------| | `on_export_start` | Triggered when the export process starts | -| `on_export_end` | Triggered when the export process ends | \ No newline at end of file +| `on_export_end` | Triggered when the export process ends | diff --git a/downloads/ultralytics-main/docs/usage/cfg.md b/downloads/ultralytics-main/docs/usage/cfg.md index 9113ecf0b..f2c0d2fb0 100644 --- a/downloads/ultralytics-main/docs/usage/cfg.md +++ b/downloads/ultralytics-main/docs/usage/cfg.md @@ -1,6 +1,7 @@ --- comments: true -description: 'Learn about YOLO settings and modes for different tasks like detection, segmentation etc. Train and predict with custom argparse commands.' +description: Master YOLOv8 settings and hyperparameters for improved model performance. Learn to use YOLO CLI commands, adjust training settings, and optimize YOLO tasks & modes. +keywords: YOLOv8, settings, hyperparameters, YOLO CLI commands, YOLO tasks, YOLO modes, Ultralytics documentation, model optimization, YOLOv8 training --- YOLO settings and hyperparameters play a critical role in the model's performance, speed, and accuracy. These settings @@ -12,19 +13,19 @@ YOLOv8 'yolo' CLI commands use the following syntax: !!! example "" === "CLI" - + ```bash yolo TASK MODE ARGS ``` === "Python" - + ```python from ultralytics import YOLO - + # Load a YOLOv8 model from a pre-trained weights file model = YOLO('yolov8n.pt') - + # Run MODE mode using the custom arguments ARGS (guess TASK) model.MODE(ARGS) ``` @@ -37,16 +38,16 @@ Where: - `MODE` (required) is one of `[train, val, predict, export, track, benchmark]` - `ARGS` (optional) are any number of custom `arg=value` pairs like `imgsz=320` that override defaults. For a full list of available `ARGS` see the [Configuration](cfg.md) page and `defaults.yaml` - GitHub [source](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/yolo/cfg/default.yaml). + GitHub [source](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/default.yaml). #### Tasks YOLO models can be used for a variety of tasks, including detection, segmentation, classification and pose. These tasks differ in the type of output they produce and the specific problem they are designed to solve. -**Detect**: For identifying and localizing objects or regions of interest in an image or video. -**Segment**: For dividing an image or video into regions or pixels that correspond to different objects or classes. -**Classify**: For predicting the class label of an input image. +**Detect**: For identifying and localizing objects or regions of interest in an image or video. +**Segment**: For dividing an image or video into regions or pixels that correspond to different objects or classes. +**Classify**: For predicting the class label of an input image. **Pose**: For identifying objects and estimating their keypoints in an image or video. | Key | Value | Description | @@ -60,11 +61,11 @@ differ in the type of output they produce and the specific problem they are desi YOLO models can be used in different modes depending on the specific problem you are trying to solve. These modes include: -**Train**: For training a YOLOv8 model on a custom dataset. -**Val**: For validating a YOLOv8 model after it has been trained. -**Predict**: For making predictions using a trained YOLOv8 model on new images or videos. -**Export**: For exporting a YOLOv8 model to a format that can be used for deployment. -**Track**: For tracking objects in real-time using a YOLOv8 model. +**Train**: For training a YOLOv8 model on a custom dataset. +**Val**: For validating a YOLOv8 model after it has been trained. +**Predict**: For making predictions using a trained YOLOv8 model on new images or videos. +**Export**: For exporting a YOLOv8 model to a format that can be used for deployment. +**Track**: For tracking objects in real-time using a YOLOv8 model. **Benchmark**: For benchmarking YOLOv8 exports (ONNX, TensorRT, etc.) speed and accuracy. | Key | Value | Description | @@ -77,51 +78,54 @@ include: The training settings for YOLO models encompass various hyperparameters and configurations used during the training process. These settings influence the model's performance, speed, and accuracy. Key training settings include batch size, learning rate, momentum, and weight decay. Additionally, the choice of optimizer, loss function, and training dataset composition can impact the training process. Careful tuning and experimentation with these settings are crucial for optimizing performance. -| Key | Value | Description | -|-------------------|----------|-----------------------------------------------------------------------------| -| `model` | `None` | path to model file, i.e. yolov8n.pt, yolov8n.yaml | -| `data` | `None` | path to data file, i.e. coco128.yaml | -| `epochs` | `100` | number of epochs to train for | -| `patience` | `50` | epochs to wait for no observable improvement for early stopping of training | -| `batch` | `16` | number of images per batch (-1 for AutoBatch) | -| `imgsz` | `640` | size of input images as integer or w,h | -| `save` | `True` | save train checkpoints and predict results | -| `save_period` | `-1` | Save checkpoint every x epochs (disabled if < 1) | -| `cache` | `False` | True/ram, disk or False. Use cache for data loading | -| `device` | `None` | device to run on, i.e. cuda device=0 or device=0,1,2,3 or device=cpu | -| `workers` | `8` | number of worker threads for data loading (per RANK if DDP) | -| `project` | `None` | project name | -| `name` | `None` | experiment name | -| `exist_ok` | `False` | whether to overwrite existing experiment | -| `pretrained` | `False` | whether to use a pretrained model | -| `optimizer` | `'SGD'` | optimizer to use, choices=['SGD', 'Adam', 'AdamW', 'RMSProp'] | -| `verbose` | `False` | whether to print verbose output | -| `seed` | `0` | random seed for reproducibility | -| `deterministic` | `True` | whether to enable deterministic mode | -| `single_cls` | `False` | train multi-class data as single-class | -| `rect` | `False` | rectangular training with each batch collated for minimum padding | -| `cos_lr` | `False` | use cosine learning rate scheduler | -| `close_mosaic` | `0` | (int) disable mosaic augmentation for final epochs | -| `resume` | `False` | resume training from last checkpoint | -| `amp` | `True` | Automatic Mixed Precision (AMP) training, choices=[True, False] | -| `lr0` | `0.01` | initial learning rate (i.e. SGD=1E-2, Adam=1E-3) | -| `lrf` | `0.01` | final learning rate (lr0 * lrf) | -| `momentum` | `0.937` | SGD momentum/Adam beta1 | -| `weight_decay` | `0.0005` | optimizer weight decay 5e-4 | -| `warmup_epochs` | `3.0` | warmup epochs (fractions ok) | -| `warmup_momentum` | `0.8` | warmup initial momentum | -| `warmup_bias_lr` | `0.1` | warmup initial bias lr | -| `box` | `7.5` | box loss gain | -| `cls` | `0.5` | cls loss gain (scale with pixels) | -| `dfl` | `1.5` | dfl loss gain | -| `pose` | `12.0` | pose loss gain (pose-only) | -| `kobj` | `2.0` | keypoint obj loss gain (pose-only) | -| `label_smoothing` | `0.0` | label smoothing (fraction) | -| `nbs` | `64` | nominal batch size | -| `overlap_mask` | `True` | masks should overlap during training (segment train only) | -| `mask_ratio` | `4` | mask downsample ratio (segment train only) | -| `dropout` | `0.0` | use dropout regularization (classify train only) | -| `val` | `True` | validate/test during training | +| Key | Value | Description | +|-------------------|----------|------------------------------------------------------------------------------------------------| +| `model` | `None` | path to model file, i.e. yolov8n.pt, yolov8n.yaml | +| `data` | `None` | path to data file, i.e. coco128.yaml | +| `epochs` | `100` | number of epochs to train for | +| `patience` | `50` | epochs to wait for no observable improvement for early stopping of training | +| `batch` | `16` | number of images per batch (-1 for AutoBatch) | +| `imgsz` | `640` | size of input images as integer or w,h | +| `save` | `True` | save train checkpoints and predict results | +| `save_period` | `-1` | Save checkpoint every x epochs (disabled if < 1) | +| `cache` | `False` | True/ram, disk or False. Use cache for data loading | +| `device` | `None` | device to run on, i.e. cuda device=0 or device=0,1,2,3 or device=cpu | +| `workers` | `8` | number of worker threads for data loading (per RANK if DDP) | +| `project` | `None` | project name | +| `name` | `None` | experiment name | +| `exist_ok` | `False` | whether to overwrite existing experiment | +| `pretrained` | `False` | whether to use a pretrained model | +| `optimizer` | `'auto'` | optimizer to use, choices=[SGD, Adam, Adamax, AdamW, NAdam, RAdam, RMSProp, auto] | +| `verbose` | `False` | whether to print verbose output | +| `seed` | `0` | random seed for reproducibility | +| `deterministic` | `True` | whether to enable deterministic mode | +| `single_cls` | `False` | train multi-class data as single-class | +| `rect` | `False` | rectangular training with each batch collated for minimum padding | +| `cos_lr` | `False` | use cosine learning rate scheduler | +| `close_mosaic` | `10` | (int) disable mosaic augmentation for final epochs (0 to disable) | +| `resume` | `False` | resume training from last checkpoint | +| `amp` | `True` | Automatic Mixed Precision (AMP) training, choices=[True, False] | +| `fraction` | `1.0` | dataset fraction to train on (default is 1.0, all images in train set) | +| `profile` | `False` | profile ONNX and TensorRT speeds during training for loggers | +| `freeze` | `None` | (int or list, optional) freeze first n layers, or freeze list of layer indices during training | +| `lr0` | `0.01` | initial learning rate (i.e. SGD=1E-2, Adam=1E-3) | +| `lrf` | `0.01` | final learning rate (lr0 * lrf) | +| `momentum` | `0.937` | SGD momentum/Adam beta1 | +| `weight_decay` | `0.0005` | optimizer weight decay 5e-4 | +| `warmup_epochs` | `3.0` | warmup epochs (fractions ok) | +| `warmup_momentum` | `0.8` | warmup initial momentum | +| `warmup_bias_lr` | `0.1` | warmup initial bias lr | +| `box` | `7.5` | box loss gain | +| `cls` | `0.5` | cls loss gain (scale with pixels) | +| `dfl` | `1.5` | dfl loss gain | +| `pose` | `12.0` | pose loss gain (pose-only) | +| `kobj` | `2.0` | keypoint obj loss gain (pose-only) | +| `label_smoothing` | `0.0` | label smoothing (fraction) | +| `nbs` | `64` | nominal batch size | +| `overlap_mask` | `True` | masks should overlap during training (segment train only) | +| `mask_ratio` | `4` | mask downsample ratio (segment train only) | +| `dropout` | `0.0` | use dropout regularization (classify train only) | +| `val` | `True` | validate/test during training | [Train Guide](../modes/train.md){ .md-button .md-button--primary} @@ -150,7 +154,7 @@ The prediction settings for YOLO models encompass a range of hyperparameters and | `augment` | `False` | apply image augmentation to prediction sources | | `agnostic_nms` | `False` | class-agnostic NMS | | `retina_masks` | `False` | use high-resolution segmentation masks | -| `classes` | `None` | filter results by class, i.e. class=0, or class=[0,2,3] | +| `classes` | `None` | filter results by class, i.e. classes=0, or classes=[0,2,3] | | `boxes` | `True` | Show boxes in segmentation predictions | [Predict Guide](../modes/predict.md){ .md-button .md-button--primary} @@ -248,4 +252,4 @@ it easier to debug and optimize the training process. | `name` | `'exp'` | experiment name. `exp` gets automatically incremented if not specified, i.e, `exp`, `exp2` ... | | `exist_ok` | `False` | whether to overwrite existing experiment | | `plots` | `False` | save plots during train/val | -| `save` | `False` | save train checkpoints and predict results | \ No newline at end of file +| `save` | `False` | save train checkpoints and predict results | diff --git a/downloads/ultralytics-main/docs/usage/cli.md b/downloads/ultralytics-main/docs/usage/cli.md index 1b07b61e1..e08ef10a3 100644 --- a/downloads/ultralytics-main/docs/usage/cli.md +++ b/downloads/ultralytics-main/docs/usage/cli.md @@ -1,6 +1,7 @@ --- comments: true -description: Learn how to use YOLOv8 from the Command Line Interface (CLI) through simple, single-line commands with `yolo` without Python code. +description: 'Learn how to use Ultralytics YOLO through Command Line: train models, run predictions and exports models to different formats easily using terminal commands.' +keywords: Ultralytics, YOLO, CLI, train, validation, prediction, command line interface, YOLO CLI, YOLO terminal, model training, prediction, exporting --- # Command Line Interface Usage @@ -69,11 +70,11 @@ Where: - `MODE` (required) is one of `[train, val, predict, export, track]` - `ARGS` (optional) are any number of custom `arg=value` pairs like `imgsz=320` that override defaults. For a full list of available `ARGS` see the [Configuration](cfg.md) page and `defaults.yaml` - GitHub [source](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/yolo/cfg/default.yaml). + GitHub [source](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/default.yaml). !!! warning "Warning" - Arguments must be passed as `arg=val` pairs, split by an equals `=` sign and delimited by spaces ` ` between pairs. Do not use `--` argument prefixes or commas `,` beteen arguments. + Arguments must be passed as `arg=val` pairs, split by an equals `=` sign and delimited by spaces ` ` between pairs. Do not use `--` argument prefixes or commas `,` between arguments. - `yolo predict model=yolov8n.pt imgsz=640 conf=0.25`   ✅ - `yolo predict model yolov8n.pt imgsz 640 conf 0.25`   ❌ @@ -87,7 +88,7 @@ the [Configuration](cfg.md) page. !!! example "Example" === "Train" - + Start training YOLOv8n on COCO128 for 100 epochs at image-size 640. ```bash yolo detect train data=coco128.yaml model=yolov8n.pt epochs=100 imgsz=640 @@ -164,22 +165,21 @@ Export a YOLOv8n model to a different format like ONNX, CoreML, etc. Available YOLOv8 export formats are in the table below. You can export to any format using the `format` argument, i.e. `format='onnx'` or `format='engine'`. -| Format | `format` Argument | Model | Metadata | -|--------------------------------------------------------------------|-------------------|---------------------------|----------| -| [PyTorch](https://pytorch.org/) | - | `yolov8n.pt` | ✅ | -| [TorchScript](https://pytorch.org/docs/stable/jit.html) | `torchscript` | `yolov8n.torchscript` | ✅ | -| [ONNX](https://onnx.ai/) | `onnx` | `yolov8n.onnx` | ✅ | -| [OpenVINO](https://docs.openvino.ai/latest/index.html) | `openvino` | `yolov8n_openvino_model/` | ✅ | -| [TensorRT](https://developer.nvidia.com/tensorrt) | `engine` | `yolov8n.engine` | ✅ | -| [CoreML](https://github.com/apple/coremltools) | `coreml` | `yolov8n.mlmodel` | ✅ | -| [TF SavedModel](https://www.tensorflow.org/guide/saved_model) | `saved_model` | `yolov8n_saved_model/` | ✅ | -| [TF GraphDef](https://www.tensorflow.org/api_docs/python/tf/Graph) | `pb` | `yolov8n.pb` | ❌ | -| [TF Lite](https://www.tensorflow.org/lite) | `tflite` | `yolov8n.tflite` | ✅ | -| [TF Edge TPU](https://coral.ai/docs/edgetpu/models-intro/) | `edgetpu` | `yolov8n_edgetpu.tflite` | ✅ | -| [TF.js](https://www.tensorflow.org/js) | `tfjs` | `yolov8n_web_model/` | ✅ | -| [PaddlePaddle](https://github.com/PaddlePaddle) | `paddle` | `yolov8n_paddle_model/` | ✅ | - ---- +| Format | `format` Argument | Model | Metadata | Arguments | +|--------------------------------------------------------------------|-------------------|---------------------------|----------|-----------------------------------------------------| +| [PyTorch](https://pytorch.org/) | - | `yolov8n.pt` | ✅ | - | +| [TorchScript](https://pytorch.org/docs/stable/jit.html) | `torchscript` | `yolov8n.torchscript` | ✅ | `imgsz`, `optimize` | +| [ONNX](https://onnx.ai/) | `onnx` | `yolov8n.onnx` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `opset` | +| [OpenVINO](https://docs.openvino.ai/latest/index.html) | `openvino` | `yolov8n_openvino_model/` | ✅ | `imgsz`, `half` | +| [TensorRT](https://developer.nvidia.com/tensorrt) | `engine` | `yolov8n.engine` | ✅ | `imgsz`, `half`, `dynamic`, `simplify`, `workspace` | +| [CoreML](https://github.com/apple/coremltools) | `coreml` | `yolov8n.mlpackage` | ✅ | `imgsz`, `half`, `int8`, `nms` | +| [TF SavedModel](https://www.tensorflow.org/guide/saved_model) | `saved_model` | `yolov8n_saved_model/` | ✅ | `imgsz`, `keras` | +| [TF GraphDef](https://www.tensorflow.org/api_docs/python/tf/Graph) | `pb` | `yolov8n.pb` | ❌ | `imgsz` | +| [TF Lite](https://www.tensorflow.org/lite) | `tflite` | `yolov8n.tflite` | ✅ | `imgsz`, `half`, `int8` | +| [TF Edge TPU](https://coral.ai/docs/edgetpu/models-intro/) | `edgetpu` | `yolov8n_edgetpu.tflite` | ✅ | `imgsz` | +| [TF.js](https://www.tensorflow.org/js) | `tfjs` | `yolov8n_web_model/` | ✅ | `imgsz` | +| [PaddlePaddle](https://github.com/PaddlePaddle) | `paddle` | `yolov8n_paddle_model/` | ✅ | `imgsz` | +| [ncnn](https://github.com/Tencent/ncnn) | `ncnn` | `yolov8n_ncnn_model/` | ✅ | `imgsz`, `half` | ## Overriding default arguments @@ -205,8 +205,6 @@ Default arguments can be overridden by simply passing them as arguments in the C yolo detect val model=yolov8n.pt data=coco128.yaml batch=1 imgsz=640 ``` ---- - ## Overriding default config file You can override the `default.yaml` config file entirely by passing a new file with the `cfg` arguments, @@ -223,4 +221,4 @@ like `imgsz=320` in this example: ```bash yolo copy-cfg yolo cfg=default_copy.yaml imgsz=320 - ``` \ No newline at end of file + ``` diff --git a/downloads/ultralytics-main/docs/usage/engine.md b/downloads/ultralytics-main/docs/usage/engine.md index 2a77f7e1a..4edf33156 100644 --- a/downloads/ultralytics-main/docs/usage/engine.md +++ b/downloads/ultralytics-main/docs/usage/engine.md @@ -1,6 +1,7 @@ --- comments: true -description: Learn how to train and customize your models fast with the Ultralytics YOLO 'DetectionTrainer' and 'CustomTrainer'. Read more here! +description: Discover how to customize and extend base Ultralytics YOLO Trainer engines. Support your custom model and dataloader by overriding built-in functions. +keywords: Ultralytics, YOLO, trainer engines, BaseTrainer, DetectionTrainer, customizing trainers, extending trainers, custom model, custom dataloader --- Both the Ultralytics YOLO command-line and python interfaces are simply a high-level abstraction on the base engine @@ -13,15 +14,15 @@ the required functions or operations as long the as correct formats are followed custom model and dataloader by just overriding these functions: * `get_model(cfg, weights)` - The function that builds the model to be trained -* `get_dataloder()` - The function that builds the dataloader - More details and source code can be found in [`BaseTrainer` Reference](../reference/yolo/engine/trainer.md) +* `get_dataloader()` - The function that builds the dataloader + More details and source code can be found in [`BaseTrainer` Reference](../reference/engine/trainer.md) ## DetectionTrainer Here's how you can use the YOLOv8 `DetectionTrainer` and customize it. ```python -from ultralytics.yolo.v8.detect import DetectionTrainer +from ultralytics.models.yolo.detect import DetectionTrainer trainer = DetectionTrainer(overrides={...}) trainer.train() @@ -34,7 +35,7 @@ Let's customize the trainer **to train a custom detection model** that is not su simply overloading the existing the `get_model` functionality: ```python -from ultralytics.yolo.v8.detect import DetectionTrainer +from ultralytics.models.yolo.detect import DetectionTrainer class CustomTrainer(DetectionTrainer): @@ -53,19 +54,18 @@ You now realize that you need to customize the trainer further to: Here's how you can do it: ```python -from ultralytics.yolo.v8.detect import DetectionTrainer +from ultralytics.models.yolo.detect import DetectionTrainer +from ultralytics.nn.tasks import DetectionModel + + +class MyCustomModel(DetectionModel): + def init_criterion(self): + ... class CustomTrainer(DetectionTrainer): def get_model(self, cfg, weights): - ... - - def criterion(self, preds, batch): - # get ground truth - imgs = batch["imgs"] - bboxes = batch["bboxes"] - ... - return loss, loss_items # see Reference-> Trainer for details on the expected format + return MyCustomModel(...) # callback to upload model weights @@ -84,4 +84,4 @@ To know more about Callback triggering events and entry point, checkout our [Cal ## Other engine components There are other components that can be customized similarly like `Validators` and `Predictors` -See Reference section for more information on these. \ No newline at end of file +See Reference section for more information on these. diff --git a/downloads/ultralytics-main/docs/usage/python.md b/downloads/ultralytics-main/docs/usage/python.md index 04b813b9f..1522c69e5 100644 --- a/downloads/ultralytics-main/docs/usage/python.md +++ b/downloads/ultralytics-main/docs/usage/python.md @@ -1,6 +1,7 @@ --- comments: true -description: Integrate YOLOv8 in Python. Load, use pretrained models, train, and infer images. Export to ONNX. Track objects in videos. +description: Boost your Python projects with object detection, segmentation and classification using YOLOv8. Explore how to load, train, validate, predict, export, track and benchmark models with ease. +keywords: YOLOv8, Ultralytics, Python, object detection, segmentation, classification, model training, validation, prediction, model export, benchmark, real-time tracking --- # Python Usage @@ -18,22 +19,22 @@ format with just a few lines of code. ```python from ultralytics import YOLO - + # Create a new YOLO model from scratch model = YOLO('yolov8n.yaml') - + # Load a pretrained YOLO model (recommended for training) model = YOLO('yolov8n.pt') - + # Train the model using the 'coco128.yaml' dataset for 3 epochs results = model.train(data='coco128.yaml', epochs=3) - + # Evaluate the model's performance on the validation set results = model.val() - + # Perform object detection on an image using the model results = model('https://ultralytics.com/images/bus.jpg') - + # Export the model to ONNX format success = model.export(format='onnx') ``` @@ -51,7 +52,7 @@ accurately predict the classes and locations of objects in an image. from ultralytics import YOLO model = YOLO('yolov8n.pt') # pass any model type - model.train(epochs=5) + results = model.train(epochs=5) ``` === "From scratch" @@ -59,13 +60,13 @@ accurately predict the classes and locations of objects in an image. from ultralytics import YOLO model = YOLO('yolov8n.yaml') - model.train(data='coco128.yaml', epochs=5) + results = model.train(data='coco128.yaml', epochs=5) ``` === "Resume" ```python model = YOLO("last.pt") - model.train(resume=True) + results = model.train(resume=True) ``` [Train Examples](../modes/train.md){ .md-button .md-button--primary} @@ -92,7 +93,7 @@ of the model to improve its performance. from ultralytics import YOLO model = YOLO("model.pt") - # It'll use the data yaml file in model.pt if you don't set data. + # It'll use the data YAML file in model.pt if you don't set data. model.val() # or you can set the data you want to val model.val(data='coco128.yaml') @@ -134,7 +135,7 @@ predicts the classes and locations of objects in the input images or videos. === "Results usage" ```python # results would be a list of Results object including all the predictions by default - # but be careful as it could occupy a lot memory when there're many images, + # but be careful as it could occupy a lot memory when there're many images, # especially the task is segmentation. # 1. return as a list results = model.predict(source="folder") @@ -160,7 +161,7 @@ predicts the classes and locations of objects in the input images or videos. # Classification result.probs # cls prob, (num_class, ) - # Each result is composed of torch.Tensor by default, + # Each result is composed of torch.Tensor by default, # in which you can easily use following functionality: result = result.cuda() result = result.cpu() @@ -209,18 +210,18 @@ for applications such as surveillance systems or self-driving cars. !!! example "Track" === "Python" - + ```python from ultralytics import YOLO - + # Load a model model = YOLO('yolov8n.pt') # load an official detection model model = YOLO('yolov8n-seg.pt') # load an official segmentation model model = YOLO('path/to/best.pt') # load a custom model - + # Track with the model - results = model.track(source="https://youtu.be/Zgi9g1ksQHc", show=True) - results = model.track(source="https://youtu.be/Zgi9g1ksQHc", show=True, tracker="bytetrack.yaml") + results = model.track(source="https://youtu.be/Zgi9g1ksQHc", show=True) + results = model.track(source="https://youtu.be/Zgi9g1ksQHc", show=True, tracker="bytetrack.yaml") ``` [Track Examples](../modes/track.md){ .md-button .md-button--primary} @@ -236,13 +237,13 @@ their specific use case based on their requirements for speed and accuracy. !!! example "Benchmark" === "Python" - + Benchmark an official YOLOv8n model across all export formats. ```python - from ultralytics.yolo.utils.benchmarks import benchmark - + from ultralytics.utils.benchmarks import benchmark + # Benchmark - benchmark(model='yolov8n.pt', imgsz=640, half=False, device=0) + benchmark(model='yolov8n.pt', data='coco8.yaml', imgsz=640, half=False, device=0) ``` [Benchmark Examples](../modes/benchmark.md){ .md-button .md-button--primary} @@ -255,7 +256,7 @@ from `BaseTrainer`. !!! tip "Detection Trainer Example" ```python - from ultralytics.yolo import v8 import DetectionTrainer, DetectionValidator, DetectionPredictor + from ultralytics.models.yolo import DetectionTrainer, DetectionValidator, DetectionPredictor # trainer trainer = DetectionTrainer(overrides={}) @@ -279,4 +280,4 @@ You can easily customize Trainers to support custom tasks or explore R&D ideas. Learn more about Customizing `Trainers`, `Validators` and `Predictors` to suit your project needs in the Customization Section. -[Customization tutorials](engine.md){ .md-button .md-button--primary} \ No newline at end of file +[Customization tutorials](engine.md){ .md-button .md-button--primary} diff --git a/downloads/ultralytics-main/docs/yolov5/environments/aws_quickstart_tutorial.md b/downloads/ultralytics-main/docs/yolov5/environments/aws_quickstart_tutorial.md index dbcfb3a4a..52c64ec94 100644 --- a/downloads/ultralytics-main/docs/yolov5/environments/aws_quickstart_tutorial.md +++ b/downloads/ultralytics-main/docs/yolov5/environments/aws_quickstart_tutorial.md @@ -1,6 +1,7 @@ --- comments: true -description: Get started with YOLOv5 on AWS. Our comprehensive guide provides everything you need to know to run YOLOv5 on an Amazon Deep Learning instance. +description: Step-by-step guide to run YOLOv5 on AWS Deep Learning instance. Learn how to create an instance, connect to it and train, validate and deploy models. +keywords: AWS, YOLOv5, instance, deep learning, Ultralytics, guide, training, deployment, object detection --- # YOLOv5 🚀 on AWS Deep Learning Instance: A Comprehensive Guide @@ -55,7 +56,7 @@ Select the checkbox next to your running instance, and then click Connect. Copy ## 4. Run YOLOv5 -Once you have logged in to your instance, clone the repository and install the dependencies in a [**Python>=3.7.0**](https://www.python.org/) environment, including [**PyTorch>=1.7**](https://pytorch.org/get-started/locally/). [Models](https://github.com/ultralytics/yolov5/tree/master/models) and [datasets](https://github.com/ultralytics/yolov5/tree/master/data) download automatically from the latest YOLOv5 [release](https://github.com/ultralytics/yolov5/releases). +Once you have logged in to your instance, clone the repository and install the dependencies in a [**Python>=3.8.0**](https://www.python.org/) environment, including [**PyTorch>=1.8**](https://pytorch.org/get-started/locally/). [Models](https://github.com/ultralytics/yolov5/tree/master/models) and [datasets](https://github.com/ultralytics/yolov5/tree/master/data) download automatically from the latest YOLOv5 [release](https://github.com/ultralytics/yolov5/releases). ```bash git clone https://github.com/ultralytics/yolov5 # clone @@ -84,4 +85,4 @@ sudo swapon /swapfile free -h # check memory ``` -Now you have successfully set up and run YOLOv5 on an AWS Deep Learning instance. Enjoy training, testing, and deploying your object detection models! \ No newline at end of file +Now you have successfully set up and run YOLOv5 on an AWS Deep Learning instance. Enjoy training, testing, and deploying your object detection models! diff --git a/downloads/ultralytics-main/docs/yolov5/environments/docker_image_quickstart_tutorial.md b/downloads/ultralytics-main/docs/yolov5/environments/docker_image_quickstart_tutorial.md index 365139d11..44dcb174d 100644 --- a/downloads/ultralytics-main/docs/yolov5/environments/docker_image_quickstart_tutorial.md +++ b/downloads/ultralytics-main/docs/yolov5/environments/docker_image_quickstart_tutorial.md @@ -1,6 +1,7 @@ --- comments: true -description: Get started with YOLOv5 in a Docker container. Learn to set up and run YOLOv5 models and explore other quickstart options. 🚀 +description: Learn how to set up and run YOLOv5 in a Docker container. This tutorial includes the prerequisites and step-by-step instructions. +keywords: YOLOv5, Docker, Ultralytics, Image Detection, YOLOv5 Docker Image, Docker Container, Machine Learning, AI --- # Get Started with YOLOv5 🚀 in Docker @@ -60,4 +61,4 @@ python detect.py --weights yolov5s.pt --source path/to/images # run inference o python export.py --weights yolov5s.pt --include onnx coreml tflite # export models to other formats ``` -

\ No newline at end of file +

diff --git a/downloads/ultralytics-main/docs/yolov5/environments/google_cloud_quickstart_tutorial.md b/downloads/ultralytics-main/docs/yolov5/environments/google_cloud_quickstart_tutorial.md index 47f53b126..38a54f1fc 100644 --- a/downloads/ultralytics-main/docs/yolov5/environments/google_cloud_quickstart_tutorial.md +++ b/downloads/ultralytics-main/docs/yolov5/environments/google_cloud_quickstart_tutorial.md @@ -1,6 +1,7 @@ --- comments: true -description: Set up YOLOv5 on a Google Cloud Platform (GCP) Deep Learning VM. Train, test, detect, and export YOLOv5 models. Tutorial updated April 2023. +description: Step-by-step tutorial on how to set up and run YOLOv5 on Google Cloud Platform Deep Learning VM. Perfect guide for beginners and GCP new users!. +keywords: YOLOv5, Google Cloud Platform, GCP, Deep Learning VM, Ultralytics --- # Run YOLOv5 🚀 on Google Cloud Platform (GCP) Deep Learning Virtual Machine (VM) ⭐ @@ -26,7 +27,7 @@ The preinstalled [Anaconda](https://docs.anaconda.com/anaconda/packages/pkg-docs ## Step 2: Set Up the VM -Clone the YOLOv5 repository and install the [requirements.txt](https://github.com/ultralytics/yolov5/blob/master/requirements.txt) in a [**Python>=3.7.0**](https://www.python.org/) environment, including [**PyTorch>=1.7**](https://pytorch.org/get-started/locally/). [Models](https://github.com/ultralytics/yolov5/tree/master/models) and [datasets](https://github.com/ultralytics/yolov5/tree/master/data) will be downloaded automatically from the latest YOLOv5 [release](https://github.com/ultralytics/yolov5/releases). +Clone the YOLOv5 repository and install the [requirements.txt](https://github.com/ultralytics/yolov5/blob/master/requirements.txt) in a [**Python>=3.8.0**](https://www.python.org/) environment, including [**PyTorch>=1.8**](https://pytorch.org/get-started/locally/). [Models](https://github.com/ultralytics/yolov5/tree/master/models) and [datasets](https://github.com/ultralytics/yolov5/tree/master/data) will be downloaded automatically from the latest YOLOv5 [release](https://github.com/ultralytics/yolov5/releases). ```bash git clone https://github.com/ultralytics/yolov5 # clone @@ -45,4 +46,4 @@ python detect.py --weights yolov5s.pt --source path/to/images # run inference o python export.py --weights yolov5s.pt --include onnx coreml tflite # export models to other formats ``` -GCP terminal \ No newline at end of file +GCP terminal diff --git a/downloads/ultralytics-main/docs/yolov5/index.md b/downloads/ultralytics-main/docs/yolov5/index.md index e9db84d6f..ccd2b4500 100644 --- a/downloads/ultralytics-main/docs/yolov5/index.md +++ b/downloads/ultralytics-main/docs/yolov5/index.md @@ -1,9 +1,10 @@ --- comments: true -description: Discover the YOLOv5 object detection model designed to deliver fast and accurate real-time results. Let's dive into this documentation to harness its full potential! +description: Deep dive into Ultralytics' YOLOv5. Learn about object detection model - YOLOv5, how to train it on custom data, multi-GPU training and more. +keywords: Ultralytics, YOLOv5, Deep Learning, Object detection, PyTorch, Tutorial, Multi-GPU training, Custom data training --- -# Ultralytics YOLOv5 +# Comprehensive Guide to Ultralytics YOLOv5

@@ -21,61 +22,55 @@ description: Discover the YOLOv5 object detection model designed to deliver fast

-Welcome to the Ultralytics YOLOv5 🚀 Docs! YOLOv5, or You Only Look Once version 5, is an Ultralytics object detection model designed to deliver fast and accurate real-time results. +Welcome to the Ultralytics' YOLOv5 🚀 Documentation! YOLOv5, the fifth iteration of the revolutionary "You Only Look Once" object detection model, is designed to deliver high-speed, high-accuracy results in real-time.

-This powerful deep learning framework is built on the PyTorch platform and has gained immense popularity due to its ease of use, high performance, and versatility. In this documentation, we will guide you through the installation process, explain the model's architecture, showcase various use-cases, and provide detailed tutorials to help you harness the full potential of YOLOv5 for your computer vision projects. Let's dive in! +Built on PyTorch, this powerful deep learning framework has garnered immense popularity for its versatility, ease of use, and high performance. Our documentation guides you through the installation process, explains the architectural nuances of the model, showcases various use-cases, and provides a series of detailed tutorials. These resources will help you harness the full potential of YOLOv5 for your computer vision projects. Let's get started!

## Tutorials -* [Train Custom Data](tutorials/train_custom_data.md) 🚀 RECOMMENDED -* [Tips for Best Training Results](tutorials/tips_for_best_training_results.md) ☘️ -* [Multi-GPU Training](tutorials/multi_gpu_training.md) -* [PyTorch Hub](tutorials/pytorch_hub_model_loading.md) 🌟 NEW -* [TFLite, ONNX, CoreML, TensorRT Export](tutorials/model_export.md) 🚀 -* [NVIDIA Jetson platform Deployment](tutorials/running_on_jetson_nano.md) 🌟 NEW -* [Test-Time Augmentation (TTA)](tutorials/test_time_augmentation.md) -* [Model Ensembling](tutorials/model_ensembling.md) -* [Model Pruning/Sparsity](tutorials/model_pruning_and_sparsity.md) -* [Hyperparameter Evolution](tutorials/hyperparameter_evolution.md) -* [Transfer Learning with Frozen Layers](tutorials/transfer_learning_with_frozen_layers.md) -* [Architecture Summary](tutorials/architecture_description.md) 🌟 NEW -* [Roboflow for Datasets, Labeling, and Active Learning](tutorials/roboflow_datasets_integration.md) -* [ClearML Logging](tutorials/clearml_logging_integration.md) 🌟 NEW -* [YOLOv5 with Neural Magic's Deepsparse](tutorials/neural_magic_pruning_quantization.md) 🌟 NEW -* [Comet Logging](tutorials/comet_logging_integration.md) 🌟 NEW +Here's a compilation of comprehensive tutorials that will guide you through different aspects of YOLOv5. + +* [Train Custom Data](tutorials/train_custom_data.md) 🚀 RECOMMENDED: Learn how to train the YOLOv5 model on your custom dataset. +* [Tips for Best Training Results](tutorials/tips_for_best_training_results.md) ☘️: Uncover practical tips to optimize your model training process. +* [Multi-GPU Training](tutorials/multi_gpu_training.md): Understand how to leverage multiple GPUs to expedite your training. +* [PyTorch Hub](tutorials/pytorch_hub_model_loading.md) 🌟 NEW: Learn to load pre-trained models via PyTorch Hub. +* [TFLite, ONNX, CoreML, TensorRT Export](tutorials/model_export.md) 🚀: Understand how to export your model to different formats. +* [NVIDIA Jetson platform Deployment](tutorials/running_on_jetson_nano.md) 🌟 NEW: Learn how to deploy your YOLOv5 model on NVIDIA Jetson platform. +* [Test-Time Augmentation (TTA)](tutorials/test_time_augmentation.md): Explore how to use TTA to improve your model's prediction accuracy. +* [Model Ensembling](tutorials/model_ensembling.md): Learn the strategy of combining multiple models for improved performance. +* [Model Pruning/Sparsity](tutorials/model_pruning_and_sparsity.md): Understand pruning and sparsity concepts, and how to create a more efficient model. +* [Hyperparameter Evolution](tutorials/hyperparameter_evolution.md): Discover the process of automated hyperparameter tuning for better model performance. +* [Transfer Learning with Frozen Layers](tutorials/transfer_learning_with_frozen_layers.md): Learn how to implement transfer learning by freezing layers in YOLOv5. +* [Architecture Summary](tutorials/architecture_description.md) 🌟 Delve into the structural details of the YOLOv5 model. +* [Roboflow for Datasets](tutorials/roboflow_datasets_integration.md): Understand how to utilize Roboflow for dataset management, labeling, and active learning. +* [ClearML Logging](tutorials/clearml_logging_integration.md) 🌟 Learn how to integrate ClearML for efficient logging during your model training. +* [YOLOv5 with Neural Magic](tutorials/neural_magic_pruning_quantization.md) Discover how to use Neural Magic's Deepsparse to prune and quantize your YOLOv5 model. +* [Comet Logging](tutorials/comet_logging_integration.md) 🌟 NEW: Explore how to utilize Comet for improved model training logging. ## Environments -YOLOv5 may be run in any of the following up-to-date verified environments (with all dependencies -including [CUDA](https://developer.nvidia.com/cuda)/[CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/) -and [PyTorch](https://pytorch.org/) preinstalled): +YOLOv5 is designed to be run in the following up-to-date, verified environments, with all dependencies (including [CUDA](https://developer.nvidia.com/cuda)/[CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/), and [PyTorch](https://pytorch.org/)) pre-installed: - **Notebooks** with free GPU: Run on Gradient Open In Colab Open In Kaggle -- **Google Cloud** Deep Learning VM. - See [GCP Quickstart Guide](environments/google_cloud_quickstart_tutorial.md) +- **Google Cloud** Deep Learning VM. See [GCP Quickstart Guide](environments/google_cloud_quickstart_tutorial.md) - **Amazon** Deep Learning AMI. See [AWS Quickstart Guide](environments/aws_quickstart_tutorial.md) -- **Docker Image**. - See [Docker Quickstart Guide](environments/docker_image_quickstart_tutorial.md) Docker Pulls +- **Docker Image**. See [Docker Quickstart Guide](environments/docker_image_quickstart_tutorial.md) Docker Pulls ## Status YOLOv5 CI -If this badge is green, all [YOLOv5 GitHub Actions](https://github.com/ultralytics/yolov5/actions) Continuous -Integration (CI) tests are currently passing. CI tests verify correct operation of -YOLOv5 [training](https://github.com/ultralytics/yolov5/blob/master/train.py), [validation](https://github.com/ultralytics/yolov5/blob/master/val.py), [inference](https://github.com/ultralytics/yolov5/blob/master/detect.py), [export](https://github.com/ultralytics/yolov5/blob/master/export.py) -and [benchmarks](https://github.com/ultralytics/yolov5/blob/master/benchmarks.py) on macOS, Windows, and Ubuntu every 24 -hours and on every commit. +This badge signifies that all [YOLOv5 GitHub Actions](https://github.com/ultralytics/yolov5/actions) Continuous Integration (CI) tests are currently passing. CI tests verify the correct operation of YOLOv5 [training](https://github.com/ultralytics/yolov5/blob/master/train.py), [validation](https://github.com/ultralytics/yolov5/blob/master/val.py), [inference](https://github.com/ultralytics/yolov5/blob/master/detect.py), [export](https://github.com/ultralytics/yolov5/blob/master/export.py) and [benchmarks](https://github.com/ultralytics/yolov5/blob/master/benchmarks.py) on macOS, Windows, and Ubuntu every 24 hours and with every new commit.
\ No newline at end of file +
diff --git a/downloads/ultralytics-main/docs/yolov5/quickstart_tutorial.md b/downloads/ultralytics-main/docs/yolov5/quickstart_tutorial.md index 055a4ab52..d42d93d4f 100644 --- a/downloads/ultralytics-main/docs/yolov5/quickstart_tutorial.md +++ b/downloads/ultralytics-main/docs/yolov5/quickstart_tutorial.md @@ -1,6 +1,7 @@ --- comments: true -description: Learn how to quickly start using YOLOv5 including installation, inference, and training on this Ultralytics Docs page. +description: Kickstart your journey with YOLOv5. Learn how to install, run inference, and train models on your own images. Dive headfirst into object detection with PyTorch. +keywords: YOLOv5, Quickstart, Installation, Inference, Training, Object detection, PyTorch, Ultralytics --- # YOLOv5 Quickstart @@ -10,8 +11,8 @@ See below for quickstart examples. ## Install Clone repo and install [requirements.txt](https://github.com/ultralytics/yolov5/blob/master/requirements.txt) in a -[**Python>=3.7.0**](https://www.python.org/) environment, including -[**PyTorch>=1.7**](https://pytorch.org/get-started/locally/). +[**Python>=3.8.0**](https://www.python.org/) environment, including +[**PyTorch>=1.8**](https://pytorch.org/get-started/locally/). ```bash git clone https://github.com/ultralytics/yolov5 # clone @@ -76,4 +77,4 @@ python train.py --data coco.yaml --epochs 300 --weights '' --cfg yolov5n.yaml - yolov5x 16 ``` - \ No newline at end of file + diff --git a/downloads/ultralytics-main/docs/yolov5/tutorials/architecture_description.md b/downloads/ultralytics-main/docs/yolov5/tutorials/architecture_description.md index 71ef2bbc0..418fe8d7f 100644 --- a/downloads/ultralytics-main/docs/yolov5/tutorials/architecture_description.md +++ b/downloads/ultralytics-main/docs/yolov5/tutorials/architecture_description.md @@ -1,27 +1,34 @@ --- comments: true -description: 'Ultralytics YOLOv5 Docs: Learn model structure, data augmentation & training strategies. Build targets and the losses of object detection.' +description: Explore the architecture of YOLOv5, an object detection algorithm by Ultralytics. Understand the model structure, data augmentation methods, training strategies, and loss computation techniques. +keywords: Ultralytics, YOLOv5, Object Detection, Architecture, Model Structure, Data Augmentation, Training Strategies, Loss Computation --- +# Ultralytics YOLOv5 Architecture + +YOLOv5 (v6.0/6.1) is a powerful object detection algorithm developed by Ultralytics. This article dives deep into the YOLOv5 architecture, data augmentation strategies, training methodologies, and loss computation techniques. This comprehensive understanding will help improve your practical application of object detection in various fields, including surveillance, autonomous vehicles, and image recognition. + ## 1. Model Structure -YOLOv5 (v6.0/6.1) consists of: +YOLOv5's architecture consists of three main parts: -- **Backbone**: `New CSP-Darknet53` -- **Neck**: `SPPF`, `New CSP-PAN` -- **Head**: `YOLOv3 Head` +- **Backbone**: This is the main body of the network. For YOLOv5, the backbone is designed using the `New CSP-Darknet53` structure, a modification of the Darknet architecture used in previous versions. +- **Neck**: This part connects the backbone and the head. In YOLOv5, `SPPF` and `New CSP-PAN` structures are utilized. +- **Head**: This part is responsible for generating the final output. YOLOv5 uses the `YOLOv3 Head` for this purpose. -Model structure (`yolov5l.yaml`): +The structure of the model is depicted in the image below. The model structure details can be found in `yolov5l.yaml`. ![yolov5](https://user-images.githubusercontent.com/31005897/172404576-c260dcf9-76bb-4bc8-b6a9-f2d987792583.png) -Some minor changes compared to previous versions: +YOLOv5 introduces some minor changes compared to its predecessors: -1. Replace the `Focus` structure with `6x6 Conv2d`(more efficient, refer #4825) -2. Replace the `SPP` structure with `SPPF`(more than double the speed) +1. The `Focus` structure, found in earlier versions, is replaced with a `6x6 Conv2d` structure. This change boosts efficiency [#4825](https://github.com/ultralytics/yolov5/issues/4825). +2. The `SPP` structure is replaced with `SPPF`. This alteration more than doubles the speed of processing. + +To test the speed of `SPP` and `SPPF`, the following code can be used:
-test code +SPP vs SPPF speed profiling example (click to open) ```python import time @@ -67,12 +74,12 @@ def main(): t_start = time.time() for _ in range(100): spp(input_tensor) - print(f"spp time: {time.time() - t_start}") + print(f"SPP time: {time.time() - t_start}") t_start = time.time() for _ in range(100): sppf(input_tensor) - print(f"sppf time: {time.time() - t_start}") + print(f"SPPF time: {time.time() - t_start}") if __name__ == '__main__': @@ -83,78 +90,90 @@ result: ``` True -spp time: 0.5373051166534424 -sppf time: 0.20780706405639648 +SPP time: 0.5373051166534424 +SPPF time: 0.20780706405639648 ```
-## 2. Data Augmentation +## 2. Data Augmentation Techniques -- Mosaic - +YOLOv5 employs various data augmentation techniques to improve the model's ability to generalize and reduce overfitting. These techniques include: -- Copy paste - +- **Mosaic Augmentation**: An image processing technique that combines four training images into one in ways that encourage object detection models to better handle various object scales and translations. -- Random affine(Rotation, Scale, Translation and Shear) - + ![mosaic](https://user-images.githubusercontent.com/31005897/159109235-c7aad8f2-1d4f-41f9-8d5f-b2fde6f2885e.png) -- MixUp - +- **Copy-Paste Augmentation**: An innovative data augmentation method that copies random patches from an image and pastes them onto another randomly chosen image, effectively generating a new training sample. -- Albumentations -- Augment HSV(Hue, Saturation, Value) - + ![copy-paste](https://user-images.githubusercontent.com/31005897/159116277-91b45033-6bec-4f82-afc4-41138866628e.png) -- Random horizontal flip - +- **Random Affine Transformations**: This includes random rotation, scaling, translation, and shearing of the images. + + ![random-affine](https://user-images.githubusercontent.com/31005897/159109326-45cd5acb-14fa-43e7-9235-0f21b0021c7d.png) + +- **MixUp Augmentation**: A method that creates composite images by taking a linear combination of two images and their associated labels. + + ![mixup](https://user-images.githubusercontent.com/31005897/159109361-3b24333b-f481-478b-ae00-df7838f0b5cd.png) + +- **Albumentations**: A powerful library for image augmenting that supports a wide variety of augmentation techniques. +- **HSV Augmentation**: Random changes to the Hue, Saturation, and Value of the images. + + ![hsv](https://user-images.githubusercontent.com/31005897/159109407-83d100ba-1aba-4f4b-aa03-4f048f815981.png) + +- **Random Horizontal Flip**: An augmentation method that randomly flips images horizontally. + + ![horizontal-flip](https://user-images.githubusercontent.com/31005897/159109429-0d44619a-a76a-49eb-bfc0-6709860c043e.png) ## 3. Training Strategies -- Multi-scale training(0.5~1.5x) -- AutoAnchor(For training custom data) -- Warmup and Cosine LR scheduler -- EMA(Exponential Moving Average) -- Mixed precision -- Evolve hyper-parameters +YOLOv5 applies several sophisticated training strategies to enhance the model's performance. They include: -## 4. Others +- **Multiscale Training**: The input images are randomly rescaled within a range of 0.5 to 1.5 times their original size during the training process. +- **AutoAnchor**: This strategy optimizes the prior anchor boxes to match the statistical characteristics of the ground truth boxes in your custom data. +- **Warmup and Cosine LR Scheduler**: A method to adjust the learning rate to enhance model performance. +- **Exponential Moving Average (EMA)**: A strategy that uses the average of parameters over past steps to stabilize the training process and reduce generalization error. +- **Mixed Precision Training**: A method to perform operations in half-precision format, reducing memory usage and enhancing computational speed. +- **Hyperparameter Evolution**: A strategy to automatically tune hyperparameters to achieve optimal performance. + +## 4. Additional Features ### 4.1 Compute Losses -The YOLOv5 loss consists of three parts: +The loss in YOLOv5 is computed as a combination of three individual loss components: -- Classes loss(BCE loss) -- Objectness loss(BCE loss) -- Location loss(CIoU loss) +- **Classes Loss (BCE Loss)**: Binary Cross-Entropy loss, measures the error for the classification task. +- **Objectness Loss (BCE Loss)**: Another Binary Cross-Entropy loss, calculates the error in detecting whether an object is present in a particular grid cell or not. +- **Location Loss (CIoU Loss)**: Complete IoU loss, measures the error in localizing the object within the grid cell. + +The overall loss function is depicted by: ![loss](https://latex.codecogs.com/svg.image?Loss=\lambda_1L_{cls}+\lambda_2L_{obj}+\lambda_3L_{loc}) ### 4.2 Balance Losses -The objectness losses of the three prediction layers(`P3`, `P4`, `P5`) are weighted differently. The balance weights are `[4.0, 1.0, 0.4]` respectively. +The objectness losses of the three prediction layers (`P3`, `P4`, `P5`) are weighted differently. The balance weights are `[4.0, 1.0, 0.4]` respectively. This approach ensures that the predictions at different scales contribute appropriately to the total loss. ![obj_loss](https://latex.codecogs.com/svg.image?L_{obj}=4.0\cdot&space;L_{obj}^{small}+1.0\cdot&space;L_{obj}^{medium}+0.4\cdot&space;L_{obj}^{large}) ### 4.3 Eliminate Grid Sensitivity -In YOLOv2 and YOLOv3, the formula for calculating the predicted target information is: +The YOLOv5 architecture makes some important changes to the box prediction strategy compared to earlier versions of YOLO. In YOLOv2 and YOLOv3, the box coordinates were directly predicted using the activation of the last layer. -![b_x](https://latex.codecogs.com/svg.image?b_x=\sigma(t_x)+c_x) -![b_y](https://latex.codecogs.com/svg.image?b_y=\sigma(t_y)+c_y) -![b_w](https://latex.codecogs.com/svg.image?b_w=p_w\cdot&space;e^{t_w}) +![b_x](https://latex.codecogs.com/svg.image?b_x=\sigma(t_x)+c_x) +![b_y](https://latex.codecogs.com/svg.image?b_y=\sigma(t_y)+c_y) +![b_w](https://latex.codecogs.com/svg.image?b_w=p_w\cdot&space;e^{t_w}) ![b_h](https://latex.codecogs.com/svg.image?b_h=p_h\cdot&space;e^{t_h}) +However, in YOLOv5, the formula for predicting the box coordinates has been updated to reduce grid sensitivity and prevent the model from predicting unbounded box dimensions. +The revised formulas for calculating the predicted bounding box are as follows: -In YOLOv5, the formula is: - -![bx](https://latex.codecogs.com/svg.image?b_x=(2\cdot\sigma(t_x)-0.5)+c_x) -![by](https://latex.codecogs.com/svg.image?b_y=(2\cdot\sigma(t_y)-0.5)+c_y) -![bw](https://latex.codecogs.com/svg.image?b_w=p_w\cdot(2\cdot\sigma(t_w))^2) +![bx](https://latex.codecogs.com/svg.image?b_x=(2\cdot\sigma(t_x)-0.5)+c_x) +![by](https://latex.codecogs.com/svg.image?b_y=(2\cdot\sigma(t_y)-0.5)+c_y) +![bw](https://latex.codecogs.com/svg.image?b_w=p_w\cdot(2\cdot\sigma(t_w))^2) ![bh](https://latex.codecogs.com/svg.image?b_h=p_h\cdot(2\cdot\sigma(t_h))^2) Compare the center point offset before and after scaling. The center point offset range is adjusted from (0, 1) to (-0.5, 1.5). @@ -168,9 +187,11 @@ Compare the height and width scaling ratio(relative to anchor) before and after ### 4.4 Build Targets -Match positive samples: +The build target process in YOLOv5 is critical for training efficiency and model accuracy. It involves assigning ground truth boxes to the appropriate grid cells in the output map and matching them with the appropriate anchor boxes. -- Calculate the aspect ratio of GT and Anchor Templates +This process follows these steps: + +- Calculate the ratio of the ground truth box dimensions and the dimensions of each anchor template. ![rw](https://latex.codecogs.com/svg.image?r_w=w_{gt}/w_{at}) @@ -186,10 +207,18 @@ Match positive samples: -- Assign the successfully matched Anchor Templates to the corresponding cells +- If the calculated ratio is within the threshold, match the ground truth box with the corresponding anchor. -- Because the center point offset range is adjusted from (0, 1) to (-0.5, 1.5). GT Box can be assigned to more anchors. +- Assign the matched anchor to the appropriate cells, keeping in mind that due to the revised center point offset, a ground truth box can be assigned to more than one anchor. Because the center point offset range is adjusted from (0, 1) to (-0.5, 1.5). GT Box can be assigned to more anchors. - \ No newline at end of file + + +This way, the build targets process ensures that each ground truth object is properly assigned and matched during the training process, allowing YOLOv5 to learn the task of object detection more effectively. + +## Conclusion + +In conclusion, YOLOv5 represents a significant step forward in the development of real-time object detection models. By incorporating various new features, enhancements, and training strategies, it surpasses previous versions of the YOLO family in performance and efficiency. + +The primary enhancements in YOLOv5 include the use of a dynamic architecture, an extensive range of data augmentation techniques, innovative training strategies, as well as important adjustments in computing losses and the process of building targets. All these innovations significantly improve the accuracy and efficiency of object detection while retaining a high degree of speed, which is the trademark of YOLO models. diff --git a/downloads/ultralytics-main/docs/yolov5/tutorials/clearml_logging_integration.md b/downloads/ultralytics-main/docs/yolov5/tutorials/clearml_logging_integration.md index f0843cfb2..667f566d1 100644 --- a/downloads/ultralytics-main/docs/yolov5/tutorials/clearml_logging_integration.md +++ b/downloads/ultralytics-main/docs/yolov5/tutorials/clearml_logging_integration.md @@ -1,6 +1,7 @@ --- comments: true -description: Integrate ClearML with YOLOv5 to track experiments and manage data versions. Optimize hyperparameters and remotely monitor your runs. +description: Learn how ClearML can enhance your YOLOv5 pipeline – track your training runs, version your data, remotely monitor your models and optimize performance. +keywords: ClearML, YOLOv5, Ultralytics, AI toolbox, training data, remote training, hyperparameter optimization, YOLOv5 model --- # ClearML Integration @@ -106,7 +107,7 @@ Versioning your data separately from your code is generally a good idea and make ### Prepare Your Dataset -The YOLOv5 repository supports a number of different datasets by using yaml files containing their information. By default datasets are downloaded to the `../datasets` folder in relation to the repository root folder. So if you downloaded the `coco128` dataset using the link in the yaml or with the scripts provided by yolov5, you get this folder structure: +The YOLOv5 repository supports a number of different datasets by using YAML files containing their information. By default datasets are downloaded to the `../datasets` folder in relation to the repository root folder. So if you downloaded the `coco128` dataset using the link in the YAML or with the scripts provided by yolov5, you get this folder structure: ``` .. @@ -121,7 +122,7 @@ The YOLOv5 repository supports a number of different datasets by using yaml file But this can be any dataset you wish. Feel free to use your own, as long as you keep to this folder structure. -Next, ⚠️**copy the corresponding yaml file to the root of the dataset folder**⚠️. This yaml files contains the information ClearML will need to properly use the dataset. You can make this yourself too, of course, just follow the structure of the example yamls. +Next, ⚠️**copy the corresponding YAML file to the root of the dataset folder**⚠️. This YAML files contains the information ClearML will need to properly use the dataset. You can make this yourself too, of course, just follow the structure of the example YAMLs. Basically we need the following keys: `path`, `train`, `test`, `val`, `nc`, `names`. @@ -239,4 +240,4 @@ ClearML comes with autoscalers too! This tool will automatically spin up new rem Check out the autoscalers getting started video below. -[![Watch the video](https://img.youtube.com/vi/j4XVMAaUt3E/0.jpg)](https://youtu.be/j4XVMAaUt3E) \ No newline at end of file +[![Watch the video](https://img.youtube.com/vi/j4XVMAaUt3E/0.jpg)](https://youtu.be/j4XVMAaUt3E) diff --git a/downloads/ultralytics-main/docs/yolov5/tutorials/comet_logging_integration.md b/downloads/ultralytics-main/docs/yolov5/tutorials/comet_logging_integration.md index e1716c957..f2c6ba845 100644 --- a/downloads/ultralytics-main/docs/yolov5/tutorials/comet_logging_integration.md +++ b/downloads/ultralytics-main/docs/yolov5/tutorials/comet_logging_integration.md @@ -1,6 +1,7 @@ --- comments: true -description: Learn how to use YOLOv5 with Comet, a tool for logging and visualizing machine learning model metrics in real-time. Install, log and analyze seamlessly. +description: Learn how to set up and use Comet to enhance your YOLOv5 model training, metrics tracking and visualization. Includes a step by step guide to integrate Comet with YOLOv5. +keywords: YOLOv5, Comet, Machine Learning, Ultralytics, Real time metrics tracking, Hyperparameters, Model checkpoints, Model predictions, YOLOv5 training, Comet Credentials --- @@ -260,4 +261,4 @@ comet optimizer -j utils/loggers/comet/hpo.py \ Comet provides a number of ways to visualize the results of your sweep. Take a look at a [project with a completed sweep here](https://www.comet.com/examples/comet-example-yolov5/view/PrlArHGuuhDTKC1UuBmTtOSXD/panels?utm_source=yolov5&utm_medium=partner&utm_campaign=partner_yolov5_2022&utm_content=github) -hyperparameter-yolo \ No newline at end of file +hyperparameter-yolo diff --git a/downloads/ultralytics-main/docs/yolov5/tutorials/hyperparameter_evolution.md b/downloads/ultralytics-main/docs/yolov5/tutorials/hyperparameter_evolution.md index eebb554bb..0ed2c94c5 100644 --- a/downloads/ultralytics-main/docs/yolov5/tutorials/hyperparameter_evolution.md +++ b/downloads/ultralytics-main/docs/yolov5/tutorials/hyperparameter_evolution.md @@ -1,6 +1,7 @@ --- comments: true -description: Learn to find optimum YOLOv5 hyperparameters via **evolution**. A guide to learn hyperparameter tuning with Genetic Algorithms. +description: Learn how to optimize YOLOv5 with hyperparameter evolution using Genetic Algorithm. This guide provides steps to initialize, define, evolve and visualize hyperparameters for top performance. +keywords: Ultralytics, YOLOv5, Hyperparameter Optimization, Genetic Algorithm, Machine Learning, Deep Learning, AI, Object Detection, Image Classification, Python --- 📚 This guide explains **hyperparameter evolution** for YOLOv5 🚀. Hyperparameter evolution is a method of [Hyperparameter Optimization](https://en.wikipedia.org/wiki/Hyperparameter_optimization) using a [Genetic Algorithm](https://en.wikipedia.org/wiki/Genetic_algorithm) (GA) for optimization. UPDATED 25 September 2022. @@ -9,7 +10,7 @@ Hyperparameters in ML control various aspects of training, and finding optimal v ## Before You Start -Clone repo and install [requirements.txt](https://github.com/ultralytics/yolov5/blob/master/requirements.txt) in a [**Python>=3.7.0**](https://www.python.org/) environment, including [**PyTorch>=1.7**](https://pytorch.org/get-started/locally/). [Models](https://github.com/ultralytics/yolov5/tree/master/models) and [datasets](https://github.com/ultralytics/yolov5/tree/master/data) download automatically from the latest YOLOv5 [release](https://github.com/ultralytics/yolov5/releases). +Clone repo and install [requirements.txt](https://github.com/ultralytics/yolov5/blob/master/requirements.txt) in a [**Python>=3.8.0**](https://www.python.org/) environment, including [**PyTorch>=1.8**](https://pytorch.org/get-started/locally/). [Models](https://github.com/ultralytics/yolov5/tree/master/models) and [datasets](https://github.com/ultralytics/yolov5/tree/master/data) download automatically from the latest YOLOv5 [release](https://github.com/ultralytics/yolov5/releases). ```bash git clone https://github.com/ultralytics/yolov5 # clone @@ -63,10 +64,10 @@ copy_paste: 0.0 # segment copy-paste (probability) Fitness is the value we seek to maximize. In YOLOv5 we define a default fitness function as a weighted combination of metrics: `mAP@0.5` contributes 10% of the weight and `mAP@0.5:0.95` contributes the remaining 90%, with [Precision `P` and Recall `R`](https://en.wikipedia.org/wiki/Precision_and_recall) absent. You may adjust these as you see fit or use the default fitness definition in utils/metrics.py (recommended). ```python -def fitness(x): - # Model fitness as a weighted combination of metrics - w = [0.0, 0.0, 0.1, 0.9] # weights for [P, R, mAP@0.5, mAP@0.5:0.95] - return (x[:, :4] * w).sum(1) +def fitness(x): + # Model fitness as a weighted combination of metrics + w = [0.0, 0.0, 0.1, 0.9] # weights for [P, R, mAP@0.5, mAP@0.5:0.95] + return (x[:, :4] * w).sum(1) ``` ## 3. Evolve @@ -151,7 +152,7 @@ We recommend a minimum of 300 generations of evolution for best results. Note th ## Environments -YOLOv5 may be run in any of the following up-to-date verified environments (with all dependencies including [CUDA](https://developer.nvidia.com/cuda)/[CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/) and [PyTorch](https://pytorch.org/) preinstalled): +YOLOv5 is designed to be run in the following up-to-date verified environments (with all dependencies including [CUDA](https://developer.nvidia.com/cuda)/[CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/) and [PyTorch](https://pytorch.org/) preinstalled): - **Notebooks** with free GPU: Run on Gradient Open In Colab Open In Kaggle - **Google Cloud** Deep Learning VM. See [GCP Quickstart Guide](https://docs.ultralytics.com/yolov5/environments/google_cloud_quickstart_tutorial/) @@ -162,4 +163,4 @@ YOLOv5 may be run in any of the following up-to-date verified environments (with YOLOv5 CI -If this badge is green, all [YOLOv5 GitHub Actions](https://github.com/ultralytics/yolov5/actions) Continuous Integration (CI) tests are currently passing. CI tests verify correct operation of YOLOv5 [training](https://github.com/ultralytics/yolov5/blob/master/train.py), [validation](https://github.com/ultralytics/yolov5/blob/master/val.py), [inference](https://github.com/ultralytics/yolov5/blob/master/detect.py), [export](https://github.com/ultralytics/yolov5/blob/master/export.py) and [benchmarks](https://github.com/ultralytics/yolov5/blob/master/benchmarks.py) on macOS, Windows, and Ubuntu every 24 hours and on every commit. \ No newline at end of file +If this badge is green, all [YOLOv5 GitHub Actions](https://github.com/ultralytics/yolov5/actions) Continuous Integration (CI) tests are currently passing. CI tests verify correct operation of YOLOv5 [training](https://github.com/ultralytics/yolov5/blob/master/train.py), [validation](https://github.com/ultralytics/yolov5/blob/master/val.py), [inference](https://github.com/ultralytics/yolov5/blob/master/detect.py), [export](https://github.com/ultralytics/yolov5/blob/master/export.py) and [benchmarks](https://github.com/ultralytics/yolov5/blob/master/benchmarks.py) on macOS, Windows, and Ubuntu every 24 hours and on every commit. diff --git a/downloads/ultralytics-main/docs/yolov5/tutorials/model_ensembling.md b/downloads/ultralytics-main/docs/yolov5/tutorials/model_ensembling.md index a76996dee..8227a7d68 100644 --- a/downloads/ultralytics-main/docs/yolov5/tutorials/model_ensembling.md +++ b/downloads/ultralytics-main/docs/yolov5/tutorials/model_ensembling.md @@ -1,9 +1,10 @@ --- comments: true description: Learn how to ensemble YOLOv5 models for improved mAP and Recall! Clone the repo, install requirements, and start testing and inference. +keywords: YOLOv5, object detection, ensemble learning, mAP, Recall --- -📚 This guide explains how to use YOLOv5 🚀 **model ensembling** during testing and inference for improved mAP and Recall. +📚 This guide explains how to use YOLOv5 🚀 **model ensembling** during testing and inference for improved mAP and Recall. UPDATED 25 September 2022. From [https://en.wikipedia.org/wiki/Ensemble_learning](https://en.wikipedia.org/wiki/Ensemble_learning): @@ -11,7 +12,7 @@ From [https://en.wikipedia.org/wiki/Ensemble_learning](https://en.wikipedia.org/ ## Before You Start -Clone repo and install [requirements.txt](https://github.com/ultralytics/yolov5/blob/master/requirements.txt) in a [**Python>=3.7.0**](https://www.python.org/) environment, including [**PyTorch>=1.7**](https://pytorch.org/get-started/locally/). [Models](https://github.com/ultralytics/yolov5/tree/master/models) and [datasets](https://github.com/ultralytics/yolov5/tree/master/data) download automatically from the latest YOLOv5 [release](https://github.com/ultralytics/yolov5/releases). +Clone repo and install [requirements.txt](https://github.com/ultralytics/yolov5/blob/master/requirements.txt) in a [**Python>=3.8.0**](https://www.python.org/) environment, including [**PyTorch>=1.8**](https://pytorch.org/get-started/locally/). [Models](https://github.com/ultralytics/yolov5/tree/master/models) and [datasets](https://github.com/ultralytics/yolov5/tree/master/data) download automatically from the latest YOLOv5 [release](https://github.com/ultralytics/yolov5/releases). ```bash git clone https://github.com/ultralytics/yolov5 # clone @@ -33,7 +34,7 @@ Output: val: data=./data/coco.yaml, weights=['yolov5x.pt'], batch_size=32, imgsz=640, conf_thres=0.001, iou_thres=0.65, task=val, device=, single_cls=False, augment=False, verbose=False, save_txt=False, save_hybrid=False, save_conf=False, save_json=True, project=runs/val, name=exp, exist_ok=False, half=True YOLOv5 🚀 v5.0-267-g6a3ee7c torch 1.9.0+cu102 CUDA:0 (Tesla P100-PCIE-16GB, 16280.875MB) -Fusing layers... +Fusing layers... Model Summary: 476 layers, 87730285 parameters, 0 gradients val: Scanning '../datasets/coco/val2017' images and labels...4952 found, 48 missing, 0 empty, 0 corrupted: 100% 5000/5000 [00:01<00:00, 2846.03it/s] @@ -75,9 +76,9 @@ Output: val: data=./data/coco.yaml, weights=['yolov5x.pt', 'yolov5l6.pt'], batch_size=32, imgsz=640, conf_thres=0.001, iou_thres=0.6, task=val, device=, single_cls=False, augment=False, verbose=False, save_txt=False, save_hybrid=False, save_conf=False, save_json=True, project=runs/val, name=exp, exist_ok=False, half=True YOLOv5 🚀 v5.0-267-g6a3ee7c torch 1.9.0+cu102 CUDA:0 (Tesla P100-PCIE-16GB, 16280.875MB) -Fusing layers... +Fusing layers... Model Summary: 476 layers, 87730285 parameters, 0 gradients # Model 1 -Fusing layers... +Fusing layers... Model Summary: 501 layers, 77218620 parameters, 0 gradients # Model 2 Ensemble created with ['yolov5x.pt', 'yolov5l6.pt'] # Ensemble notice @@ -116,9 +117,9 @@ Output: detect: weights=['yolov5x.pt', 'yolov5l6.pt'], source=data/images, imgsz=640, conf_thres=0.25, iou_thres=0.45, max_det=1000, device=, view_img=False, save_txt=False, save_conf=False, save_crop=False, nosave=False, classes=None, agnostic_nms=False, augment=False, update=False, project=runs/detect, name=exp, exist_ok=False, line_width=3, hide_labels=False, hide_conf=False, half=False YOLOv5 🚀 v5.0-267-g6a3ee7c torch 1.9.0+cu102 CUDA:0 (Tesla P100-PCIE-16GB, 16280.875MB) -Fusing layers... +Fusing layers... Model Summary: 476 layers, 87730285 parameters, 0 gradients -Fusing layers... +Fusing layers... Model Summary: 501 layers, 77218620 parameters, 0 gradients Ensemble created with ['yolov5x.pt', 'yolov5l6.pt'] @@ -132,7 +133,7 @@ Done. (0.223s) ## Environments -YOLOv5 may be run in any of the following up-to-date verified environments (with all dependencies including [CUDA](https://developer.nvidia.com/cuda)/[CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/) and [PyTorch](https://pytorch.org/) preinstalled): +YOLOv5 is designed to be run in the following up-to-date verified environments (with all dependencies including [CUDA](https://developer.nvidia.com/cuda)/[CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/) and [PyTorch](https://pytorch.org/) preinstalled): - **Notebooks** with free GPU: Run on Gradient Open In Colab Open In Kaggle - **Google Cloud** Deep Learning VM. See [GCP Quickstart Guide](https://docs.ultralytics.com/yolov5/environments/google_cloud_quickstart_tutorial/) @@ -143,4 +144,4 @@ YOLOv5 may be run in any of the following up-to-date verified environments (with YOLOv5 CI -If this badge is green, all [YOLOv5 GitHub Actions](https://github.com/ultralytics/yolov5/actions) Continuous Integration (CI) tests are currently passing. CI tests verify correct operation of YOLOv5 [training](https://github.com/ultralytics/yolov5/blob/master/train.py), [validation](https://github.com/ultralytics/yolov5/blob/master/val.py), [inference](https://github.com/ultralytics/yolov5/blob/master/detect.py), [export](https://github.com/ultralytics/yolov5/blob/master/export.py) and [benchmarks](https://github.com/ultralytics/yolov5/blob/master/benchmarks.py) on macOS, Windows, and Ubuntu every 24 hours and on every commit. \ No newline at end of file +If this badge is green, all [YOLOv5 GitHub Actions](https://github.com/ultralytics/yolov5/actions) Continuous Integration (CI) tests are currently passing. CI tests verify correct operation of YOLOv5 [training](https://github.com/ultralytics/yolov5/blob/master/train.py), [validation](https://github.com/ultralytics/yolov5/blob/master/val.py), [inference](https://github.com/ultralytics/yolov5/blob/master/detect.py), [export](https://github.com/ultralytics/yolov5/blob/master/export.py) and [benchmarks](https://github.com/ultralytics/yolov5/blob/master/benchmarks.py) on macOS, Windows, and Ubuntu every 24 hours and on every commit. diff --git a/downloads/ultralytics-main/docs/yolov5/tutorials/model_export.md b/downloads/ultralytics-main/docs/yolov5/tutorials/model_export.md index 09e726854..6bad7ac26 100644 --- a/downloads/ultralytics-main/docs/yolov5/tutorials/model_export.md +++ b/downloads/ultralytics-main/docs/yolov5/tutorials/model_export.md @@ -1,16 +1,17 @@ --- comments: true -description: Export YOLOv5 models to TFLite, ONNX, CoreML, and TensorRT formats. Achieve up to 5x GPU speedup using TensorRT. Benchmarks included. +description: Learn how to export a trained YOLOv5 model from PyTorch to different formats including TorchScript, ONNX, OpenVINO, TensorRT, and CoreML, and how to use these models. +keywords: Ultralytics, YOLOv5, model export, PyTorch, TorchScript, ONNX, OpenVINO, TensorRT, CoreML, TensorFlow --- # TFLite, ONNX, CoreML, TensorRT Export -📚 This guide explains how to export a trained YOLOv5 🚀 model from PyTorch to ONNX and TorchScript formats. +📚 This guide explains how to export a trained YOLOv5 🚀 model from PyTorch to ONNX and TorchScript formats. UPDATED 8 December 2022. ## Before You Start -Clone repo and install [requirements.txt](https://github.com/ultralytics/yolov5/blob/master/requirements.txt) in a [**Python>=3.7.0**](https://www.python.org/) environment, including [**PyTorch>=1.7**](https://pytorch.org/get-started/locally/). [Models](https://github.com/ultralytics/yolov5/tree/master/models) and [datasets](https://github.com/ultralytics/yolov5/tree/master/data) download automatically from the latest YOLOv5 [release](https://github.com/ultralytics/yolov5/releases). +Clone repo and install [requirements.txt](https://github.com/ultralytics/yolov5/blob/master/requirements.txt) in a [**Python>=3.8.0**](https://www.python.org/) environment, including [**PyTorch>=1.8**](https://pytorch.org/get-started/locally/). [Models](https://github.com/ultralytics/yolov5/tree/master/models) and [datasets](https://github.com/ultralytics/yolov5/tree/master/data) download automatically from the latest YOLOv5 [release](https://github.com/ultralytics/yolov5/releases). ```bash git clone https://github.com/ultralytics/yolov5 # clone @@ -110,12 +111,12 @@ Output: ```bash export: data=data/coco128.yaml, weights=['yolov5s.pt'], imgsz=[640, 640], batch_size=1, device=cpu, half=False, inplace=False, train=False, keras=False, optimize=False, int8=False, dynamic=False, simplify=False, opset=12, verbose=False, workspace=4, nms=False, agnostic_nms=False, topk_per_class=100, topk_all=100, iou_thres=0.45, conf_thres=0.25, include=['torchscript', 'onnx'] -YOLOv5 🚀 v6.2-104-ge3e5122 Python-3.7.13 torch-1.12.1+cu113 CPU +YOLOv5 🚀 v6.2-104-ge3e5122 Python-3.8.0 torch-1.12.1+cu113 CPU Downloading https://github.com/ultralytics/yolov5/releases/download/v6.2/yolov5s.pt to yolov5s.pt... 100% 14.1M/14.1M [00:00<00:00, 274MB/s] -Fusing layers... +Fusing layers... YOLOv5s summary: 213 layers, 7225885 parameters, 0 gradients PyTorch: starting from yolov5s.pt with output shape (1, 25200, 85) (14.1 MB) @@ -128,8 +129,8 @@ ONNX: export success ✅ 2.3s, saved as yolov5s.onnx (28.0 MB) Export complete (5.5s) Results saved to /content/yolov5 -Detect: python detect.py --weights yolov5s.onnx -Validate: python val.py --weights yolov5s.onnx +Detect: python detect.py --weights yolov5s.onnx +Validate: python val.py --weights yolov5s.onnx PyTorch Hub: model = torch.hub.load('ultralytics/yolov5', 'custom', 'yolov5s.onnx') Visualize: https://netron.app/ ``` @@ -147,7 +148,7 @@ The 3 exported models will be saved alongside the original PyTorch model: ```bash python detect.py --weights yolov5s.pt # PyTorch yolov5s.torchscript # TorchScript - yolov5s.onnx # ONNX Runtime or OpenCV DNN with --dnn + yolov5s.onnx # ONNX Runtime or OpenCV DNN with dnn=True yolov5s_openvino_model # OpenVINO yolov5s.engine # TensorRT yolov5s.mlmodel # CoreML (macOS only) @@ -163,7 +164,7 @@ python detect.py --weights yolov5s.pt # PyTorch ```bash python val.py --weights yolov5s.pt # PyTorch yolov5s.torchscript # TorchScript - yolov5s.onnx # ONNX Runtime or OpenCV DNN with --dnn + yolov5s.onnx # ONNX Runtime or OpenCV DNN with dnn=True yolov5s_openvino_model # OpenVINO yolov5s.engine # TensorRT yolov5s.mlmodel # CoreML (macOS Only) @@ -231,7 +232,7 @@ YOLOv5 OpenVINO C++ inference examples: ## Environments -YOLOv5 may be run in any of the following up-to-date verified environments (with all dependencies including [CUDA](https://developer.nvidia.com/cuda)/[CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/) and [PyTorch](https://pytorch.org/) preinstalled): +YOLOv5 is designed to be run in the following up-to-date verified environments (with all dependencies including [CUDA](https://developer.nvidia.com/cuda)/[CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/) and [PyTorch](https://pytorch.org/) preinstalled): - **Notebooks** with free GPU: Run on Gradient Open In Colab Open In Kaggle - **Google Cloud** Deep Learning VM. See [GCP Quickstart Guide](https://docs.ultralytics.com/yolov5/environments/google_cloud_quickstart_tutorial/) @@ -242,4 +243,4 @@ YOLOv5 may be run in any of the following up-to-date verified environments (with YOLOv5 CI -If this badge is green, all [YOLOv5 GitHub Actions](https://github.com/ultralytics/yolov5/actions) Continuous Integration (CI) tests are currently passing. CI tests verify correct operation of YOLOv5 [training](https://github.com/ultralytics/yolov5/blob/master/train.py), [validation](https://github.com/ultralytics/yolov5/blob/master/val.py), [inference](https://github.com/ultralytics/yolov5/blob/master/detect.py), [export](https://github.com/ultralytics/yolov5/blob/master/export.py) and [benchmarks](https://github.com/ultralytics/yolov5/blob/master/benchmarks.py) on macOS, Windows, and Ubuntu every 24 hours and on every commit. \ No newline at end of file +If this badge is green, all [YOLOv5 GitHub Actions](https://github.com/ultralytics/yolov5/actions) Continuous Integration (CI) tests are currently passing. CI tests verify correct operation of YOLOv5 [training](https://github.com/ultralytics/yolov5/blob/master/train.py), [validation](https://github.com/ultralytics/yolov5/blob/master/val.py), [inference](https://github.com/ultralytics/yolov5/blob/master/detect.py), [export](https://github.com/ultralytics/yolov5/blob/master/export.py) and [benchmarks](https://github.com/ultralytics/yolov5/blob/master/benchmarks.py) on macOS, Windows, and Ubuntu every 24 hours and on every commit. diff --git a/downloads/ultralytics-main/docs/yolov5/tutorials/model_pruning_and_sparsity.md b/downloads/ultralytics-main/docs/yolov5/tutorials/model_pruning_and_sparsity.md index 0793f662e..bf2d647fa 100644 --- a/downloads/ultralytics-main/docs/yolov5/tutorials/model_pruning_and_sparsity.md +++ b/downloads/ultralytics-main/docs/yolov5/tutorials/model_pruning_and_sparsity.md @@ -1,14 +1,15 @@ --- comments: true -description: Learn how to apply pruning to your YOLOv5 models. See the before and after performance with an explanation of sparsity and more. +description: Improve YOLOv5 model efficiency by pruning with Ultralytics. Understand the process, conduct tests and view the impact on accuracy and sparsity. Test-maintained API environments. +keywords: YOLOv5, YOLO, Ultralytics, model pruning, PyTorch, machine learning, deep learning, computer vision, object detection --- -📚 This guide explains how to apply **pruning** to YOLOv5 🚀 models. +📚 This guide explains how to apply **pruning** to YOLOv5 🚀 models. UPDATED 25 September 2022. ## Before You Start -Clone repo and install [requirements.txt](https://github.com/ultralytics/yolov5/blob/master/requirements.txt) in a [**Python>=3.7.0**](https://www.python.org/) environment, including [**PyTorch>=1.7**](https://pytorch.org/get-started/locally/). [Models](https://github.com/ultralytics/yolov5/tree/master/models) and [datasets](https://github.com/ultralytics/yolov5/tree/master/data) download automatically from the latest YOLOv5 [release](https://github.com/ultralytics/yolov5/releases). +Clone repo and install [requirements.txt](https://github.com/ultralytics/yolov5/blob/master/requirements.txt) in a [**Python>=3.8.0**](https://www.python.org/) environment, including [**PyTorch>=1.8**](https://pytorch.org/get-started/locally/). [Models](https://github.com/ultralytics/yolov5/tree/master/models) and [datasets](https://github.com/ultralytics/yolov5/tree/master/data) download automatically from the latest YOLOv5 [release](https://github.com/ultralytics/yolov5/releases). ```bash git clone https://github.com/ultralytics/yolov5 # clone @@ -30,7 +31,7 @@ Output: val: data=/content/yolov5/data/coco.yaml, weights=['yolov5x.pt'], batch_size=32, imgsz=640, conf_thres=0.001, iou_thres=0.65, task=val, device=, workers=8, single_cls=False, augment=False, verbose=False, save_txt=False, save_hybrid=False, save_conf=False, save_json=True, project=runs/val, name=exp, exist_ok=False, half=True, dnn=False YOLOv5 🚀 v6.0-224-g4c40933 torch 1.10.0+cu111 CUDA:0 (Tesla V100-SXM2-16GB, 16160MiB) -Fusing layers... +Fusing layers... Model Summary: 444 layers, 86705005 parameters, 0 gradients val: Scanning '/content/datasets/coco/val2017.cache' images and labels... 4952 found, 48 missing, 0 empty, 0 corrupt: 100% 5000/5000 [00:00Run on Gradient Open In Colab Open In Kaggle - **Google Cloud** Deep Learning VM. See [GCP Quickstart Guide](https://docs.ultralytics.com/yolov5/environments/google_cloud_quickstart_tutorial/) @@ -106,4 +107,4 @@ YOLOv5 may be run in any of the following up-to-date verified environments (with YOLOv5 CI -If this badge is green, all [YOLOv5 GitHub Actions](https://github.com/ultralytics/yolov5/actions) Continuous Integration (CI) tests are currently passing. CI tests verify correct operation of YOLOv5 [training](https://github.com/ultralytics/yolov5/blob/master/train.py), [validation](https://github.com/ultralytics/yolov5/blob/master/val.py), [inference](https://github.com/ultralytics/yolov5/blob/master/detect.py), [export](https://github.com/ultralytics/yolov5/blob/master/export.py) and [benchmarks](https://github.com/ultralytics/yolov5/blob/master/benchmarks.py) on macOS, Windows, and Ubuntu every 24 hours and on every commit. \ No newline at end of file +If this badge is green, all [YOLOv5 GitHub Actions](https://github.com/ultralytics/yolov5/actions) Continuous Integration (CI) tests are currently passing. CI tests verify correct operation of YOLOv5 [training](https://github.com/ultralytics/yolov5/blob/master/train.py), [validation](https://github.com/ultralytics/yolov5/blob/master/val.py), [inference](https://github.com/ultralytics/yolov5/blob/master/detect.py), [export](https://github.com/ultralytics/yolov5/blob/master/export.py) and [benchmarks](https://github.com/ultralytics/yolov5/blob/master/benchmarks.py) on macOS, Windows, and Ubuntu every 24 hours and on every commit. diff --git a/downloads/ultralytics-main/docs/yolov5/tutorials/multi_gpu_training.md b/downloads/ultralytics-main/docs/yolov5/tutorials/multi_gpu_training.md index d002d05c1..7fe8355d8 100644 --- a/downloads/ultralytics-main/docs/yolov5/tutorials/multi_gpu_training.md +++ b/downloads/ultralytics-main/docs/yolov5/tutorials/multi_gpu_training.md @@ -1,14 +1,15 @@ --- comments: true -description: Learn how to train your dataset on single or multiple machines using YOLOv5 on multiple GPUs. Use simple commands with DDP mode for faster performance. +description: Learn how to train datasets on single or multiple GPUs using YOLOv5. Includes setup, training modes and result profiling for efficient leveraging of multiple GPUs. +keywords: YOLOv5, multi-GPU Training, YOLOv5 training, deep learning, machine learning, object detection, Ultralytics --- -📚 This guide explains how to properly use **multiple** GPUs to train a dataset with YOLOv5 🚀 on single or multiple machine(s). +📚 This guide explains how to properly use **multiple** GPUs to train a dataset with YOLOv5 🚀 on single or multiple machine(s). UPDATED 25 December 2022. ## Before You Start -Clone repo and install [requirements.txt](https://github.com/ultralytics/yolov5/blob/master/requirements.txt) in a [**Python>=3.7.0**](https://www.python.org/) environment, including [**PyTorch>=1.7**](https://pytorch.org/get-started/locally/). [Models](https://github.com/ultralytics/yolov5/tree/master/models) and [datasets](https://github.com/ultralytics/yolov5/tree/master/data) download automatically from the latest YOLOv5 [release](https://github.com/ultralytics/yolov5/releases). +Clone repo and install [requirements.txt](https://github.com/ultralytics/yolov5/blob/master/requirements.txt) in a [**Python>=3.8.0**](https://www.python.org/) environment, including [**PyTorch>=1.8**](https://pytorch.org/get-started/locally/). [Models](https://github.com/ultralytics/yolov5/tree/master/models) and [datasets](https://github.com/ultralytics/yolov5/tree/master/data) download automatically from the latest YOLOv5 [release](https://github.com/ultralytics/yolov5/releases). ```bash git clone https://github.com/ultralytics/yolov5 # clone @@ -135,9 +136,9 @@ cd .. && rm -rf app && git clone https://github.com/ultralytics/yolov5 -b master cp data/coco.yaml data/coco_profile.yaml # profile -python train.py --batch-size 16 --data coco_profile.yaml --weights yolov5l.pt --epochs 1 --device 0 -python -m torch.distributed.run --nproc_per_node 2 train.py --batch-size 32 --data coco_profile.yaml --weights yolov5l.pt --epochs 1 --device 0,1 -python -m torch.distributed.run --nproc_per_node 4 train.py --batch-size 64 --data coco_profile.yaml --weights yolov5l.pt --epochs 1 --device 0,1,2,3 +python train.py --batch-size 16 --data coco_profile.yaml --weights yolov5l.pt --epochs 1 --device 0 +python -m torch.distributed.run --nproc_per_node 2 train.py --batch-size 32 --data coco_profile.yaml --weights yolov5l.pt --epochs 1 --device 0,1 +python -m torch.distributed.run --nproc_per_node 4 train.py --batch-size 64 --data coco_profile.yaml --weights yolov5l.pt --epochs 1 --device 0,1,2,3 python -m torch.distributed.run --nproc_per_node 8 train.py --batch-size 128 --data coco_profile.yaml --weights yolov5l.pt --epochs 1 --device 0,1,2,3,4,5,6,7 ``` @@ -172,7 +173,7 @@ If you went through all the above, feel free to raise an Issue by giving as much ## Environments -YOLOv5 may be run in any of the following up-to-date verified environments (with all dependencies including [CUDA](https://developer.nvidia.com/cuda)/[CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/) and [PyTorch](https://pytorch.org/) preinstalled): +YOLOv5 is designed to be run in the following up-to-date verified environments (with all dependencies including [CUDA](https://developer.nvidia.com/cuda)/[CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/) and [PyTorch](https://pytorch.org/) preinstalled): - **Notebooks** with free GPU: Run on Gradient Open In Colab Open In Kaggle - **Google Cloud** Deep Learning VM. See [GCP Quickstart Guide](https://docs.ultralytics.com/yolov5/environments/google_cloud_quickstart_tutorial/) @@ -187,4 +188,4 @@ If this badge is green, all [YOLOv5 GitHub Actions](https://github.com/ultralyti ## Credits -I would like to thank @MagicFrogSJTU, who did all the heavy lifting, and @glenn-jocher for guiding us along the way. \ No newline at end of file +I would like to thank @MagicFrogSJTU, who did all the heavy lifting, and @glenn-jocher for guiding us along the way. diff --git a/downloads/ultralytics-main/docs/yolov5/tutorials/neural_magic_pruning_quantization.md b/downloads/ultralytics-main/docs/yolov5/tutorials/neural_magic_pruning_quantization.md index 532ced7a7..8b978f7a1 100644 --- a/downloads/ultralytics-main/docs/yolov5/tutorials/neural_magic_pruning_quantization.md +++ b/downloads/ultralytics-main/docs/yolov5/tutorials/neural_magic_pruning_quantization.md @@ -1,6 +1,7 @@ --- comments: true -description: Learn how to deploy YOLOv5 with DeepSparse to achieve exceptional CPU performance close to GPUs, using pruning, and quantization.
+description: Explore how to achieve exceptional AI performance with DeepSparse's incredible inference speed. Discover how to deploy YOLOv5, and learn about model sparsification and fine-tuning with SparseML. +keywords: YOLOv5, DeepSparse, Ultralytics, Neural Magic, sparsification, inference runtime, deep learning, deployment, model fine-tuning, SparseML, AI performance, GPU-class performance --- (N, 1, 2), (N, ) --> (N, 1) + points, labels = points[:, None, :], labels[:, None] + if bboxes is not None: + bboxes = torch.as_tensor(bboxes, dtype=torch.float32, device=self.device) + bboxes = bboxes[None] if bboxes.ndim == 1 else bboxes + bboxes *= r + if masks is not None: + masks = torch.as_tensor(masks, dtype=torch.float32, device=self.device) + masks = masks[:, None, :, :] + + points = (points, labels) if points is not None else None + # Embed prompts + sparse_embeddings, dense_embeddings = self.model.prompt_encoder( + points=points, + boxes=bboxes, + masks=masks, + ) + + # Predict masks + pred_masks, pred_scores = self.model.mask_decoder( + image_embeddings=features, + image_pe=self.model.prompt_encoder.get_dense_pe(), + sparse_prompt_embeddings=sparse_embeddings, + dense_prompt_embeddings=dense_embeddings, + multimask_output=multimask_output, + ) + + # (N, d, H, W) --> (N*d, H, W), (N, d) --> (N*d, ) + # `d` could be 1 or 3 depends on `multimask_output`. + return pred_masks.flatten(0, 1), pred_scores.flatten(0, 1) + + def generate(self, + im, + crop_n_layers=0, + crop_overlap_ratio=512 / 1500, + crop_downscale_factor=1, + point_grids=None, + points_stride=32, + points_batch_size=64, + conf_thres=0.88, + stability_score_thresh=0.95, + stability_score_offset=0.95, + crop_nms_thresh=0.7): + """Segment the whole image. + + Args: + im (torch.Tensor): The preprocessed image, (N, C, H, W). + crop_n_layers (int): If >0, mask prediction will be run again on + crops of the image. Sets the number of layers to run, where each + layer has 2**i_layer number of image crops. + crop_overlap_ratio (float): Sets the degree to which crops overlap. + In the first crop layer, crops will overlap by this fraction of + the image length. Later layers with more crops scale down this overlap. + crop_downscale_factor (int): The number of points-per-side + sampled in layer n is scaled down by crop_n_points_downscale_factor**n. + point_grids (list(np.ndarray), None): A list over explicit grids + of points used for sampling, normalized to [0,1]. The nth grid in the + list is used in the nth crop layer. Exclusive with points_per_side. + points_stride (int, None): The number of points to be sampled + along one side of the image. The total number of points is + points_per_side**2. If None, 'point_grids' must provide explicit + point sampling. + points_batch_size (int): Sets the number of points run simultaneously + by the model. Higher numbers may be faster but use more GPU memory. + conf_thres (float): A filtering threshold in [0,1], using the + model's predicted mask quality. + stability_score_thresh (float): A filtering threshold in [0,1], using + the stability of the mask under changes to the cutoff used to binarize + the model's mask predictions. + stability_score_offset (float): The amount to shift the cutoff when + calculated the stability score. + crop_nms_thresh (float): The box IoU cutoff used by non-maximal + suppression to filter duplicate masks between different crops. + """ + self.segment_all = True + ih, iw = im.shape[2:] + crop_regions, layer_idxs = generate_crop_boxes((ih, iw), crop_n_layers, crop_overlap_ratio) + if point_grids is None: + point_grids = build_all_layer_point_grids( + points_stride, + crop_n_layers, + crop_downscale_factor, + ) + pred_masks, pred_scores, pred_bboxes, region_areas = [], [], [], [] + for crop_region, layer_idx in zip(crop_regions, layer_idxs): + x1, y1, x2, y2 = crop_region + w, h = x2 - x1, y2 - y1 + area = torch.tensor(w * h, device=im.device) + points_scale = np.array([[w, h]]) # w, h + # Crop image and interpolate to input size + crop_im = F.interpolate(im[..., y1:y2, x1:x2], (ih, iw), mode='bilinear', align_corners=False) + # (num_points, 2) + points_for_image = point_grids[layer_idx] * points_scale + crop_masks, crop_scores, crop_bboxes = [], [], [] + for (points, ) in batch_iterator(points_batch_size, points_for_image): + pred_mask, pred_score = self.prompt_inference(crop_im, points=points, multimask_output=True) + # Interpolate predicted masks to input size + pred_mask = F.interpolate(pred_mask[None], (h, w), mode='bilinear', align_corners=False)[0] + idx = pred_score > conf_thres + pred_mask, pred_score = pred_mask[idx], pred_score[idx] + + stability_score = calculate_stability_score(pred_mask, self.model.mask_threshold, + stability_score_offset) + idx = stability_score > stability_score_thresh + pred_mask, pred_score = pred_mask[idx], pred_score[idx] + # Bool type is much more memory-efficient. + pred_mask = pred_mask > self.model.mask_threshold + # (N, 4) + pred_bbox = batched_mask_to_box(pred_mask).float() + keep_mask = ~is_box_near_crop_edge(pred_bbox, crop_region, [0, 0, iw, ih]) + if not torch.all(keep_mask): + pred_bbox = pred_bbox[keep_mask] + pred_mask = pred_mask[keep_mask] + pred_score = pred_score[keep_mask] + + crop_masks.append(pred_mask) + crop_bboxes.append(pred_bbox) + crop_scores.append(pred_score) + + # Do nms within this crop + crop_masks = torch.cat(crop_masks) + crop_bboxes = torch.cat(crop_bboxes) + crop_scores = torch.cat(crop_scores) + keep = torchvision.ops.nms(crop_bboxes, crop_scores, self.args.iou) # NMS + crop_bboxes = uncrop_boxes_xyxy(crop_bboxes[keep], crop_region) + crop_masks = uncrop_masks(crop_masks[keep], crop_region, ih, iw) + crop_scores = crop_scores[keep] + + pred_masks.append(crop_masks) + pred_bboxes.append(crop_bboxes) + pred_scores.append(crop_scores) + region_areas.append(area.expand(len(crop_masks))) + + pred_masks = torch.cat(pred_masks) + pred_bboxes = torch.cat(pred_bboxes) + pred_scores = torch.cat(pred_scores) + region_areas = torch.cat(region_areas) + + # Remove duplicate masks between crops + if len(crop_regions) > 1: + scores = 1 / region_areas + keep = torchvision.ops.nms(pred_bboxes, scores, crop_nms_thresh) + pred_masks = pred_masks[keep] + pred_bboxes = pred_bboxes[keep] + pred_scores = pred_scores[keep] + + return pred_masks, pred_scores, pred_bboxes + + def setup_model(self, model, verbose=True): + """Set up YOLO model with specified thresholds and device.""" + device = select_device(self.args.device, verbose=verbose) + if model is None: + model = build_sam(self.args.model) + model.eval() + self.model = model.to(device) + self.device = device + self.mean = torch.tensor([123.675, 116.28, 103.53]).view(-1, 1, 1).to(device) + self.std = torch.tensor([58.395, 57.12, 57.375]).view(-1, 1, 1).to(device) + # TODO: Temporary settings for compatibility + self.model.pt = False + self.model.triton = False + self.model.stride = 32 + self.model.fp16 = False + self.done_warmup = True + + def postprocess(self, preds, img, orig_imgs): + """Post-processes inference output predictions to create detection masks for objects.""" + # (N, 1, H, W), (N, 1) + pred_masks, pred_scores = preds[:2] + pred_bboxes = preds[2] if self.segment_all else None + names = dict(enumerate(str(i) for i in range(len(pred_masks)))) + results = [] + for i, masks in enumerate([pred_masks]): + orig_img = orig_imgs[i] if isinstance(orig_imgs, list) else orig_imgs + if pred_bboxes is not None: + pred_bboxes = ops.scale_boxes(img.shape[2:], pred_bboxes.float(), orig_img.shape, padding=False) + cls = torch.arange(len(pred_masks), dtype=torch.int32, device=pred_masks.device) + pred_bboxes = torch.cat([pred_bboxes, pred_scores[:, None], cls[:, None]], dim=-1) + + masks = ops.scale_masks(masks[None].float(), orig_img.shape[:2], padding=False)[0] + masks = masks > self.model.mask_threshold # to bool + path = self.batch[0] + img_path = path[i] if isinstance(path, list) else path + results.append(Results(orig_img=orig_img, path=img_path, names=names, masks=masks, boxes=pred_bboxes)) + # Reset segment-all mode. + self.segment_all = False + return results + + def setup_source(self, source): + """Sets up source and inference mode.""" + if source is not None: + super().setup_source(source) + + def set_image(self, image): + """Set image in advance. + Args: + + image (str | np.ndarray): image file path or np.ndarray image by cv2. + """ + if self.model is None: + model = build_sam(self.args.model) + self.setup_model(model) + self.setup_source(image) + assert len(self.dataset) == 1, '`set_image` only supports setting one image!' + for batch in self.dataset: + im = self.preprocess(batch[1]) + self.features = self.model.image_encoder(im) + self.im = im + break + + def set_prompts(self, prompts): + """Set prompts in advance.""" + self.prompts = prompts + + def reset_image(self): + self.im = None + self.features = None + + @staticmethod + def remove_small_regions(masks, min_area=0, nms_thresh=0.7): + """ + Removes small disconnected regions and holes in masks, then reruns + box NMS to remove any new duplicates. Requires open-cv as a dependency. + + Args: + masks (torch.Tensor): Masks, (N, H, W). + min_area (int): Minimum area threshold. + nms_thresh (float): NMS threshold. + """ + if len(masks) == 0: + return masks + + # Filter small disconnected regions and holes + new_masks = [] + scores = [] + for mask in masks: + mask = mask.cpu().numpy() + mask, changed = remove_small_regions(mask, min_area, mode='holes') + unchanged = not changed + mask, changed = remove_small_regions(mask, min_area, mode='islands') + unchanged = unchanged and not changed + + new_masks.append(torch.as_tensor(mask).unsqueeze(0)) + # Give score=0 to changed masks and score=1 to unchanged masks + # so NMS will prefer ones that didn't need postprocessing + scores.append(float(unchanged)) + + # Recalculate boxes and remove any new duplicates + new_masks = torch.cat(new_masks, dim=0) + boxes = batched_mask_to_box(new_masks) + keep = torchvision.ops.nms( + boxes.float(), + torch.as_tensor(scores), + nms_thresh, + ) + + # Only recalculate masks for masks that have changed + for i in keep: + if scores[i] == 0.0: + masks[i] = new_masks[i] + + return masks[keep] diff --git a/downloads/ultralytics-main/ultralytics/models/utils/__init__.py b/downloads/ultralytics-main/ultralytics/models/utils/__init__.py new file mode 100644 index 000000000..9e68dc122 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/utils/__init__.py @@ -0,0 +1 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license diff --git a/downloads/ultralytics-main/ultralytics/models/utils/loss.py b/downloads/ultralytics-main/ultralytics/models/utils/loss.py new file mode 100644 index 000000000..db6fd6315 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/utils/loss.py @@ -0,0 +1,295 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import torch +import torch.nn as nn +import torch.nn.functional as F + +from ultralytics.utils.loss import FocalLoss, VarifocalLoss +from ultralytics.utils.metrics import bbox_iou + +from .ops import HungarianMatcher + + +class DETRLoss(nn.Module): + + def __init__(self, + nc=80, + loss_gain=None, + aux_loss=True, + use_fl=True, + use_vfl=False, + use_uni_match=False, + uni_match_ind=0): + """ + DETR loss function. + + Args: + nc (int): The number of classes. + loss_gain (dict): The coefficient of loss. + aux_loss (bool): If 'aux_loss = True', loss at each decoder layer are to be used. + use_vfl (bool): Use VarifocalLoss or not. + use_uni_match (bool): Whether to use a fixed layer to assign labels for auxiliary branch. + uni_match_ind (int): The fixed indices of a layer. + """ + super().__init__() + + if loss_gain is None: + loss_gain = {'class': 1, 'bbox': 5, 'giou': 2, 'no_object': 0.1, 'mask': 1, 'dice': 1} + self.nc = nc + self.matcher = HungarianMatcher(cost_gain={'class': 2, 'bbox': 5, 'giou': 2}) + self.loss_gain = loss_gain + self.aux_loss = aux_loss + self.fl = FocalLoss() if use_fl else None + self.vfl = VarifocalLoss() if use_vfl else None + + self.use_uni_match = use_uni_match + self.uni_match_ind = uni_match_ind + self.device = None + + def _get_loss_class(self, pred_scores, targets, gt_scores, num_gts, postfix=''): + # logits: [b, query, num_classes], gt_class: list[[n, 1]] + name_class = f'loss_class{postfix}' + bs, nq = pred_scores.shape[:2] + # one_hot = F.one_hot(targets, self.nc + 1)[..., :-1] # (bs, num_queries, num_classes) + one_hot = torch.zeros((bs, nq, self.nc + 1), dtype=torch.int64, device=targets.device) + one_hot.scatter_(2, targets.unsqueeze(-1), 1) + one_hot = one_hot[..., :-1] + gt_scores = gt_scores.view(bs, nq, 1) * one_hot + + if self.fl: + if num_gts and self.vfl: + loss_cls = self.vfl(pred_scores, gt_scores, one_hot) + else: + loss_cls = self.fl(pred_scores, one_hot.float()) + loss_cls /= max(num_gts, 1) / nq + else: + loss_cls = nn.BCEWithLogitsLoss(reduction='none')(pred_scores, gt_scores).mean(1).sum() # YOLO CLS loss + + return {name_class: loss_cls.squeeze() * self.loss_gain['class']} + + def _get_loss_bbox(self, pred_bboxes, gt_bboxes, postfix=''): + # boxes: [b, query, 4], gt_bbox: list[[n, 4]] + name_bbox = f'loss_bbox{postfix}' + name_giou = f'loss_giou{postfix}' + + loss = {} + if len(gt_bboxes) == 0: + loss[name_bbox] = torch.tensor(0., device=self.device) + loss[name_giou] = torch.tensor(0., device=self.device) + return loss + + loss[name_bbox] = self.loss_gain['bbox'] * F.l1_loss(pred_bboxes, gt_bboxes, reduction='sum') / len(gt_bboxes) + loss[name_giou] = 1.0 - bbox_iou(pred_bboxes, gt_bboxes, xywh=True, GIoU=True) + loss[name_giou] = loss[name_giou].sum() / len(gt_bboxes) + loss[name_giou] = self.loss_gain['giou'] * loss[name_giou] + loss = {k: v.squeeze() for k, v in loss.items()} + return loss + + def _get_loss_mask(self, masks, gt_mask, match_indices, postfix=''): + # masks: [b, query, h, w], gt_mask: list[[n, H, W]] + name_mask = f'loss_mask{postfix}' + name_dice = f'loss_dice{postfix}' + + loss = {} + if sum(len(a) for a in gt_mask) == 0: + loss[name_mask] = torch.tensor(0., device=self.device) + loss[name_dice] = torch.tensor(0., device=self.device) + return loss + + num_gts = len(gt_mask) + src_masks, target_masks = self._get_assigned_bboxes(masks, gt_mask, match_indices) + src_masks = F.interpolate(src_masks.unsqueeze(0), size=target_masks.shape[-2:], mode='bilinear')[0] + # TODO: torch does not have `sigmoid_focal_loss`, but it's not urgent since we don't use mask branch for now. + loss[name_mask] = self.loss_gain['mask'] * F.sigmoid_focal_loss(src_masks, target_masks, + torch.tensor([num_gts], dtype=torch.float32)) + loss[name_dice] = self.loss_gain['dice'] * self._dice_loss(src_masks, target_masks, num_gts) + return loss + + def _dice_loss(self, inputs, targets, num_gts): + inputs = F.sigmoid(inputs) + inputs = inputs.flatten(1) + targets = targets.flatten(1) + numerator = 2 * (inputs * targets).sum(1) + denominator = inputs.sum(-1) + targets.sum(-1) + loss = 1 - (numerator + 1) / (denominator + 1) + return loss.sum() / num_gts + + def _get_loss_aux(self, + pred_bboxes, + pred_scores, + gt_bboxes, + gt_cls, + gt_groups, + match_indices=None, + postfix='', + masks=None, + gt_mask=None): + """Get auxiliary losses""" + # NOTE: loss class, bbox, giou, mask, dice + loss = torch.zeros(5 if masks is not None else 3, device=pred_bboxes.device) + if match_indices is None and self.use_uni_match: + match_indices = self.matcher(pred_bboxes[self.uni_match_ind], + pred_scores[self.uni_match_ind], + gt_bboxes, + gt_cls, + gt_groups, + masks=masks[self.uni_match_ind] if masks is not None else None, + gt_mask=gt_mask) + for i, (aux_bboxes, aux_scores) in enumerate(zip(pred_bboxes, pred_scores)): + aux_masks = masks[i] if masks is not None else None + loss_ = self._get_loss(aux_bboxes, + aux_scores, + gt_bboxes, + gt_cls, + gt_groups, + masks=aux_masks, + gt_mask=gt_mask, + postfix=postfix, + match_indices=match_indices) + loss[0] += loss_[f'loss_class{postfix}'] + loss[1] += loss_[f'loss_bbox{postfix}'] + loss[2] += loss_[f'loss_giou{postfix}'] + # if masks is not None and gt_mask is not None: + # loss_ = self._get_loss_mask(aux_masks, gt_mask, match_indices, postfix) + # loss[3] += loss_[f'loss_mask{postfix}'] + # loss[4] += loss_[f'loss_dice{postfix}'] + + loss = { + f'loss_class_aux{postfix}': loss[0], + f'loss_bbox_aux{postfix}': loss[1], + f'loss_giou_aux{postfix}': loss[2]} + # if masks is not None and gt_mask is not None: + # loss[f'loss_mask_aux{postfix}'] = loss[3] + # loss[f'loss_dice_aux{postfix}'] = loss[4] + return loss + + def _get_index(self, match_indices): + batch_idx = torch.cat([torch.full_like(src, i) for i, (src, _) in enumerate(match_indices)]) + src_idx = torch.cat([src for (src, _) in match_indices]) + dst_idx = torch.cat([dst for (_, dst) in match_indices]) + return (batch_idx, src_idx), dst_idx + + def _get_assigned_bboxes(self, pred_bboxes, gt_bboxes, match_indices): + pred_assigned = torch.cat([ + t[I] if len(I) > 0 else torch.zeros(0, t.shape[-1], device=self.device) + for t, (I, _) in zip(pred_bboxes, match_indices)]) + gt_assigned = torch.cat([ + t[J] if len(J) > 0 else torch.zeros(0, t.shape[-1], device=self.device) + for t, (_, J) in zip(gt_bboxes, match_indices)]) + return pred_assigned, gt_assigned + + def _get_loss(self, + pred_bboxes, + pred_scores, + gt_bboxes, + gt_cls, + gt_groups, + masks=None, + gt_mask=None, + postfix='', + match_indices=None): + """Get losses""" + if match_indices is None: + match_indices = self.matcher(pred_bboxes, + pred_scores, + gt_bboxes, + gt_cls, + gt_groups, + masks=masks, + gt_mask=gt_mask) + + idx, gt_idx = self._get_index(match_indices) + pred_bboxes, gt_bboxes = pred_bboxes[idx], gt_bboxes[gt_idx] + + bs, nq = pred_scores.shape[:2] + targets = torch.full((bs, nq), self.nc, device=pred_scores.device, dtype=gt_cls.dtype) + targets[idx] = gt_cls[gt_idx] + + gt_scores = torch.zeros([bs, nq], device=pred_scores.device) + if len(gt_bboxes): + gt_scores[idx] = bbox_iou(pred_bboxes.detach(), gt_bboxes, xywh=True).squeeze(-1) + + loss = {} + loss.update(self._get_loss_class(pred_scores, targets, gt_scores, len(gt_bboxes), postfix)) + loss.update(self._get_loss_bbox(pred_bboxes, gt_bboxes, postfix)) + # if masks is not None and gt_mask is not None: + # loss.update(self._get_loss_mask(masks, gt_mask, match_indices, postfix)) + return loss + + def forward(self, pred_bboxes, pred_scores, batch, postfix='', **kwargs): + """ + Args: + pred_bboxes (torch.Tensor): [l, b, query, 4] + pred_scores (torch.Tensor): [l, b, query, num_classes] + batch (dict): A dict includes: + gt_cls (torch.Tensor) with shape [num_gts, ], + gt_bboxes (torch.Tensor): [num_gts, 4], + gt_groups (List(int)): a list of batch size length includes the number of gts of each image. + postfix (str): postfix of loss name. + """ + self.device = pred_bboxes.device + match_indices = kwargs.get('match_indices', None) + gt_cls, gt_bboxes, gt_groups = batch['cls'], batch['bboxes'], batch['gt_groups'] + + total_loss = self._get_loss(pred_bboxes[-1], + pred_scores[-1], + gt_bboxes, + gt_cls, + gt_groups, + postfix=postfix, + match_indices=match_indices) + + if self.aux_loss: + total_loss.update( + self._get_loss_aux(pred_bboxes[:-1], pred_scores[:-1], gt_bboxes, gt_cls, gt_groups, match_indices, + postfix)) + + return total_loss + + +class RTDETRDetectionLoss(DETRLoss): + + def forward(self, preds, batch, dn_bboxes=None, dn_scores=None, dn_meta=None): + pred_bboxes, pred_scores = preds + total_loss = super().forward(pred_bboxes, pred_scores, batch) + + if dn_meta is not None: + dn_pos_idx, dn_num_group = dn_meta['dn_pos_idx'], dn_meta['dn_num_group'] + assert len(batch['gt_groups']) == len(dn_pos_idx) + + # denoising match indices + match_indices = self.get_dn_match_indices(dn_pos_idx, dn_num_group, batch['gt_groups']) + + # compute denoising training loss + dn_loss = super().forward(dn_bboxes, dn_scores, batch, postfix='_dn', match_indices=match_indices) + total_loss.update(dn_loss) + else: + total_loss.update({f'{k}_dn': torch.tensor(0., device=self.device) for k in total_loss.keys()}) + + return total_loss + + @staticmethod + def get_dn_match_indices(dn_pos_idx, dn_num_group, gt_groups): + """Get the match indices for denoising. + + Args: + dn_pos_idx (List[torch.Tensor]): A list includes positive indices of denoising. + dn_num_group (int): The number of groups of denoising. + gt_groups (List(int)): a list of batch size length includes the number of gts of each image. + + Returns: + dn_match_indices (List(tuple)): Matched indices. + + """ + dn_match_indices = [] + idx_groups = torch.as_tensor([0, *gt_groups[:-1]]).cumsum_(0) + for i, num_gt in enumerate(gt_groups): + if num_gt > 0: + gt_idx = torch.arange(end=num_gt, dtype=torch.long) + idx_groups[i] + gt_idx = gt_idx.repeat(dn_num_group) + assert len(dn_pos_idx[i]) == len(gt_idx), 'Expected the same length, ' + f'but got {len(dn_pos_idx[i])} and {len(gt_idx)} respectively.' + dn_match_indices.append((dn_pos_idx[i], gt_idx)) + else: + dn_match_indices.append((torch.zeros([0], dtype=torch.long), torch.zeros([0], dtype=torch.long))) + return dn_match_indices diff --git a/downloads/ultralytics-main/ultralytics/models/utils/ops.py b/downloads/ultralytics-main/ultralytics/models/utils/ops.py new file mode 100644 index 000000000..e7f829b61 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/utils/ops.py @@ -0,0 +1,260 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import torch +import torch.nn as nn +import torch.nn.functional as F +from scipy.optimize import linear_sum_assignment + +from ultralytics.utils.metrics import bbox_iou +from ultralytics.utils.ops import xywh2xyxy, xyxy2xywh + + +class HungarianMatcher(nn.Module): + """ + A module implementing the HungarianMatcher, which is a differentiable module to solve the assignment problem in + an end-to-end fashion. + + HungarianMatcher performs optimal assignment over predicted and ground truth bounding boxes using a cost function + that considers classification scores, bounding box coordinates, and optionally, mask predictions. + + Attributes: + cost_gain (dict): Dictionary of cost coefficients for different components: 'class', 'bbox', 'giou', 'mask', and 'dice'. + use_fl (bool): Indicates whether to use Focal Loss for the classification cost calculation. + with_mask (bool): Indicates whether the model makes mask predictions. + num_sample_points (int): The number of sample points used in mask cost calculation. + alpha (float): The alpha factor in Focal Loss calculation. + gamma (float): The gamma factor in Focal Loss calculation. + + Methods: + forward(pred_bboxes, pred_scores, gt_bboxes, gt_cls, gt_groups, masks=None, gt_mask=None): Computes the assignment + between predictions and ground truths for a batch. + _cost_mask(bs, num_gts, masks=None, gt_mask=None): Computes the mask cost and dice cost if masks are predicted. + """ + + def __init__(self, cost_gain=None, use_fl=True, with_mask=False, num_sample_points=12544, alpha=0.25, gamma=2.0): + super().__init__() + if cost_gain is None: + cost_gain = {'class': 1, 'bbox': 5, 'giou': 2, 'mask': 1, 'dice': 1} + self.cost_gain = cost_gain + self.use_fl = use_fl + self.with_mask = with_mask + self.num_sample_points = num_sample_points + self.alpha = alpha + self.gamma = gamma + + def forward(self, pred_bboxes, pred_scores, gt_bboxes, gt_cls, gt_groups, masks=None, gt_mask=None): + """ + Forward pass for HungarianMatcher. This function computes costs based on prediction and ground truth + (classification cost, L1 cost between boxes and GIoU cost between boxes) and finds the optimal matching + between predictions and ground truth based on these costs. + + Args: + pred_bboxes (Tensor): Predicted bounding boxes with shape [batch_size, num_queries, 4]. + pred_scores (Tensor): Predicted scores with shape [batch_size, num_queries, num_classes]. + gt_cls (torch.Tensor): Ground truth classes with shape [num_gts, ]. + gt_bboxes (torch.Tensor): Ground truth bounding boxes with shape [num_gts, 4]. + gt_groups (List[int]): List of length equal to batch size, containing the number of ground truths for + each image. + masks (Tensor, optional): Predicted masks with shape [batch_size, num_queries, height, width]. + Defaults to None. + gt_mask (List[Tensor], optional): List of ground truth masks, each with shape [num_masks, Height, Width]. + Defaults to None. + + Returns: + (List[Tuple[Tensor, Tensor]]): A list of size batch_size, each element is a tuple (index_i, index_j), where: + - index_i is the tensor of indices of the selected predictions (in order) + - index_j is the tensor of indices of the corresponding selected ground truth targets (in order) + For each batch element, it holds: + len(index_i) = len(index_j) = min(num_queries, num_target_boxes) + """ + + bs, nq, nc = pred_scores.shape + + if sum(gt_groups) == 0: + return [(torch.tensor([], dtype=torch.long), torch.tensor([], dtype=torch.long)) for _ in range(bs)] + + # We flatten to compute the cost matrices in a batch + # [batch_size * num_queries, num_classes] + pred_scores = pred_scores.detach().view(-1, nc) + pred_scores = F.sigmoid(pred_scores) if self.use_fl else F.softmax(pred_scores, dim=-1) + # [batch_size * num_queries, 4] + pred_bboxes = pred_bboxes.detach().view(-1, 4) + + # Compute the classification cost + pred_scores = pred_scores[:, gt_cls] + if self.use_fl: + neg_cost_class = (1 - self.alpha) * (pred_scores ** self.gamma) * (-(1 - pred_scores + 1e-8).log()) + pos_cost_class = self.alpha * ((1 - pred_scores) ** self.gamma) * (-(pred_scores + 1e-8).log()) + cost_class = pos_cost_class - neg_cost_class + else: + cost_class = -pred_scores + + # Compute the L1 cost between boxes + cost_bbox = (pred_bboxes.unsqueeze(1) - gt_bboxes.unsqueeze(0)).abs().sum(-1) # (bs*num_queries, num_gt) + + # Compute the GIoU cost between boxes, (bs*num_queries, num_gt) + cost_giou = 1.0 - bbox_iou(pred_bboxes.unsqueeze(1), gt_bboxes.unsqueeze(0), xywh=True, GIoU=True).squeeze(-1) + + # Final cost matrix + C = self.cost_gain['class'] * cost_class + \ + self.cost_gain['bbox'] * cost_bbox + \ + self.cost_gain['giou'] * cost_giou + # Compute the mask cost and dice cost + if self.with_mask: + C += self._cost_mask(bs, gt_groups, masks, gt_mask) + + C = C.view(bs, nq, -1).cpu() + indices = [linear_sum_assignment(c[i]) for i, c in enumerate(C.split(gt_groups, -1))] + gt_groups = torch.as_tensor([0, *gt_groups[:-1]]).cumsum_(0) + # (idx for queries, idx for gt) + return [(torch.tensor(i, dtype=torch.long), torch.tensor(j, dtype=torch.long) + gt_groups[k]) + for k, (i, j) in enumerate(indices)] + + def _cost_mask(self, bs, num_gts, masks=None, gt_mask=None): + assert masks is not None and gt_mask is not None, 'Make sure the input has `mask` and `gt_mask`' + # all masks share the same set of points for efficient matching + sample_points = torch.rand([bs, 1, self.num_sample_points, 2]) + sample_points = 2.0 * sample_points - 1.0 + + out_mask = F.grid_sample(masks.detach(), sample_points, align_corners=False).squeeze(-2) + out_mask = out_mask.flatten(0, 1) + + tgt_mask = torch.cat(gt_mask).unsqueeze(1) + sample_points = torch.cat([a.repeat(b, 1, 1, 1) for a, b in zip(sample_points, num_gts) if b > 0]) + tgt_mask = F.grid_sample(tgt_mask, sample_points, align_corners=False).squeeze([1, 2]) + + with torch.cuda.amp.autocast(False): + # binary cross entropy cost + pos_cost_mask = F.binary_cross_entropy_with_logits(out_mask, torch.ones_like(out_mask), reduction='none') + neg_cost_mask = F.binary_cross_entropy_with_logits(out_mask, torch.zeros_like(out_mask), reduction='none') + cost_mask = torch.matmul(pos_cost_mask, tgt_mask.T) + torch.matmul(neg_cost_mask, 1 - tgt_mask.T) + cost_mask /= self.num_sample_points + + # dice cost + out_mask = F.sigmoid(out_mask) + numerator = 2 * torch.matmul(out_mask, tgt_mask.T) + denominator = out_mask.sum(-1, keepdim=True) + tgt_mask.sum(-1).unsqueeze(0) + cost_dice = 1 - (numerator + 1) / (denominator + 1) + + C = self.cost_gain['mask'] * cost_mask + self.cost_gain['dice'] * cost_dice + return C + + +def get_cdn_group(batch, + num_classes, + num_queries, + class_embed, + num_dn=100, + cls_noise_ratio=0.5, + box_noise_scale=1.0, + training=False): + """ + Get contrastive denoising training group. This function creates a contrastive denoising training group with + positive and negative samples from the ground truths (gt). It applies noise to the class labels and bounding + box coordinates, and returns the modified labels, bounding boxes, attention mask and meta information. + + Args: + batch (dict): A dict that includes 'gt_cls' (torch.Tensor with shape [num_gts, ]), 'gt_bboxes' + (torch.Tensor with shape [num_gts, 4]), 'gt_groups' (List(int)) which is a list of batch size length + indicating the number of gts of each image. + num_classes (int): Number of classes. + num_queries (int): Number of queries. + class_embed (torch.Tensor): Embedding weights to map class labels to embedding space. + num_dn (int, optional): Number of denoising. Defaults to 100. + cls_noise_ratio (float, optional): Noise ratio for class labels. Defaults to 0.5. + box_noise_scale (float, optional): Noise scale for bounding box coordinates. Defaults to 1.0. + training (bool, optional): If it's in training mode. Defaults to False. + + Returns: + (Tuple[Optional[Tensor], Optional[Tensor], Optional[Tensor], Optional[Dict]]): The modified class embeddings, + bounding boxes, attention mask and meta information for denoising. If not in training mode or 'num_dn' + is less than or equal to 0, the function returns None for all elements in the tuple. + """ + + if (not training) or num_dn <= 0: + return None, None, None, None + gt_groups = batch['gt_groups'] + total_num = sum(gt_groups) + max_nums = max(gt_groups) + if max_nums == 0: + return None, None, None, None + + num_group = num_dn // max_nums + num_group = 1 if num_group == 0 else num_group + # pad gt to max_num of a batch + bs = len(gt_groups) + gt_cls = batch['cls'] # (bs*num, ) + gt_bbox = batch['bboxes'] # bs*num, 4 + b_idx = batch['batch_idx'] + + # each group has positive and negative queries. + dn_cls = gt_cls.repeat(2 * num_group) # (2*num_group*bs*num, ) + dn_bbox = gt_bbox.repeat(2 * num_group, 1) # 2*num_group*bs*num, 4 + dn_b_idx = b_idx.repeat(2 * num_group).view(-1) # (2*num_group*bs*num, ) + + # positive and negative mask + # (bs*num*num_group, ), the second total_num*num_group part as negative samples + neg_idx = torch.arange(total_num * num_group, dtype=torch.long, device=gt_bbox.device) + num_group * total_num + + if cls_noise_ratio > 0: + # half of bbox prob + mask = torch.rand(dn_cls.shape) < (cls_noise_ratio * 0.5) + idx = torch.nonzero(mask).squeeze(-1) + # randomly put a new one here + new_label = torch.randint_like(idx, 0, num_classes, dtype=dn_cls.dtype, device=dn_cls.device) + dn_cls[idx] = new_label + + if box_noise_scale > 0: + known_bbox = xywh2xyxy(dn_bbox) + + diff = (dn_bbox[..., 2:] * 0.5).repeat(1, 2) * box_noise_scale # 2*num_group*bs*num, 4 + + rand_sign = torch.randint_like(dn_bbox, 0, 2) * 2.0 - 1.0 + rand_part = torch.rand_like(dn_bbox) + rand_part[neg_idx] += 1.0 + rand_part *= rand_sign + known_bbox += rand_part * diff + known_bbox.clip_(min=0.0, max=1.0) + dn_bbox = xyxy2xywh(known_bbox) + dn_bbox = inverse_sigmoid(dn_bbox) + + # total denoising queries + num_dn = int(max_nums * 2 * num_group) + # class_embed = torch.cat([class_embed, torch.zeros([1, class_embed.shape[-1]], device=class_embed.device)]) + dn_cls_embed = class_embed[dn_cls] # bs*num * 2 * num_group, 256 + padding_cls = torch.zeros(bs, num_dn, dn_cls_embed.shape[-1], device=gt_cls.device) + padding_bbox = torch.zeros(bs, num_dn, 4, device=gt_bbox.device) + + map_indices = torch.cat([torch.tensor(range(num), dtype=torch.long) for num in gt_groups]) + pos_idx = torch.stack([map_indices + max_nums * i for i in range(num_group)], dim=0) + + map_indices = torch.cat([map_indices + max_nums * i for i in range(2 * num_group)]) + padding_cls[(dn_b_idx, map_indices)] = dn_cls_embed + padding_bbox[(dn_b_idx, map_indices)] = dn_bbox + + tgt_size = num_dn + num_queries + attn_mask = torch.zeros([tgt_size, tgt_size], dtype=torch.bool) + # match query cannot see the reconstruct + attn_mask[num_dn:, :num_dn] = True + # reconstruct cannot see each other + for i in range(num_group): + if i == 0: + attn_mask[max_nums * 2 * i:max_nums * 2 * (i + 1), max_nums * 2 * (i + 1):num_dn] = True + if i == num_group - 1: + attn_mask[max_nums * 2 * i:max_nums * 2 * (i + 1), :max_nums * i * 2] = True + else: + attn_mask[max_nums * 2 * i:max_nums * 2 * (i + 1), max_nums * 2 * (i + 1):num_dn] = True + attn_mask[max_nums * 2 * i:max_nums * 2 * (i + 1), :max_nums * 2 * i] = True + dn_meta = { + 'dn_pos_idx': [p.reshape(-1) for p in pos_idx.cpu().split(list(gt_groups), dim=1)], + 'dn_num_group': num_group, + 'dn_num_split': [num_dn, num_queries]} + + return padding_cls.to(class_embed.device), padding_bbox.to(class_embed.device), attn_mask.to( + class_embed.device), dn_meta + + +def inverse_sigmoid(x, eps=1e-6): + """Inverse sigmoid function.""" + x = x.clip(min=0., max=1.) + return torch.log(x / (1 - x + eps) + eps) diff --git a/downloads/ultralytics-main/ultralytics/models/yolo/__init__.py b/downloads/ultralytics-main/ultralytics/models/yolo/__init__.py new file mode 100644 index 000000000..c66e37627 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/yolo/__init__.py @@ -0,0 +1,7 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from ultralytics.models.yolo import classify, detect, pose, segment + +from .model import YOLO + +__all__ = 'classify', 'segment', 'detect', 'pose', 'YOLO' diff --git a/downloads/ultralytics-main/ultralytics/models/yolo/classify/__init__.py b/downloads/ultralytics-main/ultralytics/models/yolo/classify/__init__.py new file mode 100644 index 000000000..33d72e68e --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/yolo/classify/__init__.py @@ -0,0 +1,7 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from ultralytics.models.yolo.classify.predict import ClassificationPredictor +from ultralytics.models.yolo.classify.train import ClassificationTrainer +from ultralytics.models.yolo.classify.val import ClassificationValidator + +__all__ = 'ClassificationPredictor', 'ClassificationTrainer', 'ClassificationValidator' diff --git a/downloads/ultralytics-main/ultralytics/models/yolo/classify/predict.py b/downloads/ultralytics-main/ultralytics/models/yolo/classify/predict.py new file mode 100644 index 000000000..95b17e446 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/yolo/classify/predict.py @@ -0,0 +1,48 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import torch + +from ultralytics.engine.predictor import BasePredictor +from ultralytics.engine.results import Results +from ultralytics.utils import DEFAULT_CFG + + +class ClassificationPredictor(BasePredictor): + """ + A class extending the BasePredictor class for prediction based on a classification model. + + Notes: + - Torchvision classification models can also be passed to the 'model' argument, i.e. model='resnet18'. + + Example: + ```python + from ultralytics.utils import ASSETS + from ultralytics.models.yolo.classify import ClassificationPredictor + + args = dict(model='yolov8n-cls.pt', source=ASSETS) + predictor = ClassificationPredictor(overrides=args) + predictor.predict_cli() + ``` + """ + + def __init__(self, cfg=DEFAULT_CFG, overrides=None, _callbacks=None): + super().__init__(cfg, overrides, _callbacks) + self.args.task = 'classify' + + def preprocess(self, img): + """Converts input image to model-compatible data type.""" + if not isinstance(img, torch.Tensor): + img = torch.stack([self.transforms(im) for im in img], dim=0) + img = (img if isinstance(img, torch.Tensor) else torch.from_numpy(img)).to(self.model.device) + return img.half() if self.model.fp16 else img.float() # uint8 to fp16/32 + + def postprocess(self, preds, img, orig_imgs): + """Post-processes predictions to return Results objects.""" + results = [] + for i, pred in enumerate(preds): + orig_img = orig_imgs[i] if isinstance(orig_imgs, list) else orig_imgs + path = self.batch[0] + img_path = path[i] if isinstance(path, list) else path + results.append(Results(orig_img=orig_img, path=img_path, names=self.model.names, probs=pred)) + + return results diff --git a/downloads/ultralytics-main/ultralytics/models/yolo/classify/train.py b/downloads/ultralytics-main/ultralytics/models/yolo/classify/train.py new file mode 100644 index 000000000..b09b5201b --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/yolo/classify/train.py @@ -0,0 +1,150 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import torch +import torchvision + +from ultralytics.data import ClassificationDataset, build_dataloader +from ultralytics.engine.trainer import BaseTrainer +from ultralytics.models import yolo +from ultralytics.nn.tasks import ClassificationModel, attempt_load_one_weight +from ultralytics.utils import DEFAULT_CFG, LOGGER, RANK, colorstr +from ultralytics.utils.plotting import plot_images, plot_results +from ultralytics.utils.torch_utils import is_parallel, strip_optimizer, torch_distributed_zero_first + + +class ClassificationTrainer(BaseTrainer): + """ + A class extending the BaseTrainer class for training based on a classification model. + + Notes: + - Torchvision classification models can also be passed to the 'model' argument, i.e. model='resnet18'. + + Example: + ```python + from ultralytics.models.yolo.classify import ClassificationTrainer + + args = dict(model='yolov8n-cls.pt', data='imagenet10', epochs=3) + trainer = ClassificationTrainer(overrides=args) + trainer.train() + ``` + """ + + def __init__(self, cfg=DEFAULT_CFG, overrides=None, _callbacks=None): + """Initialize a ClassificationTrainer object with optional configuration overrides and callbacks.""" + if overrides is None: + overrides = {} + overrides['task'] = 'classify' + if overrides.get('imgsz') is None: + overrides['imgsz'] = 224 + super().__init__(cfg, overrides, _callbacks) + + def set_model_attributes(self): + """Set the YOLO model's class names from the loaded dataset.""" + self.model.names = self.data['names'] + + def get_model(self, cfg=None, weights=None, verbose=True): + """Returns a modified PyTorch model configured for training YOLO.""" + model = ClassificationModel(cfg, nc=self.data['nc'], verbose=verbose and RANK == -1) + if weights: + model.load(weights) + + for m in model.modules(): + if not self.args.pretrained and hasattr(m, 'reset_parameters'): + m.reset_parameters() + if isinstance(m, torch.nn.Dropout) and self.args.dropout: + m.p = self.args.dropout # set dropout + for p in model.parameters(): + p.requires_grad = True # for training + return model + + def setup_model(self): + """load/create/download model for any task""" + if isinstance(self.model, torch.nn.Module): # if model is loaded beforehand. No setup needed + return + + model, ckpt = str(self.model), None + # Load a YOLO model locally, from torchvision, or from Ultralytics assets + if model.endswith('.pt'): + self.model, ckpt = attempt_load_one_weight(model, device='cpu') + for p in self.model.parameters(): + p.requires_grad = True # for training + elif model.split('.')[-1] in ('yaml', 'yml'): + self.model = self.get_model(cfg=model) + elif model in torchvision.models.__dict__: + self.model = torchvision.models.__dict__[model](weights='IMAGENET1K_V1' if self.args.pretrained else None) + else: + FileNotFoundError(f'ERROR: model={model} not found locally or online. Please check model name.') + ClassificationModel.reshape_outputs(self.model, self.data['nc']) + + return ckpt + + def build_dataset(self, img_path, mode='train', batch=None): + return ClassificationDataset(root=img_path, args=self.args, augment=mode == 'train') + + def get_dataloader(self, dataset_path, batch_size=16, rank=0, mode='train'): + """Returns PyTorch DataLoader with transforms to preprocess images for inference.""" + with torch_distributed_zero_first(rank): # init dataset *.cache only once if DDP + dataset = self.build_dataset(dataset_path, mode) + + loader = build_dataloader(dataset, batch_size, self.args.workers, rank=rank) + # Attach inference transforms + if mode != 'train': + if is_parallel(self.model): + self.model.module.transforms = loader.dataset.torch_transforms + else: + self.model.transforms = loader.dataset.torch_transforms + return loader + + def preprocess_batch(self, batch): + """Preprocesses a batch of images and classes.""" + batch['img'] = batch['img'].to(self.device) + batch['cls'] = batch['cls'].to(self.device) + return batch + + def progress_string(self): + """Returns a formatted string showing training progress.""" + return ('\n' + '%11s' * (4 + len(self.loss_names))) % \ + ('Epoch', 'GPU_mem', *self.loss_names, 'Instances', 'Size') + + def get_validator(self): + """Returns an instance of ClassificationValidator for validation.""" + self.loss_names = ['loss'] + return yolo.classify.ClassificationValidator(self.test_loader, self.save_dir) + + def label_loss_items(self, loss_items=None, prefix='train'): + """ + Returns a loss dict with labelled training loss items tensor. Not needed for classification but necessary for + segmentation & detection + """ + keys = [f'{prefix}/{x}' for x in self.loss_names] + if loss_items is None: + return keys + loss_items = [round(float(loss_items), 5)] + return dict(zip(keys, loss_items)) + + def plot_metrics(self): + """Plots metrics from a CSV file.""" + plot_results(file=self.csv, classify=True, on_plot=self.on_plot) # save results.png + + def final_eval(self): + """Evaluate trained model and save validation results.""" + for f in self.last, self.best: + if f.exists(): + strip_optimizer(f) # strip optimizers + # TODO: validate best.pt after training completes + # if f is self.best: + # LOGGER.info(f'\nValidating {f}...') + # self.validator.args.save_json = True + # self.metrics = self.validator(model=f) + # self.metrics.pop('fitness', None) + # self.run_callbacks('on_fit_epoch_end') + LOGGER.info(f"Results saved to {colorstr('bold', self.save_dir)}") + + def plot_training_samples(self, batch, ni): + """Plots training samples with their annotations.""" + plot_images( + images=batch['img'], + batch_idx=torch.arange(len(batch['img'])), + cls=batch['cls'].view(-1), # warning: use .view(), not .squeeze() for Classify models + fname=self.save_dir / f'train_batch{ni}.jpg', + on_plot=self.on_plot) diff --git a/downloads/ultralytics-main/ultralytics/models/yolo/classify/val.py b/downloads/ultralytics-main/ultralytics/models/yolo/classify/val.py new file mode 100644 index 000000000..e9de4fddc --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/yolo/classify/val.py @@ -0,0 +1,109 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import torch + +from ultralytics.data import ClassificationDataset, build_dataloader +from ultralytics.engine.validator import BaseValidator +from ultralytics.utils import LOGGER +from ultralytics.utils.metrics import ClassifyMetrics, ConfusionMatrix +from ultralytics.utils.plotting import plot_images + + +class ClassificationValidator(BaseValidator): + """ + A class extending the BaseValidator class for validation based on a classification model. + + Notes: + - Torchvision classification models can also be passed to the 'model' argument, i.e. model='resnet18'. + + Example: + ```python + from ultralytics.models.yolo.classify import ClassificationValidator + + args = dict(model='yolov8n-cls.pt', data='imagenet10') + validator = ClassificationValidator(args=args) + validator() + ``` + """ + + def __init__(self, dataloader=None, save_dir=None, pbar=None, args=None, _callbacks=None): + """Initializes ClassificationValidator instance with args, dataloader, save_dir, and progress bar.""" + super().__init__(dataloader, save_dir, pbar, args, _callbacks) + self.targets = None + self.pred = None + self.args.task = 'classify' + self.metrics = ClassifyMetrics() + + def get_desc(self): + """Returns a formatted string summarizing classification metrics.""" + return ('%22s' + '%11s' * 2) % ('classes', 'top1_acc', 'top5_acc') + + def init_metrics(self, model): + """Initialize confusion matrix, class names, and top-1 and top-5 accuracy.""" + self.names = model.names + self.nc = len(model.names) + self.confusion_matrix = ConfusionMatrix(nc=self.nc, task='classify') + self.pred = [] + self.targets = [] + + def preprocess(self, batch): + """Preprocesses input batch and returns it.""" + batch['img'] = batch['img'].to(self.device, non_blocking=True) + batch['img'] = batch['img'].half() if self.args.half else batch['img'].float() + batch['cls'] = batch['cls'].to(self.device) + return batch + + def update_metrics(self, preds, batch): + """Updates running metrics with model predictions and batch targets.""" + n5 = min(len(self.model.names), 5) + self.pred.append(preds.argsort(1, descending=True)[:, :n5]) + self.targets.append(batch['cls']) + + def finalize_metrics(self, *args, **kwargs): + """Finalizes metrics of the model such as confusion_matrix and speed.""" + self.confusion_matrix.process_cls_preds(self.pred, self.targets) + if self.args.plots: + for normalize in True, False: + self.confusion_matrix.plot(save_dir=self.save_dir, + names=self.names.values(), + normalize=normalize, + on_plot=self.on_plot) + self.metrics.speed = self.speed + self.metrics.confusion_matrix = self.confusion_matrix + + def get_stats(self): + """Returns a dictionary of metrics obtained by processing targets and predictions.""" + self.metrics.process(self.targets, self.pred) + return self.metrics.results_dict + + def build_dataset(self, img_path): + return ClassificationDataset(root=img_path, args=self.args, augment=False) + + def get_dataloader(self, dataset_path, batch_size): + """Builds and returns a data loader for classification tasks with given parameters.""" + dataset = self.build_dataset(dataset_path) + return build_dataloader(dataset, batch_size, self.args.workers, rank=-1) + + def print_results(self): + """Prints evaluation metrics for YOLO object detection model.""" + pf = '%22s' + '%11.3g' * len(self.metrics.keys) # print format + LOGGER.info(pf % ('all', self.metrics.top1, self.metrics.top5)) + + def plot_val_samples(self, batch, ni): + """Plot validation image samples.""" + plot_images( + images=batch['img'], + batch_idx=torch.arange(len(batch['img'])), + cls=batch['cls'].view(-1), # warning: use .view(), not .squeeze() for Classify models + fname=self.save_dir / f'val_batch{ni}_labels.jpg', + names=self.names, + on_plot=self.on_plot) + + def plot_predictions(self, batch, preds, ni): + """Plots predicted bounding boxes on input images and saves the result.""" + plot_images(batch['img'], + batch_idx=torch.arange(len(batch['img'])), + cls=torch.argmax(preds, dim=1), + fname=self.save_dir / f'val_batch{ni}_pred.jpg', + names=self.names, + on_plot=self.on_plot) # pred diff --git a/downloads/ultralytics-main/ultralytics/models/yolo/detect/__init__.py b/downloads/ultralytics-main/ultralytics/models/yolo/detect/__init__.py new file mode 100644 index 000000000..20fc0c489 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/yolo/detect/__init__.py @@ -0,0 +1,7 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from .predict import DetectionPredictor +from .train import DetectionTrainer +from .val import DetectionValidator + +__all__ = 'DetectionPredictor', 'DetectionTrainer', 'DetectionValidator' diff --git a/downloads/ultralytics-main/ultralytics/models/yolo/detect/predict.py b/downloads/ultralytics-main/ultralytics/models/yolo/detect/predict.py new file mode 100644 index 000000000..46de75f53 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/yolo/detect/predict.py @@ -0,0 +1,42 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import torch + +from ultralytics.engine.predictor import BasePredictor +from ultralytics.engine.results import Results +from ultralytics.utils import ops + + +class DetectionPredictor(BasePredictor): + """ + A class extending the BasePredictor class for prediction based on a detection model. + + Example: + ```python + from ultralytics.utils import ASSETS + from ultralytics.models.yolo.detect import DetectionPredictor + + args = dict(model='yolov8n.pt', source=ASSETS) + predictor = DetectionPredictor(overrides=args) + predictor.predict_cli() + ``` + """ + + def postprocess(self, preds, img, orig_imgs): + """Post-processes predictions and returns a list of Results objects.""" + preds = ops.non_max_suppression(preds, + self.args.conf, + self.args.iou, + agnostic=self.args.agnostic_nms, + max_det=self.args.max_det, + classes=self.args.classes) + + results = [] + for i, pred in enumerate(preds): + orig_img = orig_imgs[i] if isinstance(orig_imgs, list) else orig_imgs + if not isinstance(orig_imgs, torch.Tensor): + pred[:, :4] = ops.scale_boxes(img.shape[2:], pred[:, :4], orig_img.shape) + path = self.batch[0] + img_path = path[i] if isinstance(path, list) else path + results.append(Results(orig_img=orig_img, path=img_path, names=self.model.names, boxes=pred)) + return results diff --git a/downloads/ultralytics-main/ultralytics/models/yolo/detect/train.py b/downloads/ultralytics-main/ultralytics/models/yolo/detect/train.py new file mode 100644 index 000000000..56d9243cf --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/yolo/detect/train.py @@ -0,0 +1,116 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from copy import copy + +import numpy as np + +from ultralytics.data import build_dataloader, build_yolo_dataset +from ultralytics.engine.trainer import BaseTrainer +from ultralytics.models import yolo +from ultralytics.nn.tasks import DetectionModel +from ultralytics.utils import LOGGER, RANK +from ultralytics.utils.plotting import plot_images, plot_labels, plot_results +from ultralytics.utils.torch_utils import de_parallel, torch_distributed_zero_first + + +class DetectionTrainer(BaseTrainer): + """ + A class extending the BaseTrainer class for training based on a detection model. + + Example: + ```python + from ultralytics.models.yolo.detect import DetectionTrainer + + args = dict(model='yolov8n.pt', data='coco8.yaml', epochs=3) + trainer = DetectionTrainer(overrides=args) + trainer.train() + ``` + """ + + def build_dataset(self, img_path, mode='train', batch=None): + """ + Build YOLO Dataset. + + Args: + img_path (str): Path to the folder containing images. + mode (str): `train` mode or `val` mode, users are able to customize different augmentations for each mode. + batch (int, optional): Size of batches, this is for `rect`. Defaults to None. + """ + gs = max(int(de_parallel(self.model).stride.max() if self.model else 0), 32) + return build_yolo_dataset(self.args, img_path, batch, self.data, mode=mode, rect=mode == 'val', stride=gs) + + def get_dataloader(self, dataset_path, batch_size=16, rank=0, mode='train'): + """Construct and return dataloader.""" + assert mode in ['train', 'val'] + with torch_distributed_zero_first(rank): # init dataset *.cache only once if DDP + dataset = self.build_dataset(dataset_path, mode, batch_size) + shuffle = mode == 'train' + if getattr(dataset, 'rect', False) and shuffle: + LOGGER.warning("WARNING ⚠️ 'rect=True' is incompatible with DataLoader shuffle, setting shuffle=False") + shuffle = False + workers = self.args.workers if mode == 'train' else self.args.workers * 2 + return build_dataloader(dataset, batch_size, workers, shuffle, rank) # return dataloader + + def preprocess_batch(self, batch): + """Preprocesses a batch of images by scaling and converting to float.""" + batch['img'] = batch['img'].to(self.device, non_blocking=True).float() / 255 + return batch + + def set_model_attributes(self): + """nl = de_parallel(self.model).model[-1].nl # number of detection layers (to scale hyps).""" + # self.args.box *= 3 / nl # scale to layers + # self.args.cls *= self.data["nc"] / 80 * 3 / nl # scale to classes and layers + # self.args.cls *= (self.args.imgsz / 640) ** 2 * 3 / nl # scale to image size and layers + self.model.nc = self.data['nc'] # attach number of classes to model + self.model.names = self.data['names'] # attach class names to model + self.model.args = self.args # attach hyperparameters to model + # TODO: self.model.class_weights = labels_to_class_weights(dataset.labels, nc).to(device) * nc + + def get_model(self, cfg=None, weights=None, verbose=True): + """Return a YOLO detection model.""" + model = DetectionModel(cfg, nc=self.data['nc'], verbose=verbose and RANK == -1) + if weights: + model.load(weights) + return model + + def get_validator(self): + """Returns a DetectionValidator for YOLO model validation.""" + self.loss_names = 'box_loss', 'cls_loss', 'dfl_loss' + return yolo.detect.DetectionValidator(self.test_loader, save_dir=self.save_dir, args=copy(self.args)) + + def label_loss_items(self, loss_items=None, prefix='train'): + """ + Returns a loss dict with labelled training loss items tensor. Not needed for classification but necessary for + segmentation & detection + """ + keys = [f'{prefix}/{x}' for x in self.loss_names] + if loss_items is not None: + loss_items = [round(float(x), 5) for x in loss_items] # convert tensors to 5 decimal place floats + return dict(zip(keys, loss_items)) + else: + return keys + + def progress_string(self): + """Returns a formatted string of training progress with epoch, GPU memory, loss, instances and size.""" + return ('\n' + '%11s' * + (4 + len(self.loss_names))) % ('Epoch', 'GPU_mem', *self.loss_names, 'Instances', 'Size') + + def plot_training_samples(self, batch, ni): + """Plots training samples with their annotations.""" + plot_images(images=batch['img'], + batch_idx=batch['batch_idx'], + cls=batch['cls'].squeeze(-1), + bboxes=batch['bboxes'], + paths=batch['im_file'], + fname=self.save_dir / f'train_batch{ni}.jpg', + on_plot=self.on_plot) + + def plot_metrics(self): + """Plots metrics from a CSV file.""" + plot_results(file=self.csv, on_plot=self.on_plot) # save results.png + + def plot_training_labels(self): + """Create a labeled training plot of the YOLO model.""" + boxes = np.concatenate([lb['bboxes'] for lb in self.train_loader.dataset.labels], 0) + cls = np.concatenate([lb['cls'] for lb in self.train_loader.dataset.labels], 0) + plot_labels(boxes, cls.squeeze(), names=self.data['names'], save_dir=self.save_dir, on_plot=self.on_plot) diff --git a/downloads/ultralytics-main/ultralytics/models/yolo/detect/val.py b/downloads/ultralytics-main/ultralytics/models/yolo/detect/val.py new file mode 100644 index 000000000..d9f84ae8a --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/yolo/detect/val.py @@ -0,0 +1,268 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import os +from pathlib import Path + +import numpy as np +import torch + +from ultralytics.data import build_dataloader, build_yolo_dataset, converter +from ultralytics.engine.validator import BaseValidator +from ultralytics.utils import LOGGER, ops +from ultralytics.utils.checks import check_requirements +from ultralytics.utils.metrics import ConfusionMatrix, DetMetrics, box_iou +from ultralytics.utils.plotting import output_to_target, plot_images +from ultralytics.utils.torch_utils import de_parallel + + +class DetectionValidator(BaseValidator): + """ + A class extending the BaseValidator class for validation based on a detection model. + + Example: + ```python + from ultralytics.models.yolo.detect import DetectionValidator + + args = dict(model='yolov8n.pt', data='coco8.yaml') + validator = DetectionValidator(args=args) + validator() + ``` + """ + + def __init__(self, dataloader=None, save_dir=None, pbar=None, args=None, _callbacks=None): + """Initialize detection model with necessary variables and settings.""" + super().__init__(dataloader, save_dir, pbar, args, _callbacks) + self.nt_per_class = None + self.is_coco = False + self.class_map = None + self.args.task = 'detect' + self.metrics = DetMetrics(save_dir=self.save_dir, on_plot=self.on_plot) + self.iouv = torch.linspace(0.5, 0.95, 10) # iou vector for mAP@0.5:0.95 + self.niou = self.iouv.numel() + self.lb = [] # for autolabelling + + def preprocess(self, batch): + """Preprocesses batch of images for YOLO training.""" + batch['img'] = batch['img'].to(self.device, non_blocking=True) + batch['img'] = (batch['img'].half() if self.args.half else batch['img'].float()) / 255 + for k in ['batch_idx', 'cls', 'bboxes']: + batch[k] = batch[k].to(self.device) + + if self.args.save_hybrid: + height, width = batch['img'].shape[2:] + nb = len(batch['img']) + bboxes = batch['bboxes'] * torch.tensor((width, height, width, height), device=self.device) + self.lb = [ + torch.cat([batch['cls'][batch['batch_idx'] == i], bboxes[batch['batch_idx'] == i]], dim=-1) + for i in range(nb)] if self.args.save_hybrid else [] # for autolabelling + + return batch + + def init_metrics(self, model): + """Initialize evaluation metrics for YOLO.""" + val = self.data.get(self.args.split, '') # validation path + self.is_coco = isinstance(val, str) and 'coco' in val and val.endswith(f'{os.sep}val2017.txt') # is COCO + self.class_map = converter.coco80_to_coco91_class() if self.is_coco else list(range(1000)) + self.args.save_json |= self.is_coco and not self.training # run on final val if training COCO + self.names = model.names + self.nc = len(model.names) + self.metrics.names = self.names + self.metrics.plot = self.args.plots + self.confusion_matrix = ConfusionMatrix(nc=self.nc) + self.seen = 0 + self.jdict = [] + self.stats = [] + + def get_desc(self): + """Return a formatted string summarizing class metrics of YOLO model.""" + return ('%22s' + '%11s' * 6) % ('Class', 'Images', 'Instances', 'Box(P', 'R', 'mAP50', 'mAP50-95)') + + def postprocess(self, preds): + """Apply Non-maximum suppression to prediction outputs.""" + return ops.non_max_suppression(preds, + self.args.conf, + self.args.iou, + labels=self.lb, + multi_label=True, + agnostic=self.args.single_cls, + max_det=self.args.max_det) + + def update_metrics(self, preds, batch): + """Metrics.""" + for si, pred in enumerate(preds): + idx = batch['batch_idx'] == si + cls = batch['cls'][idx] + bbox = batch['bboxes'][idx] + nl, npr = cls.shape[0], pred.shape[0] # number of labels, predictions + shape = batch['ori_shape'][si] + correct_bboxes = torch.zeros(npr, self.niou, dtype=torch.bool, device=self.device) # init + self.seen += 1 + + if npr == 0: + if nl: + self.stats.append((correct_bboxes, *torch.zeros((2, 0), device=self.device), cls.squeeze(-1))) + if self.args.plots: + self.confusion_matrix.process_batch(detections=None, labels=cls.squeeze(-1)) + continue + + # Predictions + if self.args.single_cls: + pred[:, 5] = 0 + predn = pred.clone() + ops.scale_boxes(batch['img'][si].shape[1:], predn[:, :4], shape, + ratio_pad=batch['ratio_pad'][si]) # native-space pred + + # Evaluate + if nl: + height, width = batch['img'].shape[2:] + tbox = ops.xywh2xyxy(bbox) * torch.tensor( + (width, height, width, height), device=self.device) # target boxes + ops.scale_boxes(batch['img'][si].shape[1:], tbox, shape, + ratio_pad=batch['ratio_pad'][si]) # native-space labels + labelsn = torch.cat((cls, tbox), 1) # native-space labels + correct_bboxes = self._process_batch(predn, labelsn) + # TODO: maybe remove these `self.` arguments as they already are member variable + if self.args.plots: + self.confusion_matrix.process_batch(predn, labelsn) + self.stats.append((correct_bboxes, pred[:, 4], pred[:, 5], cls.squeeze(-1))) # (conf, pcls, tcls) + + # Save + if self.args.save_json: + self.pred_to_json(predn, batch['im_file'][si]) + if self.args.save_txt: + file = self.save_dir / 'labels' / f'{Path(batch["im_file"][si]).stem}.txt' + self.save_one_txt(predn, self.args.save_conf, shape, file) + + def finalize_metrics(self, *args, **kwargs): + """Set final values for metrics speed and confusion matrix.""" + self.metrics.speed = self.speed + self.metrics.confusion_matrix = self.confusion_matrix + + def get_stats(self): + """Returns metrics statistics and results dictionary.""" + stats = [torch.cat(x, 0).cpu().numpy() for x in zip(*self.stats)] # to numpy + if len(stats) and stats[0].any(): + self.metrics.process(*stats) + self.nt_per_class = np.bincount(stats[-1].astype(int), minlength=self.nc) # number of targets per class + return self.metrics.results_dict + + def print_results(self): + """Prints training/validation set metrics per class.""" + pf = '%22s' + '%11i' * 2 + '%11.3g' * len(self.metrics.keys) # print format + LOGGER.info(pf % ('all', self.seen, self.nt_per_class.sum(), *self.metrics.mean_results())) + if self.nt_per_class.sum() == 0: + LOGGER.warning( + f'WARNING ⚠️ no labels found in {self.args.task} set, can not compute metrics without labels') + + # Print results per class + if self.args.verbose and not self.training and self.nc > 1 and len(self.stats): + for i, c in enumerate(self.metrics.ap_class_index): + LOGGER.info(pf % (self.names[c], self.seen, self.nt_per_class[c], *self.metrics.class_result(i))) + + if self.args.plots: + for normalize in True, False: + self.confusion_matrix.plot(save_dir=self.save_dir, + names=self.names.values(), + normalize=normalize, + on_plot=self.on_plot) + + def _process_batch(self, detections, labels): + """ + Return correct prediction matrix. + + Args: + detections (torch.Tensor): Tensor of shape [N, 6] representing detections. + Each detection is of the format: x1, y1, x2, y2, conf, class. + labels (torch.Tensor): Tensor of shape [M, 5] representing labels. + Each label is of the format: class, x1, y1, x2, y2. + + Returns: + (torch.Tensor): Correct prediction matrix of shape [N, 10] for 10 IoU levels. + """ + iou = box_iou(labels[:, 1:], detections[:, :4]) + return self.match_predictions(detections[:, 5], labels[:, 0], iou) + + def build_dataset(self, img_path, mode='val', batch=None): + """ + Build YOLO Dataset. + + Args: + img_path (str): Path to the folder containing images. + mode (str): `train` mode or `val` mode, users are able to customize different augmentations for each mode. + batch (int, optional): Size of batches, this is for `rect`. Defaults to None. + """ + gs = max(int(de_parallel(self.model).stride if self.model else 0), 32) + return build_yolo_dataset(self.args, img_path, batch, self.data, mode=mode, stride=gs) + + def get_dataloader(self, dataset_path, batch_size): + """Construct and return dataloader.""" + dataset = self.build_dataset(dataset_path, batch=batch_size, mode='val') + return build_dataloader(dataset, batch_size, self.args.workers, shuffle=False, rank=-1) # return dataloader + + def plot_val_samples(self, batch, ni): + """Plot validation image samples.""" + plot_images(batch['img'], + batch['batch_idx'], + batch['cls'].squeeze(-1), + batch['bboxes'], + paths=batch['im_file'], + fname=self.save_dir / f'val_batch{ni}_labels.jpg', + names=self.names, + on_plot=self.on_plot) + + def plot_predictions(self, batch, preds, ni): + """Plots predicted bounding boxes on input images and saves the result.""" + plot_images(batch['img'], + *output_to_target(preds, max_det=self.args.max_det), + paths=batch['im_file'], + fname=self.save_dir / f'val_batch{ni}_pred.jpg', + names=self.names, + on_plot=self.on_plot) # pred + + def save_one_txt(self, predn, save_conf, shape, file): + """Save YOLO detections to a txt file in normalized coordinates in a specific format.""" + gn = torch.tensor(shape)[[1, 0, 1, 0]] # normalization gain whwh + for *xyxy, conf, cls in predn.tolist(): + xywh = (ops.xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist() # normalized xywh + line = (cls, *xywh, conf) if save_conf else (cls, *xywh) # label format + with open(file, 'a') as f: + f.write(('%g ' * len(line)).rstrip() % line + '\n') + + def pred_to_json(self, predn, filename): + """Serialize YOLO predictions to COCO json format.""" + stem = Path(filename).stem + image_id = int(stem) if stem.isnumeric() else stem + box = ops.xyxy2xywh(predn[:, :4]) # xywh + box[:, :2] -= box[:, 2:] / 2 # xy center to top-left corner + for p, b in zip(predn.tolist(), box.tolist()): + self.jdict.append({ + 'image_id': image_id, + 'category_id': self.class_map[int(p[5])], + 'bbox': [round(x, 3) for x in b], + 'score': round(p[4], 5)}) + + def eval_json(self, stats): + """Evaluates YOLO output in JSON format and returns performance statistics.""" + if self.args.save_json and self.is_coco and len(self.jdict): + anno_json = self.data['path'] / 'annotations/instances_val2017.json' # annotations + pred_json = self.save_dir / 'predictions.json' # predictions + LOGGER.info(f'\nEvaluating pycocotools mAP using {pred_json} and {anno_json}...') + try: # https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/pycocoEvalDemo.ipynb + check_requirements('pycocotools>=2.0.6') + from pycocotools.coco import COCO # noqa + from pycocotools.cocoeval import COCOeval # noqa + + for x in anno_json, pred_json: + assert x.is_file(), f'{x} file not found' + anno = COCO(str(anno_json)) # init annotations api + pred = anno.loadRes(str(pred_json)) # init predictions api (must pass string, not Path) + eval = COCOeval(anno, pred, 'bbox') + if self.is_coco: + eval.params.imgIds = [int(Path(x).stem) for x in self.dataloader.dataset.im_files] # images to eval + eval.evaluate() + eval.accumulate() + eval.summarize() + stats[self.metrics.keys[-1]], stats[self.metrics.keys[-2]] = eval.stats[:2] # update mAP50-95 and mAP50 + except Exception as e: + LOGGER.warning(f'pycocotools unable to run: {e}') + return stats diff --git a/downloads/ultralytics-main/ultralytics/models/yolo/model.py b/downloads/ultralytics-main/ultralytics/models/yolo/model.py new file mode 100644 index 000000000..b85d46bdb --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/yolo/model.py @@ -0,0 +1,36 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from ultralytics.engine.model import Model +from ultralytics.models import yolo # noqa +from ultralytics.nn.tasks import ClassificationModel, DetectionModel, PoseModel, SegmentationModel + + +class YOLO(Model): + """ + YOLO (You Only Look Once) object detection model. + """ + + @property + def task_map(self): + """Map head to model, trainer, validator, and predictor classes""" + return { + 'classify': { + 'model': ClassificationModel, + 'trainer': yolo.classify.ClassificationTrainer, + 'validator': yolo.classify.ClassificationValidator, + 'predictor': yolo.classify.ClassificationPredictor, }, + 'detect': { + 'model': DetectionModel, + 'trainer': yolo.detect.DetectionTrainer, + 'validator': yolo.detect.DetectionValidator, + 'predictor': yolo.detect.DetectionPredictor, }, + 'segment': { + 'model': SegmentationModel, + 'trainer': yolo.segment.SegmentationTrainer, + 'validator': yolo.segment.SegmentationValidator, + 'predictor': yolo.segment.SegmentationPredictor, }, + 'pose': { + 'model': PoseModel, + 'trainer': yolo.pose.PoseTrainer, + 'validator': yolo.pose.PoseValidator, + 'predictor': yolo.pose.PosePredictor, }, } diff --git a/downloads/ultralytics-main/ultralytics/models/yolo/pose/__init__.py b/downloads/ultralytics-main/ultralytics/models/yolo/pose/__init__.py new file mode 100644 index 000000000..2a79f0f34 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/yolo/pose/__init__.py @@ -0,0 +1,7 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from .predict import PosePredictor +from .train import PoseTrainer +from .val import PoseValidator + +__all__ = 'PoseTrainer', 'PoseValidator', 'PosePredictor' diff --git a/downloads/ultralytics-main/ultralytics/models/yolo/pose/predict.py b/downloads/ultralytics-main/ultralytics/models/yolo/pose/predict.py new file mode 100644 index 000000000..1a410a17e --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/yolo/pose/predict.py @@ -0,0 +1,55 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from ultralytics.engine.results import Results +from ultralytics.models.yolo.detect.predict import DetectionPredictor +from ultralytics.utils import DEFAULT_CFG, LOGGER, ops + + +class PosePredictor(DetectionPredictor): + """ + A class extending the DetectionPredictor class for prediction based on a pose model. + + Example: + ```python + from ultralytics.utils import ASSETS + from ultralytics.models.yolo.pose import PosePredictor + + args = dict(model='yolov8n-pose.pt', source=ASSETS) + predictor = PosePredictor(overrides=args) + predictor.predict_cli() + ``` + """ + + def __init__(self, cfg=DEFAULT_CFG, overrides=None, _callbacks=None): + super().__init__(cfg, overrides, _callbacks) + self.args.task = 'pose' + if isinstance(self.args.device, str) and self.args.device.lower() == 'mps': + LOGGER.warning("WARNING ⚠️ Apple MPS known Pose bug. Recommend 'device=cpu' for Pose models. " + 'See https://github.com/ultralytics/ultralytics/issues/4031.') + + def postprocess(self, preds, img, orig_imgs): + """Return detection results for a given input image or list of images.""" + preds = ops.non_max_suppression(preds, + self.args.conf, + self.args.iou, + agnostic=self.args.agnostic_nms, + max_det=self.args.max_det, + classes=self.args.classes, + nc=len(self.model.names)) + + results = [] + for i, pred in enumerate(preds): + orig_img = orig_imgs[i] if isinstance(orig_imgs, list) else orig_imgs + shape = orig_img.shape + pred[:, :4] = ops.scale_boxes(img.shape[2:], pred[:, :4], shape).round() + pred_kpts = pred[:, 6:].view(len(pred), *self.model.kpt_shape) if len(pred) else pred[:, 6:] + pred_kpts = ops.scale_coords(img.shape[2:], pred_kpts, shape) + path = self.batch[0] + img_path = path[i] if isinstance(path, list) else path + results.append( + Results(orig_img=orig_img, + path=img_path, + names=self.model.names, + boxes=pred[:, :6], + keypoints=pred_kpts)) + return results diff --git a/downloads/ultralytics-main/ultralytics/models/yolo/pose/train.py b/downloads/ultralytics-main/ultralytics/models/yolo/pose/train.py new file mode 100644 index 000000000..2d4f4e0d4 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/yolo/pose/train.py @@ -0,0 +1,73 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from copy import copy + +from ultralytics.models import yolo +from ultralytics.nn.tasks import PoseModel +from ultralytics.utils import DEFAULT_CFG, LOGGER +from ultralytics.utils.plotting import plot_images, plot_results + + +class PoseTrainer(yolo.detect.DetectionTrainer): + """ + A class extending the DetectionTrainer class for training based on a pose model. + + Example: + ```python + from ultralytics.models.yolo.pose import PoseTrainer + + args = dict(model='yolov8n-pose.pt', data='coco8-pose.yaml', epochs=3) + trainer = PoseTrainer(overrides=args) + trainer.train() + ``` + """ + + def __init__(self, cfg=DEFAULT_CFG, overrides=None, _callbacks=None): + """Initialize a PoseTrainer object with specified configurations and overrides.""" + if overrides is None: + overrides = {} + overrides['task'] = 'pose' + super().__init__(cfg, overrides, _callbacks) + + if isinstance(self.args.device, str) and self.args.device.lower() == 'mps': + LOGGER.warning("WARNING ⚠️ Apple MPS known Pose bug. Recommend 'device=cpu' for Pose models. " + 'See https://github.com/ultralytics/ultralytics/issues/4031.') + + def get_model(self, cfg=None, weights=None, verbose=True): + """Get pose estimation model with specified configuration and weights.""" + model = PoseModel(cfg, ch=3, nc=self.data['nc'], data_kpt_shape=self.data['kpt_shape'], verbose=verbose) + if weights: + model.load(weights) + + return model + + def set_model_attributes(self): + """Sets keypoints shape attribute of PoseModel.""" + super().set_model_attributes() + self.model.kpt_shape = self.data['kpt_shape'] + + def get_validator(self): + """Returns an instance of the PoseValidator class for validation.""" + self.loss_names = 'box_loss', 'pose_loss', 'kobj_loss', 'cls_loss', 'dfl_loss' + return yolo.pose.PoseValidator(self.test_loader, save_dir=self.save_dir, args=copy(self.args)) + + def plot_training_samples(self, batch, ni): + """Plot a batch of training samples with annotated class labels, bounding boxes, and keypoints.""" + images = batch['img'] + kpts = batch['keypoints'] + cls = batch['cls'].squeeze(-1) + bboxes = batch['bboxes'] + paths = batch['im_file'] + batch_idx = batch['batch_idx'] + plot_images(images, + batch_idx, + cls, + bboxes, + kpts=kpts, + paths=paths, + fname=self.save_dir / f'train_batch{ni}.jpg', + on_plot=self.on_plot) + + def plot_metrics(self): + """Plots training/val metrics.""" + plot_results(file=self.csv, pose=True, on_plot=self.on_plot) # save results.png diff --git a/downloads/ultralytics-main/ultralytics/models/yolo/pose/val.py b/downloads/ultralytics-main/ultralytics/models/yolo/pose/val.py new file mode 100644 index 000000000..b8ebf57ed --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/yolo/pose/val.py @@ -0,0 +1,215 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from pathlib import Path + +import numpy as np +import torch + +from ultralytics.models.yolo.detect import DetectionValidator +from ultralytics.utils import LOGGER, ops +from ultralytics.utils.checks import check_requirements +from ultralytics.utils.metrics import OKS_SIGMA, PoseMetrics, box_iou, kpt_iou +from ultralytics.utils.plotting import output_to_target, plot_images + + +class PoseValidator(DetectionValidator): + """ + A class extending the DetectionValidator class for validation based on a pose model. + + Example: + ```python + from ultralytics.models.yolo.pose import PoseValidator + + args = dict(model='yolov8n-pose.pt', data='coco8-pose.yaml') + validator = PoseValidator(args=args) + validator() + ``` + """ + + def __init__(self, dataloader=None, save_dir=None, pbar=None, args=None, _callbacks=None): + """Initialize a 'PoseValidator' object with custom parameters and assigned attributes.""" + super().__init__(dataloader, save_dir, pbar, args, _callbacks) + self.sigma = None + self.kpt_shape = None + self.args.task = 'pose' + self.metrics = PoseMetrics(save_dir=self.save_dir, on_plot=self.on_plot) + if isinstance(self.args.device, str) and self.args.device.lower() == 'mps': + LOGGER.warning("WARNING ⚠️ Apple MPS known Pose bug. Recommend 'device=cpu' for Pose models. " + 'See https://github.com/ultralytics/ultralytics/issues/4031.') + + def preprocess(self, batch): + """Preprocesses the batch by converting the 'keypoints' data into a float and moving it to the device.""" + batch = super().preprocess(batch) + batch['keypoints'] = batch['keypoints'].to(self.device).float() + return batch + + def get_desc(self): + """Returns description of evaluation metrics in string format.""" + return ('%22s' + '%11s' * 10) % ('Class', 'Images', 'Instances', 'Box(P', 'R', 'mAP50', 'mAP50-95)', 'Pose(P', + 'R', 'mAP50', 'mAP50-95)') + + def postprocess(self, preds): + """Apply non-maximum suppression and return detections with high confidence scores.""" + return ops.non_max_suppression(preds, + self.args.conf, + self.args.iou, + labels=self.lb, + multi_label=True, + agnostic=self.args.single_cls, + max_det=self.args.max_det, + nc=self.nc) + + def init_metrics(self, model): + """Initiate pose estimation metrics for YOLO model.""" + super().init_metrics(model) + self.kpt_shape = self.data['kpt_shape'] + is_pose = self.kpt_shape == [17, 3] + nkpt = self.kpt_shape[0] + self.sigma = OKS_SIGMA if is_pose else np.ones(nkpt) / nkpt + + def update_metrics(self, preds, batch): + """Metrics.""" + for si, pred in enumerate(preds): + idx = batch['batch_idx'] == si + cls = batch['cls'][idx] + bbox = batch['bboxes'][idx] + kpts = batch['keypoints'][idx] + nl, npr = cls.shape[0], pred.shape[0] # number of labels, predictions + nk = kpts.shape[1] # number of keypoints + shape = batch['ori_shape'][si] + correct_kpts = torch.zeros(npr, self.niou, dtype=torch.bool, device=self.device) # init + correct_bboxes = torch.zeros(npr, self.niou, dtype=torch.bool, device=self.device) # init + self.seen += 1 + + if npr == 0: + if nl: + self.stats.append((correct_bboxes, correct_kpts, *torch.zeros( + (2, 0), device=self.device), cls.squeeze(-1))) + if self.args.plots: + self.confusion_matrix.process_batch(detections=None, labels=cls.squeeze(-1)) + continue + + # Predictions + if self.args.single_cls: + pred[:, 5] = 0 + predn = pred.clone() + ops.scale_boxes(batch['img'][si].shape[1:], predn[:, :4], shape, + ratio_pad=batch['ratio_pad'][si]) # native-space pred + pred_kpts = predn[:, 6:].view(npr, nk, -1) + ops.scale_coords(batch['img'][si].shape[1:], pred_kpts, shape, ratio_pad=batch['ratio_pad'][si]) + + # Evaluate + if nl: + height, width = batch['img'].shape[2:] + tbox = ops.xywh2xyxy(bbox) * torch.tensor( + (width, height, width, height), device=self.device) # target boxes + ops.scale_boxes(batch['img'][si].shape[1:], tbox, shape, + ratio_pad=batch['ratio_pad'][si]) # native-space labels + tkpts = kpts.clone() + tkpts[..., 0] *= width + tkpts[..., 1] *= height + tkpts = ops.scale_coords(batch['img'][si].shape[1:], tkpts, shape, ratio_pad=batch['ratio_pad'][si]) + labelsn = torch.cat((cls, tbox), 1) # native-space labels + correct_bboxes = self._process_batch(predn[:, :6], labelsn) + correct_kpts = self._process_batch(predn[:, :6], labelsn, pred_kpts, tkpts) + if self.args.plots: + self.confusion_matrix.process_batch(predn, labelsn) + + # Append correct_masks, correct_boxes, pconf, pcls, tcls + self.stats.append((correct_bboxes, correct_kpts, pred[:, 4], pred[:, 5], cls.squeeze(-1))) + + # Save + if self.args.save_json: + self.pred_to_json(predn, batch['im_file'][si]) + # if self.args.save_txt: + # save_one_txt(predn, save_conf, shape, file=save_dir / 'labels' / f'{path.stem}.txt') + + def _process_batch(self, detections, labels, pred_kpts=None, gt_kpts=None): + """ + Return correct prediction matrix. + + Args: + detections (torch.Tensor): Tensor of shape [N, 6] representing detections. + Each detection is of the format: x1, y1, x2, y2, conf, class. + labels (torch.Tensor): Tensor of shape [M, 5] representing labels. + Each label is of the format: class, x1, y1, x2, y2. + pred_kpts (torch.Tensor, optional): Tensor of shape [N, 51] representing predicted keypoints. + 51 corresponds to 17 keypoints each with 3 values. + gt_kpts (torch.Tensor, optional): Tensor of shape [N, 51] representing ground truth keypoints. + + Returns: + torch.Tensor: Correct prediction matrix of shape [N, 10] for 10 IoU levels. + """ + if pred_kpts is not None and gt_kpts is not None: + # `0.53` is from https://github.com/jin-s13/xtcocoapi/blob/master/xtcocotools/cocoeval.py#L384 + area = ops.xyxy2xywh(labels[:, 1:])[:, 2:].prod(1) * 0.53 + iou = kpt_iou(gt_kpts, pred_kpts, sigma=self.sigma, area=area) + else: # boxes + iou = box_iou(labels[:, 1:], detections[:, :4]) + + return self.match_predictions(detections[:, 5], labels[:, 0], iou) + + def plot_val_samples(self, batch, ni): + """Plots and saves validation set samples with predicted bounding boxes and keypoints.""" + plot_images(batch['img'], + batch['batch_idx'], + batch['cls'].squeeze(-1), + batch['bboxes'], + kpts=batch['keypoints'], + paths=batch['im_file'], + fname=self.save_dir / f'val_batch{ni}_labels.jpg', + names=self.names, + on_plot=self.on_plot) + + def plot_predictions(self, batch, preds, ni): + """Plots predictions for YOLO model.""" + pred_kpts = torch.cat([p[:, 6:].view(-1, *self.kpt_shape) for p in preds], 0) + plot_images(batch['img'], + *output_to_target(preds, max_det=self.args.max_det), + kpts=pred_kpts, + paths=batch['im_file'], + fname=self.save_dir / f'val_batch{ni}_pred.jpg', + names=self.names, + on_plot=self.on_plot) # pred + + def pred_to_json(self, predn, filename): + """Converts YOLO predictions to COCO JSON format.""" + stem = Path(filename).stem + image_id = int(stem) if stem.isnumeric() else stem + box = ops.xyxy2xywh(predn[:, :4]) # xywh + box[:, :2] -= box[:, 2:] / 2 # xy center to top-left corner + for p, b in zip(predn.tolist(), box.tolist()): + self.jdict.append({ + 'image_id': image_id, + 'category_id': self.class_map[int(p[5])], + 'bbox': [round(x, 3) for x in b], + 'keypoints': p[6:], + 'score': round(p[4], 5)}) + + def eval_json(self, stats): + """Evaluates object detection model using COCO JSON format.""" + if self.args.save_json and self.is_coco and len(self.jdict): + anno_json = self.data['path'] / 'annotations/person_keypoints_val2017.json' # annotations + pred_json = self.save_dir / 'predictions.json' # predictions + LOGGER.info(f'\nEvaluating pycocotools mAP using {pred_json} and {anno_json}...') + try: # https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/pycocoEvalDemo.ipynb + check_requirements('pycocotools>=2.0.6') + from pycocotools.coco import COCO # noqa + from pycocotools.cocoeval import COCOeval # noqa + + for x in anno_json, pred_json: + assert x.is_file(), f'{x} file not found' + anno = COCO(str(anno_json)) # init annotations api + pred = anno.loadRes(str(pred_json)) # init predictions api (must pass string, not Path) + for i, eval in enumerate([COCOeval(anno, pred, 'bbox'), COCOeval(anno, pred, 'keypoints')]): + if self.is_coco: + eval.params.imgIds = [int(Path(x).stem) for x in self.dataloader.dataset.im_files] # im to eval + eval.evaluate() + eval.accumulate() + eval.summarize() + idx = i * 4 + 2 + stats[self.metrics.keys[idx + 1]], stats[ + self.metrics.keys[idx]] = eval.stats[:2] # update mAP50-95 and mAP50 + except Exception as e: + LOGGER.warning(f'pycocotools unable to run: {e}') + return stats diff --git a/downloads/ultralytics-main/ultralytics/models/yolo/segment/__init__.py b/downloads/ultralytics-main/ultralytics/models/yolo/segment/__init__.py new file mode 100644 index 000000000..c84a570e9 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/yolo/segment/__init__.py @@ -0,0 +1,7 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from .predict import SegmentationPredictor +from .train import SegmentationTrainer +from .val import SegmentationValidator + +__all__ = 'SegmentationPredictor', 'SegmentationTrainer', 'SegmentationValidator' diff --git a/downloads/ultralytics-main/ultralytics/models/yolo/segment/predict.py b/downloads/ultralytics-main/ultralytics/models/yolo/segment/predict.py new file mode 100644 index 000000000..866c32ca7 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/yolo/segment/predict.py @@ -0,0 +1,57 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import torch + +from ultralytics.engine.results import Results +from ultralytics.models.yolo.detect.predict import DetectionPredictor +from ultralytics.utils import DEFAULT_CFG, ops + + +class SegmentationPredictor(DetectionPredictor): + """ + A class extending the DetectionPredictor class for prediction based on a segmentation model. + + Example: + ```python + from ultralytics.utils import ASSETS + from ultralytics.models.yolo.segment import SegmentationPredictor + + args = dict(model='yolov8n-seg.pt', source=ASSETS) + predictor = SegmentationPredictor(overrides=args) + predictor.predict_cli() + ``` + """ + + def __init__(self, cfg=DEFAULT_CFG, overrides=None, _callbacks=None): + super().__init__(cfg, overrides, _callbacks) + self.args.task = 'segment' + + def postprocess(self, preds, img, orig_imgs): + """TODO: filter by classes.""" + p = ops.non_max_suppression(preds[0], + self.args.conf, + self.args.iou, + agnostic=self.args.agnostic_nms, + max_det=self.args.max_det, + nc=len(self.model.names), + classes=self.args.classes) + results = [] + proto = preds[1][-1] if len(preds[1]) == 3 else preds[1] # second output is len 3 if pt, but only 1 if exported + for i, pred in enumerate(p): + orig_img = orig_imgs[i] if isinstance(orig_imgs, list) else orig_imgs + path = self.batch[0] + img_path = path[i] if isinstance(path, list) else path + if not len(pred): # save empty boxes + results.append(Results(orig_img=orig_img, path=img_path, names=self.model.names, boxes=pred[:, :6])) + continue + if self.args.retina_masks: + if not isinstance(orig_imgs, torch.Tensor): + pred[:, :4] = ops.scale_boxes(img.shape[2:], pred[:, :4], orig_img.shape) + masks = ops.process_mask_native(proto[i], pred[:, 6:], pred[:, :4], orig_img.shape[:2]) # HWC + else: + masks = ops.process_mask(proto[i], pred[:, 6:], pred[:, :4], img.shape[2:], upsample=True) # HWC + if not isinstance(orig_imgs, torch.Tensor): + pred[:, :4] = ops.scale_boxes(img.shape[2:], pred[:, :4], orig_img.shape) + results.append( + Results(orig_img=orig_img, path=img_path, names=self.model.names, boxes=pred[:, :6], masks=masks)) + return results diff --git a/downloads/ultralytics-main/ultralytics/models/yolo/segment/train.py b/downloads/ultralytics-main/ultralytics/models/yolo/segment/train.py new file mode 100644 index 000000000..b290192cd --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/yolo/segment/train.py @@ -0,0 +1,58 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from copy import copy + +from ultralytics.models import yolo +from ultralytics.nn.tasks import SegmentationModel +from ultralytics.utils import DEFAULT_CFG, RANK +from ultralytics.utils.plotting import plot_images, plot_results + + +class SegmentationTrainer(yolo.detect.DetectionTrainer): + """ + A class extending the DetectionTrainer class for training based on a segmentation model. + + Example: + ```python + from ultralytics.models.yolo.segment import SegmentationTrainer + + args = dict(model='yolov8n-seg.pt', data='coco8-seg.yaml', epochs=3) + trainer = SegmentationTrainer(overrides=args) + trainer.train() + ``` + """ + + def __init__(self, cfg=DEFAULT_CFG, overrides=None, _callbacks=None): + """Initialize a SegmentationTrainer object with given arguments.""" + if overrides is None: + overrides = {} + overrides['task'] = 'segment' + super().__init__(cfg, overrides, _callbacks) + + def get_model(self, cfg=None, weights=None, verbose=True): + """Return SegmentationModel initialized with specified config and weights.""" + model = SegmentationModel(cfg, ch=3, nc=self.data['nc'], verbose=verbose and RANK == -1) + if weights: + model.load(weights) + + return model + + def get_validator(self): + """Return an instance of SegmentationValidator for validation of YOLO model.""" + self.loss_names = 'box_loss', 'seg_loss', 'cls_loss', 'dfl_loss' + return yolo.segment.SegmentationValidator(self.test_loader, save_dir=self.save_dir, args=copy(self.args)) + + def plot_training_samples(self, batch, ni): + """Creates a plot of training sample images with labels and box coordinates.""" + plot_images(batch['img'], + batch['batch_idx'], + batch['cls'].squeeze(-1), + batch['bboxes'], + batch['masks'], + paths=batch['im_file'], + fname=self.save_dir / f'train_batch{ni}.jpg', + on_plot=self.on_plot) + + def plot_metrics(self): + """Plots training/val metrics.""" + plot_results(file=self.csv, segment=True, on_plot=self.on_plot) # save results.png diff --git a/downloads/ultralytics-main/ultralytics/models/yolo/segment/val.py b/downloads/ultralytics-main/ultralytics/models/yolo/segment/val.py new file mode 100644 index 000000000..0a2acb41a --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/models/yolo/segment/val.py @@ -0,0 +1,247 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from multiprocessing.pool import ThreadPool +from pathlib import Path + +import numpy as np +import torch +import torch.nn.functional as F + +from ultralytics.models.yolo.detect import DetectionValidator +from ultralytics.utils import LOGGER, NUM_THREADS, ops +from ultralytics.utils.checks import check_requirements +from ultralytics.utils.metrics import SegmentMetrics, box_iou, mask_iou +from ultralytics.utils.plotting import output_to_target, plot_images + + +class SegmentationValidator(DetectionValidator): + """ + A class extending the DetectionValidator class for validation based on a segmentation model. + + Example: + ```python + from ultralytics.models.yolo.segment import SegmentationValidator + + args = dict(model='yolov8n-seg.pt', data='coco8-seg.yaml') + validator = SegmentationValidator(args=args) + validator() + ``` + """ + + def __init__(self, dataloader=None, save_dir=None, pbar=None, args=None, _callbacks=None): + """Initialize SegmentationValidator and set task to 'segment', metrics to SegmentMetrics.""" + super().__init__(dataloader, save_dir, pbar, args, _callbacks) + self.plot_masks = None + self.process = None + self.args.task = 'segment' + self.metrics = SegmentMetrics(save_dir=self.save_dir, on_plot=self.on_plot) + + def preprocess(self, batch): + """Preprocesses batch by converting masks to float and sending to device.""" + batch = super().preprocess(batch) + batch['masks'] = batch['masks'].to(self.device).float() + return batch + + def init_metrics(self, model): + """Initialize metrics and select mask processing function based on save_json flag.""" + super().init_metrics(model) + self.plot_masks = [] + if self.args.save_json: + check_requirements('pycocotools>=2.0.6') + self.process = ops.process_mask_upsample # more accurate + else: + self.process = ops.process_mask # faster + + def get_desc(self): + """Return a formatted description of evaluation metrics.""" + return ('%22s' + '%11s' * 10) % ('Class', 'Images', 'Instances', 'Box(P', 'R', 'mAP50', 'mAP50-95)', 'Mask(P', + 'R', 'mAP50', 'mAP50-95)') + + def postprocess(self, preds): + """Post-processes YOLO predictions and returns output detections with proto.""" + p = ops.non_max_suppression(preds[0], + self.args.conf, + self.args.iou, + labels=self.lb, + multi_label=True, + agnostic=self.args.single_cls, + max_det=self.args.max_det, + nc=self.nc) + proto = preds[1][-1] if len(preds[1]) == 3 else preds[1] # second output is len 3 if pt, but only 1 if exported + return p, proto + + def update_metrics(self, preds, batch): + """Metrics.""" + for si, (pred, proto) in enumerate(zip(preds[0], preds[1])): + idx = batch['batch_idx'] == si + cls = batch['cls'][idx] + bbox = batch['bboxes'][idx] + nl, npr = cls.shape[0], pred.shape[0] # number of labels, predictions + shape = batch['ori_shape'][si] + correct_masks = torch.zeros(npr, self.niou, dtype=torch.bool, device=self.device) # init + correct_bboxes = torch.zeros(npr, self.niou, dtype=torch.bool, device=self.device) # init + self.seen += 1 + + if npr == 0: + if nl: + self.stats.append((correct_bboxes, correct_masks, *torch.zeros( + (2, 0), device=self.device), cls.squeeze(-1))) + if self.args.plots: + self.confusion_matrix.process_batch(detections=None, labels=cls.squeeze(-1)) + continue + + # Masks + midx = [si] if self.args.overlap_mask else idx + gt_masks = batch['masks'][midx] + pred_masks = self.process(proto, pred[:, 6:], pred[:, :4], shape=batch['img'][si].shape[1:]) + + # Predictions + if self.args.single_cls: + pred[:, 5] = 0 + predn = pred.clone() + ops.scale_boxes(batch['img'][si].shape[1:], predn[:, :4], shape, + ratio_pad=batch['ratio_pad'][si]) # native-space pred + + # Evaluate + if nl: + height, width = batch['img'].shape[2:] + tbox = ops.xywh2xyxy(bbox) * torch.tensor( + (width, height, width, height), device=self.device) # target boxes + ops.scale_boxes(batch['img'][si].shape[1:], tbox, shape, + ratio_pad=batch['ratio_pad'][si]) # native-space labels + labelsn = torch.cat((cls, tbox), 1) # native-space labels + correct_bboxes = self._process_batch(predn, labelsn) + # TODO: maybe remove these `self.` arguments as they already are member variable + correct_masks = self._process_batch(predn, + labelsn, + pred_masks, + gt_masks, + overlap=self.args.overlap_mask, + masks=True) + if self.args.plots: + self.confusion_matrix.process_batch(predn, labelsn) + + # Append correct_masks, correct_boxes, pconf, pcls, tcls + self.stats.append((correct_bboxes, correct_masks, pred[:, 4], pred[:, 5], cls.squeeze(-1))) + + pred_masks = torch.as_tensor(pred_masks, dtype=torch.uint8) + if self.args.plots and self.batch_i < 3: + self.plot_masks.append(pred_masks[:15].cpu()) # filter top 15 to plot + + # Save + if self.args.save_json: + pred_masks = ops.scale_image(pred_masks.permute(1, 2, 0).contiguous().cpu().numpy(), + shape, + ratio_pad=batch['ratio_pad'][si]) + self.pred_to_json(predn, batch['im_file'][si], pred_masks) + # if self.args.save_txt: + # save_one_txt(predn, save_conf, shape, file=save_dir / 'labels' / f'{path.stem}.txt') + + def finalize_metrics(self, *args, **kwargs): + """Sets speed and confusion matrix for evaluation metrics.""" + self.metrics.speed = self.speed + self.metrics.confusion_matrix = self.confusion_matrix + + def _process_batch(self, detections, labels, pred_masks=None, gt_masks=None, overlap=False, masks=False): + """ + Return correct prediction matrix + + Args: + detections (array[N, 6]), x1, y1, x2, y2, conf, class + labels (array[M, 5]), class, x1, y1, x2, y2 + + Returns: + correct (array[N, 10]), for 10 IoU levels + """ + if masks: + if overlap: + nl = len(labels) + index = torch.arange(nl, device=gt_masks.device).view(nl, 1, 1) + 1 + gt_masks = gt_masks.repeat(nl, 1, 1) # shape(1,640,640) -> (n,640,640) + gt_masks = torch.where(gt_masks == index, 1.0, 0.0) + if gt_masks.shape[1:] != pred_masks.shape[1:]: + gt_masks = F.interpolate(gt_masks[None], pred_masks.shape[1:], mode='bilinear', align_corners=False)[0] + gt_masks = gt_masks.gt_(0.5) + iou = mask_iou(gt_masks.view(gt_masks.shape[0], -1), pred_masks.view(pred_masks.shape[0], -1)) + else: # boxes + iou = box_iou(labels[:, 1:], detections[:, :4]) + + return self.match_predictions(detections[:, 5], labels[:, 0], iou) + + def plot_val_samples(self, batch, ni): + """Plots validation samples with bounding box labels.""" + plot_images(batch['img'], + batch['batch_idx'], + batch['cls'].squeeze(-1), + batch['bboxes'], + batch['masks'], + paths=batch['im_file'], + fname=self.save_dir / f'val_batch{ni}_labels.jpg', + names=self.names, + on_plot=self.on_plot) + + def plot_predictions(self, batch, preds, ni): + """Plots batch predictions with masks and bounding boxes.""" + plot_images( + batch['img'], + *output_to_target(preds[0], max_det=15), # not set to self.args.max_det due to slow plotting speed + torch.cat(self.plot_masks, dim=0) if len(self.plot_masks) else self.plot_masks, + paths=batch['im_file'], + fname=self.save_dir / f'val_batch{ni}_pred.jpg', + names=self.names, + on_plot=self.on_plot) # pred + self.plot_masks.clear() + + def pred_to_json(self, predn, filename, pred_masks): + """Save one JSON result.""" + # Example result = {"image_id": 42, "category_id": 18, "bbox": [258.15, 41.29, 348.26, 243.78], "score": 0.236} + from pycocotools.mask import encode # noqa + + def single_encode(x): + """Encode predicted masks as RLE and append results to jdict.""" + rle = encode(np.asarray(x[:, :, None], order='F', dtype='uint8'))[0] + rle['counts'] = rle['counts'].decode('utf-8') + return rle + + stem = Path(filename).stem + image_id = int(stem) if stem.isnumeric() else stem + box = ops.xyxy2xywh(predn[:, :4]) # xywh + box[:, :2] -= box[:, 2:] / 2 # xy center to top-left corner + pred_masks = np.transpose(pred_masks, (2, 0, 1)) + with ThreadPool(NUM_THREADS) as pool: + rles = pool.map(single_encode, pred_masks) + for i, (p, b) in enumerate(zip(predn.tolist(), box.tolist())): + self.jdict.append({ + 'image_id': image_id, + 'category_id': self.class_map[int(p[5])], + 'bbox': [round(x, 3) for x in b], + 'score': round(p[4], 5), + 'segmentation': rles[i]}) + + def eval_json(self, stats): + """Return COCO-style object detection evaluation metrics.""" + if self.args.save_json and self.is_coco and len(self.jdict): + anno_json = self.data['path'] / 'annotations/instances_val2017.json' # annotations + pred_json = self.save_dir / 'predictions.json' # predictions + LOGGER.info(f'\nEvaluating pycocotools mAP using {pred_json} and {anno_json}...') + try: # https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/pycocoEvalDemo.ipynb + check_requirements('pycocotools>=2.0.6') + from pycocotools.coco import COCO # noqa + from pycocotools.cocoeval import COCOeval # noqa + + for x in anno_json, pred_json: + assert x.is_file(), f'{x} file not found' + anno = COCO(str(anno_json)) # init annotations api + pred = anno.loadRes(str(pred_json)) # init predictions api (must pass string, not Path) + for i, eval in enumerate([COCOeval(anno, pred, 'bbox'), COCOeval(anno, pred, 'segm')]): + if self.is_coco: + eval.params.imgIds = [int(Path(x).stem) for x in self.dataloader.dataset.im_files] # im to eval + eval.evaluate() + eval.accumulate() + eval.summarize() + idx = i * 4 + 2 + stats[self.metrics.keys[idx + 1]], stats[ + self.metrics.keys[idx]] = eval.stats[:2] # update mAP50-95 and mAP50 + except Exception as e: + LOGGER.warning(f'pycocotools unable to run: {e}') + return stats diff --git a/downloads/ultralytics-main/ultralytics/nn/__init__.py b/downloads/ultralytics-main/ultralytics/nn/__init__.py index e69de29bb..9889b7ef2 100644 --- a/downloads/ultralytics-main/ultralytics/nn/__init__.py +++ b/downloads/ultralytics-main/ultralytics/nn/__init__.py @@ -0,0 +1,9 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from .tasks import (BaseModel, ClassificationModel, DetectionModel, SegmentationModel, attempt_load_one_weight, + attempt_load_weights, guess_model_scale, guess_model_task, parse_model, torch_safe_load, + yaml_model_load) + +__all__ = ('attempt_load_one_weight', 'attempt_load_weights', 'parse_model', 'yaml_model_load', 'guess_model_task', + 'guess_model_scale', 'torch_safe_load', 'DetectionModel', 'SegmentationModel', 'ClassificationModel', + 'BaseModel') diff --git a/downloads/ultralytics-main/ultralytics/nn/autobackend.py b/downloads/ultralytics-main/ultralytics/nn/autobackend.py index a6f671da2..93de16bba 100644 --- a/downloads/ultralytics-main/ultralytics/nn/autobackend.py +++ b/downloads/ultralytics-main/ultralytics/nn/autobackend.py @@ -15,10 +15,10 @@ import torch import torch.nn as nn from PIL import Image -from ultralytics.yolo.utils import LINUX, LOGGER, ROOT, yaml_load -from ultralytics.yolo.utils.checks import check_requirements, check_suffix, check_version, check_yaml -from ultralytics.yolo.utils.downloads import attempt_download_asset, is_url -from ultralytics.yolo.utils.ops import xywh2xyxy +from ultralytics.utils import ARM64, LINUX, LOGGER, ROOT, yaml_load +from ultralytics.utils.checks import check_requirements, check_suffix, check_version, check_yaml +from ultralytics.utils.downloads import attempt_download_asset, is_url +from ultralytics.utils.ops import xywh2xyxy def check_class_names(names): @@ -33,7 +33,7 @@ def check_class_names(names): raise KeyError(f'{n}-class dataset requires class indices 0-{n - 1}, but you have invalid class indices ' f'{min(names.keys())}-{max(names.keys())} defined in your dataset YAML.') if isinstance(names[0], str) and names[0].startswith('n0'): # imagenet class codes, i.e. 'n01440764' - map = yaml_load(ROOT / 'datasets/ImageNet.yaml')['map'] # human-readable names + map = yaml_load(ROOT / 'cfg/datasets/ImageNet.yaml')['map'] # human-readable names names = {k: map[v] for k, v in names.items()} return names @@ -54,8 +54,8 @@ class AutoBackend(nn.Module): Args: weights (str): The path to the weights file. Default: 'yolov8n.pt' device (torch.device): The device to run the model on. - dnn (bool): Use OpenCV's DNN module for inference if True, defaults to False. - data (str), (Path): Additional data.yaml file for class names, optional + dnn (bool): Use OpenCV DNN module for inference if True, defaults to False. + data (str | Path | optional): Additional data.yaml file for class names. fp16 (bool): If True, use half precision. Default: False fuse (bool): Whether to fuse the model or not. Default: True verbose (bool): Whether to run in verbose mode or not. Default: True @@ -68,28 +68,37 @@ class AutoBackend(nn.Module): | ONNX Runtime | *.onnx | | ONNX OpenCV DNN | *.onnx dnn=True | | OpenVINO | *.xml | - | CoreML | *.mlmodel | + | CoreML | *.mlpackage | | TensorRT | *.engine | | TensorFlow SavedModel | *_saved_model | | TensorFlow GraphDef | *.pb | | TensorFlow Lite | *.tflite | | TensorFlow Edge TPU | *_edgetpu.tflite | | PaddlePaddle | *_paddle_model | + | ncnn | *_ncnn_model | """ super().__init__() w = str(weights[0] if isinstance(weights, list) else weights) nn_module = isinstance(weights, torch.nn.Module) - pt, jit, onnx, xml, engine, coreml, saved_model, pb, tflite, edgetpu, tfjs, paddle, triton = self._model_type(w) - fp16 &= pt or jit or onnx or engine or nn_module or triton # FP16 + pt, jit, onnx, xml, engine, coreml, saved_model, pb, tflite, edgetpu, tfjs, paddle, ncnn, triton = \ + self._model_type(w) + fp16 &= pt or jit or onnx or xml or engine or nn_module or triton # FP16 nhwc = coreml or saved_model or pb or tflite or edgetpu # BHWC formats (vs torch BCWH) stride = 32 # default stride model, metadata = None, None - cuda = torch.cuda.is_available() and device.type != 'cpu' # use CUDA - if not (pt or triton or nn_module): - w = attempt_download_asset(w) # download if not local - # NOTE: special case: in-memory pytorch model - if nn_module: + # Set device + cuda = torch.cuda.is_available() and device.type != 'cpu' # use CUDA + if cuda and not any([nn_module, pt, jit, engine]): # GPU dataloader formats + device = torch.device('cpu') + cuda = False + + # Download if not local + if not (pt or triton or nn_module): + w = attempt_download_asset(w) + + # Load model + if nn_module: # in-memory PyTorch model model = weights.to(device) model = model.fuse(verbose=verbose) if fuse else model if hasattr(model, 'kpt_shape'): @@ -132,19 +141,19 @@ class AutoBackend(nn.Module): metadata = session.get_modelmeta().custom_metadata_map # metadata elif xml: # OpenVINO LOGGER.info(f'Loading {w} for OpenVINO inference...') - check_requirements('openvino') # requires openvino-dev: https://pypi.org/project/openvino-dev/ + check_requirements('openvino>=2023.0') # requires openvino-dev: https://pypi.org/project/openvino-dev/ from openvino.runtime import Core, Layout, get_batch # noqa - ie = Core() + core = Core() w = Path(w) if not w.is_file(): # if not *.xml w = next(w.glob('*.xml')) # get *.xml file from *_openvino_model dir - network = ie.read_model(model=str(w), weights=w.with_suffix('.bin')) - if network.get_parameters()[0].get_layout().empty: - network.get_parameters()[0].set_layout(Layout('NCHW')) - batch_dim = get_batch(network) + ov_model = core.read_model(model=str(w), weights=w.with_suffix('.bin')) + if ov_model.get_parameters()[0].get_layout().empty: + ov_model.get_parameters()[0].set_layout(Layout('NCHW')) + batch_dim = get_batch(ov_model) if batch_dim.is_static: batch_size = batch_dim.get_length() - executable_network = ie.compile_model(network, device_name='CPU') # device_name="MYRIAD" for NCS2 + ov_compiled_model = core.compile_model(ov_model, device_name='AUTO') # AUTO selects best available device metadata = w.parent / 'metadata.yaml' elif engine: # TensorRT LOGGER.info(f'Loading {w} for TensorRT inference...') @@ -200,7 +209,7 @@ class AutoBackend(nn.Module): LOGGER.info(f'Loading {w} for TensorFlow GraphDef inference...') import tensorflow as tf - from ultralytics.yolo.engine.exporter import gd_outputs + from ultralytics.engine.exporter import gd_outputs def wrap_frozen_graph(gd, inputs, outputs): """Wrap frozen graphs for deployment.""" @@ -237,7 +246,7 @@ class AutoBackend(nn.Module): meta_file = model.namelist()[0] metadata = ast.literal_eval(model.read(meta_file).decode('utf-8')) elif tfjs: # TF.js - raise NotImplementedError('YOLOv8 TF.js inference is not supported') + raise NotImplementedError('YOLOv8 TF.js inference is not currently supported.') elif paddle: # PaddlePaddle LOGGER.info(f'Loading {w} for PaddlePaddle inference...') check_requirements('paddlepaddle-gpu' if cuda else 'paddlepaddle') @@ -252,17 +261,28 @@ class AutoBackend(nn.Module): input_handle = predictor.get_input_handle(predictor.get_input_names()[0]) output_names = predictor.get_output_names() metadata = w.parents[1] / 'metadata.yaml' + elif ncnn: # ncnn + LOGGER.info(f'Loading {w} for ncnn inference...') + check_requirements('git+https://github.com/Tencent/ncnn.git' if ARM64 else 'ncnn') # requires ncnn + import ncnn as pyncnn + net = pyncnn.Net() + net.opt.use_vulkan_compute = cuda + w = Path(w) + if not w.is_file(): # if not *.param + w = next(w.glob('*.param')) # get *.param file from *_ncnn_model dir + net.load_param(str(w)) + net.load_model(str(w.with_suffix('.bin'))) + metadata = w.parent / 'metadata.yaml' elif triton: # NVIDIA Triton Inference Server - LOGGER.info('Triton Inference Server not supported...') - ''' - TODO: + """TODO check_requirements('tritonclient[all]') from utils.triton import TritonRemoteModel model = TritonRemoteModel(url=w) nhwc = model.runtime.startswith("tensorflow") - ''' + """ + raise NotImplementedError('Triton Inference Server is not currently supported.') else: - from ultralytics.yolo.engine.exporter import export_formats + from ultralytics.engine.exporter import export_formats raise TypeError(f"model='{w}' is not a supported model format. " 'See https://docs.ultralytics.com/modes/predict for help.' f'\n\n{export_formats()}') @@ -323,7 +343,7 @@ class AutoBackend(nn.Module): y = self.session.run(self.output_names, {self.session.get_inputs()[0].name: im}) elif self.xml: # OpenVINO im = im.cpu().numpy() # FP32 - y = list(self.executable_network([im]).values()) + y = list(self.ov_compiled_model(im).values()) elif self.engine: # TensorRT if self.dynamic and im.shape != self.bindings['images'].shape: i = self.model.get_binding_index('images') @@ -340,7 +360,7 @@ class AutoBackend(nn.Module): elif self.coreml: # CoreML im = im[0].cpu().numpy() im_pil = Image.fromarray((im * 255).astype('uint8')) - # im = im.resize((192, 320), Image.ANTIALIAS) + # im = im.resize((192, 320), Image.BILINEAR) y = self.model.predict({'image': im_pil}) # coordinates are xywh normalized if 'confidence' in y: box = xywh2xyxy(y['coordinates'] * [[w, h, w, h]]) # xyxy pixels @@ -355,6 +375,16 @@ class AutoBackend(nn.Module): self.input_handle.copy_from_cpu(im) self.predictor.run() y = [self.predictor.get_output_handle(x).copy_to_cpu() for x in self.output_names] + elif self.ncnn: # ncnn + mat_in = self.pyncnn.Mat(im[0].cpu().numpy()) + ex = self.net.create_extractor() + input_names, output_names = self.net.input_names(), self.net.output_names() + ex.input(input_names[0], mat_in) + y = [] + for output_name in output_names: + mat_out = self.pyncnn.Mat() + ex.extract(output_name, mat_out) + y.append(np.array(mat_out)[None]) elif self.triton: # NVIDIA Triton Inference Server y = self.model(im) else: # TensorFlow (SavedModel, GraphDef, Lite, Edge TPU) @@ -370,19 +400,24 @@ class AutoBackend(nn.Module): nc = y[ib].shape[1] - y[ip].shape[3] - 4 # y = (1, 160, 160, 32), (1, 116, 8400) self.names = {i: f'class{i}' for i in range(nc)} else: # Lite or Edge TPU - input = self.input_details[0] - int8 = input['dtype'] == np.int8 # is TFLite quantized int8 model - if int8: - scale, zero_point = input['quantization'] - im = (im / scale + zero_point).astype(np.int8) # de-scale - self.interpreter.set_tensor(input['index'], im) + details = self.input_details[0] + integer = details['dtype'] in (np.int8, np.int16) # is TFLite quantized int8 or int16 model + if integer: + scale, zero_point = details['quantization'] + im = (im / scale + zero_point).astype(details['dtype']) # de-scale + self.interpreter.set_tensor(details['index'], im) self.interpreter.invoke() y = [] for output in self.output_details: x = self.interpreter.get_tensor(output['index']) - if int8: + if integer: scale, zero_point = output['quantization'] x = (x.astype(np.float32) - zero_point) * scale # re-scale + if x.ndim > 2: # if task is not classification + # Denormalize xywh by image size. See https://github.com/ultralytics/ultralytics/pull/1695 + # xywh are normalized in TFLite/EdgeTPU to mitigate quantization error of integer models + x[:, [0, 2]] *= w + x[:, [1, 3]] *= h y.append(x) # TF segment fixes: export is reversed vs ONNX export and protos are transposed if len(y) == 2: # segment with (det, proto) output order reversed @@ -390,7 +425,6 @@ class AutoBackend(nn.Module): y = list(reversed(y)) # should be y = (1, 116, 8400), (1, 160, 160, 32) y[1] = np.transpose(y[1], (0, 3, 1, 2)) # should be y = (1, 116, 8400), (1, 32, 160, 160) y = [x if isinstance(x, np.ndarray) else x.numpy() for x in y] - # y[0][..., :4] *= [w, h, w, h] # xywh normalized to pixels # for x in y: # print(type(x), len(x)) if isinstance(x, (list, tuple)) else print(type(x), x.shape) # debug shapes @@ -444,12 +478,17 @@ class AutoBackend(nn.Module): """ # Return model type from model path, i.e. path='path/to/model.onnx' -> type=onnx # types = [pt, jit, onnx, xml, engine, coreml, saved_model, pb, tflite, edgetpu, tfjs, paddle] - from ultralytics.yolo.engine.exporter import export_formats + from ultralytics.engine.exporter import export_formats sf = list(export_formats().Suffix) # export suffixes if not is_url(p, check=False) and not isinstance(p, str): check_suffix(p, sf) # checks - url = urlparse(p) # if url may be Triton inference server - types = [s in Path(p).name for s in sf] + name = Path(p).name + types = [s in name for s in sf] + types[5] |= name.endswith('.mlmodel') # retain support for older Apple CoreML *.mlmodel formats types[8] &= not types[9] # tflite &= not edgetpu - triton = not any(types) and all([any(s in url.scheme for s in ['http', 'grpc']), url.netloc]) + if any(types): + triton = False + else: + url = urlparse(p) # if url may be Triton inference server + triton = all([any(s in url.scheme for s in ['http', 'grpc']), url.netloc]) return types + [triton] diff --git a/downloads/ultralytics-main/ultralytics/nn/modules/__init__.py b/downloads/ultralytics-main/ultralytics/nn/modules/__init__.py index b148cbf8f..b6dc6c442 100644 --- a/downloads/ultralytics-main/ultralytics/nn/modules/__init__.py +++ b/downloads/ultralytics-main/ultralytics/nn/modules/__init__.py @@ -1,17 +1,29 @@ # Ultralytics YOLO 🚀, AGPL-3.0 license +""" +Ultralytics modules. Visualize with: + +from ultralytics.nn.modules import * +import torch +import os + +x = torch.ones(1, 128, 40, 40) +m = Conv(128, 128) +f = f'{m._get_name()}.onnx' +torch.onnx.export(m, x, f) +os.system(f'onnxsim {f} {f} && open {f}') +""" from .block import (C1, C2, C3, C3TR, DFL, SPP, SPPF, Bottleneck, BottleneckCSP, C2f, C3Ghost, C3x, GhostBottleneck, HGBlock, HGStem, Proto, RepC3) -from .conv import (CBAM, ChannelAttention, Concat, Conv, ConvTranspose, DWConv, DWConvTranspose2d, Focus, GhostConv, - LightConv, RepConv, SpatialAttention) +from .conv import (CBAM, ChannelAttention, Concat, Conv, Conv2, ConvTranspose, DWConv, DWConvTranspose2d, Focus, + GhostConv, LightConv, RepConv, SpatialAttention) from .head import Classify, Detect, Pose, RTDETRDecoder, Segment from .transformer import (AIFI, MLP, DeformableTransformerDecoder, DeformableTransformerDecoderLayer, LayerNorm2d, MLPBlock, MSDeformAttn, TransformerBlock, TransformerEncoderLayer, TransformerLayer) -__all__ = [ - 'Conv', 'LightConv', 'RepConv', 'DWConv', 'DWConvTranspose2d', 'ConvTranspose', 'Focus', 'GhostConv', - 'ChannelAttention', 'SpatialAttention', 'CBAM', 'Concat', 'TransformerLayer', 'TransformerBlock', 'MLPBlock', - 'LayerNorm2d', 'DFL', 'HGBlock', 'HGStem', 'SPP', 'SPPF', 'C1', 'C2', 'C3', 'C2f', 'C3x', 'C3TR', 'C3Ghost', - 'GhostBottleneck', 'Bottleneck', 'BottleneckCSP', 'Proto', 'Detect', 'Segment', 'Pose', 'Classify', - 'TransformerEncoderLayer', 'RepC3', 'RTDETRDecoder', 'AIFI', 'DeformableTransformerDecoder', - 'DeformableTransformerDecoderLayer', 'MSDeformAttn', 'MLP'] +__all__ = ('Conv', 'Conv2', 'LightConv', 'RepConv', 'DWConv', 'DWConvTranspose2d', 'ConvTranspose', 'Focus', + 'GhostConv', 'ChannelAttention', 'SpatialAttention', 'CBAM', 'Concat', 'TransformerLayer', + 'TransformerBlock', 'MLPBlock', 'LayerNorm2d', 'DFL', 'HGBlock', 'HGStem', 'SPP', 'SPPF', 'C1', 'C2', 'C3', + 'C2f', 'C3x', 'C3TR', 'C3Ghost', 'GhostBottleneck', 'Bottleneck', 'BottleneckCSP', 'Proto', 'Detect', + 'Segment', 'Pose', 'Classify', 'TransformerEncoderLayer', 'RepC3', 'RTDETRDecoder', 'AIFI', + 'DeformableTransformerDecoder', 'DeformableTransformerDecoderLayer', 'MSDeformAttn', 'MLP') diff --git a/downloads/ultralytics-main/ultralytics/nn/modules/block.py b/downloads/ultralytics-main/ultralytics/nn/modules/block.py index ff76db398..d8183d84d 100644 --- a/downloads/ultralytics-main/ultralytics/nn/modules/block.py +++ b/downloads/ultralytics-main/ultralytics/nn/modules/block.py @@ -10,9 +10,8 @@ import torch.nn.functional as F from .conv import Conv, DWConv, GhostConv, LightConv, RepConv from .transformer import TransformerBlock -__all__ = [ - 'DFL', 'HGBlock', 'HGStem', 'SPP', 'SPPF', 'C1', 'C2', 'C3', 'C2f', 'C3x', 'C3TR', 'C3Ghost', 'GhostBottleneck', - 'Bottleneck', 'BottleneckCSP', 'Proto', 'RepC3'] +__all__ = ('DFL', 'HGBlock', 'HGStem', 'SPP', 'SPPF', 'C1', 'C2', 'C3', 'C2f', 'C3x', 'C3TR', 'C3Ghost', + 'GhostBottleneck', 'Bottleneck', 'BottleneckCSP', 'Proto', 'RepC3') class DFL(nn.Module): @@ -167,7 +166,7 @@ class C2(nn.Module): class C2f(nn.Module): - """CSP Bottleneck with 2 convolutions.""" + """Faster Implementation of CSP Bottleneck with 2 convolutions.""" def __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5): # ch_in, ch_out, number, shortcut, groups, expansion super().__init__() diff --git a/downloads/ultralytics-main/ultralytics/nn/modules/conv.py b/downloads/ultralytics-main/ultralytics/nn/modules/conv.py index 4f2836b1d..77e99c009 100644 --- a/downloads/ultralytics-main/ultralytics/nn/modules/conv.py +++ b/downloads/ultralytics-main/ultralytics/nn/modules/conv.py @@ -9,9 +9,8 @@ import numpy as np import torch import torch.nn as nn -__all__ = [ - 'Conv', 'LightConv', 'DWConv', 'DWConvTranspose2d', 'ConvTranspose', 'Focus', 'GhostConv', 'ChannelAttention', - 'SpatialAttention', 'CBAM', 'Concat', 'RepConv'] +__all__ = ('Conv', 'Conv2', 'LightConv', 'DWConv', 'DWConvTranspose2d', 'ConvTranspose', 'Focus', 'GhostConv', + 'ChannelAttention', 'SpatialAttention', 'CBAM', 'Concat', 'RepConv') def autopad(k, p=None, d=1): # kernel, padding, dilation @@ -43,6 +42,32 @@ class Conv(nn.Module): return self.act(self.conv(x)) +class Conv2(Conv): + """Simplified RepConv module with Conv fusing.""" + + def __init__(self, c1, c2, k=3, s=1, p=None, g=1, d=1, act=True): + """Initialize Conv layer with given arguments including activation.""" + super().__init__(c1, c2, k, s, p, g=g, d=d, act=act) + self.cv2 = nn.Conv2d(c1, c2, 1, s, autopad(1, p, d), groups=g, dilation=d, bias=False) # add 1x1 conv + + def forward(self, x): + """Apply convolution, batch normalization and activation to input tensor.""" + return self.act(self.bn(self.conv(x) + self.cv2(x))) + + def forward_fuse(self, x): + """Apply fused convolution, batch normalization and activation to input tensor.""" + return self.act(self.bn(self.conv(x))) + + def fuse_convs(self): + """Fuse parallel convolutions.""" + w = torch.zeros_like(self.conv.weight.data) + i = [x // 2 for x in w.shape[2:]] + w[:, :, i[0]:i[0] + 1, i[1]:i[1] + 1] = self.cv2.weight.data.clone() + self.conv.weight.data += w + self.__delattr__('cv2') + self.forward = self.forward_fuse + + class LightConv(nn.Module): """Light convolution with args(ch_in, ch_out, kernel). https://github.com/PaddlePaddle/PaddleDetection/blob/develop/ppdet/modeling/backbones/hgnet_v2.py @@ -122,8 +147,9 @@ class GhostConv(nn.Module): class RepConv(nn.Module): - """RepConv is a basic rep-style block, including training and deploy status - This code is based on https://github.com/DingXiaoH/RepVGG/blob/main/repvgg.py + """ + RepConv is a basic rep-style block, including training and deploy status. This module is used in RT-DETR. + Based on https://github.com/DingXiaoH/RepVGG/blob/main/repvgg.py """ default_act = nn.SiLU() # default activation @@ -154,15 +180,6 @@ class RepConv(nn.Module): kernelid, biasid = self._fuse_bn_tensor(self.bn) return kernel3x3 + self._pad_1x1_to_3x3_tensor(kernel1x1) + kernelid, bias3x3 + bias1x1 + biasid - def _avg_to_3x3_tensor(self, avgp): - channels = self.c1 - groups = self.g - kernel_size = avgp.kernel_size - input_dim = channels // groups - k = torch.zeros((channels, input_dim, kernel_size, kernel_size)) - k[np.arange(channels), np.tile(np.arange(input_dim), groups), :, :] = 1.0 / kernel_size ** 2 - return k - def _pad_1x1_to_3x3_tensor(self, kernel1x1): if kernel1x1 is None: return 0 diff --git a/downloads/ultralytics-main/ultralytics/nn/modules/head.py b/downloads/ultralytics-main/ultralytics/nn/modules/head.py index 26b2342ed..0b02eb3c6 100644 --- a/downloads/ultralytics-main/ultralytics/nn/modules/head.py +++ b/downloads/ultralytics-main/ultralytics/nn/modules/head.py @@ -9,14 +9,14 @@ import torch import torch.nn as nn from torch.nn.init import constant_, xavier_uniform_ -from ultralytics.yolo.utils.tal import dist2bbox, make_anchors +from ultralytics.utils.tal import TORCH_1_10, dist2bbox, make_anchors from .block import DFL, Proto from .conv import Conv from .transformer import MLP, DeformableTransformerDecoder, DeformableTransformerDecoderLayer from .utils import bias_init_with_prob, linear_init_ -__all__ = ['Detect', 'Segment', 'Pose', 'Classify', 'RTDETRDecoder'] +__all__ = 'Detect', 'Segment', 'Pose', 'Classify', 'RTDETRDecoder' class Detect(nn.Module): @@ -34,7 +34,7 @@ class Detect(nn.Module): self.reg_max = 16 # DFL channels (ch[0] // 16 to scale 4/8/12/16/20 for n/s/m/l/x) self.no = nc + self.reg_max * 4 # number of outputs per anchor self.stride = torch.zeros(self.nl) # strides computed during build - c2, c3 = max((16, ch[0] // 4, self.reg_max * 4)), max(ch[0], self.nc) # channels + c2, c3 = max((16, ch[0] // 4, self.reg_max * 4)), max(ch[0], min(self.nc, 100)) # channels self.cv2 = nn.ModuleList( nn.Sequential(Conv(x, c2, 3), Conv(c2, c2, 3), nn.Conv2d(c2, 4 * self.reg_max, 1)) for x in ch) self.cv3 = nn.ModuleList(nn.Sequential(Conv(x, c3, 3), Conv(c3, c3, 3), nn.Conv2d(c3, self.nc, 1)) for x in ch) @@ -58,6 +58,16 @@ class Detect(nn.Module): else: box, cls = x_cat.split((self.reg_max * 4, self.nc), 1) dbox = dist2bbox(self.dfl(box), self.anchors.unsqueeze(0), xywh=True, dim=1) * self.strides + + if self.export and self.format in ('tflite', 'edgetpu'): + # Normalize xywh with image size to mitigate quantization error of TFLite integer models as done in YOLOv5: + # https://github.com/ultralytics/yolov5/blob/0c8de3fca4a702f8ff5c435e67f378d1fce70243/models/tf.py#L307-L309 + # See this PR for details: https://github.com/ultralytics/ultralytics/pull/1695 + img_h = shape[2] * self.stride[0] + img_w = shape[3] * self.stride[0] + img_size = torch.tensor([img_w, img_h, img_w, img_h], device=dbox.device).reshape(1, 4, 1) + dbox /= img_size + y = torch.cat((dbox, cls.sigmoid()), 1) return y if self.export else (y, x) @@ -127,7 +137,7 @@ class Pose(Detect): y = kpts.view(bs, *self.kpt_shape, -1) a = (y[:, :, :2] * 2.0 + (self.anchors - 0.5)) * self.strides if ndim == 3: - a = torch.cat((a, y[:, :, 1:2].sigmoid()), 2) + a = torch.cat((a, y[:, :, 2:3].sigmoid()), 2) return a.view(bs, self.nk, -1) else: y = kpts.clone() @@ -158,116 +168,186 @@ class Classify(nn.Module): class RTDETRDecoder(nn.Module): + export = False # export mode def __init__( self, nc=80, ch=(512, 1024, 2048), - hidden_dim=256, - num_queries=300, - strides=(8, 16, 32), # TODO - nl=3, - num_decoder_points=4, - nhead=8, - num_decoder_layers=6, - dim_feedforward=1024, + hd=256, # hidden dim + nq=300, # num queries + ndp=4, # num decoder points + nh=8, # num head + ndl=6, # num decoder layers + d_ffn=1024, # dim of feedforward dropout=0., act=nn.ReLU(), eval_idx=-1, # training args - num_denoising=100, + nd=100, # num denoising label_noise_ratio=0.5, box_noise_scale=1.0, learnt_init_query=False): super().__init__() - assert len(ch) <= nl - assert len(strides) == len(ch) - for _ in range(nl - len(strides)): - strides.append(strides[-1] * 2) - - self.hidden_dim = hidden_dim - self.nhead = nhead - self.feat_strides = strides - self.nl = nl + self.hidden_dim = hd + self.nhead = nh + self.nl = len(ch) # num level self.nc = nc - self.num_queries = num_queries - self.num_decoder_layers = num_decoder_layers + self.num_queries = nq + self.num_decoder_layers = ndl # backbone feature projection - self._build_input_proj_layer(ch) + self.input_proj = nn.ModuleList(nn.Sequential(nn.Conv2d(x, hd, 1, bias=False), nn.BatchNorm2d(hd)) for x in ch) + # NOTE: simplified version but it's not consistent with .pt weights. + # self.input_proj = nn.ModuleList(Conv(x, hd, act=False) for x in ch) # Transformer module - decoder_layer = DeformableTransformerDecoderLayer(hidden_dim, nhead, dim_feedforward, dropout, act, nl, - num_decoder_points) - self.decoder = DeformableTransformerDecoder(hidden_dim, decoder_layer, num_decoder_layers, eval_idx) + decoder_layer = DeformableTransformerDecoderLayer(hd, nh, d_ffn, dropout, act, self.nl, ndp) + self.decoder = DeformableTransformerDecoder(hd, decoder_layer, ndl, eval_idx) # denoising part - self.denoising_class_embed = nn.Embedding(nc, hidden_dim) - self.num_denoising = num_denoising + self.denoising_class_embed = nn.Embedding(nc, hd) + self.num_denoising = nd self.label_noise_ratio = label_noise_ratio self.box_noise_scale = box_noise_scale # decoder embedding self.learnt_init_query = learnt_init_query if learnt_init_query: - self.tgt_embed = nn.Embedding(num_queries, hidden_dim) - self.query_pos_head = MLP(4, 2 * hidden_dim, hidden_dim, num_layers=2) + self.tgt_embed = nn.Embedding(nq, hd) + self.query_pos_head = MLP(4, 2 * hd, hd, num_layers=2) # encoder head - self.enc_output = nn.Sequential(nn.Linear(hidden_dim, hidden_dim), nn.LayerNorm(hidden_dim)) - self.enc_score_head = nn.Linear(hidden_dim, nc) - self.enc_bbox_head = MLP(hidden_dim, hidden_dim, 4, num_layers=3) + self.enc_output = nn.Sequential(nn.Linear(hd, hd), nn.LayerNorm(hd)) + self.enc_score_head = nn.Linear(hd, nc) + self.enc_bbox_head = MLP(hd, hd, 4, num_layers=3) # decoder head - self.dec_score_head = nn.ModuleList([nn.Linear(hidden_dim, nc) for _ in range(num_decoder_layers)]) - self.dec_bbox_head = nn.ModuleList([ - MLP(hidden_dim, hidden_dim, 4, num_layers=3) for _ in range(num_decoder_layers)]) + self.dec_score_head = nn.ModuleList([nn.Linear(hd, nc) for _ in range(ndl)]) + self.dec_bbox_head = nn.ModuleList([MLP(hd, hd, 4, num_layers=3) for _ in range(ndl)]) self._reset_parameters() - def forward(self, feats, gt_meta=None): + def forward(self, x, batch=None): + from ultralytics.models.utils.ops import get_cdn_group + # input projection and embedding - memory, spatial_shapes, _ = self._get_encoder_input(feats) + feats, shapes = self._get_encoder_input(x) # prepare denoising training - if self.training: - raise NotImplementedError - # denoising_class, denoising_bbox_unact, attn_mask, dn_meta = \ - # get_contrastive_denoising_training_group(gt_meta, - # self.num_classes, - # self.num_queries, - # self.denoising_class_embed.weight, - # self.num_denoising, - # self.label_noise_ratio, - # self.box_noise_scale) - else: - denoising_class, denoising_bbox_unact, attn_mask = None, None, None + dn_embed, dn_bbox, attn_mask, dn_meta = \ + get_cdn_group(batch, + self.nc, + self.num_queries, + self.denoising_class_embed.weight, + self.num_denoising, + self.label_noise_ratio, + self.box_noise_scale, + self.training) - target, init_ref_points_unact, enc_topk_bboxes, enc_topk_logits = \ - self._get_decoder_input(memory, spatial_shapes, denoising_class, denoising_bbox_unact) + embed, refer_bbox, enc_bboxes, enc_scores = \ + self._get_decoder_input(feats, shapes, dn_embed, dn_bbox) # decoder - out_bboxes, out_logits = self.decoder(target, - init_ref_points_unact, - memory, - spatial_shapes, + dec_bboxes, dec_scores = self.decoder(embed, + refer_bbox, + feats, + shapes, self.dec_bbox_head, self.dec_score_head, self.query_pos_head, attn_mask=attn_mask) - if not self.training: - out_logits = out_logits.sigmoid_() - return out_bboxes, out_logits # enc_topk_bboxes, enc_topk_logits, dn_meta + x = dec_bboxes, dec_scores, enc_bboxes, enc_scores, dn_meta + if self.training: + return x + # (bs, 300, 4+nc) + y = torch.cat((dec_bboxes.squeeze(0), dec_scores.squeeze(0).sigmoid()), -1) + return y if self.export else (y, x) + def _generate_anchors(self, shapes, grid_size=0.05, dtype=torch.float32, device='cpu', eps=1e-2): + anchors = [] + for i, (h, w) in enumerate(shapes): + sy = torch.arange(end=h, dtype=dtype, device=device) + sx = torch.arange(end=w, dtype=dtype, device=device) + grid_y, grid_x = torch.meshgrid(sy, sx, indexing='ij') if TORCH_1_10 else torch.meshgrid(sy, sx) + grid_xy = torch.stack([grid_x, grid_y], -1) # (h, w, 2) + + valid_WH = torch.tensor([h, w], dtype=dtype, device=device) + grid_xy = (grid_xy.unsqueeze(0) + 0.5) / valid_WH # (1, h, w, 2) + wh = torch.ones_like(grid_xy, dtype=dtype, device=device) * grid_size * (2.0 ** i) + anchors.append(torch.cat([grid_xy, wh], -1).view(-1, h * w, 4)) # (1, h*w, 4) + + anchors = torch.cat(anchors, 1) # (1, h*w*nl, 4) + valid_mask = ((anchors > eps) * (anchors < 1 - eps)).all(-1, keepdim=True) # 1, h*w*nl, 1 + anchors = torch.log(anchors / (1 - anchors)) + anchors = anchors.masked_fill(~valid_mask, float('inf')) + return anchors, valid_mask + + def _get_encoder_input(self, x): + # get projection features + x = [self.input_proj[i](feat) for i, feat in enumerate(x)] + # get encoder inputs + feats = [] + shapes = [] + for feat in x: + h, w = feat.shape[2:] + # [b, c, h, w] -> [b, h*w, c] + feats.append(feat.flatten(2).permute(0, 2, 1)) + # [nl, 2] + shapes.append([h, w]) + + # [b, h*w, c] + feats = torch.cat(feats, 1) + return feats, shapes + + def _get_decoder_input(self, feats, shapes, dn_embed=None, dn_bbox=None): + bs = len(feats) + # prepare input for decoder + anchors, valid_mask = self._generate_anchors(shapes, dtype=feats.dtype, device=feats.device) + features = self.enc_output(valid_mask * feats) # bs, h*w, 256 + + enc_outputs_scores = self.enc_score_head(features) # (bs, h*w, nc) + + # query selection + # (bs, num_queries) + topk_ind = torch.topk(enc_outputs_scores.max(-1).values, self.num_queries, dim=1).indices.view(-1) + # (bs, num_queries) + batch_ind = torch.arange(end=bs, dtype=topk_ind.dtype).unsqueeze(-1).repeat(1, self.num_queries).view(-1) + + # (bs, num_queries, 256) + top_k_features = features[batch_ind, topk_ind].view(bs, self.num_queries, -1) + # (bs, num_queries, 4) + top_k_anchors = anchors[:, topk_ind].view(bs, self.num_queries, -1) + + # dynamic anchors + static content + refer_bbox = self.enc_bbox_head(top_k_features) + top_k_anchors + + enc_bboxes = refer_bbox.sigmoid() + if dn_bbox is not None: + refer_bbox = torch.cat([dn_bbox, refer_bbox], 1) + enc_scores = enc_outputs_scores[batch_ind, topk_ind].view(bs, self.num_queries, -1) + + embeddings = self.tgt_embed.weight.unsqueeze(0).repeat(bs, 1, 1) if self.learnt_init_query else top_k_features + if self.training: + refer_bbox = refer_bbox.detach() + if not self.learnt_init_query: + embeddings = embeddings.detach() + if dn_embed is not None: + embeddings = torch.cat([dn_embed, embeddings], 1) + + return embeddings, refer_bbox, enc_bboxes, enc_scores + + # TODO def _reset_parameters(self): # class and bbox head init - bias_cls = bias_init_with_prob(0.01) - linear_init_(self.enc_score_head) + bias_cls = bias_init_with_prob(0.01) / 80 * self.nc + # NOTE: the weight initialization in `linear_init_` would cause NaN when training with custom datasets. + # linear_init_(self.enc_score_head) constant_(self.enc_score_head.bias, bias_cls) constant_(self.enc_bbox_head.layers[-1].weight, 0.) constant_(self.enc_bbox_head.layers[-1].bias, 0.) for cls_, reg_ in zip(self.dec_score_head, self.dec_bbox_head): - linear_init_(cls_) + # linear_init_(cls_) constant_(cls_.bias, bias_cls) constant_(reg_.layers[-1].weight, 0.) constant_(reg_.layers[-1].bias, 0.) @@ -280,103 +360,3 @@ class RTDETRDecoder(nn.Module): xavier_uniform_(self.query_pos_head.layers[1].weight) for layer in self.input_proj: xavier_uniform_(layer[0].weight) - - def _build_input_proj_layer(self, ch): - self.input_proj = nn.ModuleList() - for in_channels in ch: - self.input_proj.append( - nn.Sequential(nn.Conv2d(in_channels, self.hidden_dim, kernel_size=1, bias=False), - nn.BatchNorm2d(self.hidden_dim))) - in_channels = ch[-1] - for _ in range(self.nl - len(ch)): - self.input_proj.append( - nn.Sequential(nn.Conv2D(in_channels, self.hidden_dim, kernel_size=3, stride=2, padding=1, bias=False), - nn.BatchNorm2d(self.hidden_dim))) - in_channels = self.hidden_dim - - def _generate_anchors(self, spatial_shapes, grid_size=0.05, dtype=torch.float32, device='cpu', eps=1e-2): - anchors = [] - for lvl, (h, w) in enumerate(spatial_shapes): - grid_y, grid_x = torch.meshgrid(torch.arange(end=h, dtype=torch.float32), - torch.arange(end=w, dtype=torch.float32), - indexing='ij') - grid_xy = torch.stack([grid_x, grid_y], -1) - - valid_WH = torch.tensor([h, w]).to(torch.float32) - grid_xy = (grid_xy.unsqueeze(0) + 0.5) / valid_WH - wh = torch.ones_like(grid_xy) * grid_size * (2.0 ** lvl) - anchors.append(torch.concat([grid_xy, wh], -1).reshape([-1, h * w, 4])) - - anchors = torch.concat(anchors, 1) - valid_mask = ((anchors > eps) * (anchors < 1 - eps)).all(-1, keepdim=True) - anchors = torch.log(anchors / (1 - anchors)) - anchors = torch.where(valid_mask, anchors, torch.inf) - return anchors.to(device=device, dtype=dtype), valid_mask.to(device=device) - - def _get_encoder_input(self, feats): - # get projection features - proj_feats = [self.input_proj[i](feat) for i, feat in enumerate(feats)] - if self.nl > len(proj_feats): - len_srcs = len(proj_feats) - for i in range(len_srcs, self.nl): - if i == len_srcs: - proj_feats.append(self.input_proj[i](feats[-1])) - else: - proj_feats.append(self.input_proj[i](proj_feats[-1])) - - # get encoder inputs - feat_flatten = [] - spatial_shapes = [] - level_start_index = [0] - for feat in proj_feats: - _, _, h, w = feat.shape - # [b, c, h, w] -> [b, h*w, c] - feat_flatten.append(feat.flatten(2).permute(0, 2, 1)) - # [nl, 2] - spatial_shapes.append([h, w]) - # [l], start index of each level - level_start_index.append(h * w + level_start_index[-1]) - - # [b, l, c] - feat_flatten = torch.concat(feat_flatten, 1) - level_start_index.pop() - return feat_flatten, spatial_shapes, level_start_index - - def _get_decoder_input(self, memory, spatial_shapes, denoising_class=None, denoising_bbox_unact=None): - bs, _, _ = memory.shape - # prepare input for decoder - anchors, valid_mask = self._generate_anchors(spatial_shapes, dtype=memory.dtype, device=memory.device) - memory = torch.where(valid_mask, memory, 0) - output_memory = self.enc_output(memory) - - enc_outputs_class = self.enc_score_head(output_memory) # (bs, h*w, nc) - enc_outputs_coord_unact = self.enc_bbox_head(output_memory) + anchors # (bs, h*w, 4) - - # (bs, topk) - _, topk_ind = torch.topk(enc_outputs_class.max(-1).values, self.num_queries, dim=1) - # extract region proposal boxes - # (bs, topk_ind) - batch_ind = torch.arange(end=bs, dtype=topk_ind.dtype).unsqueeze(-1).repeat(1, self.num_queries).view(-1) - topk_ind = topk_ind.view(-1) - - # Unsigmoided - reference_points_unact = enc_outputs_coord_unact[batch_ind, topk_ind].view(bs, self.num_queries, -1) - - enc_topk_bboxes = torch.sigmoid(reference_points_unact) - if denoising_bbox_unact is not None: - reference_points_unact = torch.concat([denoising_bbox_unact, reference_points_unact], 1) - if self.training: - reference_points_unact = reference_points_unact.detach() - enc_topk_logits = enc_outputs_class[batch_ind, topk_ind].view(bs, self.num_queries, -1) - - # extract region features - if self.learnt_init_query: - target = self.tgt_embed.weight.unsqueeze(0).repeat(bs, 1, 1) - else: - target = output_memory[batch_ind, topk_ind].view(bs, self.num_queries, -1) - if self.training: - target = target.detach() - if denoising_class is not None: - target = torch.concat([denoising_class, target], 1) - - return target, reference_points_unact, enc_topk_bboxes, enc_topk_logits diff --git a/downloads/ultralytics-main/ultralytics/nn/modules/transformer.py b/downloads/ultralytics-main/ultralytics/nn/modules/transformer.py index 4ae946a78..ecbc4c0bf 100644 --- a/downloads/ultralytics-main/ultralytics/nn/modules/transformer.py +++ b/downloads/ultralytics-main/ultralytics/nn/modules/transformer.py @@ -13,9 +13,8 @@ from torch.nn.init import constant_, xavier_uniform_ from .conv import Conv from .utils import _get_clones, inverse_sigmoid, multi_scale_deformable_attn_pytorch -__all__ = [ - 'TransformerEncoderLayer', 'TransformerLayer', 'TransformerBlock', 'MLPBlock', 'LayerNorm2d', 'AIFI', - 'DeformableTransformerDecoder', 'DeformableTransformerDecoderLayer', 'MSDeformAttn', 'MLP'] +__all__ = ('TransformerEncoderLayer', 'TransformerLayer', 'TransformerBlock', 'MLPBlock', 'LayerNorm2d', 'AIFI', + 'DeformableTransformerDecoder', 'DeformableTransformerDecoderLayer', 'MSDeformAttn', 'MLP') class TransformerEncoderLayer(nn.Module): @@ -23,6 +22,10 @@ class TransformerEncoderLayer(nn.Module): def __init__(self, c1, cm=2048, num_heads=8, dropout=0.0, act=nn.GELU(), normalize_before=False): super().__init__() + from ...utils.torch_utils import TORCH_1_9 + if not TORCH_1_9: + raise ModuleNotFoundError( + 'TransformerEncoderLayer() requires torch>=1.9 to use nn.MultiheadAttention(batch_first=True).') self.ma = nn.MultiheadAttention(c1, num_heads, dropout=dropout, batch_first=True) # Implementation of Feedforward model self.fc1 = nn.Linear(c1, cm) @@ -78,7 +81,7 @@ class AIFI(TransformerEncoderLayer): pos_embed = self.build_2d_sincos_position_embedding(w, h, c) # flatten [B, C, H, W] to [B, HxW, C] x = super().forward(x.flatten(2).permute(0, 2, 1), pos=pos_embed.to(device=x.device, dtype=x.dtype)) - return x.permute((0, 2, 1)).view([-1, c, h, w]) + return x.permute(0, 2, 1).view([-1, c, h, w]).contiguous() @staticmethod def build_2d_sincos_position_embedding(w, h, embed_dim=256, temperature=10000.): @@ -94,8 +97,7 @@ class AIFI(TransformerEncoderLayer): out_w = grid_w.flatten()[..., None] @ omega[None] out_h = grid_h.flatten()[..., None] @ omega[None] - return torch.concat([torch.sin(out_w), torch.cos(out_w), - torch.sin(out_h), torch.cos(out_h)], axis=1)[None, :, :] + return torch.cat([torch.sin(out_w), torch.cos(out_w), torch.sin(out_h), torch.cos(out_h)], 1)[None] class TransformerLayer(nn.Module): @@ -167,9 +169,11 @@ class MLP(nn.Module): return x -# From https://github.com/facebookresearch/detectron2/blob/main/detectron2/layers/batch_norm.py # noqa -# Itself from https://github.com/facebookresearch/ConvNeXt/blob/d1fa8f6fef0a165b27399986cc2bdacc92777e40/models/convnext.py#L119 # noqa class LayerNorm2d(nn.Module): + """ + LayerNorm2d module from https://github.com/facebookresearch/detectron2/blob/main/detectron2/layers/batch_norm.py + https://github.com/facebookresearch/ConvNeXt/blob/d1fa8f6fef0a165b27399986cc2bdacc92777e40/models/convnext.py#L119 + """ def __init__(self, num_channels, eps=1e-6): super().__init__() @@ -230,23 +234,23 @@ class MSDeformAttn(nn.Module): xavier_uniform_(self.output_proj.weight.data) constant_(self.output_proj.bias.data, 0.) - def forward(self, query, reference_points, value, value_spatial_shapes, value_mask=None): + def forward(self, query, refer_bbox, value, value_shapes, value_mask=None): """ https://github.com/PaddlePaddle/PaddleDetection/blob/develop/ppdet/modeling/transformers/deformable_transformer.py Args: - query (Tensor): [bs, query_length, C] - reference_points (Tensor): [bs, query_length, n_levels, 2], range in [0, 1], top-left (0,0), + query (torch.Tensor): [bs, query_length, C] + refer_bbox (torch.Tensor): [bs, query_length, n_levels, 2], range in [0, 1], top-left (0,0), bottom-right (1, 1), including padding area - value (Tensor): [bs, value_length, C] - value_spatial_shapes (List): [n_levels, 2], [(H_0, W_0), (H_1, W_1), ..., (H_{L-1}, W_{L-1})] + value (torch.Tensor): [bs, value_length, C] + value_shapes (List): [n_levels, 2], [(H_0, W_0), (H_1, W_1), ..., (H_{L-1}, W_{L-1})] value_mask (Tensor): [bs, value_length], True for non-padding elements, False for padding elements Returns: output (Tensor): [bs, Length_{query}, C] """ bs, len_q = query.shape[:2] - _, len_v = value.shape[:2] - assert sum(s[0] * s[1] for s in value_spatial_shapes) == len_v + len_v = value.shape[1] + assert sum(s[0] * s[1] for s in value_shapes) == len_v value = self.value_proj(value) if value_mask is not None: @@ -256,18 +260,17 @@ class MSDeformAttn(nn.Module): attention_weights = self.attention_weights(query).view(bs, len_q, self.n_heads, self.n_levels * self.n_points) attention_weights = F.softmax(attention_weights, -1).view(bs, len_q, self.n_heads, self.n_levels, self.n_points) # N, Len_q, n_heads, n_levels, n_points, 2 - n = reference_points.shape[-1] - if n == 2: - offset_normalizer = torch.as_tensor(value_spatial_shapes, dtype=query.dtype, device=query.device).flip(-1) + num_points = refer_bbox.shape[-1] + if num_points == 2: + offset_normalizer = torch.as_tensor(value_shapes, dtype=query.dtype, device=query.device).flip(-1) add = sampling_offsets / offset_normalizer[None, None, None, :, None, :] - sampling_locations = reference_points[:, :, None, :, None, :] + add - - elif n == 4: - add = sampling_offsets / self.n_points * reference_points[:, :, None, :, None, 2:] * 0.5 - sampling_locations = reference_points[:, :, None, :, None, :2] + add + sampling_locations = refer_bbox[:, :, None, :, None, :] + add + elif num_points == 4: + add = sampling_offsets / self.n_points * refer_bbox[:, :, None, :, None, 2:] * 0.5 + sampling_locations = refer_bbox[:, :, None, :, None, :2] + add else: - raise ValueError(f'Last dim of reference_points must be 2 or 4, but got {n}.') - output = multi_scale_deformable_attn_pytorch(value, value_spatial_shapes, sampling_locations, attention_weights) + raise ValueError(f'Last dim of reference_points must be 2 or 4, but got {num_points}.') + output = multi_scale_deformable_attn_pytorch(value, value_shapes, sampling_locations, attention_weights) output = self.output_proj(output) return output @@ -309,33 +312,24 @@ class DeformableTransformerDecoderLayer(nn.Module): tgt = self.norm3(tgt) return tgt - def forward(self, - tgt, - reference_points, - src, - src_spatial_shapes, - src_padding_mask=None, - attn_mask=None, - query_pos=None): + def forward(self, embed, refer_bbox, feats, shapes, padding_mask=None, attn_mask=None, query_pos=None): # self attention - q = k = self.with_pos_embed(tgt, query_pos) - if attn_mask is not None: - attn_mask = torch.where(attn_mask.astype('bool'), torch.zeros(attn_mask.shape, tgt.dtype), - torch.full(attn_mask.shape, float('-inf'), tgt.dtype)) - tgt2 = self.self_attn(q.transpose(0, 1), k.transpose(0, 1), tgt.transpose(0, 1))[0].transpose(0, 1) - tgt = tgt + self.dropout1(tgt2) - tgt = self.norm1(tgt) + q = k = self.with_pos_embed(embed, query_pos) + tgt = self.self_attn(q.transpose(0, 1), k.transpose(0, 1), embed.transpose(0, 1), + attn_mask=attn_mask)[0].transpose(0, 1) + embed = embed + self.dropout1(tgt) + embed = self.norm1(embed) # cross attention - tgt2 = self.cross_attn(self.with_pos_embed(tgt, query_pos), reference_points, src, src_spatial_shapes, - src_padding_mask) - tgt = tgt + self.dropout2(tgt2) - tgt = self.norm2(tgt) + tgt = self.cross_attn(self.with_pos_embed(embed, query_pos), refer_bbox.unsqueeze(2), feats, shapes, + padding_mask) + embed = embed + self.dropout2(tgt) + embed = self.norm2(embed) # ffn - tgt = self.forward_ffn(tgt) + embed = self.forward_ffn(embed) - return tgt + return embed class DeformableTransformerDecoder(nn.Module): @@ -350,41 +344,40 @@ class DeformableTransformerDecoder(nn.Module): self.hidden_dim = hidden_dim self.eval_idx = eval_idx if eval_idx >= 0 else num_layers + eval_idx - def forward(self, - tgt, - reference_points, - src, - src_spatial_shapes, - bbox_head, - score_head, - query_pos_head, - attn_mask=None, - src_padding_mask=None): - output = tgt - dec_out_bboxes = [] - dec_out_logits = [] - ref_points = None - ref_points_detach = torch.sigmoid(reference_points) + def forward( + self, + embed, # decoder embeddings + refer_bbox, # anchor + feats, # image features + shapes, # feature shapes + bbox_head, + score_head, + pos_mlp, + attn_mask=None, + padding_mask=None): + output = embed + dec_bboxes = [] + dec_cls = [] + last_refined_bbox = None + refer_bbox = refer_bbox.sigmoid() for i, layer in enumerate(self.layers): - ref_points_input = ref_points_detach.unsqueeze(2) - query_pos_embed = query_pos_head(ref_points_detach) - output = layer(output, ref_points_input, src, src_spatial_shapes, src_padding_mask, attn_mask, - query_pos_embed) + output = layer(output, refer_bbox, feats, shapes, padding_mask, attn_mask, pos_mlp(refer_bbox)) - inter_ref_bbox = torch.sigmoid(bbox_head[i](output) + inverse_sigmoid(ref_points_detach)) + # refine bboxes, (bs, num_queries+num_denoising, 4) + refined_bbox = torch.sigmoid(bbox_head[i](output) + inverse_sigmoid(refer_bbox)) if self.training: - dec_out_logits.append(score_head[i](output)) + dec_cls.append(score_head[i](output)) if i == 0: - dec_out_bboxes.append(inter_ref_bbox) + dec_bboxes.append(refined_bbox) else: - dec_out_bboxes.append(torch.sigmoid(bbox_head[i](output) + inverse_sigmoid(ref_points))) + dec_bboxes.append(torch.sigmoid(bbox_head[i](output) + inverse_sigmoid(last_refined_bbox))) elif i == self.eval_idx: - dec_out_logits.append(score_head[i](output)) - dec_out_bboxes.append(inter_ref_bbox) + dec_cls.append(score_head[i](output)) + dec_bboxes.append(refined_bbox) break - ref_points = inter_ref_bbox - ref_points_detach = inter_ref_bbox.detach() if self.training else inter_ref_bbox + last_refined_bbox = refined_bbox + refer_bbox = refined_bbox.detach() if self.training else refined_bbox - return torch.stack(dec_out_bboxes), torch.stack(dec_out_logits) + return torch.stack(dec_bboxes), torch.stack(dec_cls) diff --git a/downloads/ultralytics-main/ultralytics/nn/modules/utils.py b/downloads/ultralytics-main/ultralytics/nn/modules/utils.py index 35cf30c44..f8636dc47 100644 --- a/downloads/ultralytics-main/ultralytics/nn/modules/utils.py +++ b/downloads/ultralytics-main/ultralytics/nn/modules/utils.py @@ -12,7 +12,7 @@ import torch.nn as nn import torch.nn.functional as F from torch.nn.init import uniform_ -__all__ = ['multi_scale_deformable_attn_pytorch', 'inverse_sigmoid'] +__all__ = 'multi_scale_deformable_attn_pytorch', 'inverse_sigmoid' def _get_clones(module, n): diff --git a/downloads/ultralytics-main/ultralytics/nn/tasks.py b/downloads/ultralytics-main/ultralytics/nn/tasks.py index 856456010..8cf66e2d7 100644 --- a/downloads/ultralytics-main/ultralytics/nn/tasks.py +++ b/downloads/ultralytics-main/ultralytics/nn/tasks.py @@ -8,14 +8,15 @@ import torch import torch.nn as nn from ultralytics.nn.modules import (AIFI, C1, C2, C3, C3TR, SPP, SPPF, Bottleneck, BottleneckCSP, C2f, C3Ghost, C3x, - Classify, Concat, Conv, ConvTranspose, Detect, DWConv, DWConvTranspose2d, Focus, - GhostBottleneck, GhostConv, HGBlock, HGStem, Pose, RepC3, RepConv, RTDETRDecoder, - Segment) -from ultralytics.yolo.utils import DEFAULT_CFG_DICT, DEFAULT_CFG_KEYS, LOGGER, colorstr, emojis, yaml_load -from ultralytics.yolo.utils.checks import check_requirements, check_suffix, check_yaml -from ultralytics.yolo.utils.plotting import feature_visualization -from ultralytics.yolo.utils.torch_utils import (fuse_conv_and_bn, fuse_deconv_and_bn, initialize_weights, - intersect_dicts, make_divisible, model_info, scale_img, time_sync) + Classify, Concat, Conv, Conv2, ConvTranspose, Detect, DWConv, DWConvTranspose2d, + Focus, GhostBottleneck, GhostConv, HGBlock, HGStem, Pose, RepC3, RepConv, + RTDETRDecoder, Segment) +from ultralytics.utils import DEFAULT_CFG_DICT, DEFAULT_CFG_KEYS, LOGGER, colorstr, emojis, yaml_load +from ultralytics.utils.checks import check_requirements, check_suffix, check_yaml +from ultralytics.utils.loss import v8ClassificationLoss, v8DetectionLoss, v8PoseLoss, v8SegmentationLoss +from ultralytics.utils.plotting import feature_visualization +from ultralytics.utils.torch_utils import (fuse_conv_and_bn, fuse_deconv_and_bn, initialize_weights, intersect_dicts, + make_divisible, model_info, scale_img, time_sync) try: import thop @@ -28,29 +29,46 @@ class BaseModel(nn.Module): The BaseModel class serves as a base class for all the models in the Ultralytics YOLO family. """ - def forward(self, x, profile=False, visualize=False): + def forward(self, x, *args, **kwargs): """ Forward pass of the model on a single scale. Wrapper for `_forward_once` method. Args: - x (torch.Tensor): The input image tensor - profile (bool): Whether to profile the model, defaults to False - visualize (bool): Whether to return the intermediate feature maps, defaults to False + x (torch.Tensor | dict): The input image tensor or a dict including image tensor and gt labels. Returns: (torch.Tensor): The output of the network. """ - return self._forward_once(x, profile, visualize) + if isinstance(x, dict): # for cases of training and validating while training. + return self.loss(x, *args, **kwargs) + return self.predict(x, *args, **kwargs) - def _forward_once(self, x, profile=False, visualize=False): + def predict(self, x, profile=False, visualize=False, augment=False): """ Perform a forward pass through the network. Args: - x (torch.Tensor): The input tensor to the model + x (torch.Tensor): The input tensor to the model. profile (bool): Print the computation time of each layer if True, defaults to False. - visualize (bool): Save the feature maps of the model if True, defaults to False + visualize (bool): Save the feature maps of the model if True, defaults to False. + augment (bool): Augment image during prediction, defaults to False. + + Returns: + (torch.Tensor): The last output of the model. + """ + if augment: + return self._predict_augment(x) + return self._predict_once(x, profile, visualize) + + def _predict_once(self, x, profile=False, visualize=False): + """ + Perform a forward pass through the network. + + Args: + x (torch.Tensor): The input tensor to the model. + profile (bool): Print the computation time of each layer if True, defaults to False. + visualize (bool): Save the feature maps of the model if True, defaults to False. Returns: (torch.Tensor): The last output of the model. @@ -67,6 +85,12 @@ class BaseModel(nn.Module): feature_visualization(x, m.type, m.i, save_dir=visualize) return x + def _predict_augment(self, x): + """Perform augmentations on input image x and return augmented inference.""" + LOGGER.warning(f'WARNING ⚠️ {self.__class__.__name__} does not support augmented inference yet. ' + f'Reverting to single-scale inference instead.') + return self._predict_once(x) + def _profile_one_layer(self, m, x, dt): """ Profile the computation time and FLOPs of a single layer of the model on a given input. @@ -80,15 +104,15 @@ class BaseModel(nn.Module): Returns: None """ - c = m == self.model[-1] # is final layer, copy input as inplace fix - o = thop.profile(m, inputs=[x.clone() if c else x], verbose=False)[0] / 1E9 * 2 if thop else 0 # FLOPs + c = m == self.model[-1] and isinstance(x, list) # is final layer list, copy input as inplace fix + flops = thop.profile(m, inputs=[x.copy() if c else x], verbose=False)[0] / 1E9 * 2 if thop else 0 # FLOPs t = time_sync() for _ in range(10): - m(x.clone() if c else x) + m(x.copy() if c else x) dt.append((time_sync() - t) * 100) if m == self.model[0]: LOGGER.info(f"{'time (ms)':>10s} {'GFLOPs':>10s} {'params':>10s} module") - LOGGER.info(f'{dt[-1]:10.2f} {o:10.2f} {m.np:10.0f} {m.type}') + LOGGER.info(f'{dt[-1]:10.2f} {flops:10.2f} {m.np:10.0f} {m.type}') if c: LOGGER.info(f"{sum(dt):10.2f} {'-':>10s} {'-':>10s} Total") @@ -102,7 +126,9 @@ class BaseModel(nn.Module): """ if not self.is_fused(): for m in self.model.modules(): - if isinstance(m, (Conv, DWConv)) and hasattr(m, 'bn'): + if isinstance(m, (Conv, Conv2, DWConv)) and hasattr(m, 'bn'): + if isinstance(m, Conv2): + m.fuse_convs() m.conv = fuse_conv_and_bn(m.conv, m.bn) # update conv delattr(m, 'bn') # remove batchnorm m.forward = m.forward_fuse # update forward @@ -135,6 +161,7 @@ class BaseModel(nn.Module): Prints model information Args: + detailed (bool): if True, prints out detailed information about the model. Defaults to False verbose (bool): if True, prints out the model information. Defaults to False imgsz (int): the size of the image that the model will be trained on. Defaults to 640 """ @@ -142,11 +169,10 @@ class BaseModel(nn.Module): def _apply(self, fn): """ - `_apply()` is a function that applies a function to all the tensors in the model that are not - parameters or registered buffers + Applies a function to all the tensors in the model that are not parameters or registered buffers. Args: - fn: the function to apply to the model + fn (function): the function to apply to the model Returns: A model that is a Detect() object. @@ -160,10 +186,11 @@ class BaseModel(nn.Module): return self def load(self, weights, verbose=True): - """Load the weights into the model. + """ + Load the weights into the model. Args: - weights (dict) or (torch.nn.Module): The pre-trained weights to be loaded. + weights (dict | torch.nn.Module): The pre-trained weights to be loaded. verbose (bool, optional): Whether to log the transfer progress. Defaults to True. """ model = weights['model'] if isinstance(weights, dict) else weights # torchvision models are not dicts @@ -173,6 +200,23 @@ class BaseModel(nn.Module): if verbose: LOGGER.info(f'Transferred {len(csd)}/{len(self.model.state_dict())} items from pretrained weights') + def loss(self, batch, preds=None): + """ + Compute loss + + Args: + batch (dict): Batch to compute loss on + preds (torch.Tensor | List[torch.Tensor]): Predictions. + """ + if not hasattr(self, 'criterion'): + self.criterion = self.init_criterion() + + preds = self.forward(batch['img']) if preds is None else preds + return self.criterion(preds, batch) + + def init_criterion(self): + raise NotImplementedError('compute_loss() needs to be implemented by task heads') + class DetectionModel(BaseModel): """YOLOv8 detection model.""" @@ -185,7 +229,7 @@ class DetectionModel(BaseModel): ch = self.yaml['ch'] = self.yaml.get('ch', ch) # input channels if nc and nc != self.yaml['nc']: LOGGER.info(f"Overriding model.yaml nc={self.yaml['nc']} with nc={nc}") - self.yaml['nc'] = nc # override yaml value + self.yaml['nc'] = nc # override YAML value self.model, self.save = parse_model(deepcopy(self.yaml), ch=ch, verbose=verbose) # model, savelist self.names = {i: f'{i}' for i in range(self.yaml['nc'])} # default names dict self.inplace = self.yaml.get('inplace', True) @@ -199,6 +243,8 @@ class DetectionModel(BaseModel): m.stride = torch.tensor([s / x.shape[-2] for x in forward(torch.zeros(1, ch, s, s))]) # forward self.stride = m.stride m.bias_init() # only run once + else: + self.stride = torch.Tensor([32]) # default stride for i.e. RTDETR # Init weights, biases initialize_weights(self) @@ -206,13 +252,7 @@ class DetectionModel(BaseModel): self.info() LOGGER.info('') - def forward(self, x, augment=False, profile=False, visualize=False): - """Run forward pass on input image(s) with optional augmentation and profiling.""" - if augment: - return self._forward_augment(x) # augmented inference, None - return self._forward_once(x, profile, visualize) # single-scale inference, train - - def _forward_augment(self, x): + def _predict_augment(self, x): """Perform augmentations on input image x and return augmented inference and train outputs.""" img_size = x.shape[-2:] # height, width s = [1, 0.83, 0.67] # scales @@ -220,7 +260,7 @@ class DetectionModel(BaseModel): y = [] # outputs for si, fi in zip(s, f): xi = scale_img(x.flip(fi) if fi else x, si, gs=int(self.stride.max())) - yi = self._forward_once(xi)[0] # forward + yi = super().predict(xi)[0] # forward # cv2.imwrite(f'img_{si}.jpg', 255 * xi[0].cpu().numpy().transpose((1, 2, 0))[:, :, ::-1]) # save yi = self._descale_pred(yi, fi, si, img_size) y.append(yi) @@ -249,6 +289,9 @@ class DetectionModel(BaseModel): y[-1] = y[-1][..., i:] # small return y + def init_criterion(self): + return v8DetectionLoss(self) + class SegmentationModel(DetectionModel): """YOLOv8 segmentation model.""" @@ -257,9 +300,8 @@ class SegmentationModel(DetectionModel): """Initialize YOLOv8 segmentation model with given config and parameters.""" super().__init__(cfg=cfg, ch=ch, nc=nc, verbose=verbose) - def _forward_augment(self, x): - """Undocumented function.""" - raise NotImplementedError(emojis('WARNING ⚠️ SegmentationModel has not supported augment inference yet!')) + def init_criterion(self): + return v8SegmentationLoss(self) class PoseModel(DetectionModel): @@ -274,17 +316,20 @@ class PoseModel(DetectionModel): cfg['kpt_shape'] = data_kpt_shape super().__init__(cfg=cfg, ch=ch, nc=nc, verbose=verbose) + def init_criterion(self): + return v8PoseLoss(self) + class ClassificationModel(BaseModel): """YOLOv8 classification model.""" def __init__(self, - cfg=None, + cfg='yolov8n-cls.yaml', model=None, ch=3, nc=None, cutoff=10, - verbose=True): # yaml, model, channels, number of classes, cutoff index, verbose flag + verbose=True): # YAML, model, channels, number of classes, cutoff index, verbose flag super().__init__() self._from_detection_model(model, nc, cutoff) if model is not None else self._from_yaml(cfg, ch, nc, verbose) @@ -312,7 +357,7 @@ class ClassificationModel(BaseModel): ch = self.yaml['ch'] = self.yaml.get('ch', ch) # input channels if nc and nc != self.yaml['nc']: LOGGER.info(f"Overriding model.yaml nc={self.yaml['nc']} with nc={nc}") - self.yaml['nc'] = nc # override yaml value + self.yaml['nc'] = nc # override YAML value elif not nc and not self.yaml.get('nc', None): raise ValueError('nc not specified. Must specify nc in model.yaml or function arguments.') self.model, self.save = parse_model(deepcopy(self.yaml), ch=ch, verbose=verbose) # model, savelist @@ -341,6 +386,84 @@ class ClassificationModel(BaseModel): if m[i].out_channels != nc: m[i] = nn.Conv2d(m[i].in_channels, nc, m[i].kernel_size, m[i].stride, bias=m[i].bias is not None) + def init_criterion(self): + """Compute the classification loss between predictions and true labels.""" + return v8ClassificationLoss() + + +class RTDETRDetectionModel(DetectionModel): + + def __init__(self, cfg='rtdetr-l.yaml', ch=3, nc=None, verbose=True): + super().__init__(cfg=cfg, ch=ch, nc=nc, verbose=verbose) + + def init_criterion(self): + """Compute the classification loss between predictions and true labels.""" + from ultralytics.models.utils.loss import RTDETRDetectionLoss + + return RTDETRDetectionLoss(nc=self.nc, use_vfl=True) + + def loss(self, batch, preds=None): + if not hasattr(self, 'criterion'): + self.criterion = self.init_criterion() + + img = batch['img'] + # NOTE: preprocess gt_bbox and gt_labels to list. + bs = len(img) + batch_idx = batch['batch_idx'] + gt_groups = [(batch_idx == i).sum().item() for i in range(bs)] + targets = { + 'cls': batch['cls'].to(img.device, dtype=torch.long).view(-1), + 'bboxes': batch['bboxes'].to(device=img.device), + 'batch_idx': batch_idx.to(img.device, dtype=torch.long).view(-1), + 'gt_groups': gt_groups} + + preds = self.predict(img, batch=targets) if preds is None else preds + dec_bboxes, dec_scores, enc_bboxes, enc_scores, dn_meta = preds if self.training else preds[1] + if dn_meta is None: + dn_bboxes, dn_scores = None, None + else: + dn_bboxes, dec_bboxes = torch.split(dec_bboxes, dn_meta['dn_num_split'], dim=2) + dn_scores, dec_scores = torch.split(dec_scores, dn_meta['dn_num_split'], dim=2) + + dec_bboxes = torch.cat([enc_bboxes.unsqueeze(0), dec_bboxes]) # (7, bs, 300, 4) + dec_scores = torch.cat([enc_scores.unsqueeze(0), dec_scores]) + + loss = self.criterion((dec_bboxes, dec_scores), + targets, + dn_bboxes=dn_bboxes, + dn_scores=dn_scores, + dn_meta=dn_meta) + # NOTE: There are like 12 losses in RTDETR, backward with all losses but only show the main three losses. + return sum(loss.values()), torch.as_tensor([loss[k].detach() for k in ['loss_giou', 'loss_class', 'loss_bbox']], + device=img.device) + + def predict(self, x, profile=False, visualize=False, batch=None, augment=False): + """ + Perform a forward pass through the network. + + Args: + x (torch.Tensor): The input tensor to the model + profile (bool): Print the computation time of each layer if True, defaults to False. + visualize (bool): Save the feature maps of the model if True, defaults to False + batch (dict): A dict including gt boxes and labels from dataloader. + + Returns: + (torch.Tensor): The last output of the model. + """ + y, dt = [], [] # outputs + for m in self.model[:-1]: # except the head part + if m.f != -1: # if not from previous layer + x = y[m.f] if isinstance(m.f, int) else [x if j == -1 else y[j] for j in m.f] # from earlier layers + if profile: + self._profile_one_layer(m, x, dt) + x = m(x) # run + y.append(x if m.i in self.save else None) # save output + if visualize: + feature_visualization(x, m.type, m.i, save_dir=visualize) + head = self.model[-1] + x = head([y[j] for j in head.f], batch) # head inference + return x + class Ensemble(nn.ModuleList): """Ensemble of models.""" @@ -361,6 +484,47 @@ class Ensemble(nn.ModuleList): # Functions ------------------------------------------------------------------------------------------------------------ +@contextlib.contextmanager +def temporary_modules(modules=None): + """ + Context manager for temporarily adding or modifying modules in Python's module cache (`sys.modules`). + + This function can be used to change the module paths during runtime. It's useful when refactoring code, + where you've moved a module from one location to another, but you still want to support the old import + paths for backwards compatibility. + + Args: + modules (dict, optional): A dictionary mapping old module paths to new module paths. + + Example: + ```python + with temporary_modules({'old.module.path': 'new.module.path'}): + import old.module.path # this will now import new.module.path + ``` + + Note: + The changes are only in effect inside the context manager and are undone once the context manager exits. + Be aware that directly manipulating `sys.modules` can lead to unpredictable results, especially in larger + applications or libraries. Use this function with caution. + """ + if not modules: + modules = {} + + import importlib + import sys + try: + # Set modules in sys.modules under their old name + for old, new in modules.items(): + sys.modules[old] = importlib.import_module(new) + + yield + finally: + # Remove the temporary module paths + for old in modules: + if old in sys.modules: + del sys.modules[old] + + def torch_safe_load(weight): """ This function attempts to load a PyTorch model with the torch.load() function. If a ModuleNotFoundError is raised, @@ -373,12 +537,17 @@ def torch_safe_load(weight): Returns: (dict): The loaded PyTorch model. """ - from ultralytics.yolo.utils.downloads import attempt_download_asset + from ultralytics.utils.downloads import attempt_download_asset check_suffix(file=weight, suffix='.pt') file = attempt_download_asset(weight) # search online if missing locally try: - return torch.load(file, map_location='cpu'), file # load + with temporary_modules({ + 'ultralytics.yolo.utils': 'ultralytics.utils', + 'ultralytics.yolo.v8': 'ultralytics.models.yolo', + 'ultralytics.yolo.data': 'ultralytics.data'}): # for legacy 8.0 Classify and Pose models + return torch.load(file, map_location='cpu'), file # load + except ModuleNotFoundError as e: # e.name is missing module name if e.name == 'models': raise TypeError( @@ -402,7 +571,7 @@ def attempt_load_weights(weights, device=None, inplace=True, fuse=False): ensemble = Ensemble() for w in weights if isinstance(weights, list) else [weights]: ckpt, w = torch_safe_load(w) # load ckpt - args = {**DEFAULT_CFG_DICT, **ckpt['train_args']} # combine model and default args, preferring model args + args = {**DEFAULT_CFG_DICT, **ckpt['train_args']} if 'train_args' in ckpt else None # combined args model = (ckpt.get('ema') or ckpt['model']).to(device).float() # FP32 model # Model compatibility updates @@ -415,11 +584,11 @@ def attempt_load_weights(weights, device=None, inplace=True, fuse=False): # Append ensemble.append(model.fuse().eval() if fuse and hasattr(model, 'fuse') else model.eval()) # model in eval mode - # Module compatibility updates + # Module updates for m in ensemble.modules(): t = type(m) if t in (nn.Hardswish, nn.LeakyReLU, nn.ReLU, nn.ReLU6, nn.SiLU, Detect, Segment): - m.inplace = inplace # torch 1.7.0 compatibility + m.inplace = inplace elif t is nn.Upsample and not hasattr(m, 'recompute_scale_factor'): m.recompute_scale_factor = None # torch 1.11.0 compatibility @@ -451,11 +620,11 @@ def attempt_load_one_weight(weight, device=None, inplace=True, fuse=False): model = model.fuse().eval() if fuse and hasattr(model, 'fuse') else model.eval() # model in eval mode - # Module compatibility updates + # Module updates for m in model.modules(): t = type(m) if t in (nn.Hardswish, nn.LeakyReLU, nn.ReLU, nn.ReLU6, nn.SiLU, Detect, Segment): - m.inplace = inplace # torch 1.7.0 compatibility + m.inplace = inplace elif t is nn.Upsample and not hasattr(m, 'recompute_scale_factor'): m.recompute_scale_factor = None # torch 1.11.0 compatibility @@ -464,12 +633,12 @@ def attempt_load_one_weight(weight, device=None, inplace=True, fuse=False): def parse_model(d, ch, verbose=True): # model_dict, input_channels(3) - # Parse a YOLO model.yaml dictionary into a PyTorch model + """Parse a YOLO model.yaml dictionary into a PyTorch model.""" import ast # Args max_channels = float('inf') - nc, act, scales = (d.get(x) for x in ('nc', 'act', 'scales')) + nc, act, scales = (d.get(x) for x in ('nc', 'activation', 'scales')) depth, width, kpt_shape = (d.get(x, 1.0) for x in ('depth_multiple', 'width_multiple', 'kpt_shape')) if scales: scale = d.get('scale') @@ -518,10 +687,12 @@ def parse_model(d, ch, verbose=True): # model_dict, input_channels(3) args = [ch[f]] elif m is Concat: c2 = sum(ch[x] for x in f) - elif m in (Detect, Segment, Pose, RTDETRDecoder): + elif m in (Detect, Segment, Pose): args.append([ch[x] for x in f]) if m is Segment: args[2] = make_divisible(min(args[2], max_channels) * width, 8) + elif m is RTDETRDecoder: # special case, channels arg must be passed in index 1 + args.insert(1, [ch[x] for x in f]) else: c2 = ch[f] @@ -547,7 +718,7 @@ def yaml_model_load(path): if path.stem in (f'yolov{d}{x}6' for x in 'nsmlx' for d in (5, 8)): new_stem = re.sub(r'(\d+)([nslmx])6(.+)?$', r'\1\2-p6\3', path.stem) LOGGER.warning(f'WARNING ⚠️ Ultralytics YOLO P6 models now use -p6 suffix. Renaming {path.stem} to {new_stem}.') - path = path.with_stem(new_stem) + path = path.with_name(new_stem + path.suffix) unified_path = re.sub(r'(\d+)([nslmx])(.+)?$', r'\1\3', str(path)) # i.e. yolov8x.yaml -> yolov8.yaml yaml_file = check_yaml(unified_path, hard=False) or check_yaml(path) @@ -564,7 +735,7 @@ def guess_model_scale(model_path): which is denoted by n, s, m, l, or x. The function returns the size character of the model scale as a string. Args: - model_path (str) or (Path): The path to the YOLO model's YAML file. + model_path (str | Path): The path to the YOLO model's YAML file. Returns: (str): The size character of the model's scale, which can be n, s, m, l, or x. @@ -580,7 +751,7 @@ def guess_model_task(model): Guess the task of a PyTorch model from its architecture or configuration. Args: - model (nn.Module) or (dict): PyTorch model or model configuration in YAML format. + model (nn.Module | dict): PyTorch model or model configuration in YAML format. Returns: (str): Task of the model ('detect', 'segment', 'classify', 'pose'). diff --git a/downloads/ultralytics-main/ultralytics/trackers/README.md b/downloads/ultralytics-main/ultralytics/trackers/README.md new file mode 100644 index 000000000..843bd2245 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/trackers/README.md @@ -0,0 +1,86 @@ +# Tracker + +## Supported Trackers + +- [x] ByteTracker +- [x] BoT-SORT + +## Usage + +### python interface: + +You can use the Python interface to track objects using the YOLO model. + +```python +from ultralytics import YOLO + +model = YOLO("yolov8n.pt") # or a segmentation model .i.e yolov8n-seg.pt +model.track( + source="video/streams", + stream=True, + tracker="botsort.yaml", # or 'bytetrack.yaml' + show=True, +) +``` + +You can get the IDs of the tracked objects using the following code: + +```python +from ultralytics import YOLO + +model = YOLO("yolov8n.pt") + +for result in model.track(source="video.mp4"): + print( + result.boxes.id.cpu().numpy().astype(int) + ) # this will print the IDs of the tracked objects in the frame +``` + +If you want to use the tracker with a folder of images or when you loop on the video frames, you should use the `persist` parameter to tell the model that these frames are related to each other so the IDs will be fixed for the same objects. Otherwise, the IDs will be different in each frame because in each loop, the model creates a new object for tracking, but the `persist` parameter makes it use the same object for tracking. + +```python +import cv2 +from ultralytics import YOLO + +cap = cv2.VideoCapture("video.mp4") +model = YOLO("yolov8n.pt") +while True: + ret, frame = cap.read() + if not ret: + break + results = model.track(frame, persist=True) + boxes = results[0].boxes.xyxy.cpu().numpy().astype(int) + ids = results[0].boxes.id.cpu().numpy().astype(int) + for box, id in zip(boxes, ids): + cv2.rectangle(frame, (box[0], box[1]), (box[2], box[3]), (0, 255, 0), 2) + cv2.putText( + frame, + f"Id {id}", + (box[0], box[1]), + cv2.FONT_HERSHEY_SIMPLEX, + 1, + (0, 0, 255), + 2, + ) + cv2.imshow("frame", frame) + if cv2.waitKey(1) & 0xFF == ord("q"): + break +``` + +## Change tracker parameters + +You can change the tracker parameters by eding the `tracker.yaml` file which is located in the ultralytics/cfg/trackers folder. + +## Command Line Interface (CLI) + +You can also use the command line interface to track objects using the YOLO model. + +```bash +yolo detect track source=... tracker=... +yolo segment track source=... tracker=... +yolo pose track source=... tracker=... +``` + +By default, trackers will use the configuration in `ultralytics/cfg/trackers`. +We also support using a modified tracker config file. Please refer to the tracker config files +in `ultralytics/cfg/trackers`.
diff --git a/downloads/ultralytics-main/ultralytics/trackers/__init__.py b/downloads/ultralytics-main/ultralytics/trackers/__init__.py new file mode 100644 index 000000000..46e178e42 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/trackers/__init__.py @@ -0,0 +1,7 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from .bot_sort import BOTSORT +from .byte_tracker import BYTETracker +from .track import register_tracker + +__all__ = 'register_tracker', 'BOTSORT', 'BYTETracker' # allow simpler import diff --git a/downloads/ultralytics-main/ultralytics/trackers/basetrack.py b/downloads/ultralytics-main/ultralytics/trackers/basetrack.py new file mode 100644 index 000000000..3c7b0f707 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/trackers/basetrack.py @@ -0,0 +1,71 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from collections import OrderedDict + +import numpy as np + + +class TrackState: + """Enumeration of possible object tracking states.""" + + New = 0 + Tracked = 1 + Lost = 2 + Removed = 3 + + +class BaseTrack: + """Base class for object tracking, handling basic track attributes and operations.""" + + _count = 0 + + track_id = 0 + is_activated = False + state = TrackState.New + + history = OrderedDict() + features = [] + curr_feature = None + score = 0 + start_frame = 0 + frame_id = 0 + time_since_update = 0 + + # Multi-camera + location = (np.inf, np.inf) + + @property + def end_frame(self): + """Return the last frame ID of the track.""" + return self.frame_id + + @staticmethod + def next_id(): + """Increment and return the global track ID counter.""" + BaseTrack._count += 1 + return BaseTrack._count + + def activate(self, *args): + """Activate the track with the provided arguments.""" + raise NotImplementedError + + def predict(self): + """Predict the next state of the track.""" + raise NotImplementedError + + def update(self, *args, **kwargs): + """Update the track with new observations.""" + raise NotImplementedError + + def mark_lost(self): + """Mark the track as lost.""" + self.state = TrackState.Lost + + def mark_removed(self): + """Mark the track as removed.""" + self.state = TrackState.Removed + + @staticmethod + def reset_id(): + """Reset the global track ID counter.""" + BaseTrack._count = 0 diff --git a/downloads/ultralytics-main/ultralytics/trackers/bot_sort.py b/downloads/ultralytics-main/ultralytics/trackers/bot_sort.py new file mode 100644 index 000000000..d42d46ebd --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/trackers/bot_sort.py @@ -0,0 +1,147 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from collections import deque + +import numpy as np + +from .basetrack import TrackState +from .byte_tracker import BYTETracker, STrack +from .utils import matching +from .utils.gmc import GMC +from .utils.kalman_filter import KalmanFilterXYWH + + +class BOTrack(STrack): + shared_kalman = KalmanFilterXYWH() + + def __init__(self, tlwh, score, cls, feat=None, feat_history=50): + """Initialize YOLOv8 object with temporal parameters, such as feature history, alpha and current features.""" + super().__init__(tlwh, score, cls) + + self.smooth_feat = None + self.curr_feat = None + if feat is not None: + self.update_features(feat) + self.features = deque([], maxlen=feat_history) + self.alpha = 0.9 + + def update_features(self, feat): + """Update features vector and smooth it using exponential moving average.""" + feat /= np.linalg.norm(feat) + self.curr_feat = feat + if self.smooth_feat is None: + self.smooth_feat = feat + else: + self.smooth_feat = self.alpha * self.smooth_feat + (1 - self.alpha) * feat + self.features.append(feat) + self.smooth_feat /= np.linalg.norm(self.smooth_feat) + + def predict(self): + """Predicts the mean and covariance using Kalman filter.""" + mean_state = self.mean.copy() + if self.state != TrackState.Tracked: + mean_state[6] = 0 + mean_state[7] = 0 + + self.mean, self.covariance = self.kalman_filter.predict(mean_state, self.covariance) + + def re_activate(self, new_track, frame_id, new_id=False): + """Reactivates a track with updated features and optionally assigns a new ID.""" + if new_track.curr_feat is not None: + self.update_features(new_track.curr_feat) + super().re_activate(new_track, frame_id, new_id) + + def update(self, new_track, frame_id): + """Update the YOLOv8 instance with new track and frame ID.""" + if new_track.curr_feat is not None: + self.update_features(new_track.curr_feat) + super().update(new_track, frame_id) + + @property + def tlwh(self): + """Get current position in bounding box format `(top left x, top left y, + width, height)`. + """ + if self.mean is None: + return self._tlwh.copy() + ret = self.mean[:4].copy() + ret[:2] -= ret[2:] / 2 + return ret + + @staticmethod + def multi_predict(stracks): + """Predicts the mean and covariance of multiple object tracks using shared Kalman filter.""" + if len(stracks) <= 0: + return + multi_mean = np.asarray([st.mean.copy() for st in stracks]) + multi_covariance = np.asarray([st.covariance for st in stracks]) + for i, st in enumerate(stracks): + if st.state != TrackState.Tracked: + multi_mean[i][6] = 0 + multi_mean[i][7] = 0 + multi_mean, multi_covariance = BOTrack.shared_kalman.multi_predict(multi_mean, multi_covariance) + for i, (mean, cov) in enumerate(zip(multi_mean, multi_covariance)): + stracks[i].mean = mean + stracks[i].covariance = cov + + def convert_coords(self, tlwh): + """Converts Top-Left-Width-Height bounding box coordinates to X-Y-Width-Height format.""" + return self.tlwh_to_xywh(tlwh) + + @staticmethod + def tlwh_to_xywh(tlwh): + """Convert bounding box to format `(center x, center y, width, + height)`. + """ + ret = np.asarray(tlwh).copy() + ret[:2] += ret[2:] / 2 + return ret + + +class BOTSORT(BYTETracker): + + def __init__(self, args, frame_rate=30): + """Initialize YOLOv8 object with ReID module and GMC algorithm.""" + super().__init__(args, frame_rate) + # ReID module + self.proximity_thresh = args.proximity_thresh + self.appearance_thresh = args.appearance_thresh + + if args.with_reid: + # Haven't supported BoT-SORT(reid) yet + self.encoder = None + self.gmc = GMC(method=args.gmc_method) + + def get_kalmanfilter(self): + """Returns an instance of KalmanFilterXYWH for object tracking.""" + return KalmanFilterXYWH() + + def init_track(self, dets, scores, cls, img=None): + """Initialize track with detections, scores, and classes.""" + if len(dets) == 0: + return [] + if self.args.with_reid and self.encoder is not None: + features_keep = self.encoder.inference(img, dets) + return [BOTrack(xyxy, s, c, f) for (xyxy, s, c, f) in zip(dets, scores, cls, features_keep)] # detections + else: + return [BOTrack(xyxy, s, c) for (xyxy, s, c) in zip(dets, scores, cls)] # detections + + def get_dists(self, tracks, detections): + """Get distances between tracks and detections using IoU and (optionally) ReID embeddings.""" + dists = matching.iou_distance(tracks, detections) + dists_mask = (dists > self.proximity_thresh) + + # TODO: mot20 + # if not self.args.mot20: + dists = matching.fuse_score(dists, detections) + + if self.args.with_reid and self.encoder is not None: + emb_dists = matching.embedding_distance(tracks, detections) / 2.0 + emb_dists[emb_dists > self.appearance_thresh] = 1.0 + emb_dists[dists_mask] = 1.0 + dists = np.minimum(dists, emb_dists) + return dists + + def multi_predict(self, tracks): + """Predict and track multiple objects with YOLOv8 model.""" + BOTrack.multi_predict(tracks) diff --git a/downloads/ultralytics-main/ultralytics/trackers/byte_tracker.py b/downloads/ultralytics-main/ultralytics/trackers/byte_tracker.py new file mode 100644 index 000000000..04958cda6 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/trackers/byte_tracker.py @@ -0,0 +1,364 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import numpy as np + +from .basetrack import BaseTrack, TrackState +from .utils import matching +from .utils.kalman_filter import KalmanFilterXYAH + + +class STrack(BaseTrack): + shared_kalman = KalmanFilterXYAH() + + def __init__(self, tlwh, score, cls): + """wait activate.""" + self._tlwh = np.asarray(self.tlbr_to_tlwh(tlwh[:-1]), dtype=np.float32) + self.kalman_filter = None + self.mean, self.covariance = None, None + self.is_activated = False + + self.score = score + self.tracklet_len = 0 + self.cls = cls + self.idx = tlwh[-1] + + def predict(self): + """Predicts mean and covariance using Kalman filter.""" + mean_state = self.mean.copy() + if self.state != TrackState.Tracked: + mean_state[7] = 0 + self.mean, self.covariance = self.kalman_filter.predict(mean_state, self.covariance) + + @staticmethod + def multi_predict(stracks): + """Perform multi-object predictive tracking using Kalman filter for given stracks.""" + if len(stracks) <= 0: + return + multi_mean = np.asarray([st.mean.copy() for st in stracks]) + multi_covariance = np.asarray([st.covariance for st in stracks]) + for i, st in enumerate(stracks): + if st.state != TrackState.Tracked: + multi_mean[i][7] = 0 + multi_mean, multi_covariance = STrack.shared_kalman.multi_predict(multi_mean, multi_covariance) + for i, (mean, cov) in enumerate(zip(multi_mean, multi_covariance)): + stracks[i].mean = mean + stracks[i].covariance = cov + + @staticmethod + def multi_gmc(stracks, H=np.eye(2, 3)): + """Update state tracks positions and covariances using a homography matrix.""" + if len(stracks) > 0: + multi_mean = np.asarray([st.mean.copy() for st in stracks]) + multi_covariance = np.asarray([st.covariance for st in stracks]) + + R = H[:2, :2] + R8x8 = np.kron(np.eye(4, dtype=float), R) + t = H[:2, 2] + + for i, (mean, cov) in enumerate(zip(multi_mean, multi_covariance)): + mean = R8x8.dot(mean) + mean[:2] += t + cov = R8x8.dot(cov).dot(R8x8.transpose()) + + stracks[i].mean = mean + stracks[i].covariance = cov + + def activate(self, kalman_filter, frame_id): + """Start a new tracklet.""" + self.kalman_filter = kalman_filter + self.track_id = self.next_id() + self.mean, self.covariance = self.kalman_filter.initiate(self.convert_coords(self._tlwh)) + + self.tracklet_len = 0 + self.state = TrackState.Tracked + if frame_id == 1: + self.is_activated = True + self.frame_id = frame_id + self.start_frame = frame_id + + def re_activate(self, new_track, frame_id, new_id=False): + """Reactivates a previously lost track with a new detection.""" + self.mean, self.covariance = self.kalman_filter.update(self.mean, self.covariance, + self.convert_coords(new_track.tlwh)) + self.tracklet_len = 0 + self.state = TrackState.Tracked + self.is_activated = True + self.frame_id = frame_id + if new_id: + self.track_id = self.next_id() + self.score = new_track.score + self.cls = new_track.cls + self.idx = new_track.idx + + def update(self, new_track, frame_id): + """ + Update a matched track + :type new_track: STrack + :type frame_id: int + :return: + """ + self.frame_id = frame_id + self.tracklet_len += 1 + + new_tlwh = new_track.tlwh + self.mean, self.covariance = self.kalman_filter.update(self.mean, self.covariance, + self.convert_coords(new_tlwh)) + self.state = TrackState.Tracked + self.is_activated = True + + self.score = new_track.score + self.cls = new_track.cls + self.idx = new_track.idx + + def convert_coords(self, tlwh): + """Convert a bounding box's top-left-width-height format to its x-y-angle-height equivalent.""" + return self.tlwh_to_xyah(tlwh) + + @property + def tlwh(self): + """Get current position in bounding box format `(top left x, top left y, + width, height)`. + """ + if self.mean is None: + return self._tlwh.copy() + ret = self.mean[:4].copy() + ret[2] *= ret[3] + ret[:2] -= ret[2:] / 2 + return ret + + @property + def tlbr(self): + """Convert bounding box to format `(min x, min y, max x, max y)`, i.e., + `(top left, bottom right)`. + """ + ret = self.tlwh.copy() + ret[2:] += ret[:2] + return ret + + @staticmethod + def tlwh_to_xyah(tlwh): + """Convert bounding box to format `(center x, center y, aspect ratio, + height)`, where the aspect ratio is `width / height`. + """ + ret = np.asarray(tlwh).copy() + ret[:2] += ret[2:] / 2 + ret[2] /= ret[3] + return ret + + @staticmethod + def tlbr_to_tlwh(tlbr): + """Converts top-left bottom-right format to top-left width height format.""" + ret = np.asarray(tlbr).copy() + ret[2:] -= ret[:2] + return ret + + @staticmethod + def tlwh_to_tlbr(tlwh): + """Converts tlwh bounding box format to tlbr format.""" + ret = np.asarray(tlwh).copy() + ret[2:] += ret[:2] + return ret + + def __repr__(self): + """Return a string representation of the BYTETracker object with start and end frames and track ID.""" + return f'OT_{self.track_id}_({self.start_frame}-{self.end_frame})' + + +class BYTETracker: + + def __init__(self, args, frame_rate=30): + """Initialize a YOLOv8 object to track objects with given arguments and frame rate.""" + self.tracked_stracks = [] # type: list[STrack] + self.lost_stracks = [] # type: list[STrack] + self.removed_stracks = [] # type: list[STrack] + + self.frame_id = 0 + self.args = args + self.max_time_lost = int(frame_rate / 30.0 * args.track_buffer) + self.kalman_filter = self.get_kalmanfilter() + self.reset_id() + + def update(self, results, img=None): + """Updates object tracker with new detections and returns tracked object bounding boxes.""" + self.frame_id += 1 + activated_stracks = [] + refind_stracks = [] + lost_stracks = [] + removed_stracks = [] + + scores = results.conf + bboxes = results.xyxy + # Add index + bboxes = np.concatenate([bboxes, np.arange(len(bboxes)).reshape(-1, 1)], axis=-1) + cls = results.cls + + remain_inds = scores > self.args.track_high_thresh + inds_low = scores > self.args.track_low_thresh + inds_high = scores < self.args.track_high_thresh + + inds_second = np.logical_and(inds_low, inds_high) + dets_second = bboxes[inds_second] + dets = bboxes[remain_inds] + scores_keep = scores[remain_inds] + scores_second = scores[inds_second] + cls_keep = cls[remain_inds] + cls_second = cls[inds_second] + + detections = self.init_track(dets, scores_keep, cls_keep, img) + # Add newly detected tracklets to tracked_stracks + unconfirmed = [] + tracked_stracks = [] # type: list[STrack] + for track in self.tracked_stracks: + if not track.is_activated: + unconfirmed.append(track) + else: + tracked_stracks.append(track) + # Step 2: First association, with high score detection boxes + strack_pool = self.joint_stracks(tracked_stracks, self.lost_stracks) + # Predict the current location with KF + self.multi_predict(strack_pool) + if hasattr(self, 'gmc') and img is not None: + warp = self.gmc.apply(img, dets) + STrack.multi_gmc(strack_pool, warp) + STrack.multi_gmc(unconfirmed, warp) + + dists = self.get_dists(strack_pool, detections) + matches, u_track, u_detection = matching.linear_assignment(dists, thresh=self.args.match_thresh) + + for itracked, idet in matches: + track = strack_pool[itracked] + det = detections[idet] + if track.state == TrackState.Tracked: + track.update(det, self.frame_id) + activated_stracks.append(track) + else: + track.re_activate(det, self.frame_id, new_id=False) + refind_stracks.append(track) + # Step 3: Second association, with low score detection boxes + # association the untrack to the low score detections + detections_second = self.init_track(dets_second, scores_second, cls_second, img) + r_tracked_stracks = [strack_pool[i] for i in u_track if strack_pool[i].state == TrackState.Tracked] + # TODO + dists = matching.iou_distance(r_tracked_stracks, detections_second) + matches, u_track, u_detection_second = matching.linear_assignment(dists, thresh=0.5) + for itracked, idet in matches: + track = r_tracked_stracks[itracked] + det = detections_second[idet] + if track.state == TrackState.Tracked: + track.update(det, self.frame_id) + activated_stracks.append(track) + else: + track.re_activate(det, self.frame_id, new_id=False) + refind_stracks.append(track) + + for it in u_track: + track = r_tracked_stracks[it] + if track.state != TrackState.Lost: + track.mark_lost() + lost_stracks.append(track) + # Deal with unconfirmed tracks, usually tracks with only one beginning frame + detections = [detections[i] for i in u_detection] + dists = self.get_dists(unconfirmed, detections) + matches, u_unconfirmed, u_detection = matching.linear_assignment(dists, thresh=0.7) + for itracked, idet in matches: + unconfirmed[itracked].update(detections[idet], self.frame_id) + activated_stracks.append(unconfirmed[itracked]) + for it in u_unconfirmed: + track = unconfirmed[it] + track.mark_removed() + removed_stracks.append(track) + # Step 4: Init new stracks + for inew in u_detection: + track = detections[inew] + if track.score < self.args.new_track_thresh: + continue + track.activate(self.kalman_filter, self.frame_id) + activated_stracks.append(track) + # Step 5: Update state + for track in self.lost_stracks: + if self.frame_id - track.end_frame > self.max_time_lost: + track.mark_removed() + removed_stracks.append(track) + + self.tracked_stracks = [t for t in self.tracked_stracks if t.state == TrackState.Tracked] + self.tracked_stracks = self.joint_stracks(self.tracked_stracks, activated_stracks) + self.tracked_stracks = self.joint_stracks(self.tracked_stracks, refind_stracks) + self.lost_stracks = self.sub_stracks(self.lost_stracks, self.tracked_stracks) + self.lost_stracks.extend(lost_stracks) + self.lost_stracks = self.sub_stracks(self.lost_stracks, self.removed_stracks) + self.tracked_stracks, self.lost_stracks = self.remove_duplicate_stracks(self.tracked_stracks, self.lost_stracks) + self.removed_stracks.extend(removed_stracks) + if len(self.removed_stracks) > 1000: + self.removed_stracks = self.removed_stracks[-999:] # clip remove stracks to 1000 maximum + return np.asarray( + [x.tlbr.tolist() + [x.track_id, x.score, x.cls, x.idx] for x in self.tracked_stracks if x.is_activated], + dtype=np.float32) + + def get_kalmanfilter(self): + """Returns a Kalman filter object for tracking bounding boxes.""" + return KalmanFilterXYAH() + + def init_track(self, dets, scores, cls, img=None): + """Initialize object tracking with detections and scores using STrack algorithm.""" + return [STrack(xyxy, s, c) for (xyxy, s, c) in zip(dets, scores, cls)] if len(dets) else [] # detections + + def get_dists(self, tracks, detections): + """Calculates the distance between tracks and detections using IOU and fuses scores.""" + dists = matching.iou_distance(tracks, detections) + # TODO: mot20 + # if not self.args.mot20: + dists = matching.fuse_score(dists, detections) + return dists + + def multi_predict(self, tracks): + """Returns the predicted tracks using the YOLOv8 network.""" + STrack.multi_predict(tracks) + + def reset_id(self): + """Resets the ID counter of STrack.""" + STrack.reset_id() + + @staticmethod + def joint_stracks(tlista, tlistb): + """Combine two lists of stracks into a single one.""" + exists = {} + res = [] + for t in tlista: + exists[t.track_id] = 1 + res.append(t) + for t in tlistb: + tid = t.track_id + if not exists.get(tid, 0): + exists[tid] = 1 + res.append(t) + return res + + @staticmethod + def sub_stracks(tlista, tlistb): + """DEPRECATED CODE in https://github.com/ultralytics/ultralytics/pull/1890/ + stracks = {t.track_id: t for t in tlista} + for t in tlistb: + tid = t.track_id + if stracks.get(tid, 0): + del stracks[tid] + return list(stracks.values()) + """ + track_ids_b = {t.track_id for t in tlistb} + return [t for t in tlista if t.track_id not in track_ids_b] + + @staticmethod + def remove_duplicate_stracks(stracksa, stracksb): + """Remove duplicate stracks with non-maximum IOU distance.""" + pdist = matching.iou_distance(stracksa, stracksb) + pairs = np.where(pdist < 0.15) + dupa, dupb = [], [] + for p, q in zip(*pairs): + timep = stracksa[p].frame_id - stracksa[p].start_frame + timeq = stracksb[q].frame_id - stracksb[q].start_frame + if timep > timeq: + dupb.append(q) + else: + dupa.append(p) + resa = [t for i, t in enumerate(stracksa) if i not in dupa] + resb = [t for i, t in enumerate(stracksb) if i not in dupb] + return resa, resb diff --git a/downloads/ultralytics-main/ultralytics/trackers/track.py b/downloads/ultralytics-main/ultralytics/trackers/track.py new file mode 100644 index 000000000..cfb4b08ad --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/trackers/track.py @@ -0,0 +1,66 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from functools import partial + +import torch + +from ultralytics.utils import IterableSimpleNamespace, yaml_load +from ultralytics.utils.checks import check_yaml + +from .bot_sort import BOTSORT +from .byte_tracker import BYTETracker + +TRACKER_MAP = {'bytetrack': BYTETracker, 'botsort': BOTSORT} + + +def on_predict_start(predictor, persist=False): + """ + Initialize trackers for object tracking during prediction. + + Args: + predictor (object): The predictor object to initialize trackers for. + persist (bool, optional): Whether to persist the trackers if they already exist. Defaults to False. + + Raises: + AssertionError: If the tracker_type is not 'bytetrack' or 'botsort'. + """ + if hasattr(predictor, 'trackers') and persist: + return + tracker = check_yaml(predictor.args.tracker) + cfg = IterableSimpleNamespace(**yaml_load(tracker)) + assert cfg.tracker_type in ['bytetrack', 'botsort'], \ + f"Only support 'bytetrack' and 'botsort' for now, but got '{cfg.tracker_type}'" + trackers = [] + for _ in range(predictor.dataset.bs): + tracker = TRACKER_MAP[cfg.tracker_type](args=cfg, frame_rate=30) + trackers.append(tracker) + predictor.trackers = trackers + + +def on_predict_postprocess_end(predictor): + """Postprocess detected boxes and update with object tracking.""" + bs = predictor.dataset.bs + im0s = predictor.batch[1] + for i in range(bs): + det = predictor.results[i].boxes.cpu().numpy() + if len(det) == 0: + continue + tracks = predictor.trackers[i].update(det, im0s[i]) + if len(tracks) == 0: + continue + idx = tracks[:, -1].astype(int) + predictor.results[i] = predictor.results[i][idx] + predictor.results[i].update(boxes=torch.as_tensor(tracks[:, :-1])) + + +def register_tracker(model, persist): + """ + Register tracking callbacks to the model for object tracking during prediction. + + Args: + model (object): The model object to register tracking callbacks for. + persist (bool): Whether to persist the trackers if they already exist. + + """ + model.add_callback('on_predict_start', partial(on_predict_start, persist=persist)) + model.add_callback('on_predict_postprocess_end', on_predict_postprocess_end) diff --git a/downloads/ultralytics-main/ultralytics/trackers/utils/__init__.py b/downloads/ultralytics-main/ultralytics/trackers/utils/__init__.py new file mode 100644 index 000000000..9e68dc122 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/trackers/utils/__init__.py @@ -0,0 +1 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license diff --git a/downloads/ultralytics-main/ultralytics/trackers/utils/gmc.py b/downloads/ultralytics-main/ultralytics/trackers/utils/gmc.py new file mode 100644 index 000000000..4d91df45f --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/trackers/utils/gmc.py @@ -0,0 +1,279 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import copy + +import cv2 +import numpy as np + +from ultralytics.utils import LOGGER + + +class GMC: + + def __init__(self, method='sparseOptFlow', downscale=2): + """Initialize a video tracker with specified parameters.""" + super().__init__() + + self.method = method + self.downscale = max(1, int(downscale)) + + if self.method == 'orb': + self.detector = cv2.FastFeatureDetector_create(20) + self.extractor = cv2.ORB_create() + self.matcher = cv2.BFMatcher(cv2.NORM_HAMMING) + + elif self.method == 'sift': + self.detector = cv2.SIFT_create(nOctaveLayers=3, contrastThreshold=0.02, edgeThreshold=20) + self.extractor = cv2.SIFT_create(nOctaveLayers=3, contrastThreshold=0.02, edgeThreshold=20) + self.matcher = cv2.BFMatcher(cv2.NORM_L2) + + elif self.method == 'ecc': + number_of_iterations = 5000 + termination_eps = 1e-6 + self.warp_mode = cv2.MOTION_EUCLIDEAN + self.criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, number_of_iterations, termination_eps) + + elif self.method == 'sparseOptFlow': + self.feature_params = dict(maxCorners=1000, + qualityLevel=0.01, + minDistance=1, + blockSize=3, + useHarrisDetector=False, + k=0.04) + + elif self.method in ['none', 'None', None]: + self.method = None + else: + raise ValueError(f'Error: Unknown GMC method:{method}') + + self.prevFrame = None + self.prevKeyPoints = None + self.prevDescriptors = None + + self.initializedFirstFrame = False + + def apply(self, raw_frame, detections=None): + """Apply object detection on a raw frame using specified method.""" + if self.method in ['orb', 'sift']: + return self.applyFeatures(raw_frame, detections) + elif self.method == 'ecc': + return self.applyEcc(raw_frame, detections) + elif self.method == 'sparseOptFlow': + return self.applySparseOptFlow(raw_frame, detections) + else: + return np.eye(2, 3) + + def applyEcc(self, raw_frame, detections=None): + """Initialize.""" + height, width, _ = raw_frame.shape + frame = cv2.cvtColor(raw_frame, cv2.COLOR_BGR2GRAY) + H = np.eye(2, 3, dtype=np.float32) + + # Downscale image (TODO: consider using pyramids) + if self.downscale > 1.0: + frame = cv2.GaussianBlur(frame, (3, 3), 1.5) + frame = cv2.resize(frame, (width // self.downscale, height // self.downscale)) + width = width // self.downscale + height = height // self.downscale + + # Handle first frame + if not self.initializedFirstFrame: + # Initialize data + self.prevFrame = frame.copy() + + # Initialization done + self.initializedFirstFrame = True + + return H + + # Run the ECC algorithm. The results are stored in warp_matrix. + # (cc, H) = cv2.findTransformECC(self.prevFrame, frame, H, self.warp_mode, self.criteria) + try: + (cc, H) = cv2.findTransformECC(self.prevFrame, frame, H, self.warp_mode, self.criteria, None, 1) + except Exception as e: + LOGGER.warning(f'WARNING: find transform failed. Set warp as identity {e}') + + return H + + def applyFeatures(self, raw_frame, detections=None): + """Initialize.""" + height, width, _ = raw_frame.shape + frame = cv2.cvtColor(raw_frame, cv2.COLOR_BGR2GRAY) + H = np.eye(2, 3) + + # Downscale image (TODO: consider using pyramids) + if self.downscale > 1.0: + # frame = cv2.GaussianBlur(frame, (3, 3), 1.5) + frame = cv2.resize(frame, (width // self.downscale, height // self.downscale)) + width = width // self.downscale + height = height // self.downscale + + # Find the keypoints + mask = np.zeros_like(frame) + # mask[int(0.05 * height): int(0.95 * height), int(0.05 * width): int(0.95 * width)] = 255 + mask[int(0.02 * height):int(0.98 * height), int(0.02 * width):int(0.98 * width)] = 255 + if detections is not None: + for det in detections: + tlbr = (det[:4] / self.downscale).astype(np.int_) + mask[tlbr[1]:tlbr[3], tlbr[0]:tlbr[2]] = 0 + + keypoints = self.detector.detect(frame, mask) + + # Compute the descriptors + keypoints, descriptors = self.extractor.compute(frame, keypoints) + + # Handle first frame + if not self.initializedFirstFrame: + # Initialize data + self.prevFrame = frame.copy() + self.prevKeyPoints = copy.copy(keypoints) + self.prevDescriptors = copy.copy(descriptors) + + # Initialization done + self.initializedFirstFrame = True + + return H + + # Match descriptors. + knnMatches = self.matcher.knnMatch(self.prevDescriptors, descriptors, 2) + + # Filtered matches based on smallest spatial distance + matches = [] + spatialDistances = [] + + maxSpatialDistance = 0.25 * np.array([width, height]) + + # Handle empty matches case + if len(knnMatches) == 0: + # Store to next iteration + self.prevFrame = frame.copy() + self.prevKeyPoints = copy.copy(keypoints) + self.prevDescriptors = copy.copy(descriptors) + + return H + + for m, n in knnMatches: + if m.distance < 0.9 * n.distance: + prevKeyPointLocation = self.prevKeyPoints[m.queryIdx].pt + currKeyPointLocation = keypoints[m.trainIdx].pt + + spatialDistance = (prevKeyPointLocation[0] - currKeyPointLocation[0], + prevKeyPointLocation[1] - currKeyPointLocation[1]) + + if (np.abs(spatialDistance[0]) < maxSpatialDistance[0]) and \ + (np.abs(spatialDistance[1]) < maxSpatialDistance[1]): + spatialDistances.append(spatialDistance) + matches.append(m) + + meanSpatialDistances = np.mean(spatialDistances, 0) + stdSpatialDistances = np.std(spatialDistances, 0) + + inliers = (spatialDistances - meanSpatialDistances) < 2.5 * stdSpatialDistances + + goodMatches = [] + prevPoints = [] + currPoints = [] + for i in range(len(matches)): + if inliers[i, 0] and inliers[i, 1]: + goodMatches.append(matches[i]) + prevPoints.append(self.prevKeyPoints[matches[i].queryIdx].pt) + currPoints.append(keypoints[matches[i].trainIdx].pt) + + prevPoints = np.array(prevPoints) + currPoints = np.array(currPoints) + + # Draw the keypoint matches on the output image + # if False: + # import matplotlib.pyplot as plt + # matches_img = np.hstack((self.prevFrame, frame)) + # matches_img = cv2.cvtColor(matches_img, cv2.COLOR_GRAY2BGR) + # W = np.size(self.prevFrame, 1) + # for m in goodMatches: + # prev_pt = np.array(self.prevKeyPoints[m.queryIdx].pt, dtype=np.int_) + # curr_pt = np.array(keypoints[m.trainIdx].pt, dtype=np.int_) + # curr_pt[0] += W + # color = np.random.randint(0, 255, 3) + # color = (int(color[0]), int(color[1]), int(color[2])) + # + # matches_img = cv2.line(matches_img, prev_pt, curr_pt, tuple(color), 1, cv2.LINE_AA) + # matches_img = cv2.circle(matches_img, prev_pt, 2, tuple(color), -1) + # matches_img = cv2.circle(matches_img, curr_pt, 2, tuple(color), -1) + # + # plt.figure() + # plt.imshow(matches_img) + # plt.show() + + # Find rigid matrix + if (np.size(prevPoints, 0) > 4) and (np.size(prevPoints, 0) == np.size(prevPoints, 0)): + H, inliers = cv2.estimateAffinePartial2D(prevPoints, currPoints, cv2.RANSAC) + + # Handle downscale + if self.downscale > 1.0: + H[0, 2] *= self.downscale + H[1, 2] *= self.downscale + else: + LOGGER.warning('WARNING: not enough matching points') + + # Store to next iteration + self.prevFrame = frame.copy() + self.prevKeyPoints = copy.copy(keypoints) + self.prevDescriptors = copy.copy(descriptors) + + return H + + def applySparseOptFlow(self, raw_frame, detections=None): + """Initialize.""" + height, width, _ = raw_frame.shape + frame = cv2.cvtColor(raw_frame, cv2.COLOR_BGR2GRAY) + H = np.eye(2, 3) + + # Downscale image + if self.downscale > 1.0: + # frame = cv2.GaussianBlur(frame, (3, 3), 1.5) + frame = cv2.resize(frame, (width // self.downscale, height // self.downscale)) + + # Find the keypoints + keypoints = cv2.goodFeaturesToTrack(frame, mask=None, **self.feature_params) + + # Handle first frame + if not self.initializedFirstFrame: + # Initialize data + self.prevFrame = frame.copy() + self.prevKeyPoints = copy.copy(keypoints) + + # Initialization done + self.initializedFirstFrame = True + + return H + + # Find correspondences + matchedKeypoints, status, err = cv2.calcOpticalFlowPyrLK(self.prevFrame, frame, self.prevKeyPoints, None) + + # Leave good correspondences only + prevPoints = [] + currPoints = [] + + for i in range(len(status)): + if status[i]: + prevPoints.append(self.prevKeyPoints[i]) + currPoints.append(matchedKeypoints[i]) + + prevPoints = np.array(prevPoints) + currPoints = np.array(currPoints) + + # Find rigid matrix + if (np.size(prevPoints, 0) > 4) and (np.size(prevPoints, 0) == np.size(prevPoints, 0)): + H, inliers = cv2.estimateAffinePartial2D(prevPoints, currPoints, cv2.RANSAC) + + # Handle downscale + if self.downscale > 1.0: + H[0, 2] *= self.downscale + H[1, 2] *= self.downscale + else: + LOGGER.warning('WARNING: not enough matching points') + + # Store to next iteration + self.prevFrame = frame.copy() + self.prevKeyPoints = copy.copy(keypoints) + + return H diff --git a/downloads/ultralytics-main/ultralytics/trackers/utils/kalman_filter.py b/downloads/ultralytics-main/ultralytics/trackers/utils/kalman_filter.py new file mode 100644 index 000000000..9527ede79 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/trackers/utils/kalman_filter.py @@ -0,0 +1,368 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import numpy as np +import scipy.linalg + + +class KalmanFilterXYAH: + """ + For bytetrack. A simple Kalman filter for tracking bounding boxes in image space. + + The 8-dimensional state space (x, y, a, h, vx, vy, va, vh) contains the bounding box center position (x, y), + aspect ratio a, height h, and their respective velocities. + + Object motion follows a constant velocity model. The bounding box location (x, y, a, h) is taken as direct + observation of the state space (linear observation model). + """ + + def __init__(self): + """Initialize Kalman filter model matrices with motion and observation uncertainty weights.""" + ndim, dt = 4, 1. + + # Create Kalman filter model matrices. + self._motion_mat = np.eye(2 * ndim, 2 * ndim) + for i in range(ndim): + self._motion_mat[i, ndim + i] = dt + self._update_mat = np.eye(ndim, 2 * ndim) + + # Motion and observation uncertainty are chosen relative to the current state estimate. These weights control + # the amount of uncertainty in the model. This is a bit hacky. + self._std_weight_position = 1. / 20 + self._std_weight_velocity = 1. / 160 + + def initiate(self, measurement): + """ + Create track from unassociated measurement. + + Parameters + ---------- + measurement : ndarray + Bounding box coordinates (x, y, a, h) with center position (x, y), + aspect ratio a, and height h. + + Returns + ------- + (ndarray, ndarray) + Returns the mean vector (8 dimensional) and covariance matrix (8x8 + dimensional) of the new track. Unobserved velocities are initialized + to 0 mean. + """ + mean_pos = measurement + mean_vel = np.zeros_like(mean_pos) + mean = np.r_[mean_pos, mean_vel] + + std = [ + 2 * self._std_weight_position * measurement[3], 2 * self._std_weight_position * measurement[3], 1e-2, + 2 * self._std_weight_position * measurement[3], 10 * self._std_weight_velocity * measurement[3], + 10 * self._std_weight_velocity * measurement[3], 1e-5, 10 * self._std_weight_velocity * measurement[3]] + covariance = np.diag(np.square(std)) + return mean, covariance + + def predict(self, mean, covariance): + """ + Run Kalman filter prediction step. + + Parameters + ---------- + mean : ndarray + The 8 dimensional mean vector of the object state at the previous time step. + covariance : ndarray + The 8x8 dimensional covariance matrix of the object state at the previous time step. + + Returns + ------- + (ndarray, ndarray) + Returns the mean vector and covariance matrix of the predicted state. Unobserved velocities are + initialized to 0 mean. + """ + std_pos = [ + self._std_weight_position * mean[3], self._std_weight_position * mean[3], 1e-2, + self._std_weight_position * mean[3]] + std_vel = [ + self._std_weight_velocity * mean[3], self._std_weight_velocity * mean[3], 1e-5, + self._std_weight_velocity * mean[3]] + motion_cov = np.diag(np.square(np.r_[std_pos, std_vel])) + + # mean = np.dot(self._motion_mat, mean) + mean = np.dot(mean, self._motion_mat.T) + covariance = np.linalg.multi_dot((self._motion_mat, covariance, self._motion_mat.T)) + motion_cov + + return mean, covariance + + def project(self, mean, covariance): + """ + Project state distribution to measurement space. + + Parameters + ---------- + mean : ndarray + The state's mean vector (8 dimensional array). + covariance : ndarray + The state's covariance matrix (8x8 dimensional). + + Returns + ------- + (ndarray, ndarray) + Returns the projected mean and covariance matrix of the given state estimate. + """ + std = [ + self._std_weight_position * mean[3], self._std_weight_position * mean[3], 1e-1, + self._std_weight_position * mean[3]] + innovation_cov = np.diag(np.square(std)) + + mean = np.dot(self._update_mat, mean) + covariance = np.linalg.multi_dot((self._update_mat, covariance, self._update_mat.T)) + return mean, covariance + innovation_cov + + def multi_predict(self, mean, covariance): + """ + Run Kalman filter prediction step (Vectorized version). + + Parameters + ---------- + mean : ndarray + The Nx8 dimensional mean matrix of the object states at the previous time step. + covariance : ndarray + The Nx8x8 dimensional covariance matrix of the object states at the previous time step. + + Returns + ------- + (ndarray, ndarray) + Returns the mean vector and covariance matrix of the predicted state. Unobserved velocities are + initialized to 0 mean. + """ + std_pos = [ + self._std_weight_position * mean[:, 3], self._std_weight_position * mean[:, 3], + 1e-2 * np.ones_like(mean[:, 3]), self._std_weight_position * mean[:, 3]] + std_vel = [ + self._std_weight_velocity * mean[:, 3], self._std_weight_velocity * mean[:, 3], + 1e-5 * np.ones_like(mean[:, 3]), self._std_weight_velocity * mean[:, 3]] + sqr = np.square(np.r_[std_pos, std_vel]).T + + motion_cov = [np.diag(sqr[i]) for i in range(len(mean))] + motion_cov = np.asarray(motion_cov) + + mean = np.dot(mean, self._motion_mat.T) + left = np.dot(self._motion_mat, covariance).transpose((1, 0, 2)) + covariance = np.dot(left, self._motion_mat.T) + motion_cov + + return mean, covariance + + def update(self, mean, covariance, measurement): + """ + Run Kalman filter correction step. + + Parameters + ---------- + mean : ndarray + The predicted state's mean vector (8 dimensional). + covariance : ndarray + The state's covariance matrix (8x8 dimensional). + measurement : ndarray + The 4 dimensional measurement vector (x, y, a, h), where (x, y) is the center position, a the aspect + ratio, and h the height of the bounding box. + + Returns + ------- + (ndarray, ndarray) + Returns the measurement-corrected state distribution. + """ + projected_mean, projected_cov = self.project(mean, covariance) + + chol_factor, lower = scipy.linalg.cho_factor(projected_cov, lower=True, check_finite=False) + kalman_gain = scipy.linalg.cho_solve((chol_factor, lower), + np.dot(covariance, self._update_mat.T).T, + check_finite=False).T + innovation = measurement - projected_mean + + new_mean = mean + np.dot(innovation, kalman_gain.T) + new_covariance = covariance - np.linalg.multi_dot((kalman_gain, projected_cov, kalman_gain.T)) + return new_mean, new_covariance + + def gating_distance(self, mean, covariance, measurements, only_position=False, metric='maha'): + """ + Compute gating distance between state distribution and measurements. A suitable distance threshold can be + obtained from `chi2inv95`. If `only_position` is False, the chi-square distribution has 4 degrees of + freedom, otherwise 2. + + Parameters + ---------- + mean : ndarray + Mean vector over the state distribution (8 dimensional). + covariance : ndarray + Covariance of the state distribution (8x8 dimensional). + measurements : ndarray + An Nx4 dimensional matrix of N measurements, each in format (x, y, a, h) where (x, y) is the bounding box + center position, a the aspect ratio, and h the height. + only_position : Optional[bool] + If True, distance computation is done with respect to the bounding box center position only. + + Returns + ------- + ndarray + Returns an array of length N, where the i-th element contains the squared Mahalanobis distance between + (mean, covariance) and `measurements[i]`. + """ + mean, covariance = self.project(mean, covariance) + if only_position: + mean, covariance = mean[:2], covariance[:2, :2] + measurements = measurements[:, :2] + + d = measurements - mean + if metric == 'gaussian': + return np.sum(d * d, axis=1) + elif metric == 'maha': + cholesky_factor = np.linalg.cholesky(covariance) + z = scipy.linalg.solve_triangular(cholesky_factor, d.T, lower=True, check_finite=False, overwrite_b=True) + return np.sum(z * z, axis=0) # square maha + else: + raise ValueError('invalid distance metric') + + +class KalmanFilterXYWH(KalmanFilterXYAH): + """ + For BoT-SORT. A simple Kalman filter for tracking bounding boxes in image space. + + The 8-dimensional state space (x, y, w, h, vx, vy, vw, vh) contains the bounding box center position (x, y), + width w, height h, and their respective velocities. + + Object motion follows a constant velocity model. The bounding box location (x, y, w, h) is taken as direct + observation of the state space (linear observation model). + """ + + def initiate(self, measurement): + """ + Create track from unassociated measurement. + + Parameters + ---------- + measurement : ndarray + Bounding box coordinates (x, y, w, h) with center position (x, y), width w, and height h. + + Returns + ------- + (ndarray, ndarray) + Returns the mean vector (8 dimensional) and covariance matrix (8x8 dimensional) of the new track. + Unobserved velocities are initialized to 0 mean. + """ + mean_pos = measurement + mean_vel = np.zeros_like(mean_pos) + mean = np.r_[mean_pos, mean_vel] + + std = [ + 2 * self._std_weight_position * measurement[2], 2 * self._std_weight_position * measurement[3], + 2 * self._std_weight_position * measurement[2], 2 * self._std_weight_position * measurement[3], + 10 * self._std_weight_velocity * measurement[2], 10 * self._std_weight_velocity * measurement[3], + 10 * self._std_weight_velocity * measurement[2], 10 * self._std_weight_velocity * measurement[3]] + covariance = np.diag(np.square(std)) + return mean, covariance + + def predict(self, mean, covariance): + """ + Run Kalman filter prediction step. + + Parameters + ---------- + mean : ndarray + The 8 dimensional mean vector of the object state at the previous time step. + covariance : ndarray + The 8x8 dimensional covariance matrix of the object state at the previous time step. + + Returns + ------- + (ndarray, ndarray) + Returns the mean vector and covariance matrix of the predicted state. Unobserved velocities are + initialized to 0 mean. + """ + std_pos = [ + self._std_weight_position * mean[2], self._std_weight_position * mean[3], + self._std_weight_position * mean[2], self._std_weight_position * mean[3]] + std_vel = [ + self._std_weight_velocity * mean[2], self._std_weight_velocity * mean[3], + self._std_weight_velocity * mean[2], self._std_weight_velocity * mean[3]] + motion_cov = np.diag(np.square(np.r_[std_pos, std_vel])) + + mean = np.dot(mean, self._motion_mat.T) + covariance = np.linalg.multi_dot((self._motion_mat, covariance, self._motion_mat.T)) + motion_cov + + return mean, covariance + + def project(self, mean, covariance): + """ + Project state distribution to measurement space. + + Parameters + ---------- + mean : ndarray + The state's mean vector (8 dimensional array). + covariance : ndarray + The state's covariance matrix (8x8 dimensional). + + Returns + ------- + (ndarray, ndarray) + Returns the projected mean and covariance matrix of the given state estimate. + """ + std = [ + self._std_weight_position * mean[2], self._std_weight_position * mean[3], + self._std_weight_position * mean[2], self._std_weight_position * mean[3]] + innovation_cov = np.diag(np.square(std)) + + mean = np.dot(self._update_mat, mean) + covariance = np.linalg.multi_dot((self._update_mat, covariance, self._update_mat.T)) + return mean, covariance + innovation_cov + + def multi_predict(self, mean, covariance): + """ + Run Kalman filter prediction step (Vectorized version). + + Parameters + ---------- + mean : ndarray + The Nx8 dimensional mean matrix of the object states at the previous time step. + covariance : ndarray + The Nx8x8 dimensional covariance matrix of the object states at the previous time step. + + Returns + ------- + (ndarray, ndarray) + Returns the mean vector and covariance matrix of the predicted state. Unobserved velocities are + initialized to 0 mean. + """ + std_pos = [ + self._std_weight_position * mean[:, 2], self._std_weight_position * mean[:, 3], + self._std_weight_position * mean[:, 2], self._std_weight_position * mean[:, 3]] + std_vel = [ + self._std_weight_velocity * mean[:, 2], self._std_weight_velocity * mean[:, 3], + self._std_weight_velocity * mean[:, 2], self._std_weight_velocity * mean[:, 3]] + sqr = np.square(np.r_[std_pos, std_vel]).T + + motion_cov = [np.diag(sqr[i]) for i in range(len(mean))] + motion_cov = np.asarray(motion_cov) + + mean = np.dot(mean, self._motion_mat.T) + left = np.dot(self._motion_mat, covariance).transpose((1, 0, 2)) + covariance = np.dot(left, self._motion_mat.T) + motion_cov + + return mean, covariance + + def update(self, mean, covariance, measurement): + """ + Run Kalman filter correction step. + + Parameters + ---------- + mean : ndarray + The predicted state's mean vector (8 dimensional). + covariance : ndarray + The state's covariance matrix (8x8 dimensional). + measurement : ndarray + The 4 dimensional measurement vector (x, y, w, h), where (x, y) is the center position, w the width, + and h the height of the bounding box. + + Returns + ------- + (ndarray, ndarray) + Returns the measurement-corrected state distribution. + """ + return super().update(mean, covariance, measurement) diff --git a/downloads/ultralytics-main/ultralytics/trackers/utils/matching.py b/downloads/ultralytics-main/ultralytics/trackers/utils/matching.py new file mode 100644 index 000000000..f2ee75e54 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/trackers/utils/matching.py @@ -0,0 +1,126 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import numpy as np +import scipy +from scipy.spatial.distance import cdist + +from ultralytics.utils.metrics import bbox_ioa + +try: + import lap # for linear_assignment + + assert lap.__version__ # verify package is not directory +except (ImportError, AssertionError, AttributeError): + from ultralytics.utils.checks import check_requirements + + check_requirements('lapx>=0.5.2') # update to lap package from https://github.com/rathaROG/lapx + import lap + + +def linear_assignment(cost_matrix, thresh, use_lap=True): + """ + Perform linear assignment using scipy or lap.lapjv. + + Args: + cost_matrix (np.ndarray): The matrix containing cost values for assignments. + thresh (float): Threshold for considering an assignment valid. + use_lap (bool, optional): Whether to use lap.lapjv. Defaults to True. + + Returns: + (tuple): Tuple containing matched indices, unmatched indices from 'a', and unmatched indices from 'b'. + """ + + if cost_matrix.size == 0: + return np.empty((0, 2), dtype=int), tuple(range(cost_matrix.shape[0])), tuple(range(cost_matrix.shape[1])) + + if use_lap: + # https://github.com/gatagat/lap + _, x, y = lap.lapjv(cost_matrix, extend_cost=True, cost_limit=thresh) + matches = [[ix, mx] for ix, mx in enumerate(x) if mx >= 0] + unmatched_a = np.where(x < 0)[0] + unmatched_b = np.where(y < 0)[0] + else: + # https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.linear_sum_assignment.html + x, y = scipy.optimize.linear_sum_assignment(cost_matrix) # row x, col y + matches = np.asarray([[x[i], y[i]] for i in range(len(x)) if cost_matrix[x[i], y[i]] <= thresh]) + if len(matches) == 0: + unmatched_a = list(np.arange(cost_matrix.shape[0])) + unmatched_b = list(np.arange(cost_matrix.shape[1])) + else: + unmatched_a = list(set(np.arange(cost_matrix.shape[0])) - set(matches[:, 0])) + unmatched_b = list(set(np.arange(cost_matrix.shape[1])) - set(matches[:, 1])) + + return matches, unmatched_a, unmatched_b + + +def iou_distance(atracks, btracks): + """ + Compute cost based on Intersection over Union (IoU) between tracks. + + Args: + atracks (list[STrack] | list[np.ndarray]): List of tracks 'a' or bounding boxes. + btracks (list[STrack] | list[np.ndarray]): List of tracks 'b' or bounding boxes. + + Returns: + (np.ndarray): Cost matrix computed based on IoU. + """ + + if (len(atracks) > 0 and isinstance(atracks[0], np.ndarray)) \ + or (len(btracks) > 0 and isinstance(btracks[0], np.ndarray)): + atlbrs = atracks + btlbrs = btracks + else: + atlbrs = [track.tlbr for track in atracks] + btlbrs = [track.tlbr for track in btracks] + + ious = np.zeros((len(atlbrs), len(btlbrs)), dtype=np.float32) + if len(atlbrs) and len(btlbrs): + ious = bbox_ioa(np.ascontiguousarray(atlbrs, dtype=np.float32), + np.ascontiguousarray(btlbrs, dtype=np.float32), + iou=True) + return 1 - ious # cost matrix + + +def embedding_distance(tracks, detections, metric='cosine'): + """ + Compute distance between tracks and detections based on embeddings. + + Args: + tracks (list[STrack]): List of tracks. + detections (list[BaseTrack]): List of detections. + metric (str, optional): Metric for distance computation. Defaults to 'cosine'. + + Returns: + (np.ndarray): Cost matrix computed based on embeddings. + """ + + cost_matrix = np.zeros((len(tracks), len(detections)), dtype=np.float32) + if cost_matrix.size == 0: + return cost_matrix + det_features = np.asarray([track.curr_feat for track in detections], dtype=np.float32) + # for i, track in enumerate(tracks): + # cost_matrix[i, :] = np.maximum(0.0, cdist(track.smooth_feat.reshape(1,-1), det_features, metric)) + track_features = np.asarray([track.smooth_feat for track in tracks], dtype=np.float32) + cost_matrix = np.maximum(0.0, cdist(track_features, det_features, metric)) # Normalized features + return cost_matrix + + +def fuse_score(cost_matrix, detections): + """ + Fuses cost matrix with detection scores to produce a single similarity matrix. + + Args: + cost_matrix (np.ndarray): The matrix containing cost values for assignments. + detections (list[BaseTrack]): List of detections with scores. + + Returns: + (np.ndarray): Fused similarity matrix. + """ + + if cost_matrix.size == 0: + return cost_matrix + iou_sim = 1 - cost_matrix + det_scores = np.array([det.score for det in detections]) + det_scores = np.expand_dims(det_scores, axis=0).repeat(cost_matrix.shape[0], axis=0) + fuse_sim = iou_sim * det_scores + return 1 - fuse_sim # fuse_cost diff --git a/downloads/ultralytics-main/ultralytics/utils/__init__.py b/downloads/ultralytics-main/ultralytics/utils/__init__.py new file mode 100644 index 000000000..b9d3bfb99 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/__init__.py @@ -0,0 +1,860 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import contextlib +import inspect +import logging.config +import os +import platform +import re +import subprocess +import sys +import threading +import urllib +import uuid +from pathlib import Path +from types import SimpleNamespace +from typing import Union + +import cv2 +import matplotlib.pyplot as plt +import numpy as np +import torch +import yaml + +from ultralytics import __version__ + +# PyTorch Multi-GPU DDP Constants +RANK = int(os.getenv('RANK', -1)) +LOCAL_RANK = int(os.getenv('LOCAL_RANK', -1)) # https://pytorch.org/docs/stable/elastic/run.html + +# Other Constants +FILE = Path(__file__).resolve() +ROOT = FILE.parents[1] # YOLO +ASSETS = ROOT / 'assets' # default images +DEFAULT_CFG_PATH = ROOT / 'cfg/default.yaml' +NUM_THREADS = min(8, max(1, os.cpu_count() - 1)) # number of YOLOv5 multiprocessing threads +AUTOINSTALL = str(os.getenv('YOLO_AUTOINSTALL', True)).lower() == 'true' # global auto-install mode +VERBOSE = str(os.getenv('YOLO_VERBOSE', True)).lower() == 'true' # global verbose mode +TQDM_BAR_FORMAT = '{l_bar}{bar:10}{r_bar}' # tqdm bar format +LOGGING_NAME = 'ultralytics' +MACOS, LINUX, WINDOWS = (platform.system() == x for x in ['Darwin', 'Linux', 'Windows']) # environment booleans +ARM64 = platform.machine() in ('arm64', 'aarch64') # ARM64 booleans +HELP_MSG = \ + """ + Usage examples for running YOLOv8: + + 1. Install the ultralytics package: + + pip install ultralytics + + 2. Use the Python SDK: + + from ultralytics import YOLO + + # Load a model + model = YOLO('yolov8n.yaml') # build a new model from scratch + model = YOLO("yolov8n.pt") # load a pretrained model (recommended for training) + + # Use the model + results = model.train(data="coco128.yaml", epochs=3) # train the model + results = model.val() # evaluate model performance on the validation set + results = model('https://ultralytics.com/images/bus.jpg') # predict on an image + success = model.export(format='onnx') # export the model to ONNX format + + 3. Use the command line interface (CLI): + + YOLOv8 'yolo' CLI commands use the following syntax: + + yolo TASK MODE ARGS + + Where TASK (optional) is one of [detect, segment, classify] + MODE (required) is one of [train, val, predict, export] + ARGS (optional) are any number of custom 'arg=value' pairs like 'imgsz=320' that override defaults. + See all ARGS at https://docs.ultralytics.com/usage/cfg or with 'yolo cfg' + + - Train a detection model for 10 epochs with an initial learning_rate of 0.01 + yolo detect train data=coco128.yaml model=yolov8n.pt epochs=10 lr0=0.01 + + - Predict a YouTube video using a pretrained segmentation model at image size 320: + yolo segment predict model=yolov8n-seg.pt source='https://youtu.be/Zgi9g1ksQHc' imgsz=320 + + - Val a pretrained detection model at batch-size 1 and image size 640: + yolo detect val model=yolov8n.pt data=coco128.yaml batch=1 imgsz=640 + + - Export a YOLOv8n classification model to ONNX format at image size 224 by 128 (no TASK required) + yolo export model=yolov8n-cls.pt format=onnx imgsz=224,128 + + - Run special commands: + yolo help + yolo checks + yolo version + yolo settings + yolo copy-cfg + yolo cfg + + Docs: https://docs.ultralytics.com + Community: https://community.ultralytics.com + GitHub: https://github.com/ultralytics/ultralytics + """ + +# Settings +torch.set_printoptions(linewidth=320, precision=4, profile='default') +np.set_printoptions(linewidth=320, formatter={'float_kind': '{:11.5g}'.format}) # format short g, %precision=5 +cv2.setNumThreads(0) # prevent OpenCV from multithreading (incompatible with PyTorch DataLoader) +os.environ['NUMEXPR_MAX_THREADS'] = str(NUM_THREADS) # NumExpr max threads +os.environ['CUBLAS_WORKSPACE_CONFIG'] = ':4096:8' # for deterministic training +os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' # suppress verbose TF compiler warnings in Colab + + +class SimpleClass: + """ + Ultralytics SimpleClass is a base class providing helpful string representation, error reporting, and attribute + access methods for easier debugging and usage. + """ + + def __str__(self): + """Return a human-readable string representation of the object.""" + attr = [] + for a in dir(self): + v = getattr(self, a) + if not callable(v) and not a.startswith('_'): + if isinstance(v, SimpleClass): + # Display only the module and class name for subclasses + s = f'{a}: {v.__module__}.{v.__class__.__name__} object' + else: + s = f'{a}: {repr(v)}' + attr.append(s) + return f'{self.__module__}.{self.__class__.__name__} object with attributes:\n\n' + '\n'.join(attr) + + def __repr__(self): + """Return a machine-readable string representation of the object.""" + return self.__str__() + + def __getattr__(self, attr): + """Custom attribute access error message with helpful information.""" + name = self.__class__.__name__ + raise AttributeError(f"'{name}' object has no attribute '{attr}'. See valid attributes below.\n{self.__doc__}") + + +class IterableSimpleNamespace(SimpleNamespace): + """ + Ultralytics IterableSimpleNamespace is an extension class of SimpleNamespace that adds iterable functionality and + enables usage with dict() and for loops. + """ + + def __iter__(self): + """Return an iterator of key-value pairs from the namespace's attributes.""" + return iter(vars(self).items()) + + def __str__(self): + """Return a human-readable string representation of the object.""" + return '\n'.join(f'{k}={v}' for k, v in vars(self).items()) + + def __getattr__(self, attr): + """Custom attribute access error message with helpful information.""" + name = self.__class__.__name__ + raise AttributeError(f""" + '{name}' object has no attribute '{attr}'. This may be caused by a modified or out of date ultralytics + 'default.yaml' file.\nPlease update your code with 'pip install -U ultralytics' and if necessary replace + {DEFAULT_CFG_PATH} with the latest version from + https://github.com/ultralytics/ultralytics/blob/main/ultralytics/cfg/default.yaml + """) + + def get(self, key, default=None): + """Return the value of the specified key if it exists; otherwise, return the default value.""" + return getattr(self, key, default) + + +def plt_settings(rcparams=None, backend='Agg'): + """ + Decorator to temporarily set rc parameters and the backend for a plotting function. + + Example: + decorator: @plt_settings({"font.size": 12}) + context manager: with plt_settings({"font.size": 12}): + + Args: + rcparams (dict): Dictionary of rc parameters to set. + backend (str, optional): Name of the backend to use. Defaults to 'Agg'. + + Returns: + (Callable): Decorated function with temporarily set rc parameters and backend. This decorator can be + applied to any function that needs to have specific matplotlib rc parameters and backend for its execution. + """ + + if rcparams is None: + rcparams = {'font.size': 11} + + def decorator(func): + """Decorator to apply temporary rc parameters and backend to a function.""" + + def wrapper(*args, **kwargs): + """Sets rc parameters and backend, calls the original function, and restores the settings.""" + original_backend = plt.get_backend() + plt.switch_backend(backend) + + with plt.rc_context(rcparams): + result = func(*args, **kwargs) + + plt.switch_backend(original_backend) + return result + + return wrapper + + return decorator + + +def set_logging(name=LOGGING_NAME, verbose=True): + """Sets up logging for the given name.""" + rank = int(os.getenv('RANK', -1)) # rank in world for Multi-GPU trainings + level = logging.INFO if verbose and rank in {-1, 0} else logging.ERROR + logging.config.dictConfig({ + 'version': 1, + 'disable_existing_loggers': False, + 'formatters': { + name: { + 'format': '%(message)s'}}, + 'handlers': { + name: { + 'class': 'logging.StreamHandler', + 'formatter': name, + 'level': level}}, + 'loggers': { + name: { + 'level': level, + 'handlers': [name], + 'propagate': False}}}) + + +def emojis(string=''): + """Return platform-dependent emoji-safe version of string.""" + return string.encode().decode('ascii', 'ignore') if WINDOWS else string + + +class EmojiFilter(logging.Filter): + """ + A custom logging filter class for removing emojis in log messages. + + This filter is particularly useful for ensuring compatibility with Windows terminals + that may not support the display of emojis in log messages. + """ + + def filter(self, record): + """Filter logs by emoji unicode characters on windows.""" + record.msg = emojis(record.msg) + return super().filter(record) + + +# Set logger +set_logging(LOGGING_NAME, verbose=VERBOSE) # run before defining LOGGER +LOGGER = logging.getLogger(LOGGING_NAME) # define globally (used in train.py, val.py, detect.py, etc.) +if WINDOWS: # emoji-safe logging + LOGGER.addFilter(EmojiFilter()) + + +class ThreadingLocked: + """ + A decorator class for ensuring thread-safe execution of a function or method. + This class can be used as a decorator to make sure that if the decorated function + is called from multiple threads, only one thread at a time will be able to execute the function. + + Attributes: + lock (threading.Lock): A lock object used to manage access to the decorated function. + + Example: + ```python + from ultralytics.utils import ThreadingLocked + + @ThreadingLocked() + def my_function(): + # Your code here + pass + ``` + """ + + def __init__(self): + self.lock = threading.Lock() + + def __call__(self, f): + from functools import wraps + + @wraps(f) + def decorated(*args, **kwargs): + with self.lock: + return f(*args, **kwargs) + + return decorated + + +def yaml_save(file='data.yaml', data=None): + """ + Save YAML data to a file. + + Args: + file (str, optional): File name. Default is 'data.yaml'. + data (dict): Data to save in YAML format. + + Returns: + (None): Data is saved to the specified file. + """ + if data is None: + data = {} + file = Path(file) + if not file.parent.exists(): + # Create parent directories if they don't exist + file.parent.mkdir(parents=True, exist_ok=True) + + # Convert Path objects to strings + for k, v in data.items(): + if isinstance(v, Path): + data[k] = str(v) + + # Dump data to file in YAML format + with open(file, 'w') as f: + yaml.safe_dump(data, f, sort_keys=False, allow_unicode=True) + + +def yaml_load(file='data.yaml', append_filename=False): + """ + Load YAML data from a file. + + Args: + file (str, optional): File name. Default is 'data.yaml'. + append_filename (bool): Add the YAML filename to the YAML dictionary. Default is False. + + Returns: + (dict): YAML data and file name. + """ + with open(file, errors='ignore', encoding='utf-8') as f: + s = f.read() # string + + # Remove special characters + if not s.isprintable(): + s = re.sub(r'[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\uD7FF\uE000-\uFFFD\U00010000-\U0010ffff]+', '', s) + + # Add YAML filename to dict and return + data = yaml.safe_load(s) or {} # always return a dict (yaml.safe_load() may return None for empty files) + if append_filename: + data['yaml_file'] = str(file) + return data + + +def yaml_print(yaml_file: Union[str, Path, dict]) -> None: + """ + Pretty prints a YAML file or a YAML-formatted dictionary. + + Args: + yaml_file: The file path of the YAML file or a YAML-formatted dictionary. + + Returns: + None + """ + yaml_dict = yaml_load(yaml_file) if isinstance(yaml_file, (str, Path)) else yaml_file + dump = yaml.dump(yaml_dict, sort_keys=False, allow_unicode=True) + LOGGER.info(f"Printing '{colorstr('bold', 'black', yaml_file)}'\n\n{dump}") + + +# Default configuration +DEFAULT_CFG_DICT = yaml_load(DEFAULT_CFG_PATH) +for k, v in DEFAULT_CFG_DICT.items(): + if isinstance(v, str) and v.lower() == 'none': + DEFAULT_CFG_DICT[k] = None +DEFAULT_CFG_KEYS = DEFAULT_CFG_DICT.keys() +DEFAULT_CFG = IterableSimpleNamespace(**DEFAULT_CFG_DICT) + + +def is_ubuntu() -> bool: + """ + Check if the OS is Ubuntu. + + Returns: + (bool): True if OS is Ubuntu, False otherwise. + """ + with contextlib.suppress(FileNotFoundError): + with open('/etc/os-release') as f: + return 'ID=ubuntu' in f.read() + return False + + +def is_colab(): + """ + Check if the current script is running inside a Google Colab notebook. + + Returns: + (bool): True if running inside a Colab notebook, False otherwise. + """ + return 'COLAB_RELEASE_TAG' in os.environ or 'COLAB_BACKEND_VERSION' in os.environ + + +def is_kaggle(): + """ + Check if the current script is running inside a Kaggle kernel. + + Returns: + (bool): True if running inside a Kaggle kernel, False otherwise. + """ + return os.environ.get('PWD') == '/kaggle/working' and os.environ.get('KAGGLE_URL_BASE') == 'https://www.kaggle.com' + + +def is_jupyter(): + """ + Check if the current script is running inside a Jupyter Notebook. + Verified on Colab, Jupyterlab, Kaggle, Paperspace. + + Returns: + (bool): True if running inside a Jupyter Notebook, False otherwise. + """ + with contextlib.suppress(Exception): + from IPython import get_ipython + return get_ipython() is not None + return False + + +def is_docker() -> bool: + """ + Determine if the script is running inside a Docker container. + + Returns: + (bool): True if the script is running inside a Docker container, False otherwise. + """ + file = Path('/proc/self/cgroup') + if file.exists(): + with open(file) as f: + return 'docker' in f.read() + else: + return False + + +def is_online() -> bool: + """ + Check internet connectivity by attempting to connect to a known online host. + + Returns: + (bool): True if connection is successful, False otherwise. + """ + import socket + + for host in '1.1.1.1', '8.8.8.8', '223.5.5.5': # Cloudflare, Google, AliDNS: + try: + test_connection = socket.create_connection(address=(host, 53), timeout=2) + except (socket.timeout, socket.gaierror, OSError): + continue + else: + # If the connection was successful, close it to avoid a ResourceWarning + test_connection.close() + return True + return False + + +ONLINE = is_online() + + +def is_pip_package(filepath: str = __name__) -> bool: + """ + Determines if the file at the given filepath is part of a pip package. + + Args: + filepath (str): The filepath to check. + + Returns: + (bool): True if the file is part of a pip package, False otherwise. + """ + import importlib.util + + # Get the spec for the module + spec = importlib.util.find_spec(filepath) + + # Return whether the spec is not None and the origin is not None (indicating it is a package) + return spec is not None and spec.origin is not None + + +def is_dir_writeable(dir_path: Union[str, Path]) -> bool: + """ + Check if a directory is writeable. + + Args: + dir_path (str | Path): The path to the directory. + + Returns: + (bool): True if the directory is writeable, False otherwise. + """ + return os.access(str(dir_path), os.W_OK) + + +def is_pytest_running(): + """ + Determines whether pytest is currently running or not. + + Returns: + (bool): True if pytest is running, False otherwise. + """ + return ('PYTEST_CURRENT_TEST' in os.environ) or ('pytest' in sys.modules) or ('pytest' in Path(sys.argv[0]).stem) + + +def is_github_actions_ci() -> bool: + """ + Determine if the current environment is a GitHub Actions CI Python runner. + + Returns: + (bool): True if the current environment is a GitHub Actions CI Python runner, False otherwise. + """ + return 'GITHUB_ACTIONS' in os.environ and 'RUNNER_OS' in os.environ and 'RUNNER_TOOL_CACHE' in os.environ + + +def is_git_dir(): + """ + Determines whether the current file is part of a git repository. + If the current file is not part of a git repository, returns None. + + Returns: + (bool): True if current file is part of a git repository. + """ + return get_git_dir() is not None + + +def get_git_dir(): + """ + Determines whether the current file is part of a git repository and if so, returns the repository root directory. + If the current file is not part of a git repository, returns None. + + Returns: + (Path | None): Git root directory if found or None if not found. + """ + for d in Path(__file__).parents: + if (d / '.git').is_dir(): + return d + + +def get_git_origin_url(): + """ + Retrieves the origin URL of a git repository. + + Returns: + (str | None): The origin URL of the git repository or None if not git directory. + """ + if is_git_dir(): + with contextlib.suppress(subprocess.CalledProcessError): + origin = subprocess.check_output(['git', 'config', '--get', 'remote.origin.url']) + return origin.decode().strip() + + +def get_git_branch(): + """ + Returns the current git branch name. If not in a git repository, returns None. + + Returns: + (str | None): The current git branch name or None if not a git directory. + """ + if is_git_dir(): + with contextlib.suppress(subprocess.CalledProcessError): + origin = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD']) + return origin.decode().strip() + + +def get_default_args(func): + """Returns a dictionary of default arguments for a function. + + Args: + func (callable): The function to inspect. + + Returns: + (dict): A dictionary where each key is a parameter name, and each value is the default value of that parameter. + """ + signature = inspect.signature(func) + return {k: v.default for k, v in signature.parameters.items() if v.default is not inspect.Parameter.empty} + + +def get_ubuntu_version(): + """ + Retrieve the Ubuntu version if the OS is Ubuntu. + + Returns: + (str): Ubuntu version or None if not an Ubuntu OS. + """ + if is_ubuntu(): + with contextlib.suppress(FileNotFoundError, AttributeError): + with open('/etc/os-release') as f: + return re.search(r'VERSION_ID="(\d+\.\d+)"', f.read())[1] + + +def get_user_config_dir(sub_dir='Ultralytics'): + """ + Get the user config directory. + + Args: + sub_dir (str): The name of the subdirectory to create. + + Returns: + (Path): The path to the user config directory. + """ + # Return the appropriate config directory for each operating system + if WINDOWS: + path = Path.home() / 'AppData' / 'Roaming' / sub_dir + elif MACOS: # macOS + path = Path.home() / 'Library' / 'Application Support' / sub_dir + elif LINUX: + path = Path.home() / '.config' / sub_dir + else: + raise ValueError(f'Unsupported operating system: {platform.system()}') + + # GCP and AWS lambda fix, only /tmp is writeable + if not is_dir_writeable(path.parent): + LOGGER.warning(f"WARNING ⚠️ user config directory '{path}' is not writeable, defaulting to '/tmp' or CWD." + 'Alternatively you can define a YOLO_CONFIG_DIR environment variable for this path.') + path = Path('/tmp') / sub_dir if is_dir_writeable('/tmp') else Path().cwd() / sub_dir + + # Create the subdirectory if it does not exist + path.mkdir(parents=True, exist_ok=True) + + return path + + +USER_CONFIG_DIR = Path(os.getenv('YOLO_CONFIG_DIR') or get_user_config_dir()) # Ultralytics settings dir +SETTINGS_YAML = USER_CONFIG_DIR / 'settings.yaml' + + +def colorstr(*input): + """Colors a string https://en.wikipedia.org/wiki/ANSI_escape_code, i.e. colorstr('blue', 'hello world').""" + *args, string = input if len(input) > 1 else ('blue', 'bold', input[0]) # color arguments, string + colors = { + 'black': '\033[30m', # basic colors + 'red': '\033[31m', + 'green': '\033[32m', + 'yellow': '\033[33m', + 'blue': '\033[34m', + 'magenta': '\033[35m', + 'cyan': '\033[36m', + 'white': '\033[37m', + 'bright_black': '\033[90m', # bright colors + 'bright_red': '\033[91m', + 'bright_green': '\033[92m', + 'bright_yellow': '\033[93m', + 'bright_blue': '\033[94m', + 'bright_magenta': '\033[95m', + 'bright_cyan': '\033[96m', + 'bright_white': '\033[97m', + 'end': '\033[0m', # misc + 'bold': '\033[1m', + 'underline': '\033[4m'} + return ''.join(colors[x] for x in args) + f'{string}' + colors['end'] + + +class TryExcept(contextlib.ContextDecorator): + """YOLOv8 TryExcept class. Usage: @TryExcept() decorator or 'with TryExcept():' context manager.""" + + def __init__(self, msg='', verbose=True): + """Initialize TryExcept class with optional message and verbosity settings.""" + self.msg = msg + self.verbose = verbose + + def __enter__(self): + """Executes when entering TryExcept context, initializes instance.""" + pass + + def __exit__(self, exc_type, value, traceback): + """Defines behavior when exiting a 'with' block, prints error message if necessary.""" + if self.verbose and value: + print(emojis(f"{self.msg}{': ' if self.msg else ''}{value}")) + return True + + +def threaded(func): + """Multi-threads a target function and returns thread. Usage: @threaded decorator.""" + + def wrapper(*args, **kwargs): + """Multi-threads a given function and returns the thread.""" + thread = threading.Thread(target=func, args=args, kwargs=kwargs, daemon=True) + thread.start() + return thread + + return wrapper + + +def set_sentry(): + """ + Initialize the Sentry SDK for error tracking and reporting. Only used if sentry_sdk package is installed and + sync=True in settings. Run 'yolo settings' to see and update settings YAML file. + + Conditions required to send errors (ALL conditions must be met or no errors will be reported): + - sentry_sdk package is installed + - sync=True in YOLO settings + - pytest is not running + - running in a pip package installation + - running in a non-git directory + - running with rank -1 or 0 + - online environment + - CLI used to run package (checked with 'yolo' as the name of the main CLI command) + + The function also configures Sentry SDK to ignore KeyboardInterrupt and FileNotFoundError + exceptions and to exclude events with 'out of memory' in their exception message. + + Additionally, the function sets custom tags and user information for Sentry events. + """ + + def before_send(event, hint): + """ + Modify the event before sending it to Sentry based on specific exception types and messages. + + Args: + event (dict): The event dictionary containing information about the error. + hint (dict): A dictionary containing additional information about the error. + + Returns: + dict: The modified event or None if the event should not be sent to Sentry. + """ + if 'exc_info' in hint: + exc_type, exc_value, tb = hint['exc_info'] + if exc_type in (KeyboardInterrupt, FileNotFoundError) \ + or 'out of memory' in str(exc_value): + return None # do not send event + + event['tags'] = { + 'sys_argv': sys.argv[0], + 'sys_argv_name': Path(sys.argv[0]).name, + 'install': 'git' if is_git_dir() else 'pip' if is_pip_package() else 'other', + 'os': ENVIRONMENT} + return event + + if SETTINGS['sync'] and \ + RANK in (-1, 0) and \ + Path(sys.argv[0]).name == 'yolo' and \ + not TESTS_RUNNING and \ + ONLINE and \ + is_pip_package() and \ + not is_git_dir(): + + # If sentry_sdk package is not installed then return and do not use Sentry + try: + import sentry_sdk # noqa + except ImportError: + return + + sentry_sdk.init( + dsn='https://5ff1556b71594bfea135ff0203a0d290@o4504521589325824.ingest.sentry.io/4504521592406016', + debug=False, + traces_sample_rate=1.0, + release=__version__, + environment='production', # 'dev' or 'production' + before_send=before_send, + ignore_errors=[KeyboardInterrupt, FileNotFoundError]) + sentry_sdk.set_user({'id': SETTINGS['uuid']}) # SHA-256 anonymized UUID hash + + # Disable all sentry logging + for logger in 'sentry_sdk', 'sentry_sdk.errors': + logging.getLogger(logger).setLevel(logging.CRITICAL) + + +class SettingsManager(dict): + """ + Manages Ultralytics settings stored in a YAML file. + + Args: + file (str | Path): Path to the Ultralytics settings YAML file. Default is USER_CONFIG_DIR / 'settings.yaml'. + version (str): Settings version. In case of local version mismatch, new default settings will be saved. + """ + + def __init__(self, file=SETTINGS_YAML, version='0.0.4'): + import copy + import hashlib + + from ultralytics.utils.checks import check_version + from ultralytics.utils.torch_utils import torch_distributed_zero_first + + git_dir = get_git_dir() + root = git_dir or Path() + datasets_root = (root.parent if git_dir and is_dir_writeable(root.parent) else root).resolve() + + self.file = Path(file) + self.version = version + self.defaults = { + 'settings_version': version, + 'datasets_dir': str(datasets_root / 'datasets'), + 'weights_dir': str(root / 'weights'), + 'runs_dir': str(root / 'runs'), + 'uuid': hashlib.sha256(str(uuid.getnode()).encode()).hexdigest(), + 'sync': True, + 'api_key': '', + 'clearml': True, # integrations + 'comet': True, + 'dvc': True, + 'hub': True, + 'mlflow': True, + 'neptune': True, + 'raytune': True, + 'tensorboard': True, + 'wandb': True} + + super().__init__(copy.deepcopy(self.defaults)) + + with torch_distributed_zero_first(RANK): + if not self.file.exists(): + self.save() + + self.load() + correct_keys = self.keys() == self.defaults.keys() + correct_types = all(type(a) is type(b) for a, b in zip(self.values(), self.defaults.values())) + correct_version = check_version(self['settings_version'], self.version) + if not (correct_keys and correct_types and correct_version): + LOGGER.warning( + 'WARNING ⚠️ Ultralytics settings reset to default values. This may be due to a possible problem ' + 'with your settings or a recent ultralytics package update. ' + f"\nView settings with 'yolo settings' or at '{self.file}'" + "\nUpdate settings with 'yolo settings key=value', i.e. 'yolo settings runs_dir=path/to/dir'.") + self.reset() + + def load(self): + """Loads settings from the YAML file.""" + super().update(yaml_load(self.file)) + + def save(self): + """Saves the current settings to the YAML file.""" + yaml_save(self.file, dict(self)) + + def update(self, *args, **kwargs): + """Updates a setting value in the current settings.""" + super().update(*args, **kwargs) + self.save() + + def reset(self): + """Resets the settings to default and saves them.""" + self.clear() + self.update(self.defaults) + self.save() + + +def deprecation_warn(arg, new_arg, version=None): + """Issue a deprecation warning when a deprecated argument is used, suggesting an updated argument.""" + if not version: + version = float(__version__[:3]) + 0.2 # deprecate after 2nd major release + LOGGER.warning(f"WARNING ⚠️ '{arg}' is deprecated and will be removed in 'ultralytics {version}' in the future. " + f"Please use '{new_arg}' instead.") + + +def clean_url(url): + """Strip auth from URL, i.e. https://url.com/file.txt?auth -> https://url.com/file.txt.""" + url = Path(url).as_posix().replace(':/', '://') # Pathlib turns :// -> :/, as_posix() for Windows + return urllib.parse.unquote(url).split('?')[0] # '%2F' to '/', split https://url.com/file.txt?auth + + +def url2file(url): + """Convert URL to filename, i.e. https://url.com/file.txt?auth -> file.txt.""" + return Path(clean_url(url)).name + + +# Run below code on utils init ------------------------------------------------------------------------------------ + +# Check first-install steps +PREFIX = colorstr('Ultralytics: ') +SETTINGS = SettingsManager() # initialize settings +DATASETS_DIR = Path(SETTINGS['datasets_dir']) # global datasets directory +ENVIRONMENT = 'Colab' if is_colab() else 'Kaggle' if is_kaggle() else 'Jupyter' if is_jupyter() else \ + 'Docker' if is_docker() else platform.system() +TESTS_RUNNING = is_pytest_running() or is_github_actions_ci() +set_sentry() + +# Apply monkey patches if the script is being run from within the parent directory of the script's location +from .patches import imread, imshow, imwrite + +# torch.save = torch_save +if Path(inspect.stack()[0].filename).parent.parent.as_posix() in inspect.stack()[-1].filename: + cv2.imread, cv2.imwrite, cv2.imshow = imread, imwrite, imshow diff --git a/downloads/ultralytics-main/ultralytics/utils/autobatch.py b/downloads/ultralytics-main/ultralytics/utils/autobatch.py new file mode 100644 index 000000000..252f3db81 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/autobatch.py @@ -0,0 +1,90 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license +""" +Functions for estimating the best YOLO batch size to use a fraction of the available CUDA memory in PyTorch. +""" + +from copy import deepcopy + +import numpy as np +import torch + +from ultralytics.utils import DEFAULT_CFG, LOGGER, colorstr +from ultralytics.utils.torch_utils import profile + + +def check_train_batch_size(model, imgsz=640, amp=True): + """ + Check YOLO training batch size using the autobatch() function. + + Args: + model (torch.nn.Module): YOLO model to check batch size for. + imgsz (int): Image size used for training. + amp (bool): If True, use automatic mixed precision (AMP) for training. + + Returns: + (int): Optimal batch size computed using the autobatch() function. + """ + + with torch.cuda.amp.autocast(amp): + return autobatch(deepcopy(model).train(), imgsz) # compute optimal batch size + + +def autobatch(model, imgsz=640, fraction=0.67, batch_size=DEFAULT_CFG.batch): + """ + Automatically estimate the best YOLO batch size to use a fraction of the available CUDA memory. + + Args: + model (torch.nn.module): YOLO model to compute batch size for. + imgsz (int, optional): The image size used as input for the YOLO model. Defaults to 640. + fraction (float, optional): The fraction of available CUDA memory to use. Defaults to 0.67. + batch_size (int, optional): The default batch size to use if an error is detected. Defaults to 16. + + Returns: + (int): The optimal batch size. + """ + + # Check device + prefix = colorstr('AutoBatch: ') + LOGGER.info(f'{prefix}Computing optimal batch size for imgsz={imgsz}') + device = next(model.parameters()).device # get model device + if device.type == 'cpu': + LOGGER.info(f'{prefix}CUDA not detected, using default CPU batch-size {batch_size}') + return batch_size + if torch.backends.cudnn.benchmark: + LOGGER.info(f'{prefix} ⚠️ Requires torch.backends.cudnn.benchmark=False, using default batch-size {batch_size}') + return batch_size + + # Inspect CUDA memory + gb = 1 << 30 # bytes to GiB (1024 ** 3) + d = str(device).upper() # 'CUDA:0' + properties = torch.cuda.get_device_properties(device) # device properties + t = properties.total_memory / gb # GiB total + r = torch.cuda.memory_reserved(device) / gb # GiB reserved + a = torch.cuda.memory_allocated(device) / gb # GiB allocated + f = t - (r + a) # GiB free + LOGGER.info(f'{prefix}{d} ({properties.name}) {t:.2f}G total, {r:.2f}G reserved, {a:.2f}G allocated, {f:.2f}G free') + + # Profile batch sizes + batch_sizes = [1, 2, 4, 8, 16] + try: + img = [torch.empty(b, 3, imgsz, imgsz) for b in batch_sizes] + results = profile(img, model, n=3, device=device) + + # Fit a solution + y = [x[2] for x in results if x] # memory [2] + p = np.polyfit(batch_sizes[:len(y)], y, deg=1) # first degree polynomial fit + b = int((f * fraction - p[1]) / p[0]) # y intercept (optimal batch size) + if None in results: # some sizes failed + i = results.index(None) # first fail index + if b >= batch_sizes[i]: # y intercept above failure point + b = batch_sizes[max(i - 1, 0)] # select prior safe point + if b < 1 or b > 1024: # b outside of safe range + b = batch_size + LOGGER.info(f'{prefix}WARNING ⚠️ CUDA anomaly detected, using default batch-size {batch_size}.') + + fraction = (np.polyval(p, b) + r + a) / t # actual fraction predicted + LOGGER.info(f'{prefix}Using batch-size {b} for {d} {t * fraction:.2f}G/{t:.2f}G ({fraction * 100:.0f}%) ✅') + return b + except Exception as e: + LOGGER.warning(f'{prefix}WARNING ⚠️ error detected: {e}, using default batch-size {batch_size}.') + return batch_size diff --git a/downloads/ultralytics-main/ultralytics/utils/benchmarks.py b/downloads/ultralytics-main/ultralytics/utils/benchmarks.py new file mode 100644 index 000000000..71fa57a0f --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/benchmarks.py @@ -0,0 +1,366 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license +""" +Benchmark a YOLO model formats for speed and accuracy + +Usage: + from ultralytics.utils.benchmarks import ProfileModels, benchmark + ProfileModels(['yolov8n.yaml', 'yolov8s.yaml']).profile() + benchmark(model='yolov8n.pt', imgsz=160) + +Format | `format=argument` | Model +--- | --- | --- +PyTorch | - | yolov8n.pt +TorchScript | `torchscript` | yolov8n.torchscript +ONNX | `onnx` | yolov8n.onnx +OpenVINO | `openvino` | yolov8n_openvino_model/ +TensorRT | `engine` | yolov8n.engine +CoreML | `coreml` | yolov8n.mlpackage +TensorFlow SavedModel | `saved_model` | yolov8n_saved_model/ +TensorFlow GraphDef | `pb` | yolov8n.pb +TensorFlow Lite | `tflite` | yolov8n.tflite +TensorFlow Edge TPU | `edgetpu` | yolov8n_edgetpu.tflite +TensorFlow.js | `tfjs` | yolov8n_web_model/ +PaddlePaddle | `paddle` | yolov8n_paddle_model/ +ncnn | `ncnn` | yolov8n_ncnn_model/ +""" + +import glob +import platform +import sys +import time +from pathlib import Path + +import numpy as np +import torch.cuda +from tqdm import tqdm + +from ultralytics import YOLO +from ultralytics.cfg import TASK2DATA, TASK2METRIC +from ultralytics.engine.exporter import export_formats +from ultralytics.utils import ASSETS, LINUX, LOGGER, MACOS, SETTINGS +from ultralytics.utils.checks import check_requirements, check_yolo +from ultralytics.utils.files import file_size +from ultralytics.utils.torch_utils import select_device + + +def benchmark(model=Path(SETTINGS['weights_dir']) / 'yolov8n.pt', + data=None, + imgsz=160, + half=False, + int8=False, + device='cpu', + verbose=False): + """ + Benchmark a YOLO model across different formats for speed and accuracy. + + Args: + model (str | Path | optional): Path to the model file or directory. Default is + Path(SETTINGS['weights_dir']) / 'yolov8n.pt'. + data (str, optional): Dataset to evaluate on, inherited from TASK2DATA if not passed. Default is None. + imgsz (int, optional): Image size for the benchmark. Default is 160. + half (bool, optional): Use half-precision for the model if True. Default is False. + int8 (bool, optional): Use int8-precision for the model if True. Default is False. + device (str, optional): Device to run the benchmark on, either 'cpu' or 'cuda'. Default is 'cpu'. + verbose (bool | float | optional): If True or a float, assert benchmarks pass with given metric. + Default is False. + + Returns: + df (pandas.DataFrame): A pandas DataFrame with benchmark results for each format, including file size, + metric, and inference time. + + Example: + ```python + from ultralytics.utils.benchmarks import benchmark + + benchmark(model='yolov8n.pt', imgsz=640) + ``` + """ + + import pandas as pd + pd.options.display.max_columns = 10 + pd.options.display.width = 120 + device = select_device(device, verbose=False) + if isinstance(model, (str, Path)): + model = YOLO(model) + + y = [] + t0 = time.time() + for i, (name, format, suffix, cpu, gpu) in export_formats().iterrows(): # index, (name, format, suffix, CPU, GPU) + emoji, filename = '❌', None # export defaults + try: + assert i != 9 or LINUX, 'Edge TPU export only supported on Linux' + if i == 10: + assert MACOS or LINUX, 'TF.js export only supported on macOS and Linux' + elif i == 11: + assert sys.version_info < (3, 11), 'PaddlePaddle export only supported on Python<=3.10' + if 'cpu' in device.type: + assert cpu, 'inference not supported on CPU' + if 'cuda' in device.type: + assert gpu, 'inference not supported on GPU' + + # Export + if format == '-': + filename = model.ckpt_path or model.cfg + export = model # PyTorch format + else: + filename = model.export(imgsz=imgsz, format=format, half=half, int8=int8, device=device, verbose=False) + export = YOLO(filename, task=model.task) + assert suffix in str(filename), 'export failed' + emoji = '❎' # indicates export succeeded + + # Predict + assert model.task != 'pose' or i != 7, 'GraphDef Pose inference is not supported' + assert i not in (9, 10), 'inference not supported' # Edge TPU and TF.js are unsupported + assert i != 5 or platform.system() == 'Darwin', 'inference only supported on macOS>=10.13' # CoreML + export.predict(ASSETS / 'bus.jpg', imgsz=imgsz, device=device, half=half) + + # Validate + data = data or TASK2DATA[model.task] # task to dataset, i.e. coco8.yaml for task=detect + key = TASK2METRIC[model.task] # task to metric, i.e. metrics/mAP50-95(B) for task=detect + results = export.val(data=data, + batch=1, + imgsz=imgsz, + plots=False, + device=device, + half=half, + int8=int8, + verbose=False) + metric, speed = results.results_dict[key], results.speed['inference'] + y.append([name, '✅', round(file_size(filename), 1), round(metric, 4), round(speed, 2)]) + except Exception as e: + if verbose: + assert type(e) is AssertionError, f'Benchmark failure for {name}: {e}' + LOGGER.warning(f'ERROR ❌️ Benchmark failure for {name}: {e}') + y.append([name, emoji, round(file_size(filename), 1), None, None]) # mAP, t_inference + + # Print results + check_yolo(device=device) # print system info + df = pd.DataFrame(y, columns=['Format', 'Status❔', 'Size (MB)', key, 'Inference time (ms/im)']) + + name = Path(model.ckpt_path).name + s = f'\nBenchmarks complete for {name} on {data} at imgsz={imgsz} ({time.time() - t0:.2f}s)\n{df}\n' + LOGGER.info(s) + with open('benchmarks.log', 'a', errors='ignore', encoding='utf-8') as f: + f.write(s) + + if verbose and isinstance(verbose, float): + metrics = df[key].array # values to compare to floor + floor = verbose # minimum metric floor to pass, i.e. = 0.29 mAP for YOLOv5n + assert all(x > floor for x in metrics if pd.notna(x)), f'Benchmark failure: metric(s) < floor {floor}' + + return df + + +class ProfileModels: + """ + ProfileModels class for profiling different models on ONNX and TensorRT. + + This class profiles the performance of different models, provided their paths. The profiling includes parameters such as + model speed and FLOPs. + + Attributes: + paths (list): Paths of the models to profile. + num_timed_runs (int): Number of timed runs for the profiling. Default is 100. + num_warmup_runs (int): Number of warmup runs before profiling. Default is 10. + min_time (float): Minimum number of seconds to profile for. Default is 60. + imgsz (int): Image size used in the models. Default is 640. + + Methods: + profile(): Profiles the models and prints the result. + + Example: + ```python + from ultralytics.utils.benchmarks import ProfileModels + + ProfileModels(['yolov8n.yaml', 'yolov8s.yaml'], imgsz=640).profile() + ``` + """ + + def __init__(self, + paths: list, + num_timed_runs=100, + num_warmup_runs=10, + min_time=60, + imgsz=640, + trt=True, + device=None): + self.paths = paths + self.num_timed_runs = num_timed_runs + self.num_warmup_runs = num_warmup_runs + self.min_time = min_time + self.imgsz = imgsz + self.trt = trt # run TensorRT profiling + self.device = device or torch.device(0 if torch.cuda.is_available() else 'cpu') + + def profile(self): + files = self.get_files() + + if not files: + print('No matching *.pt or *.onnx files found.') + return + + table_rows = [] + output = [] + for file in files: + engine_file = file.with_suffix('.engine') + if file.suffix in ('.pt', '.yaml', '.yml'): + model = YOLO(str(file)) + model.fuse() # to report correct params and GFLOPs in model.info() + model_info = model.info() + if self.trt and self.device.type != 'cpu' and not engine_file.is_file(): + engine_file = model.export(format='engine', + half=True, + imgsz=self.imgsz, + device=self.device, + verbose=False) + onnx_file = model.export(format='onnx', + half=True, + imgsz=self.imgsz, + simplify=True, + device=self.device, + verbose=False) + elif file.suffix == '.onnx': + model_info = self.get_onnx_model_info(file) + onnx_file = file + else: + continue + + t_engine = self.profile_tensorrt_model(str(engine_file)) + t_onnx = self.profile_onnx_model(str(onnx_file)) + table_rows.append(self.generate_table_row(file.stem, t_onnx, t_engine, model_info)) + output.append(self.generate_results_dict(file.stem, t_onnx, t_engine, model_info)) + + self.print_table(table_rows) + return output + + def get_files(self): + files = [] + for path in self.paths: + path = Path(path) + if path.is_dir(): + extensions = ['*.pt', '*.onnx', '*.yaml'] + files.extend([file for ext in extensions for file in glob.glob(str(path / ext))]) + elif path.suffix in ('.pt', '.yaml', '.yml'): # add non-existing + files.append(str(path)) + else: + files.extend(glob.glob(str(path))) + + print(f'Profiling: {sorted(files)}') + return [Path(file) for file in sorted(files)] + + def get_onnx_model_info(self, onnx_file: str): + # return (num_layers, num_params, num_gradients, num_flops) + return 0.0, 0.0, 0.0, 0.0 + + def iterative_sigma_clipping(self, data, sigma=2, max_iters=3): + data = np.array(data) + for _ in range(max_iters): + mean, std = np.mean(data), np.std(data) + clipped_data = data[(data > mean - sigma * std) & (data < mean + sigma * std)] + if len(clipped_data) == len(data): + break + data = clipped_data + return data + + def profile_tensorrt_model(self, engine_file: str): + if not self.trt or not Path(engine_file).is_file(): + return 0.0, 0.0 + + # Model and input + model = YOLO(engine_file) + input_data = np.random.rand(self.imgsz, self.imgsz, 3).astype(np.float32) # must be FP32 + + # Warmup runs + elapsed = 0.0 + for _ in range(3): + start_time = time.time() + for _ in range(self.num_warmup_runs): + model(input_data, imgsz=self.imgsz, verbose=False) + elapsed = time.time() - start_time + + # Compute number of runs as higher of min_time or num_timed_runs + num_runs = max(round(self.min_time / elapsed * self.num_warmup_runs), self.num_timed_runs * 50) + + # Timed runs + run_times = [] + for _ in tqdm(range(num_runs), desc=engine_file): + results = model(input_data, imgsz=self.imgsz, verbose=False) + run_times.append(results[0].speed['inference']) # Convert to milliseconds + + run_times = self.iterative_sigma_clipping(np.array(run_times), sigma=2, max_iters=3) # sigma clipping + return np.mean(run_times), np.std(run_times) + + def profile_onnx_model(self, onnx_file: str): + check_requirements('onnxruntime') + import onnxruntime as ort + + # Session with either 'TensorrtExecutionProvider', 'CUDAExecutionProvider', 'CPUExecutionProvider' + sess_options = ort.SessionOptions() + sess_options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL + sess_options.intra_op_num_threads = 8 # Limit the number of threads + sess = ort.InferenceSession(onnx_file, sess_options, providers=['CPUExecutionProvider']) + + input_tensor = sess.get_inputs()[0] + input_type = input_tensor.type + + # Mapping ONNX datatype to numpy datatype + if 'float16' in input_type: + input_dtype = np.float16 + elif 'float' in input_type: + input_dtype = np.float32 + elif 'double' in input_type: + input_dtype = np.float64 + elif 'int64' in input_type: + input_dtype = np.int64 + elif 'int32' in input_type: + input_dtype = np.int32 + else: + raise ValueError(f'Unsupported ONNX datatype {input_type}') + + input_data = np.random.rand(*input_tensor.shape).astype(input_dtype) + input_name = input_tensor.name + output_name = sess.get_outputs()[0].name + + # Warmup runs + elapsed = 0.0 + for _ in range(3): + start_time = time.time() + for _ in range(self.num_warmup_runs): + sess.run([output_name], {input_name: input_data}) + elapsed = time.time() - start_time + + # Compute number of runs as higher of min_time or num_timed_runs + num_runs = max(round(self.min_time / elapsed * self.num_warmup_runs), self.num_timed_runs) + + # Timed runs + run_times = [] + for _ in tqdm(range(num_runs), desc=onnx_file): + start_time = time.time() + sess.run([output_name], {input_name: input_data}) + run_times.append((time.time() - start_time) * 1000) # Convert to milliseconds + + run_times = self.iterative_sigma_clipping(np.array(run_times), sigma=2, max_iters=5) # sigma clipping + return np.mean(run_times), np.std(run_times) + + def generate_table_row(self, model_name, t_onnx, t_engine, model_info): + layers, params, gradients, flops = model_info + return f'| {model_name:18s} | {self.imgsz} | - | {t_onnx[0]:.2f} ± {t_onnx[1]:.2f} ms | {t_engine[0]:.2f} ± {t_engine[1]:.2f} ms | {params / 1e6:.1f} | {flops:.1f} |' + + def generate_results_dict(self, model_name, t_onnx, t_engine, model_info): + layers, params, gradients, flops = model_info + return { + 'model/name': model_name, + 'model/parameters': params, + 'model/GFLOPs': round(flops, 3), + 'model/speed_ONNX(ms)': round(t_onnx[0], 3), + 'model/speed_TensorRT(ms)': round(t_engine[0], 3)} + + def print_table(self, table_rows): + gpu = torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'GPU' + header = f'| Model | size
(pixels) | mAPval
50-95 | Speed
CPU ONNX
(ms) | Speed
{gpu} TensorRT
(ms) | params
(M) | FLOPs
(B) |' + separator = '|-------------|---------------------|--------------------|------------------------------|-----------------------------------|------------------|-----------------|' + + print(f'\n\n{header}') + print(separator) + for row in table_rows: + print(row) diff --git a/downloads/ultralytics-main/ultralytics/utils/callbacks/__init__.py b/downloads/ultralytics-main/ultralytics/utils/callbacks/__init__.py new file mode 100644 index 000000000..8ad4ad6e7 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/callbacks/__init__.py @@ -0,0 +1,5 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from .base import add_integration_callbacks, default_callbacks, get_default_callbacks + +__all__ = 'add_integration_callbacks', 'default_callbacks', 'get_default_callbacks' diff --git a/downloads/ultralytics-main/ultralytics/utils/callbacks/base.py b/downloads/ultralytics-main/ultralytics/utils/callbacks/base.py new file mode 100644 index 000000000..0b1734798 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/callbacks/base.py @@ -0,0 +1,212 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license +""" +Base callbacks +""" + +from collections import defaultdict +from copy import deepcopy + +# Trainer callbacks ---------------------------------------------------------------------------------------------------- + + +def on_pretrain_routine_start(trainer): + """Called before the pretraining routine starts.""" + pass + + +def on_pretrain_routine_end(trainer): + """Called after the pretraining routine ends.""" + pass + + +def on_train_start(trainer): + """Called when the training starts.""" + pass + + +def on_train_epoch_start(trainer): + """Called at the start of each training epoch.""" + pass + + +def on_train_batch_start(trainer): + """Called at the start of each training batch.""" + pass + + +def optimizer_step(trainer): + """Called when the optimizer takes a step.""" + pass + + +def on_before_zero_grad(trainer): + """Called before the gradients are set to zero.""" + pass + + +def on_train_batch_end(trainer): + """Called at the end of each training batch.""" + pass + + +def on_train_epoch_end(trainer): + """Called at the end of each training epoch.""" + pass + + +def on_fit_epoch_end(trainer): + """Called at the end of each fit epoch (train + val).""" + pass + + +def on_model_save(trainer): + """Called when the model is saved.""" + pass + + +def on_train_end(trainer): + """Called when the training ends.""" + pass + + +def on_params_update(trainer): + """Called when the model parameters are updated.""" + pass + + +def teardown(trainer): + """Called during the teardown of the training process.""" + pass + + +# Validator callbacks -------------------------------------------------------------------------------------------------- + + +def on_val_start(validator): + """Called when the validation starts.""" + pass + + +def on_val_batch_start(validator): + """Called at the start of each validation batch.""" + pass + + +def on_val_batch_end(validator): + """Called at the end of each validation batch.""" + pass + + +def on_val_end(validator): + """Called when the validation ends.""" + pass + + +# Predictor callbacks -------------------------------------------------------------------------------------------------- + + +def on_predict_start(predictor): + """Called when the prediction starts.""" + pass + + +def on_predict_batch_start(predictor): + """Called at the start of each prediction batch.""" + pass + + +def on_predict_batch_end(predictor): + """Called at the end of each prediction batch.""" + pass + + +def on_predict_postprocess_end(predictor): + """Called after the post-processing of the prediction ends.""" + pass + + +def on_predict_end(predictor): + """Called when the prediction ends.""" + pass + + +# Exporter callbacks --------------------------------------------------------------------------------------------------- + + +def on_export_start(exporter): + """Called when the model export starts.""" + pass + + +def on_export_end(exporter): + """Called when the model export ends.""" + pass + + +default_callbacks = { + # Run in trainer + 'on_pretrain_routine_start': [on_pretrain_routine_start], + 'on_pretrain_routine_end': [on_pretrain_routine_end], + 'on_train_start': [on_train_start], + 'on_train_epoch_start': [on_train_epoch_start], + 'on_train_batch_start': [on_train_batch_start], + 'optimizer_step': [optimizer_step], + 'on_before_zero_grad': [on_before_zero_grad], + 'on_train_batch_end': [on_train_batch_end], + 'on_train_epoch_end': [on_train_epoch_end], + 'on_fit_epoch_end': [on_fit_epoch_end], # fit = train + val + 'on_model_save': [on_model_save], + 'on_train_end': [on_train_end], + 'on_params_update': [on_params_update], + 'teardown': [teardown], + + # Run in validator + 'on_val_start': [on_val_start], + 'on_val_batch_start': [on_val_batch_start], + 'on_val_batch_end': [on_val_batch_end], + 'on_val_end': [on_val_end], + + # Run in predictor + 'on_predict_start': [on_predict_start], + 'on_predict_batch_start': [on_predict_batch_start], + 'on_predict_postprocess_end': [on_predict_postprocess_end], + 'on_predict_batch_end': [on_predict_batch_end], + 'on_predict_end': [on_predict_end], + + # Run in exporter + 'on_export_start': [on_export_start], + 'on_export_end': [on_export_end]} + + +def get_default_callbacks(): + """ + Return a copy of the default_callbacks dictionary with lists as default values. + + Returns: + (defaultdict): A defaultdict with keys from default_callbacks and empty lists as default values. + """ + return defaultdict(list, deepcopy(default_callbacks)) + + +def add_integration_callbacks(instance): + """ + Add integration callbacks from various sources to the instance's callbacks. + + Args: + instance (Trainer, Predictor, Validator, Exporter): An object with a 'callbacks' attribute that is a dictionary + of callback lists. + """ + from .clearml import callbacks as clearml_cb + from .comet import callbacks as comet_cb + from .dvc import callbacks as dvc_cb + from .hub import callbacks as hub_cb + from .mlflow import callbacks as mlflow_cb + from .neptune import callbacks as neptune_cb + from .raytune import callbacks as tune_cb + from .tensorboard import callbacks as tensorboard_cb + from .wb import callbacks as wb_cb + + for x in clearml_cb, comet_cb, hub_cb, mlflow_cb, neptune_cb, tune_cb, tensorboard_cb, wb_cb, dvc_cb: + for k, v in x.items(): + if v not in instance.callbacks[k]: # prevent duplicate callbacks addition + instance.callbacks[k].append(v) # callback[name].append(func) diff --git a/downloads/ultralytics-main/ultralytics/utils/callbacks/clearml.py b/downloads/ultralytics-main/ultralytics/utils/callbacks/clearml.py new file mode 100644 index 000000000..5460aca61 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/callbacks/clearml.py @@ -0,0 +1,139 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import re + +import matplotlib.image as mpimg +import matplotlib.pyplot as plt + +from ultralytics.utils import LOGGER, SETTINGS, TESTS_RUNNING +from ultralytics.utils.torch_utils import model_info_for_loggers + +try: + import clearml + from clearml import Task + from clearml.binding.frameworks.pytorch_bind import PatchPyTorchModelIO + from clearml.binding.matplotlib_bind import PatchedMatplotlib + + assert hasattr(clearml, '__version__') # verify package is not directory + assert not TESTS_RUNNING # do not log pytest + assert SETTINGS['clearml'] is True # verify integration is enabled +except (ImportError, AssertionError): + clearml = None + + +def _log_debug_samples(files, title='Debug Samples') -> None: + """ + Log files (images) as debug samples in the ClearML task. + + Args: + files (list): A list of file paths in PosixPath format. + title (str): A title that groups together images with the same values. + """ + if task := Task.current_task(): + for f in files: + if f.exists(): + it = re.search(r'_batch(\d+)', f.name) + iteration = int(it.groups()[0]) if it else 0 + task.get_logger().report_image(title=title, + series=f.name.replace(it.group(), ''), + local_path=str(f), + iteration=iteration) + + +def _log_plot(title, plot_path) -> None: + """ + Log an image as a plot in the plot section of ClearML. + + Args: + title (str): The title of the plot. + plot_path (str): The path to the saved image file. + """ + img = mpimg.imread(plot_path) + fig = plt.figure() + ax = fig.add_axes([0, 0, 1, 1], frameon=False, aspect='auto', xticks=[], yticks=[]) # no ticks + ax.imshow(img) + + Task.current_task().get_logger().report_matplotlib_figure(title=title, + series='', + figure=fig, + report_interactive=False) + + +def on_pretrain_routine_start(trainer): + """Runs at start of pretraining routine; initializes and connects/ logs task to ClearML.""" + try: + if task := Task.current_task(): + # Make sure the automatic pytorch and matplotlib bindings are disabled! + # We are logging these plots and model files manually in the integration + PatchPyTorchModelIO.update_current_task(None) + PatchedMatplotlib.update_current_task(None) + else: + task = Task.init(project_name=trainer.args.project or 'YOLOv8', + task_name=trainer.args.name, + tags=['YOLOv8'], + output_uri=True, + reuse_last_task_id=False, + auto_connect_frameworks={ + 'pytorch': False, + 'matplotlib': False}) + LOGGER.warning('ClearML Initialized a new task. If you want to run remotely, ' + 'please add clearml-init and connect your arguments before initializing YOLO.') + task.connect(vars(trainer.args), name='General') + except Exception as e: + LOGGER.warning(f'WARNING ⚠️ ClearML installed but not initialized correctly, not logging this run. {e}') + + +def on_train_epoch_end(trainer): + """Logs debug samples for the first epoch of YOLO training and report current training progress.""" + if task := Task.current_task(): + # Log debug samples + if trainer.epoch == 1: + _log_debug_samples(sorted(trainer.save_dir.glob('train_batch*.jpg')), 'Mosaic') + # Report the current training progress + for k, v in trainer.validator.metrics.results_dict.items(): + task.get_logger().report_scalar('train', k, v, iteration=trainer.epoch) + + +def on_fit_epoch_end(trainer): + """Reports model information to logger at the end of an epoch.""" + if task := Task.current_task(): + # You should have access to the validation bboxes under jdict + task.get_logger().report_scalar(title='Epoch Time', + series='Epoch Time', + value=trainer.epoch_time, + iteration=trainer.epoch) + if trainer.epoch == 0: + for k, v in model_info_for_loggers(trainer).items(): + task.get_logger().report_single_value(k, v) + + +def on_val_end(validator): + """Logs validation results including labels and predictions.""" + if Task.current_task(): + # Log val_labels and val_pred + _log_debug_samples(sorted(validator.save_dir.glob('val*.jpg')), 'Validation') + + +def on_train_end(trainer): + """Logs final model and its name on training completion.""" + if task := Task.current_task(): + # Log final results, CM matrix + PR plots + files = [ + 'results.png', 'confusion_matrix.png', 'confusion_matrix_normalized.png', + *(f'{x}_curve.png' for x in ('F1', 'PR', 'P', 'R'))] + files = [(trainer.save_dir / f) for f in files if (trainer.save_dir / f).exists()] # filter + for f in files: + _log_plot(title=f.stem, plot_path=f) + # Report final metrics + for k, v in trainer.validator.metrics.results_dict.items(): + task.get_logger().report_single_value(k, v) + # Log the final model + task.update_output_model(model_path=str(trainer.best), model_name=trainer.args.name, auto_delete_file=False) + + +callbacks = { + 'on_pretrain_routine_start': on_pretrain_routine_start, + 'on_train_epoch_end': on_train_epoch_end, + 'on_fit_epoch_end': on_fit_epoch_end, + 'on_val_end': on_val_end, + 'on_train_end': on_train_end} if clearml else {} diff --git a/downloads/ultralytics-main/ultralytics/utils/callbacks/comet.py b/downloads/ultralytics-main/ultralytics/utils/callbacks/comet.py new file mode 100644 index 000000000..a6f6c4038 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/callbacks/comet.py @@ -0,0 +1,369 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import os +from pathlib import Path + +from ultralytics.utils import LOGGER, RANK, SETTINGS, TESTS_RUNNING, ops +from ultralytics.utils.torch_utils import model_info_for_loggers + +try: + import comet_ml + + assert not TESTS_RUNNING # do not log pytest + assert hasattr(comet_ml, '__version__') # verify package is not directory + assert SETTINGS['comet'] is True # verify integration is enabled +except (ImportError, AssertionError): + comet_ml = None + +# Ensures certain logging functions only run for supported tasks +COMET_SUPPORTED_TASKS = ['detect'] + +# Names of plots created by YOLOv8 that are logged to Comet +EVALUATION_PLOT_NAMES = 'F1_curve', 'P_curve', 'R_curve', 'PR_curve', 'confusion_matrix' +LABEL_PLOT_NAMES = 'labels', 'labels_correlogram' + +_comet_image_prediction_count = 0 + + +def _get_comet_mode(): + return os.getenv('COMET_MODE', 'online') + + +def _get_comet_model_name(): + return os.getenv('COMET_MODEL_NAME', 'YOLOv8') + + +def _get_eval_batch_logging_interval(): + return int(os.getenv('COMET_EVAL_BATCH_LOGGING_INTERVAL', 1)) + + +def _get_max_image_predictions_to_log(): + return int(os.getenv('COMET_MAX_IMAGE_PREDICTIONS', 100)) + + +def _scale_confidence_score(score): + scale = float(os.getenv('COMET_MAX_CONFIDENCE_SCORE', 100.0)) + return score * scale + + +def _should_log_confusion_matrix(): + return os.getenv('COMET_EVAL_LOG_CONFUSION_MATRIX', 'false').lower() == 'true' + + +def _should_log_image_predictions(): + return os.getenv('COMET_EVAL_LOG_IMAGE_PREDICTIONS', 'true').lower() == 'true' + + +def _get_experiment_type(mode, project_name): + """Return an experiment based on mode and project name.""" + if mode == 'offline': + return comet_ml.OfflineExperiment(project_name=project_name) + + return comet_ml.Experiment(project_name=project_name) + + +def _create_experiment(args): + """Ensures that the experiment object is only created in a single process during distributed training.""" + if RANK not in (-1, 0): + return + try: + comet_mode = _get_comet_mode() + _project_name = os.getenv('COMET_PROJECT_NAME', args.project) + experiment = _get_experiment_type(comet_mode, _project_name) + experiment.log_parameters(vars(args)) + experiment.log_others({ + 'eval_batch_logging_interval': _get_eval_batch_logging_interval(), + 'log_confusion_matrix_on_eval': _should_log_confusion_matrix(), + 'log_image_predictions': _should_log_image_predictions(), + 'max_image_predictions': _get_max_image_predictions_to_log(), }) + experiment.log_other('Created from', 'yolov8') + + except Exception as e: + LOGGER.warning(f'WARNING ⚠️ Comet installed but not initialized correctly, not logging this run. {e}') + + +def _fetch_trainer_metadata(trainer): + """Returns metadata for YOLO training including epoch and asset saving status.""" + curr_epoch = trainer.epoch + 1 + + train_num_steps_per_epoch = len(trainer.train_loader.dataset) // trainer.batch_size + curr_step = curr_epoch * train_num_steps_per_epoch + final_epoch = curr_epoch == trainer.epochs + + save = trainer.args.save + save_period = trainer.args.save_period + save_interval = curr_epoch % save_period == 0 + save_assets = save and save_period > 0 and save_interval and not final_epoch + + return dict( + curr_epoch=curr_epoch, + curr_step=curr_step, + save_assets=save_assets, + final_epoch=final_epoch, + ) + + +def _scale_bounding_box_to_original_image_shape(box, resized_image_shape, original_image_shape, ratio_pad): + """YOLOv8 resizes images during training and the label values + are normalized based on this resized shape. This function rescales the + bounding box labels to the original image shape. + """ + + resized_image_height, resized_image_width = resized_image_shape + + # Convert normalized xywh format predictions to xyxy in resized scale format + box = ops.xywhn2xyxy(box, h=resized_image_height, w=resized_image_width) + # Scale box predictions from resized image scale back to original image scale + box = ops.scale_boxes(resized_image_shape, box, original_image_shape, ratio_pad) + # Convert bounding box format from xyxy to xywh for Comet logging + box = ops.xyxy2xywh(box) + # Adjust xy center to correspond top-left corner + box[:2] -= box[2:] / 2 + box = box.tolist() + + return box + + +def _format_ground_truth_annotations_for_detection(img_idx, image_path, batch, class_name_map=None): + """Format ground truth annotations for detection.""" + indices = batch['batch_idx'] == img_idx + bboxes = batch['bboxes'][indices] + if len(bboxes) == 0: + LOGGER.debug(f'COMET WARNING: Image: {image_path} has no bounding boxes labels') + return None + + cls_labels = batch['cls'][indices].squeeze(1).tolist() + if class_name_map: + cls_labels = [str(class_name_map[label]) for label in cls_labels] + + original_image_shape = batch['ori_shape'][img_idx] + resized_image_shape = batch['resized_shape'][img_idx] + ratio_pad = batch['ratio_pad'][img_idx] + + data = [] + for box, label in zip(bboxes, cls_labels): + box = _scale_bounding_box_to_original_image_shape(box, resized_image_shape, original_image_shape, ratio_pad) + data.append({ + 'boxes': [box], + 'label': f'gt_{label}', + 'score': _scale_confidence_score(1.0), }) + + return {'name': 'ground_truth', 'data': data} + + +def _format_prediction_annotations_for_detection(image_path, metadata, class_label_map=None): + """Format YOLO predictions for object detection visualization.""" + stem = image_path.stem + image_id = int(stem) if stem.isnumeric() else stem + + predictions = metadata.get(image_id) + if not predictions: + LOGGER.debug(f'COMET WARNING: Image: {image_path} has no bounding boxes predictions') + return None + + data = [] + for prediction in predictions: + boxes = prediction['bbox'] + score = _scale_confidence_score(prediction['score']) + cls_label = prediction['category_id'] + if class_label_map: + cls_label = str(class_label_map[cls_label]) + + data.append({'boxes': [boxes], 'label': cls_label, 'score': score}) + + return {'name': 'prediction', 'data': data} + + +def _fetch_annotations(img_idx, image_path, batch, prediction_metadata_map, class_label_map): + """Join the ground truth and prediction annotations if they exist.""" + ground_truth_annotations = _format_ground_truth_annotations_for_detection(img_idx, image_path, batch, + class_label_map) + prediction_annotations = _format_prediction_annotations_for_detection(image_path, prediction_metadata_map, + class_label_map) + + annotations = [ + annotation for annotation in [ground_truth_annotations, prediction_annotations] if annotation is not None] + return [annotations] if annotations else None + + +def _create_prediction_metadata_map(model_predictions): + """Create metadata map for model predictions by groupings them based on image ID.""" + pred_metadata_map = {} + for prediction in model_predictions: + pred_metadata_map.setdefault(prediction['image_id'], []) + pred_metadata_map[prediction['image_id']].append(prediction) + + return pred_metadata_map + + +def _log_confusion_matrix(experiment, trainer, curr_step, curr_epoch): + """Log the confusion matrix to Comet experiment.""" + conf_mat = trainer.validator.confusion_matrix.matrix + names = list(trainer.data['names'].values()) + ['background'] + experiment.log_confusion_matrix( + matrix=conf_mat, + labels=names, + max_categories=len(names), + epoch=curr_epoch, + step=curr_step, + ) + + +def _log_images(experiment, image_paths, curr_step, annotations=None): + """Logs images to the experiment with optional annotations.""" + if annotations: + for image_path, annotation in zip(image_paths, annotations): + experiment.log_image(image_path, name=image_path.stem, step=curr_step, annotations=annotation) + + else: + for image_path in image_paths: + experiment.log_image(image_path, name=image_path.stem, step=curr_step) + + +def _log_image_predictions(experiment, validator, curr_step): + """Logs predicted boxes for a single image during training.""" + global _comet_image_prediction_count + + task = validator.args.task + if task not in COMET_SUPPORTED_TASKS: + return + + jdict = validator.jdict + if not jdict: + return + + predictions_metadata_map = _create_prediction_metadata_map(jdict) + dataloader = validator.dataloader + class_label_map = validator.names + + batch_logging_interval = _get_eval_batch_logging_interval() + max_image_predictions = _get_max_image_predictions_to_log() + + for batch_idx, batch in enumerate(dataloader): + if (batch_idx + 1) % batch_logging_interval != 0: + continue + + image_paths = batch['im_file'] + for img_idx, image_path in enumerate(image_paths): + if _comet_image_prediction_count >= max_image_predictions: + return + + image_path = Path(image_path) + annotations = _fetch_annotations( + img_idx, + image_path, + batch, + predictions_metadata_map, + class_label_map, + ) + _log_images( + experiment, + [image_path], + curr_step, + annotations=annotations, + ) + _comet_image_prediction_count += 1 + + +def _log_plots(experiment, trainer): + """Logs evaluation plots and label plots for the experiment.""" + plot_filenames = [trainer.save_dir / f'{plots}.png' for plots in EVALUATION_PLOT_NAMES] + _log_images(experiment, plot_filenames, None) + + label_plot_filenames = [trainer.save_dir / f'{labels}.jpg' for labels in LABEL_PLOT_NAMES] + _log_images(experiment, label_plot_filenames, None) + + +def _log_model(experiment, trainer): + """Log the best-trained model to Comet.ml.""" + model_name = _get_comet_model_name() + experiment.log_model( + model_name, + file_or_folder=str(trainer.best), + file_name='best.pt', + overwrite=True, + ) + + +def on_pretrain_routine_start(trainer): + """Creates or resumes a CometML experiment at the start of a YOLO pre-training routine.""" + experiment = comet_ml.get_global_experiment() + is_alive = getattr(experiment, 'alive', False) + if not experiment or not is_alive: + _create_experiment(trainer.args) + + +def on_train_epoch_end(trainer): + """Log metrics and save batch images at the end of training epochs.""" + experiment = comet_ml.get_global_experiment() + if not experiment: + return + + metadata = _fetch_trainer_metadata(trainer) + curr_epoch = metadata['curr_epoch'] + curr_step = metadata['curr_step'] + + experiment.log_metrics( + trainer.label_loss_items(trainer.tloss, prefix='train'), + step=curr_step, + epoch=curr_epoch, + ) + + if curr_epoch == 1: + _log_images(experiment, trainer.save_dir.glob('train_batch*.jpg'), curr_step) + + +def on_fit_epoch_end(trainer): + """Logs model assets at the end of each epoch.""" + experiment = comet_ml.get_global_experiment() + if not experiment: + return + + metadata = _fetch_trainer_metadata(trainer) + curr_epoch = metadata['curr_epoch'] + curr_step = metadata['curr_step'] + save_assets = metadata['save_assets'] + + experiment.log_metrics(trainer.metrics, step=curr_step, epoch=curr_epoch) + experiment.log_metrics(trainer.lr, step=curr_step, epoch=curr_epoch) + if curr_epoch == 1: + experiment.log_metrics(model_info_for_loggers(trainer), step=curr_step, epoch=curr_epoch) + + if not save_assets: + return + + _log_model(experiment, trainer) + if _should_log_confusion_matrix(): + _log_confusion_matrix(experiment, trainer, curr_step, curr_epoch) + if _should_log_image_predictions(): + _log_image_predictions(experiment, trainer.validator, curr_step) + + +def on_train_end(trainer): + """Perform operations at the end of training.""" + experiment = comet_ml.get_global_experiment() + if not experiment: + return + + metadata = _fetch_trainer_metadata(trainer) + curr_epoch = metadata['curr_epoch'] + curr_step = metadata['curr_step'] + plots = trainer.args.plots + + _log_model(experiment, trainer) + if plots: + _log_plots(experiment, trainer) + + _log_confusion_matrix(experiment, trainer, curr_step, curr_epoch) + _log_image_predictions(experiment, trainer.validator, curr_step) + experiment.end() + + global _comet_image_prediction_count + _comet_image_prediction_count = 0 + + +callbacks = { + 'on_pretrain_routine_start': on_pretrain_routine_start, + 'on_train_epoch_end': on_train_epoch_end, + 'on_fit_epoch_end': on_fit_epoch_end, + 'on_train_end': on_train_end} if comet_ml else {} diff --git a/downloads/ultralytics-main/ultralytics/utils/callbacks/dvc.py b/downloads/ultralytics-main/ultralytics/utils/callbacks/dvc.py new file mode 100644 index 000000000..bf7498bf3 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/callbacks/dvc.py @@ -0,0 +1,140 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import os +import re +from pathlib import Path + +import pkg_resources as pkg + +from ultralytics.utils import LOGGER, SETTINGS, TESTS_RUNNING +from ultralytics.utils.torch_utils import model_info_for_loggers + +try: + from importlib.metadata import version + + import dvclive + + assert not TESTS_RUNNING # do not log pytest + assert SETTINGS['dvc'] is True # verify integration is enabled + + ver = version('dvclive') + if pkg.parse_version(ver) < pkg.parse_version('2.11.0'): + LOGGER.debug(f'DVCLive is detected but version {ver} is incompatible (>=2.11 required).') + dvclive = None # noqa: F811 +except (ImportError, AssertionError, TypeError): + dvclive = None + +# DVCLive logger instance +live = None +_processed_plots = {} + +# `on_fit_epoch_end` is called on final validation (probably need to be fixed) +# for now this is the way we distinguish final evaluation of the best model vs +# last epoch validation +_training_epoch = False + + +def _log_images(path, prefix=''): + if live: + name = path.name + + # Group images by batch to enable sliders in UI + if m := re.search(r'_batch(\d+)', name): + ni = m[1] + new_stem = re.sub(r'_batch(\d+)', '_batch', path.stem) + name = (Path(new_stem) / ni).with_suffix(path.suffix) + + live.log_image(os.path.join(prefix, name), path) + + +def _log_plots(plots, prefix=''): + for name, params in plots.items(): + timestamp = params['timestamp'] + if _processed_plots.get(name) != timestamp: + _log_images(name, prefix) + _processed_plots[name] = timestamp + + +def _log_confusion_matrix(validator): + targets = [] + preds = [] + matrix = validator.confusion_matrix.matrix + names = list(validator.names.values()) + if validator.confusion_matrix.task == 'detect': + names += ['background'] + + for ti, pred in enumerate(matrix.T.astype(int)): + for pi, num in enumerate(pred): + targets.extend([names[ti]] * num) + preds.extend([names[pi]] * num) + + live.log_sklearn_plot('confusion_matrix', targets, preds, name='cf.json', normalized=True) + + +def on_pretrain_routine_start(trainer): + try: + global live + live = dvclive.Live(save_dvc_exp=True, cache_images=True) + LOGGER.info( + f'DVCLive is detected and auto logging is enabled (can be disabled in the {SETTINGS.file} with `dvc: false`).' + ) + except Exception as e: + LOGGER.warning(f'WARNING ⚠️ DVCLive installed but not initialized correctly, not logging this run. {e}') + + +def on_pretrain_routine_end(trainer): + _log_plots(trainer.plots, 'train') + + +def on_train_start(trainer): + if live: + live.log_params(trainer.args) + + +def on_train_epoch_start(trainer): + global _training_epoch + _training_epoch = True + + +def on_fit_epoch_end(trainer): + global _training_epoch + if live and _training_epoch: + all_metrics = {**trainer.label_loss_items(trainer.tloss, prefix='train'), **trainer.metrics, **trainer.lr} + for metric, value in all_metrics.items(): + live.log_metric(metric, value) + + if trainer.epoch == 0: + for metric, value in model_info_for_loggers(trainer).items(): + live.log_metric(metric, value, plot=False) + + _log_plots(trainer.plots, 'train') + _log_plots(trainer.validator.plots, 'val') + + live.next_step() + _training_epoch = False + + +def on_train_end(trainer): + if live: + # At the end log the best metrics. It runs validator on the best model internally. + all_metrics = {**trainer.label_loss_items(trainer.tloss, prefix='train'), **trainer.metrics, **trainer.lr} + for metric, value in all_metrics.items(): + live.log_metric(metric, value, plot=False) + + _log_plots(trainer.plots, 'val') + _log_plots(trainer.validator.plots, 'val') + _log_confusion_matrix(trainer.validator) + + if trainer.best.exists(): + live.log_artifact(trainer.best, copy=True, type='model') + + live.end() + + +callbacks = { + 'on_pretrain_routine_start': on_pretrain_routine_start, + 'on_pretrain_routine_end': on_pretrain_routine_end, + 'on_train_start': on_train_start, + 'on_train_epoch_start': on_train_epoch_start, + 'on_fit_epoch_end': on_fit_epoch_end, + 'on_train_end': on_train_end} if dvclive else {} diff --git a/downloads/ultralytics-main/ultralytics/utils/callbacks/hub.py b/downloads/ultralytics-main/ultralytics/utils/callbacks/hub.py new file mode 100644 index 000000000..fba5a6b57 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/callbacks/hub.py @@ -0,0 +1,87 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import json +from time import time + +from ultralytics.hub.utils import HUB_WEB_ROOT, PREFIX, events +from ultralytics.utils import LOGGER, SETTINGS +from ultralytics.utils.torch_utils import model_info_for_loggers + + +def on_pretrain_routine_end(trainer): + """Logs info before starting timer for upload rate limit.""" + session = getattr(trainer, 'hub_session', None) + if session: + # Start timer for upload rate limit + LOGGER.info(f'{PREFIX}View model at {HUB_WEB_ROOT}/models/{session.model_id} 🚀') + session.timers = {'metrics': time(), 'ckpt': time()} # start timer on session.rate_limit + + +def on_fit_epoch_end(trainer): + """Uploads training progress metrics at the end of each epoch.""" + session = getattr(trainer, 'hub_session', None) + if session: + # Upload metrics after val end + all_plots = {**trainer.label_loss_items(trainer.tloss, prefix='train'), **trainer.metrics} + if trainer.epoch == 0: + all_plots = {**all_plots, **model_info_for_loggers(trainer)} + session.metrics_queue[trainer.epoch] = json.dumps(all_plots) + if time() - session.timers['metrics'] > session.rate_limits['metrics']: + session.upload_metrics() + session.timers['metrics'] = time() # reset timer + session.metrics_queue = {} # reset queue + + +def on_model_save(trainer): + """Saves checkpoints to Ultralytics HUB with rate limiting.""" + session = getattr(trainer, 'hub_session', None) + if session: + # Upload checkpoints with rate limiting + is_best = trainer.best_fitness == trainer.fitness + if time() - session.timers['ckpt'] > session.rate_limits['ckpt']: + LOGGER.info(f'{PREFIX}Uploading checkpoint {HUB_WEB_ROOT}/models/{session.model_id}') + session.upload_model(trainer.epoch, trainer.last, is_best) + session.timers['ckpt'] = time() # reset timer + + +def on_train_end(trainer): + """Upload final model and metrics to Ultralytics HUB at the end of training.""" + session = getattr(trainer, 'hub_session', None) + if session: + # Upload final model and metrics with exponential standoff + LOGGER.info(f'{PREFIX}Syncing final model...') + session.upload_model(trainer.epoch, trainer.best, map=trainer.metrics.get('metrics/mAP50-95(B)', 0), final=True) + session.alive = False # stop heartbeats + LOGGER.info(f'{PREFIX}Done ✅\n' + f'{PREFIX}View model at {HUB_WEB_ROOT}/models/{session.model_id} 🚀') + + +def on_train_start(trainer): + """Run events on train start.""" + events(trainer.args) + + +def on_val_start(validator): + """Runs events on validation start.""" + events(validator.args) + + +def on_predict_start(predictor): + """Run events on predict start.""" + events(predictor.args) + + +def on_export_start(exporter): + """Run events on export start.""" + events(exporter.args) + + +callbacks = { + 'on_pretrain_routine_end': on_pretrain_routine_end, + 'on_fit_epoch_end': on_fit_epoch_end, + 'on_model_save': on_model_save, + 'on_train_end': on_train_end, + 'on_train_start': on_train_start, + 'on_val_start': on_val_start, + 'on_predict_start': on_predict_start, + 'on_export_start': on_export_start} if SETTINGS['hub'] is True else {} # verify enabled diff --git a/downloads/ultralytics-main/ultralytics/utils/callbacks/mlflow.py b/downloads/ultralytics-main/ultralytics/utils/callbacks/mlflow.py new file mode 100644 index 000000000..b3256d6f0 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/callbacks/mlflow.py @@ -0,0 +1,71 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import os +import re +from pathlib import Path + +from ultralytics.utils import LOGGER, SETTINGS, TESTS_RUNNING, colorstr + +try: + import mlflow + + assert not TESTS_RUNNING # do not log pytest + assert hasattr(mlflow, '__version__') # verify package is not directory + assert SETTINGS['mlflow'] is True # verify integration is enabled +except (ImportError, AssertionError): + mlflow = None + + +def on_pretrain_routine_end(trainer): + """Logs training parameters to MLflow.""" + global mlflow, run, experiment_name + + if os.environ.get('MLFLOW_TRACKING_URI') is None: + mlflow = None + + if mlflow: + mlflow_location = os.environ['MLFLOW_TRACKING_URI'] # "http://192.168.xxx.xxx:5000" + mlflow.set_tracking_uri(mlflow_location) + + experiment_name = os.environ.get('MLFLOW_EXPERIMENT_NAME') or trainer.args.project or '/Shared/YOLOv8' + run_name = os.environ.get('MLFLOW_RUN') or trainer.args.name + experiment = mlflow.get_experiment_by_name(experiment_name) + if experiment is None: + mlflow.create_experiment(experiment_name) + mlflow.set_experiment(experiment_name) + + prefix = colorstr('MLFlow: ') + try: + run, active_run = mlflow, mlflow.active_run() + if not active_run: + active_run = mlflow.start_run(experiment_id=experiment.experiment_id, run_name=run_name) + LOGGER.info(f'{prefix}Using run_id({active_run.info.run_id}) at {mlflow_location}') + run.log_params(vars(trainer.model.args)) + except Exception as err: + LOGGER.error(f'{prefix}Failing init - {repr(err)}') + LOGGER.warning(f'{prefix}Continuing without Mlflow') + + +def on_fit_epoch_end(trainer): + """Logs training metrics to Mlflow.""" + if mlflow: + metrics_dict = {f"{re.sub('[()]', '', k)}": float(v) for k, v in trainer.metrics.items()} + run.log_metrics(metrics=metrics_dict, step=trainer.epoch) + + +def on_train_end(trainer): + """Called at end of train loop to log model artifact info.""" + if mlflow: + root_dir = Path(__file__).resolve().parents[3] + run.log_artifact(trainer.last) + run.log_artifact(trainer.best) + run.pyfunc.log_model(artifact_path=experiment_name, + code_path=[str(root_dir)], + artifacts={'model_path': str(trainer.save_dir)}, + python_model=run.pyfunc.PythonModel()) + + +callbacks = { + 'on_pretrain_routine_end': on_pretrain_routine_end, + 'on_fit_epoch_end': on_fit_epoch_end, + 'on_train_end': on_train_end} if mlflow else {} diff --git a/downloads/ultralytics-main/ultralytics/utils/callbacks/neptune.py b/downloads/ultralytics-main/ultralytics/utils/callbacks/neptune.py new file mode 100644 index 000000000..f72a63b25 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/callbacks/neptune.py @@ -0,0 +1,104 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import matplotlib.image as mpimg +import matplotlib.pyplot as plt + +from ultralytics.utils import LOGGER, SETTINGS, TESTS_RUNNING +from ultralytics.utils.torch_utils import model_info_for_loggers + +try: + import neptune + from neptune.types import File + + assert not TESTS_RUNNING # do not log pytest + assert hasattr(neptune, '__version__') + assert SETTINGS['neptune'] is True # verify integration is enabled +except (ImportError, AssertionError): + neptune = None + +run = None # NeptuneAI experiment logger instance + + +def _log_scalars(scalars, step=0): + """Log scalars to the NeptuneAI experiment logger.""" + if run: + for k, v in scalars.items(): + run[k].append(value=v, step=step) + + +def _log_images(imgs_dict, group=''): + """Log scalars to the NeptuneAI experiment logger.""" + if run: + for k, v in imgs_dict.items(): + run[f'{group}/{k}'].upload(File(v)) + + +def _log_plot(title, plot_path): + """Log plots to the NeptuneAI experiment logger.""" + """ + Log image as plot in the plot section of NeptuneAI + + arguments: + title (str) Title of the plot + plot_path (PosixPath or str) Path to the saved image file + """ + img = mpimg.imread(plot_path) + fig = plt.figure() + ax = fig.add_axes([0, 0, 1, 1], frameon=False, aspect='auto', xticks=[], yticks=[]) # no ticks + ax.imshow(img) + run[f'Plots/{title}'].upload(fig) + + +def on_pretrain_routine_start(trainer): + """Callback function called before the training routine starts.""" + try: + global run + run = neptune.init_run(project=trainer.args.project or 'YOLOv8', name=trainer.args.name, tags=['YOLOv8']) + run['Configuration/Hyperparameters'] = {k: '' if v is None else v for k, v in vars(trainer.args).items()} + except Exception as e: + LOGGER.warning(f'WARNING ⚠️ NeptuneAI installed but not initialized correctly, not logging this run. {e}') + + +def on_train_epoch_end(trainer): + """Callback function called at end of each training epoch.""" + _log_scalars(trainer.label_loss_items(trainer.tloss, prefix='train'), trainer.epoch + 1) + _log_scalars(trainer.lr, trainer.epoch + 1) + if trainer.epoch == 1: + _log_images({f.stem: str(f) for f in trainer.save_dir.glob('train_batch*.jpg')}, 'Mosaic') + + +def on_fit_epoch_end(trainer): + """Callback function called at end of each fit (train+val) epoch.""" + if run and trainer.epoch == 0: + run['Configuration/Model'] = model_info_for_loggers(trainer) + _log_scalars(trainer.metrics, trainer.epoch + 1) + + +def on_val_end(validator): + """Callback function called at end of each validation.""" + if run: + # Log val_labels and val_pred + _log_images({f.stem: str(f) for f in validator.save_dir.glob('val*.jpg')}, 'Validation') + + +def on_train_end(trainer): + """Callback function called at end of training.""" + if run: + # Log final results, CM matrix + PR plots + files = [ + 'results.png', 'confusion_matrix.png', 'confusion_matrix_normalized.png', + *(f'{x}_curve.png' for x in ('F1', 'PR', 'P', 'R'))] + files = [(trainer.save_dir / f) for f in files if (trainer.save_dir / f).exists()] # filter + for f in files: + _log_plot(title=f.stem, plot_path=f) + # Log the final model + run[f'weights/{trainer.args.name or trainer.args.task}/{str(trainer.best.name)}'].upload(File(str( + trainer.best))) + + +callbacks = { + 'on_pretrain_routine_start': on_pretrain_routine_start, + 'on_train_epoch_end': on_train_epoch_end, + 'on_fit_epoch_end': on_fit_epoch_end, + 'on_val_end': on_val_end, + 'on_train_end': on_train_end} if neptune else {} diff --git a/downloads/ultralytics-main/ultralytics/utils/callbacks/raytune.py b/downloads/ultralytics-main/ultralytics/utils/callbacks/raytune.py new file mode 100644 index 000000000..0ca1d2b3c --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/callbacks/raytune.py @@ -0,0 +1,24 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from ultralytics.utils import SETTINGS + +try: + import ray + from ray import tune + from ray.air import session + + assert SETTINGS['raytune'] is True # verify integration is enabled +except (ImportError, AssertionError): + tune = None + + +def on_fit_epoch_end(trainer): + """Sends training metrics to Ray Tune at end of each epoch.""" + if ray.tune.is_session_enabled(): + metrics = trainer.metrics + metrics['epoch'] = trainer.epoch + session.report(metrics) + + +callbacks = { + 'on_fit_epoch_end': on_fit_epoch_end, } if tune else {} diff --git a/downloads/ultralytics-main/ultralytics/utils/callbacks/tensorboard.py b/downloads/ultralytics-main/ultralytics/utils/callbacks/tensorboard.py new file mode 100644 index 000000000..c542c9e85 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/callbacks/tensorboard.py @@ -0,0 +1,69 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from ultralytics.utils import LOGGER, SETTINGS, TESTS_RUNNING, colorstr + +try: + from torch.utils.tensorboard import SummaryWriter + + assert not TESTS_RUNNING # do not log pytest + assert SETTINGS['tensorboard'] is True # verify integration is enabled + +# TypeError for handling 'Descriptors cannot not be created directly.' protobuf errors in Windows +except (ImportError, AssertionError, TypeError): + SummaryWriter = None + +WRITER = None # TensorBoard SummaryWriter instance + + +def _log_scalars(scalars, step=0): + """Logs scalar values to TensorBoard.""" + if WRITER: + for k, v in scalars.items(): + WRITER.add_scalar(k, v, step) + + +def _log_tensorboard_graph(trainer): + # Log model graph to TensorBoard + try: + import warnings + + from ultralytics.utils.torch_utils import de_parallel, torch + + imgsz = trainer.args.imgsz + imgsz = (imgsz, imgsz) if isinstance(imgsz, int) else imgsz + p = next(trainer.model.parameters()) # for device, type + im = torch.zeros((1, 3, *imgsz), device=p.device, dtype=p.dtype) # input (WARNING: must be zeros, not empty) + with warnings.catch_warnings(category=UserWarning): + warnings.simplefilter('ignore') # suppress jit trace warning + WRITER.add_graph(torch.jit.trace(de_parallel(trainer.model), im, strict=False), []) + except Exception as e: + LOGGER.warning(f'WARNING ⚠️ TensorBoard graph visualization failure {e}') + + +def on_pretrain_routine_start(trainer): + """Initialize TensorBoard logging with SummaryWriter.""" + if SummaryWriter: + try: + global WRITER + WRITER = SummaryWriter(str(trainer.save_dir)) + prefix = colorstr('TensorBoard: ') + LOGGER.info(f"{prefix}Start with 'tensorboard --logdir {trainer.save_dir}', view at http://localhost:6006/") + _log_tensorboard_graph(trainer) + except Exception as e: + LOGGER.warning(f'WARNING ⚠️ TensorBoard not initialized correctly, not logging this run. {e}') + + +def on_batch_end(trainer): + """Logs scalar statistics at the end of a training batch.""" + _log_scalars(trainer.label_loss_items(trainer.tloss, prefix='train'), trainer.epoch + 1) + + +def on_fit_epoch_end(trainer): + """Logs epoch metrics at end of training epoch.""" + _log_scalars(trainer.metrics, trainer.epoch + 1) + + +callbacks = { + 'on_pretrain_routine_start': on_pretrain_routine_start, + 'on_fit_epoch_end': on_fit_epoch_end, + 'on_batch_end': on_batch_end} diff --git a/downloads/ultralytics-main/ultralytics/utils/callbacks/wb.py b/downloads/ultralytics-main/ultralytics/utils/callbacks/wb.py new file mode 100644 index 000000000..4a8ee2426 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/callbacks/wb.py @@ -0,0 +1,62 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from ultralytics.utils import SETTINGS, TESTS_RUNNING +from ultralytics.utils.torch_utils import model_info_for_loggers + +try: + import wandb as wb + + assert hasattr(wb, '__version__') + assert not TESTS_RUNNING # do not log pytest + assert SETTINGS['wandb'] is True # verify integration is enabled +except (ImportError, AssertionError): + wb = None + +_processed_plots = {} + + +def _log_plots(plots, step): + for name, params in plots.items(): + timestamp = params['timestamp'] + if _processed_plots.get(name) != timestamp: + wb.run.log({name.stem: wb.Image(str(name))}, step=step) + _processed_plots[name] = timestamp + + +def on_pretrain_routine_start(trainer): + """Initiate and start project if module is present.""" + wb.run or wb.init(project=trainer.args.project or 'YOLOv8', name=trainer.args.name, config=vars(trainer.args)) + + +def on_fit_epoch_end(trainer): + """Logs training metrics and model information at the end of an epoch.""" + wb.run.log(trainer.metrics, step=trainer.epoch + 1) + _log_plots(trainer.plots, step=trainer.epoch + 1) + _log_plots(trainer.validator.plots, step=trainer.epoch + 1) + if trainer.epoch == 0: + wb.run.log(model_info_for_loggers(trainer), step=trainer.epoch + 1) + + +def on_train_epoch_end(trainer): + """Log metrics and save images at the end of each training epoch.""" + wb.run.log(trainer.label_loss_items(trainer.tloss, prefix='train'), step=trainer.epoch + 1) + wb.run.log(trainer.lr, step=trainer.epoch + 1) + if trainer.epoch == 1: + _log_plots(trainer.plots, step=trainer.epoch + 1) + + +def on_train_end(trainer): + """Save the best model as an artifact at end of training.""" + _log_plots(trainer.validator.plots, step=trainer.epoch + 1) + _log_plots(trainer.plots, step=trainer.epoch + 1) + art = wb.Artifact(type='model', name=f'run_{wb.run.id}_model') + if trainer.best.exists(): + art.add_file(trainer.best) + wb.run.log_artifact(art, aliases=['best']) + + +callbacks = { + 'on_pretrain_routine_start': on_pretrain_routine_start, + 'on_train_epoch_end': on_train_epoch_end, + 'on_fit_epoch_end': on_fit_epoch_end, + 'on_train_end': on_train_end} if wb else {} diff --git a/downloads/ultralytics-main/ultralytics/utils/checks.py b/downloads/ultralytics-main/ultralytics/utils/checks.py new file mode 100644 index 000000000..aa48430bc --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/checks.py @@ -0,0 +1,509 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license +import contextlib +import glob +import inspect +import math +import os +import platform +import re +import shutil +import subprocess +import time +from pathlib import Path +from typing import Optional + +import cv2 +import numpy as np +import pkg_resources as pkg +import psutil +import requests +import torch +from matplotlib import font_manager + +from ultralytics.utils import (ASSETS, AUTOINSTALL, LINUX, LOGGER, ONLINE, ROOT, USER_CONFIG_DIR, ThreadingLocked, + TryExcept, clean_url, colorstr, downloads, emojis, is_colab, is_docker, is_jupyter, + is_kaggle, is_online, is_pip_package, url2file) + + +def is_ascii(s) -> bool: + """ + Check if a string is composed of only ASCII characters. + + Args: + s (str): String to be checked. + + Returns: + bool: True if the string is composed only of ASCII characters, False otherwise. + """ + # Convert list, tuple, None, etc. to string + s = str(s) + + # Check if the string is composed of only ASCII characters + return all(ord(c) < 128 for c in s) + + +def check_imgsz(imgsz, stride=32, min_dim=1, max_dim=2, floor=0): + """ + Verify image size is a multiple of the given stride in each dimension. If the image size is not a multiple of the + stride, update it to the nearest multiple of the stride that is greater than or equal to the given floor value. + + Args: + imgsz (int | cList[int]): Image size. + stride (int): Stride value. + min_dim (int): Minimum number of dimensions. + max_dim (int): Maximum number of dimensions. + floor (int): Minimum allowed value for image size. + + Returns: + (List[int]): Updated image size. + """ + # Convert stride to integer if it is a tensor + stride = int(stride.max() if isinstance(stride, torch.Tensor) else stride) + + # Convert image size to list if it is an integer + if isinstance(imgsz, int): + imgsz = [imgsz] + elif isinstance(imgsz, (list, tuple)): + imgsz = list(imgsz) + else: + raise TypeError(f"'imgsz={imgsz}' is of invalid type {type(imgsz).__name__}. " + f"Valid imgsz types are int i.e. 'imgsz=640' or list i.e. 'imgsz=[640,640]'") + + # Apply max_dim + if len(imgsz) > max_dim: + msg = "'train' and 'val' imgsz must be an integer, while 'predict' and 'export' imgsz may be a [h, w] list " \ + "or an integer, i.e. 'yolo export imgsz=640,480' or 'yolo export imgsz=640'" + if max_dim != 1: + raise ValueError(f'imgsz={imgsz} is not a valid image size. {msg}') + LOGGER.warning(f"WARNING ⚠️ updating to 'imgsz={max(imgsz)}'. {msg}") + imgsz = [max(imgsz)] + # Make image size a multiple of the stride + sz = [max(math.ceil(x / stride) * stride, floor) for x in imgsz] + + # Print warning message if image size was updated + if sz != imgsz: + LOGGER.warning(f'WARNING ⚠️ imgsz={imgsz} must be multiple of max stride {stride}, updating to {sz}') + + # Add missing dimensions if necessary + sz = [sz[0], sz[0]] if min_dim == 2 and len(sz) == 1 else sz[0] if min_dim == 1 and len(sz) == 1 else sz + + return sz + + +def check_version(current: str = '0.0.0', + required: str = '0.0.0', + name: str = 'version ', + hard: bool = False, + verbose: bool = False) -> bool: + """ + Check current version against the required version or range. + + Args: + current (str): Current version. + required (str): Required version or range (in pip-style format). + name (str): Name to be used in warning message. + hard (bool): If True, raise an AssertionError if the requirement is not met. + verbose (bool): If True, print warning message if requirement is not met. + + Returns: + (bool): True if requirement is met, False otherwise. + + Example: + # check if current version is exactly 22.04 + check_version(current='22.04', required='==22.04') + + # check if current version is greater than or equal to 22.04 + check_version(current='22.10', required='22.04') # assumes '>=' inequality if none passed + + # check if current version is less than or equal to 22.04 + check_version(current='22.04', required='<=22.04') + + # check if current version is between 20.04 (inclusive) and 22.04 (exclusive) + check_version(current='21.10', required='>20.04,<22.04') + """ + current = pkg.parse_version(current) + constraints = re.findall(r'([<>!=]{1,2}\s*\d+\.\d+)', required) or [f'>={required}'] + + result = True + for constraint in constraints: + op, version = re.match(r'([<>!=]{1,2})\s*(\d+\.\d+)', constraint).groups() + version = pkg.parse_version(version) + if op == '==' and current != version: + result = False + elif op == '!=' and current == version: + result = False + elif op == '>=' and not (current >= version): + result = False + elif op == '<=' and not (current <= version): + result = False + elif op == '>' and not (current > version): + result = False + elif op == '<' and not (current < version): + result = False + if not result: + warning_message = f'WARNING ⚠️ {name}{required} is required, but {name}{current} is currently installed' + if hard: + raise ModuleNotFoundError(emojis(warning_message)) # assert version requirements met + if verbose: + LOGGER.warning(warning_message) + return result + + +def check_latest_pypi_version(package_name='ultralytics'): + """ + Returns the latest version of a PyPI package without downloading or installing it. + + Parameters: + package_name (str): The name of the package to find the latest version for. + + Returns: + (str): The latest version of the package. + """ + with contextlib.suppress(Exception): + requests.packages.urllib3.disable_warnings() # Disable the InsecureRequestWarning + response = requests.get(f'https://pypi.org/pypi/{package_name}/json', timeout=3) + if response.status_code == 200: + return response.json()['info']['version'] + + +def check_pip_update_available(): + """ + Checks if a new version of the ultralytics package is available on PyPI. + + Returns: + (bool): True if an update is available, False otherwise. + """ + if ONLINE and is_pip_package(): + with contextlib.suppress(Exception): + from ultralytics import __version__ + latest = check_latest_pypi_version() + if pkg.parse_version(__version__) < pkg.parse_version(latest): # update is available + LOGGER.info(f'New https://pypi.org/project/ultralytics/{latest} available 😃 ' + f"Update with 'pip install -U ultralytics'") + return True + return False + + +@ThreadingLocked() +def check_font(font='Arial.ttf'): + """ + Find font locally or download to user's configuration directory if it does not already exist. + + Args: + font (str): Path or name of font. + + Returns: + file (Path): Resolved font file path. + """ + name = Path(font).name + + # Check USER_CONFIG_DIR + file = USER_CONFIG_DIR / name + if file.exists(): + return file + + # Check system fonts + matches = [s for s in font_manager.findSystemFonts() if font in s] + if any(matches): + return matches[0] + + # Download to USER_CONFIG_DIR if missing + url = f'https://ultralytics.com/assets/{name}' + if downloads.is_url(url): + downloads.safe_download(url=url, file=file) + return file + + +def check_python(minimum: str = '3.8.0') -> bool: + """ + Check current python version against the required minimum version. + + Args: + minimum (str): Required minimum version of python. + + Returns: + None + """ + return check_version(platform.python_version(), minimum, name='Python ', hard=True) + + +@TryExcept() +def check_requirements(requirements=ROOT.parent / 'requirements.txt', exclude=(), install=True, cmds=''): + """ + Check if installed dependencies meet YOLOv8 requirements and attempt to auto-update if needed. + + Args: + requirements (Union[Path, str, List[str]]): Path to a requirements.txt file, a single package requirement as a + string, or a list of package requirements as strings. + exclude (Tuple[str]): Tuple of package names to exclude from checking. + install (bool): If True, attempt to auto-update packages that don't meet requirements. + cmds (str): Additional commands to pass to the pip install command when auto-updating. + + Example: + ```python + from ultralytics.utils.checks import check_requirements + + # Check a requirements.txt file + check_requirements('path/to/requirements.txt') + + # Check a single package + check_requirements('ultralytics>=8.0.0') + + # Check multiple packages + check_requirements(['numpy', 'ultralytics>=8.0.0']) + ``` + """ + prefix = colorstr('red', 'bold', 'requirements:') + check_python() # check python version + check_torchvision() # check torch-torchvision compatibility + if isinstance(requirements, Path): # requirements.txt file + file = requirements.resolve() + assert file.exists(), f'{prefix} {file} not found, check failed.' + with file.open() as f: + requirements = [f'{x.name}{x.specifier}' for x in pkg.parse_requirements(f) if x.name not in exclude] + elif isinstance(requirements, str): + requirements = [requirements] + + pkgs = [] + for r in requirements: + r_stripped = r.split('/')[-1].replace('.git', '') # replace git+https://org/repo.git -> 'repo' + try: + pkg.require(r_stripped) # exception if requirements not met + except pkg.DistributionNotFound: + try: # attempt to import (slower but more accurate) + import importlib + importlib.import_module(next(pkg.parse_requirements(r_stripped)).name) + except ImportError: + pkgs.append(r) + except pkg.VersionConflict: + pkgs.append(r) + + s = ' '.join(f'"{x}"' for x in pkgs) # console string + if s: + if install and AUTOINSTALL: # check environment variable + n = len(pkgs) # number of packages updates + LOGGER.info(f"{prefix} Ultralytics requirement{'s' * (n > 1)} {pkgs} not found, attempting AutoUpdate...") + try: + t = time.time() + assert is_online(), 'AutoUpdate skipped (offline)' + LOGGER.info(subprocess.check_output(f'pip install --no-cache {s} {cmds}', shell=True).decode()) + dt = time.time() - t + LOGGER.info( + f"{prefix} AutoUpdate success ✅ {dt:.1f}s, installed {n} package{'s' * (n > 1)}: {pkgs}\n" + f"{prefix} ⚠️ {colorstr('bold', 'Restart runtime or rerun command for updates to take effect')}\n") + except Exception as e: + LOGGER.warning(f'{prefix} ❌ {e}') + return False + else: + return False + + return True + + +def check_torchvision(): + """ + Checks the installed versions of PyTorch and Torchvision to ensure they're compatible. + + This function checks the installed versions of PyTorch and Torchvision, and warns if they're incompatible according + to the provided compatibility table based on https://github.com/pytorch/vision#installation. The + compatibility table is a dictionary where the keys are PyTorch versions and the values are lists of compatible + Torchvision versions. + """ + + import torchvision + + # Compatibility table + compatibility_table = {'2.0': ['0.15'], '1.13': ['0.14'], '1.12': ['0.13']} + + # Extract only the major and minor versions + v_torch = '.'.join(torch.__version__.split('+')[0].split('.')[:2]) + v_torchvision = '.'.join(torchvision.__version__.split('+')[0].split('.')[:2]) + + if v_torch in compatibility_table: + compatible_versions = compatibility_table[v_torch] + if all(pkg.parse_version(v_torchvision) != pkg.parse_version(v) for v in compatible_versions): + print(f'WARNING ⚠️ torchvision=={v_torchvision} is incompatible with torch=={v_torch}.\n' + f"Run 'pip install torchvision=={compatible_versions[0]}' to fix torchvision or " + "'pip install -U torch torchvision' to update both.\n" + 'For a full compatibility table see https://github.com/pytorch/vision#installation') + + +def check_suffix(file='yolov8n.pt', suffix='.pt', msg=''): + """Check file(s) for acceptable suffix.""" + if file and suffix: + if isinstance(suffix, str): + suffix = (suffix, ) + for f in file if isinstance(file, (list, tuple)) else [file]: + s = Path(f).suffix.lower().strip() # file suffix + if len(s): + assert s in suffix, f'{msg}{f} acceptable suffix is {suffix}, not {s}' + + +def check_yolov5u_filename(file: str, verbose: bool = True): + """Replace legacy YOLOv5 filenames with updated YOLOv5u filenames.""" + if 'yolov3' in file or 'yolov5' in file: + if 'u.yaml' in file: + file = file.replace('u.yaml', '.yaml') # i.e. yolov5nu.yaml -> yolov5n.yaml + elif '.pt' in file and 'u' not in file: + original_file = file + file = re.sub(r'(.*yolov5([nsmlx]))\.pt', '\\1u.pt', file) # i.e. yolov5n.pt -> yolov5nu.pt + file = re.sub(r'(.*yolov5([nsmlx])6)\.pt', '\\1u.pt', file) # i.e. yolov5n6.pt -> yolov5n6u.pt + file = re.sub(r'(.*yolov3(|-tiny|-spp))\.pt', '\\1u.pt', file) # i.e. yolov3-spp.pt -> yolov3-sppu.pt + if file != original_file and verbose: + LOGGER.info( + f"PRO TIP 💡 Replace 'model={original_file}' with new 'model={file}'.\nYOLOv5 'u' models are " + f'trained with https://github.com/ultralytics/ultralytics and feature improved performance vs ' + f'standard YOLOv5 models trained with https://github.com/ultralytics/yolov5.\n') + return file + + +def check_file(file, suffix='', download=True, hard=True): + """Search/download file (if necessary) and return path.""" + check_suffix(file, suffix) # optional + file = str(file).strip() # convert to string and strip spaces + file = check_yolov5u_filename(file) # yolov5n -> yolov5nu + if not file or ('://' not in file and Path(file).exists()): # exists ('://' check required in Windows Python<3.10) + return file + elif download and file.lower().startswith(('https://', 'http://', 'rtsp://', 'rtmp://')): # download + url = file # warning: Pathlib turns :// -> :/ + file = url2file(file) # '%2F' to '/', split https://url.com/file.txt?auth + if Path(file).exists(): + LOGGER.info(f'Found {clean_url(url)} locally at {file}') # file already exists + else: + downloads.safe_download(url=url, file=file, unzip=False) + return file + else: # search + files = glob.glob(str(ROOT / 'cfg' / '**' / file), recursive=True) # find file + if not files and hard: + raise FileNotFoundError(f"'{file}' does not exist") + elif len(files) > 1 and hard: + raise FileNotFoundError(f"Multiple files match '{file}', specify exact path: {files}") + return files[0] if len(files) else [] # return file + + +def check_yaml(file, suffix=('.yaml', '.yml'), hard=True): + """Search/download YAML file (if necessary) and return path, checking suffix.""" + return check_file(file, suffix, hard=hard) + + +def check_imshow(warn=False): + """Check if environment supports image displays.""" + try: + if LINUX: + assert 'DISPLAY' in os.environ and not is_docker() and not is_colab() and not is_kaggle() + cv2.imshow('test', np.zeros((8, 8, 3), dtype=np.uint8)) # show a small 8-pixel image + cv2.waitKey(1) + cv2.destroyAllWindows() + cv2.waitKey(1) + return True + except Exception as e: + if warn: + LOGGER.warning(f'WARNING ⚠️ Environment does not support cv2.imshow() or PIL Image.show()\n{e}') + return False + + +def check_yolo(verbose=True, device=''): + """Return a human-readable YOLO software and hardware summary.""" + from ultralytics.utils.torch_utils import select_device + + if is_jupyter(): + if check_requirements('wandb', install=False): + os.system('pip uninstall -y wandb') # uninstall wandb: unwanted account creation prompt with infinite hang + if is_colab(): + shutil.rmtree('sample_data', ignore_errors=True) # remove colab /sample_data directory + + if verbose: + # System info + gib = 1 << 30 # bytes per GiB + ram = psutil.virtual_memory().total + total, used, free = shutil.disk_usage('/') + s = f'({os.cpu_count()} CPUs, {ram / gib:.1f} GB RAM, {(total - free) / gib:.1f}/{total / gib:.1f} GB disk)' + with contextlib.suppress(Exception): # clear display if ipython is installed + from IPython import display + display.clear_output() + else: + s = '' + + select_device(device=device, newline=False) + LOGGER.info(f'Setup complete ✅ {s}') + + +def check_amp(model): + """ + This function checks the PyTorch Automatic Mixed Precision (AMP) functionality of a YOLOv8 model. + If the checks fail, it means there are anomalies with AMP on the system that may cause NaN losses or zero-mAP + results, so AMP will be disabled during training. + + Args: + model (nn.Module): A YOLOv8 model instance. + + Example: + ```python + from ultralytics import YOLO + from ultralytics.utils.checks import check_amp + + model = YOLO('yolov8n.pt').model.cuda() + check_amp(model) + ``` + + Returns: + (bool): Returns True if the AMP functionality works correctly with YOLOv8 model, else False. + """ + device = next(model.parameters()).device # get model device + if device.type in ('cpu', 'mps'): + return False # AMP only used on CUDA devices + + def amp_allclose(m, im): + """All close FP32 vs AMP results.""" + a = m(im, device=device, verbose=False)[0].boxes.data # FP32 inference + with torch.cuda.amp.autocast(True): + b = m(im, device=device, verbose=False)[0].boxes.data # AMP inference + del m + return a.shape == b.shape and torch.allclose(a, b.float(), atol=0.5) # close to 0.5 absolute tolerance + + im = ASSETS / 'bus.jpg' # image to check + prefix = colorstr('AMP: ') + LOGGER.info(f'{prefix}running Automatic Mixed Precision (AMP) checks with YOLOv8n...') + warning_msg = "Setting 'amp=True'. If you experience zero-mAP or NaN losses you can disable AMP with amp=False." + try: + from ultralytics import YOLO + assert amp_allclose(YOLO('yolov8n.pt'), im) + LOGGER.info(f'{prefix}checks passed ✅') + except ConnectionError: + LOGGER.warning(f'{prefix}checks skipped ⚠️, offline and unable to download YOLOv8n. {warning_msg}') + except (AttributeError, ModuleNotFoundError): + LOGGER.warning( + f'{prefix}checks skipped ⚠️. Unable to load YOLOv8n due to possible Ultralytics package modifications. {warning_msg}' + ) + except AssertionError: + LOGGER.warning(f'{prefix}checks failed ❌. Anomalies were detected with AMP on your system that may lead to ' + f'NaN losses or zero-mAP results, so AMP will be disabled during training.') + return False + return True + + +def git_describe(path=ROOT): # path must be a directory + """Return human-readable git description, i.e. v5.0-5-g3e25f1e https://git-scm.com/docs/git-describe.""" + with contextlib.suppress(Exception): + return subprocess.check_output(f'git -C {path} describe --tags --long --always', shell=True).decode()[:-1] + return '' + + +def print_args(args: Optional[dict] = None, show_file=True, show_func=False): + """Print function arguments (optional args dict).""" + + def strip_auth(v): + """Clean longer Ultralytics HUB URLs by stripping potential authentication information.""" + return clean_url(v) if (isinstance(v, str) and v.startswith('http') and len(v) > 100) else v + + x = inspect.currentframe().f_back # previous frame + file, _, func, _, _ = inspect.getframeinfo(x) + if args is None: # get args automatically + args, _, _, frm = inspect.getargvalues(x) + args = {k: v for k, v in frm.items() if k in args} + try: + file = Path(file).resolve().relative_to(ROOT).with_suffix('') + except ValueError: + file = Path(file).stem + s = (f'{file}: ' if show_file else '') + (f'{func}: ' if show_func else '') + LOGGER.info(colorstr(s) + ', '.join(f'{k}={strip_auth(v)}' for k, v in args.items())) diff --git a/downloads/ultralytics-main/ultralytics/utils/dist.py b/downloads/ultralytics-main/ultralytics/utils/dist.py new file mode 100644 index 000000000..11900985a --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/dist.py @@ -0,0 +1,67 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import os +import re +import shutil +import socket +import sys +import tempfile +from pathlib import Path + +from . import USER_CONFIG_DIR +from .torch_utils import TORCH_1_9 + + +def find_free_network_port() -> int: + """Finds a free port on localhost. + + It is useful in single-node training when we don't want to connect to a real main node but have to set the + `MASTER_PORT` environment variable. + """ + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.bind(('127.0.0.1', 0)) + return s.getsockname()[1] # port + + +def generate_ddp_file(trainer): + """Generates a DDP file and returns its file name.""" + module, name = f'{trainer.__class__.__module__}.{trainer.__class__.__name__}'.rsplit('.', 1) + + content = f'''overrides = {vars(trainer.args)} \nif __name__ == "__main__": + from {module} import {name} + from ultralytics.utils import DEFAULT_CFG_DICT + + cfg = DEFAULT_CFG_DICT.copy() + cfg.update(save_dir='') # handle the extra key 'save_dir' + trainer = {name}(cfg=cfg, overrides=overrides) + trainer.train()''' + (USER_CONFIG_DIR / 'DDP').mkdir(exist_ok=True) + with tempfile.NamedTemporaryFile(prefix='_temp_', + suffix=f'{id(trainer)}.py', + mode='w+', + encoding='utf-8', + dir=USER_CONFIG_DIR / 'DDP', + delete=False) as file: + file.write(content) + return file.name + + +def generate_ddp_command(world_size, trainer): + """Generates and returns command for distributed training.""" + import __main__ # noqa local import to avoid https://github.com/Lightning-AI/lightning/issues/15218 + if not trainer.resume: + shutil.rmtree(trainer.save_dir) # remove the save_dir + file = str(Path(sys.argv[0]).resolve()) + safe_pattern = re.compile(r'^[a-zA-Z0-9_. /\\-]{1,128}$') # allowed characters and maximum of 100 characters + if not (safe_pattern.match(file) and Path(file).exists() and file.endswith('.py')): # using CLI + file = generate_ddp_file(trainer) + dist_cmd = 'torch.distributed.run' if TORCH_1_9 else 'torch.distributed.launch' + port = find_free_network_port() + cmd = [sys.executable, '-m', dist_cmd, '--nproc_per_node', f'{world_size}', '--master_port', f'{port}', file] + return cmd, file + + +def ddp_cleanup(trainer, file): + """Delete temp file if created.""" + if f'{id(trainer)}.py' in file: # if temp_file suffix in file + os.remove(file) diff --git a/downloads/ultralytics-main/ultralytics/utils/downloads.py b/downloads/ultralytics-main/ultralytics/utils/downloads.py new file mode 100644 index 000000000..3171c038a --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/downloads.py @@ -0,0 +1,395 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import contextlib +import re +import shutil +import subprocess +from itertools import repeat +from multiprocessing.pool import ThreadPool +from pathlib import Path +from urllib import parse, request + +import requests +import torch +from tqdm import tqdm + +from ultralytics.utils import LOGGER, TQDM_BAR_FORMAT, checks, clean_url, emojis, is_online, url2file + +GITHUB_ASSET_NAMES = [f'yolov8{k}{suffix}.pt' for k in 'nsmlx' for suffix in ('', '6', '-cls', '-seg', '-pose')] + \ + [f'yolov5{k}u.pt' for k in 'nsmlx'] + \ + [f'yolov3{k}u.pt' for k in ('', '-spp', '-tiny')] + \ + [f'yolo_nas_{k}.pt' for k in 'sml'] + \ + [f'sam_{k}.pt' for k in 'bl'] + \ + [f'FastSAM-{k}.pt' for k in 'sx'] + \ + [f'rtdetr-{k}.pt' for k in 'lx'] + \ + ['mobile_sam.pt'] +GITHUB_ASSET_STEMS = [Path(k).stem for k in GITHUB_ASSET_NAMES] + + +def is_url(url, check=True): + """Check if string is URL and check if URL exists.""" + with contextlib.suppress(Exception): + url = str(url) + result = parse.urlparse(url) + assert all([result.scheme, result.netloc]) # check if is url + if check: + with request.urlopen(url) as response: + return response.getcode() == 200 # check if exists online + return True + return False + + +def delete_dsstore(path): + """ + Deletes all ".DS_store" files under a specified directory. + + Args: + path (str, optional): The directory path where the ".DS_store" files should be deleted. + + Example: + ```python + from ultralytics.data.utils import delete_dsstore + + delete_dsstore('path/to/dir') + ``` + + Note: + ".DS_store" files are created by the Apple operating system and contain metadata about folders and files. They + are hidden system files and can cause issues when transferring files between different operating systems. + """ + # Delete Apple .DS_store files + files = list(Path(path).rglob('.DS_store')) + LOGGER.info(f'Deleting *.DS_store files: {files}') + for f in files: + f.unlink() + + +def zip_directory(directory, compress=True, exclude=('.DS_Store', '__MACOSX'), progress=True): + """ + Zips the contents of a directory, excluding files containing strings in the exclude list. + The resulting zip file is named after the directory and placed alongside it. + + Args: + directory (str | Path): The path to the directory to be zipped. + compress (bool): Whether to compress the files while zipping. Default is True. + exclude (tuple, optional): A tuple of filename strings to be excluded. Defaults to ('.DS_Store', '__MACOSX'). + progress (bool, optional): Whether to display a progress bar. Defaults to True. + + Returns: + (Path): The path to the resulting zip file. + + Example: + ```python + from ultralytics.utils.downloads import zip_directory + + file = zip_directory('path/to/dir') + ``` + """ + from zipfile import ZIP_DEFLATED, ZIP_STORED, ZipFile + + delete_dsstore(directory) + directory = Path(directory) + if not directory.is_dir(): + raise FileNotFoundError(f"Directory '{directory}' does not exist.") + + # Unzip with progress bar + files_to_zip = [f for f in directory.rglob('*') if f.is_file() and all(x not in f.name for x in exclude)] + zip_file = directory.with_suffix('.zip') + compression = ZIP_DEFLATED if compress else ZIP_STORED + with ZipFile(zip_file, 'w', compression) as f: + for file in tqdm(files_to_zip, desc=f'Zipping {directory} to {zip_file}...', unit='file', disable=not progress): + f.write(file, file.relative_to(directory)) + + return zip_file # return path to zip file + + +def unzip_file(file, path=None, exclude=('.DS_Store', '__MACOSX'), exist_ok=False, progress=True): + """ + Unzips a *.zip file to the specified path, excluding files containing strings in the exclude list. + + If the zipfile does not contain a single top-level directory, the function will create a new + directory with the same name as the zipfile (without the extension) to extract its contents. + If a path is not provided, the function will use the parent directory of the zipfile as the default path. + + Args: + file (str): The path to the zipfile to be extracted. + path (str, optional): The path to extract the zipfile to. Defaults to None. + exclude (tuple, optional): A tuple of filename strings to be excluded. Defaults to ('.DS_Store', '__MACOSX'). + exist_ok (bool, optional): Whether to overwrite existing contents if they exist. Defaults to False. + progress (bool, optional): Whether to display a progress bar. Defaults to True. + + Raises: + BadZipFile: If the provided file does not exist or is not a valid zipfile. + + Returns: + (Path): The path to the directory where the zipfile was extracted. + + Example: + ```python + from ultralytics.utils.downloads import unzip_file + + dir = unzip_file('path/to/file.zip') + ``` + """ + from zipfile import BadZipFile, ZipFile, is_zipfile + + if not (Path(file).exists() and is_zipfile(file)): + raise BadZipFile(f"File '{file}' does not exist or is a bad zip file.") + if path is None: + path = Path(file).parent # default path + + # Unzip the file contents + with ZipFile(file) as zipObj: + files = [f for f in zipObj.namelist() if all(x not in f for x in exclude)] + top_level_dirs = {Path(f).parts[0] for f in files} + + if len(top_level_dirs) > 1 or not files[0].endswith('/'): # zip has multiple files at top level + path = extract_path = Path(path) / Path(file).stem # i.e. ../datasets/coco8 + else: # zip has 1 top-level directory + extract_path = path # i.e. ../datasets + path = Path(path) / list(top_level_dirs)[0] # i.e. ../datasets/coco8 + + # Check if destination directory already exists and contains files + if path.exists() and any(path.iterdir()) and not exist_ok: + # If it exists and is not empty, return the path without unzipping + LOGGER.info(f'Skipping {file} unzip (already unzipped)') + return path + + for f in tqdm(files, desc=f'Unzipping {file} to {Path(path).resolve()}...', unit='file', disable=not progress): + zipObj.extract(f, path=extract_path) + + return path # return unzip dir + + +def check_disk_space(url='https://ultralytics.com/assets/coco128.zip', sf=1.5, hard=True): + """ + Check if there is sufficient disk space to download and store a file. + + Args: + url (str, optional): The URL to the file. Defaults to 'https://ultralytics.com/assets/coco128.zip'. + sf (float, optional): Safety factor, the multiplier for the required free space. Defaults to 2.0. + hard (bool, optional): Whether to throw an error or not on insufficient disk space. Defaults to True. + + Returns: + (bool): True if there is sufficient disk space, False otherwise. + """ + with contextlib.suppress(Exception): + gib = 1 << 30 # bytes per GiB + data = int(requests.head(url).headers['Content-Length']) / gib # file size (GB) + total, used, free = (x / gib for x in shutil.disk_usage('/')) # bytes + if data * sf < free: + return True # sufficient space + + # Insufficient space + text = (f'WARNING ⚠️ Insufficient free disk space {free:.1f} GB < {data * sf:.3f} GB required, ' + f'Please free {data * sf - free:.1f} GB additional disk space and try again.') + if hard: + raise MemoryError(text) + LOGGER.warning(text) + return False + + return True + + +def get_google_drive_file_info(link): + """ + Retrieves the direct download link and filename for a shareable Google Drive file link. + + Args: + link (str): The shareable link of the Google Drive file. + + Returns: + (str): Direct download URL for the Google Drive file. + (str): Original filename of the Google Drive file. If filename extraction fails, returns None. + + Example: + ```python + from ultralytics.utils.downloads import get_google_drive_file_info + + link = "https://drive.google.com/file/d/1cqT-cJgANNrhIHCrEufUYhQ4RqiWG_lJ/view?usp=drive_link" + url, filename = get_google_drive_file_info(link) + ``` + """ + file_id = link.split('/d/')[1].split('/view')[0] + drive_url = f'https://drive.google.com/uc?export=download&id={file_id}' + filename = None + + # Start session + with requests.Session() as session: + response = session.get(drive_url, stream=True) + if 'quota exceeded' in str(response.content.lower()): + raise ConnectionError( + emojis(f'❌ Google Drive file download quota exceeded. ' + f'Please try again later or download this file manually at {link}.')) + for k, v in response.cookies.items(): + if k.startswith('download_warning'): + drive_url += f'&confirm={v}' # v is token + cd = response.headers.get('content-disposition') + if cd: + filename = re.findall('filename="(.+)"', cd)[0] + return drive_url, filename + + +def safe_download(url, + file=None, + dir=None, + unzip=True, + delete=False, + curl=False, + retry=3, + min_bytes=1E0, + progress=True): + """ + Downloads files from a URL, with options for retrying, unzipping, and deleting the downloaded file. + + Args: + url (str): The URL of the file to be downloaded. + file (str, optional): The filename of the downloaded file. + If not provided, the file will be saved with the same name as the URL. + dir (str, optional): The directory to save the downloaded file. + If not provided, the file will be saved in the current working directory. + unzip (bool, optional): Whether to unzip the downloaded file. Default: True. + delete (bool, optional): Whether to delete the downloaded file after unzipping. Default: False. + curl (bool, optional): Whether to use curl command line tool for downloading. Default: False. + retry (int, optional): The number of times to retry the download in case of failure. Default: 3. + min_bytes (float, optional): The minimum number of bytes that the downloaded file should have, to be considered + a successful download. Default: 1E0. + progress (bool, optional): Whether to display a progress bar during the download. Default: True. + """ + + # Check if the URL is a Google Drive link + gdrive = 'drive.google.com' in url + if gdrive: + url, file = get_google_drive_file_info(url) + + f = dir / (file if gdrive else url2file(url)) if dir else Path(file) # URL converted to filename + if '://' not in str(url) and Path(url).is_file(): # URL exists ('://' check required in Windows Python<3.10) + f = Path(url) # filename + elif not f.is_file(): # URL and file do not exist + assert dir or file, 'dir or file required for download' + desc = f"Downloading {url if gdrive else clean_url(url)} to '{f}'" + LOGGER.info(f'{desc}...') + f.parent.mkdir(parents=True, exist_ok=True) # make directory if missing + check_disk_space(url) + for i in range(retry + 1): + try: + if curl or i > 0: # curl download with retry, continue + s = 'sS' * (not progress) # silent + r = subprocess.run(['curl', '-#', f'-{s}L', url, '-o', f, '--retry', '3', '-C', '-']).returncode + assert r == 0, f'Curl return value {r}' + else: # urllib download + method = 'torch' + if method == 'torch': + torch.hub.download_url_to_file(url, f, progress=progress) + else: + with request.urlopen(url) as response, tqdm(total=int(response.getheader('Content-Length', 0)), + desc=desc, + disable=not progress, + unit='B', + unit_scale=True, + unit_divisor=1024, + bar_format=TQDM_BAR_FORMAT) as pbar: + with open(f, 'wb') as f_opened: + for data in response: + f_opened.write(data) + pbar.update(len(data)) + + if f.exists(): + if f.stat().st_size > min_bytes: + break # success + f.unlink() # remove partial downloads + except Exception as e: + if i == 0 and not is_online(): + raise ConnectionError(emojis(f'❌ Download failure for {url}. Environment is not online.')) from e + elif i >= retry: + raise ConnectionError(emojis(f'❌ Download failure for {url}. Retry limit reached.')) from e + LOGGER.warning(f'⚠️ Download failure, retrying {i + 1}/{retry} {url}...') + + if unzip and f.exists() and f.suffix in ('', '.zip', '.tar', '.gz'): + from zipfile import is_zipfile + + unzip_dir = dir or f.parent # unzip to dir if provided else unzip in place + if is_zipfile(f): + unzip_dir = unzip_file(file=f, path=unzip_dir, progress=progress) # unzip + elif f.suffix in ('.tar', '.gz'): + LOGGER.info(f'Unzipping {f} to {unzip_dir.resolve()}...') + subprocess.run(['tar', 'xf' if f.suffix == '.tar' else 'xfz', f, '--directory', unzip_dir], check=True) + if delete: + f.unlink() # remove zip + return unzip_dir + + +def get_github_assets(repo='ultralytics/assets', version='latest', retry=False): + """Return GitHub repo tag and assets (i.e. ['yolov8n.pt', 'yolov8s.pt', ...]).""" + if version != 'latest': + version = f'tags/{version}' # i.e. tags/v6.2 + url = f'https://api.github.com/repos/{repo}/releases/{version}' + r = requests.get(url) # github api + if r.status_code != 200 and retry: + r = requests.get(url) # try again + if r.status_code != 200: + LOGGER.warning(f'⚠️ GitHub assets check failure for {url}: {r.status_code} {r.reason}') + return '', [] + data = r.json() + return data['tag_name'], [x['name'] for x in data['assets']] # tag, assets + + +def attempt_download_asset(file, repo='ultralytics/assets', release='v0.0.0'): + """Attempt file download from GitHub release assets if not found locally. release = 'latest', 'v6.2', etc.""" + from ultralytics.utils import SETTINGS # scoped for circular import + + # YOLOv3/5u updates + file = str(file) + file = checks.check_yolov5u_filename(file) + file = Path(file.strip().replace("'", '')) + if file.exists(): + return str(file) + elif (SETTINGS['weights_dir'] / file).exists(): + return str(SETTINGS['weights_dir'] / file) + else: + # URL specified + name = Path(parse.unquote(str(file))).name # decode '%2F' to '/' etc. + if str(file).startswith(('http:/', 'https:/')): # download + url = str(file).replace(':/', '://') # Pathlib turns :// -> :/ + file = url2file(name) # parse authentication https://url.com/file.txt?auth... + if Path(file).is_file(): + LOGGER.info(f'Found {clean_url(url)} locally at {file}') # file already exists + else: + safe_download(url=url, file=file, min_bytes=1E5) + return file + + # GitHub assets + assets = GITHUB_ASSET_NAMES + try: + tag, assets = get_github_assets(repo, release) + except Exception: + try: + tag, assets = get_github_assets(repo) # latest release + except Exception: + try: + tag = subprocess.check_output(['git', 'tag']).decode().split()[-1] + except Exception: + tag = release + + file.parent.mkdir(parents=True, exist_ok=True) # make parent dir (if required) + if name in assets: + safe_download(url=f'https://github.com/{repo}/releases/download/{tag}/{name}', file=file, min_bytes=1E5) + + return str(file) + + +def download(url, dir=Path.cwd(), unzip=True, delete=False, curl=False, threads=1, retry=3): + """Downloads and unzips files concurrently if threads > 1, else sequentially.""" + dir = Path(dir) + dir.mkdir(parents=True, exist_ok=True) # make directory + if threads > 1: + with ThreadPool(threads) as pool: + pool.map( + lambda x: safe_download( + url=x[0], dir=x[1], unzip=unzip, delete=delete, curl=curl, retry=retry, progress=threads <= 1), + zip(url, repeat(dir))) + pool.close() + pool.join() + else: + for u in [url] if isinstance(url, (str, Path)) else url: + safe_download(url=u, dir=dir, unzip=unzip, delete=delete, curl=curl, retry=retry) diff --git a/downloads/ultralytics-main/ultralytics/utils/errors.py b/downloads/ultralytics-main/ultralytics/utils/errors.py new file mode 100644 index 000000000..5a7643186 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/errors.py @@ -0,0 +1,10 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from ultralytics.utils import emojis + + +class HUBModelError(Exception): + + def __init__(self, message='Model not found. Please check model URL and try again.'): + """Create an exception for when a model is not found.""" + super().__init__(emojis(message)) diff --git a/downloads/ultralytics-main/ultralytics/utils/files.py b/downloads/ultralytics-main/ultralytics/utils/files.py new file mode 100644 index 000000000..0102c4b6a --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/files.py @@ -0,0 +1,147 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import contextlib +import glob +import os +import shutil +import tempfile +from contextlib import contextmanager +from datetime import datetime +from pathlib import Path + + +class WorkingDirectory(contextlib.ContextDecorator): + """Usage: @WorkingDirectory(dir) decorator or 'with WorkingDirectory(dir):' context manager.""" + + def __init__(self, new_dir): + """Sets the working directory to 'new_dir' upon instantiation.""" + self.dir = new_dir # new dir + self.cwd = Path.cwd().resolve() # current dir + + def __enter__(self): + """Changes the current directory to the specified directory.""" + os.chdir(self.dir) + + def __exit__(self, exc_type, exc_val, exc_tb): # noqa + """Restore the current working directory on context exit.""" + os.chdir(self.cwd) + + +@contextmanager +def spaces_in_path(path): + """ + Context manager to handle paths with spaces in their names. + If a path contains spaces, it replaces them with underscores, copies the file/directory to the new path, + executes the context code block, then copies the file/directory back to its original location. + + Args: + path (str | Path): The original path. + + Yields: + (Path): Temporary path with spaces replaced by underscores if spaces were present, otherwise the original path. + + Example: + ```python + with ultralytics.utils.files import spaces_in_path + + with spaces_in_path('/path/with spaces') as new_path: + # your code here + ``` + """ + + # If path has spaces, replace them with underscores + if ' ' in str(path): + string = isinstance(path, str) # input type + path = Path(path) + + # Create a temporary directory and construct the new path + with tempfile.TemporaryDirectory() as tmp_dir: + tmp_path = Path(tmp_dir) / path.name.replace(' ', '_') + + # Copy file/directory + if path.is_dir(): + # tmp_path.mkdir(parents=True, exist_ok=True) + shutil.copytree(path, tmp_path) + elif path.is_file(): + tmp_path.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(path, tmp_path) + + try: + # Yield the temporary path + yield str(tmp_path) if string else tmp_path + + finally: + # Copy file/directory back + if tmp_path.is_dir(): + shutil.copytree(tmp_path, path, dirs_exist_ok=True) + elif tmp_path.is_file(): + shutil.copy2(tmp_path, path) # Copy back the file + + else: + # If there are no spaces, just yield the original path + yield path + + +def increment_path(path, exist_ok=False, sep='', mkdir=False): + """ + Increments a file or directory path, i.e. runs/exp --> runs/exp{sep}2, runs/exp{sep}3, ... etc. + + If the path exists and exist_ok is not set to True, the path will be incremented by appending a number and sep to + the end of the path. If the path is a file, the file extension will be preserved. If the path is a directory, the + number will be appended directly to the end of the path. If mkdir is set to True, the path will be created as a + directory if it does not already exist. + + Args: + path (str, pathlib.Path): Path to increment. + exist_ok (bool, optional): If True, the path will not be incremented and returned as-is. Defaults to False. + sep (str, optional): Separator to use between the path and the incrementation number. Defaults to ''. + mkdir (bool, optional): Create a directory if it does not exist. Defaults to False. + + Returns: + (pathlib.Path): Incremented path. + """ + path = Path(path) # os-agnostic + if path.exists() and not exist_ok: + path, suffix = (path.with_suffix(''), path.suffix) if path.is_file() else (path, '') + + # Method 1 + for n in range(2, 9999): + p = f'{path}{sep}{n}{suffix}' # increment path + if not os.path.exists(p): # + break + path = Path(p) + + if mkdir: + path.mkdir(parents=True, exist_ok=True) # make directory + + return path + + +def file_age(path=__file__): + """Return days since last file update.""" + dt = (datetime.now() - datetime.fromtimestamp(Path(path).stat().st_mtime)) # delta + return dt.days # + dt.seconds / 86400 # fractional days + + +def file_date(path=__file__): + """Return human-readable file modification date, i.e. '2021-3-26'.""" + t = datetime.fromtimestamp(Path(path).stat().st_mtime) + return f'{t.year}-{t.month}-{t.day}' + + +def file_size(path): + """Return file/dir size (MB).""" + if isinstance(path, (str, Path)): + mb = 1 << 20 # bytes to MiB (1024 ** 2) + path = Path(path) + if path.is_file(): + return path.stat().st_size / mb + elif path.is_dir(): + return sum(f.stat().st_size for f in path.glob('**/*') if f.is_file()) / mb + return 0.0 + + +def get_latest_run(search_dir='.'): + """Return path to most recent 'last.pt' in /runs (i.e. to --resume from).""" + last_list = glob.glob(f'{search_dir}/**/last*.pt', recursive=True) + return max(last_list, key=os.path.getctime) if last_list else '' diff --git a/downloads/ultralytics-main/ultralytics/utils/instance.py b/downloads/ultralytics-main/ultralytics/utils/instance.py new file mode 100644 index 000000000..4e2e43809 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/instance.py @@ -0,0 +1,370 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from collections import abc +from itertools import repeat +from numbers import Number +from typing import List + +import numpy as np + +from .ops import ltwh2xywh, ltwh2xyxy, resample_segments, xywh2ltwh, xywh2xyxy, xyxy2ltwh, xyxy2xywh + + +def _ntuple(n): + """From PyTorch internals.""" + + def parse(x): + """Parse bounding boxes format between XYWH and LTWH.""" + return x if isinstance(x, abc.Iterable) else tuple(repeat(x, n)) + + return parse + + +to_2tuple = _ntuple(2) +to_4tuple = _ntuple(4) + +# `xyxy` means left top and right bottom +# `xywh` means center x, center y and width, height(YOLO format) +# `ltwh` means left top and width, height(COCO format) +_formats = ['xyxy', 'xywh', 'ltwh'] + +__all__ = 'Bboxes', # tuple or list + + +class Bboxes: + """Bounding Boxes class. Only numpy variables are supported.""" + + def __init__(self, bboxes, format='xyxy') -> None: + assert format in _formats, f'Invalid bounding box format: {format}, format must be one of {_formats}' + bboxes = bboxes[None, :] if bboxes.ndim == 1 else bboxes + assert bboxes.ndim == 2 + assert bboxes.shape[1] == 4 + self.bboxes = bboxes + self.format = format + # self.normalized = normalized + + def convert(self, format): + """Converts bounding box format from one type to another.""" + assert format in _formats, f'Invalid bounding box format: {format}, format must be one of {_formats}' + if self.format == format: + return + elif self.format == 'xyxy': + func = xyxy2xywh if format == 'xywh' else xyxy2ltwh + elif self.format == 'xywh': + func = xywh2xyxy if format == 'xyxy' else xywh2ltwh + else: + func = ltwh2xyxy if format == 'xyxy' else ltwh2xywh + self.bboxes = func(self.bboxes) + self.format = format + + def areas(self): + """Return box areas.""" + self.convert('xyxy') + return (self.bboxes[:, 2] - self.bboxes[:, 0]) * (self.bboxes[:, 3] - self.bboxes[:, 1]) + + # def denormalize(self, w, h): + # if not self.normalized: + # return + # assert (self.bboxes <= 1.0).all() + # self.bboxes[:, 0::2] *= w + # self.bboxes[:, 1::2] *= h + # self.normalized = False + # + # def normalize(self, w, h): + # if self.normalized: + # return + # assert (self.bboxes > 1.0).any() + # self.bboxes[:, 0::2] /= w + # self.bboxes[:, 1::2] /= h + # self.normalized = True + + def mul(self, scale): + """ + Args: + scale (tuple | list | int): the scale for four coords. + """ + if isinstance(scale, Number): + scale = to_4tuple(scale) + assert isinstance(scale, (tuple, list)) + assert len(scale) == 4 + self.bboxes[:, 0] *= scale[0] + self.bboxes[:, 1] *= scale[1] + self.bboxes[:, 2] *= scale[2] + self.bboxes[:, 3] *= scale[3] + + def add(self, offset): + """ + Args: + offset (tuple | list | int): the offset for four coords. + """ + if isinstance(offset, Number): + offset = to_4tuple(offset) + assert isinstance(offset, (tuple, list)) + assert len(offset) == 4 + self.bboxes[:, 0] += offset[0] + self.bboxes[:, 1] += offset[1] + self.bboxes[:, 2] += offset[2] + self.bboxes[:, 3] += offset[3] + + def __len__(self): + """Return the number of boxes.""" + return len(self.bboxes) + + @classmethod + def concatenate(cls, boxes_list: List['Bboxes'], axis=0) -> 'Bboxes': + """ + Concatenate a list of Bboxes objects into a single Bboxes object. + + Args: + boxes_list (List[Bboxes]): A list of Bboxes objects to concatenate. + axis (int, optional): The axis along which to concatenate the bounding boxes. + Defaults to 0. + + Returns: + Bboxes: A new Bboxes object containing the concatenated bounding boxes. + + Note: + The input should be a list or tuple of Bboxes objects. + """ + assert isinstance(boxes_list, (list, tuple)) + if not boxes_list: + return cls(np.empty(0)) + assert all(isinstance(box, Bboxes) for box in boxes_list) + + if len(boxes_list) == 1: + return boxes_list[0] + return cls(np.concatenate([b.bboxes for b in boxes_list], axis=axis)) + + def __getitem__(self, index) -> 'Bboxes': + """ + Retrieve a specific bounding box or a set of bounding boxes using indexing. + + Args: + index (int, slice, or np.ndarray): The index, slice, or boolean array to select + the desired bounding boxes. + + Returns: + Bboxes: A new Bboxes object containing the selected bounding boxes. + + Raises: + AssertionError: If the indexed bounding boxes do not form a 2-dimensional matrix. + + Note: + When using boolean indexing, make sure to provide a boolean array with the same + length as the number of bounding boxes. + """ + if isinstance(index, int): + return Bboxes(self.bboxes[index].view(1, -1)) + b = self.bboxes[index] + assert b.ndim == 2, f'Indexing on Bboxes with {index} failed to return a matrix!' + return Bboxes(b) + + +class Instances: + + def __init__(self, bboxes, segments=None, keypoints=None, bbox_format='xywh', normalized=True) -> None: + """ + Args: + bboxes (ndarray): bboxes with shape [N, 4]. + segments (list | ndarray): segments. + keypoints (ndarray): keypoints(x, y, visible) with shape [N, 17, 3]. + """ + if segments is None: + segments = [] + self._bboxes = Bboxes(bboxes=bboxes, format=bbox_format) + self.keypoints = keypoints + self.normalized = normalized + + if len(segments) > 0: + # list[np.array(1000, 2)] * num_samples + segments = resample_segments(segments) + # (N, 1000, 2) + segments = np.stack(segments, axis=0) + else: + segments = np.zeros((0, 1000, 2), dtype=np.float32) + self.segments = segments + + def convert_bbox(self, format): + """Convert bounding box format.""" + self._bboxes.convert(format=format) + + @property + def bbox_areas(self): + """Calculate the area of bounding boxes.""" + return self._bboxes.areas() + + def scale(self, scale_w, scale_h, bbox_only=False): + """this might be similar with denormalize func but without normalized sign.""" + self._bboxes.mul(scale=(scale_w, scale_h, scale_w, scale_h)) + if bbox_only: + return + self.segments[..., 0] *= scale_w + self.segments[..., 1] *= scale_h + if self.keypoints is not None: + self.keypoints[..., 0] *= scale_w + self.keypoints[..., 1] *= scale_h + + def denormalize(self, w, h): + """Denormalizes boxes, segments, and keypoints from normalized coordinates.""" + if not self.normalized: + return + self._bboxes.mul(scale=(w, h, w, h)) + self.segments[..., 0] *= w + self.segments[..., 1] *= h + if self.keypoints is not None: + self.keypoints[..., 0] *= w + self.keypoints[..., 1] *= h + self.normalized = False + + def normalize(self, w, h): + """Normalize bounding boxes, segments, and keypoints to image dimensions.""" + if self.normalized: + return + self._bboxes.mul(scale=(1 / w, 1 / h, 1 / w, 1 / h)) + self.segments[..., 0] /= w + self.segments[..., 1] /= h + if self.keypoints is not None: + self.keypoints[..., 0] /= w + self.keypoints[..., 1] /= h + self.normalized = True + + def add_padding(self, padw, padh): + """Handle rect and mosaic situation.""" + assert not self.normalized, 'you should add padding with absolute coordinates.' + self._bboxes.add(offset=(padw, padh, padw, padh)) + self.segments[..., 0] += padw + self.segments[..., 1] += padh + if self.keypoints is not None: + self.keypoints[..., 0] += padw + self.keypoints[..., 1] += padh + + def __getitem__(self, index) -> 'Instances': + """ + Retrieve a specific instance or a set of instances using indexing. + + Args: + index (int, slice, or np.ndarray): The index, slice, or boolean array to select + the desired instances. + + Returns: + Instances: A new Instances object containing the selected bounding boxes, + segments, and keypoints if present. + + Note: + When using boolean indexing, make sure to provide a boolean array with the same + length as the number of instances. + """ + segments = self.segments[index] if len(self.segments) else self.segments + keypoints = self.keypoints[index] if self.keypoints is not None else None + bboxes = self.bboxes[index] + bbox_format = self._bboxes.format + return Instances( + bboxes=bboxes, + segments=segments, + keypoints=keypoints, + bbox_format=bbox_format, + normalized=self.normalized, + ) + + def flipud(self, h): + """Flips the coordinates of bounding boxes, segments, and keypoints vertically.""" + if self._bboxes.format == 'xyxy': + y1 = self.bboxes[:, 1].copy() + y2 = self.bboxes[:, 3].copy() + self.bboxes[:, 1] = h - y2 + self.bboxes[:, 3] = h - y1 + else: + self.bboxes[:, 1] = h - self.bboxes[:, 1] + self.segments[..., 1] = h - self.segments[..., 1] + if self.keypoints is not None: + self.keypoints[..., 1] = h - self.keypoints[..., 1] + + def fliplr(self, w): + """Reverses the order of the bounding boxes and segments horizontally.""" + if self._bboxes.format == 'xyxy': + x1 = self.bboxes[:, 0].copy() + x2 = self.bboxes[:, 2].copy() + self.bboxes[:, 0] = w - x2 + self.bboxes[:, 2] = w - x1 + else: + self.bboxes[:, 0] = w - self.bboxes[:, 0] + self.segments[..., 0] = w - self.segments[..., 0] + if self.keypoints is not None: + self.keypoints[..., 0] = w - self.keypoints[..., 0] + + def clip(self, w, h): + """Clips bounding boxes, segments, and keypoints values to stay within image boundaries.""" + ori_format = self._bboxes.format + self.convert_bbox(format='xyxy') + self.bboxes[:, [0, 2]] = self.bboxes[:, [0, 2]].clip(0, w) + self.bboxes[:, [1, 3]] = self.bboxes[:, [1, 3]].clip(0, h) + if ori_format != 'xyxy': + self.convert_bbox(format=ori_format) + self.segments[..., 0] = self.segments[..., 0].clip(0, w) + self.segments[..., 1] = self.segments[..., 1].clip(0, h) + if self.keypoints is not None: + self.keypoints[..., 0] = self.keypoints[..., 0].clip(0, w) + self.keypoints[..., 1] = self.keypoints[..., 1].clip(0, h) + + def remove_zero_area_boxes(self): + """Remove zero-area boxes, i.e. after clipping some boxes may have zero width or height. This removes them.""" + good = self.bbox_areas > 0 + if not all(good): + self._bboxes = self._bboxes[good] + if len(self.segments): + self.segments = self.segments[good] + if self.keypoints is not None: + self.keypoints = self.keypoints[good] + return good + + def update(self, bboxes, segments=None, keypoints=None): + """Updates instance variables.""" + self._bboxes = Bboxes(bboxes, format=self._bboxes.format) + if segments is not None: + self.segments = segments + if keypoints is not None: + self.keypoints = keypoints + + def __len__(self): + """Return the length of the instance list.""" + return len(self.bboxes) + + @classmethod + def concatenate(cls, instances_list: List['Instances'], axis=0) -> 'Instances': + """ + Concatenates a list of Instances objects into a single Instances object. + + Args: + instances_list (List[Instances]): A list of Instances objects to concatenate. + axis (int, optional): The axis along which the arrays will be concatenated. Defaults to 0. + + Returns: + Instances: A new Instances object containing the concatenated bounding boxes, + segments, and keypoints if present. + + Note: + The `Instances` objects in the list should have the same properties, such as + the format of the bounding boxes, whether keypoints are present, and if the + coordinates are normalized. + """ + assert isinstance(instances_list, (list, tuple)) + if not instances_list: + return cls(np.empty(0)) + assert all(isinstance(instance, Instances) for instance in instances_list) + + if len(instances_list) == 1: + return instances_list[0] + + use_keypoint = instances_list[0].keypoints is not None + bbox_format = instances_list[0]._bboxes.format + normalized = instances_list[0].normalized + + cat_boxes = np.concatenate([ins.bboxes for ins in instances_list], axis=axis) + cat_segments = np.concatenate([b.segments for b in instances_list], axis=axis) + cat_keypoints = np.concatenate([b.keypoints for b in instances_list], axis=axis) if use_keypoint else None + return cls(cat_boxes, cat_segments, cat_keypoints, bbox_format, normalized) + + @property + def bboxes(self): + """Return bounding boxes.""" + return self._bboxes.bboxes diff --git a/downloads/ultralytics-main/ultralytics/utils/loss.py b/downloads/ultralytics-main/ultralytics/utils/loss.py new file mode 100644 index 000000000..1da0586c8 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/loss.py @@ -0,0 +1,392 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import torch +import torch.nn as nn +import torch.nn.functional as F + +from ultralytics.utils.metrics import OKS_SIGMA +from ultralytics.utils.ops import crop_mask, xywh2xyxy, xyxy2xywh +from ultralytics.utils.tal import TaskAlignedAssigner, dist2bbox, make_anchors + +from .metrics import bbox_iou +from .tal import bbox2dist + + +class VarifocalLoss(nn.Module): + """Varifocal loss by Zhang et al. https://arxiv.org/abs/2008.13367.""" + + def __init__(self): + """Initialize the VarifocalLoss class.""" + super().__init__() + + def forward(self, pred_score, gt_score, label, alpha=0.75, gamma=2.0): + """Computes varfocal loss.""" + weight = alpha * pred_score.sigmoid().pow(gamma) * (1 - label) + gt_score * label + with torch.cuda.amp.autocast(enabled=False): + loss = (F.binary_cross_entropy_with_logits(pred_score.float(), gt_score.float(), reduction='none') * + weight).mean(1).sum() + return loss + + +# Losses +class FocalLoss(nn.Module): + """Wraps focal loss around existing loss_fcn(), i.e. criteria = FocalLoss(nn.BCEWithLogitsLoss(), gamma=1.5).""" + + def __init__(self, ): + super().__init__() + + def forward(self, pred, label, gamma=1.5, alpha=0.25): + """Calculates and updates confusion matrix for object detection/classification tasks.""" + loss = F.binary_cross_entropy_with_logits(pred, label, reduction='none') + # p_t = torch.exp(-loss) + # loss *= self.alpha * (1.000001 - p_t) ** self.gamma # non-zero power for gradient stability + + # TF implementation https://github.com/tensorflow/addons/blob/v0.7.1/tensorflow_addons/losses/focal_loss.py + pred_prob = pred.sigmoid() # prob from logits + p_t = label * pred_prob + (1 - label) * (1 - pred_prob) + modulating_factor = (1.0 - p_t) ** gamma + loss *= modulating_factor + if alpha > 0: + alpha_factor = label * alpha + (1 - label) * (1 - alpha) + loss *= alpha_factor + return loss.mean(1).sum() + + +class BboxLoss(nn.Module): + + def __init__(self, reg_max, use_dfl=False): + """Initialize the BboxLoss module with regularization maximum and DFL settings.""" + super().__init__() + self.reg_max = reg_max + self.use_dfl = use_dfl + + def forward(self, pred_dist, pred_bboxes, anchor_points, target_bboxes, target_scores, target_scores_sum, fg_mask): + """IoU loss.""" + weight = target_scores.sum(-1)[fg_mask].unsqueeze(-1) + iou = bbox_iou(pred_bboxes[fg_mask], target_bboxes[fg_mask], xywh=False, CIoU=True) + loss_iou = ((1.0 - iou) * weight).sum() / target_scores_sum + + # DFL loss + if self.use_dfl: + target_ltrb = bbox2dist(anchor_points, target_bboxes, self.reg_max) + loss_dfl = self._df_loss(pred_dist[fg_mask].view(-1, self.reg_max + 1), target_ltrb[fg_mask]) * weight + loss_dfl = loss_dfl.sum() / target_scores_sum + else: + loss_dfl = torch.tensor(0.0).to(pred_dist.device) + + return loss_iou, loss_dfl + + @staticmethod + def _df_loss(pred_dist, target): + """Return sum of left and right DFL losses.""" + # Distribution Focal Loss (DFL) proposed in Generalized Focal Loss https://ieeexplore.ieee.org/document/9792391 + tl = target.long() # target left + tr = tl + 1 # target right + wl = tr - target # weight left + wr = 1 - wl # weight right + return (F.cross_entropy(pred_dist, tl.view(-1), reduction='none').view(tl.shape) * wl + + F.cross_entropy(pred_dist, tr.view(-1), reduction='none').view(tl.shape) * wr).mean(-1, keepdim=True) + + +class KeypointLoss(nn.Module): + + def __init__(self, sigmas) -> None: + super().__init__() + self.sigmas = sigmas + + def forward(self, pred_kpts, gt_kpts, kpt_mask, area): + """Calculates keypoint loss factor and Euclidean distance loss for predicted and actual keypoints.""" + d = (pred_kpts[..., 0] - gt_kpts[..., 0]) ** 2 + (pred_kpts[..., 1] - gt_kpts[..., 1]) ** 2 + kpt_loss_factor = (torch.sum(kpt_mask != 0) + torch.sum(kpt_mask == 0)) / (torch.sum(kpt_mask != 0) + 1e-9) + # e = d / (2 * (area * self.sigmas) ** 2 + 1e-9) # from formula + e = d / (2 * self.sigmas) ** 2 / (area + 1e-9) / 2 # from cocoeval + return kpt_loss_factor * ((1 - torch.exp(-e)) * kpt_mask).mean() + + +# Criterion class for computing Detection training losses +class v8DetectionLoss: + + def __init__(self, model): # model must be de-paralleled + + device = next(model.parameters()).device # get model device + h = model.args # hyperparameters + + m = model.model[-1] # Detect() module + self.bce = nn.BCEWithLogitsLoss(reduction='none') + self.hyp = h + self.stride = m.stride # model strides + self.nc = m.nc # number of classes + self.no = m.no + self.reg_max = m.reg_max + self.device = device + + self.use_dfl = m.reg_max > 1 + + self.assigner = TaskAlignedAssigner(topk=10, num_classes=self.nc, alpha=0.5, beta=6.0) + self.bbox_loss = BboxLoss(m.reg_max - 1, use_dfl=self.use_dfl).to(device) + self.proj = torch.arange(m.reg_max, dtype=torch.float, device=device) + + def preprocess(self, targets, batch_size, scale_tensor): + """Preprocesses the target counts and matches with the input batch size to output a tensor.""" + if targets.shape[0] == 0: + out = torch.zeros(batch_size, 0, 5, device=self.device) + else: + i = targets[:, 0] # image index + _, counts = i.unique(return_counts=True) + counts = counts.to(dtype=torch.int32) + out = torch.zeros(batch_size, counts.max(), 5, device=self.device) + for j in range(batch_size): + matches = i == j + n = matches.sum() + if n: + out[j, :n] = targets[matches, 1:] + out[..., 1:5] = xywh2xyxy(out[..., 1:5].mul_(scale_tensor)) + return out + + def bbox_decode(self, anchor_points, pred_dist): + """Decode predicted object bounding box coordinates from anchor points and distribution.""" + if self.use_dfl: + b, a, c = pred_dist.shape # batch, anchors, channels + pred_dist = pred_dist.view(b, a, 4, c // 4).softmax(3).matmul(self.proj.type(pred_dist.dtype)) + # pred_dist = pred_dist.view(b, a, c // 4, 4).transpose(2,3).softmax(3).matmul(self.proj.type(pred_dist.dtype)) + # pred_dist = (pred_dist.view(b, a, c // 4, 4).softmax(2) * self.proj.type(pred_dist.dtype).view(1, 1, -1, 1)).sum(2) + return dist2bbox(pred_dist, anchor_points, xywh=False) + + def __call__(self, preds, batch): + """Calculate the sum of the loss for box, cls and dfl multiplied by batch size.""" + loss = torch.zeros(3, device=self.device) # box, cls, dfl + feats = preds[1] if isinstance(preds, tuple) else preds + pred_distri, pred_scores = torch.cat([xi.view(feats[0].shape[0], self.no, -1) for xi in feats], 2).split( + (self.reg_max * 4, self.nc), 1) + + pred_scores = pred_scores.permute(0, 2, 1).contiguous() + pred_distri = pred_distri.permute(0, 2, 1).contiguous() + + dtype = pred_scores.dtype + batch_size = pred_scores.shape[0] + imgsz = torch.tensor(feats[0].shape[2:], device=self.device, dtype=dtype) * self.stride[0] # image size (h,w) + anchor_points, stride_tensor = make_anchors(feats, self.stride, 0.5) + + # targets + targets = torch.cat((batch['batch_idx'].view(-1, 1), batch['cls'].view(-1, 1), batch['bboxes']), 1) + targets = self.preprocess(targets.to(self.device), batch_size, scale_tensor=imgsz[[1, 0, 1, 0]]) + gt_labels, gt_bboxes = targets.split((1, 4), 2) # cls, xyxy + mask_gt = gt_bboxes.sum(2, keepdim=True).gt_(0) + + # pboxes + pred_bboxes = self.bbox_decode(anchor_points, pred_distri) # xyxy, (b, h*w, 4) + + _, target_bboxes, target_scores, fg_mask, _ = self.assigner( + pred_scores.detach().sigmoid(), (pred_bboxes.detach() * stride_tensor).type(gt_bboxes.dtype), + anchor_points * stride_tensor, gt_labels, gt_bboxes, mask_gt) + + target_scores_sum = max(target_scores.sum(), 1) + + # cls loss + # loss[1] = self.varifocal_loss(pred_scores, target_scores, target_labels) / target_scores_sum # VFL way + loss[1] = self.bce(pred_scores, target_scores.to(dtype)).sum() / target_scores_sum # BCE + + # bbox loss + if fg_mask.sum(): + target_bboxes /= stride_tensor + loss[0], loss[2] = self.bbox_loss(pred_distri, pred_bboxes, anchor_points, target_bboxes, target_scores, + target_scores_sum, fg_mask) + + loss[0] *= self.hyp.box # box gain + loss[1] *= self.hyp.cls # cls gain + loss[2] *= self.hyp.dfl # dfl gain + + return loss.sum() * batch_size, loss.detach() # loss(box, cls, dfl) + + +# Criterion class for computing training losses +class v8SegmentationLoss(v8DetectionLoss): + + def __init__(self, model): # model must be de-paralleled + super().__init__(model) + self.nm = model.model[-1].nm # number of masks + self.overlap = model.args.overlap_mask + + def __call__(self, preds, batch): + """Calculate and return the loss for the YOLO model.""" + loss = torch.zeros(4, device=self.device) # box, cls, dfl + feats, pred_masks, proto = preds if len(preds) == 3 else preds[1] + batch_size, _, mask_h, mask_w = proto.shape # batch size, number of masks, mask height, mask width + pred_distri, pred_scores = torch.cat([xi.view(feats[0].shape[0], self.no, -1) for xi in feats], 2).split( + (self.reg_max * 4, self.nc), 1) + + # b, grids, .. + pred_scores = pred_scores.permute(0, 2, 1).contiguous() + pred_distri = pred_distri.permute(0, 2, 1).contiguous() + pred_masks = pred_masks.permute(0, 2, 1).contiguous() + + dtype = pred_scores.dtype + imgsz = torch.tensor(feats[0].shape[2:], device=self.device, dtype=dtype) * self.stride[0] # image size (h,w) + anchor_points, stride_tensor = make_anchors(feats, self.stride, 0.5) + + # targets + try: + batch_idx = batch['batch_idx'].view(-1, 1) + targets = torch.cat((batch_idx, batch['cls'].view(-1, 1), batch['bboxes']), 1) + targets = self.preprocess(targets.to(self.device), batch_size, scale_tensor=imgsz[[1, 0, 1, 0]]) + gt_labels, gt_bboxes = targets.split((1, 4), 2) # cls, xyxy + mask_gt = gt_bboxes.sum(2, keepdim=True).gt_(0) + except RuntimeError as e: + raise TypeError('ERROR ❌ segment dataset incorrectly formatted or not a segment dataset.\n' + "This error can occur when incorrectly training a 'segment' model on a 'detect' dataset, " + "i.e. 'yolo train model=yolov8n-seg.pt data=coco128.yaml'.\nVerify your dataset is a " + "correctly formatted 'segment' dataset using 'data=coco128-seg.yaml' " + 'as an example.\nSee https://docs.ultralytics.com/tasks/segment/ for help.') from e + + # pboxes + pred_bboxes = self.bbox_decode(anchor_points, pred_distri) # xyxy, (b, h*w, 4) + + _, target_bboxes, target_scores, fg_mask, target_gt_idx = self.assigner( + pred_scores.detach().sigmoid(), (pred_bboxes.detach() * stride_tensor).type(gt_bboxes.dtype), + anchor_points * stride_tensor, gt_labels, gt_bboxes, mask_gt) + + target_scores_sum = max(target_scores.sum(), 1) + + # cls loss + # loss[1] = self.varifocal_loss(pred_scores, target_scores, target_labels) / target_scores_sum # VFL way + loss[2] = self.bce(pred_scores, target_scores.to(dtype)).sum() / target_scores_sum # BCE + + if fg_mask.sum(): + # bbox loss + loss[0], loss[3] = self.bbox_loss(pred_distri, pred_bboxes, anchor_points, target_bboxes / stride_tensor, + target_scores, target_scores_sum, fg_mask) + # masks loss + masks = batch['masks'].to(self.device).float() + if tuple(masks.shape[-2:]) != (mask_h, mask_w): # downsample + masks = F.interpolate(masks[None], (mask_h, mask_w), mode='nearest')[0] + + for i in range(batch_size): + if fg_mask[i].sum(): + mask_idx = target_gt_idx[i][fg_mask[i]] + if self.overlap: + gt_mask = torch.where(masks[[i]] == (mask_idx + 1).view(-1, 1, 1), 1.0, 0.0) + else: + gt_mask = masks[batch_idx.view(-1) == i][mask_idx] + xyxyn = target_bboxes[i][fg_mask[i]] / imgsz[[1, 0, 1, 0]] + marea = xyxy2xywh(xyxyn)[:, 2:].prod(1) + mxyxy = xyxyn * torch.tensor([mask_w, mask_h, mask_w, mask_h], device=self.device) + loss[1] += self.single_mask_loss(gt_mask, pred_masks[i][fg_mask[i]], proto[i], mxyxy, marea) # seg + + # WARNING: lines below prevents Multi-GPU DDP 'unused gradient' PyTorch errors, do not remove + else: + loss[1] += (proto * 0).sum() + (pred_masks * 0).sum() # inf sums may lead to nan loss + + # WARNING: lines below prevent Multi-GPU DDP 'unused gradient' PyTorch errors, do not remove + else: + loss[1] += (proto * 0).sum() + (pred_masks * 0).sum() # inf sums may lead to nan loss + + loss[0] *= self.hyp.box # box gain + loss[1] *= self.hyp.box / batch_size # seg gain + loss[2] *= self.hyp.cls # cls gain + loss[3] *= self.hyp.dfl # dfl gain + + return loss.sum() * batch_size, loss.detach() # loss(box, cls, dfl) + + def single_mask_loss(self, gt_mask, pred, proto, xyxy, area): + """Mask loss for one image.""" + pred_mask = (pred @ proto.view(self.nm, -1)).view(-1, *proto.shape[1:]) # (n, 32) @ (32,80,80) -> (n,80,80) + loss = F.binary_cross_entropy_with_logits(pred_mask, gt_mask, reduction='none') + return (crop_mask(loss, xyxy).mean(dim=(1, 2)) / area).mean() + + +# Criterion class for computing training losses +class v8PoseLoss(v8DetectionLoss): + + def __init__(self, model): # model must be de-paralleled + super().__init__(model) + self.kpt_shape = model.model[-1].kpt_shape + self.bce_pose = nn.BCEWithLogitsLoss() + is_pose = self.kpt_shape == [17, 3] + nkpt = self.kpt_shape[0] # number of keypoints + sigmas = torch.from_numpy(OKS_SIGMA).to(self.device) if is_pose else torch.ones(nkpt, device=self.device) / nkpt + self.keypoint_loss = KeypointLoss(sigmas=sigmas) + + def __call__(self, preds, batch): + """Calculate the total loss and detach it.""" + loss = torch.zeros(5, device=self.device) # box, cls, dfl, kpt_location, kpt_visibility + feats, pred_kpts = preds if isinstance(preds[0], list) else preds[1] + pred_distri, pred_scores = torch.cat([xi.view(feats[0].shape[0], self.no, -1) for xi in feats], 2).split( + (self.reg_max * 4, self.nc), 1) + + # b, grids, .. + pred_scores = pred_scores.permute(0, 2, 1).contiguous() + pred_distri = pred_distri.permute(0, 2, 1).contiguous() + pred_kpts = pred_kpts.permute(0, 2, 1).contiguous() + + dtype = pred_scores.dtype + imgsz = torch.tensor(feats[0].shape[2:], device=self.device, dtype=dtype) * self.stride[0] # image size (h,w) + anchor_points, stride_tensor = make_anchors(feats, self.stride, 0.5) + + # targets + batch_size = pred_scores.shape[0] + batch_idx = batch['batch_idx'].view(-1, 1) + targets = torch.cat((batch_idx, batch['cls'].view(-1, 1), batch['bboxes']), 1) + targets = self.preprocess(targets.to(self.device), batch_size, scale_tensor=imgsz[[1, 0, 1, 0]]) + gt_labels, gt_bboxes = targets.split((1, 4), 2) # cls, xyxy + mask_gt = gt_bboxes.sum(2, keepdim=True).gt_(0) + + # pboxes + pred_bboxes = self.bbox_decode(anchor_points, pred_distri) # xyxy, (b, h*w, 4) + pred_kpts = self.kpts_decode(anchor_points, pred_kpts.view(batch_size, -1, *self.kpt_shape)) # (b, h*w, 17, 3) + + _, target_bboxes, target_scores, fg_mask, target_gt_idx = self.assigner( + pred_scores.detach().sigmoid(), (pred_bboxes.detach() * stride_tensor).type(gt_bboxes.dtype), + anchor_points * stride_tensor, gt_labels, gt_bboxes, mask_gt) + + target_scores_sum = max(target_scores.sum(), 1) + + # cls loss + # loss[1] = self.varifocal_loss(pred_scores, target_scores, target_labels) / target_scores_sum # VFL way + loss[3] = self.bce(pred_scores, target_scores.to(dtype)).sum() / target_scores_sum # BCE + + # bbox loss + if fg_mask.sum(): + target_bboxes /= stride_tensor + loss[0], loss[4] = self.bbox_loss(pred_distri, pred_bboxes, anchor_points, target_bboxes, target_scores, + target_scores_sum, fg_mask) + keypoints = batch['keypoints'].to(self.device).float().clone() + keypoints[..., 0] *= imgsz[1] + keypoints[..., 1] *= imgsz[0] + for i in range(batch_size): + if fg_mask[i].sum(): + idx = target_gt_idx[i][fg_mask[i]] + gt_kpt = keypoints[batch_idx.view(-1) == i][idx] # (n, 51) + gt_kpt[..., 0] /= stride_tensor[fg_mask[i]] + gt_kpt[..., 1] /= stride_tensor[fg_mask[i]] + area = xyxy2xywh(target_bboxes[i][fg_mask[i]])[:, 2:].prod(1, keepdim=True) + pred_kpt = pred_kpts[i][fg_mask[i]] + kpt_mask = gt_kpt[..., 2] != 0 + loss[1] += self.keypoint_loss(pred_kpt, gt_kpt, kpt_mask, area) # pose loss + # kpt_score loss + if pred_kpt.shape[-1] == 3: + loss[2] += self.bce_pose(pred_kpt[..., 2], kpt_mask.float()) # keypoint obj loss + + loss[0] *= self.hyp.box # box gain + loss[1] *= self.hyp.pose / batch_size # pose gain + loss[2] *= self.hyp.kobj / batch_size # kobj gain + loss[3] *= self.hyp.cls # cls gain + loss[4] *= self.hyp.dfl # dfl gain + + return loss.sum() * batch_size, loss.detach() # loss(box, cls, dfl) + + def kpts_decode(self, anchor_points, pred_kpts): + """Decodes predicted keypoints to image coordinates.""" + y = pred_kpts.clone() + y[..., :2] *= 2.0 + y[..., 0] += anchor_points[:, [0]] - 0.5 + y[..., 1] += anchor_points[:, [1]] - 0.5 + return y + + +class v8ClassificationLoss: + + def __call__(self, preds, batch): + """Compute the classification loss between predictions and true labels.""" + loss = torch.nn.functional.cross_entropy(preds, batch['cls'], reduction='sum') / 64 + loss_items = loss.detach() + return loss, loss_items diff --git a/downloads/ultralytics-main/ultralytics/utils/metrics.py b/downloads/ultralytics-main/ultralytics/utils/metrics.py new file mode 100644 index 000000000..a1dddf6f3 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/metrics.py @@ -0,0 +1,970 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license +""" +Model validation metrics +""" +import math +import warnings +from pathlib import Path + +import matplotlib.pyplot as plt +import numpy as np +import torch + +from ultralytics.utils import LOGGER, SimpleClass, TryExcept, plt_settings + +OKS_SIGMA = np.array([.26, .25, .25, .35, .35, .79, .79, .72, .72, .62, .62, 1.07, 1.07, .87, .87, .89, .89]) / 10.0 + + +def bbox_ioa(box1, box2, iou=False, eps=1e-7): + """ + Calculate the intersection over box2 area given box1 and box2. Boxes are in x1y1x2y2 format. + + Args: + box1 (np.array): A numpy array of shape (n, 4) representing n bounding boxes. + box2 (np.array): A numpy array of shape (m, 4) representing m bounding boxes. + iou (bool): Calculate the standard iou if True else return inter_area/box2_area. + eps (float, optional): A small value to avoid division by zero. Defaults to 1e-7. + + Returns: + (np.array): A numpy array of shape (n, m) representing the intersection over box2 area. + """ + + # Get the coordinates of bounding boxes + b1_x1, b1_y1, b1_x2, b1_y2 = box1.T + b2_x1, b2_y1, b2_x2, b2_y2 = box2.T + + # Intersection area + inter_area = (np.minimum(b1_x2[:, None], b2_x2) - np.maximum(b1_x1[:, None], b2_x1)).clip(0) * \ + (np.minimum(b1_y2[:, None], b2_y2) - np.maximum(b1_y1[:, None], b2_y1)).clip(0) + + # box2 area + area = (b2_x2 - b2_x1) * (b2_y2 - b2_y1) + if iou: + box1_area = (b1_x2 - b1_x1) * (b1_y2 - b1_y1) + area = area + box1_area[:, None] - inter_area + + # Intersection over box2 area + return inter_area / (area + eps) + + +def box_iou(box1, box2, eps=1e-7): + """ + Calculate intersection-over-union (IoU) of boxes. + Both sets of boxes are expected to be in (x1, y1, x2, y2) format. + Based on https://github.com/pytorch/vision/blob/master/torchvision/ops/boxes.py + + Args: + box1 (torch.Tensor): A tensor of shape (N, 4) representing N bounding boxes. + box2 (torch.Tensor): A tensor of shape (M, 4) representing M bounding boxes. + eps (float, optional): A small value to avoid division by zero. Defaults to 1e-7. + + Returns: + (torch.Tensor): An NxM tensor containing the pairwise IoU values for every element in box1 and box2. + """ + + # inter(N,M) = (rb(N,M,2) - lt(N,M,2)).clamp(0).prod(2) + (a1, a2), (b1, b2) = box1.unsqueeze(1).chunk(2, 2), box2.unsqueeze(0).chunk(2, 2) + inter = (torch.min(a2, b2) - torch.max(a1, b1)).clamp_(0).prod(2) + + # IoU = inter / (area1 + area2 - inter) + return inter / ((a2 - a1).prod(2) + (b2 - b1).prod(2) - inter + eps) + + +def bbox_iou(box1, box2, xywh=True, GIoU=False, DIoU=False, CIoU=False, eps=1e-7): + """ + Calculate Intersection over Union (IoU) of box1(1, 4) to box2(n, 4). + + Args: + box1 (torch.Tensor): A tensor representing a single bounding box with shape (1, 4). + box2 (torch.Tensor): A tensor representing n bounding boxes with shape (n, 4). + xywh (bool, optional): If True, input boxes are in (x, y, w, h) format. If False, input boxes are in + (x1, y1, x2, y2) format. Defaults to True. + GIoU (bool, optional): If True, calculate Generalized IoU. Defaults to False. + DIoU (bool, optional): If True, calculate Distance IoU. Defaults to False. + CIoU (bool, optional): If True, calculate Complete IoU. Defaults to False. + eps (float, optional): A small value to avoid division by zero. Defaults to 1e-7. + + Returns: + (torch.Tensor): IoU, GIoU, DIoU, or CIoU values depending on the specified flags. + """ + + # Get the coordinates of bounding boxes + if xywh: # transform from xywh to xyxy + (x1, y1, w1, h1), (x2, y2, w2, h2) = box1.chunk(4, -1), box2.chunk(4, -1) + w1_, h1_, w2_, h2_ = w1 / 2, h1 / 2, w2 / 2, h2 / 2 + b1_x1, b1_x2, b1_y1, b1_y2 = x1 - w1_, x1 + w1_, y1 - h1_, y1 + h1_ + b2_x1, b2_x2, b2_y1, b2_y2 = x2 - w2_, x2 + w2_, y2 - h2_, y2 + h2_ + else: # x1, y1, x2, y2 = box1 + b1_x1, b1_y1, b1_x2, b1_y2 = box1.chunk(4, -1) + b2_x1, b2_y1, b2_x2, b2_y2 = box2.chunk(4, -1) + w1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1 + eps + w2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1 + eps + + # Intersection area + inter = (b1_x2.minimum(b2_x2) - b1_x1.maximum(b2_x1)).clamp_(0) * \ + (b1_y2.minimum(b2_y2) - b1_y1.maximum(b2_y1)).clamp_(0) + + # Union Area + union = w1 * h1 + w2 * h2 - inter + eps + + # IoU + iou = inter / union + if CIoU or DIoU or GIoU: + cw = b1_x2.maximum(b2_x2) - b1_x1.minimum(b2_x1) # convex (smallest enclosing box) width + ch = b1_y2.maximum(b2_y2) - b1_y1.minimum(b2_y1) # convex height + if CIoU or DIoU: # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1 + c2 = cw ** 2 + ch ** 2 + eps # convex diagonal squared + rho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 + (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4 # center dist ** 2 + if CIoU: # https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47 + v = (4 / math.pi ** 2) * (torch.atan(w2 / h2) - torch.atan(w1 / h1)).pow(2) + with torch.no_grad(): + alpha = v / (v - iou + (1 + eps)) + return iou - (rho2 / c2 + v * alpha) # CIoU + return iou - rho2 / c2 # DIoU + c_area = cw * ch + eps # convex area + return iou - (c_area - union) / c_area # GIoU https://arxiv.org/pdf/1902.09630.pdf + return iou # IoU + + +def mask_iou(mask1, mask2, eps=1e-7): + """ + Calculate masks IoU. + + Args: + mask1 (torch.Tensor): A tensor of shape (N, n) where N is the number of ground truth objects and n is the + product of image width and height. + mask2 (torch.Tensor): A tensor of shape (M, n) where M is the number of predicted objects and n is the + product of image width and height. + eps (float, optional): A small value to avoid division by zero. Defaults to 1e-7. + + Returns: + (torch.Tensor): A tensor of shape (N, M) representing masks IoU. + """ + intersection = torch.matmul(mask1, mask2.T).clamp_(0) + union = (mask1.sum(1)[:, None] + mask2.sum(1)[None]) - intersection # (area1 + area2) - intersection + return intersection / (union + eps) + + +def kpt_iou(kpt1, kpt2, area, sigma, eps=1e-7): + """ + Calculate Object Keypoint Similarity (OKS). + + Args: + kpt1 (torch.Tensor): A tensor of shape (N, 17, 3) representing ground truth keypoints. + kpt2 (torch.Tensor): A tensor of shape (M, 17, 3) representing predicted keypoints. + area (torch.Tensor): A tensor of shape (N,) representing areas from ground truth. + sigma (list): A list containing 17 values representing keypoint scales. + eps (float, optional): A small value to avoid division by zero. Defaults to 1e-7. + + Returns: + (torch.Tensor): A tensor of shape (N, M) representing keypoint similarities. + """ + d = (kpt1[:, None, :, 0] - kpt2[..., 0]) ** 2 + (kpt1[:, None, :, 1] - kpt2[..., 1]) ** 2 # (N, M, 17) + sigma = torch.tensor(sigma, device=kpt1.device, dtype=kpt1.dtype) # (17, ) + kpt_mask = kpt1[..., 2] != 0 # (N, 17) + e = d / (2 * sigma) ** 2 / (area[:, None, None] + eps) / 2 # from cocoeval + # e = d / ((area[None, :, None] + eps) * sigma) ** 2 / 2 # from formula + return (torch.exp(-e) * kpt_mask[:, None]).sum(-1) / (kpt_mask.sum(-1)[:, None] + eps) + + +def smooth_BCE(eps=0.1): # https://github.com/ultralytics/yolov3/issues/238#issuecomment-598028441 + # return positive, negative label smoothing BCE targets + return 1.0 - 0.5 * eps, 0.5 * eps + + +class ConfusionMatrix: + """ + A class for calculating and updating a confusion matrix for object detection and classification tasks. + + Attributes: + task (str): The type of task, either 'detect' or 'classify'. + matrix (np.array): The confusion matrix, with dimensions depending on the task. + nc (int): The number of classes. + conf (float): The confidence threshold for detections. + iou_thres (float): The Intersection over Union threshold. + """ + + def __init__(self, nc, conf=0.25, iou_thres=0.45, task='detect'): + """Initialize attributes for the YOLO model.""" + self.task = task + self.matrix = np.zeros((nc + 1, nc + 1)) if self.task == 'detect' else np.zeros((nc, nc)) + self.nc = nc # number of classes + self.conf = conf + self.iou_thres = iou_thres + + def process_cls_preds(self, preds, targets): + """ + Update confusion matrix for classification task + + Args: + preds (Array[N, min(nc,5)]): Predicted class labels. + targets (Array[N, 1]): Ground truth class labels. + """ + preds, targets = torch.cat(preds)[:, 0], torch.cat(targets) + for p, t in zip(preds.cpu().numpy(), targets.cpu().numpy()): + self.matrix[p][t] += 1 + + def process_batch(self, detections, labels): + """ + Update confusion matrix for object detection task. + + Args: + detections (Array[N, 6]): Detected bounding boxes and their associated information. + Each row should contain (x1, y1, x2, y2, conf, class). + labels (Array[M, 5]): Ground truth bounding boxes and their associated class labels. + Each row should contain (class, x1, y1, x2, y2). + """ + if detections is None: + gt_classes = labels.int() + for gc in gt_classes: + self.matrix[self.nc, gc] += 1 # background FN + return + + detections = detections[detections[:, 4] > self.conf] + gt_classes = labels[:, 0].int() + detection_classes = detections[:, 5].int() + iou = box_iou(labels[:, 1:], detections[:, :4]) + + x = torch.where(iou > self.iou_thres) + if x[0].shape[0]: + matches = torch.cat((torch.stack(x, 1), iou[x[0], x[1]][:, None]), 1).cpu().numpy() + if x[0].shape[0] > 1: + matches = matches[matches[:, 2].argsort()[::-1]] + matches = matches[np.unique(matches[:, 1], return_index=True)[1]] + matches = matches[matches[:, 2].argsort()[::-1]] + matches = matches[np.unique(matches[:, 0], return_index=True)[1]] + else: + matches = np.zeros((0, 3)) + + n = matches.shape[0] > 0 + m0, m1, _ = matches.transpose().astype(int) + for i, gc in enumerate(gt_classes): + j = m0 == i + if n and sum(j) == 1: + self.matrix[detection_classes[m1[j]], gc] += 1 # correct + else: + self.matrix[self.nc, gc] += 1 # true background + + if n: + for i, dc in enumerate(detection_classes): + if not any(m1 == i): + self.matrix[dc, self.nc] += 1 # predicted background + + def matrix(self): + """Returns the confusion matrix.""" + return self.matrix + + def tp_fp(self): + """Returns true positives and false positives.""" + tp = self.matrix.diagonal() # true positives + fp = self.matrix.sum(1) - tp # false positives + # fn = self.matrix.sum(0) - tp # false negatives (missed detections) + return (tp[:-1], fp[:-1]) if self.task == 'detect' else (tp, fp) # remove background class if task=detect + + @TryExcept('WARNING ⚠️ ConfusionMatrix plot failure') + @plt_settings() + def plot(self, normalize=True, save_dir='', names=(), on_plot=None): + """ + Plot the confusion matrix using seaborn and save it to a file. + + Args: + normalize (bool): Whether to normalize the confusion matrix. + save_dir (str): Directory where the plot will be saved. + names (tuple): Names of classes, used as labels on the plot. + on_plot (func): An optional callback to pass plots path and data when they are rendered. + """ + import seaborn as sn + + array = self.matrix / ((self.matrix.sum(0).reshape(1, -1) + 1E-9) if normalize else 1) # normalize columns + array[array < 0.005] = np.nan # don't annotate (would appear as 0.00) + + fig, ax = plt.subplots(1, 1, figsize=(12, 9), tight_layout=True) + nc, nn = self.nc, len(names) # number of classes, names + sn.set(font_scale=1.0 if nc < 50 else 0.8) # for label size + labels = (0 < nn < 99) and (nn == nc) # apply names to ticklabels + ticklabels = (list(names) + ['background']) if labels else 'auto' + with warnings.catch_warnings(): + warnings.simplefilter('ignore') # suppress empty matrix RuntimeWarning: All-NaN slice encountered + sn.heatmap(array, + ax=ax, + annot=nc < 30, + annot_kws={ + 'size': 8}, + cmap='Blues', + fmt='.2f' if normalize else '.0f', + square=True, + vmin=0.0, + xticklabels=ticklabels, + yticklabels=ticklabels).set_facecolor((1, 1, 1)) + title = 'Confusion Matrix' + ' Normalized' * normalize + ax.set_xlabel('True') + ax.set_ylabel('Predicted') + ax.set_title(title) + plot_fname = Path(save_dir) / f'{title.lower().replace(" ", "_")}.png' + fig.savefig(plot_fname, dpi=250) + plt.close(fig) + if on_plot: + on_plot(plot_fname) + + def print(self): + """ + Print the confusion matrix to the console. + """ + for i in range(self.nc + 1): + LOGGER.info(' '.join(map(str, self.matrix[i]))) + + +def smooth(y, f=0.05): + """Box filter of fraction f.""" + nf = round(len(y) * f * 2) // 2 + 1 # number of filter elements (must be odd) + p = np.ones(nf // 2) # ones padding + yp = np.concatenate((p * y[0], y, p * y[-1]), 0) # y padded + return np.convolve(yp, np.ones(nf) / nf, mode='valid') # y-smoothed + + +@plt_settings() +def plot_pr_curve(px, py, ap, save_dir=Path('pr_curve.png'), names=(), on_plot=None): + """Plots a precision-recall curve.""" + fig, ax = plt.subplots(1, 1, figsize=(9, 6), tight_layout=True) + py = np.stack(py, axis=1) + + if 0 < len(names) < 21: # display per-class legend if < 21 classes + for i, y in enumerate(py.T): + ax.plot(px, y, linewidth=1, label=f'{names[i]} {ap[i, 0]:.3f}') # plot(recall, precision) + else: + ax.plot(px, py, linewidth=1, color='grey') # plot(recall, precision) + + ax.plot(px, py.mean(1), linewidth=3, color='blue', label='all classes %.3f mAP@0.5' % ap[:, 0].mean()) + ax.set_xlabel('Recall') + ax.set_ylabel('Precision') + ax.set_xlim(0, 1) + ax.set_ylim(0, 1) + ax.legend(bbox_to_anchor=(1.04, 1), loc='upper left') + ax.set_title('Precision-Recall Curve') + fig.savefig(save_dir, dpi=250) + plt.close(fig) + if on_plot: + on_plot(save_dir) + + +@plt_settings() +def plot_mc_curve(px, py, save_dir=Path('mc_curve.png'), names=(), xlabel='Confidence', ylabel='Metric', on_plot=None): + """Plots a metric-confidence curve.""" + fig, ax = plt.subplots(1, 1, figsize=(9, 6), tight_layout=True) + + if 0 < len(names) < 21: # display per-class legend if < 21 classes + for i, y in enumerate(py): + ax.plot(px, y, linewidth=1, label=f'{names[i]}') # plot(confidence, metric) + else: + ax.plot(px, py.T, linewidth=1, color='grey') # plot(confidence, metric) + + y = smooth(py.mean(0), 0.05) + ax.plot(px, y, linewidth=3, color='blue', label=f'all classes {y.max():.2f} at {px[y.argmax()]:.3f}') + ax.set_xlabel(xlabel) + ax.set_ylabel(ylabel) + ax.set_xlim(0, 1) + ax.set_ylim(0, 1) + ax.legend(bbox_to_anchor=(1.04, 1), loc='upper left') + ax.set_title(f'{ylabel}-Confidence Curve') + fig.savefig(save_dir, dpi=250) + plt.close(fig) + if on_plot: + on_plot(save_dir) + + +def compute_ap(recall, precision): + """ + Compute the average precision (AP) given the recall and precision curves. + + Args: + recall (list): The recall curve. + precision (list): The precision curve. + + Returns: + (float): Average precision. + (np.ndarray): Precision envelope curve. + (np.ndarray): Modified recall curve with sentinel values added at the beginning and end. + """ + + # Append sentinel values to beginning and end + mrec = np.concatenate(([0.0], recall, [1.0])) + mpre = np.concatenate(([1.0], precision, [0.0])) + + # Compute the precision envelope + mpre = np.flip(np.maximum.accumulate(np.flip(mpre))) + + # Integrate area under curve + method = 'interp' # methods: 'continuous', 'interp' + if method == 'interp': + x = np.linspace(0, 1, 101) # 101-point interp (COCO) + ap = np.trapz(np.interp(x, mrec, mpre), x) # integrate + else: # 'continuous' + i = np.where(mrec[1:] != mrec[:-1])[0] # points where x-axis (recall) changes + ap = np.sum((mrec[i + 1] - mrec[i]) * mpre[i + 1]) # area under curve + + return ap, mpre, mrec + + +def ap_per_class(tp, + conf, + pred_cls, + target_cls, + plot=False, + on_plot=None, + save_dir=Path(), + names=(), + eps=1e-16, + prefix=''): + """ + Computes the average precision per class for object detection evaluation. + + Args: + tp (np.ndarray): Binary array indicating whether the detection is correct (True) or not (False). + conf (np.ndarray): Array of confidence scores of the detections. + pred_cls (np.ndarray): Array of predicted classes of the detections. + target_cls (np.ndarray): Array of true classes of the detections. + plot (bool, optional): Whether to plot PR curves or not. Defaults to False. + on_plot (func, optional): A callback to pass plots path and data when they are rendered. Defaults to None. + save_dir (Path, optional): Directory to save the PR curves. Defaults to an empty path. + names (tuple, optional): Tuple of class names to plot PR curves. Defaults to an empty tuple. + eps (float, optional): A small value to avoid division by zero. Defaults to 1e-16. + prefix (str, optional): A prefix string for saving the plot files. Defaults to an empty string. + + Returns: + (tuple): A tuple of six arrays and one array of unique classes, where: + tp (np.ndarray): True positive counts for each class. + fp (np.ndarray): False positive counts for each class. + p (np.ndarray): Precision values at each confidence threshold. + r (np.ndarray): Recall values at each confidence threshold. + f1 (np.ndarray): F1-score values at each confidence threshold. + ap (np.ndarray): Average precision for each class at different IoU thresholds. + unique_classes (np.ndarray): An array of unique classes that have data. + + """ + + # Sort by objectness + i = np.argsort(-conf) + tp, conf, pred_cls = tp[i], conf[i], pred_cls[i] + + # Find unique classes + unique_classes, nt = np.unique(target_cls, return_counts=True) + nc = unique_classes.shape[0] # number of classes, number of detections + + # Create Precision-Recall curve and compute AP for each class + px, py = np.linspace(0, 1, 1000), [] # for plotting + ap, p, r = np.zeros((nc, tp.shape[1])), np.zeros((nc, 1000)), np.zeros((nc, 1000)) + for ci, c in enumerate(unique_classes): + i = pred_cls == c + n_l = nt[ci] # number of labels + n_p = i.sum() # number of predictions + if n_p == 0 or n_l == 0: + continue + + # Accumulate FPs and TPs + fpc = (1 - tp[i]).cumsum(0) + tpc = tp[i].cumsum(0) + + # Recall + recall = tpc / (n_l + eps) # recall curve + r[ci] = np.interp(-px, -conf[i], recall[:, 0], left=0) # negative x, xp because xp decreases + + # Precision + precision = tpc / (tpc + fpc) # precision curve + p[ci] = np.interp(-px, -conf[i], precision[:, 0], left=1) # p at pr_score + + # AP from recall-precision curve + for j in range(tp.shape[1]): + ap[ci, j], mpre, mrec = compute_ap(recall[:, j], precision[:, j]) + if plot and j == 0: + py.append(np.interp(px, mrec, mpre)) # precision at mAP@0.5 + + # Compute F1 (harmonic mean of precision and recall) + f1 = 2 * p * r / (p + r + eps) + names = [v for k, v in names.items() if k in unique_classes] # list: only classes that have data + names = dict(enumerate(names)) # to dict + if plot: + plot_pr_curve(px, py, ap, save_dir / f'{prefix}PR_curve.png', names, on_plot=on_plot) + plot_mc_curve(px, f1, save_dir / f'{prefix}F1_curve.png', names, ylabel='F1', on_plot=on_plot) + plot_mc_curve(px, p, save_dir / f'{prefix}P_curve.png', names, ylabel='Precision', on_plot=on_plot) + plot_mc_curve(px, r, save_dir / f'{prefix}R_curve.png', names, ylabel='Recall', on_plot=on_plot) + + i = smooth(f1.mean(0), 0.1).argmax() # max F1 index + p, r, f1 = p[:, i], r[:, i], f1[:, i] + tp = (r * nt).round() # true positives + fp = (tp / (p + eps) - tp).round() # false positives + return tp, fp, p, r, f1, ap, unique_classes.astype(int) + + +class Metric(SimpleClass): + """ + Class for computing evaluation metrics for YOLOv8 model. + + Attributes: + p (list): Precision for each class. Shape: (nc,). + r (list): Recall for each class. Shape: (nc,). + f1 (list): F1 score for each class. Shape: (nc,). + all_ap (list): AP scores for all classes and all IoU thresholds. Shape: (nc, 10). + ap_class_index (list): Index of class for each AP score. Shape: (nc,). + nc (int): Number of classes. + + Methods: + ap50(): AP at IoU threshold of 0.5 for all classes. Returns: List of AP scores. Shape: (nc,) or []. + ap(): AP at IoU thresholds from 0.5 to 0.95 for all classes. Returns: List of AP scores. Shape: (nc,) or []. + mp(): Mean precision of all classes. Returns: Float. + mr(): Mean recall of all classes. Returns: Float. + map50(): Mean AP at IoU threshold of 0.5 for all classes. Returns: Float. + map75(): Mean AP at IoU threshold of 0.75 for all classes. Returns: Float. + map(): Mean AP at IoU thresholds from 0.5 to 0.95 for all classes. Returns: Float. + mean_results(): Mean of results, returns mp, mr, map50, map. + class_result(i): Class-aware result, returns p[i], r[i], ap50[i], ap[i]. + maps(): mAP of each class. Returns: Array of mAP scores, shape: (nc,). + fitness(): Model fitness as a weighted combination of metrics. Returns: Float. + update(results): Update metric attributes with new evaluation results. + + """ + + def __init__(self) -> None: + self.p = [] # (nc, ) + self.r = [] # (nc, ) + self.f1 = [] # (nc, ) + self.all_ap = [] # (nc, 10) + self.ap_class_index = [] # (nc, ) + self.nc = 0 + + @property + def ap50(self): + """ + Returns the Average Precision (AP) at an IoU threshold of 0.5 for all classes. + + Returns: + (np.ndarray, list): Array of shape (nc,) with AP50 values per class, or an empty list if not available. + """ + return self.all_ap[:, 0] if len(self.all_ap) else [] + + @property + def ap(self): + """ + Returns the Average Precision (AP) at an IoU threshold of 0.5-0.95 for all classes. + + Returns: + (np.ndarray, list): Array of shape (nc,) with AP50-95 values per class, or an empty list if not available. + """ + return self.all_ap.mean(1) if len(self.all_ap) else [] + + @property + def mp(self): + """ + Returns the Mean Precision of all classes. + + Returns: + (float): The mean precision of all classes. + """ + return self.p.mean() if len(self.p) else 0.0 + + @property + def mr(self): + """ + Returns the Mean Recall of all classes. + + Returns: + (float): The mean recall of all classes. + """ + return self.r.mean() if len(self.r) else 0.0 + + @property + def map50(self): + """ + Returns the mean Average Precision (mAP) at an IoU threshold of 0.5. + + Returns: + (float): The mAP50 at an IoU threshold of 0.5. + """ + return self.all_ap[:, 0].mean() if len(self.all_ap) else 0.0 + + @property + def map75(self): + """ + Returns the mean Average Precision (mAP) at an IoU threshold of 0.75. + + Returns: + (float): The mAP50 at an IoU threshold of 0.75. + """ + return self.all_ap[:, 5].mean() if len(self.all_ap) else 0.0 + + @property + def map(self): + """ + Returns the mean Average Precision (mAP) over IoU thresholds of 0.5 - 0.95 in steps of 0.05. + + Returns: + (float): The mAP over IoU thresholds of 0.5 - 0.95 in steps of 0.05. + """ + return self.all_ap.mean() if len(self.all_ap) else 0.0 + + def mean_results(self): + """Mean of results, return mp, mr, map50, map.""" + return [self.mp, self.mr, self.map50, self.map] + + def class_result(self, i): + """class-aware result, return p[i], r[i], ap50[i], ap[i].""" + return self.p[i], self.r[i], self.ap50[i], self.ap[i] + + @property + def maps(self): + """mAP of each class.""" + maps = np.zeros(self.nc) + self.map + for i, c in enumerate(self.ap_class_index): + maps[c] = self.ap[i] + return maps + + def fitness(self): + """Model fitness as a weighted combination of metrics.""" + w = [0.0, 0.0, 0.1, 0.9] # weights for [P, R, mAP@0.5, mAP@0.5:0.95] + return (np.array(self.mean_results()) * w).sum() + + def update(self, results): + """ + Args: + results (tuple): A tuple of (p, r, ap, f1, ap_class) + """ + self.p, self.r, self.f1, self.all_ap, self.ap_class_index = results + + +class DetMetrics(SimpleClass): + """ + This class is a utility class for computing detection metrics such as precision, recall, and mean average precision + (mAP) of an object detection model. + + Args: + save_dir (Path): A path to the directory where the output plots will be saved. Defaults to current directory. + plot (bool): A flag that indicates whether to plot precision-recall curves for each class. Defaults to False. + on_plot (func): An optional callback to pass plots path and data when they are rendered. Defaults to None. + names (tuple of str): A tuple of strings that represents the names of the classes. Defaults to an empty tuple. + + Attributes: + save_dir (Path): A path to the directory where the output plots will be saved. + plot (bool): A flag that indicates whether to plot the precision-recall curves for each class. + on_plot (func): An optional callback to pass plots path and data when they are rendered. + names (tuple of str): A tuple of strings that represents the names of the classes. + box (Metric): An instance of the Metric class for storing the results of the detection metrics. + speed (dict): A dictionary for storing the execution time of different parts of the detection process. + + Methods: + process(tp, conf, pred_cls, target_cls): Updates the metric results with the latest batch of predictions. + keys: Returns a list of keys for accessing the computed detection metrics. + mean_results: Returns a list of mean values for the computed detection metrics. + class_result(i): Returns a list of values for the computed detection metrics for a specific class. + maps: Returns a dictionary of mean average precision (mAP) values for different IoU thresholds. + fitness: Computes the fitness score based on the computed detection metrics. + ap_class_index: Returns a list of class indices sorted by their average precision (AP) values. + results_dict: Returns a dictionary that maps detection metric keys to their computed values. + """ + + def __init__(self, save_dir=Path('.'), plot=False, on_plot=None, names=()) -> None: + self.save_dir = save_dir + self.plot = plot + self.on_plot = on_plot + self.names = names + self.box = Metric() + self.speed = {'preprocess': 0.0, 'inference': 0.0, 'loss': 0.0, 'postprocess': 0.0} + + def process(self, tp, conf, pred_cls, target_cls): + """Process predicted results for object detection and update metrics.""" + results = ap_per_class(tp, + conf, + pred_cls, + target_cls, + plot=self.plot, + save_dir=self.save_dir, + names=self.names, + on_plot=self.on_plot)[2:] + self.box.nc = len(self.names) + self.box.update(results) + + @property + def keys(self): + """Returns a list of keys for accessing specific metrics.""" + return ['metrics/precision(B)', 'metrics/recall(B)', 'metrics/mAP50(B)', 'metrics/mAP50-95(B)'] + + def mean_results(self): + """Calculate mean of detected objects & return precision, recall, mAP50, and mAP50-95.""" + return self.box.mean_results() + + def class_result(self, i): + """Return the result of evaluating the performance of an object detection model on a specific class.""" + return self.box.class_result(i) + + @property + def maps(self): + """Returns mean Average Precision (mAP) scores per class.""" + return self.box.maps + + @property + def fitness(self): + """Returns the fitness of box object.""" + return self.box.fitness() + + @property + def ap_class_index(self): + """Returns the average precision index per class.""" + return self.box.ap_class_index + + @property + def results_dict(self): + """Returns dictionary of computed performance metrics and statistics.""" + return dict(zip(self.keys + ['fitness'], self.mean_results() + [self.fitness])) + + +class SegmentMetrics(SimpleClass): + """ + Calculates and aggregates detection and segmentation metrics over a given set of classes. + + Args: + save_dir (Path): Path to the directory where the output plots should be saved. Default is the current directory. + plot (bool): Whether to save the detection and segmentation plots. Default is False. + on_plot (func): An optional callback to pass plots path and data when they are rendered. Defaults to None. + names (list): List of class names. Default is an empty list. + + Attributes: + save_dir (Path): Path to the directory where the output plots should be saved. + plot (bool): Whether to save the detection and segmentation plots. + on_plot (func): An optional callback to pass plots path and data when they are rendered. + names (list): List of class names. + box (Metric): An instance of the Metric class to calculate box detection metrics. + seg (Metric): An instance of the Metric class to calculate mask segmentation metrics. + speed (dict): Dictionary to store the time taken in different phases of inference. + + Methods: + process(tp_m, tp_b, conf, pred_cls, target_cls): Processes metrics over the given set of predictions. + mean_results(): Returns the mean of the detection and segmentation metrics over all the classes. + class_result(i): Returns the detection and segmentation metrics of class `i`. + maps: Returns the mean Average Precision (mAP) scores for IoU thresholds ranging from 0.50 to 0.95. + fitness: Returns the fitness scores, which are a single weighted combination of metrics. + ap_class_index: Returns the list of indices of classes used to compute Average Precision (AP). + results_dict: Returns the dictionary containing all the detection and segmentation metrics and fitness score. + """ + + def __init__(self, save_dir=Path('.'), plot=False, on_plot=None, names=()) -> None: + self.save_dir = save_dir + self.plot = plot + self.on_plot = on_plot + self.names = names + self.box = Metric() + self.seg = Metric() + self.speed = {'preprocess': 0.0, 'inference': 0.0, 'loss': 0.0, 'postprocess': 0.0} + + def process(self, tp_b, tp_m, conf, pred_cls, target_cls): + """ + Processes the detection and segmentation metrics over the given set of predictions. + + Args: + tp_b (list): List of True Positive boxes. + tp_m (list): List of True Positive masks. + conf (list): List of confidence scores. + pred_cls (list): List of predicted classes. + target_cls (list): List of target classes. + """ + + results_mask = ap_per_class(tp_m, + conf, + pred_cls, + target_cls, + plot=self.plot, + on_plot=self.on_plot, + save_dir=self.save_dir, + names=self.names, + prefix='Mask')[2:] + self.seg.nc = len(self.names) + self.seg.update(results_mask) + results_box = ap_per_class(tp_b, + conf, + pred_cls, + target_cls, + plot=self.plot, + on_plot=self.on_plot, + save_dir=self.save_dir, + names=self.names, + prefix='Box')[2:] + self.box.nc = len(self.names) + self.box.update(results_box) + + @property + def keys(self): + """Returns a list of keys for accessing metrics.""" + return [ + 'metrics/precision(B)', 'metrics/recall(B)', 'metrics/mAP50(B)', 'metrics/mAP50-95(B)', + 'metrics/precision(M)', 'metrics/recall(M)', 'metrics/mAP50(M)', 'metrics/mAP50-95(M)'] + + def mean_results(self): + """Return the mean metrics for bounding box and segmentation results.""" + return self.box.mean_results() + self.seg.mean_results() + + def class_result(self, i): + """Returns classification results for a specified class index.""" + return self.box.class_result(i) + self.seg.class_result(i) + + @property + def maps(self): + """Returns mAP scores for object detection and semantic segmentation models.""" + return self.box.maps + self.seg.maps + + @property + def fitness(self): + """Get the fitness score for both segmentation and bounding box models.""" + return self.seg.fitness() + self.box.fitness() + + @property + def ap_class_index(self): + """Boxes and masks have the same ap_class_index.""" + return self.box.ap_class_index + + @property + def results_dict(self): + """Returns results of object detection model for evaluation.""" + return dict(zip(self.keys + ['fitness'], self.mean_results() + [self.fitness])) + + +class PoseMetrics(SegmentMetrics): + """ + Calculates and aggregates detection and pose metrics over a given set of classes. + + Args: + save_dir (Path): Path to the directory where the output plots should be saved. Default is the current directory. + plot (bool): Whether to save the detection and segmentation plots. Default is False. + on_plot (func): An optional callback to pass plots path and data when they are rendered. Defaults to None. + names (list): List of class names. Default is an empty list. + + Attributes: + save_dir (Path): Path to the directory where the output plots should be saved. + plot (bool): Whether to save the detection and segmentation plots. + on_plot (func): An optional callback to pass plots path and data when they are rendered. + names (list): List of class names. + box (Metric): An instance of the Metric class to calculate box detection metrics. + pose (Metric): An instance of the Metric class to calculate mask segmentation metrics. + speed (dict): Dictionary to store the time taken in different phases of inference. + + Methods: + process(tp_m, tp_b, conf, pred_cls, target_cls): Processes metrics over the given set of predictions. + mean_results(): Returns the mean of the detection and segmentation metrics over all the classes. + class_result(i): Returns the detection and segmentation metrics of class `i`. + maps: Returns the mean Average Precision (mAP) scores for IoU thresholds ranging from 0.50 to 0.95. + fitness: Returns the fitness scores, which are a single weighted combination of metrics. + ap_class_index: Returns the list of indices of classes used to compute Average Precision (AP). + results_dict: Returns the dictionary containing all the detection and segmentation metrics and fitness score. + """ + + def __init__(self, save_dir=Path('.'), plot=False, on_plot=None, names=()) -> None: + super().__init__(save_dir, plot, names) + self.save_dir = save_dir + self.plot = plot + self.on_plot = on_plot + self.names = names + self.box = Metric() + self.pose = Metric() + self.speed = {'preprocess': 0.0, 'inference': 0.0, 'loss': 0.0, 'postprocess': 0.0} + + def process(self, tp_b, tp_p, conf, pred_cls, target_cls): + """ + Processes the detection and pose metrics over the given set of predictions. + + Args: + tp_b (list): List of True Positive boxes. + tp_p (list): List of True Positive keypoints. + conf (list): List of confidence scores. + pred_cls (list): List of predicted classes. + target_cls (list): List of target classes. + """ + + results_pose = ap_per_class(tp_p, + conf, + pred_cls, + target_cls, + plot=self.plot, + on_plot=self.on_plot, + save_dir=self.save_dir, + names=self.names, + prefix='Pose')[2:] + self.pose.nc = len(self.names) + self.pose.update(results_pose) + results_box = ap_per_class(tp_b, + conf, + pred_cls, + target_cls, + plot=self.plot, + on_plot=self.on_plot, + save_dir=self.save_dir, + names=self.names, + prefix='Box')[2:] + self.box.nc = len(self.names) + self.box.update(results_box) + + @property + def keys(self): + """Returns list of evaluation metric keys.""" + return [ + 'metrics/precision(B)', 'metrics/recall(B)', 'metrics/mAP50(B)', 'metrics/mAP50-95(B)', + 'metrics/precision(P)', 'metrics/recall(P)', 'metrics/mAP50(P)', 'metrics/mAP50-95(P)'] + + def mean_results(self): + """Return the mean results of box and pose.""" + return self.box.mean_results() + self.pose.mean_results() + + def class_result(self, i): + """Return the class-wise detection results for a specific class i.""" + return self.box.class_result(i) + self.pose.class_result(i) + + @property + def maps(self): + """Returns the mean average precision (mAP) per class for both box and pose detections.""" + return self.box.maps + self.pose.maps + + @property + def fitness(self): + """Computes classification metrics and speed using the `targets` and `pred` inputs.""" + return self.pose.fitness() + self.box.fitness() + + +class ClassifyMetrics(SimpleClass): + """ + Class for computing classification metrics including top-1 and top-5 accuracy. + + Attributes: + top1 (float): The top-1 accuracy. + top5 (float): The top-5 accuracy. + speed (Dict[str, float]): A dictionary containing the time taken for each step in the pipeline. + + Properties: + fitness (float): The fitness of the model, which is equal to top-5 accuracy. + results_dict (Dict[str, Union[float, str]]): A dictionary containing the classification metrics and fitness. + keys (List[str]): A list of keys for the results_dict. + + Methods: + process(targets, pred): Processes the targets and predictions to compute classification metrics. + """ + + def __init__(self) -> None: + self.top1 = 0 + self.top5 = 0 + self.speed = {'preprocess': 0.0, 'inference': 0.0, 'loss': 0.0, 'postprocess': 0.0} + + def process(self, targets, pred): + """Target classes and predicted classes.""" + pred, targets = torch.cat(pred), torch.cat(targets) + correct = (targets[:, None] == pred).float() + acc = torch.stack((correct[:, 0], correct.max(1).values), dim=1) # (top1, top5) accuracy + self.top1, self.top5 = acc.mean(0).tolist() + + @property + def fitness(self): + """Returns mean of top-1 and top-5 accuracies as fitness score.""" + return (self.top1 + self.top5) / 2 + + @property + def results_dict(self): + """Returns a dictionary with model's performance metrics and fitness score.""" + return dict(zip(self.keys + ['fitness'], [self.top1, self.top5, self.fitness])) + + @property + def keys(self): + """Returns a list of keys for the results_dict property.""" + return ['metrics/accuracy_top1', 'metrics/accuracy_top5'] diff --git a/downloads/ultralytics-main/ultralytics/utils/ops.py b/downloads/ultralytics-main/ultralytics/utils/ops.py new file mode 100644 index 000000000..ef741ad53 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/ops.py @@ -0,0 +1,771 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import contextlib +import math +import re +import time + +import cv2 +import numpy as np +import torch +import torch.nn.functional as F +import torchvision + +from ultralytics.utils import LOGGER + + +class Profile(contextlib.ContextDecorator): + """ + YOLOv8 Profile class. Use as a decorator with @Profile() or as a context manager with 'with Profile():'. + """ + + def __init__(self, t=0.0): + """ + Initialize the Profile class. + + Args: + t (float): Initial time. Defaults to 0.0. + """ + self.t = t + self.cuda = torch.cuda.is_available() + + def __enter__(self): + """Start timing.""" + self.start = self.time() + return self + + def __exit__(self, type, value, traceback): # noqa + """Stop timing.""" + self.dt = self.time() - self.start # delta-time + self.t += self.dt # accumulate dt + + def time(self): + """Get current time.""" + if self.cuda: + torch.cuda.synchronize() + return time.time() + + +def segment2box(segment, width=640, height=640): + """ + Convert 1 segment label to 1 box label, applying inside-image constraint, i.e. (xy1, xy2, ...) to (xyxy). + + Args: + segment (torch.Tensor): the segment label + width (int): the width of the image. Defaults to 640 + height (int): The height of the image. Defaults to 640 + + Returns: + (np.ndarray): the minimum and maximum x and y values of the segment. + """ + # Convert 1 segment label to 1 box label, applying inside-image constraint, i.e. (xy1, xy2, ...) to (xyxy) + x, y = segment.T # segment xy + inside = (x >= 0) & (y >= 0) & (x <= width) & (y <= height) + x, y, = x[inside], y[inside] + return np.array([x.min(), y.min(), x.max(), y.max()], dtype=segment.dtype) if any(x) else np.zeros( + 4, dtype=segment.dtype) # xyxy + + +def scale_boxes(img1_shape, boxes, img0_shape, ratio_pad=None, padding=True): + """ + Rescales bounding boxes (in the format of xyxy) from the shape of the image they were originally specified in + (img1_shape) to the shape of a different image (img0_shape). + + Args: + img1_shape (tuple): The shape of the image that the bounding boxes are for, in the format of (height, width). + boxes (torch.Tensor): the bounding boxes of the objects in the image, in the format of (x1, y1, x2, y2) + img0_shape (tuple): the shape of the target image, in the format of (height, width). + ratio_pad (tuple): a tuple of (ratio, pad) for scaling the boxes. If not provided, the ratio and pad will be + calculated based on the size difference between the two images. + padding (bool): If True, assuming the boxes is based on image augmented by yolo style. If False then do regular + rescaling. + + Returns: + boxes (torch.Tensor): The scaled bounding boxes, in the format of (x1, y1, x2, y2) + """ + if ratio_pad is None: # calculate from img0_shape + gain = min(img1_shape[0] / img0_shape[0], img1_shape[1] / img0_shape[1]) # gain = old / new + pad = round((img1_shape[1] - img0_shape[1] * gain) / 2 - 0.1), round( + (img1_shape[0] - img0_shape[0] * gain) / 2 - 0.1) # wh padding + else: + gain = ratio_pad[0][0] + pad = ratio_pad[1] + + if padding: + boxes[..., [0, 2]] -= pad[0] # x padding + boxes[..., [1, 3]] -= pad[1] # y padding + boxes[..., :4] /= gain + clip_boxes(boxes, img0_shape) + return boxes + + +def make_divisible(x, divisor): + """ + Returns the nearest number that is divisible by the given divisor. + + Args: + x (int): The number to make divisible. + divisor (int | torch.Tensor): The divisor. + + Returns: + (int): The nearest number divisible by the divisor. + """ + if isinstance(divisor, torch.Tensor): + divisor = int(divisor.max()) # to int + return math.ceil(x / divisor) * divisor + + +def non_max_suppression( + prediction, + conf_thres=0.25, + iou_thres=0.45, + classes=None, + agnostic=False, + multi_label=False, + labels=(), + max_det=300, + nc=0, # number of classes (optional) + max_time_img=0.05, + max_nms=30000, + max_wh=7680, +): + """ + Perform non-maximum suppression (NMS) on a set of boxes, with support for masks and multiple labels per box. + + Args: + prediction (torch.Tensor): A tensor of shape (batch_size, num_classes + 4 + num_masks, num_boxes) + containing the predicted boxes, classes, and masks. The tensor should be in the format + output by a model, such as YOLO. + conf_thres (float): The confidence threshold below which boxes will be filtered out. + Valid values are between 0.0 and 1.0. + iou_thres (float): The IoU threshold below which boxes will be filtered out during NMS. + Valid values are between 0.0 and 1.0. + classes (List[int]): A list of class indices to consider. If None, all classes will be considered. + agnostic (bool): If True, the model is agnostic to the number of classes, and all + classes will be considered as one. + multi_label (bool): If True, each box may have multiple labels. + labels (List[List[Union[int, float, torch.Tensor]]]): A list of lists, where each inner + list contains the apriori labels for a given image. The list should be in the format + output by a dataloader, with each label being a tuple of (class_index, x1, y1, x2, y2). + max_det (int): The maximum number of boxes to keep after NMS. + nc (int, optional): The number of classes output by the model. Any indices after this will be considered masks. + max_time_img (float): The maximum time (seconds) for processing one image. + max_nms (int): The maximum number of boxes into torchvision.ops.nms(). + max_wh (int): The maximum box width and height in pixels + + Returns: + (List[torch.Tensor]): A list of length batch_size, where each element is a tensor of + shape (num_boxes, 6 + num_masks) containing the kept boxes, with columns + (x1, y1, x2, y2, confidence, class, mask1, mask2, ...). + """ + + # Checks + assert 0 <= conf_thres <= 1, f'Invalid Confidence threshold {conf_thres}, valid values are between 0.0 and 1.0' + assert 0 <= iou_thres <= 1, f'Invalid IoU {iou_thres}, valid values are between 0.0 and 1.0' + if isinstance(prediction, (list, tuple)): # YOLOv8 model in validation model, output = (inference_out, loss_out) + prediction = prediction[0] # select only inference output + + device = prediction.device + mps = 'mps' in device.type # Apple MPS + if mps: # MPS not fully supported yet, convert tensors to CPU before NMS + prediction = prediction.cpu() + bs = prediction.shape[0] # batch size + nc = nc or (prediction.shape[1] - 4) # number of classes + nm = prediction.shape[1] - nc - 4 + mi = 4 + nc # mask start index + xc = prediction[:, 4:mi].amax(1) > conf_thres # candidates + + # Settings + # min_wh = 2 # (pixels) minimum box width and height + time_limit = 0.5 + max_time_img * bs # seconds to quit after + multi_label &= nc > 1 # multiple labels per box (adds 0.5ms/img) + + prediction = prediction.transpose(-1, -2) # shape(1,84,6300) to shape(1,6300,84) + prediction[..., :4] = xywh2xyxy(prediction[..., :4]) # xywh to xyxy + + t = time.time() + output = [torch.zeros((0, 6 + nm), device=prediction.device)] * bs + for xi, x in enumerate(prediction): # image index, image inference + # Apply constraints + # x[((x[:, 2:4] < min_wh) | (x[:, 2:4] > max_wh)).any(1), 4] = 0 # width-height + x = x[xc[xi]] # confidence + + # Cat apriori labels if autolabelling + if labels and len(labels[xi]): + lb = labels[xi] + v = torch.zeros((len(lb), nc + nm + 4), device=x.device) + v[:, :4] = xywh2xyxy(lb[:, 1:5]) # box + v[range(len(lb)), lb[:, 0].long() + 4] = 1.0 # cls + x = torch.cat((x, v), 0) + + # If none remain process next image + if not x.shape[0]: + continue + + # Detections matrix nx6 (xyxy, conf, cls) + box, cls, mask = x.split((4, nc, nm), 1) + + if multi_label: + i, j = torch.where(cls > conf_thres) + x = torch.cat((box[i], x[i, 4 + j, None], j[:, None].float(), mask[i]), 1) + else: # best class only + conf, j = cls.max(1, keepdim=True) + x = torch.cat((box, conf, j.float(), mask), 1)[conf.view(-1) > conf_thres] + + # Filter by class + if classes is not None: + x = x[(x[:, 5:6] == torch.tensor(classes, device=x.device)).any(1)] + + # Check shape + n = x.shape[0] # number of boxes + if not n: # no boxes + continue + if n > max_nms: # excess boxes + x = x[x[:, 4].argsort(descending=True)[:max_nms]] # sort by confidence and remove excess boxes + + # Batched NMS + c = x[:, 5:6] * (0 if agnostic else max_wh) # classes + boxes, scores = x[:, :4] + c, x[:, 4] # boxes (offset by class), scores + i = torchvision.ops.nms(boxes, scores, iou_thres) # NMS + i = i[:max_det] # limit detections + + # # Experimental + # merge = False # use merge-NMS + # if merge and (1 < n < 3E3): # Merge NMS (boxes merged using weighted mean) + # # Update boxes as boxes(i,4) = weights(i,n) * boxes(n,4) + # from .metrics import box_iou + # iou = box_iou(boxes[i], boxes) > iou_thres # iou matrix + # weights = iou * scores[None] # box weights + # x[i, :4] = torch.mm(weights, x[:, :4]).float() / weights.sum(1, keepdim=True) # merged boxes + # redundant = True # require redundant detections + # if redundant: + # i = i[iou.sum(1) > 1] # require redundancy + + output[xi] = x[i] + if mps: + output[xi] = output[xi].to(device) + if (time.time() - t) > time_limit: + LOGGER.warning(f'WARNING ⚠️ NMS time limit {time_limit:.3f}s exceeded') + break # time limit exceeded + + return output + + +def clip_boxes(boxes, shape): + """ + Takes a list of bounding boxes and a shape (height, width) and clips the bounding boxes to the shape. + + Args: + boxes (torch.Tensor): the bounding boxes to clip + shape (tuple): the shape of the image + """ + if isinstance(boxes, torch.Tensor): # faster individually + boxes[..., 0].clamp_(0, shape[1]) # x1 + boxes[..., 1].clamp_(0, shape[0]) # y1 + boxes[..., 2].clamp_(0, shape[1]) # x2 + boxes[..., 3].clamp_(0, shape[0]) # y2 + else: # np.array (faster grouped) + boxes[..., [0, 2]] = boxes[..., [0, 2]].clip(0, shape[1]) # x1, x2 + boxes[..., [1, 3]] = boxes[..., [1, 3]].clip(0, shape[0]) # y1, y2 + + +def clip_coords(coords, shape): + """ + Clip line coordinates to the image boundaries. + + Args: + coords (torch.Tensor | numpy.ndarray): A list of line coordinates. + shape (tuple): A tuple of integers representing the size of the image in the format (height, width). + + Returns: + (None): The function modifies the input `coordinates` in place, by clipping each coordinate to the image boundaries. + """ + if isinstance(coords, torch.Tensor): # faster individually + coords[..., 0].clamp_(0, shape[1]) # x + coords[..., 1].clamp_(0, shape[0]) # y + else: # np.array (faster grouped) + coords[..., 0] = coords[..., 0].clip(0, shape[1]) # x + coords[..., 1] = coords[..., 1].clip(0, shape[0]) # y + + +def scale_image(masks, im0_shape, ratio_pad=None): + """ + Takes a mask, and resizes it to the original image size + + Args: + masks (np.ndarray): resized and padded masks/images, [h, w, num]/[h, w, 3]. + im0_shape (tuple): the original image shape + ratio_pad (tuple): the ratio of the padding to the original image. + + Returns: + masks (torch.Tensor): The masks that are being returned. + """ + # Rescale coordinates (xyxy) from im1_shape to im0_shape + im1_shape = masks.shape + if im1_shape[:2] == im0_shape[:2]: + return masks + if ratio_pad is None: # calculate from im0_shape + gain = min(im1_shape[0] / im0_shape[0], im1_shape[1] / im0_shape[1]) # gain = old / new + pad = (im1_shape[1] - im0_shape[1] * gain) / 2, (im1_shape[0] - im0_shape[0] * gain) / 2 # wh padding + else: + gain = ratio_pad[0][0] + pad = ratio_pad[1] + top, left = int(pad[1]), int(pad[0]) # y, x + bottom, right = int(im1_shape[0] - pad[1]), int(im1_shape[1] - pad[0]) + + if len(masks.shape) < 2: + raise ValueError(f'"len of masks shape" should be 2 or 3, but got {len(masks.shape)}') + masks = masks[top:bottom, left:right] + masks = cv2.resize(masks, (im0_shape[1], im0_shape[0])) + if len(masks.shape) == 2: + masks = masks[:, :, None] + + return masks + + +def xyxy2xywh(x): + """ + Convert bounding box coordinates from (x1, y1, x2, y2) format to (x, y, width, height) format where (x1, y1) is the + top-left corner and (x2, y2) is the bottom-right corner. + + Args: + x (np.ndarray | torch.Tensor): The input bounding box coordinates in (x1, y1, x2, y2) format. + + Returns: + y (np.ndarray | torch.Tensor): The bounding box coordinates in (x, y, width, height) format. + """ + assert x.shape[-1] == 4, f'input shape last dimension expected 4 but input shape is {x.shape}' + y = torch.empty_like(x) if isinstance(x, torch.Tensor) else np.empty_like(x) # faster than clone/copy + y[..., 0] = (x[..., 0] + x[..., 2]) / 2 # x center + y[..., 1] = (x[..., 1] + x[..., 3]) / 2 # y center + y[..., 2] = x[..., 2] - x[..., 0] # width + y[..., 3] = x[..., 3] - x[..., 1] # height + return y + + +def xywh2xyxy(x): + """ + Convert bounding box coordinates from (x, y, width, height) format to (x1, y1, x2, y2) format where (x1, y1) is the + top-left corner and (x2, y2) is the bottom-right corner. + + Args: + x (np.ndarray | torch.Tensor): The input bounding box coordinates in (x, y, width, height) format. + + Returns: + y (np.ndarray | torch.Tensor): The bounding box coordinates in (x1, y1, x2, y2) format. + """ + assert x.shape[-1] == 4, f'input shape last dimension expected 4 but input shape is {x.shape}' + y = torch.empty_like(x) if isinstance(x, torch.Tensor) else np.empty_like(x) # faster than clone/copy + dw = x[..., 2] / 2 # half-width + dh = x[..., 3] / 2 # half-height + y[..., 0] = x[..., 0] - dw # top left x + y[..., 1] = x[..., 1] - dh # top left y + y[..., 2] = x[..., 0] + dw # bottom right x + y[..., 3] = x[..., 1] + dh # bottom right y + return y + + +def xywhn2xyxy(x, w=640, h=640, padw=0, padh=0): + """ + Convert normalized bounding box coordinates to pixel coordinates. + + Args: + x (np.ndarray | torch.Tensor): The bounding box coordinates. + w (int): Width of the image. Defaults to 640 + h (int): Height of the image. Defaults to 640 + padw (int): Padding width. Defaults to 0 + padh (int): Padding height. Defaults to 0 + Returns: + y (np.ndarray | torch.Tensor): The coordinates of the bounding box in the format [x1, y1, x2, y2] where + x1,y1 is the top-left corner, x2,y2 is the bottom-right corner of the bounding box. + """ + assert x.shape[-1] == 4, f'input shape last dimension expected 4 but input shape is {x.shape}' + y = torch.empty_like(x) if isinstance(x, torch.Tensor) else np.empty_like(x) # faster than clone/copy + y[..., 0] = w * (x[..., 0] - x[..., 2] / 2) + padw # top left x + y[..., 1] = h * (x[..., 1] - x[..., 3] / 2) + padh # top left y + y[..., 2] = w * (x[..., 0] + x[..., 2] / 2) + padw # bottom right x + y[..., 3] = h * (x[..., 1] + x[..., 3] / 2) + padh # bottom right y + return y + + +def xyxy2xywhn(x, w=640, h=640, clip=False, eps=0.0): + """ + Convert bounding box coordinates from (x1, y1, x2, y2) format to (x, y, width, height, normalized) format. + x, y, width and height are normalized to image dimensions + + Args: + x (np.ndarray | torch.Tensor): The input bounding box coordinates in (x1, y1, x2, y2) format. + w (int): The width of the image. Defaults to 640 + h (int): The height of the image. Defaults to 640 + clip (bool): If True, the boxes will be clipped to the image boundaries. Defaults to False + eps (float): The minimum value of the box's width and height. Defaults to 0.0 + + Returns: + y (np.ndarray | torch.Tensor): The bounding box coordinates in (x, y, width, height, normalized) format + """ + if clip: + clip_boxes(x, (h - eps, w - eps)) # warning: inplace clip + assert x.shape[-1] == 4, f'input shape last dimension expected 4 but input shape is {x.shape}' + y = torch.empty_like(x) if isinstance(x, torch.Tensor) else np.empty_like(x) # faster than clone/copy + y[..., 0] = ((x[..., 0] + x[..., 2]) / 2) / w # x center + y[..., 1] = ((x[..., 1] + x[..., 3]) / 2) / h # y center + y[..., 2] = (x[..., 2] - x[..., 0]) / w # width + y[..., 3] = (x[..., 3] - x[..., 1]) / h # height + return y + + +def xywh2ltwh(x): + """ + Convert the bounding box format from [x, y, w, h] to [x1, y1, w, h], where x1, y1 are the top-left coordinates. + + Args: + x (np.ndarray | torch.Tensor): The input tensor with the bounding box coordinates in the xywh format + + Returns: + y (np.ndarray | torch.Tensor): The bounding box coordinates in the xyltwh format + """ + y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x) + y[..., 0] = x[..., 0] - x[..., 2] / 2 # top left x + y[..., 1] = x[..., 1] - x[..., 3] / 2 # top left y + return y + + +def xyxy2ltwh(x): + """ + Convert nx4 bounding boxes from [x1, y1, x2, y2] to [x1, y1, w, h], where xy1=top-left, xy2=bottom-right + + Args: + x (np.ndarray | torch.Tensor): The input tensor with the bounding boxes coordinates in the xyxy format + + Returns: + y (np.ndarray | torch.Tensor): The bounding box coordinates in the xyltwh format. + """ + y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x) + y[..., 2] = x[..., 2] - x[..., 0] # width + y[..., 3] = x[..., 3] - x[..., 1] # height + return y + + +def ltwh2xywh(x): + """ + Convert nx4 boxes from [x1, y1, w, h] to [x, y, w, h] where xy1=top-left, xy=center + + Args: + x (torch.Tensor): the input tensor + + Returns: + y (np.ndarray | torch.Tensor): The bounding box coordinates in the xywh format. + """ + y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x) + y[..., 0] = x[..., 0] + x[..., 2] / 2 # center x + y[..., 1] = x[..., 1] + x[..., 3] / 2 # center y + return y + + +def xyxyxyxy2xywhr(corners): + """ + Convert batched Oriented Bounding Boxes (OBB) from [xy1, xy2, xy3, xy4] to [xywh, rotation]. + + Args: + corners (numpy.ndarray | torch.Tensor): Input corners of shape (n, 8). + + Returns: + (numpy.ndarray | torch.Tensor): Converted data in [cx, cy, w, h, rotation] format of shape (n, 5). + """ + is_numpy = isinstance(corners, np.ndarray) + atan2, sqrt = (np.arctan2, np.sqrt) if is_numpy else (torch.atan2, torch.sqrt) + + x1, y1, x2, y2, x3, y3, x4, y4 = corners.T + cx = (x1 + x3) / 2 + cy = (y1 + y3) / 2 + dx21 = x2 - x1 + dy21 = y2 - y1 + + w = sqrt(dx21 ** 2 + dy21 ** 2) + h = sqrt((x2 - x3) ** 2 + (y2 - y3) ** 2) + + rotation = atan2(-dy21, dx21) + rotation *= 180.0 / math.pi # radians to degrees + + return np.vstack((cx, cy, w, h, rotation)).T if is_numpy else torch.stack((cx, cy, w, h, rotation), dim=1) + + +def xywhr2xyxyxyxy(center): + """ + Convert batched Oriented Bounding Boxes (OBB) from [xywh, rotation] to [xy1, xy2, xy3, xy4]. + + Args: + center (numpy.ndarray | torch.Tensor): Input data in [cx, cy, w, h, rotation] format of shape (n, 5). + + Returns: + (numpy.ndarray | torch.Tensor): Converted corner points of shape (n, 8). + """ + is_numpy = isinstance(center, np.ndarray) + cos, sin = (np.cos, np.sin) if is_numpy else (torch.cos, torch.sin) + + cx, cy, w, h, rotation = center.T + rotation *= math.pi / 180.0 # degrees to radians + + dx = w / 2 + dy = h / 2 + + cos_rot = cos(rotation) + sin_rot = sin(rotation) + dx_cos_rot = dx * cos_rot + dx_sin_rot = dx * sin_rot + dy_cos_rot = dy * cos_rot + dy_sin_rot = dy * sin_rot + + x1 = cx - dx_cos_rot - dy_sin_rot + y1 = cy + dx_sin_rot - dy_cos_rot + x2 = cx + dx_cos_rot - dy_sin_rot + y2 = cy - dx_sin_rot - dy_cos_rot + x3 = cx + dx_cos_rot + dy_sin_rot + y3 = cy - dx_sin_rot + dy_cos_rot + x4 = cx - dx_cos_rot + dy_sin_rot + y4 = cy + dx_sin_rot + dy_cos_rot + + return np.vstack((x1, y1, x2, y2, x3, y3, x4, y4)).T if is_numpy else torch.stack( + (x1, y1, x2, y2, x3, y3, x4, y4), dim=1) + + +def ltwh2xyxy(x): + """ + It converts the bounding box from [x1, y1, w, h] to [x1, y1, x2, y2] where xy1=top-left, xy2=bottom-right + + Args: + x (np.ndarray | torch.Tensor): the input image + + Returns: + y (np.ndarray | torch.Tensor): the xyxy coordinates of the bounding boxes. + """ + y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x) + y[..., 2] = x[..., 2] + x[..., 0] # width + y[..., 3] = x[..., 3] + x[..., 1] # height + return y + + +def segments2boxes(segments): + """ + It converts segment labels to box labels, i.e. (cls, xy1, xy2, ...) to (cls, xywh) + + Args: + segments (list): list of segments, each segment is a list of points, each point is a list of x, y coordinates + + Returns: + (np.ndarray): the xywh coordinates of the bounding boxes. + """ + boxes = [] + for s in segments: + x, y = s.T # segment xy + boxes.append([x.min(), y.min(), x.max(), y.max()]) # cls, xyxy + return xyxy2xywh(np.array(boxes)) # cls, xywh + + +def resample_segments(segments, n=1000): + """ + Inputs a list of segments (n,2) and returns a list of segments (n,2) up-sampled to n points each. + + Args: + segments (list): a list of (n,2) arrays, where n is the number of points in the segment. + n (int): number of points to resample the segment to. Defaults to 1000 + + Returns: + segments (list): the resampled segments. + """ + for i, s in enumerate(segments): + s = np.concatenate((s, s[0:1, :]), axis=0) + x = np.linspace(0, len(s) - 1, n) + xp = np.arange(len(s)) + segments[i] = np.concatenate([np.interp(x, xp, s[:, i]) for i in range(2)], + dtype=np.float32).reshape(2, -1).T # segment xy + return segments + + +def crop_mask(masks, boxes): + """ + It takes a mask and a bounding box, and returns a mask that is cropped to the bounding box. + + Args: + masks (torch.Tensor): [n, h, w] tensor of masks + boxes (torch.Tensor): [n, 4] tensor of bbox coordinates in relative point form + + Returns: + (torch.Tensor): The masks are being cropped to the bounding box. + """ + n, h, w = masks.shape + x1, y1, x2, y2 = torch.chunk(boxes[:, :, None], 4, 1) # x1 shape(n,1,1) + r = torch.arange(w, device=masks.device, dtype=x1.dtype)[None, None, :] # rows shape(1,1,w) + c = torch.arange(h, device=masks.device, dtype=x1.dtype)[None, :, None] # cols shape(1,h,1) + + return masks * ((r >= x1) * (r < x2) * (c >= y1) * (c < y2)) + + +def process_mask_upsample(protos, masks_in, bboxes, shape): + """ + Takes the output of the mask head, and applies the mask to the bounding boxes. This produces masks of higher + quality but is slower. + + Args: + protos (torch.Tensor): [mask_dim, mask_h, mask_w] + masks_in (torch.Tensor): [n, mask_dim], n is number of masks after nms + bboxes (torch.Tensor): [n, 4], n is number of masks after nms + shape (tuple): the size of the input image (h,w) + + Returns: + (torch.Tensor): The upsampled masks. + """ + c, mh, mw = protos.shape # CHW + masks = (masks_in @ protos.float().view(c, -1)).sigmoid().view(-1, mh, mw) + masks = F.interpolate(masks[None], shape, mode='bilinear', align_corners=False)[0] # CHW + masks = crop_mask(masks, bboxes) # CHW + return masks.gt_(0.5) + + +def process_mask(protos, masks_in, bboxes, shape, upsample=False): + """ + Apply masks to bounding boxes using the output of the mask head. + + Args: + protos (torch.Tensor): A tensor of shape [mask_dim, mask_h, mask_w]. + masks_in (torch.Tensor): A tensor of shape [n, mask_dim], where n is the number of masks after NMS. + bboxes (torch.Tensor): A tensor of shape [n, 4], where n is the number of masks after NMS. + shape (tuple): A tuple of integers representing the size of the input image in the format (h, w). + upsample (bool): A flag to indicate whether to upsample the mask to the original image size. Default is False. + + Returns: + (torch.Tensor): A binary mask tensor of shape [n, h, w], where n is the number of masks after NMS, and h and w + are the height and width of the input image. The mask is applied to the bounding boxes. + """ + + c, mh, mw = protos.shape # CHW + ih, iw = shape + masks = (masks_in @ protos.float().view(c, -1)).sigmoid().view(-1, mh, mw) # CHW + + downsampled_bboxes = bboxes.clone() + downsampled_bboxes[:, 0] *= mw / iw + downsampled_bboxes[:, 2] *= mw / iw + downsampled_bboxes[:, 3] *= mh / ih + downsampled_bboxes[:, 1] *= mh / ih + + masks = crop_mask(masks, downsampled_bboxes) # CHW + if upsample: + masks = F.interpolate(masks[None], shape, mode='bilinear', align_corners=False)[0] # CHW + return masks.gt_(0.5) + + +def process_mask_native(protos, masks_in, bboxes, shape): + """ + It takes the output of the mask head, and crops it after upsampling to the bounding boxes. + + Args: + protos (torch.Tensor): [mask_dim, mask_h, mask_w] + masks_in (torch.Tensor): [n, mask_dim], n is number of masks after nms + bboxes (torch.Tensor): [n, 4], n is number of masks after nms + shape (tuple): the size of the input image (h,w) + + Returns: + masks (torch.Tensor): The returned masks with dimensions [h, w, n] + """ + c, mh, mw = protos.shape # CHW + masks = (masks_in @ protos.float().view(c, -1)).sigmoid().view(-1, mh, mw) + masks = scale_masks(masks[None], shape)[0] # CHW + masks = crop_mask(masks, bboxes) # CHW + return masks.gt_(0.5) + + +def scale_masks(masks, shape, padding=True): + """ + Rescale segment masks to shape. + + Args: + masks (torch.Tensor): (N, C, H, W). + shape (tuple): Height and width. + padding (bool): If True, assuming the boxes is based on image augmented by yolo style. If False then do regular + rescaling. + """ + mh, mw = masks.shape[2:] + gain = min(mh / shape[0], mw / shape[1]) # gain = old / new + pad = [mw - shape[1] * gain, mh - shape[0] * gain] # wh padding + if padding: + pad[0] /= 2 + pad[1] /= 2 + top, left = (int(pad[1]), int(pad[0])) if padding else (0, 0) # y, x + bottom, right = (int(mh - pad[1]), int(mw - pad[0])) + masks = masks[..., top:bottom, left:right] + + masks = F.interpolate(masks, shape, mode='bilinear', align_corners=False) # NCHW + return masks + + +def scale_coords(img1_shape, coords, img0_shape, ratio_pad=None, normalize=False, padding=True): + """ + Rescale segment coordinates (xy) from img1_shape to img0_shape + + Args: + img1_shape (tuple): The shape of the image that the coords are from. + coords (torch.Tensor): the coords to be scaled of shape n,2. + img0_shape (tuple): the shape of the image that the segmentation is being applied to. + ratio_pad (tuple): the ratio of the image size to the padded image size. + normalize (bool): If True, the coordinates will be normalized to the range [0, 1]. Defaults to False. + padding (bool): If True, assuming the boxes is based on image augmented by yolo style. If False then do regular + rescaling. + + Returns: + coords (torch.Tensor): The scaled coordinates. + """ + if ratio_pad is None: # calculate from img0_shape + gain = min(img1_shape[0] / img0_shape[0], img1_shape[1] / img0_shape[1]) # gain = old / new + pad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2 # wh padding + else: + gain = ratio_pad[0][0] + pad = ratio_pad[1] + + if padding: + coords[..., 0] -= pad[0] # x padding + coords[..., 1] -= pad[1] # y padding + coords[..., 0] /= gain + coords[..., 1] /= gain + clip_coords(coords, img0_shape) + if normalize: + coords[..., 0] /= img0_shape[1] # width + coords[..., 1] /= img0_shape[0] # height + return coords + + +def masks2segments(masks, strategy='largest'): + """ + It takes a list of masks(n,h,w) and returns a list of segments(n,xy) + + Args: + masks (torch.Tensor): the output of the model, which is a tensor of shape (batch_size, 160, 160) + strategy (str): 'concat' or 'largest'. Defaults to largest + + Returns: + segments (List): list of segment masks + """ + segments = [] + for x in masks.int().cpu().numpy().astype('uint8'): + c = cv2.findContours(x, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0] + if c: + if strategy == 'concat': # concatenate all segments + c = np.concatenate([x.reshape(-1, 2) for x in c]) + elif strategy == 'largest': # select largest segment + c = np.array(c[np.array([len(x) for x in c]).argmax()]).reshape(-1, 2) + else: + c = np.zeros((0, 2)) # no segments found + segments.append(c.astype('float32')) + return segments + + +def clean_str(s): + """ + Cleans a string by replacing special characters with underscore _ + + Args: + s (str): a string needing special characters replaced + + Returns: + (str): a string with special characters replaced by an underscore _ + """ + return re.sub(pattern='[|@#!¡·$€%&()=?¿^*;:,¨´><+]', repl='_', string=s) diff --git a/downloads/ultralytics-main/ultralytics/utils/patches.py b/downloads/ultralytics-main/ultralytics/utils/patches.py new file mode 100644 index 000000000..4cbebd0ef --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/patches.py @@ -0,0 +1,45 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license +""" +Monkey patches to update/extend functionality of existing functions +""" + +from pathlib import Path + +import cv2 +import numpy as np +import torch + +# OpenCV Multilanguage-friendly functions ------------------------------------------------------------------------------ +_imshow = cv2.imshow # copy to avoid recursion errors + + +def imread(filename, flags=cv2.IMREAD_COLOR): + return cv2.imdecode(np.fromfile(filename, np.uint8), flags) + + +def imwrite(filename, img): + try: + cv2.imencode(Path(filename).suffix, img)[1].tofile(filename) + return True + except Exception: + return False + + +def imshow(path, im): + _imshow(path.encode('unicode_escape').decode(), im) + + +# PyTorch functions ---------------------------------------------------------------------------------------------------- +_torch_save = torch.save # copy to avoid recursion errors + + +def torch_save(*args, **kwargs): + """Use dill (if exists) to serialize the lambda functions where pickle does not do this.""" + try: + import dill as pickle + except ImportError: + import pickle + + if 'pickle_module' not in kwargs: + kwargs['pickle_module'] = pickle + return _torch_save(*args, **kwargs) diff --git a/downloads/ultralytics-main/ultralytics/utils/plotting.py b/downloads/ultralytics-main/ultralytics/utils/plotting.py new file mode 100644 index 000000000..9ad79e20c --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/plotting.py @@ -0,0 +1,592 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import contextlib +import math +import warnings +from pathlib import Path + +import cv2 +import matplotlib.pyplot as plt +import numpy as np +import torch +from PIL import Image, ImageDraw, ImageFont +from PIL import __version__ as pil_version + +from ultralytics.utils import LOGGER, TryExcept, plt_settings, threaded + +from .checks import check_font, check_version, is_ascii +from .files import increment_path +from .ops import clip_boxes, scale_image, xywh2xyxy, xyxy2xywh + + +class Colors: + """ + Ultralytics default color palette https://ultralytics.com/. + + This class provides methods to work with the Ultralytics color palette, including converting hex color codes to + RGB values. + + Attributes: + palette (list of tuple): List of RGB color values. + n (int): The number of colors in the palette. + pose_palette (np.array): A specific color palette array with dtype np.uint8. + """ + + def __init__(self): + """Initialize colors as hex = matplotlib.colors.TABLEAU_COLORS.values().""" + hexs = ('FF3838', 'FF9D97', 'FF701F', 'FFB21D', 'CFD231', '48F90A', '92CC17', '3DDB86', '1A9334', '00D4BB', + '2C99A8', '00C2FF', '344593', '6473FF', '0018EC', '8438FF', '520085', 'CB38FF', 'FF95C8', 'FF37C7') + self.palette = [self.hex2rgb(f'#{c}') for c in hexs] + self.n = len(self.palette) + self.pose_palette = np.array([[255, 128, 0], [255, 153, 51], [255, 178, 102], [230, 230, 0], [255, 153, 255], + [153, 204, 255], [255, 102, 255], [255, 51, 255], [102, 178, 255], [51, 153, 255], + [255, 153, 153], [255, 102, 102], [255, 51, 51], [153, 255, 153], [102, 255, 102], + [51, 255, 51], [0, 255, 0], [0, 0, 255], [255, 0, 0], [255, 255, 255]], + dtype=np.uint8) + + def __call__(self, i, bgr=False): + """Converts hex color codes to RGB values.""" + c = self.palette[int(i) % self.n] + return (c[2], c[1], c[0]) if bgr else c + + @staticmethod + def hex2rgb(h): + """Converts hex color codes to RGB values (i.e. default PIL order).""" + return tuple(int(h[1 + i:1 + i + 2], 16) for i in (0, 2, 4)) + + +colors = Colors() # create instance for 'from utils.plots import colors' + + +class Annotator: + """ + Ultralytics Annotator for train/val mosaics and JPGs and predictions annotations. + + Attributes: + im (Image.Image or numpy array): The image to annotate. + pil (bool): Whether to use PIL or cv2 for drawing annotations. + font (ImageFont.truetype or ImageFont.load_default): Font used for text annotations. + lw (float): Line width for drawing. + skeleton (List[List[int]]): Skeleton structure for keypoints. + limb_color (List[int]): Color palette for limbs. + kpt_color (List[int]): Color palette for keypoints. + """ + + def __init__(self, im, line_width=None, font_size=None, font='Arial.ttf', pil=False, example='abc'): + """Initialize the Annotator class with image and line width along with color palette for keypoints and limbs.""" + assert im.data.contiguous, 'Image not contiguous. Apply np.ascontiguousarray(im) to Annotator() input images.' + non_ascii = not is_ascii(example) # non-latin labels, i.e. asian, arabic, cyrillic + self.pil = pil or non_ascii + if self.pil: # use PIL + self.im = im if isinstance(im, Image.Image) else Image.fromarray(im) + self.draw = ImageDraw.Draw(self.im) + try: + font = check_font('Arial.Unicode.ttf' if non_ascii else font) + size = font_size or max(round(sum(self.im.size) / 2 * 0.035), 12) + self.font = ImageFont.truetype(str(font), size) + except Exception: + self.font = ImageFont.load_default() + # Deprecation fix for w, h = getsize(string) -> _, _, w, h = getbox(string) + if check_version(pil_version, '9.2.0'): + self.font.getsize = lambda x: self.font.getbbox(x)[2:4] # text width, height + else: # use cv2 + self.im = im + self.lw = line_width or max(round(sum(im.shape) / 2 * 0.003), 2) # line width + # Pose + self.skeleton = [[16, 14], [14, 12], [17, 15], [15, 13], [12, 13], [6, 12], [7, 13], [6, 7], [6, 8], [7, 9], + [8, 10], [9, 11], [2, 3], [1, 2], [1, 3], [2, 4], [3, 5], [4, 6], [5, 7]] + + self.limb_color = colors.pose_palette[[9, 9, 9, 9, 7, 7, 7, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16]] + self.kpt_color = colors.pose_palette[[16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9]] + + def box_label(self, box, label='', color=(128, 128, 128), txt_color=(255, 255, 255)): + """Add one xyxy box to image with label.""" + if isinstance(box, torch.Tensor): + box = box.tolist() + if self.pil or not is_ascii(label): + self.draw.rectangle(box, width=self.lw, outline=color) # box + if label: + w, h = self.font.getsize(label) # text width, height + outside = box[1] - h >= 0 # label fits outside box + self.draw.rectangle( + (box[0], box[1] - h if outside else box[1], box[0] + w + 1, + box[1] + 1 if outside else box[1] + h + 1), + fill=color, + ) + # self.draw.text((box[0], box[1]), label, fill=txt_color, font=self.font, anchor='ls') # for PIL>8.0 + self.draw.text((box[0], box[1] - h if outside else box[1]), label, fill=txt_color, font=self.font) + else: # cv2 + p1, p2 = (int(box[0]), int(box[1])), (int(box[2]), int(box[3])) + cv2.rectangle(self.im, p1, p2, color, thickness=self.lw, lineType=cv2.LINE_AA) + if label: + tf = max(self.lw - 1, 1) # font thickness + w, h = cv2.getTextSize(label, 0, fontScale=self.lw / 3, thickness=tf)[0] # text width, height + outside = p1[1] - h >= 3 + p2 = p1[0] + w, p1[1] - h - 3 if outside else p1[1] + h + 3 + cv2.rectangle(self.im, p1, p2, color, -1, cv2.LINE_AA) # filled + cv2.putText(self.im, + label, (p1[0], p1[1] - 2 if outside else p1[1] + h + 2), + 0, + self.lw / 3, + txt_color, + thickness=tf, + lineType=cv2.LINE_AA) + + def masks(self, masks, colors, im_gpu, alpha=0.5, retina_masks=False): + """ + Plot masks on image. + + Args: + masks (tensor): Predicted masks on cuda, shape: [n, h, w] + colors (List[List[Int]]): Colors for predicted masks, [[r, g, b] * n] + im_gpu (tensor): Image is in cuda, shape: [3, h, w], range: [0, 1] + alpha (float): Mask transparency: 0.0 fully transparent, 1.0 opaque + retina_masks (bool): Whether to use high resolution masks or not. Defaults to False. + """ + if self.pil: + # Convert to numpy first + self.im = np.asarray(self.im).copy() + if len(masks) == 0: + self.im[:] = im_gpu.permute(1, 2, 0).contiguous().cpu().numpy() * 255 + if im_gpu.device != masks.device: + im_gpu = im_gpu.to(masks.device) + colors = torch.tensor(colors, device=masks.device, dtype=torch.float32) / 255.0 # shape(n,3) + colors = colors[:, None, None] # shape(n,1,1,3) + masks = masks.unsqueeze(3) # shape(n,h,w,1) + masks_color = masks * (colors * alpha) # shape(n,h,w,3) + + inv_alph_masks = (1 - masks * alpha).cumprod(0) # shape(n,h,w,1) + mcs = masks_color.max(dim=0).values # shape(n,h,w,3) + + im_gpu = im_gpu.flip(dims=[0]) # flip channel + im_gpu = im_gpu.permute(1, 2, 0).contiguous() # shape(h,w,3) + im_gpu = im_gpu * inv_alph_masks[-1] + mcs + im_mask = (im_gpu * 255) + im_mask_np = im_mask.byte().cpu().numpy() + self.im[:] = im_mask_np if retina_masks else scale_image(im_mask_np, self.im.shape) + if self.pil: + # Convert im back to PIL and update draw + self.fromarray(self.im) + + def kpts(self, kpts, shape=(640, 640), radius=5, kpt_line=True): + """ + Plot keypoints on the image. + + Args: + kpts (tensor): Predicted keypoints with shape [17, 3]. Each keypoint has (x, y, confidence). + shape (tuple): Image shape as a tuple (h, w), where h is the height and w is the width. + radius (int, optional): Radius of the drawn keypoints. Default is 5. + kpt_line (bool, optional): If True, the function will draw lines connecting keypoints + for human pose. Default is True. + + Note: `kpt_line=True` currently only supports human pose plotting. + """ + if self.pil: + # Convert to numpy first + self.im = np.asarray(self.im).copy() + nkpt, ndim = kpts.shape + is_pose = nkpt == 17 and ndim == 3 + kpt_line &= is_pose # `kpt_line=True` for now only supports human pose plotting + for i, k in enumerate(kpts): + color_k = [int(x) for x in self.kpt_color[i]] if is_pose else colors(i) + x_coord, y_coord = k[0], k[1] + if x_coord % shape[1] != 0 and y_coord % shape[0] != 0: + if len(k) == 3: + conf = k[2] + if conf < 0.5: + continue + cv2.circle(self.im, (int(x_coord), int(y_coord)), radius, color_k, -1, lineType=cv2.LINE_AA) + + if kpt_line: + ndim = kpts.shape[-1] + for i, sk in enumerate(self.skeleton): + pos1 = (int(kpts[(sk[0] - 1), 0]), int(kpts[(sk[0] - 1), 1])) + pos2 = (int(kpts[(sk[1] - 1), 0]), int(kpts[(sk[1] - 1), 1])) + if ndim == 3: + conf1 = kpts[(sk[0] - 1), 2] + conf2 = kpts[(sk[1] - 1), 2] + if conf1 < 0.5 or conf2 < 0.5: + continue + if pos1[0] % shape[1] == 0 or pos1[1] % shape[0] == 0 or pos1[0] < 0 or pos1[1] < 0: + continue + if pos2[0] % shape[1] == 0 or pos2[1] % shape[0] == 0 or pos2[0] < 0 or pos2[1] < 0: + continue + cv2.line(self.im, pos1, pos2, [int(x) for x in self.limb_color[i]], thickness=2, lineType=cv2.LINE_AA) + if self.pil: + # Convert im back to PIL and update draw + self.fromarray(self.im) + + def rectangle(self, xy, fill=None, outline=None, width=1): + """Add rectangle to image (PIL-only).""" + self.draw.rectangle(xy, fill, outline, width) + + def text(self, xy, text, txt_color=(255, 255, 255), anchor='top', box_style=False): + """Adds text to an image using PIL or cv2.""" + if anchor == 'bottom': # start y from font bottom + w, h = self.font.getsize(text) # text width, height + xy[1] += 1 - h + if self.pil: + if box_style: + w, h = self.font.getsize(text) + self.draw.rectangle((xy[0], xy[1], xy[0] + w + 1, xy[1] + h + 1), fill=txt_color) + # Using `txt_color` for background and draw fg with white color + txt_color = (255, 255, 255) + if '\n' in text: + lines = text.split('\n') + _, h = self.font.getsize(text) + for line in lines: + self.draw.text(xy, line, fill=txt_color, font=self.font) + xy[1] += h + else: + self.draw.text(xy, text, fill=txt_color, font=self.font) + else: + if box_style: + tf = max(self.lw - 1, 1) # font thickness + w, h = cv2.getTextSize(text, 0, fontScale=self.lw / 3, thickness=tf)[0] # text width, height + outside = xy[1] - h >= 3 + p2 = xy[0] + w, xy[1] - h - 3 if outside else xy[1] + h + 3 + cv2.rectangle(self.im, xy, p2, txt_color, -1, cv2.LINE_AA) # filled + # Using `txt_color` for background and draw fg with white color + txt_color = (255, 255, 255) + tf = max(self.lw - 1, 1) # font thickness + cv2.putText(self.im, text, xy, 0, self.lw / 3, txt_color, thickness=tf, lineType=cv2.LINE_AA) + + def fromarray(self, im): + """Update self.im from a numpy array.""" + self.im = im if isinstance(im, Image.Image) else Image.fromarray(im) + self.draw = ImageDraw.Draw(self.im) + + def result(self): + """Return annotated image as array.""" + return np.asarray(self.im) + + +@TryExcept() # known issue https://github.com/ultralytics/yolov5/issues/5395 +@plt_settings() +def plot_labels(boxes, cls, names=(), save_dir=Path(''), on_plot=None): + """Plot training labels including class histograms and box statistics.""" + import pandas as pd + import seaborn as sn + + # Filter matplotlib>=3.7.2 warning + warnings.filterwarnings('ignore', category=UserWarning, message='The figure layout has changed to tight') + + # Plot dataset labels + LOGGER.info(f"Plotting labels to {save_dir / 'labels.jpg'}... ") + nc = int(cls.max() + 1) # number of classes + boxes = boxes[:1000000] # limit to 1M boxes + x = pd.DataFrame(boxes, columns=['x', 'y', 'width', 'height']) + + # Seaborn correlogram + sn.pairplot(x, corner=True, diag_kind='auto', kind='hist', diag_kws=dict(bins=50), plot_kws=dict(pmax=0.9)) + plt.savefig(save_dir / 'labels_correlogram.jpg', dpi=200) + plt.close() + + # Matplotlib labels + ax = plt.subplots(2, 2, figsize=(8, 8), tight_layout=True)[1].ravel() + y = ax[0].hist(cls, bins=np.linspace(0, nc, nc + 1) - 0.5, rwidth=0.8) + with contextlib.suppress(Exception): # color histogram bars by class + [y[2].patches[i].set_color([x / 255 for x in colors(i)]) for i in range(nc)] # known issue #3195 + ax[0].set_ylabel('instances') + if 0 < len(names) < 30: + ax[0].set_xticks(range(len(names))) + ax[0].set_xticklabels(list(names.values()), rotation=90, fontsize=10) + else: + ax[0].set_xlabel('classes') + sn.histplot(x, x='x', y='y', ax=ax[2], bins=50, pmax=0.9) + sn.histplot(x, x='width', y='height', ax=ax[3], bins=50, pmax=0.9) + + # Rectangles + boxes[:, 0:2] = 0.5 # center + boxes = xywh2xyxy(boxes) * 1000 + img = Image.fromarray(np.ones((1000, 1000, 3), dtype=np.uint8) * 255) + for cls, box in zip(cls[:500], boxes[:500]): + ImageDraw.Draw(img).rectangle(box, width=1, outline=colors(cls)) # plot + ax[1].imshow(img) + ax[1].axis('off') + + for a in [0, 1, 2, 3]: + for s in ['top', 'right', 'left', 'bottom']: + ax[a].spines[s].set_visible(False) + + fname = save_dir / 'labels.jpg' + plt.savefig(fname, dpi=200) + plt.close() + if on_plot: + on_plot(fname) + + +def save_one_box(xyxy, im, file=Path('im.jpg'), gain=1.02, pad=10, square=False, BGR=False, save=True): + """Save image crop as {file} with crop size multiple {gain} and {pad} pixels. Save and/or return crop. + + This function takes a bounding box and an image, and then saves a cropped portion of the image according + to the bounding box. Optionally, the crop can be squared, and the function allows for gain and padding + adjustments to the bounding box. + + Args: + xyxy (torch.Tensor or list): A tensor or list representing the bounding box in xyxy format. + im (numpy.ndarray): The input image. + file (Path, optional): The path where the cropped image will be saved. Defaults to 'im.jpg'. + gain (float, optional): A multiplicative factor to increase the size of the bounding box. Defaults to 1.02. + pad (int, optional): The number of pixels to add to the width and height of the bounding box. Defaults to 10. + square (bool, optional): If True, the bounding box will be transformed into a square. Defaults to False. + BGR (bool, optional): If True, the image will be saved in BGR format, otherwise in RGB. Defaults to False. + save (bool, optional): If True, the cropped image will be saved to disk. Defaults to True. + + Returns: + (numpy.ndarray): The cropped image. + + Example: + ```python + from ultralytics.utils.plotting import save_one_box + + xyxy = [50, 50, 150, 150] + im = cv2.imread('image.jpg') + cropped_im = save_one_box(xyxy, im, file='cropped.jpg', square=True) + ``` + """ + + if not isinstance(xyxy, torch.Tensor): # may be list + xyxy = torch.stack(xyxy) + b = xyxy2xywh(xyxy.view(-1, 4)) # boxes + if square: + b[:, 2:] = b[:, 2:].max(1)[0].unsqueeze(1) # attempt rectangle to square + b[:, 2:] = b[:, 2:] * gain + pad # box wh * gain + pad + xyxy = xywh2xyxy(b).long() + clip_boxes(xyxy, im.shape) + crop = im[int(xyxy[0, 1]):int(xyxy[0, 3]), int(xyxy[0, 0]):int(xyxy[0, 2]), ::(1 if BGR else -1)] + if save: + file.parent.mkdir(parents=True, exist_ok=True) # make directory + f = str(increment_path(file).with_suffix('.jpg')) + # cv2.imwrite(f, crop) # save BGR, https://github.com/ultralytics/yolov5/issues/7007 chroma subsampling issue + Image.fromarray(crop[..., ::-1]).save(f, quality=95, subsampling=0) # save RGB + return crop + + +@threaded +def plot_images(images, + batch_idx, + cls, + bboxes=np.zeros(0, dtype=np.float32), + masks=np.zeros(0, dtype=np.uint8), + kpts=np.zeros((0, 51), dtype=np.float32), + paths=None, + fname='images.jpg', + names=None, + on_plot=None): + """Plot image grid with labels.""" + if isinstance(images, torch.Tensor): + images = images.cpu().float().numpy() + if isinstance(cls, torch.Tensor): + cls = cls.cpu().numpy() + if isinstance(bboxes, torch.Tensor): + bboxes = bboxes.cpu().numpy() + if isinstance(masks, torch.Tensor): + masks = masks.cpu().numpy().astype(int) + if isinstance(kpts, torch.Tensor): + kpts = kpts.cpu().numpy() + if isinstance(batch_idx, torch.Tensor): + batch_idx = batch_idx.cpu().numpy() + + max_size = 1920 # max image size + max_subplots = 16 # max image subplots, i.e. 4x4 + bs, _, h, w = images.shape # batch size, _, height, width + bs = min(bs, max_subplots) # limit plot images + ns = np.ceil(bs ** 0.5) # number of subplots (square) + if np.max(images[0]) <= 1: + images *= 255 # de-normalise (optional) + + # Build Image + mosaic = np.full((int(ns * h), int(ns * w), 3), 255, dtype=np.uint8) # init + for i, im in enumerate(images): + if i == max_subplots: # if last batch has fewer images than we expect + break + x, y = int(w * (i // ns)), int(h * (i % ns)) # block origin + im = im.transpose(1, 2, 0) + mosaic[y:y + h, x:x + w, :] = im + + # Resize (optional) + scale = max_size / ns / max(h, w) + if scale < 1: + h = math.ceil(scale * h) + w = math.ceil(scale * w) + mosaic = cv2.resize(mosaic, tuple(int(x * ns) for x in (w, h))) + + # Annotate + fs = int((h + w) * ns * 0.01) # font size + annotator = Annotator(mosaic, line_width=round(fs / 10), font_size=fs, pil=True, example=names) + for i in range(i + 1): + x, y = int(w * (i // ns)), int(h * (i % ns)) # block origin + annotator.rectangle([x, y, x + w, y + h], None, (255, 255, 255), width=2) # borders + if paths: + annotator.text((x + 5, y + 5), text=Path(paths[i]).name[:40], txt_color=(220, 220, 220)) # filenames + if len(cls) > 0: + idx = batch_idx == i + classes = cls[idx].astype('int') + + if len(bboxes): + boxes = xywh2xyxy(bboxes[idx, :4]).T + labels = bboxes.shape[1] == 4 # labels if no conf column + conf = None if labels else bboxes[idx, 4] # check for confidence presence (label vs pred) + + if boxes.shape[1]: + if boxes.max() <= 1.01: # if normalized with tolerance 0.01 + boxes[[0, 2]] *= w # scale to pixels + boxes[[1, 3]] *= h + elif scale < 1: # absolute coords need scale if image scales + boxes *= scale + boxes[[0, 2]] += x + boxes[[1, 3]] += y + for j, box in enumerate(boxes.T.tolist()): + c = classes[j] + color = colors(c) + c = names.get(c, c) if names else c + if labels or conf[j] > 0.25: # 0.25 conf thresh + label = f'{c}' if labels else f'{c} {conf[j]:.1f}' + annotator.box_label(box, label, color=color) + elif len(classes): + for c in classes: + color = colors(c) + c = names.get(c, c) if names else c + annotator.text((x, y), f'{c}', txt_color=color, box_style=True) + + # Plot keypoints + if len(kpts): + kpts_ = kpts[idx].copy() + if len(kpts_): + if kpts_[..., 0].max() <= 1.01 or kpts_[..., 1].max() <= 1.01: # if normalized with tolerance .01 + kpts_[..., 0] *= w # scale to pixels + kpts_[..., 1] *= h + elif scale < 1: # absolute coords need scale if image scales + kpts_ *= scale + kpts_[..., 0] += x + kpts_[..., 1] += y + for j in range(len(kpts_)): + if labels or conf[j] > 0.25: # 0.25 conf thresh + annotator.kpts(kpts_[j]) + + # Plot masks + if len(masks): + if idx.shape[0] == masks.shape[0]: # overlap_masks=False + image_masks = masks[idx] + else: # overlap_masks=True + image_masks = masks[[i]] # (1, 640, 640) + nl = idx.sum() + index = np.arange(nl).reshape((nl, 1, 1)) + 1 + image_masks = np.repeat(image_masks, nl, axis=0) + image_masks = np.where(image_masks == index, 1.0, 0.0) + + im = np.asarray(annotator.im).copy() + for j, box in enumerate(boxes.T.tolist()): + if labels or conf[j] > 0.25: # 0.25 conf thresh + color = colors(classes[j]) + mh, mw = image_masks[j].shape + if mh != h or mw != w: + mask = image_masks[j].astype(np.uint8) + mask = cv2.resize(mask, (w, h)) + mask = mask.astype(bool) + else: + mask = image_masks[j].astype(bool) + with contextlib.suppress(Exception): + im[y:y + h, x:x + w, :][mask] = im[y:y + h, x:x + w, :][mask] * 0.4 + np.array(color) * 0.6 + annotator.fromarray(im) + annotator.im.save(fname) # save + if on_plot: + on_plot(fname) + + +@plt_settings() +def plot_results(file='path/to/results.csv', dir='', segment=False, pose=False, classify=False, on_plot=None): + """ + Plot training results from results CSV file. + + Example: + ```python + from ultralytics.utils.plotting import plot_results + + plot_results('path/to/results.csv') + ``` + """ + import pandas as pd + from scipy.ndimage import gaussian_filter1d + save_dir = Path(file).parent if file else Path(dir) + if classify: + fig, ax = plt.subplots(2, 2, figsize=(6, 6), tight_layout=True) + index = [1, 4, 2, 3] + elif segment: + fig, ax = plt.subplots(2, 8, figsize=(18, 6), tight_layout=True) + index = [1, 2, 3, 4, 5, 6, 9, 10, 13, 14, 15, 16, 7, 8, 11, 12] + elif pose: + fig, ax = plt.subplots(2, 9, figsize=(21, 6), tight_layout=True) + index = [1, 2, 3, 4, 5, 6, 7, 10, 11, 14, 15, 16, 17, 18, 8, 9, 12, 13] + else: + fig, ax = plt.subplots(2, 5, figsize=(12, 6), tight_layout=True) + index = [1, 2, 3, 4, 5, 8, 9, 10, 6, 7] + ax = ax.ravel() + files = list(save_dir.glob('results*.csv')) + assert len(files), f'No results.csv files found in {save_dir.resolve()}, nothing to plot.' + for f in files: + try: + data = pd.read_csv(f) + s = [x.strip() for x in data.columns] + x = data.values[:, 0] + for i, j in enumerate(index): + y = data.values[:, j].astype('float') + # y[y == 0] = np.nan # don't show zero values + ax[i].plot(x, y, marker='.', label=f.stem, linewidth=2, markersize=8) # actual results + ax[i].plot(x, gaussian_filter1d(y, sigma=3), ':', label='smooth', linewidth=2) # smoothing line + ax[i].set_title(s[j], fontsize=12) + # if j in [8, 9, 10]: # share train and val loss y axes + # ax[i].get_shared_y_axes().join(ax[i], ax[i - 5]) + except Exception as e: + LOGGER.warning(f'WARNING: Plotting error for {f}: {e}') + ax[1].legend() + fname = save_dir / 'results.png' + fig.savefig(fname, dpi=200) + plt.close() + if on_plot: + on_plot(fname) + + +def output_to_target(output, max_det=300): + """Convert model output to target format [batch_id, class_id, x, y, w, h, conf] for plotting.""" + targets = [] + for i, o in enumerate(output): + box, conf, cls = o[:max_det, :6].cpu().split((4, 1, 1), 1) + j = torch.full((conf.shape[0], 1), i) + targets.append(torch.cat((j, cls, xyxy2xywh(box), conf), 1)) + targets = torch.cat(targets, 0).numpy() + return targets[:, 0], targets[:, 1], targets[:, 2:] + + +def feature_visualization(x, module_type, stage, n=32, save_dir=Path('runs/detect/exp')): + """ + Visualize feature maps of a given model module during inference. + + Args: + x (torch.Tensor): Features to be visualized. + module_type (str): Module type. + stage (int): Module stage within the model. + n (int, optional): Maximum number of feature maps to plot. Defaults to 32. + save_dir (Path, optional): Directory to save results. Defaults to Path('runs/detect/exp'). + """ + for m in ['Detect', 'Pose', 'Segment']: + if m in module_type: + return + batch, channels, height, width = x.shape # batch, channels, height, width + if height > 1 and width > 1: + f = save_dir / f"stage{stage}_{module_type.split('.')[-1]}_features.png" # filename + + blocks = torch.chunk(x[0].cpu(), channels, dim=0) # select batch index 0, block by channels + n = min(n, channels) # number of plots + fig, ax = plt.subplots(math.ceil(n / 8), 8, tight_layout=True) # 8 rows x n/8 cols + ax = ax.ravel() + plt.subplots_adjust(wspace=0.05, hspace=0.05) + for i in range(n): + ax[i].imshow(blocks[i].squeeze()) # cmap='gray' + ax[i].axis('off') + + LOGGER.info(f'Saving {f}... ({n}/{channels})') + plt.savefig(f, dpi=300, bbox_inches='tight') + plt.close() + np.save(str(f.with_suffix('.npy')), x[0].cpu().numpy()) # npy save diff --git a/downloads/ultralytics-main/ultralytics/utils/tal.py b/downloads/ultralytics-main/ultralytics/utils/tal.py new file mode 100644 index 000000000..87f457915 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/tal.py @@ -0,0 +1,279 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import torch +import torch.nn as nn + +from .checks import check_version +from .metrics import bbox_iou + +TORCH_1_10 = check_version(torch.__version__, '1.10.0') + + +def select_candidates_in_gts(xy_centers, gt_bboxes, eps=1e-9): + """ + Select the positive anchor center in gt. + + Args: + xy_centers (Tensor): shape(h*w, 4) + gt_bboxes (Tensor): shape(b, n_boxes, 4) + + Returns: + (Tensor): shape(b, n_boxes, h*w) + """ + n_anchors = xy_centers.shape[0] + bs, n_boxes, _ = gt_bboxes.shape + lt, rb = gt_bboxes.view(-1, 1, 4).chunk(2, 2) # left-top, right-bottom + bbox_deltas = torch.cat((xy_centers[None] - lt, rb - xy_centers[None]), dim=2).view(bs, n_boxes, n_anchors, -1) + # return (bbox_deltas.min(3)[0] > eps).to(gt_bboxes.dtype) + return bbox_deltas.amin(3).gt_(eps) + + +def select_highest_overlaps(mask_pos, overlaps, n_max_boxes): + """ + If an anchor box is assigned to multiple gts, the one with the highest IoI will be selected. + + Args: + mask_pos (Tensor): shape(b, n_max_boxes, h*w) + overlaps (Tensor): shape(b, n_max_boxes, h*w) + + Returns: + target_gt_idx (Tensor): shape(b, h*w) + fg_mask (Tensor): shape(b, h*w) + mask_pos (Tensor): shape(b, n_max_boxes, h*w) + """ + # (b, n_max_boxes, h*w) -> (b, h*w) + fg_mask = mask_pos.sum(-2) + if fg_mask.max() > 1: # one anchor is assigned to multiple gt_bboxes + mask_multi_gts = (fg_mask.unsqueeze(1) > 1).expand(-1, n_max_boxes, -1) # (b, n_max_boxes, h*w) + max_overlaps_idx = overlaps.argmax(1) # (b, h*w) + + is_max_overlaps = torch.zeros(mask_pos.shape, dtype=mask_pos.dtype, device=mask_pos.device) + is_max_overlaps.scatter_(1, max_overlaps_idx.unsqueeze(1), 1) + + mask_pos = torch.where(mask_multi_gts, is_max_overlaps, mask_pos).float() # (b, n_max_boxes, h*w) + fg_mask = mask_pos.sum(-2) + # Find each grid serve which gt(index) + target_gt_idx = mask_pos.argmax(-2) # (b, h*w) + return target_gt_idx, fg_mask, mask_pos + + +class TaskAlignedAssigner(nn.Module): + """ + A task-aligned assigner for object detection. + + This class assigns ground-truth (gt) objects to anchors based on the task-aligned metric, + which combines both classification and localization information. + + Attributes: + topk (int): The number of top candidates to consider. + num_classes (int): The number of object classes. + alpha (float): The alpha parameter for the classification component of the task-aligned metric. + beta (float): The beta parameter for the localization component of the task-aligned metric. + eps (float): A small value to prevent division by zero. + """ + + def __init__(self, topk=13, num_classes=80, alpha=1.0, beta=6.0, eps=1e-9): + """Initialize a TaskAlignedAssigner object with customizable hyperparameters.""" + super().__init__() + self.topk = topk + self.num_classes = num_classes + self.bg_idx = num_classes + self.alpha = alpha + self.beta = beta + self.eps = eps + + @torch.no_grad() + def forward(self, pd_scores, pd_bboxes, anc_points, gt_labels, gt_bboxes, mask_gt): + """ + Compute the task-aligned assignment. + Reference https://github.com/Nioolek/PPYOLOE_pytorch/blob/master/ppyoloe/assigner/tal_assigner.py + + Args: + pd_scores (Tensor): shape(bs, num_total_anchors, num_classes) + pd_bboxes (Tensor): shape(bs, num_total_anchors, 4) + anc_points (Tensor): shape(num_total_anchors, 2) + gt_labels (Tensor): shape(bs, n_max_boxes, 1) + gt_bboxes (Tensor): shape(bs, n_max_boxes, 4) + mask_gt (Tensor): shape(bs, n_max_boxes, 1) + + Returns: + target_labels (Tensor): shape(bs, num_total_anchors) + target_bboxes (Tensor): shape(bs, num_total_anchors, 4) + target_scores (Tensor): shape(bs, num_total_anchors, num_classes) + fg_mask (Tensor): shape(bs, num_total_anchors) + target_gt_idx (Tensor): shape(bs, num_total_anchors) + """ + self.bs = pd_scores.size(0) + self.n_max_boxes = gt_bboxes.size(1) + + if self.n_max_boxes == 0: + device = gt_bboxes.device + return (torch.full_like(pd_scores[..., 0], self.bg_idx).to(device), torch.zeros_like(pd_bboxes).to(device), + torch.zeros_like(pd_scores).to(device), torch.zeros_like(pd_scores[..., 0]).to(device), + torch.zeros_like(pd_scores[..., 0]).to(device)) + + mask_pos, align_metric, overlaps = self.get_pos_mask(pd_scores, pd_bboxes, gt_labels, gt_bboxes, anc_points, + mask_gt) + + target_gt_idx, fg_mask, mask_pos = select_highest_overlaps(mask_pos, overlaps, self.n_max_boxes) + + # Assigned target + target_labels, target_bboxes, target_scores = self.get_targets(gt_labels, gt_bboxes, target_gt_idx, fg_mask) + + # Normalize + align_metric *= mask_pos + pos_align_metrics = align_metric.amax(axis=-1, keepdim=True) # b, max_num_obj + pos_overlaps = (overlaps * mask_pos).amax(axis=-1, keepdim=True) # b, max_num_obj + norm_align_metric = (align_metric * pos_overlaps / (pos_align_metrics + self.eps)).amax(-2).unsqueeze(-1) + target_scores = target_scores * norm_align_metric + + return target_labels, target_bboxes, target_scores, fg_mask.bool(), target_gt_idx + + def get_pos_mask(self, pd_scores, pd_bboxes, gt_labels, gt_bboxes, anc_points, mask_gt): + """Get in_gts mask, (b, max_num_obj, h*w).""" + mask_in_gts = select_candidates_in_gts(anc_points, gt_bboxes) + # Get anchor_align metric, (b, max_num_obj, h*w) + align_metric, overlaps = self.get_box_metrics(pd_scores, pd_bboxes, gt_labels, gt_bboxes, mask_in_gts * mask_gt) + # Get topk_metric mask, (b, max_num_obj, h*w) + mask_topk = self.select_topk_candidates(align_metric, topk_mask=mask_gt.expand(-1, -1, self.topk).bool()) + # Merge all mask to a final mask, (b, max_num_obj, h*w) + mask_pos = mask_topk * mask_in_gts * mask_gt + + return mask_pos, align_metric, overlaps + + def get_box_metrics(self, pd_scores, pd_bboxes, gt_labels, gt_bboxes, mask_gt): + """Compute alignment metric given predicted and ground truth bounding boxes.""" + na = pd_bboxes.shape[-2] + mask_gt = mask_gt.bool() # b, max_num_obj, h*w + overlaps = torch.zeros([self.bs, self.n_max_boxes, na], dtype=pd_bboxes.dtype, device=pd_bboxes.device) + bbox_scores = torch.zeros([self.bs, self.n_max_boxes, na], dtype=pd_scores.dtype, device=pd_scores.device) + + ind = torch.zeros([2, self.bs, self.n_max_boxes], dtype=torch.long) # 2, b, max_num_obj + ind[0] = torch.arange(end=self.bs).view(-1, 1).expand(-1, self.n_max_boxes) # b, max_num_obj + ind[1] = gt_labels.squeeze(-1) # b, max_num_obj + # Get the scores of each grid for each gt cls + bbox_scores[mask_gt] = pd_scores[ind[0], :, ind[1]][mask_gt] # b, max_num_obj, h*w + + # (b, max_num_obj, 1, 4), (b, 1, h*w, 4) + pd_boxes = pd_bboxes.unsqueeze(1).expand(-1, self.n_max_boxes, -1, -1)[mask_gt] + gt_boxes = gt_bboxes.unsqueeze(2).expand(-1, -1, na, -1)[mask_gt] + overlaps[mask_gt] = bbox_iou(gt_boxes, pd_boxes, xywh=False, CIoU=True).squeeze(-1).clamp_(0) + + align_metric = bbox_scores.pow(self.alpha) * overlaps.pow(self.beta) + return align_metric, overlaps + + def select_topk_candidates(self, metrics, largest=True, topk_mask=None): + """ + Select the top-k candidates based on the given metrics. + + Args: + metrics (Tensor): A tensor of shape (b, max_num_obj, h*w), where b is the batch size, + max_num_obj is the maximum number of objects, and h*w represents the + total number of anchor points. + largest (bool): If True, select the largest values; otherwise, select the smallest values. + topk_mask (Tensor): An optional boolean tensor of shape (b, max_num_obj, topk), where + topk is the number of top candidates to consider. If not provided, + the top-k values are automatically computed based on the given metrics. + + Returns: + (Tensor): A tensor of shape (b, max_num_obj, h*w) containing the selected top-k candidates. + """ + + # (b, max_num_obj, topk) + topk_metrics, topk_idxs = torch.topk(metrics, self.topk, dim=-1, largest=largest) + if topk_mask is None: + topk_mask = (topk_metrics.max(-1, keepdim=True)[0] > self.eps).expand_as(topk_idxs) + # (b, max_num_obj, topk) + topk_idxs.masked_fill_(~topk_mask, 0) + + # (b, max_num_obj, topk, h*w) -> (b, max_num_obj, h*w) + count_tensor = torch.zeros(metrics.shape, dtype=torch.int8, device=topk_idxs.device) + ones = torch.ones_like(topk_idxs[:, :, :1], dtype=torch.int8, device=topk_idxs.device) + for k in range(self.topk): + # Expand topk_idxs for each value of k and add 1 at the specified positions + count_tensor.scatter_add_(-1, topk_idxs[:, :, k:k + 1], ones) + # count_tensor.scatter_add_(-1, topk_idxs, torch.ones_like(topk_idxs, dtype=torch.int8, device=topk_idxs.device)) + # filter invalid bboxes + count_tensor.masked_fill_(count_tensor > 1, 0) + + return count_tensor.to(metrics.dtype) + + def get_targets(self, gt_labels, gt_bboxes, target_gt_idx, fg_mask): + """ + Compute target labels, target bounding boxes, and target scores for the positive anchor points. + + Args: + gt_labels (Tensor): Ground truth labels of shape (b, max_num_obj, 1), where b is the + batch size and max_num_obj is the maximum number of objects. + gt_bboxes (Tensor): Ground truth bounding boxes of shape (b, max_num_obj, 4). + target_gt_idx (Tensor): Indices of the assigned ground truth objects for positive + anchor points, with shape (b, h*w), where h*w is the total + number of anchor points. + fg_mask (Tensor): A boolean tensor of shape (b, h*w) indicating the positive + (foreground) anchor points. + + Returns: + (Tuple[Tensor, Tensor, Tensor]): A tuple containing the following tensors: + - target_labels (Tensor): Shape (b, h*w), containing the target labels for + positive anchor points. + - target_bboxes (Tensor): Shape (b, h*w, 4), containing the target bounding boxes + for positive anchor points. + - target_scores (Tensor): Shape (b, h*w, num_classes), containing the target scores + for positive anchor points, where num_classes is the number + of object classes. + """ + + # Assigned target labels, (b, 1) + batch_ind = torch.arange(end=self.bs, dtype=torch.int64, device=gt_labels.device)[..., None] + target_gt_idx = target_gt_idx + batch_ind * self.n_max_boxes # (b, h*w) + target_labels = gt_labels.long().flatten()[target_gt_idx] # (b, h*w) + + # Assigned target boxes, (b, max_num_obj, 4) -> (b, h*w) + target_bboxes = gt_bboxes.view(-1, 4)[target_gt_idx] + + # Assigned target scores + target_labels.clamp_(0) + + # 10x faster than F.one_hot() + target_scores = torch.zeros((target_labels.shape[0], target_labels.shape[1], self.num_classes), + dtype=torch.int64, + device=target_labels.device) # (b, h*w, 80) + target_scores.scatter_(2, target_labels.unsqueeze(-1), 1) + + fg_scores_mask = fg_mask[:, :, None].repeat(1, 1, self.num_classes) # (b, h*w, 80) + target_scores = torch.where(fg_scores_mask > 0, target_scores, 0) + + return target_labels, target_bboxes, target_scores + + +def make_anchors(feats, strides, grid_cell_offset=0.5): + """Generate anchors from features.""" + anchor_points, stride_tensor = [], [] + assert feats is not None + dtype, device = feats[0].dtype, feats[0].device + for i, stride in enumerate(strides): + _, _, h, w = feats[i].shape + sx = torch.arange(end=w, device=device, dtype=dtype) + grid_cell_offset # shift x + sy = torch.arange(end=h, device=device, dtype=dtype) + grid_cell_offset # shift y + sy, sx = torch.meshgrid(sy, sx, indexing='ij') if TORCH_1_10 else torch.meshgrid(sy, sx) + anchor_points.append(torch.stack((sx, sy), -1).view(-1, 2)) + stride_tensor.append(torch.full((h * w, 1), stride, dtype=dtype, device=device)) + return torch.cat(anchor_points), torch.cat(stride_tensor) + + +def dist2bbox(distance, anchor_points, xywh=True, dim=-1): + """Transform distance(ltrb) to box(xywh or xyxy).""" + lt, rb = distance.chunk(2, dim) + x1y1 = anchor_points - lt + x2y2 = anchor_points + rb + if xywh: + c_xy = (x1y1 + x2y2) / 2 + wh = x2y2 - x1y1 + return torch.cat((c_xy, wh), dim) # xywh bbox + return torch.cat((x1y1, x2y2), dim) # xyxy bbox + + +def bbox2dist(anchor_points, bbox, reg_max): + """Transform bbox(xyxy) to dist(ltrb).""" + x1y1, x2y2 = bbox.chunk(2, -1) + return torch.cat((anchor_points - x1y1, x2y2 - anchor_points), -1).clamp_(0, reg_max - 0.01) # dist (lt, rb) diff --git a/downloads/ultralytics-main/ultralytics/utils/torch_utils.py b/downloads/ultralytics-main/ultralytics/utils/torch_utils.py new file mode 100644 index 000000000..def7442b9 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/torch_utils.py @@ -0,0 +1,526 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +import math +import os +import platform +import random +import time +from contextlib import contextmanager +from copy import deepcopy +from pathlib import Path +from typing import Union + +import numpy as np +import torch +import torch.distributed as dist +import torch.nn as nn +import torch.nn.functional as F + +from ultralytics.utils import DEFAULT_CFG_DICT, DEFAULT_CFG_KEYS, LOGGER, RANK, __version__ +from ultralytics.utils.checks import check_version + +try: + import thop +except ImportError: + thop = None + +TORCH_1_9 = check_version(torch.__version__, '1.9.0') +TORCH_2_0 = check_version(torch.__version__, '2.0.0') + + +@contextmanager +def torch_distributed_zero_first(local_rank: int): + """Decorator to make all processes in distributed training wait for each local_master to do something.""" + initialized = torch.distributed.is_available() and torch.distributed.is_initialized() + if initialized and local_rank not in (-1, 0): + dist.barrier(device_ids=[local_rank]) + yield + if initialized and local_rank == 0: + dist.barrier(device_ids=[0]) + + +def smart_inference_mode(): + """Applies torch.inference_mode() decorator if torch>=1.9.0 else torch.no_grad() decorator.""" + + def decorate(fn): + """Applies appropriate torch decorator for inference mode based on torch version.""" + return (torch.inference_mode if TORCH_1_9 else torch.no_grad)()(fn) + + return decorate + + +def get_cpu_info(): + """Return a string with system CPU information, i.e. 'Apple M2'.""" + import cpuinfo # pip install py-cpuinfo + + k = 'brand_raw', 'hardware_raw', 'arch_string_raw' # info keys sorted by preference (not all keys always available) + info = cpuinfo.get_cpu_info() # info dict + string = info.get(k[0] if k[0] in info else k[1] if k[1] in info else k[2], 'unknown') + return string.replace('(R)', '').replace('CPU ', '').replace('@ ', '') + + +def select_device(device='', batch=0, newline=False, verbose=True): + """Selects PyTorch Device. Options are device = None or 'cpu' or 0 or '0' or '0,1,2,3'.""" + s = f'Ultralytics YOLOv{__version__} 🚀 Python-{platform.python_version()} torch-{torch.__version__} ' + device = str(device).lower() + for remove in 'cuda:', 'none', '(', ')', '[', ']', "'", ' ': + device = device.replace(remove, '') # to string, 'cuda:0' -> '0' and '(0, 1)' -> '0,1' + cpu = device == 'cpu' + mps = device == 'mps' # Apple Metal Performance Shaders (MPS) + if cpu or mps: + os.environ['CUDA_VISIBLE_DEVICES'] = '-1' # force torch.cuda.is_available() = False + elif device: # non-cpu device requested + if device == 'cuda': + device = '0' + visible = os.environ.get('CUDA_VISIBLE_DEVICES', None) + os.environ['CUDA_VISIBLE_DEVICES'] = device # set environment variable - must be before assert is_available() + if not (torch.cuda.is_available() and torch.cuda.device_count() >= len(device.replace(',', ''))): + LOGGER.info(s) + install = 'See https://pytorch.org/get-started/locally/ for up-to-date torch install instructions if no ' \ + 'CUDA devices are seen by torch.\n' if torch.cuda.device_count() == 0 else '' + raise ValueError(f"Invalid CUDA 'device={device}' requested." + f" Use 'device=cpu' or pass valid CUDA device(s) if available," + f" i.e. 'device=0' or 'device=0,1,2,3' for Multi-GPU.\n" + f'\ntorch.cuda.is_available(): {torch.cuda.is_available()}' + f'\ntorch.cuda.device_count(): {torch.cuda.device_count()}' + f"\nos.environ['CUDA_VISIBLE_DEVICES']: {visible}\n" + f'{install}') + + if not cpu and not mps and torch.cuda.is_available(): # prefer GPU if available + devices = device.split(',') if device else '0' # range(torch.cuda.device_count()) # i.e. 0,1,6,7 + n = len(devices) # device count + if n > 1 and batch > 0 and batch % n != 0: # check batch_size is divisible by device_count + raise ValueError(f"'batch={batch}' must be a multiple of GPU count {n}. Try 'batch={batch // n * n}' or " + f"'batch={batch // n * n + n}', the nearest batch sizes evenly divisible by {n}.") + space = ' ' * (len(s) + 1) + for i, d in enumerate(devices): + p = torch.cuda.get_device_properties(i) + s += f"{'' if i == 0 else space}CUDA:{d} ({p.name}, {p.total_memory / (1 << 20):.0f}MiB)\n" # bytes to MB + arg = 'cuda:0' + elif mps and getattr(torch, 'has_mps', False) and torch.backends.mps.is_available() and TORCH_2_0: + # Prefer MPS if available + s += f'MPS ({get_cpu_info()})\n' + arg = 'mps' + else: # revert to CPU + s += f'CPU ({get_cpu_info()})\n' + arg = 'cpu' + + if verbose and RANK == -1: + LOGGER.info(s if newline else s.rstrip()) + return torch.device(arg) + + +def time_sync(): + """PyTorch-accurate time.""" + if torch.cuda.is_available(): + torch.cuda.synchronize() + return time.time() + + +def fuse_conv_and_bn(conv, bn): + """Fuse Conv2d() and BatchNorm2d() layers https://tehnokv.com/posts/fusing-batchnorm-and-conv/.""" + fusedconv = nn.Conv2d(conv.in_channels, + conv.out_channels, + kernel_size=conv.kernel_size, + stride=conv.stride, + padding=conv.padding, + dilation=conv.dilation, + groups=conv.groups, + bias=True).requires_grad_(False).to(conv.weight.device) + + # Prepare filters + w_conv = conv.weight.clone().view(conv.out_channels, -1) + w_bn = torch.diag(bn.weight.div(torch.sqrt(bn.eps + bn.running_var))) + fusedconv.weight.copy_(torch.mm(w_bn, w_conv).view(fusedconv.weight.shape)) + + # Prepare spatial bias + b_conv = torch.zeros(conv.weight.size(0), device=conv.weight.device) if conv.bias is None else conv.bias + b_bn = bn.bias - bn.weight.mul(bn.running_mean).div(torch.sqrt(bn.running_var + bn.eps)) + fusedconv.bias.copy_(torch.mm(w_bn, b_conv.reshape(-1, 1)).reshape(-1) + b_bn) + + return fusedconv + + +def fuse_deconv_and_bn(deconv, bn): + """Fuse ConvTranspose2d() and BatchNorm2d() layers.""" + fuseddconv = nn.ConvTranspose2d(deconv.in_channels, + deconv.out_channels, + kernel_size=deconv.kernel_size, + stride=deconv.stride, + padding=deconv.padding, + output_padding=deconv.output_padding, + dilation=deconv.dilation, + groups=deconv.groups, + bias=True).requires_grad_(False).to(deconv.weight.device) + + # Prepare filters + w_deconv = deconv.weight.clone().view(deconv.out_channels, -1) + w_bn = torch.diag(bn.weight.div(torch.sqrt(bn.eps + bn.running_var))) + fuseddconv.weight.copy_(torch.mm(w_bn, w_deconv).view(fuseddconv.weight.shape)) + + # Prepare spatial bias + b_conv = torch.zeros(deconv.weight.size(1), device=deconv.weight.device) if deconv.bias is None else deconv.bias + b_bn = bn.bias - bn.weight.mul(bn.running_mean).div(torch.sqrt(bn.running_var + bn.eps)) + fuseddconv.bias.copy_(torch.mm(w_bn, b_conv.reshape(-1, 1)).reshape(-1) + b_bn) + + return fuseddconv + + +def model_info(model, detailed=False, verbose=True, imgsz=640): + """Model information. imgsz may be int or list, i.e. imgsz=640 or imgsz=[640, 320].""" + if not verbose: + return + n_p = get_num_params(model) # number of parameters + n_g = get_num_gradients(model) # number of gradients + n_l = len(list(model.modules())) # number of layers + if detailed: + LOGGER.info( + f"{'layer':>5} {'name':>40} {'gradient':>9} {'parameters':>12} {'shape':>20} {'mu':>10} {'sigma':>10}") + for i, (name, p) in enumerate(model.named_parameters()): + name = name.replace('module_list.', '') + LOGGER.info('%5g %40s %9s %12g %20s %10.3g %10.3g %10s' % + (i, name, p.requires_grad, p.numel(), list(p.shape), p.mean(), p.std(), p.dtype)) + + flops = get_flops(model, imgsz) + fused = ' (fused)' if getattr(model, 'is_fused', lambda: False)() else '' + fs = f', {flops:.1f} GFLOPs' if flops else '' + yaml_file = getattr(model, 'yaml_file', '') or getattr(model, 'yaml', {}).get('yaml_file', '') + model_name = Path(yaml_file).stem.replace('yolo', 'YOLO') or 'Model' + LOGGER.info(f'{model_name} summary{fused}: {n_l} layers, {n_p} parameters, {n_g} gradients{fs}') + return n_l, n_p, n_g, flops + + +def get_num_params(model): + """Return the total number of parameters in a YOLO model.""" + return sum(x.numel() for x in model.parameters()) + + +def get_num_gradients(model): + """Return the total number of parameters with gradients in a YOLO model.""" + return sum(x.numel() for x in model.parameters() if x.requires_grad) + + +def model_info_for_loggers(trainer): + """ + Return model info dict with useful model information. + + Example for YOLOv8n: + {'model/parameters': 3151904, + 'model/GFLOPs': 8.746, + 'model/speed_ONNX(ms)': 41.244, + 'model/speed_TensorRT(ms)': 3.211, + 'model/speed_PyTorch(ms)': 18.755} + """ + if trainer.args.profile: # profile ONNX and TensorRT times + from ultralytics.utils.benchmarks import ProfileModels + results = ProfileModels([trainer.last], device=trainer.device).profile()[0] + results.pop('model/name') + else: # only return PyTorch times from most recent validation + results = { + 'model/parameters': get_num_params(trainer.model), + 'model/GFLOPs': round(get_flops(trainer.model), 3)} + results['model/speed_PyTorch(ms)'] = round(trainer.validator.speed['inference'], 3) + return results + + +def get_flops(model, imgsz=640): + """Return a YOLO model's FLOPs.""" + try: + model = de_parallel(model) + p = next(model.parameters()) + stride = max(int(model.stride.max()), 32) if hasattr(model, 'stride') else 32 # max stride + im = torch.empty((1, p.shape[1], stride, stride), device=p.device) # input image in BCHW format + flops = thop.profile(deepcopy(model), inputs=[im], verbose=False)[0] / 1E9 * 2 if thop else 0 # stride GFLOPs + imgsz = imgsz if isinstance(imgsz, list) else [imgsz, imgsz] # expand if int/float + return flops * imgsz[0] / stride * imgsz[1] / stride # 640x640 GFLOPs + except Exception: + return 0 + + +def get_flops_with_torch_profiler(model, imgsz=640): + """Compute model FLOPs (thop alternative).""" + if TORCH_2_0: + model = de_parallel(model) + p = next(model.parameters()) + stride = (max(int(model.stride.max()), 32) if hasattr(model, 'stride') else 32) * 2 # max stride + im = torch.zeros((1, p.shape[1], stride, stride), device=p.device) # input image in BCHW format + with torch.profiler.profile(with_flops=True) as prof: + model(im) + flops = sum(x.flops for x in prof.key_averages()) / 1E9 + imgsz = imgsz if isinstance(imgsz, list) else [imgsz, imgsz] # expand if int/float + flops = flops * imgsz[0] / stride * imgsz[1] / stride # 640x640 GFLOPs + return flops + return 0 + + +def initialize_weights(model): + """Initialize model weights to random values.""" + for m in model.modules(): + t = type(m) + if t is nn.Conv2d: + pass # nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu') + elif t is nn.BatchNorm2d: + m.eps = 1e-3 + m.momentum = 0.03 + elif t in [nn.Hardswish, nn.LeakyReLU, nn.ReLU, nn.ReLU6, nn.SiLU]: + m.inplace = True + + +def scale_img(img, ratio=1.0, same_shape=False, gs=32): # img(16,3,256,416) + # Scales img(bs,3,y,x) by ratio constrained to gs-multiple + if ratio == 1.0: + return img + h, w = img.shape[2:] + s = (int(h * ratio), int(w * ratio)) # new size + img = F.interpolate(img, size=s, mode='bilinear', align_corners=False) # resize + if not same_shape: # pad/crop img + h, w = (math.ceil(x * ratio / gs) * gs for x in (h, w)) + return F.pad(img, [0, w - s[1], 0, h - s[0]], value=0.447) # value = imagenet mean + + +def make_divisible(x, divisor): + """Returns nearest x divisible by divisor.""" + if isinstance(divisor, torch.Tensor): + divisor = int(divisor.max()) # to int + return math.ceil(x / divisor) * divisor + + +def copy_attr(a, b, include=(), exclude=()): + """Copies attributes from object 'b' to object 'a', with options to include/exclude certain attributes.""" + for k, v in b.__dict__.items(): + if (len(include) and k not in include) or k.startswith('_') or k in exclude: + continue + else: + setattr(a, k, v) + + +def get_latest_opset(): + """Return second-most (for maturity) recently supported ONNX opset by this version of torch.""" + return max(int(k[14:]) for k in vars(torch.onnx) if 'symbolic_opset' in k) - 1 # opset + + +def intersect_dicts(da, db, exclude=()): + """Returns a dictionary of intersecting keys with matching shapes, excluding 'exclude' keys, using da values.""" + return {k: v for k, v in da.items() if k in db and all(x not in k for x in exclude) and v.shape == db[k].shape} + + +def is_parallel(model): + """Returns True if model is of type DP or DDP.""" + return isinstance(model, (nn.parallel.DataParallel, nn.parallel.DistributedDataParallel)) + + +def de_parallel(model): + """De-parallelize a model: returns single-GPU model if model is of type DP or DDP.""" + return model.module if is_parallel(model) else model + + +def one_cycle(y1=0.0, y2=1.0, steps=100): + """Returns a lambda function for sinusoidal ramp from y1 to y2 https://arxiv.org/pdf/1812.01187.pdf.""" + return lambda x: ((1 - math.cos(x * math.pi / steps)) / 2) * (y2 - y1) + y1 + + +def init_seeds(seed=0, deterministic=False): + """Initialize random number generator (RNG) seeds https://pytorch.org/docs/stable/notes/randomness.html.""" + random.seed(seed) + np.random.seed(seed) + torch.manual_seed(seed) + torch.cuda.manual_seed(seed) + torch.cuda.manual_seed_all(seed) # for Multi-GPU, exception safe + # torch.backends.cudnn.benchmark = True # AutoBatch problem https://github.com/ultralytics/yolov5/issues/9287 + if deterministic: + if TORCH_2_0: + torch.use_deterministic_algorithms(True, warn_only=True) # warn if deterministic is not possible + torch.backends.cudnn.deterministic = True + os.environ['CUBLAS_WORKSPACE_CONFIG'] = ':4096:8' + os.environ['PYTHONHASHSEED'] = str(seed) + else: + LOGGER.warning('WARNING ⚠️ Upgrade to torch>=2.0.0 for deterministic training.') + else: + torch.use_deterministic_algorithms(False) + torch.backends.cudnn.deterministic = False + + +class ModelEMA: + """Updated Exponential Moving Average (EMA) from https://github.com/rwightman/pytorch-image-models + Keeps a moving average of everything in the model state_dict (parameters and buffers) + For EMA details see https://www.tensorflow.org/api_docs/python/tf/train/ExponentialMovingAverage + To disable EMA set the `enabled` attribute to `False`. + """ + + def __init__(self, model, decay=0.9999, tau=2000, updates=0): + """Create EMA.""" + self.ema = deepcopy(de_parallel(model)).eval() # FP32 EMA + self.updates = updates # number of EMA updates + self.decay = lambda x: decay * (1 - math.exp(-x / tau)) # decay exponential ramp (to help early epochs) + for p in self.ema.parameters(): + p.requires_grad_(False) + self.enabled = True + + def update(self, model): + """Update EMA parameters.""" + if self.enabled: + self.updates += 1 + d = self.decay(self.updates) + + msd = de_parallel(model).state_dict() # model state_dict + for k, v in self.ema.state_dict().items(): + if v.dtype.is_floating_point: # true for FP16 and FP32 + v *= d + v += (1 - d) * msd[k].detach() + # assert v.dtype == msd[k].dtype == torch.float32, f'{k}: EMA {v.dtype}, model {msd[k].dtype}' + + def update_attr(self, model, include=(), exclude=('process_group', 'reducer')): + """Updates attributes and saves stripped model with optimizer removed.""" + if self.enabled: + copy_attr(self.ema, model, include, exclude) + + +def strip_optimizer(f: Union[str, Path] = 'best.pt', s: str = '') -> None: + """ + Strip optimizer from 'f' to finalize training, optionally save as 's'. + + Args: + f (str): file path to model to strip the optimizer from. Default is 'best.pt'. + s (str): file path to save the model with stripped optimizer to. If not provided, 'f' will be overwritten. + + Returns: + None + + Example: + ```python + from pathlib import Path + from ultralytics.utils.torch_utils import strip_optimizer + + for f in Path('path/to/weights').rglob('*.pt'): + strip_optimizer(f) + ``` + """ + # Use dill (if exists) to serialize the lambda functions where pickle does not do this + try: + import dill as pickle + except ImportError: + import pickle + + x = torch.load(f, map_location=torch.device('cpu')) + if 'model' not in x: + LOGGER.info(f'Skipping {f}, not a valid Ultralytics model.') + return + + if hasattr(x['model'], 'args'): + x['model'].args = dict(x['model'].args) # convert from IterableSimpleNamespace to dict + args = {**DEFAULT_CFG_DICT, **x['train_args']} if 'train_args' in x else None # combine args + if x.get('ema'): + x['model'] = x['ema'] # replace model with ema + for k in 'optimizer', 'best_fitness', 'ema', 'updates': # keys + x[k] = None + x['epoch'] = -1 + x['model'].half() # to FP16 + for p in x['model'].parameters(): + p.requires_grad = False + x['train_args'] = {k: v for k, v in args.items() if k in DEFAULT_CFG_KEYS} # strip non-default keys + # x['model'].args = x['train_args'] + torch.save(x, s or f, pickle_module=pickle) + mb = os.path.getsize(s or f) / 1E6 # filesize + LOGGER.info(f"Optimizer stripped from {f},{f' saved as {s},' if s else ''} {mb:.1f}MB") + + +def profile(input, ops, n=10, device=None): + """ + Ultralytics speed, memory and FLOPs profiler. + + Example: + ```python + from ultralytics.utils.torch_utils import profile + + input = torch.randn(16, 3, 640, 640) + m1 = lambda x: x * torch.sigmoid(x) + m2 = nn.SiLU() + profile(input, [m1, m2], n=100) # profile over 100 iterations + ``` + """ + results = [] + if not isinstance(device, torch.device): + device = select_device(device) + LOGGER.info(f"{'Params':>12s}{'GFLOPs':>12s}{'GPU_mem (GB)':>14s}{'forward (ms)':>14s}{'backward (ms)':>14s}" + f"{'input':>24s}{'output':>24s}") + + for x in input if isinstance(input, list) else [input]: + x = x.to(device) + x.requires_grad = True + for m in ops if isinstance(ops, list) else [ops]: + m = m.to(device) if hasattr(m, 'to') else m # device + m = m.half() if hasattr(m, 'half') and isinstance(x, torch.Tensor) and x.dtype is torch.float16 else m + tf, tb, t = 0, 0, [0, 0, 0] # dt forward, backward + try: + flops = thop.profile(m, inputs=[x], verbose=False)[0] / 1E9 * 2 if thop else 0 # GFLOPs + except Exception: + flops = 0 + + try: + for _ in range(n): + t[0] = time_sync() + y = m(x) + t[1] = time_sync() + try: + (sum(yi.sum() for yi in y) if isinstance(y, list) else y).sum().backward() + t[2] = time_sync() + except Exception: # no backward method + # print(e) # for debug + t[2] = float('nan') + tf += (t[1] - t[0]) * 1000 / n # ms per op forward + tb += (t[2] - t[1]) * 1000 / n # ms per op backward + mem = torch.cuda.memory_reserved() / 1E9 if torch.cuda.is_available() else 0 # (GB) + s_in, s_out = (tuple(x.shape) if isinstance(x, torch.Tensor) else 'list' for x in (x, y)) # shapes + p = sum(x.numel() for x in m.parameters()) if isinstance(m, nn.Module) else 0 # parameters + LOGGER.info(f'{p:12}{flops:12.4g}{mem:>14.3f}{tf:14.4g}{tb:14.4g}{str(s_in):>24s}{str(s_out):>24s}') + results.append([p, flops, mem, tf, tb, s_in, s_out]) + except Exception as e: + LOGGER.info(e) + results.append(None) + torch.cuda.empty_cache() + return results + + +class EarlyStopping: + """ + Early stopping class that stops training when a specified number of epochs have passed without improvement. + """ + + def __init__(self, patience=50): + """ + Initialize early stopping object + + Args: + patience (int, optional): Number of epochs to wait after fitness stops improving before stopping. + """ + self.best_fitness = 0.0 # i.e. mAP + self.best_epoch = 0 + self.patience = patience or float('inf') # epochs to wait after fitness stops improving to stop + self.possible_stop = False # possible stop may occur next epoch + + def __call__(self, epoch, fitness): + """ + Check whether to stop training + + Args: + epoch (int): Current epoch of training + fitness (float): Fitness value of current epoch + + Returns: + (bool): True if training should stop, False otherwise + """ + if fitness is None: # check if fitness=None (happens when val=False) + return False + + if fitness >= self.best_fitness: # >= 0 to allow for early zero-fitness stage of training + self.best_epoch = epoch + self.best_fitness = fitness + delta = epoch - self.best_epoch # epochs without improvement + self.possible_stop = delta >= (self.patience - 1) # possible stop may occur next epoch + stop = delta >= self.patience # stop training if patience exceeded + if stop: + LOGGER.info(f'Stopping training early as no improvement observed in last {self.patience} epochs. ' + f'Best results observed at epoch {self.best_epoch}, best model saved as best.pt.\n' + f'To update EarlyStopping(patience={self.patience}) pass a new patience value, ' + f'i.e. `patience=300` or use `patience=0` to disable EarlyStopping.') + return stop diff --git a/downloads/ultralytics-main/ultralytics/utils/tuner.py b/downloads/ultralytics-main/ultralytics/utils/tuner.py new file mode 100644 index 000000000..b8672de28 --- /dev/null +++ b/downloads/ultralytics-main/ultralytics/utils/tuner.py @@ -0,0 +1,121 @@ +# Ultralytics YOLO 🚀, AGPL-3.0 license + +from ultralytics.cfg import TASK2DATA, TASK2METRIC +from ultralytics.utils import DEFAULT_CFG_DICT, LOGGER, NUM_THREADS + + +def run_ray_tune(model, + space: dict = None, + grace_period: int = 10, + gpu_per_trial: int = None, + max_samples: int = 10, + **train_args): + """ + Runs hyperparameter tuning using Ray Tune. + + Args: + model (YOLO): Model to run the tuner on. + space (dict, optional): The hyperparameter search space. Defaults to None. + grace_period (int, optional): The grace period in epochs of the ASHA scheduler. Defaults to 10. + gpu_per_trial (int, optional): The number of GPUs to allocate per trial. Defaults to None. + max_samples (int, optional): The maximum number of trials to run. Defaults to 10. + train_args (dict, optional): Additional arguments to pass to the `train()` method. Defaults to {}. + + Returns: + (dict): A dictionary containing the results of the hyperparameter search. + + Raises: + ModuleNotFoundError: If Ray Tune is not installed. + """ + if train_args is None: + train_args = {} + + try: + from ray import tune + from ray.air import RunConfig + from ray.air.integrations.wandb import WandbLoggerCallback + from ray.tune.schedulers import ASHAScheduler + except ImportError: + raise ModuleNotFoundError('Tuning hyperparameters requires Ray Tune. Install with: pip install "ray[tune]"') + + try: + import wandb + + assert hasattr(wandb, '__version__') + except (ImportError, AssertionError): + wandb = False + + default_space = { + # 'optimizer': tune.choice(['SGD', 'Adam', 'AdamW', 'NAdam', 'RAdam', 'RMSProp']), + 'lr0': tune.uniform(1e-5, 1e-1), + 'lrf': tune.uniform(0.01, 1.0), # final OneCycleLR learning rate (lr0 * lrf) + 'momentum': tune.uniform(0.6, 0.98), # SGD momentum/Adam beta1 + 'weight_decay': tune.uniform(0.0, 0.001), # optimizer weight decay 5e-4 + 'warmup_epochs': tune.uniform(0.0, 5.0), # warmup epochs (fractions ok) + 'warmup_momentum': tune.uniform(0.0, 0.95), # warmup initial momentum + 'box': tune.uniform(0.02, 0.2), # box loss gain + 'cls': tune.uniform(0.2, 4.0), # cls loss gain (scale with pixels) + 'hsv_h': tune.uniform(0.0, 0.1), # image HSV-Hue augmentation (fraction) + 'hsv_s': tune.uniform(0.0, 0.9), # image HSV-Saturation augmentation (fraction) + 'hsv_v': tune.uniform(0.0, 0.9), # image HSV-Value augmentation (fraction) + 'degrees': tune.uniform(0.0, 45.0), # image rotation (+/- deg) + 'translate': tune.uniform(0.0, 0.9), # image translation (+/- fraction) + 'scale': tune.uniform(0.0, 0.9), # image scale (+/- gain) + 'shear': tune.uniform(0.0, 10.0), # image shear (+/- deg) + 'perspective': tune.uniform(0.0, 0.001), # image perspective (+/- fraction), range 0-0.001 + 'flipud': tune.uniform(0.0, 1.0), # image flip up-down (probability) + 'fliplr': tune.uniform(0.0, 1.0), # image flip left-right (probability) + 'mosaic': tune.uniform(0.0, 1.0), # image mixup (probability) + 'mixup': tune.uniform(0.0, 1.0), # image mixup (probability) + 'copy_paste': tune.uniform(0.0, 1.0)} # segment copy-paste (probability) + + def _tune(config): + """ + Trains the YOLO model with the specified hyperparameters and additional arguments. + + Args: + config (dict): A dictionary of hyperparameters to use for training. + + Returns: + None. + """ + model._reset_callbacks() + config.update(train_args) + model.train(**config) + + # Get search space + if not space: + space = default_space + LOGGER.warning('WARNING ⚠️ search space not provided, using default search space.') + + # Get dataset + data = train_args.get('data', TASK2DATA[model.task]) + space['data'] = data + if 'data' not in train_args: + LOGGER.warning(f'WARNING ⚠️ data not provided, using default "data={data}".') + + # Define the trainable function with allocated resources + trainable_with_resources = tune.with_resources(_tune, {'cpu': NUM_THREADS, 'gpu': gpu_per_trial or 0}) + + # Define the ASHA scheduler for hyperparameter search + asha_scheduler = ASHAScheduler(time_attr='epoch', + metric=TASK2METRIC[model.task], + mode='max', + max_t=train_args.get('epochs') or DEFAULT_CFG_DICT['epochs'] or 100, + grace_period=grace_period, + reduction_factor=3) + + # Define the callbacks for the hyperparameter search + tuner_callbacks = [WandbLoggerCallback(project='YOLOv8-tune')] if wandb else [] + + # Create the Ray Tune hyperparameter search tuner + tuner = tune.Tuner(trainable_with_resources, + param_space=space, + tune_config=tune.TuneConfig(scheduler=asha_scheduler, num_samples=max_samples), + run_config=RunConfig(callbacks=tuner_callbacks, storage_path='./runs/tune')) + + # Run the hyperparameter search + tuner.fit() + + # Return the results of the hyperparameter search + return tuner.get_results() diff --git a/downloads/ultralytics-main/ultralytics/yolo/cfg/__init__.py b/downloads/ultralytics-main/ultralytics/yolo/cfg/__init__.py index eed2cb440..5ea5519b6 100644 --- a/downloads/ultralytics-main/ultralytics/yolo/cfg/__init__.py +++ b/downloads/ultralytics-main/ultralytics/yolo/cfg/__init__.py @@ -1,408 +1,10 @@ -# Ultralytics YOLO 🚀, AGPL-3.0 license -import contextlib -import re -import shutil +import importlib import sys -from difflib import get_close_matches -from pathlib import Path -from types import SimpleNamespace -from typing import Dict, List, Union -from ultralytics.yolo.utils import (DEFAULT_CFG, DEFAULT_CFG_DICT, DEFAULT_CFG_PATH, LOGGER, ROOT, USER_CONFIG_DIR, - IterableSimpleNamespace, __version__, checks, colorstr, deprecation_warn, - get_settings, yaml_load, yaml_print) +from ultralytics.utils import LOGGER -# Define valid tasks and modes -MODES = 'train', 'val', 'predict', 'export', 'track', 'benchmark' -TASKS = 'detect', 'segment', 'classify', 'pose' -TASK2DATA = { - 'detect': 'coco128.yaml', - 'segment': 'coco128-seg.yaml', - 'classify': 'imagenet100', - 'pose': 'coco8-pose.yaml'} -TASK2MODEL = { - 'detect': 'yolov8n.pt', - 'segment': 'yolov8n-seg.pt', - 'classify': 'yolov8n-cls.pt', - 'pose': 'yolov8n-pose.pt'} +# Set modules in sys.modules under their old name +sys.modules['ultralytics.yolo.cfg'] = importlib.import_module('ultralytics.cfg') -CLI_HELP_MSG = \ - f""" - Arguments received: {str(['yolo'] + sys.argv[1:])}. Ultralytics 'yolo' commands use the following syntax: - - yolo TASK MODE ARGS - - Where TASK (optional) is one of {TASKS} - MODE (required) is one of {MODES} - ARGS (optional) are any number of custom 'arg=value' pairs like 'imgsz=320' that override defaults. - See all ARGS at https://docs.ultralytics.com/usage/cfg or with 'yolo cfg' - - 1. Train a detection model for 10 epochs with an initial learning_rate of 0.01 - yolo train data=coco128.yaml model=yolov8n.pt epochs=10 lr0=0.01 - - 2. Predict a YouTube video using a pretrained segmentation model at image size 320: - yolo predict model=yolov8n-seg.pt source='https://youtu.be/Zgi9g1ksQHc' imgsz=320 - - 3. Val a pretrained detection model at batch-size 1 and image size 640: - yolo val model=yolov8n.pt data=coco128.yaml batch=1 imgsz=640 - - 4. Export a YOLOv8n classification model to ONNX format at image size 224 by 128 (no TASK required) - yolo export model=yolov8n-cls.pt format=onnx imgsz=224,128 - - 5. Run special commands: - yolo help - yolo checks - yolo version - yolo settings - yolo copy-cfg - yolo cfg - - Docs: https://docs.ultralytics.com - Community: https://community.ultralytics.com - GitHub: https://github.com/ultralytics/ultralytics - """ - -# Define keys for arg type checks -CFG_FLOAT_KEYS = 'warmup_epochs', 'box', 'cls', 'dfl', 'degrees', 'shear' -CFG_FRACTION_KEYS = ('dropout', 'iou', 'lr0', 'lrf', 'momentum', 'weight_decay', 'warmup_momentum', 'warmup_bias_lr', - 'label_smoothing', 'hsv_h', 'hsv_s', 'hsv_v', 'translate', 'scale', 'perspective', 'flipud', - 'fliplr', 'mosaic', 'mixup', 'copy_paste', 'conf', 'iou') # fractional floats limited to 0.0 - 1.0 -CFG_INT_KEYS = ('epochs', 'patience', 'batch', 'workers', 'seed', 'close_mosaic', 'mask_ratio', 'max_det', 'vid_stride', - 'line_width', 'workspace', 'nbs', 'save_period') -CFG_BOOL_KEYS = ('save', 'exist_ok', 'verbose', 'deterministic', 'single_cls', 'rect', 'cos_lr', 'overlap_mask', 'val', - 'save_json', 'save_hybrid', 'half', 'dnn', 'plots', 'show', 'save_txt', 'save_conf', 'save_crop', - 'show_labels', 'show_conf', 'visualize', 'augment', 'agnostic_nms', 'retina_masks', 'boxes', 'keras', - 'optimize', 'int8', 'dynamic', 'simplify', 'nms', 'v5loader') - - -def cfg2dict(cfg): - """ - Convert a configuration object to a dictionary, whether it is a file path, a string, or a SimpleNamespace object. - - Inputs: - cfg (str) or (Path) or (SimpleNamespace): Configuration object to be converted to a dictionary. - - Returns: - cfg (dict): Configuration object in dictionary format. - """ - if isinstance(cfg, (str, Path)): - cfg = yaml_load(cfg) # load dict - elif isinstance(cfg, SimpleNamespace): - cfg = vars(cfg) # convert to dict - return cfg - - -def get_cfg(cfg: Union[str, Path, Dict, SimpleNamespace] = DEFAULT_CFG_DICT, overrides: Dict = None): - """ - Load and merge configuration data from a file or dictionary. - - Args: - cfg (str) or (Path) or (Dict) or (SimpleNamespace): Configuration data. - overrides (str) or (Dict), optional: Overrides in the form of a file name or a dictionary. Default is None. - - Returns: - (SimpleNamespace): Training arguments namespace. - """ - cfg = cfg2dict(cfg) - - # Merge overrides - if overrides: - overrides = cfg2dict(overrides) - check_cfg_mismatch(cfg, overrides) - cfg = {**cfg, **overrides} # merge cfg and overrides dicts (prefer overrides) - - # Special handling for numeric project/names - for k in 'project', 'name': - if k in cfg and isinstance(cfg[k], (int, float)): - cfg[k] = str(cfg[k]) - - # Type and Value checks - for k, v in cfg.items(): - if v is not None: # None values may be from optional args - if k in CFG_FLOAT_KEYS and not isinstance(v, (int, float)): - raise TypeError(f"'{k}={v}' is of invalid type {type(v).__name__}. " - f"Valid '{k}' types are int (i.e. '{k}=0') or float (i.e. '{k}=0.5')") - elif k in CFG_FRACTION_KEYS: - if not isinstance(v, (int, float)): - raise TypeError(f"'{k}={v}' is of invalid type {type(v).__name__}. " - f"Valid '{k}' types are int (i.e. '{k}=0') or float (i.e. '{k}=0.5')") - if not (0.0 <= v <= 1.0): - raise ValueError(f"'{k}={v}' is an invalid value. " - f"Valid '{k}' values are between 0.0 and 1.0.") - elif k in CFG_INT_KEYS and not isinstance(v, int): - raise TypeError(f"'{k}={v}' is of invalid type {type(v).__name__}. " - f"'{k}' must be an int (i.e. '{k}=8')") - elif k in CFG_BOOL_KEYS and not isinstance(v, bool): - raise TypeError(f"'{k}={v}' is of invalid type {type(v).__name__}. " - f"'{k}' must be a bool (i.e. '{k}=True' or '{k}=False')") - - # Return instance - return IterableSimpleNamespace(**cfg) - - -def _handle_deprecation(custom): - """ - Hardcoded function to handle deprecated config keys - """ - - for key in custom.copy().keys(): - if key == 'hide_labels': - deprecation_warn(key, 'show_labels') - custom['show_labels'] = custom.pop('hide_labels') == 'False' - if key == 'hide_conf': - deprecation_warn(key, 'show_conf') - custom['show_conf'] = custom.pop('hide_conf') == 'False' - if key == 'line_thickness': - deprecation_warn(key, 'line_width') - custom['line_width'] = custom.pop('line_thickness') - - return custom - - -def check_cfg_mismatch(base: Dict, custom: Dict, e=None): - """ - This function checks for any mismatched keys between a custom configuration list and a base configuration list. - If any mismatched keys are found, the function prints out similar keys from the base list and exits the program. - - Inputs: - - custom (Dict): a dictionary of custom configuration options - - base (Dict): a dictionary of base configuration options - """ - custom = _handle_deprecation(custom) - base, custom = (set(x.keys()) for x in (base, custom)) - mismatched = [x for x in custom if x not in base] - if mismatched: - string = '' - for x in mismatched: - matches = get_close_matches(x, base) # key list - matches = [f'{k}={DEFAULT_CFG_DICT[k]}' if DEFAULT_CFG_DICT.get(k) is not None else k for k in matches] - match_str = f'Similar arguments are i.e. {matches}.' if matches else '' - string += f"'{colorstr('red', 'bold', x)}' is not a valid YOLO argument. {match_str}\n" - raise SyntaxError(string + CLI_HELP_MSG) from e - - -def merge_equals_args(args: List[str]) -> List[str]: - """ - Merges arguments around isolated '=' args in a list of strings. - The function considers cases where the first argument ends with '=' or the second starts with '=', - as well as when the middle one is an equals sign. - - Args: - args (List[str]): A list of strings where each element is an argument. - - Returns: - List[str]: A list of strings where the arguments around isolated '=' are merged. - """ - new_args = [] - for i, arg in enumerate(args): - if arg == '=' and 0 < i < len(args) - 1: # merge ['arg', '=', 'val'] - new_args[-1] += f'={args[i + 1]}' - del args[i + 1] - elif arg.endswith('=') and i < len(args) - 1 and '=' not in args[i + 1]: # merge ['arg=', 'val'] - new_args.append(f'{arg}{args[i + 1]}') - del args[i + 1] - elif arg.startswith('=') and i > 0: # merge ['arg', '=val'] - new_args[-1] += arg - else: - new_args.append(arg) - return new_args - - -def handle_yolo_hub(args: List[str]) -> None: - """ - Handle Ultralytics HUB command-line interface (CLI) commands. - - This function processes Ultralytics HUB CLI commands such as login and logout. - It should be called when executing a script with arguments related to HUB authentication. - - Args: - args (List[str]): A list of command line arguments - - Example: - python my_script.py hub login your_api_key - """ - from ultralytics import hub - - if args[0] == 'login': - key = args[1] if len(args) > 1 else '' - # Log in to Ultralytics HUB using the provided API key - hub.login(key) - elif args[0] == 'logout': - # Log out from Ultralytics HUB - hub.logout() - - -def handle_yolo_settings(args: List[str]) -> None: - """ - Handle YOLO settings command-line interface (CLI) commands. - - This function processes YOLO settings CLI commands such as reset. - It should be called when executing a script with arguments related to YOLO settings management. - - Args: - args (List[str]): A list of command line arguments for YOLO settings management. - - Example: - python my_script.py yolo settings reset - """ - path = USER_CONFIG_DIR / 'settings.yaml' # get SETTINGS YAML file path - if any(args) and args[0] == 'reset': - path.unlink() # delete the settings file - get_settings() # create new settings - LOGGER.info('Settings reset successfully') # inform the user that settings have been reset - yaml_print(path) # print the current settings - - -def entrypoint(debug=''): - """ - This function is the ultralytics package entrypoint, it's responsible for parsing the command line arguments passed - to the package. - - This function allows for: - - passing mandatory YOLO args as a list of strings - - specifying the task to be performed, either 'detect', 'segment' or 'classify' - - specifying the mode, either 'train', 'val', 'test', or 'predict' - - running special modes like 'checks' - - passing overrides to the package's configuration - - It uses the package's default cfg and initializes it using the passed overrides. - Then it calls the CLI function with the composed cfg - """ - args = (debug.split(' ') if debug else sys.argv)[1:] - if not args: # no arguments passed - LOGGER.info(CLI_HELP_MSG) - return - - special = { - 'help': lambda: LOGGER.info(CLI_HELP_MSG), - 'checks': checks.check_yolo, - 'version': lambda: LOGGER.info(__version__), - 'settings': lambda: handle_yolo_settings(args[1:]), - 'cfg': lambda: yaml_print(DEFAULT_CFG_PATH), - 'hub': lambda: handle_yolo_hub(args[1:]), - 'login': lambda: handle_yolo_hub(args), - 'copy-cfg': copy_default_cfg} - full_args_dict = {**DEFAULT_CFG_DICT, **{k: None for k in TASKS}, **{k: None for k in MODES}, **special} - - # Define common mis-uses of special commands, i.e. -h, -help, --help - special.update({k[0]: v for k, v in special.items()}) # singular - special.update({k[:-1]: v for k, v in special.items() if len(k) > 1 and k.endswith('s')}) # singular - special = {**special, **{f'-{k}': v for k, v in special.items()}, **{f'--{k}': v for k, v in special.items()}} - - overrides = {} # basic overrides, i.e. imgsz=320 - for a in merge_equals_args(args): # merge spaces around '=' sign - if a.startswith('--'): - LOGGER.warning(f"WARNING ⚠️ '{a}' does not require leading dashes '--', updating to '{a[2:]}'.") - a = a[2:] - if a.endswith(','): - LOGGER.warning(f"WARNING ⚠️ '{a}' does not require trailing comma ',', updating to '{a[:-1]}'.") - a = a[:-1] - if '=' in a: - try: - re.sub(r' *= *', '=', a) # remove spaces around equals sign - k, v = a.split('=', 1) # split on first '=' sign - assert v, f"missing '{k}' value" - if k == 'cfg': # custom.yaml passed - LOGGER.info(f'Overriding {DEFAULT_CFG_PATH} with {v}') - overrides = {k: val for k, val in yaml_load(checks.check_yaml(v)).items() if k != 'cfg'} - else: - if v.lower() == 'none': - v = None - elif v.lower() == 'true': - v = True - elif v.lower() == 'false': - v = False - else: - with contextlib.suppress(Exception): - v = eval(v) - overrides[k] = v - except (NameError, SyntaxError, ValueError, AssertionError) as e: - check_cfg_mismatch(full_args_dict, {a: ''}, e) - - elif a in TASKS: - overrides['task'] = a - elif a in MODES: - overrides['mode'] = a - elif a.lower() in special: - special[a.lower()]() - return - elif a in DEFAULT_CFG_DICT and isinstance(DEFAULT_CFG_DICT[a], bool): - overrides[a] = True # auto-True for default bool args, i.e. 'yolo show' sets show=True - elif a in DEFAULT_CFG_DICT: - raise SyntaxError(f"'{colorstr('red', 'bold', a)}' is a valid YOLO argument but is missing an '=' sign " - f"to set its value, i.e. try '{a}={DEFAULT_CFG_DICT[a]}'\n{CLI_HELP_MSG}") - else: - check_cfg_mismatch(full_args_dict, {a: ''}) - - # Check keys - check_cfg_mismatch(full_args_dict, overrides) - - # Mode - mode = overrides.get('mode', None) - if mode is None: - mode = DEFAULT_CFG.mode or 'predict' - LOGGER.warning(f"WARNING ⚠️ 'mode' is missing. Valid modes are {MODES}. Using default 'mode={mode}'.") - elif mode not in MODES: - if mode not in ('checks', checks): - raise ValueError(f"Invalid 'mode={mode}'. Valid modes are {MODES}.\n{CLI_HELP_MSG}") - LOGGER.warning("WARNING ⚠️ 'yolo mode=checks' is deprecated. Use 'yolo checks' instead.") - checks.check_yolo() - return - - # Task - task = overrides.pop('task', None) - if task: - if task not in TASKS: - raise ValueError(f"Invalid 'task={task}'. Valid tasks are {TASKS}.\n{CLI_HELP_MSG}") - if 'model' not in overrides: - overrides['model'] = TASK2MODEL[task] - - # Model - model = overrides.pop('model', DEFAULT_CFG.model) - if model is None: - model = 'yolov8n.pt' - LOGGER.warning(f"WARNING ⚠️ 'model' is missing. Using default 'model={model}'.") - from ultralytics.yolo.engine.model import YOLO - overrides['model'] = model - model = YOLO(model, task=task) - if isinstance(overrides.get('pretrained'), str): - model.load(overrides['pretrained']) - - # Task Update - if task != model.task: - if task: - LOGGER.warning(f"WARNING ⚠️ conflicting 'task={task}' passed with 'task={model.task}' model. " - f"Ignoring 'task={task}' and updating to 'task={model.task}' to match model.") - task = model.task - - # Mode - if mode in ('predict', 'track') and 'source' not in overrides: - overrides['source'] = DEFAULT_CFG.source or ROOT / 'assets' if (ROOT / 'assets').exists() \ - else 'https://ultralytics.com/images/bus.jpg' - LOGGER.warning(f"WARNING ⚠️ 'source' is missing. Using default 'source={overrides['source']}'.") - elif mode in ('train', 'val'): - if 'data' not in overrides: - overrides['data'] = TASK2DATA.get(task or DEFAULT_CFG.task, DEFAULT_CFG.data) - LOGGER.warning(f"WARNING ⚠️ 'data' is missing. Using default 'data={overrides['data']}'.") - elif mode == 'export': - if 'format' not in overrides: - overrides['format'] = DEFAULT_CFG.format or 'torchscript' - LOGGER.warning(f"WARNING ⚠️ 'format' is missing. Using default 'format={overrides['format']}'.") - - # Run command in python - # getattr(model, mode)(**vars(get_cfg(overrides=overrides))) # default args using default.yaml - getattr(model, mode)(**overrides) # default args from model - - -# Special modes -------------------------------------------------------------------------------------------------------- -def copy_default_cfg(): - """Copy and create a new default configuration file with '_copy' appended to its name.""" - new_file = Path.cwd() / DEFAULT_CFG_PATH.name.replace('.yaml', '_copy.yaml') - shutil.copy2(DEFAULT_CFG_PATH, new_file) - LOGGER.info(f'{DEFAULT_CFG_PATH} copied to {new_file}\n' - f"Example YOLO command with this new custom cfg:\n yolo cfg='{new_file}' imgsz=320 batch=8") - - -if __name__ == '__main__': - # Example Usage: entrypoint(debug='yolo predict model=yolov8n.pt') - entrypoint(debug='') +LOGGER.warning("WARNING ⚠️ 'ultralytics.yolo.cfg' is deprecated since '8.0.136' and will be removed in '8.1.0'. " + "Please use 'ultralytics.cfg' instead.") diff --git a/downloads/ultralytics-main/ultralytics/yolo/data/__init__.py b/downloads/ultralytics-main/ultralytics/yolo/data/__init__.py index f1d9deeed..f68391ef0 100644 --- a/downloads/ultralytics-main/ultralytics/yolo/data/__init__.py +++ b/downloads/ultralytics-main/ultralytics/yolo/data/__init__.py @@ -1,9 +1,17 @@ -# Ultralytics YOLO 🚀, AGPL-3.0 license +import importlib +import sys -from .base import BaseDataset -from .build import build_dataloader, build_yolo_dataset, load_inference_source -from .dataset import ClassificationDataset, SemanticDataset, YOLODataset -from .dataset_wrappers import MixAndRectDataset +from ultralytics.utils import LOGGER -__all__ = ('BaseDataset', 'ClassificationDataset', 'MixAndRectDataset', 'SemanticDataset', 'YOLODataset', - 'build_yolo_dataset', 'build_dataloader', 'load_inference_source') +# Set modules in sys.modules under their old name +sys.modules['ultralytics.yolo.data'] = importlib.import_module('ultralytics.data') +# This is for updating old cls models, or the way in following warning won't work. +sys.modules['ultralytics.yolo.data.augment'] = importlib.import_module('ultralytics.data.augment') + +DATA_WARNING = """WARNING ⚠️ 'ultralytics.yolo.data' is deprecated since '8.0.136' and will be removed in '8.1.0'. Please use 'ultralytics.data' instead. +Note this warning may be related to loading older models. You can update your model to current structure with: + import torch + ckpt = torch.load("model.pt") # applies to both official and custom models + torch.save(ckpt, "updated-model.pt") +""" +LOGGER.warning(DATA_WARNING) diff --git a/downloads/ultralytics-main/ultralytics/yolo/engine/__init__.py b/downloads/ultralytics-main/ultralytics/yolo/engine/__init__.py index e69de29bb..794efcd0c 100644 --- a/downloads/ultralytics-main/ultralytics/yolo/engine/__init__.py +++ b/downloads/ultralytics-main/ultralytics/yolo/engine/__init__.py @@ -0,0 +1,10 @@ +import importlib +import sys + +from ultralytics.utils import LOGGER + +# Set modules in sys.modules under their old name +sys.modules['ultralytics.yolo.engine'] = importlib.import_module('ultralytics.engine') + +LOGGER.warning("WARNING ⚠️ 'ultralytics.yolo.engine' is deprecated since '8.0.136' and will be removed in '8.1.0'. " + "Please use 'ultralytics.engine' instead.") diff --git a/downloads/ultralytics-main/ultralytics/yolo/utils/__init__.py b/downloads/ultralytics-main/ultralytics/yolo/utils/__init__.py index 96010aa0b..71557b0a7 100644 --- a/downloads/ultralytics-main/ultralytics/yolo/utils/__init__.py +++ b/downloads/ultralytics-main/ultralytics/yolo/utils/__init__.py @@ -1,778 +1,15 @@ -# Ultralytics YOLO 🚀, AGPL-3.0 license - -import contextlib -import inspect -import logging.config -import os -import platform -import re -import subprocess +import importlib import sys -import threading -import urllib -import uuid -from pathlib import Path -from types import SimpleNamespace -from typing import Union -import cv2 -import matplotlib.pyplot as plt -import numpy as np -import torch -import yaml +from ultralytics.utils import LOGGER -from ultralytics import __version__ +# Set modules in sys.modules under their old name +sys.modules['ultralytics.yolo.utils'] = importlib.import_module('ultralytics.utils') -# PyTorch Multi-GPU DDP Constants -RANK = int(os.getenv('RANK', -1)) -LOCAL_RANK = int(os.getenv('LOCAL_RANK', -1)) # https://pytorch.org/docs/stable/elastic/run.html -WORLD_SIZE = int(os.getenv('WORLD_SIZE', 1)) - -# Other Constants -FILE = Path(__file__).resolve() -ROOT = FILE.parents[2] # YOLO -DEFAULT_CFG_PATH = ROOT / 'yolo/cfg/default.yaml' -NUM_THREADS = min(8, max(1, os.cpu_count() - 1)) # number of YOLOv5 multiprocessing threads -AUTOINSTALL = str(os.getenv('YOLO_AUTOINSTALL', True)).lower() == 'true' # global auto-install mode -VERBOSE = str(os.getenv('YOLO_VERBOSE', True)).lower() == 'true' # global verbose mode -TQDM_BAR_FORMAT = '{l_bar}{bar:10}{r_bar}' # tqdm bar format -LOGGING_NAME = 'ultralytics' -MACOS, LINUX, WINDOWS = (platform.system() == x for x in ['Darwin', 'Linux', 'Windows']) # environment booleans -HELP_MSG = \ - """ - Usage examples for running YOLOv8: - - 1. Install the ultralytics package: - - pip install ultralytics - - 2. Use the Python SDK: - - from ultralytics import YOLO - - # Load a model - model = YOLO('yolov8n.yaml') # build a new model from scratch - model = YOLO("yolov8n.pt") # load a pretrained model (recommended for training) - - # Use the model - results = model.train(data="coco128.yaml", epochs=3) # train the model - results = model.val() # evaluate model performance on the validation set - results = model('https://ultralytics.com/images/bus.jpg') # predict on an image - success = model.export(format='onnx') # export the model to ONNX format - - 3. Use the command line interface (CLI): - - YOLOv8 'yolo' CLI commands use the following syntax: - - yolo TASK MODE ARGS - - Where TASK (optional) is one of [detect, segment, classify] - MODE (required) is one of [train, val, predict, export] - ARGS (optional) are any number of custom 'arg=value' pairs like 'imgsz=320' that override defaults. - See all ARGS at https://docs.ultralytics.com/usage/cfg or with 'yolo cfg' - - - Train a detection model for 10 epochs with an initial learning_rate of 0.01 - yolo detect train data=coco128.yaml model=yolov8n.pt epochs=10 lr0=0.01 - - - Predict a YouTube video using a pretrained segmentation model at image size 320: - yolo segment predict model=yolov8n-seg.pt source='https://youtu.be/Zgi9g1ksQHc' imgsz=320 - - - Val a pretrained detection model at batch-size 1 and image size 640: - yolo detect val model=yolov8n.pt data=coco128.yaml batch=1 imgsz=640 - - - Export a YOLOv8n classification model to ONNX format at image size 224 by 128 (no TASK required) - yolo export model=yolov8n-cls.pt format=onnx imgsz=224,128 - - - Run special commands: - yolo help - yolo checks - yolo version - yolo settings - yolo copy-cfg - yolo cfg - - Docs: https://docs.ultralytics.com - Community: https://community.ultralytics.com - GitHub: https://github.com/ultralytics/ultralytics - """ - -# Settings -torch.set_printoptions(linewidth=320, precision=4, profile='default') -np.set_printoptions(linewidth=320, formatter={'float_kind': '{:11.5g}'.format}) # format short g, %precision=5 -cv2.setNumThreads(0) # prevent OpenCV from multithreading (incompatible with PyTorch DataLoader) -os.environ['NUMEXPR_MAX_THREADS'] = str(NUM_THREADS) # NumExpr max threads -os.environ['CUBLAS_WORKSPACE_CONFIG'] = ':4096:8' # for deterministic training -os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' # suppress verbose TF compiler warnings in Colab - - -class SimpleClass: - """ - Ultralytics SimpleClass is a base class providing helpful string representation, error reporting, and attribute - access methods for easier debugging and usage. - """ - - def __str__(self): - """Return a human-readable string representation of the object.""" - attr = [] - for a in dir(self): - v = getattr(self, a) - if not callable(v) and not a.startswith('_'): - if isinstance(v, SimpleClass): - # Display only the module and class name for subclasses - s = f'{a}: {v.__module__}.{v.__class__.__name__} object' - else: - s = f'{a}: {repr(v)}' - attr.append(s) - return f'{self.__module__}.{self.__class__.__name__} object with attributes:\n\n' + '\n'.join(attr) - - def __repr__(self): - """Return a machine-readable string representation of the object.""" - return self.__str__() - - def __getattr__(self, attr): - """Custom attribute access error message with helpful information.""" - name = self.__class__.__name__ - raise AttributeError(f"'{name}' object has no attribute '{attr}'. See valid attributes below.\n{self.__doc__}") - - -class IterableSimpleNamespace(SimpleNamespace): - """ - Ultralytics IterableSimpleNamespace is an extension class of SimpleNamespace that adds iterable functionality and - enables usage with dict() and for loops. - """ - - def __iter__(self): - """Return an iterator of key-value pairs from the namespace's attributes.""" - return iter(vars(self).items()) - - def __str__(self): - """Return a human-readable string representation of the object.""" - return '\n'.join(f'{k}={v}' for k, v in vars(self).items()) - - def __getattr__(self, attr): - """Custom attribute access error message with helpful information.""" - name = self.__class__.__name__ - raise AttributeError(f""" - '{name}' object has no attribute '{attr}'. This may be caused by a modified or out of date ultralytics - 'default.yaml' file.\nPlease update your code with 'pip install -U ultralytics' and if necessary replace - {DEFAULT_CFG_PATH} with the latest version from - https://github.com/ultralytics/ultralytics/blob/main/ultralytics/yolo/cfg/default.yaml - """) - - def get(self, key, default=None): - """Return the value of the specified key if it exists; otherwise, return the default value.""" - return getattr(self, key, default) - - -def plt_settings(rcparams={'font.size': 11}, backend='Agg'): - """ - Decorator to temporarily set rc parameters and the backend for a plotting function. - - Usage: - decorator: @plt_settings({"font.size": 12}) - context manager: with plt_settings({"font.size": 12}): - - Args: - rcparams (dict): Dictionary of rc parameters to set. - backend (str, optional): Name of the backend to use. Defaults to 'Agg'. - - Returns: - callable: Decorated function with temporarily set rc parameters and backend. - """ - - def decorator(func): - """Decorator to apply temporary rc parameters and backend to a function.""" - - def wrapper(*args, **kwargs): - """Sets rc parameters and backend, calls the original function, and restores the settings.""" - original_backend = plt.get_backend() - plt.switch_backend(backend) - - with plt.rc_context(rcparams): - result = func(*args, **kwargs) - - plt.switch_backend(original_backend) - return result - - return wrapper - - return decorator - - -def set_logging(name=LOGGING_NAME, verbose=True): - """Sets up logging for the given name.""" - rank = int(os.getenv('RANK', -1)) # rank in world for Multi-GPU trainings - level = logging.INFO if verbose and rank in {-1, 0} else logging.ERROR - logging.config.dictConfig({ - 'version': 1, - 'disable_existing_loggers': False, - 'formatters': { - name: { - 'format': '%(message)s'}}, - 'handlers': { - name: { - 'class': 'logging.StreamHandler', - 'formatter': name, - 'level': level}}, - 'loggers': { - name: { - 'level': level, - 'handlers': [name], - 'propagate': False}}}) - - -class EmojiFilter(logging.Filter): - """ - A custom logging filter class for removing emojis in log messages. - - This filter is particularly useful for ensuring compatibility with Windows terminals - that may not support the display of emojis in log messages. - """ - - def filter(self, record): - """Filter logs by emoji unicode characters on windows.""" - record.msg = emojis(record.msg) - return super().filter(record) - - -# Set logger -set_logging(LOGGING_NAME, verbose=VERBOSE) # run before defining LOGGER -LOGGER = logging.getLogger(LOGGING_NAME) # define globally (used in train.py, val.py, detect.py, etc.) -if WINDOWS: # emoji-safe logging - LOGGER.addFilter(EmojiFilter()) - - -def yaml_save(file='data.yaml', data={}): - """ - Save YAML data to a file. - - Args: - file (str, optional): File name. Default is 'data.yaml'. - data (dict): Data to save in YAML format. - - Returns: - None: Data is saved to the specified file. - """ - file = Path(file) - if not file.parent.exists(): - # Create parent directories if they don't exist - file.parent.mkdir(parents=True, exist_ok=True) - - # Convert Path objects to strings - for k, v in data.items(): - if isinstance(v, Path): - data[k] = str(v) - - # Dump data to file in YAML format - with open(file, 'w') as f: - yaml.safe_dump(data, f, sort_keys=False, allow_unicode=True) - - -def yaml_load(file='data.yaml', append_filename=False): - """ - Load YAML data from a file. - - Args: - file (str, optional): File name. Default is 'data.yaml'. - append_filename (bool): Add the YAML filename to the YAML dictionary. Default is False. - - Returns: - dict: YAML data and file name. - """ - with open(file, errors='ignore', encoding='utf-8') as f: - s = f.read() # string - - # Remove special characters - if not s.isprintable(): - s = re.sub(r'[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\uD7FF\uE000-\uFFFD\U00010000-\U0010ffff]+', '', s) - - # Add YAML filename to dict and return - return {**yaml.safe_load(s), 'yaml_file': str(file)} if append_filename else yaml.safe_load(s) - - -def yaml_print(yaml_file: Union[str, Path, dict]) -> None: - """ - Pretty prints a yaml file or a yaml-formatted dictionary. - - Args: - yaml_file: The file path of the yaml file or a yaml-formatted dictionary. - - Returns: - None - """ - yaml_dict = yaml_load(yaml_file) if isinstance(yaml_file, (str, Path)) else yaml_file - dump = yaml.dump(yaml_dict, sort_keys=False, allow_unicode=True) - LOGGER.info(f"Printing '{colorstr('bold', 'black', yaml_file)}'\n\n{dump}") - - -# Default configuration -DEFAULT_CFG_DICT = yaml_load(DEFAULT_CFG_PATH) -for k, v in DEFAULT_CFG_DICT.items(): - if isinstance(v, str) and v.lower() == 'none': - DEFAULT_CFG_DICT[k] = None -DEFAULT_CFG_KEYS = DEFAULT_CFG_DICT.keys() -DEFAULT_CFG = IterableSimpleNamespace(**DEFAULT_CFG_DICT) - - -def is_colab(): - """ - Check if the current script is running inside a Google Colab notebook. - - Returns: - bool: True if running inside a Colab notebook, False otherwise. - """ - return 'COLAB_RELEASE_TAG' in os.environ or 'COLAB_BACKEND_VERSION' in os.environ - - -def is_kaggle(): - """ - Check if the current script is running inside a Kaggle kernel. - - Returns: - bool: True if running inside a Kaggle kernel, False otherwise. - """ - return os.environ.get('PWD') == '/kaggle/working' and os.environ.get('KAGGLE_URL_BASE') == 'https://www.kaggle.com' - - -def is_jupyter(): - """ - Check if the current script is running inside a Jupyter Notebook. - Verified on Colab, Jupyterlab, Kaggle, Paperspace. - - Returns: - bool: True if running inside a Jupyter Notebook, False otherwise. - """ - with contextlib.suppress(Exception): - from IPython import get_ipython - return get_ipython() is not None - return False - - -def is_docker() -> bool: - """ - Determine if the script is running inside a Docker container. - - Returns: - bool: True if the script is running inside a Docker container, False otherwise. - """ - file = Path('/proc/self/cgroup') - if file.exists(): - with open(file) as f: - return 'docker' in f.read() - else: - return False - - -def is_online() -> bool: - """ - Check internet connectivity by attempting to connect to a known online host. - - Returns: - bool: True if connection is successful, False otherwise. - """ - import socket - - for server in '1.1.1.1', '8.8.8.8', '223.5.5.5': # Cloudflare, Google, AliDNS: - try: - socket.create_connection((server, 53), timeout=2) # connect to (server, port=53) - return True - except (socket.timeout, socket.gaierror, OSError): - continue - return False - - -ONLINE = is_online() - - -def is_pip_package(filepath: str = __name__) -> bool: - """ - Determines if the file at the given filepath is part of a pip package. - - Args: - filepath (str): The filepath to check. - - Returns: - bool: True if the file is part of a pip package, False otherwise. - """ - import importlib.util - - # Get the spec for the module - spec = importlib.util.find_spec(filepath) - - # Return whether the spec is not None and the origin is not None (indicating it is a package) - return spec is not None and spec.origin is not None - - -def is_dir_writeable(dir_path: Union[str, Path]) -> bool: - """ - Check if a directory is writeable. - - Args: - dir_path (str) or (Path): The path to the directory. - - Returns: - bool: True if the directory is writeable, False otherwise. - """ - return os.access(str(dir_path), os.W_OK) - - -def is_pytest_running(): - """ - Determines whether pytest is currently running or not. - - Returns: - (bool): True if pytest is running, False otherwise. - """ - return ('PYTEST_CURRENT_TEST' in os.environ) or ('pytest' in sys.modules) or ('pytest' in Path(sys.argv[0]).stem) - - -def is_github_actions_ci() -> bool: - """ - Determine if the current environment is a GitHub Actions CI Python runner. - - Returns: - (bool): True if the current environment is a GitHub Actions CI Python runner, False otherwise. - """ - return 'GITHUB_ACTIONS' in os.environ and 'RUNNER_OS' in os.environ and 'RUNNER_TOOL_CACHE' in os.environ - - -def is_git_dir(): - """ - Determines whether the current file is part of a git repository. - If the current file is not part of a git repository, returns None. - - Returns: - (bool): True if current file is part of a git repository. - """ - return get_git_dir() is not None - - -def get_git_dir(): - """ - Determines whether the current file is part of a git repository and if so, returns the repository root directory. - If the current file is not part of a git repository, returns None. - - Returns: - (Path) or (None): Git root directory if found or None if not found. - """ - for d in Path(__file__).parents: - if (d / '.git').is_dir(): - return d - return None # no .git dir found - - -def get_git_origin_url(): - """ - Retrieves the origin URL of a git repository. - - Returns: - (str) or (None): The origin URL of the git repository. - """ - if is_git_dir(): - with contextlib.suppress(subprocess.CalledProcessError): - origin = subprocess.check_output(['git', 'config', '--get', 'remote.origin.url']) - return origin.decode().strip() - return None # if not git dir or on error - - -def get_git_branch(): - """ - Returns the current git branch name. If not in a git repository, returns None. - - Returns: - (str) or (None): The current git branch name. - """ - if is_git_dir(): - with contextlib.suppress(subprocess.CalledProcessError): - origin = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD']) - return origin.decode().strip() - return None # if not git dir or on error - - -def get_default_args(func): - """Returns a dictionary of default arguments for a function. - - Args: - func (callable): The function to inspect. - - Returns: - dict: A dictionary where each key is a parameter name, and each value is the default value of that parameter. - """ - signature = inspect.signature(func) - return {k: v.default for k, v in signature.parameters.items() if v.default is not inspect.Parameter.empty} - - -def get_user_config_dir(sub_dir='Ultralytics'): - """ - Get the user config directory. - - Args: - sub_dir (str): The name of the subdirectory to create. - - Returns: - Path: The path to the user config directory. - """ - # Return the appropriate config directory for each operating system - if WINDOWS: - path = Path.home() / 'AppData' / 'Roaming' / sub_dir - elif MACOS: # macOS - path = Path.home() / 'Library' / 'Application Support' / sub_dir - elif LINUX: - path = Path.home() / '.config' / sub_dir - else: - raise ValueError(f'Unsupported operating system: {platform.system()}') - - # GCP and AWS lambda fix, only /tmp is writeable - if not is_dir_writeable(str(path.parent)): - path = Path('/tmp') / sub_dir - - # Create the subdirectory if it does not exist - path.mkdir(parents=True, exist_ok=True) - - return path - - -USER_CONFIG_DIR = Path(os.getenv('YOLO_CONFIG_DIR', get_user_config_dir())) # Ultralytics settings dir -SETTINGS_YAML = USER_CONFIG_DIR / 'settings.yaml' - - -def emojis(string=''): - """Return platform-dependent emoji-safe version of string.""" - return string.encode().decode('ascii', 'ignore') if WINDOWS else string - - -def colorstr(*input): - """Colors a string https://en.wikipedia.org/wiki/ANSI_escape_code, i.e. colorstr('blue', 'hello world').""" - *args, string = input if len(input) > 1 else ('blue', 'bold', input[0]) # color arguments, string - colors = { - 'black': '\033[30m', # basic colors - 'red': '\033[31m', - 'green': '\033[32m', - 'yellow': '\033[33m', - 'blue': '\033[34m', - 'magenta': '\033[35m', - 'cyan': '\033[36m', - 'white': '\033[37m', - 'bright_black': '\033[90m', # bright colors - 'bright_red': '\033[91m', - 'bright_green': '\033[92m', - 'bright_yellow': '\033[93m', - 'bright_blue': '\033[94m', - 'bright_magenta': '\033[95m', - 'bright_cyan': '\033[96m', - 'bright_white': '\033[97m', - 'end': '\033[0m', # misc - 'bold': '\033[1m', - 'underline': '\033[4m'} - return ''.join(colors[x] for x in args) + f'{string}' + colors['end'] - - -class TryExcept(contextlib.ContextDecorator): - """YOLOv8 TryExcept class. Usage: @TryExcept() decorator or 'with TryExcept():' context manager.""" - - def __init__(self, msg='', verbose=True): - """Initialize TryExcept class with optional message and verbosity settings.""" - self.msg = msg - self.verbose = verbose - - def __enter__(self): - """Executes when entering TryExcept context, initializes instance.""" - pass - - def __exit__(self, exc_type, value, traceback): - """Defines behavior when exiting a 'with' block, prints error message if necessary.""" - if self.verbose and value: - print(emojis(f"{self.msg}{': ' if self.msg else ''}{value}")) - return True - - -def threaded(func): - """Multi-threads a target function and returns thread. Usage: @threaded decorator.""" - - def wrapper(*args, **kwargs): - """Multi-threads a given function and returns the thread.""" - thread = threading.Thread(target=func, args=args, kwargs=kwargs, daemon=True) - thread.start() - return thread - - return wrapper - - -def set_sentry(): - """ - Initialize the Sentry SDK for error tracking and reporting. Enabled when sync=True in settings and - disabled when sync=False. Run 'yolo settings' to see and update settings YAML file. - - Conditions required to send errors: - - sync=True in YOLO settings - - pytest is not running - - running in a pip package installation - - running in a non-git directory - - running with rank -1 or 0 - - online environment - - CLI used to run package (checked with 'yolo' as the name of the main CLI command) - - The function also configures Sentry SDK to ignore KeyboardInterrupt and FileNotFoundError - exceptions and to exclude events with 'out of memory' in their exception message. - - Additionally, the function sets custom tags and user information for Sentry events. - """ - - def before_send(event, hint): - """ - Modify the event before sending it to Sentry based on specific exception types and messages. - - Args: - event (dict): The event dictionary containing information about the error. - hint (dict): A dictionary containing additional information about the error. - - Returns: - dict: The modified event or None if the event should not be sent to Sentry. - """ - if 'exc_info' in hint: - exc_type, exc_value, tb = hint['exc_info'] - if exc_type in (KeyboardInterrupt, FileNotFoundError) \ - or 'out of memory' in str(exc_value): - return None # do not send event - - event['tags'] = { - 'sys_argv': sys.argv[0], - 'sys_argv_name': Path(sys.argv[0]).name, - 'install': 'git' if is_git_dir() else 'pip' if is_pip_package() else 'other', - 'os': ENVIRONMENT} - return event - - if SETTINGS['sync'] and \ - RANK in (-1, 0) and \ - Path(sys.argv[0]).name == 'yolo' and \ - not TESTS_RUNNING and \ - ONLINE and \ - is_pip_package() and \ - not is_git_dir(): - - import sentry_sdk # noqa - sentry_sdk.init( - dsn='https://5ff1556b71594bfea135ff0203a0d290@o4504521589325824.ingest.sentry.io/4504521592406016', - debug=False, - traces_sample_rate=1.0, - release=__version__, - environment='production', # 'dev' or 'production' - before_send=before_send, - ignore_errors=[KeyboardInterrupt, FileNotFoundError]) - sentry_sdk.set_user({'id': SETTINGS['uuid']}) # SHA-256 anonymized UUID hash - - # Disable all sentry logging - for logger in 'sentry_sdk', 'sentry_sdk.errors': - logging.getLogger(logger).setLevel(logging.CRITICAL) - - -def get_settings(file=SETTINGS_YAML, version='0.0.3'): - """ - Loads a global Ultralytics settings YAML file or creates one with default values if it does not exist. - - Args: - file (Path): Path to the Ultralytics settings YAML file. Defaults to 'settings.yaml' in the USER_CONFIG_DIR. - version (str): Settings version. If min settings version not met, new default settings will be saved. - - Returns: - dict: Dictionary of settings key-value pairs. - """ - import hashlib - - from ultralytics.yolo.utils.checks import check_version - from ultralytics.yolo.utils.torch_utils import torch_distributed_zero_first - - git_dir = get_git_dir() - root = git_dir or Path() - datasets_root = (root.parent if git_dir and is_dir_writeable(root.parent) else root).resolve() - defaults = { - 'datasets_dir': str(datasets_root / 'datasets'), # default datasets directory. - 'weights_dir': str(root / 'weights'), # default weights directory. - 'runs_dir': str(root / 'runs'), # default runs directory. - 'uuid': hashlib.sha256(str(uuid.getnode()).encode()).hexdigest(), # SHA-256 anonymized UUID hash - 'sync': True, # sync analytics to help with YOLO development - 'api_key': '', # Ultralytics HUB API key (https://hub.ultralytics.com/) - 'settings_version': version} # Ultralytics settings version - - with torch_distributed_zero_first(RANK): - if not file.exists(): - yaml_save(file, defaults) - settings = yaml_load(file) - - # Check that settings keys and types match defaults - correct = \ - settings \ - and settings.keys() == defaults.keys() \ - and all(type(a) == type(b) for a, b in zip(settings.values(), defaults.values())) \ - and check_version(settings['settings_version'], version) - if not correct: - LOGGER.warning('WARNING ⚠️ Ultralytics settings reset to defaults. This is normal and may be due to a ' - 'recent ultralytics package update, but may have overwritten previous settings. ' - f"\nView and update settings with 'yolo settings' or at '{file}'") - settings = defaults # merge **defaults with **settings (prefer **settings) - yaml_save(file, settings) # save updated defaults - - return settings - - -def set_settings(kwargs, file=SETTINGS_YAML): - """ - Function that runs on a first-time ultralytics package installation to set up global settings and create necessary - directories. - """ - SETTINGS.update(kwargs) - yaml_save(file, SETTINGS) - - -def deprecation_warn(arg, new_arg, version=None): - """Issue a deprecation warning when a deprecated argument is used, suggesting an updated argument.""" - if not version: - version = float(__version__[:3]) + 0.2 # deprecate after 2nd major release - LOGGER.warning(f"WARNING ⚠️ '{arg}' is deprecated and will be removed in 'ultralytics {version}' in the future. " - f"Please use '{new_arg}' instead.") - - -def clean_url(url): - """Strip auth from URL, i.e. https://url.com/file.txt?auth -> https://url.com/file.txt.""" - url = str(Path(url)).replace(':/', '://') # Pathlib turns :// -> :/ - return urllib.parse.unquote(url).split('?')[0] # '%2F' to '/', split https://url.com/file.txt?auth - - -def url2file(url): - """Convert URL to filename, i.e. https://url.com/file.txt?auth -> file.txt.""" - return Path(clean_url(url)).name - - -# Run below code on yolo/utils init ------------------------------------------------------------------------------------ - -# Check first-install steps -PREFIX = colorstr('Ultralytics: ') -SETTINGS = get_settings() -DATASETS_DIR = Path(SETTINGS['datasets_dir']) # global datasets directory -ENVIRONMENT = 'Colab' if is_colab() else 'Kaggle' if is_kaggle() else 'Jupyter' if is_jupyter() else \ - 'Docker' if is_docker() else platform.system() -TESTS_RUNNING = is_pytest_running() or is_github_actions_ci() -set_sentry() - -# OpenCV Multilanguage-friendly functions ------------------------------------------------------------------------------ -imshow_ = cv2.imshow # copy to avoid recursion errors - - -def imread(filename, flags=cv2.IMREAD_COLOR): - return cv2.imdecode(np.fromfile(filename, np.uint8), flags) - - -def imwrite(filename, img): - try: - cv2.imencode(Path(filename).suffix, img)[1].tofile(filename) - return True - except Exception: - return False - - -def imshow(path, im): - imshow_(path.encode('unicode_escape').decode(), im) - - -if Path(inspect.stack()[0].filename).parent.parent.as_posix() in inspect.stack()[-1].filename: - cv2.imread, cv2.imwrite, cv2.imshow = imread, imwrite, imshow # redefine +UTILS_WARNING = """WARNING ⚠️ 'ultralytics.yolo.utils' is deprecated since '8.0.136' and will be removed in '8.1.0'. Please use 'ultralytics.utils' instead. +Note this warning may be related to loading older models. You can update your model to current structure with: + import torch + ckpt = torch.load("model.pt") # applies to both official and custom models + torch.save(ckpt, "updated-model.pt") +""" +LOGGER.warning(UTILS_WARNING) diff --git a/downloads/ultralytics-main/ultralytics/yolo/v8/__init__.py b/downloads/ultralytics-main/ultralytics/yolo/v8/__init__.py index adc0351ba..51adf814c 100644 --- a/downloads/ultralytics-main/ultralytics/yolo/v8/__init__.py +++ b/downloads/ultralytics-main/ultralytics/yolo/v8/__init__.py @@ -1,5 +1,10 @@ -# Ultralytics YOLO 🚀, AGPL-3.0 license +import importlib +import sys -from ultralytics.yolo.v8 import classify, detect, pose, segment +from ultralytics.utils import LOGGER -__all__ = 'classify', 'segment', 'detect', 'pose' +# Set modules in sys.modules under their old name +sys.modules['ultralytics.yolo.v8'] = importlib.import_module('ultralytics.models.yolo') + +LOGGER.warning("WARNING ⚠️ 'ultralytics.yolo.v8' is deprecated since '8.0.136' and will be removed in '8.1.0'. " + "Please use 'ultralytics.models.yolo' instead.") diff --git a/downloads/yolov5-master/.github/ISSUE_TEMPLATE/config.yml b/downloads/yolov5-master/.github/ISSUE_TEMPLATE/config.yml index 743feb957..37080927c 100644 --- a/downloads/yolov5-master/.github/ISSUE_TEMPLATE/config.yml +++ b/downloads/yolov5-master/.github/ISSUE_TEMPLATE/config.yml @@ -7,5 +7,5 @@ contact_links: url: https://community.ultralytics.com/ about: Ask on Ultralytics Community Forum - name: 🎧 Discord - url: https://discord.gg/n6cFeSPZdD + url: https://ultralytics.com/discord about: Ask on Ultralytics Discord diff --git a/downloads/yolov5-master/.github/workflows/ci-testing.yml b/downloads/yolov5-master/.github/workflows/ci-testing.yml index e71a4b8f1..80ae42955 100644 --- a/downloads/yolov5-master/.github/workflows/ci-testing.yml +++ b/downloads/yolov5-master/.github/workflows/ci-testing.yml @@ -57,18 +57,15 @@ jobs: model: [ yolov5n ] include: - os: ubuntu-latest - python-version: '3.7' # '3.6.8' min - model: yolov5n - - os: ubuntu-latest - python-version: '3.8' + python-version: '3.8' # '3.6.8' min model: yolov5n - os: ubuntu-latest python-version: '3.9' model: yolov5n - os: ubuntu-latest - python-version: '3.8' # torch 1.7.0 requires python >=3.6, <=3.8 + python-version: '3.8' # torch 1.8.0 requires python >=3.6, <=3.8 model: yolov5n - torch: '1.7.0' # min torch version CI https://pypi.org/project/torchvision/ + torch: '1.8.0' # min torch version CI https://pypi.org/project/torchvision/ steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 @@ -78,8 +75,8 @@ jobs: - name: Install requirements run: | python -m pip install --upgrade pip wheel - if [ "${{ matrix.torch }}" == "1.7.0" ]; then - pip install -r requirements.txt torch==1.7.0 torchvision==0.8.1 --extra-index-url https://download.pytorch.org/whl/cpu + if [ "${{ matrix.torch }}" == "1.8.0" ]; then + pip install -r requirements.txt torch==1.8.0 torchvision==0.9.0 --extra-index-url https://download.pytorch.org/whl/cpu else pip install -r requirements.txt --extra-index-url https://download.pytorch.org/whl/cpu fi @@ -158,8 +155,8 @@ jobs: if: always() # This ensures the job runs even if previous jobs fail steps: - name: Check for failure and notify - if: (needs.Benchmarks.result == 'failure' || needs.Tests.result == 'failure') && github.repository == 'ultralytics/yolov5' && (github.event_name == 'schedule' || github.event_name == 'push') - uses: slackapi/slack-github-action@v1.23.0 + if: (needs.Benchmarks.result == 'failure' || needs.Tests.result == 'failure' || needs.Benchmarks.result == 'cancelled' || needs.Tests.result == 'cancelled') && github.repository == 'ultralytics/yolov5' && (github.event_name == 'schedule' || github.event_name == 'push') + uses: slackapi/slack-github-action@v1.24.0 with: payload: | {"text": " GitHub Actions error for ${{ github.workflow }} ❌\n\n\n*Repository:* https://github.com/${{ github.repository }}\n*Action:* https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\n*Author:* ${{ github.actor }}\n*Event:* ${{ github.event_name }}\n"} diff --git a/downloads/yolov5-master/.github/workflows/greetings.yml b/downloads/yolov5-master/.github/workflows/greetings.yml index 8aca12d3c..3058d78b0 100644 --- a/downloads/yolov5-master/.github/workflows/greetings.yml +++ b/downloads/yolov5-master/.github/workflows/greetings.yml @@ -31,7 +31,7 @@ jobs: ## Requirements - [**Python>=3.7.0**](https://www.python.org/) with all [requirements.txt](https://github.com/ultralytics/yolov5/blob/master/requirements.txt) installed including [**PyTorch>=1.7**](https://pytorch.org/get-started/locally/). To get started: + [**Python>=3.8.0**](https://www.python.org/) with all [requirements.txt](https://github.com/ultralytics/yolov5/blob/master/requirements.txt) installed including [**PyTorch>=1.8**](https://pytorch.org/get-started/locally/). To get started: ```bash git clone https://github.com/ultralytics/yolov5 # clone cd yolov5 diff --git a/downloads/yolov5-master/.github/workflows/links.yml b/downloads/yolov5-master/.github/workflows/links.yml index cd65b961f..98803c7e1 100644 --- a/downloads/yolov5-master/.github/workflows/links.yml +++ b/downloads/yolov5-master/.github/workflows/links.yml @@ -28,7 +28,7 @@ jobs: timeout_minutes: 5 retry_wait_seconds: 60 max_attempts: 3 - command: lychee --accept 429,999 --exclude-loopback --exclude 'https?://(www\.)?(twitter\.com|instagram\.com)' --exclude-path '**/ci.yaml' --exclude-mail --github-token ${{ secrets.GITHUB_TOKEN }} './**/*.md' './**/*.html' + command: lychee --accept 429,999 --exclude-loopback --exclude 'https?://(www\.)?(linkedin\.com|twitter\.com|instagram\.com)' --exclude-path '**/ci.yaml' --exclude-mail --github-token ${{ secrets.GITHUB_TOKEN }} './**/*.md' './**/*.html' - name: Test Markdown, HTML, YAML, Python and Notebook links with retry if: github.event_name == 'workflow_dispatch' @@ -37,4 +37,4 @@ jobs: timeout_minutes: 5 retry_wait_seconds: 60 max_attempts: 3 - command: lychee --accept 429,999 --exclude-loopback --exclude 'https?://(www\.)?(twitter\.com|instagram\.com|url\.com)' --exclude-path '**/ci.yaml' --exclude-mail --github-token ${{ secrets.GITHUB_TOKEN }} './**/*.md' './**/*.html' './**/*.yml' './**/*.yaml' './**/*.py' './**/*.ipynb' + command: lychee --accept 429,999 --exclude-loopback --exclude 'https?://(www\.)?(linkedin\.com|twitter\.com|instagram\.com|url\.com)' --exclude-path '**/ci.yaml' --exclude-mail --github-token ${{ secrets.GITHUB_TOKEN }} './**/*.md' './**/*.html' './**/*.yml' './**/*.yaml' './**/*.py' './**/*.ipynb' diff --git a/downloads/yolov5-master/.pre-commit-config.yaml b/downloads/yolov5-master/.pre-commit-config.yaml index defb13726..b8099b978 100644 --- a/downloads/yolov5-master/.pre-commit-config.yaml +++ b/downloads/yolov5-master/.pre-commit-config.yaml @@ -16,17 +16,16 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - id: check-case-conflict - - id: check-yaml + # - id: check-yaml - id: check-docstring-first - id: double-quote-string-fixer - id: detect-private-key - repo: https://github.com/asottile/pyupgrade - rev: v3.3.2 + rev: v3.10.1 hooks: - id: pyupgrade name: Upgrade code - args: [--py37-plus] - repo: https://github.com/PyCQA/isort rev: 5.12.0 @@ -35,7 +34,7 @@ repos: name: Sort imports - repo: https://github.com/google/yapf - rev: v0.33.0 + rev: v0.40.0 hooks: - id: yapf name: YAPF formatting @@ -51,19 +50,24 @@ repos: # exclude: "README.md|README.zh-CN.md|CONTRIBUTING.md" - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 6.1.0 hooks: - id: flake8 name: PEP8 - repo: https://github.com/codespell-project/codespell - rev: v2.2.4 + rev: v2.2.5 hooks: - id: codespell args: - --ignore-words-list=crate,nd,strack,dota - #- repo: https://github.com/asottile/yesqa - # rev: v1.4.0 - # hooks: - # - id: yesqa +# - repo: https://github.com/asottile/yesqa +# rev: v1.4.0 +# hooks: +# - id: yesqa + +# - repo: https://github.com/asottile/dead +# rev: v1.5.0 +# hooks: +# - id: dead diff --git a/downloads/yolov5-master/README.md b/downloads/yolov5-master/README.md index 37f683343..b9941b74e 100644 --- a/downloads/yolov5-master/README.md +++ b/downloads/yolov5-master/README.md @@ -20,7 +20,7 @@ YOLOv5 🚀 is the world's most loved vision AI, representing Ultralytics open-source research into future vision AI methods, incorporating lessons learned and best practices evolved over thousands of hours of research and development. -We hope that the resources here will help you get the most out of YOLOv5. Please browse the YOLOv5 Docs for details, raise an issue on GitHub for support, and join our Discord community for questions and discussions! +We hope that the resources here will help you get the most out of YOLOv5. Please browse the YOLOv5 Docs for details, raise an issue on GitHub for support, and join our Discord community for questions and discussions! To request an Enterprise License please complete the form at [Ultralytics Licensing](https://ultralytics.com/license). @@ -28,7 +28,7 @@ To request an Enterprise License please complete the form at [Ultralytics Licens - + @@ -43,7 +43,7 @@ To request an Enterprise License please complete the form at [Ultralytics Licens - + @@ -59,7 +59,9 @@ object detection, image segmentation and image classification tasks. See the [YOLOv8 Docs](https://docs.ultralytics.com) for details and get started with: -```commandline +[![PyPI version](https://badge.fury.io/py/ultralytics.svg)](https://badge.fury.io/py/ultralytics) [![Downloads](https://static.pepy.tech/badge/ultralytics)](https://pepy.tech/project/ultralytics) + +```bash pip install ultralytics ``` @@ -76,8 +78,8 @@ See the [YOLOv5 Docs](https://docs.ultralytics.com/yolov5) for full documentatio Install Clone repo and install [requirements.txt](https://github.com/ultralytics/yolov5/blob/master/requirements.txt) in a -[**Python>=3.7.0**](https://www.python.org/) environment, including -[**PyTorch>=1.7**](https://pytorch.org/get-started/locally/). +[**Python>=3.8.0**](https://www.python.org/) environment, including +[**PyTorch>=1.8**](https://pytorch.org/get-started/locally/). ```bash git clone https://github.com/ultralytics/yolov5 # clone @@ -459,21 +461,21 @@ We love your input! We want to make contributing to YOLOv5 as easy and transpare ##
License
-YOLOv5 is available under two different licenses: +Ultralytics offers two licensing options to accommodate diverse use cases: -- **AGPL-3.0 License**: See [LICENSE](https://github.com/ultralytics/yolov5/blob/master/LICENSE) file for details. -- **Enterprise License**: Provides greater flexibility for commercial product development without the open-source requirements of AGPL-3.0. Typical use cases are embedding Ultralytics software and AI models in commercial products and applications. Request an Enterprise License at [Ultralytics Licensing](https://ultralytics.com/license). +- **AGPL-3.0 License**: This [OSI-approved](https://opensource.org/licenses/) open-source license is ideal for students and enthusiasts, promoting open collaboration and knowledge sharing. See the [LICENSE](https://github.com/ultralytics/yolov5/blob/master/LICENSE) file for more details. +- **Enterprise License**: Designed for commercial use, this license permits seamless integration of Ultralytics software and AI models into commercial goods and services, bypassing the open-source requirements of AGPL-3.0. If your scenario involves embedding our solutions into a commercial offering, reach out through [Ultralytics Licensing](https://ultralytics.com/license). ##
Contact
-For YOLOv5 bug reports and feature requests please visit [GitHub Issues](https://github.com/ultralytics/yolov5/issues), and join our [Discord](https://discord.gg/n6cFeSPZdD) community for questions and discussions! +For YOLOv5 bug reports and feature requests please visit [GitHub Issues](https://github.com/ultralytics/yolov5/issues), and join our [Discord](https://ultralytics.com/discord) community for questions and discussions!
diff --git a/downloads/yolov5-master/README.zh-CN.md b/downloads/yolov5-master/README.zh-CN.md index da60d3fe0..d8b2a900b 100644 --- a/downloads/yolov5-master/README.zh-CN.md +++ b/downloads/yolov5-master/README.zh-CN.md @@ -19,7 +19,7 @@ YOLOv5 🚀 是世界上最受欢迎的视觉 AI,代表 Ultralytics 对未来视觉 AI 方法的开源研究,结合在数千小时的研究和开发中积累的经验教训和最佳实践。 -我们希望这里的资源能帮助您充分利用 YOLOv5。请浏览 YOLOv5 文档 了解详细信息,在 GitHub 上提交问题以获得支持,并加入我们的 Discord 社区进行问题和讨论! +我们希望这里的资源能帮助您充分利用 YOLOv5。请浏览 YOLOv5 文档 了解详细信息,在 GitHub 上提交问题以获得支持,并加入我们的 Discord 社区进行问题和讨论! 如需申请企业许可,请在 [Ultralytics Licensing](https://ultralytics.com/license) 处填写表格 @@ -27,7 +27,7 @@ YOLOv5 🚀 是世界上最受欢迎的视觉 AI,代表 - + @@ -42,19 +42,19 @@ YOLOv5 🚀 是世界上最受欢迎的视觉 AI,代表 - + -##
YOLOv8 🚀 NEW
+##
YOLOv8 🚀 新品
-We are thrilled to announce the launch of Ultralytics YOLOv8 🚀, our NEW cutting-edge, state-of-the-art (SOTA) model -released at **[https://github.com/ultralytics/ultralytics](https://github.com/ultralytics/ultralytics)**. -YOLOv8 is designed to be fast, accurate, and easy to use, making it an excellent choice for a wide range of -object detection, image segmentation and image classification tasks. +我们很高兴宣布 Ultralytics YOLOv8 🚀 的发布,这是我们新推出的领先水平、最先进的(SOTA)模型,发布于 **[https://github.com/ultralytics/ultralytics](https://github.com/ultralytics/ultralytics)**。 +YOLOv8 旨在快速、准确且易于使用,使其成为广泛的物体检测、图像分割和图像分类任务的极佳选择。 -See the [YOLOv8 Docs](https://docs.ultralytics.com) for details and get started with: +请查看 [YOLOv8 文档](https://docs.ultralytics.com)了解详细信息,并开始使用: + +[![PyPI 版本](https://badge.fury.io/py/ultralytics.svg)](https://badge.fury.io/py/ultralytics) [![下载量](https://static.pepy.tech/badge/ultralytics)](https://pepy.tech/project/ultralytics) ```commandline pip install ultralytics @@ -72,7 +72,7 @@ pip install ultralytics
安装 -克隆 repo,并要求在 [**Python>=3.7.0**](https://www.python.org/) 环境中安装 [requirements.txt](https://github.com/ultralytics/yolov5/blob/master/requirements.txt) ,且要求 [**PyTorch>=1.7**](https://pytorch.org/get-started/locally/) 。 +克隆 repo,并要求在 [**Python>=3.8.0**](https://www.python.org/) 环境中安装 [requirements.txt](https://github.com/ultralytics/yolov5/blob/master/requirements.txt) ,且要求 [**PyTorch>=1.8**](https://pytorch.org/get-started/locally/) 。 ```bash git clone https://github.com/ultralytics/yolov5 # clone @@ -452,23 +452,23 @@ python export.py --weights yolov5s-cls.pt resnet50.pt efficientnet_b0.pt --inclu -##
License
+##
许可证
-YOLOv5 在两种不同的 License 下可用: +Ultralytics 提供两种许可证选项以适应各种使用场景: -- **AGPL-3.0 License**: 查看 [License](https://github.com/ultralytics/yolov5/blob/master/LICENSE) 文件的详细信息。 -- **企业License**:在没有 AGPL-3.0 开源要求的情况下为商业产品开发提供更大的灵活性。典型用例是将 Ultralytics 软件和 AI 模型嵌入到商业产品和应用程序中。在以下位置申请企业许可证 [Ultralytics 许可](https://ultralytics.com/license) 。 +- **AGPL-3.0 许可证**:这个[OSI 批准](https://opensource.org/licenses/)的开源许可证非常适合学生和爱好者,可以推动开放的协作和知识分享。请查看[LICENSE](https://github.com/ultralytics/yolov5/blob/master/LICENSE) 文件以了解更多细节。 +- **企业许可证**:专为商业用途设计,该许可证允许将 Ultralytics 的软件和 AI 模型无缝集成到商业产品和服务中,从而绕过 AGPL-3.0 的开源要求。如果您的场景涉及将我们的解决方案嵌入到商业产品中,请通过 [Ultralytics Licensing](https://ultralytics.com/license)与我们联系。 -##
联系我们
+##
联系方式
-对于 YOLOv5 的错误报告和功能请求,请访问 [GitHub Issues](https://github.com/ultralytics/yolov5/issues),并加入我们的 [Discord](https://discord.gg/n6cFeSPZdD) 社区进行问题和讨论! +对于 Ultralytics 的错误报告和功能请求,请访问 [GitHub Issues](https://github.com/ultralytics/yolov5/issues),并加入我们的 [Discord](https://ultralytics.com/discord) 社区进行问题和讨论!
diff --git a/downloads/yolov5-master/benchmarks.py b/downloads/yolov5-master/benchmarks.py index fc3073965..b590ff63c 100644 --- a/downloads/yolov5-master/benchmarks.py +++ b/downloads/yolov5-master/benchmarks.py @@ -76,7 +76,12 @@ def run( if f == '-': w = weights # PyTorch format else: - w = export.run(weights=weights, imgsz=[imgsz], include=[f], device=device, half=half)[-1] # all others + w = export.run(weights=weights, + imgsz=[imgsz], + include=[f], + batch_size=batch_size, + device=device, + half=half)[-1] # all others assert suffix in str(w), 'export failed' # Validate diff --git a/downloads/yolov5-master/classify/predict.py b/downloads/yolov5-master/classify/predict.py index 9b64810d4..1cbbc094a 100644 --- a/downloads/yolov5-master/classify/predict.py +++ b/downloads/yolov5-master/classify/predict.py @@ -43,12 +43,13 @@ if str(ROOT) not in sys.path: sys.path.append(str(ROOT)) # add ROOT to PATH ROOT = Path(os.path.relpath(ROOT, Path.cwd())) # relative +from ultralytics.utils.plotting import Annotator + from models.common import DetectMultiBackend from utils.augmentations import classify_transforms from utils.dataloaders import IMG_FORMATS, VID_FORMATS, LoadImages, LoadScreenshots, LoadStreams from utils.general import (LOGGER, Profile, check_file, check_img_size, check_imshow, check_requirements, colorstr, cv2, increment_path, print_args, strip_optimizer) -from utils.plots import Annotator from utils.torch_utils import select_device, smart_inference_mode @@ -144,7 +145,7 @@ def run( # Write results text = '\n'.join(f'{prob[j]:.2f} {names[j]}' for j in top5i) if save_img or view_img: # Add bbox to image - annotator.text((32, 32), text, txt_color=(255, 255, 255)) + annotator.text([32, 32], text, txt_color=(255, 255, 255)) if save_txt: # Write to file with open(f'{txt_path}.txt', 'a') as f: f.write(text + '\n') diff --git a/downloads/yolov5-master/classify/tutorial.ipynb b/downloads/yolov5-master/classify/tutorial.ipynb index 75eebd8e1..844da0c41 100644 --- a/downloads/yolov5-master/classify/tutorial.ipynb +++ b/downloads/yolov5-master/classify/tutorial.ipynb @@ -1445,7 +1445,7 @@ "# YOLOv5 PyTorch HUB Inference (DetectionModels only)\n", "import torch\n", "\n", - "model = torch.hub.load('ultralytics/yolov5', 'yolov5s') # yolov5n - yolov5x6 or custom\n", + "model = torch.hub.load('ultralytics/yolov5', 'yolov5s', force_reload=True, trust_repo=True) # or yolov5n - yolov5x6 or custom\n", "im = 'https://ultralytics.com/images/zidane.jpg' # file, Path, PIL.Image, OpenCV, nparray, list\n", "results = model(im) # inference\n", "results.print() # or .show(), .save(), .crop(), .pandas(), etc." diff --git a/downloads/yolov5-master/data/Objects365.yaml b/downloads/yolov5-master/data/Objects365.yaml index 990f5a56b..d4045e2f8 100644 --- a/downloads/yolov5-master/data/Objects365.yaml +++ b/downloads/yolov5-master/data/Objects365.yaml @@ -428,7 +428,7 @@ download: | path = Path(im["file_name"]) # image filename try: with open(labels / path.with_suffix('.txt').name, 'a') as file: - annIds = coco.getAnnIds(imgIds=im["id"], catIds=catIds, iscrowd=None) + annIds = coco.getAnnIds(imgIds=im["id"], catIds=catIds, iscrowd=False) for a in coco.loadAnns(annIds): x, y, w, h = a['bbox'] # bounding box in xywh (xy top-left corner) xyxy = np.array([x, y, x + w, y + h])[None] # pixels(1,4) diff --git a/downloads/yolov5-master/detect.py b/downloads/yolov5-master/detect.py index 216c9dbd5..8934a093f 100644 --- a/downloads/yolov5-master/detect.py +++ b/downloads/yolov5-master/detect.py @@ -42,11 +42,12 @@ if str(ROOT) not in sys.path: sys.path.append(str(ROOT)) # add ROOT to PATH ROOT = Path(os.path.relpath(ROOT, Path.cwd())) # relative +from ultralytics.utils.plotting import Annotator, colors, save_one_box + from models.common import DetectMultiBackend from utils.dataloaders import IMG_FORMATS, VID_FORMATS, LoadImages, LoadScreenshots, LoadStreams from utils.general import (LOGGER, Profile, check_file, check_img_size, check_imshow, check_requirements, colorstr, cv2, increment_path, non_max_suppression, print_args, scale_boxes, strip_optimizer, xyxy2xywh) -from utils.plots import Annotator, colors, save_one_box from utils.torch_utils import select_device, smart_inference_mode diff --git a/downloads/yolov5-master/export.py b/downloads/yolov5-master/export.py index 5f8e1c482..92d42472d 100644 --- a/downloads/yolov5-master/export.py +++ b/downloads/yolov5-master/export.py @@ -110,7 +110,7 @@ def export_formats(): ['TensorFlow Lite', 'tflite', '.tflite', True, False], ['TensorFlow Edge TPU', 'edgetpu', '_edgetpu.tflite', False, False], ['TensorFlow.js', 'tfjs', '_web_model', False, False], - ['PaddlePaddle', 'paddle', '_paddle_model', True, True],] + ['PaddlePaddle', 'paddle', '_paddle_model', True, True], ] return pd.DataFrame(x, columns=['Format', 'Argument', 'Suffix', 'CPU', 'GPU']) @@ -205,23 +205,68 @@ def export_onnx(model, im, file, opset, dynamic, simplify, prefix=colorstr('ONNX @try_export -def export_openvino(file, metadata, half, prefix=colorstr('OpenVINO:')): +def export_openvino(file, metadata, half, int8, data, prefix=colorstr('OpenVINO:')): # YOLOv5 OpenVINO export - check_requirements('openvino-dev') # requires openvino-dev: https://pypi.org/project/openvino-dev/ - import openvino.inference_engine as ie + check_requirements('openvino-dev>=2023.0') # requires openvino-dev: https://pypi.org/project/openvino-dev/ + import openvino.runtime as ov # noqa + from openvino.tools import mo # noqa - LOGGER.info(f'\n{prefix} starting export with openvino {ie.__version__}...') - f = str(file).replace('.pt', f'_openvino_model{os.sep}') + LOGGER.info(f'\n{prefix} starting export with openvino {ov.__version__}...') + f = str(file).replace(file.suffix, f'_openvino_model{os.sep}') + f_onnx = file.with_suffix('.onnx') + f_ov = str(Path(f) / file.with_suffix('.xml').name) + if int8: + check_requirements('nncf>=2.4.0') # requires at least version 2.4.0 to use the post-training quantization + import nncf + import numpy as np + from openvino.runtime import Core - args = [ - 'mo', - '--input_model', - str(file.with_suffix('.onnx')), - '--output_dir', - f, - '--data_type', - ('FP16' if half else 'FP32'),] - subprocess.run(args, check=True, env=os.environ) # export + from utils.dataloaders import create_dataloader + core = Core() + onnx_model = core.read_model(f_onnx) # export + + def prepare_input_tensor(image: np.ndarray): + input_tensor = image.astype(np.float32) # uint8 to fp16/32 + input_tensor /= 255.0 # 0 - 255 to 0.0 - 1.0 + + if input_tensor.ndim == 3: + input_tensor = np.expand_dims(input_tensor, 0) + return input_tensor + + def gen_dataloader(yaml_path, task='train', imgsz=640, workers=4): + data_yaml = check_yaml(yaml_path) + data = check_dataset(data_yaml) + dataloader = create_dataloader(data[task], + imgsz=imgsz, + batch_size=1, + stride=32, + pad=0.5, + single_cls=False, + rect=False, + workers=workers)[0] + return dataloader + + # noqa: F811 + + def transform_fn(data_item): + """ + Quantization transform function. Extracts and preprocess input data from dataloader item for quantization. + Parameters: + data_item: Tuple with data item produced by DataLoader during iteration + Returns: + input_tensor: Input data for quantization + """ + img = data_item[0].numpy() + input_tensor = prepare_input_tensor(img) + return input_tensor + + ds = gen_dataloader(data) + quantization_dataset = nncf.Dataset(ds, transform_fn) + ov_model = nncf.quantize(onnx_model, quantization_dataset, preset=nncf.QuantizationPreset.MIXED) + else: + ov_model = mo.convert_model(f_onnx, model_name=file.stem, framework='onnx', compress_to_fp16=half) # export + + ov.serialize(ov_model, f_ov) # save yaml_save(Path(f) / file.with_suffix('.yaml').name, metadata) # add metadata.yaml return f, None @@ -456,7 +501,7 @@ def export_edgetpu(file, prefix=colorstr('Edge TPU:')): '10', '--out_dir', str(file.parent), - f_tfl,], check=True) + f_tfl, ], check=True) return f, None @@ -477,7 +522,7 @@ def export_tfjs(file, int8, prefix=colorstr('TensorFlow.js:')): '--quantize_uint8' if int8 else '', '--output_node_names=Identity,Identity_1,Identity_2,Identity_3', str(f_pb), - str(f),] + str(f), ] subprocess.run([arg for arg in args if arg], check=True) json = Path(f_json).read_text() @@ -536,7 +581,7 @@ def pipeline_coreml(model, im, file, names, y, prefix=colorstr('CoreML Pipeline: batch_size, ch, h, w = list(im.shape) # BCHW t = time.time() - # Output shapes + # YOLOv5 Output shapes spec = model.get_spec() out0, out1 = iter(spec.description.output) if platform.system() == 'Darwin': @@ -726,7 +771,7 @@ def run( if onnx or xml: # OpenVINO requires ONNX f[2], _ = export_onnx(model, im, file, opset, dynamic, simplify) if xml: # OpenVINO - f[3], _ = export_openvino(file, metadata, half) + f[3], _ = export_openvino(file, metadata, half, int8, data) if coreml: # CoreML f[4], ct_model = export_coreml(model, im, file, int8, half, nms) if nms: @@ -786,7 +831,7 @@ def parse_opt(known=False): parser.add_argument('--inplace', action='store_true', help='set YOLOv5 Detect() inplace=True') parser.add_argument('--keras', action='store_true', help='TF: use Keras') parser.add_argument('--optimize', action='store_true', help='TorchScript: optimize for mobile') - parser.add_argument('--int8', action='store_true', help='CoreML/TF INT8 quantization') + parser.add_argument('--int8', action='store_true', help='CoreML/TF/OpenVINO INT8 quantization') parser.add_argument('--dynamic', action='store_true', help='ONNX/TF/TensorRT: dynamic axes') parser.add_argument('--simplify', action='store_true', help='ONNX: simplify model') parser.add_argument('--opset', type=int, default=17, help='ONNX: opset version') diff --git a/downloads/yolov5-master/models/common.py b/downloads/yolov5-master/models/common.py index 16537703e..75cc4e97b 100644 --- a/downloads/yolov5-master/models/common.py +++ b/downloads/yolov5-master/models/common.py @@ -24,12 +24,24 @@ import torch.nn as nn from PIL import Image from torch.cuda import amp +# Import 'ultralytics' package or install if if missing +try: + import ultralytics + + assert hasattr(ultralytics, '__version__') # verify package is not directory +except (ImportError, AssertionError): + import os + + os.system('pip install -U ultralytics') + import ultralytics + +from ultralytics.utils.plotting import Annotator, colors, save_one_box + from utils import TryExcept from utils.dataloaders import exif_transpose, letterbox from utils.general import (LOGGER, ROOT, Profile, check_requirements, check_suffix, check_version, colorstr, increment_path, is_jupyter, make_divisible, non_max_suppression, scale_boxes, xywh2xyxy, xyxy2xywh, yaml_load) -from utils.plots import Annotator, colors, save_one_box from utils.torch_utils import copy_attr, smart_inference_mode @@ -373,18 +385,18 @@ class DetectMultiBackend(nn.Module): stride, names = int(meta['stride']), eval(meta['names']) elif xml: # OpenVINO LOGGER.info(f'Loading {w} for OpenVINO inference...') - check_requirements('openvino') # requires openvino-dev: https://pypi.org/project/openvino-dev/ + check_requirements('openvino>=2023.0') # requires openvino-dev: https://pypi.org/project/openvino-dev/ from openvino.runtime import Core, Layout, get_batch - ie = Core() + core = Core() if not Path(w).is_file(): # if not *.xml w = next(Path(w).glob('*.xml')) # get *.xml file from *_openvino_model dir - network = ie.read_model(model=w, weights=Path(w).with_suffix('.bin')) - if network.get_parameters()[0].get_layout().empty: - network.get_parameters()[0].set_layout(Layout('NCHW')) - batch_dim = get_batch(network) + ov_model = core.read_model(model=w, weights=Path(w).with_suffix('.bin')) + if ov_model.get_parameters()[0].get_layout().empty: + ov_model.get_parameters()[0].set_layout(Layout('NCHW')) + batch_dim = get_batch(ov_model) if batch_dim.is_static: batch_size = batch_dim.get_length() - executable_network = ie.compile_model(network, device_name='CPU') # device_name="MYRIAD" for Intel NCS2 + ov_compiled_model = core.compile_model(ov_model, device_name='AUTO') # AUTO selects best available device stride, names = self._load_metadata(Path(w).with_suffix('.yaml')) # load metadata elif engine: # TensorRT LOGGER.info(f'Loading {w} for TensorRT inference...') @@ -524,7 +536,7 @@ class DetectMultiBackend(nn.Module): y = self.session.run(self.output_names, {self.session.get_inputs()[0].name: im}) elif self.xml: # OpenVINO im = im.cpu().numpy() # FP32 - y = list(self.executable_network([im]).values()) + y = list(self.ov_compiled_model(im).values()) elif self.engine: # TensorRT if self.dynamic and im.shape != self.bindings['images'].shape: i = self.model.get_binding_index('images') @@ -541,7 +553,7 @@ class DetectMultiBackend(nn.Module): elif self.coreml: # CoreML im = im.cpu().numpy() im = Image.fromarray((im[0] * 255).astype('uint8')) - # im = im.resize((192, 320), Image.ANTIALIAS) + # im = im.resize((192, 320), Image.BILINEAR) y = self.model.predict({'image': im}) # coordinates are xywh normalized if 'confidence' in y: box = xywh2xyxy(y['coordinates'] * [[w, h, w, h]]) # xyxy pixels diff --git a/downloads/yolov5-master/models/experimental.py b/downloads/yolov5-master/models/experimental.py index d60d1808d..11f75e225 100644 --- a/downloads/yolov5-master/models/experimental.py +++ b/downloads/yolov5-master/models/experimental.py @@ -87,11 +87,11 @@ def attempt_load(weights, device=None, inplace=True, fuse=True): model.append(ckpt.fuse().eval() if fuse and hasattr(ckpt, 'fuse') else ckpt.eval()) # model in eval mode - # Module compatibility updates + # Module updates for m in model.modules(): t = type(m) if t in (nn.Hardswish, nn.LeakyReLU, nn.ReLU, nn.ReLU6, nn.SiLU, Detect, Model): - m.inplace = inplace # torch 1.7.0 compatibility + m.inplace = inplace if t is Detect and not isinstance(m.anchor_grid, list): delattr(m, 'anchor_grid') setattr(m, 'anchor_grid', [torch.zeros(1)] * m.nl) diff --git a/downloads/yolov5-master/models/tf.py b/downloads/yolov5-master/models/tf.py index bc0a465d7..62ba3ebf0 100644 --- a/downloads/yolov5-master/models/tf.py +++ b/downloads/yolov5-master/models/tf.py @@ -310,7 +310,7 @@ class TFDetect(keras.layers.Layer): y = tf.concat([xy, wh, tf.sigmoid(y[..., 4:5 + self.nc]), y[..., 5 + self.nc:]], -1) z.append(tf.reshape(y, [-1, self.na * ny * nx, self.no])) - return tf.transpose(x, [0, 2, 1, 3]) if self.training else (tf.concat(z, 1),) + return tf.transpose(x, [0, 2, 1, 3]) if self.training else (tf.concat(z, 1), ) @staticmethod def _make_grid(nx=20, ny=20): @@ -486,7 +486,7 @@ class TFModel: iou_thres, conf_thres, clip_boxes=False) - return (nms,) + return (nms, ) return x # output [1,6300,85] = [xywh, conf, class0, class1, ...] # x = x[0] # [x(1,6300,85), ...] to x(6300,85) # xywh = x[..., :4] # x(6300,4) boxes diff --git a/downloads/yolov5-master/models/yolo.py b/downloads/yolov5-master/models/yolo.py index 18d2542bf..4f4d567be 100644 --- a/downloads/yolov5-master/models/yolo.py +++ b/downloads/yolov5-master/models/yolo.py @@ -21,8 +21,8 @@ if str(ROOT) not in sys.path: if platform.system() != 'Windows': ROOT = Path(os.path.relpath(ROOT, Path.cwd())) # relative -from models.common import * -from models.experimental import * +from models.common import * # noqa +from models.experimental import * # noqa from utils.autoanchor import check_anchor_order from utils.general import LOGGER, check_version, check_yaml, make_divisible, print_args from utils.plots import feature_visualization @@ -76,7 +76,7 @@ class Detect(nn.Module): y = torch.cat((xy, wh, conf), 4) z.append(y.view(bs, self.na * nx * ny, self.no)) - return x if self.training else (torch.cat(z, 1),) if self.export else (torch.cat(z, 1), x) + return x if self.training else (torch.cat(z, 1), ) if self.export else (torch.cat(z, 1), x) def _make_grid(self, nx=20, ny=20, i=0, torch_1_10=check_version(torch.__version__, '1.10.0')): d = self.anchors[i].device @@ -126,7 +126,7 @@ class BaseModel(nn.Module): def _profile_one_layer(self, m, x, dt): c = m == self.model[-1] # is final layer, copy input as inplace fix - o = thop.profile(m, inputs=(x.copy() if c else x,), verbose=False)[0] / 1E9 * 2 if thop else 0 # FLOPs + o = thop.profile(m, inputs=(x.copy() if c else x, ), verbose=False)[0] / 1E9 * 2 if thop else 0 # FLOPs t = time_sync() for _ in range(10): m(x.copy() if c else x) diff --git a/downloads/yolov5-master/requirements.txt b/downloads/yolov5-master/requirements.txt index ae0a21f00..33bb7dba2 100644 --- a/downloads/yolov5-master/requirements.txt +++ b/downloads/yolov5-master/requirements.txt @@ -4,7 +4,7 @@ # Base ------------------------------------------------------------------------ gitpython>=3.1.30 matplotlib>=3.3 -numpy>=1.18.5 +numpy>=1.22.2 opencv-python>=4.1.1 Pillow>=7.1.2 psutil # system resources @@ -12,10 +12,10 @@ PyYAML>=5.3.1 requests>=2.23.0 scipy>=1.4.1 thop>=0.1.1 # FLOPs computation -torch>=1.7.0 # see https://pytorch.org/get-started/locally (recommended) -torchvision>=0.8.1 +torch>=1.8.0 # see https://pytorch.org/get-started/locally (recommended) +torchvision>=0.9.0 tqdm>=4.64.0 -ultralytics>=8.0.100 +ultralytics>=8.0.147 # protobuf<=3.20.1 # https://github.com/ultralytics/yolov5/issues/8012 # Logging --------------------------------------------------------------------- @@ -36,7 +36,7 @@ seaborn>=0.11.0 # scikit-learn<=1.1.2 # CoreML quantization # tensorflow>=2.4.0 # TF exports (-cpu, -aarch64, -macos) # tensorflowjs>=3.9.0 # TF.js export -# openvino-dev # OpenVINO export +# openvino-dev>=2023.0 # OpenVINO export # Deploy ---------------------------------------------------------------------- setuptools>=65.5.1 # Snyk vulnerability fix diff --git a/downloads/yolov5-master/segment/predict.py b/downloads/yolov5-master/segment/predict.py index 6a4d5eff3..77e8df790 100644 --- a/downloads/yolov5-master/segment/predict.py +++ b/downloads/yolov5-master/segment/predict.py @@ -42,12 +42,13 @@ if str(ROOT) not in sys.path: sys.path.append(str(ROOT)) # add ROOT to PATH ROOT = Path(os.path.relpath(ROOT, Path.cwd())) # relative +from ultralytics.utils.plotting import Annotator, colors, save_one_box + from models.common import DetectMultiBackend from utils.dataloaders import IMG_FORMATS, VID_FORMATS, LoadImages, LoadScreenshots, LoadStreams from utils.general import (LOGGER, Profile, check_file, check_img_size, check_imshow, check_requirements, colorstr, cv2, increment_path, non_max_suppression, print_args, scale_boxes, scale_segments, strip_optimizer) -from utils.plots import Annotator, colors, save_one_box from utils.segment.general import masks2segments, process_mask, process_mask_native from utils.torch_utils import select_device, smart_inference_mode diff --git a/downloads/yolov5-master/segment/train.py b/downloads/yolov5-master/segment/train.py index 5f1fa4a1e..2ae09c1cb 100644 --- a/downloads/yolov5-master/segment/train.py +++ b/downloads/yolov5-master/segment/train.py @@ -605,7 +605,7 @@ def main(opt, callbacks=Callbacks()): 'gsutil', 'cp', f'gs://{opt.bucket}/evolve.csv', - str(evolve_csv),]) + str(evolve_csv), ]) for _ in range(opt.evolve): # generations to evolve if evolve_csv.exists(): # if evolve.csv exists: select best hyps and mutate diff --git a/downloads/yolov5-master/segment/tutorial.ipynb b/downloads/yolov5-master/segment/tutorial.ipynb index f2aee9e26..cd215e7f3 100644 --- a/downloads/yolov5-master/segment/tutorial.ipynb +++ b/downloads/yolov5-master/segment/tutorial.ipynb @@ -63,7 +63,7 @@ "source": [ "!git clone https://github.com/ultralytics/yolov5 # clone\n", "%cd yolov5\n", - "%pip install -qr requirements.txt # install\n", + "%pip install -qr requirements.txt comet_ml # install\n", "\n", "import torch\n", "import utils\n", @@ -558,7 +558,7 @@ "# YOLOv5 PyTorch HUB Inference (DetectionModels only)\n", "import torch\n", "\n", - "model = torch.hub.load('ultralytics/yolov5', 'yolov5s-seg') # yolov5n - yolov5x6 or custom\n", + "model = torch.hub.load('ultralytics/yolov5', 'yolov5s-seg', force_reload=True, trust_repo=True) # or yolov5n - yolov5x6 or custom\n", "im = 'https://ultralytics.com/images/zidane.jpg' # file, Path, PIL.Image, OpenCV, nparray, list\n", "results = model(im) # inference\n", "results.print() # or .show(), .save(), .crop(), .pandas(), etc." diff --git a/downloads/yolov5-master/setup.cfg b/downloads/yolov5-master/setup.cfg index d7c4cb3e1..2cde6a494 100644 --- a/downloads/yolov5-master/setup.cfg +++ b/downloads/yolov5-master/setup.cfg @@ -3,7 +3,7 @@ # Local usage: pip install pre-commit, pre-commit run --all-files [metadata] -license_file = LICENSE +license_files = LICENSE description_file = README.md [tool:pytest] @@ -25,17 +25,19 @@ verbose = 2 # https://pep8.readthedocs.io/en/latest/intro.html#error-codes format = pylint # see: https://www.flake8rules.com/ -ignore = E731,F405,E402,F401,W504,E127,E231,E501,F403 +ignore = E731,F405,E402,W504,E501 # E731: Do not assign a lambda expression, use a def # F405: name may be undefined, or defined from star imports: module # E402: module level import not at top of file - # F401: module imported but unused # W504: line break after binary operator - # E127: continuation line over-indented for visual indent - # E231: missing whitespace after ‘,’, ‘;’, or ‘:’ # E501: line too long + # removed: + # F401: module imported but unused + # E231: missing whitespace after ‘,’, ‘;’, or ‘:’ + # E127: continuation line over-indented for visual indent # F403: ‘from module import *’ used; unable to detect undefined names + [isort] # https://pycqa.github.io/isort/docs/configuration/options.html line_length = 120 @@ -48,7 +50,7 @@ spaces_before_comment = 2 COLUMN_LIMIT = 120 COALESCE_BRACKETS = True SPACES_AROUND_POWER_OPERATOR = True -SPACE_BETWEEN_ENDING_COMMA_AND_CLOSING_BRACKET = False +SPACE_BETWEEN_ENDING_COMMA_AND_CLOSING_BRACKET = True SPLIT_BEFORE_CLOSING_BRACKET = False SPLIT_BEFORE_FIRST_ARGUMENT = False # EACH_DICT_ENTRY_ON_SEPARATE_LINE = False diff --git a/downloads/yolov5-master/train.py b/downloads/yolov5-master/train.py index 48eeb0946..004c8eeda 100644 --- a/downloads/yolov5-master/train.py +++ b/downloads/yolov5-master/train.py @@ -26,6 +26,11 @@ from copy import deepcopy from datetime import datetime from pathlib import Path +try: + import comet_ml # must be imported before torch (if installed) +except ImportError: + comet_ml = None + import numpy as np import torch import torch.distributed as dist @@ -579,7 +584,7 @@ def main(opt, callbacks=Callbacks()): 'gsutil', 'cp', f'gs://{opt.bucket}/evolve.csv', - str(evolve_csv),]) + str(evolve_csv), ]) for _ in range(opt.evolve): # generations to evolve if evolve_csv.exists(): # if evolve.csv exists: select best hyps and mutate diff --git a/downloads/yolov5-master/tutorial.ipynb b/downloads/yolov5-master/tutorial.ipynb index be8706882..f666dbde7 100644 --- a/downloads/yolov5-master/tutorial.ipynb +++ b/downloads/yolov5-master/tutorial.ipynb @@ -31,7 +31,7 @@ " \"Open\n", "
\n", "\n", - "This YOLOv5 🚀 notebook by Ultralytics presents simple train, validate and predict examples to help start your AI adventure.
We hope that the resources in this notebook will help you get the most out of YOLOv5. Please browse the YOLOv5 Docs for details, raise an issue on GitHub for support, and join our Discord community for questions and discussions!\n", + "This YOLOv5 🚀 notebook by Ultralytics presents simple train, validate and predict examples to help start your AI adventure.
We hope that the resources in this notebook will help you get the most out of YOLOv5. Please browse the YOLOv5 Docs for details, raise an issue on GitHub for support, and join our Discord community for questions and discussions!\n", "\n", "" ] @@ -59,13 +59,13 @@ "source": [ "!git clone https://github.com/ultralytics/yolov5 # clone\n", "%cd yolov5\n", - "%pip install -qr requirements.txt # install\n", + "%pip install -qr requirements.txt comet_ml # install\n", "\n", "import torch\n", "import utils\n", "display = utils.notebook_init() # checks" ], - "execution_count": 1, + "execution_count": null, "outputs": [ { "output_type": "stream", @@ -95,7 +95,7 @@ "\n", "```shell\n", "python detect.py --source 0 # webcam\n", - " img.jpg # image \n", + " img.jpg # image\n", " vid.mp4 # video\n", " screen # screenshot\n", " path/ # directory\n", @@ -118,7 +118,7 @@ "!python detect.py --weights yolov5s.pt --img 640 --conf 0.25 --source data/images\n", "# display.Image(filename='runs/detect/exp/zidane.jpg', width=600)" ], - "execution_count": 13, + "execution_count": null, "outputs": [ { "output_type": "stream", @@ -174,7 +174,7 @@ "torch.hub.download_url_to_file('https://ultralytics.com/assets/coco2017val.zip', 'tmp.zip') # download (780M - 5000 images)\n", "!unzip -q tmp.zip -d ../datasets && rm tmp.zip # unzip" ], - "execution_count": 3, + "execution_count": null, "outputs": [ { "output_type": "stream", @@ -198,7 +198,7 @@ "# Validate YOLOv5s on COCO val\n", "!python val.py --weights yolov5s.pt --data coco.yaml --img 640 --half" ], - "execution_count": 4, + "execution_count": null, "outputs": [ { "output_type": "stream", @@ -308,7 +308,7 @@ "# Train YOLOv5s on COCO128 for 3 epochs\n", "!python train.py --img 640 --batch 16 --epochs 3 --data coco128.yaml --weights yolov5s.pt --cache" ], - "execution_count": 5, + "execution_count": null, "outputs": [ { "output_type": "stream", @@ -539,7 +539,7 @@ "\n", "Training results are automatically logged with [Tensorboard](https://www.tensorflow.org/tensorboard) and [CSV](https://github.com/ultralytics/yolov5/pull/4148) loggers to `runs/train`, with a new experiment directory created for each new training as `runs/train/exp2`, `runs/train/exp3`, etc.\n", "\n", - "This directory contains train and val statistics, mosaics, labels, predictions and augmentated mosaics, as well as metrics and charts including precision-recall (PR) curves and confusion matrices. \n", + "This directory contains train and val statistics, mosaics, labels, predictions and augmentated mosaics, as well as metrics and charts including precision-recall (PR) curves and confusion matrices.\n", "\n", "\"Local\n" ] @@ -593,7 +593,7 @@ "# YOLOv5 PyTorch HUB Inference (DetectionModels only)\n", "import torch\n", "\n", - "model = torch.hub.load('ultralytics/yolov5', 'yolov5s', force_reload=True) # yolov5n - yolov5x6 or custom\n", + "model = torch.hub.load('ultralytics/yolov5', 'yolov5s', force_reload=True, trust_repo=True) # or yolov5n - yolov5x6 or custom\n", "im = 'https://ultralytics.com/images/zidane.jpg' # file, Path, PIL.Image, OpenCV, nparray, list\n", "results = model(im) # inference\n", "results.print() # or .show(), .save(), .crop(), .pandas(), etc." diff --git a/downloads/yolov5-master/utils/__init__.py b/downloads/yolov5-master/utils/__init__.py index 6c10857df..4c7379c87 100644 --- a/downloads/yolov5-master/utils/__init__.py +++ b/downloads/yolov5-master/utils/__init__.py @@ -54,13 +54,17 @@ def notebook_init(verbose=True): import os import shutil - from utils.general import check_font, check_requirements, is_colab + from ultralytics.utils.checks import check_requirements + + from utils.general import check_font, is_colab from utils.torch_utils import select_device # imports check_font() import psutil + if check_requirements('wandb', install=False): + os.system('pip uninstall -y wandb') # eliminate unexpected account creation prompt with infinite hang if is_colab(): shutil.rmtree('/content/sample_data', ignore_errors=True) # remove colab /sample_data directory diff --git a/downloads/yolov5-master/utils/augmentations.py b/downloads/yolov5-master/utils/augmentations.py index 52e2e346e..1e609303e 100644 --- a/downloads/yolov5-master/utils/augmentations.py +++ b/downloads/yolov5-master/utils/augmentations.py @@ -330,7 +330,7 @@ def classify_albumentations( if vflip > 0: T += [A.VerticalFlip(p=vflip)] if jitter > 0: - color_jitter = (float(jitter),) * 3 # repeat value for brightness, contrast, satuaration, 0 hue + color_jitter = (float(jitter), ) * 3 # repeat value for brightness, contrast, satuaration, 0 hue T += [A.ColorJitter(*color_jitter, 0)] else: # Use fixed crop for eval set (reproducibility) T = [A.SmallestMaxSize(max_size=size), A.CenterCrop(height=size, width=size)] diff --git a/downloads/yolov5-master/utils/callbacks.py b/downloads/yolov5-master/utils/callbacks.py index ccebba02b..c90fa824c 100644 --- a/downloads/yolov5-master/utils/callbacks.py +++ b/downloads/yolov5-master/utils/callbacks.py @@ -32,7 +32,7 @@ class Callbacks: 'on_model_save': [], 'on_train_end': [], 'on_params_update': [], - 'teardown': [],} + 'teardown': [], } self.stop_training = False # set True to interrupt training def register_action(self, hook, name='', callback=None): diff --git a/downloads/yolov5-master/utils/docker/Dockerfile b/downloads/yolov5-master/utils/docker/Dockerfile index ff657dea2..4346fc823 100644 --- a/downloads/yolov5-master/utils/docker/Dockerfile +++ b/downloads/yolov5-master/utils/docker/Dockerfile @@ -31,7 +31,7 @@ RUN git clone https://github.com/ultralytics/yolov5 /usr/src/app COPY requirements.txt . RUN python3 -m pip install --upgrade pip wheel RUN pip install --no-cache -r requirements.txt albumentations comet gsutil notebook \ - coremltools onnx onnx-simplifier onnxruntime 'openvino-dev>=2022.3' + coremltools onnx onnx-simplifier onnxruntime 'openvino-dev>=2023.0' # tensorflow tensorflowjs \ # Set environment variables diff --git a/downloads/yolov5-master/utils/docker/Dockerfile-cpu b/downloads/yolov5-master/utils/docker/Dockerfile-cpu index 613bdffa4..17316986c 100644 --- a/downloads/yolov5-master/utils/docker/Dockerfile-cpu +++ b/downloads/yolov5-master/utils/docker/Dockerfile-cpu @@ -3,23 +3,25 @@ # Image is CPU-optimized for ONNX, OpenVINO and PyTorch YOLOv5 deployments # Start FROM Ubuntu image https://hub.docker.com/_/ubuntu -FROM ubuntu:22.10 +FROM ubuntu:lunar-20230615 # Downloads to user config dir ADD https://ultralytics.com/assets/Arial.ttf https://ultralytics.com/assets/Arial.Unicode.ttf /root/.config/Ultralytics/ # Install linux packages -ENV DEBIAN_FRONTEND noninteractive -RUN apt update -RUN TZ=Etc/UTC apt install -y tzdata -RUN apt install --no-install-recommends -y python3-pip git zip curl htop libgl1-mesa-glx libglib2.0-0 libpython3-dev gnupg +# g++ required to build 'tflite_support' and 'lap' packages, libusb-1.0-0 required for 'tflite_support' package +RUN apt update \ + && apt install --no-install-recommends -y python3-pip git zip curl htop libgl1-mesa-glx libglib2.0-0 libpython3-dev gnupg g++ libusb-1.0-0 # RUN alias python=python3 +# Remove python3.11/EXTERNALLY-MANAGED or use 'pip install --break-system-packages' avoid 'externally-managed-environment' Ubuntu nightly error +RUN rm -rf /usr/lib/python3.11/EXTERNALLY-MANAGED + # Install pip packages COPY requirements.txt . RUN python3 -m pip install --upgrade pip wheel RUN pip install --no-cache -r requirements.txt albumentations gsutil notebook \ - coremltools onnx onnx-simplifier onnxruntime 'openvino-dev>=2022.3' \ + coremltools onnx onnx-simplifier onnxruntime 'openvino-dev>=2023.0' \ # tensorflow tensorflowjs \ --extra-index-url https://download.pytorch.org/whl/cpu @@ -30,7 +32,6 @@ WORKDIR /usr/src/app # Copy contents # COPY . /usr/src/app (issues as not a .git directory) RUN git clone https://github.com/ultralytics/yolov5 /usr/src/app -ENV DEBIAN_FRONTEND teletype # Usage Examples ------------------------------------------------------------------------------------------------------- diff --git a/downloads/yolov5-master/utils/downloads.py b/downloads/yolov5-master/utils/downloads.py index 629537d5a..9298259d4 100644 --- a/downloads/yolov5-master/utils/downloads.py +++ b/downloads/yolov5-master/utils/downloads.py @@ -4,7 +4,6 @@ Download utils """ import logging -import os import subprocess import urllib from pathlib import Path @@ -53,7 +52,7 @@ def curl_download(url, filename, *, silent: bool = False) -> bool: '--retry', '9', '-C', - '-',]) + '-', ]) return proc.returncode == 0 diff --git a/downloads/yolov5-master/utils/general.py b/downloads/yolov5-master/utils/general.py index e95b07486..135141e21 100644 --- a/downloads/yolov5-master/utils/general.py +++ b/downloads/yolov5-master/utils/general.py @@ -35,7 +35,17 @@ import pkg_resources as pkg import torch import torchvision import yaml -from ultralytics.yolo.utils.checks import check_requirements + +# Import 'ultralytics' package or install if if missing +try: + import ultralytics + + assert hasattr(ultralytics, '__version__') # verify package is not directory +except (ImportError, AssertionError): + os.system('pip install -U ultralytics') + import ultralytics + +from ultralytics.utils.checks import check_requirements from utils import TryExcept, emojis from utils.downloads import curl_download, gsutil_getsize @@ -139,12 +149,12 @@ def set_logging(name=LOGGING_NAME, verbose=True): name: { 'class': 'logging.StreamHandler', 'formatter': name, - 'level': level,}}, + 'level': level, }}, 'loggers': { name: { 'level': level, 'handlers': [name], - 'propagate': False,}}}) + 'propagate': False, }}}) set_logging(LOGGING_NAME) # run before defining LOGGER @@ -371,7 +381,7 @@ def check_git_info(path='.'): return {'remote': None, 'branch': None, 'commit': None} -def check_python(minimum='3.7.0'): +def check_python(minimum='3.8.0'): # Check current python version vs. required python version check_version(platform.python_version(), minimum, name='Python ', hard=True) @@ -416,7 +426,7 @@ def check_imshow(warn=False): return False -def check_suffix(file='yolov5s.pt', suffix=('.pt',), msg=''): +def check_suffix(file='yolov5s.pt', suffix=('.pt', ), msg=''): # Check file(s) for acceptable suffix if file and suffix: if isinstance(suffix, str): diff --git a/downloads/yolov5-master/utils/loggers/__init__.py b/downloads/yolov5-master/utils/loggers/__init__.py index c7c283b72..ba7d2790e 100644 --- a/downloads/yolov5-master/utils/loggers/__init__.py +++ b/downloads/yolov5-master/utils/loggers/__init__.py @@ -46,15 +46,15 @@ except (ImportError, AssertionError): clearml = None try: - if RANK not in [0, -1]: - comet_ml = None - else: + if RANK in {0, -1}: import comet_ml assert hasattr(comet_ml, '__version__') # verify package import not local dir from utils.loggers.comet import CometLogger -except (ModuleNotFoundError, ImportError, AssertionError): + else: + comet_ml = None +except (ImportError, AssertionError): comet_ml = None @@ -88,10 +88,6 @@ class Loggers(): self.csv = True # always log to csv # Messages - if not clearml: - prefix = colorstr('ClearML: ') - s = f"{prefix}run 'pip install clearml' to automatically track, visualize and remotely train YOLOv5 🚀 in ClearML" - self.logger.info(s) if not comet_ml: prefix = colorstr('Comet: ') s = f"{prefix}run 'pip install comet_ml' to automatically track and visualize YOLOv5 🚀 runs in Comet" diff --git a/downloads/yolov5-master/utils/loggers/clearml/clearml_utils.py b/downloads/yolov5-master/utils/loggers/clearml/clearml_utils.py index 2764abe90..4e999bfee 100644 --- a/downloads/yolov5-master/utils/loggers/clearml/clearml_utils.py +++ b/downloads/yolov5-master/utils/loggers/clearml/clearml_utils.py @@ -5,8 +5,7 @@ from pathlib import Path import numpy as np import yaml - -from utils.plots import Annotator, colors +from ultralytics.utils.plotting import Annotator, colors try: import clearml diff --git a/downloads/yolov5-master/utils/loggers/comet/README.md b/downloads/yolov5-master/utils/loggers/comet/README.md index aee8d16a3..3ad52b01b 100644 --- a/downloads/yolov5-master/utils/loggers/comet/README.md +++ b/downloads/yolov5-master/utils/loggers/comet/README.md @@ -59,7 +59,7 @@ Check out an example of a [completed run here](https://www.comet.com/examples/co Or better yet, try it out yourself in this Colab Notebook -[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1RG0WOQyxlDlo5Km8GogJpIEJlg_5lyYO?usp=sharing) +[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/comet-ml/comet-examples/blob/master/integrations/model-training/yolov5/notebooks/Comet_and_YOLOv5.ipynb) # Log automatically diff --git a/downloads/yolov5-master/utils/loggers/comet/__init__.py b/downloads/yolov5-master/utils/loggers/comet/__init__.py index d4599841c..c14a5f885 100644 --- a/downloads/yolov5-master/utils/loggers/comet/__init__.py +++ b/downloads/yolov5-master/utils/loggers/comet/__init__.py @@ -18,7 +18,7 @@ try: # Project Configuration config = comet_ml.config.get_config() COMET_PROJECT_NAME = config.get_string(os.getenv('COMET_PROJECT_NAME'), 'comet.project_name', default='yolov5') -except (ModuleNotFoundError, ImportError): +except ImportError: comet_ml = None COMET_PROJECT_NAME = None @@ -42,7 +42,7 @@ COMET_MODEL_NAME = os.getenv('COMET_MODEL_NAME', 'yolov5') COMET_UPLOAD_DATASET = os.getenv('COMET_UPLOAD_DATASET', 'false').lower() == 'true' # Evaluation Settings -COMET_LOG_CONFUSION_MATRIX = os.getenv('COMET_LOG_CONFUSION_MATRIX', 'true').lower() == 'true' +COMET_LOG_CONFUSION_MATRIX = (os.getenv('COMET_LOG_CONFUSION_MATRIX', 'true').lower() == 'true') COMET_LOG_PREDICTIONS = os.getenv('COMET_LOG_PREDICTIONS', 'true').lower() == 'true' COMET_MAX_IMAGE_UPLOADS = int(os.getenv('COMET_MAX_IMAGE_UPLOADS', 100)) @@ -51,10 +51,10 @@ CONF_THRES = float(os.getenv('CONF_THRES', 0.001)) IOU_THRES = float(os.getenv('IOU_THRES', 0.6)) # Batch Logging Settings -COMET_LOG_BATCH_METRICS = os.getenv('COMET_LOG_BATCH_METRICS', 'false').lower() == 'true' +COMET_LOG_BATCH_METRICS = (os.getenv('COMET_LOG_BATCH_METRICS', 'false').lower() == 'true') COMET_BATCH_LOGGING_INTERVAL = os.getenv('COMET_BATCH_LOGGING_INTERVAL', 1) COMET_PREDICTION_LOGGING_INTERVAL = os.getenv('COMET_PREDICTION_LOGGING_INTERVAL', 1) -COMET_LOG_PER_CLASS_METRICS = os.getenv('COMET_LOG_PER_CLASS_METRICS', 'false').lower() == 'true' +COMET_LOG_PER_CLASS_METRICS = (os.getenv('COMET_LOG_PER_CLASS_METRICS', 'false').lower() == 'true') RANK = int(os.getenv('RANK', -1)) @@ -82,7 +82,7 @@ class CometLogger: self.comet_log_batch_interval = COMET_BATCH_LOGGING_INTERVAL # Dataset Artifact Settings - self.upload_dataset = self.opt.upload_dataset if self.opt.upload_dataset else COMET_UPLOAD_DATASET + self.upload_dataset = self.opt.upload_dataset or COMET_UPLOAD_DATASET self.resume = self.opt.resume # Default parameters to pass to Experiment objects @@ -90,9 +90,10 @@ class CometLogger: 'log_code': False, 'log_env_gpu': True, 'log_env_cpu': True, - 'project_name': COMET_PROJECT_NAME,} + 'project_name': COMET_PROJECT_NAME, } self.default_experiment_kwargs.update(experiment_kwargs) self.experiment = self._get_experiment(self.comet_mode, run_id) + self.experiment.set_name(self.opt.name) self.data_dict = self.check_dataset(self.opt.data) self.class_names = self.data_dict['names'] @@ -136,7 +137,7 @@ class CometLogger: self.comet_log_predictions = COMET_LOG_PREDICTIONS if self.opt.bbox_interval == -1: - self.comet_log_prediction_interval = 1 if self.opt.epochs < 10 else self.opt.epochs // 10 + self.comet_log_prediction_interval = (1 if self.opt.epochs < 10 else self.opt.epochs // 10) else: self.comet_log_prediction_interval = self.opt.bbox_interval @@ -152,7 +153,7 @@ class CometLogger: 'comet_log_per_class_metrics': COMET_LOG_PER_CLASS_METRICS, 'comet_log_batch_metrics': COMET_LOG_BATCH_METRICS, 'comet_log_confusion_matrix': COMET_LOG_CONFUSION_MATRIX, - 'comet_model_name': COMET_MODEL_NAME,}) + 'comet_model_name': COMET_MODEL_NAME, }) # Check if running the Experiment with the Comet Optimizer if hasattr(self.opt, 'comet_optimizer_id'): @@ -169,7 +170,7 @@ class CometLogger: **self.default_experiment_kwargs, ) - return comet_ml.OfflineExperiment(**self.default_experiment_kwargs,) + return comet_ml.OfflineExperiment(**self.default_experiment_kwargs, ) else: try: @@ -213,7 +214,7 @@ class CometLogger: 'fitness_score': fitness_score[-1], 'epochs_trained': epoch + 1, 'save_period': opt.save_period, - 'total_epochs': opt.epochs,} + 'total_epochs': opt.epochs, } model_files = glob.glob(f'{path}/*.pt') for model_path in model_files: @@ -231,7 +232,8 @@ class CometLogger: with open(data_file) as f: data_config = yaml.safe_load(f) - if data_config['path'].startswith(COMET_PREFIX): + path = data_config.get('path') + if path and path.startswith(COMET_PREFIX): path = data_config['path'].replace(COMET_PREFIX, '') data_dict = self.download_dataset_artifact(path) @@ -269,7 +271,7 @@ class CometLogger: 'x': xyxy[0], 'y': xyxy[1], 'x2': xyxy[2], - 'y2': xyxy[3]},}) + 'y2': xyxy[3]}, }) for *xyxy, conf, cls in filtered_detections.tolist(): metadata.append({ 'label': f'{self.class_names[int(cls)]}', @@ -278,7 +280,7 @@ class CometLogger: 'x': xyxy[0], 'y': xyxy[1], 'x2': xyxy[2], - 'y2': xyxy[3]},}) + 'y2': xyxy[3]}, }) self.metadata_dict[image_name] = metadata self.logged_images_count += 1 @@ -312,8 +314,16 @@ class CometLogger: image_logical_path, label_logical_path = map(lambda x: os.path.relpath(x, path), [image_file, label_file]) try: - artifact.add(image_file, logical_path=image_logical_path, metadata={'split': split}) - artifact.add(label_file, logical_path=label_logical_path, metadata={'split': split}) + artifact.add( + image_file, + logical_path=image_logical_path, + metadata={'split': split}, + ) + artifact.add( + label_file, + logical_path=label_logical_path, + metadata={'split': split}, + ) except ValueError as e: logger.error('COMET ERROR: Error adding file to Artifact. Skipping file.') logger.error(f'COMET ERROR: {e}') @@ -355,15 +365,14 @@ class CometLogger: data_dict['path'] = artifact_save_dir metadata_names = metadata.get('names') - if type(metadata_names) == dict: + if isinstance(metadata_names, dict): data_dict['names'] = {int(k): v for k, v in metadata.get('names').items()} - elif type(metadata_names) == list: + elif isinstance(metadata_names, list): data_dict['names'] = {int(k): v for k, v in zip(range(len(metadata_names)), metadata_names)} else: raise "Invalid 'names' field in dataset yaml file. Please use a list or dictionary" - data_dict = self.update_data_paths(data_dict) - return data_dict + return self.update_data_paths(data_dict) def update_data_paths(self, data_dict): path = data_dict.get('path', '') @@ -475,8 +484,9 @@ class CometLogger: 'f1': f1[i], 'true_positives': tp[i], 'false_positives': fp[i], - 'support': nt[c]}, - prefix=class_name) + 'support': nt[c], }, + prefix=class_name, + ) if self.comet_log_confusion_matrix: epoch = self.experiment.curr_epoch diff --git a/downloads/yolov5-master/utils/plots.py b/downloads/yolov5-master/utils/plots.py index d1284b950..db6f94a66 100644 --- a/downloads/yolov5-master/utils/plots.py +++ b/downloads/yolov5-master/utils/plots.py @@ -8,7 +8,6 @@ import math import os from copy import copy from pathlib import Path -from urllib.error import URLError import cv2 import matplotlib @@ -17,13 +16,13 @@ import numpy as np import pandas as pd import seaborn as sn import torch -from PIL import Image, ImageDraw, ImageFont +from PIL import Image, ImageDraw +from scipy.ndimage.filters import gaussian_filter1d +from ultralytics.utils.plotting import Annotator from utils import TryExcept, threaded -from utils.general import (CONFIG_DIR, FONT, LOGGER, check_font, check_requirements, clip_boxes, increment_path, - is_ascii, xywh2xyxy, xyxy2xywh) +from utils.general import LOGGER, clip_boxes, increment_path, xywh2xyxy, xyxy2xywh from utils.metrics import fitness -from utils.segment.general import scale_image # Settings RANK = int(os.getenv('RANK', -1)) @@ -52,120 +51,6 @@ class Colors: colors = Colors() # create instance for 'from utils.plots import colors' -def check_pil_font(font=FONT, size=10): - # Return a PIL TrueType Font, downloading to CONFIG_DIR if necessary - font = Path(font) - font = font if font.exists() else (CONFIG_DIR / font.name) - try: - return ImageFont.truetype(str(font) if font.exists() else font.name, size) - except Exception: # download if missing - try: - check_font(font) - return ImageFont.truetype(str(font), size) - except TypeError: - check_requirements('Pillow>=8.4.0') # known issue https://github.com/ultralytics/yolov5/issues/5374 - except URLError: # not online - return ImageFont.load_default() - - -class Annotator: - # YOLOv5 Annotator for train/val mosaics and jpgs and detect/hub inference annotations - def __init__(self, im, line_width=None, font_size=None, font='Arial.ttf', pil=False, example='abc'): - assert im.data.contiguous, 'Image not contiguous. Apply np.ascontiguousarray(im) to Annotator() input images.' - non_ascii = not is_ascii(example) # non-latin labels, i.e. asian, arabic, cyrillic - self.pil = pil or non_ascii - if self.pil: # use PIL - self.im = im if isinstance(im, Image.Image) else Image.fromarray(im) - self.draw = ImageDraw.Draw(self.im) - self.font = check_pil_font(font='Arial.Unicode.ttf' if non_ascii else font, - size=font_size or max(round(sum(self.im.size) / 2 * 0.035), 12)) - else: # use cv2 - self.im = im - self.lw = line_width or max(round(sum(im.shape) / 2 * 0.003), 2) # line width - - def box_label(self, box, label='', color=(128, 128, 128), txt_color=(255, 255, 255)): - # Add one xyxy box to image with label - if self.pil or not is_ascii(label): - self.draw.rectangle(box, width=self.lw, outline=color) # box - if label: - w, h = self.font.getsize(label) # text width, height (WARNING: deprecated) in 9.2.0 - # _, _, w, h = self.font.getbbox(label) # text width, height (New) - outside = box[1] - h >= 0 # label fits outside box - self.draw.rectangle( - (box[0], box[1] - h if outside else box[1], box[0] + w + 1, - box[1] + 1 if outside else box[1] + h + 1), - fill=color, - ) - # self.draw.text((box[0], box[1]), label, fill=txt_color, font=self.font, anchor='ls') # for PIL>8.0 - self.draw.text((box[0], box[1] - h if outside else box[1]), label, fill=txt_color, font=self.font) - else: # cv2 - p1, p2 = (int(box[0]), int(box[1])), (int(box[2]), int(box[3])) - cv2.rectangle(self.im, p1, p2, color, thickness=self.lw, lineType=cv2.LINE_AA) - if label: - tf = max(self.lw - 1, 1) # font thickness - w, h = cv2.getTextSize(label, 0, fontScale=self.lw / 3, thickness=tf)[0] # text width, height - outside = p1[1] - h >= 3 - p2 = p1[0] + w, p1[1] - h - 3 if outside else p1[1] + h + 3 - cv2.rectangle(self.im, p1, p2, color, -1, cv2.LINE_AA) # filled - cv2.putText(self.im, - label, (p1[0], p1[1] - 2 if outside else p1[1] + h + 2), - 0, - self.lw / 3, - txt_color, - thickness=tf, - lineType=cv2.LINE_AA) - - def masks(self, masks, colors, im_gpu, alpha=0.5, retina_masks=False): - """Plot masks at once. - Args: - masks (tensor): predicted masks on cuda, shape: [n, h, w] - colors (List[List[Int]]): colors for predicted masks, [[r, g, b] * n] - im_gpu (tensor): img is in cuda, shape: [3, h, w], range: [0, 1] - alpha (float): mask transparency: 0.0 fully transparent, 1.0 opaque - """ - if self.pil: - # convert to numpy first - self.im = np.asarray(self.im).copy() - if len(masks) == 0: - self.im[:] = im_gpu.permute(1, 2, 0).contiguous().cpu().numpy() * 255 - colors = torch.tensor(colors, device=im_gpu.device, dtype=torch.float32) / 255.0 - colors = colors[:, None, None] # shape(n,1,1,3) - masks = masks.unsqueeze(3) # shape(n,h,w,1) - masks_color = masks * (colors * alpha) # shape(n,h,w,3) - - inv_alph_masks = (1 - masks * alpha).cumprod(0) # shape(n,h,w,1) - mcs = (masks_color * inv_alph_masks).sum(0) * 2 # mask color summand shape(n,h,w,3) - - im_gpu = im_gpu.flip(dims=[0]) # flip channel - im_gpu = im_gpu.permute(1, 2, 0).contiguous() # shape(h,w,3) - im_gpu = im_gpu * inv_alph_masks[-1] + mcs - im_mask = (im_gpu * 255).byte().cpu().numpy() - self.im[:] = im_mask if retina_masks else scale_image(im_gpu.shape, im_mask, self.im.shape) - if self.pil: - # convert im back to PIL and update draw - self.fromarray(self.im) - - def rectangle(self, xy, fill=None, outline=None, width=1): - # Add rectangle to image (PIL-only) - self.draw.rectangle(xy, fill, outline, width) - - def text(self, xy, text, txt_color=(255, 255, 255), anchor='top'): - # Add text to image (PIL-only) - if anchor == 'bottom': # start y from font bottom - w, h = self.font.getsize(text) # text width, height - xy[1] += 1 - h - self.draw.text(xy, text, fill=txt_color, font=self.font) - - def fromarray(self, im): - # Update self.im from a numpy array - self.im = im if isinstance(im, Image.Image) else Image.fromarray(im) - self.draw = ImageDraw.Draw(self.im) - - def result(self): - # Return annotated image as array - return np.asarray(self.im) - - def feature_visualization(x, module_type, stage, n=32, save_dir=Path('runs/detect/exp')): """ x: Features to be visualized @@ -265,7 +150,7 @@ def plot_images(images, targets, paths=None, fname='images.jpg', names=None): x, y = int(w * (i // ns)), int(h * (i % ns)) # block origin annotator.rectangle([x, y, x + w, y + h], None, (255, 255, 255), width=2) # borders if paths: - annotator.text((x + 5, y + 5), text=Path(paths[i]).name[:40], txt_color=(220, 220, 220)) # filenames + annotator.text([x + 5, y + 5], text=Path(paths[i]).name[:40], txt_color=(220, 220, 220)) # filenames if len(targets) > 0: ti = targets[targets[:, 0] == i] # image targets boxes = xywh2xyxy(ti[:, 2:6]).T @@ -500,7 +385,8 @@ def plot_results(file='path/to/results.csv', dir=''): for i, j in enumerate([1, 2, 3, 4, 5, 8, 9, 10, 6, 7]): y = data.values[:, j].astype('float') # y[y == 0] = np.nan # don't show zero values - ax[i].plot(x, y, marker='.', label=f.stem, linewidth=2, markersize=8) + ax[i].plot(x, y, marker='.', label=f.stem, linewidth=2, markersize=8) # actual results + ax[i].plot(x, gaussian_filter1d(y, sigma=3), ':', label='smooth', linewidth=2) # smoothing line ax[i].set_title(s[j], fontsize=12) # if j in [8, 9, 10]: # share train and val loss y axes # ax[i].get_shared_y_axes().join(ax[i], ax[i - 5]) diff --git a/downloads/yolov5-master/utils/segment/metrics.py b/downloads/yolov5-master/utils/segment/metrics.py index 6020fa062..787961bee 100644 --- a/downloads/yolov5-master/utils/segment/metrics.py +++ b/downloads/yolov5-master/utils/segment/metrics.py @@ -196,7 +196,7 @@ KEYS = [ 'val/cls_loss', 'x/lr0', 'x/lr1', - 'x/lr2',] + 'x/lr2', ] BEST_KEYS = [ 'best/epoch', @@ -207,4 +207,4 @@ BEST_KEYS = [ 'best/precision(M)', 'best/recall(M)', 'best/mAP_0.5(M)', - 'best/mAP_0.5:0.95(M)',] + 'best/mAP_0.5:0.95(M)', ] diff --git a/downloads/yolov5-master/utils/segment/plots.py b/downloads/yolov5-master/utils/segment/plots.py index 1b22ec838..f9938cd1b 100644 --- a/downloads/yolov5-master/utils/segment/plots.py +++ b/downloads/yolov5-master/utils/segment/plots.py @@ -54,7 +54,7 @@ def plot_images_and_masks(images, targets, masks, paths=None, fname='images.jpg' x, y = int(w * (i // ns)), int(h * (i % ns)) # block origin annotator.rectangle([x, y, x + w, y + h], None, (255, 255, 255), width=2) # borders if paths: - annotator.text((x + 5, y + 5), text=Path(paths[i]).name[:40], txt_color=(220, 220, 220)) # filenames + annotator.text([x + 5, y + 5], text=Path(paths[i]).name[:40], txt_color=(220, 220, 220)) # filenames if len(targets) > 0: idx = targets[:, 0] == i ti = targets[idx] # image targets diff --git a/downloads/yolov5-master/utils/torch_utils.py b/downloads/yolov5-master/utils/torch_utils.py index d9e060ab9..13a356f32 100644 --- a/downloads/yolov5-master/utils/torch_utils.py +++ b/downloads/yolov5-master/utils/torch_utils.py @@ -170,7 +170,7 @@ def profile(input, ops, n=10, device=None): m = m.half() if hasattr(m, 'half') and isinstance(x, torch.Tensor) and x.dtype is torch.float16 else m tf, tb, t = 0, 0, [0, 0, 0] # dt forward, backward try: - flops = thop.profile(m, inputs=(x,), verbose=False)[0] / 1E9 * 2 # GFLOPs + flops = thop.profile(m, inputs=(x, ), verbose=False)[0] / 1E9 * 2 # GFLOPs except Exception: flops = 0 @@ -284,7 +284,7 @@ def model_info(model, verbose=False, imgsz=640): p = next(model.parameters()) stride = max(int(model.stride.max()), 32) if hasattr(model, 'stride') else 32 # max stride im = torch.empty((1, p.shape[1], stride, stride), device=p.device) # input image in BCHW format - flops = thop.profile(deepcopy(model), inputs=(im,), verbose=False)[0] / 1E9 * 2 # stride GFLOPs + flops = thop.profile(deepcopy(model), inputs=(im, ), verbose=False)[0] / 1E9 * 2 # stride GFLOPs imgsz = imgsz if isinstance(imgsz, list) else [imgsz, imgsz] # expand if int/float fs = f', {flops * imgsz[0] / stride * imgsz[1] / stride:.1f} GFLOPs' # 640x640 GFLOPs except Exception: diff --git a/downloads/yolov5-master/val.py b/downloads/yolov5-master/val.py index 71268651d..8da3ef766 100644 --- a/downloads/yolov5-master/val.py +++ b/downloads/yolov5-master/val.py @@ -304,6 +304,8 @@ def run( if save_json and len(jdict): w = Path(weights[0] if isinstance(weights, list) else weights).stem if weights is not None else '' # weights anno_json = str(Path('../datasets/coco/annotations/instances_val2017.json')) # annotations + if not os.path.exists(anno_json): + anno_json = os.path.join(data['path'], 'annotations', 'instances_val2017.json') pred_json = str(save_dir / f'{w}_predictions.json') # predictions LOGGER.info(f'\nEvaluating pycocotools mAP... saving {pred_json}...') with open(pred_json, 'w') as f: diff --git a/downloads/yolov5.zip b/downloads/yolov5.zip index b73fa5ba5..350481241 100644 Binary files a/downloads/yolov5.zip and b/downloads/yolov5.zip differ diff --git a/downloads/yolov8.zip b/downloads/yolov8.zip index 1d15d39a3..55d78db8b 100644 Binary files a/downloads/yolov8.zip and b/downloads/yolov8.zip differ diff --git a/sbin/ctl.sh b/sbin/ctl.sh index 798ef65f3..a1ca8b0ac 100755 --- a/sbin/ctl.sh +++ b/sbin/ctl.sh @@ -33,7 +33,7 @@ cd $DIR/.. # Read in UKDI and determine basic PATHs etc function f_read_ukdi(){ cat /etc/ukdi.json |\ - tr -d '",'|\ + tr -d '"'| sed 's/,$//'|\ awk '{ if (NF>1){print "export UKDI_"$1"=\""$2"\"" } }' |\ sed 's/://' > var/gen.ukdi chmod +x var/gen.ukdi @@ -62,24 +62,37 @@ ZZZ=5 # Determina all the possible libs based on whats in UKDI_yolo_devices LIB_OPENVINO="modules/openvino/inference_engine" PYP_OPENVINO="modules/openvino" -PYP_PARAVISION="modules/paravision" +PYP_PARAVISION="modules" +PYP_YOLOV5="modules/yolov5-face_Jan1" # WHich libs are loaded depends on the YOLO device list -LLP="" -PYP="" -for i in `echo $UKDI_yolo_devices | tr ',' ' ' ` +LLP="." +PYP="." +echo "UKDI_yolo_devices = $UKDI_yolo_devices" +for i in `echo $UKDI_yolo_devices| tr ',' ' '` do case $i in "paravision") LLP="$LLP:$LIB_OPENVINO" PYP="$PYP:$PYP_PARAVISION" ;; + "yolov5") LLP="$LLP:$LIB_OPENVINO" + PYP="$PYP:$PYP_YOLOV5" + ;; esac done +echo "PYTHONPATH = $PYP" export LD_LIBRARY_PATH="$LLP" export PYTHONPATH="$PYP" export WEIGHTS="$DIR/../modules/yolov5-face_Jan1/runs/train/exp/weights/yolov5m6_face.pt" + # # # #### ##### ## # # + # ## # # # # # # # + # # # # #### # # # # # + # # # # # # ###### # # + # # ## # # # # # # # + # # # #### # # # ###### ###### + # Install all the components. # There are many of them and they are all different. # Some are proprietary, so check your licensing (ask Matt) @@ -97,15 +110,14 @@ function f_apt(){ ;; "yolov8") f_apt_yolov8 ;; - "paravision") f_apt_paravision + "paravision") f_apt_openvino + f_apt_paravision + ;; + "openvino") f_apt_openvino ;; "deepface") pip3 install deepface ;; - "freeface") f_apt_facerec - ;; - "paraface") f_apt_regula - f_apt_yolov5 - f_apt_paravision + "facerec") f_apt_facerec ;; "intox") f_apt_yolov5 f_apt_intox @@ -115,6 +127,7 @@ function f_apt(){ esac } + function f_apt_regula(){ apt install pcscd libccid wget -O downloads/regula.deb https://downloads.regulaforensics.com/repo/ubuntu/pool/stable/r/regula-reader/regula-reader_6.7.198393.16246_amd64.deb @@ -164,6 +177,16 @@ function f_apt_intox(){ make -f sbin/Makefile } + + + + #### #### # # ##### ##### #### # + # # # # ## # # # # # # # + # # # # # # # # # # # # + # # # # # # # ##### # # # + # # # # # ## # # # # # # + #### #### # # # # # #### ###### + function f_test(){ wget http://localhost:$PORT/process/ }