{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "9a67092a",
   "metadata": {},
   "source": [
    "# Training notebook"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4dfbc71a-a78d-4ebb-ab77-276dab5821c9",
   "metadata": {},
   "source": [
    "## Please install the requirements\n",
    "(if you don't have them already)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "20c8a661575d1c6f",
   "metadata": {
    "ExecuteTime": {
     "start_time": "2024-05-25T09:03:54.172573Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: torchvision in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (0.18.0)\n",
      "Requirement already satisfied: numpy in /home/vlad/.local/lib/python3.10/site-packages (from torchvision) (1.23.5)\n",
      "Requirement already satisfied: torch==2.3.0 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torchvision) (2.3.0)\n",
      "Requirement already satisfied: pillow!=8.3.*,>=5.3.0 in /home/vlad/.local/lib/python3.10/site-packages (from torchvision) (9.5.0)\n",
      "Requirement already satisfied: filelock in /home/vlad/.local/lib/python3.10/site-packages (from torch==2.3.0->torchvision) (3.12.2)\n",
      "Requirement already satisfied: typing-extensions>=4.8.0 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch==2.3.0->torchvision) (4.11.0)\n",
      "Requirement already satisfied: sympy in /home/vlad/.local/lib/python3.10/site-packages (from torch==2.3.0->torchvision) (1.12)\n",
      "Requirement already satisfied: networkx in /home/vlad/.local/lib/python3.10/site-packages (from torch==2.3.0->torchvision) (3.1)\n",
      "Requirement already satisfied: jinja2 in /home/vlad/.local/lib/python3.10/site-packages (from torch==2.3.0->torchvision) (3.1.2)\n",
      "Requirement already satisfied: fsspec in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch==2.3.0->torchvision) (2024.5.0)\n",
      "Requirement already satisfied: nvidia-cuda-nvrtc-cu12==12.1.105 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch==2.3.0->torchvision) (12.1.105)\n",
      "Requirement already satisfied: nvidia-cuda-runtime-cu12==12.1.105 in /home/vlad/.local/lib/python3.10/site-packages (from torch==2.3.0->torchvision) (12.1.105)\n",
      "Requirement already satisfied: nvidia-cuda-cupti-cu12==12.1.105 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch==2.3.0->torchvision) (12.1.105)\n",
      "Requirement already satisfied: nvidia-cudnn-cu12==8.9.2.26 in /home/vlad/.local/lib/python3.10/site-packages (from torch==2.3.0->torchvision) (8.9.2.26)\n",
      "Requirement already satisfied: nvidia-cublas-cu12==12.1.3.1 in /home/vlad/.local/lib/python3.10/site-packages (from torch==2.3.0->torchvision) (12.1.3.1)\n",
      "Requirement already satisfied: nvidia-cufft-cu12==11.0.2.54 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch==2.3.0->torchvision) (11.0.2.54)\n",
      "Requirement already satisfied: nvidia-curand-cu12==10.3.2.106 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch==2.3.0->torchvision) (10.3.2.106)\n",
      "Requirement already satisfied: nvidia-cusolver-cu12==11.4.5.107 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch==2.3.0->torchvision) (11.4.5.107)\n",
      "Requirement already satisfied: nvidia-cusparse-cu12==12.1.0.106 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch==2.3.0->torchvision) (12.1.0.106)\n",
      "Requirement already satisfied: nvidia-nccl-cu12==2.20.5 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch==2.3.0->torchvision) (2.20.5)\n",
      "Requirement already satisfied: nvidia-nvtx-cu12==12.1.105 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch==2.3.0->torchvision) (12.1.105)\n",
      "Requirement already satisfied: triton==2.3.0 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch==2.3.0->torchvision) (2.3.0)\n",
      "Requirement already satisfied: nvidia-nvjitlink-cu12 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from nvidia-cusolver-cu12==11.4.5.107->torch==2.3.0->torchvision) (12.4.127)\n",
      "Requirement already satisfied: MarkupSafe>=2.0 in /home/vlad/.local/lib/python3.10/site-packages (from jinja2->torch==2.3.0->torchvision) (2.1.3)\n",
      "Requirement already satisfied: mpmath>=0.19 in /home/vlad/.local/lib/python3.10/site-packages (from sympy->torch==2.3.0->torchvision) (1.3.0)\n",
      "\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.0\u001b[0m\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
      "Note: you may need to restart the kernel to use updated packages.\n",
      "Requirement already satisfied: torch in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (2.3.0)\n",
      "Requirement already satisfied: torchvision in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (0.18.0)\n",
      "Requirement already satisfied: filelock in /home/vlad/.local/lib/python3.10/site-packages (from torch) (3.12.2)\n",
      "Requirement already satisfied: typing-extensions>=4.8.0 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch) (4.11.0)\n",
      "Requirement already satisfied: sympy in /home/vlad/.local/lib/python3.10/site-packages (from torch) (1.12)\n",
      "Requirement already satisfied: networkx in /home/vlad/.local/lib/python3.10/site-packages (from torch) (3.1)\n",
      "Requirement already satisfied: jinja2 in /home/vlad/.local/lib/python3.10/site-packages (from torch) (3.1.2)\n",
      "Requirement already satisfied: fsspec in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch) (2024.5.0)\n",
      "Requirement already satisfied: nvidia-cuda-nvrtc-cu12==12.1.105 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch) (12.1.105)\n",
      "Requirement already satisfied: nvidia-cuda-runtime-cu12==12.1.105 in /home/vlad/.local/lib/python3.10/site-packages (from torch) (12.1.105)\n",
      "Requirement already satisfied: nvidia-cuda-cupti-cu12==12.1.105 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch) (12.1.105)\n",
      "Requirement already satisfied: nvidia-cudnn-cu12==8.9.2.26 in /home/vlad/.local/lib/python3.10/site-packages (from torch) (8.9.2.26)\n",
      "Requirement already satisfied: nvidia-cublas-cu12==12.1.3.1 in /home/vlad/.local/lib/python3.10/site-packages (from torch) (12.1.3.1)\n",
      "Requirement already satisfied: nvidia-cufft-cu12==11.0.2.54 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch) (11.0.2.54)\n",
      "Requirement already satisfied: nvidia-curand-cu12==10.3.2.106 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch) (10.3.2.106)\n",
      "Requirement already satisfied: nvidia-cusolver-cu12==11.4.5.107 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch) (11.4.5.107)\n",
      "Requirement already satisfied: nvidia-cusparse-cu12==12.1.0.106 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch) (12.1.0.106)\n",
      "Requirement already satisfied: nvidia-nccl-cu12==2.20.5 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch) (2.20.5)\n",
      "Requirement already satisfied: nvidia-nvtx-cu12==12.1.105 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch) (12.1.105)\n",
      "Requirement already satisfied: triton==2.3.0 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch) (2.3.0)\n",
      "Requirement already satisfied: nvidia-nvjitlink-cu12 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from nvidia-cusolver-cu12==11.4.5.107->torch) (12.4.127)\n",
      "Requirement already satisfied: numpy in /home/vlad/.local/lib/python3.10/site-packages (from torchvision) (1.23.5)\n",
      "Requirement already satisfied: pillow!=8.3.*,>=5.3.0 in /home/vlad/.local/lib/python3.10/site-packages (from torchvision) (9.5.0)\n",
      "Requirement already satisfied: MarkupSafe>=2.0 in /home/vlad/.local/lib/python3.10/site-packages (from jinja2->torch) (2.1.3)\n",
      "Requirement already satisfied: mpmath>=0.19 in /home/vlad/.local/lib/python3.10/site-packages (from sympy->torch) (1.3.0)\n",
      "\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.0\u001b[0m\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
      "Note: you may need to restart the kernel to use updated packages.\n",
      "Requirement already satisfied: ultralytics in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (8.2.21)\n",
      "Collecting ultralytics\n",
      "  Obtaining dependency information for ultralytics from https://files.pythonhosted.org/packages/d4/6c/e9c1b34e258cca32528867b67ee75704c19b96153234745a6fa41488b209/ultralytics-8.2.25-py3-none-any.whl.metadata\n",
      "  Downloading ultralytics-8.2.25-py3-none-any.whl.metadata (41 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m41.2/41.2 kB\u001b[0m \u001b[31m943.0 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: matplotlib>=3.3.0 in /home/vlad/.local/lib/python3.10/site-packages (from ultralytics) (3.7.1)\n",
      "Requirement already satisfied: opencv-python>=4.6.0 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from ultralytics) (4.9.0.80)\n",
      "Requirement already satisfied: pillow>=7.1.2 in /home/vlad/.local/lib/python3.10/site-packages (from ultralytics) (9.5.0)\n",
      "Requirement already satisfied: pyyaml>=5.3.1 in /home/vlad/.local/lib/python3.10/site-packages (from ultralytics) (6.0)\n",
      "Requirement already satisfied: requests>=2.23.0 in /home/vlad/.local/lib/python3.10/site-packages (from ultralytics) (2.31.0)\n",
      "Requirement already satisfied: scipy>=1.4.1 in /home/vlad/.local/lib/python3.10/site-packages (from ultralytics) (1.10.1)\n",
      "Requirement already satisfied: torch>=1.8.0 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from ultralytics) (2.3.0)\n",
      "Requirement already satisfied: torchvision>=0.9.0 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from ultralytics) (0.18.0)\n",
      "Requirement already satisfied: tqdm>=4.64.0 in /home/vlad/.local/lib/python3.10/site-packages (from ultralytics) (4.65.0)\n",
      "Requirement already satisfied: psutil in /home/vlad/.local/lib/python3.10/site-packages (from ultralytics) (5.9.5)\n",
      "Requirement already satisfied: py-cpuinfo in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from ultralytics) (9.0.0)\n",
      "Requirement already satisfied: thop>=0.1.1 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from ultralytics) (0.1.1.post2209072238)\n",
      "Requirement already satisfied: pandas>=1.1.4 in /home/vlad/.local/lib/python3.10/site-packages (from ultralytics) (2.0.2)\n",
      "Requirement already satisfied: seaborn>=0.11.0 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from ultralytics) (0.13.2)\n",
      "Requirement already satisfied: contourpy>=1.0.1 in /home/vlad/.local/lib/python3.10/site-packages (from matplotlib>=3.3.0->ultralytics) (1.1.0)\n",
      "Requirement already satisfied: cycler>=0.10 in /home/vlad/.local/lib/python3.10/site-packages (from matplotlib>=3.3.0->ultralytics) (0.11.0)\n",
      "Requirement already satisfied: fonttools>=4.22.0 in /home/vlad/.local/lib/python3.10/site-packages (from matplotlib>=3.3.0->ultralytics) (4.40.0)\n",
      "Requirement already satisfied: kiwisolver>=1.0.1 in /home/vlad/.local/lib/python3.10/site-packages (from matplotlib>=3.3.0->ultralytics) (1.4.4)\n",
      "Requirement already satisfied: numpy>=1.20 in /home/vlad/.local/lib/python3.10/site-packages (from matplotlib>=3.3.0->ultralytics) (1.23.5)\n",
      "Requirement already satisfied: packaging>=20.0 in /home/vlad/.local/lib/python3.10/site-packages (from matplotlib>=3.3.0->ultralytics) (23.1)\n",
      "Requirement already satisfied: pyparsing>=2.3.1 in /home/vlad/.local/lib/python3.10/site-packages (from matplotlib>=3.3.0->ultralytics) (3.1.0)\n",
      "Requirement already satisfied: python-dateutil>=2.7 in /home/vlad/.local/lib/python3.10/site-packages (from matplotlib>=3.3.0->ultralytics) (2.8.2)\n",
      "Requirement already satisfied: pytz>=2020.1 in /home/vlad/.local/lib/python3.10/site-packages (from pandas>=1.1.4->ultralytics) (2023.3)\n",
      "Requirement already satisfied: tzdata>=2022.1 in /home/vlad/.local/lib/python3.10/site-packages (from pandas>=1.1.4->ultralytics) (2023.3)\n",
      "Requirement already satisfied: charset-normalizer<4,>=2 in /home/vlad/.local/lib/python3.10/site-packages (from requests>=2.23.0->ultralytics) (2.0.12)\n",
      "Requirement already satisfied: idna<4,>=2.5 in /home/vlad/.local/lib/python3.10/site-packages (from requests>=2.23.0->ultralytics) (3.4)\n",
      "Requirement already satisfied: urllib3<3,>=1.21.1 in /home/vlad/.local/lib/python3.10/site-packages (from requests>=2.23.0->ultralytics) (1.26.16)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in /home/vlad/.local/lib/python3.10/site-packages (from requests>=2.23.0->ultralytics) (2023.5.7)\n",
      "Requirement already satisfied: filelock in /home/vlad/.local/lib/python3.10/site-packages (from torch>=1.8.0->ultralytics) (3.12.2)\n",
      "Requirement already satisfied: typing-extensions>=4.8.0 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch>=1.8.0->ultralytics) (4.11.0)\n",
      "Requirement already satisfied: sympy in /home/vlad/.local/lib/python3.10/site-packages (from torch>=1.8.0->ultralytics) (1.12)\n",
      "Requirement already satisfied: networkx in /home/vlad/.local/lib/python3.10/site-packages (from torch>=1.8.0->ultralytics) (3.1)\n",
      "Requirement already satisfied: jinja2 in /home/vlad/.local/lib/python3.10/site-packages (from torch>=1.8.0->ultralytics) (3.1.2)\n",
      "Requirement already satisfied: fsspec in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch>=1.8.0->ultralytics) (2024.5.0)\n",
      "Requirement already satisfied: nvidia-cuda-nvrtc-cu12==12.1.105 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch>=1.8.0->ultralytics) (12.1.105)\n",
      "Requirement already satisfied: nvidia-cuda-runtime-cu12==12.1.105 in /home/vlad/.local/lib/python3.10/site-packages (from torch>=1.8.0->ultralytics) (12.1.105)\n",
      "Requirement already satisfied: nvidia-cuda-cupti-cu12==12.1.105 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch>=1.8.0->ultralytics) (12.1.105)\n",
      "Requirement already satisfied: nvidia-cudnn-cu12==8.9.2.26 in /home/vlad/.local/lib/python3.10/site-packages (from torch>=1.8.0->ultralytics) (8.9.2.26)\n",
      "Requirement already satisfied: nvidia-cublas-cu12==12.1.3.1 in /home/vlad/.local/lib/python3.10/site-packages (from torch>=1.8.0->ultralytics) (12.1.3.1)\n",
      "Requirement already satisfied: nvidia-cufft-cu12==11.0.2.54 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch>=1.8.0->ultralytics) (11.0.2.54)\n",
      "Requirement already satisfied: nvidia-curand-cu12==10.3.2.106 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch>=1.8.0->ultralytics) (10.3.2.106)\n",
      "Requirement already satisfied: nvidia-cusolver-cu12==11.4.5.107 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch>=1.8.0->ultralytics) (11.4.5.107)\n",
      "Requirement already satisfied: nvidia-cusparse-cu12==12.1.0.106 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch>=1.8.0->ultralytics) (12.1.0.106)\n",
      "Requirement already satisfied: nvidia-nccl-cu12==2.20.5 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch>=1.8.0->ultralytics) (2.20.5)\n",
      "Requirement already satisfied: nvidia-nvtx-cu12==12.1.105 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch>=1.8.0->ultralytics) (12.1.105)\n",
      "Requirement already satisfied: triton==2.3.0 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from torch>=1.8.0->ultralytics) (2.3.0)\n",
      "Requirement already satisfied: nvidia-nvjitlink-cu12 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from nvidia-cusolver-cu12==11.4.5.107->torch>=1.8.0->ultralytics) (12.4.127)\n",
      "Requirement already satisfied: six>=1.5 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from python-dateutil>=2.7->matplotlib>=3.3.0->ultralytics) (1.16.0)\n",
      "Requirement already satisfied: MarkupSafe>=2.0 in /home/vlad/.local/lib/python3.10/site-packages (from jinja2->torch>=1.8.0->ultralytics) (2.1.3)\n",
      "Requirement already satisfied: mpmath>=0.19 in /home/vlad/.local/lib/python3.10/site-packages (from sympy->torch>=1.8.0->ultralytics) (1.3.0)\n",
      "Downloading ultralytics-8.2.25-py3-none-any.whl (778 kB)\n",
      "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m778.8/778.8 kB\u001b[0m \u001b[31m4.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n",
      "\u001b[?25hInstalling collected packages: ultralytics\n",
      "  Attempting uninstall: ultralytics\n",
      "    Found existing installation: ultralytics 8.2.21\n",
      "    Uninstalling ultralytics-8.2.21:\n",
      "      Successfully uninstalled ultralytics-8.2.21\n",
      "Successfully installed ultralytics-8.2.25\n",
      "\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.0\u001b[0m\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
      "Note: you may need to restart the kernel to use updated packages.\n",
      "Requirement already satisfied: pillow_heif in /home/vlad/.local/lib/python3.10/site-packages (0.16.0)\n",
      "Requirement already satisfied: pillow>=9.5.0 in /home/vlad/.local/lib/python3.10/site-packages (from pillow_heif) (9.5.0)\n",
      "\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.0\u001b[0m\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
      "Note: you may need to restart the kernel to use updated packages.\n",
      "Requirement already satisfied: plotly in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (5.22.0)\n",
      "Requirement already satisfied: tenacity>=6.2.0 in /home/vlad/miniconda3/envs/tf/lib/python3.10/site-packages (from plotly) (8.3.0)\n",
      "Requirement already satisfied: packaging in /home/vlad/.local/lib/python3.10/site-packages (from plotly) (23.1)\n",
      "\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.0\u001b[0m\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
      "Note: you may need to restart the kernel to use updated packages.\n",
      "Requirement already satisfied: Pillow in /home/vlad/.local/lib/python3.10/site-packages (9.5.0)\n",
      "\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.0\u001b[0m\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
      "Note: you may need to restart the kernel to use updated packages.\n",
      "Requirement already satisfied: tqdm in /home/vlad/.local/lib/python3.10/site-packages (4.65.0)\n",
      "\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.0\u001b[0m\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
      "Note: you may need to restart the kernel to use updated packages.\n",
      "Requirement already satisfied: ruamel.yaml in /home/vlad/.local/lib/python3.10/site-packages (0.17.32)\n",
      "Requirement already satisfied: ruamel.yaml.clib>=0.2.7 in /home/vlad/.local/lib/python3.10/site-packages (from ruamel.yaml) (0.2.7)\n",
      "\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.2.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.0\u001b[0m\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
      "Note: you may need to restart the kernel to use updated packages.\n"
     ]
    }
   ],
   "source": [
    "%pip install torchvision\n",
    "%pip install torch torchvision\n",
    "%pip install --upgrade ultralytics\n",
    "%pip install pillow_heif\n",
    "%pip install plotly\n",
    "%pip install Pillow\n",
    "%pip install tqdm\n",
    "%pip install ruamel.yaml"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "45105e3c6e3463b4",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-27T16:21:01.379912Z",
     "start_time": "2024-05-27T16:21:00.743540Z"
    }
   },
   "outputs": [],
   "source": [
    "import os  # for file operations\n",
    "import json  # for loading the annotations file\n",
    "from PIL import Image, ImageDraw, ImageOps, ImageEnhance  # for processing the image data\n",
    "import numpy as np\n",
    "from random import shuffle\n",
    "import nvidia.cudnn\n",
    "import torch\n",
    "from pillow_heif import register_heif_opener\n",
    "\n",
    "os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"1\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a9af0815fbb0b5f3",
   "metadata": {},
   "source": [
    "## Constants"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "3af63db86b518835",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-27T16:21:01.390931Z",
     "start_time": "2024-05-27T16:21:01.388577Z"
    }
   },
   "outputs": [],
   "source": [
    "DATA_PATH = \"./data/\"  # must contain multiple subdirectories - one for each class\n",
    "ANNOTATIONS_PATH = \"./via-annotations.json\"  # relative to the notebook\n",
    "YOLO_CONFIG_PATH = \"yolo.yaml\"\n",
    "\n",
    "BATCH_SIZE = 8\n",
    "\n",
    "CLASS_NAMES = sorted(list(set([os.path.basename(f).split(\",\")[0] for f in os.scandir(DATA_PATH) if f.is_dir()])))  # automatically generated\n",
    "ALL_CLASS_NAMES = sorted(list(set([os.path.basename(f) for f in os.scandir(DATA_PATH) if f.is_dir()])))\n",
    "CLASS_COUNT = len(CLASS_NAMES)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a2e58dbd6685dbb4",
   "metadata": {},
   "source": [
    "## Data size chart (treemap)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "bfdbbe283d63cffc",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-25T09:29:25.048415Z",
     "start_time": "2024-05-25T09:29:24.848381Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<iframe\n",
       "    scrolling=\"no\"\n",
       "    width=\"2420px\"\n",
       "    height=\"1220\"\n",
       "    src=\"iframe_figures/figure_6.html\"\n",
       "    frameborder=\"0\"\n",
       "    allowfullscreen\n",
       "></iframe>\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import os\n",
    "import collections\n",
    "import plotly.express as px\n",
    "import plotly.io as pio\n",
    "import pandas as pd\n",
    "\n",
    "pio.renderers.default = \"iframe\"\n",
    "\n",
    "subcategories = collections.defaultdict(list)\n",
    "\n",
    "for klass in ALL_CLASS_NAMES:\n",
    "    main, _, sub = klass.partition(\", \")\n",
    "    file_count = len(os.listdir(os.path.join(DATA_PATH, klass)))  # count files in each subcategory directory\n",
    "    subcategories[main].append((sub, file_count))\n",
    "\n",
    "categories = []\n",
    "subcategories_list = []\n",
    "values = []\n",
    "\n",
    "for main, subs in subcategories.items():\n",
    "    for sub, count in subs:\n",
    "        categories.append(main)\n",
    "        subcategories_list.append(sub)\n",
    "        values.append(count)\n",
    "\n",
    "df = pd.DataFrame({\n",
    "    \"Category\": categories,\n",
    "    \"Subcategory\": subcategories_list,\n",
    "    \"Number of samples\": values\n",
    "})\n",
    "\n",
    "fig = px.treemap(\n",
    "    df,\n",
    "    path=[px.Constant(\"data\"), \"Category\", \"Subcategory\"],\n",
    "    values=\"Number of samples\",\n",
    "    title=\"Treemap of classes\"\n",
    ")\n",
    "\n",
    "# The palette (from Google)\n",
    "material_colours_hex = [\n",
    "    \"#009688\",  # Teal\n",
    "    \"#4CAF50\",  # Green\n",
    "    \"#8BC34A\",  # Light Green\n",
    "    \"#CDDC39\",  # Lime\n",
    "    \"#FFEB3B\",  # Yellow\n",
    "    \"#FFC107\",  # Amber\n",
    "    \"#FF9800\",  # Orange\n",
    "    \"#FF5722\",  # Deep Orange\n",
    "    \"#F44336\",  # Red\n",
    "    \"#E91E63\",  # Pink\n",
    "    \"#9C27B0\",  # Purple\n",
    "    \"#673AB7\",  # Deep Purple\n",
    "    \"#3F51B5\",  # Indigo\n",
    "    \"#2196F3\",  # Blue\n",
    "    \"#03A9F4\",  # Light Blue\n",
    "    \"#00BCD4\",  # Cyan\n",
    "    \"#795548\",  # Brown\n",
    "    \"#9E9E9E\",  # Grey\n",
    "    \"#607D8B\",  # Blue Grey\n",
    "]\n",
    "\n",
    "\n",
    "fig.update_layout(\n",
    "        width=2400, height=1200,\n",
    "        treemapcolorway=material_colours_hex\n",
    ")\n",
    "\n",
    "fig.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "67ae3a36e7fbb2cc",
   "metadata": {},
   "source": [
    "## Data augmentation and conversion to YOLO format\n",
    "We convert the data from the VGG Image Annotator format to the format used in the YOLO pipeline.\n",
    "\n",
    "Data augmentation is also performed to increase the diversity of the dataset.\n",
    "* Random rotation and flipping\n",
    "* Random brightness\n",
    "* Random contrast\n",
    "* Random sharpness\n",
    "* Random colour\n",
    "* Random RGB deviation\n",
    "* Salt and pepper noise\n",
    "* JPEG compression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "cdc4e80fe5566372",
   "metadata": {
    "ExecuteTime": {
     "start_time": "2024-05-28T09:25:56.416150Z"
    },
    "jupyter": {
     "is_executing": true
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|█████████████████████████████████████████████████████████████████████████████████████| 11191/11191 [02:30<00:00, 74.19it/s]\n"
     ]
    }
   ],
   "source": [
    "import json\n",
    "import os\n",
    "import shutil\n",
    "import random\n",
    "import math\n",
    "from PIL import Image, UnidentifiedImageError, ImageEnhance, ImageOps\n",
    "from tqdm import tqdm\n",
    "\n",
    "register_heif_opener()\n",
    "\n",
    "def rotate_point(point, origin, angle):\n",
    "    # Fast calculation for 90 degree rotations\n",
    "    match angle % 360:\n",
    "        case 0:\n",
    "            return point\n",
    "        case 90:\n",
    "            return origin[1] + origin[0] - point[1], origin[1] - origin[0] + point[0]\n",
    "        case 180:\n",
    "            return 2 * origin[0] - point[0], 2 * origin[1] - point[1]\n",
    "        case 270:\n",
    "            return origin[1] - origin[0] + point[1], origin[1] + origin[0] - point[0]\n",
    "    \n",
    "    # Otherwise do math\n",
    "    angle_rad = math.radians(angle)\n",
    "    ox, oy = origin\n",
    "    px, py = point\n",
    "    \n",
    "    qx = ox + math.cos(angle_rad) * (px - ox) - math.sin(angle_rad) * (py - oy)\n",
    "    qy = oy + math.sin(angle_rad) * (px - ox) + math.cos(angle_rad) * (py - oy)\n",
    "    \n",
    "    return qx, qy\n",
    "\n",
    "def save_photos(via_annotations_path, images_directory, output_directory, num_augmented_copies=3, save_quality=80):\n",
    "    annotated_images = 0\n",
    "    \n",
    "    if os.path.exists(output_directory):\n",
    "        shutil.rmtree(output_directory)\n",
    "    os.makedirs(output_directory)\n",
    "\n",
    "    with open(via_annotations_path, 'r') as f:\n",
    "        data = json.load(f)\n",
    "        \n",
    "    rotation_angles = [0, 90, 180, 270]\n",
    "\n",
    "    class_mapping = {}\n",
    "\n",
    "    for image_id, image_data in tqdm(data[\"_via_img_metadata\"].items()):\n",
    "        filename = image_data[\"filename\"]\n",
    "        image_path = os.path.normpath(os.path.join(images_directory, filename))\n",
    "        try:\n",
    "            image = Image.open(image_path)\n",
    "        except (UnidentifiedImageError, IOError):\n",
    "            continue        # skip non-image or missing files\n",
    "\n",
    "        image.verify()      # verify that it is, indeed, an image\n",
    "        image.close()\n",
    "\n",
    "        image = Image.open(image_path)\n",
    "        w, h = image.size\n",
    "        cx, cy = w / 2, h / 2\n",
    "\n",
    "        class_name = os.path.basename(os.path.dirname(image_path)).split(\",\")[0]\n",
    "        if class_name not in class_mapping:\n",
    "            # Add new classes when encountered\n",
    "            class_mapping[class_name] = len(class_mapping)\n",
    "            \n",
    "        # Skip images with no annotations\n",
    "        if \"regions\" not in image_data or len(image_data['regions']) == 0:\n",
    "            continue\n",
    "        \n",
    "        annotated_images += 1\n",
    "\n",
    "        # Generate augmented copies, but always keep the original image as well\n",
    "        for i in range(num_augmented_copies + 1):\n",
    "            if not i:\n",
    "                output_image_path = os.path.join(output_directory, os.path.splitext(os.path.basename(image_path))[0] + \".jpg\")\n",
    "            else:\n",
    "                output_image_path = os.path.join(output_directory, os.path.splitext(os.path.basename(image_path))[0] + \"_\" + str(i) + \".jpg\")    # append suffix to avoid clashes\n",
    "            transform_info_output_path = os.path.join(output_directory, os.path.splitext(os.path.basename(output_image_path))[0] + \".info.txt\")\n",
    "            if os.path.exists(transform_info_output_path):\n",
    "                # This image was already transformed from another class, so we're adding the annotations from this one\n",
    "                # as well\n",
    "                with open(transform_info_output_path, \"r\") as info_file:\n",
    "                    angle, flip = map(int, info_file.read().split())\n",
    "            else:\n",
    "                # Resize the image so the following operations are faster and the data size is reduced\n",
    "                x_multiplier = 640/w\n",
    "                y_multiplier = 640/h\n",
    "                # image.thumbnail((640, 640), Image.HAMMING)\n",
    "                image = image.resize((640, 640), Image.HAMMING)\n",
    "                if not i:\n",
    "                    # Keep the original image\n",
    "                    angle = 0\n",
    "                    flip = False\n",
    "                    image.save(output_image_path)\n",
    "                else:\n",
    "                    angle = random.choice(rotation_angles)\n",
    "                \n",
    "                    # Random rotation\n",
    "                    modified_image = image.rotate(angle, resample=Image.BICUBIC, expand=True)\n",
    "                    # Random brightness\n",
    "                    enhancer = ImageEnhance.Brightness(modified_image)\n",
    "                    modified_image = enhancer.enhance(random.uniform(0.75, 1.25))\n",
    "                    # Random contrast\n",
    "                    enhancer = ImageEnhance.Contrast(modified_image)\n",
    "                    modified_image = enhancer.enhance(random.uniform(0.625, 1.375))\n",
    "                    # Random sharpness\n",
    "                    enhancer = ImageEnhance.Sharpness(modified_image)\n",
    "                    modified_image = enhancer.enhance(random.uniform(0.5, 1.5))\n",
    "                    # Random colour\n",
    "                    enhancer = ImageEnhance.Color(modified_image)\n",
    "                    modified_image = enhancer.enhance(random.uniform(0.625, 1.375))\n",
    "                    # Random horizontal flip\n",
    "                    if random.random() < 0.5:\n",
    "                        flip = True\n",
    "                        modified_image = ImageOps.mirror(modified_image)\n",
    "                    else:\n",
    "                        flip = False\n",
    "                    # Random RGB deviation\n",
    "                    r_multiplier = random.uniform(0.875, 1.125)\n",
    "                    g_multiplier = random.uniform(0.875, 1.125)\n",
    "                    b_multiplier = random.uniform(0.875, 1.125)\n",
    "                    r, g, b = modified_image.split()\n",
    "                    r = r.point(lambda p: min(255, max(0, int(p * r_multiplier))))\n",
    "                    g = g.point(lambda p: min(255, max(0, int(p * g_multiplier))))\n",
    "                    b = b.point(lambda p: min(255, max(0, int(p * b_multiplier))))\n",
    "                    modified_image = Image.merge(\"RGB\", (r, g, b))\n",
    "                    # Noise\n",
    "                    try:\n",
    "                        noise = Image.new(\"RGB\", modified_image.size, (0, 0, 0))\n",
    "                        for _ in range(int(image.width * image.height * 0.01)):\n",
    "                            x, y = random.randint(0, image.width - 1), random.randint(0, image.height - 1)\n",
    "                            # Salt or pepper?\n",
    "                            if random.random() > 0.25:\n",
    "                                noise.putpixel((x, y), (255, 255, 255))\n",
    "                            else:\n",
    "                                noise.putpixel((x, y), (0, 0, 0))\n",
    "                        modified_image = Image.blend(modified_image, noise, 0.125)\n",
    "                    except IndexError:\n",
    "                        # Image is buggy\n",
    "                        pass\n",
    "                    modified_image.save(output_image_path, quality=save_quality)   # low quality to save space and diversify the dataset\n",
    "\n",
    "            annotations_output_path = os.path.join(output_directory, os.path.splitext(os.path.basename(output_image_path))[0] + \".txt\")\n",
    "            with open(annotations_output_path, \"a\") as file:\n",
    "                if \"regions\" not in image_data or len(image_data[\"regions\"]) == 0:\n",
    "                    continue  # skip unannotated images\n",
    "                for region in image_data['regions']:\n",
    "                    shape_attr = region['shape_attributes']\n",
    "                    points = []\n",
    "                    if shape_attr['name'] == 'rect':\n",
    "                        x, y, width, height = shape_attr['x'], shape_attr['y'], shape_attr['width'], shape_attr['height']\n",
    "                        points = [(x, y), (x + width, y), (x + width, y + height), (x, y + height)]\n",
    "                    elif shape_attr['name'] == 'polygon':\n",
    "                        points = list(zip(shape_attr['all_points_x'], shape_attr['all_points_y']))\n",
    "                    elif shape_attr['name'] == 'circle':\n",
    "                        cx, cy, r = shape_attr['cx'], shape_attr['cy'], shape_attr['r']\n",
    "                        points = [(cx - r, cy - r), (cx + r, cy - r), (cx + r, cy + r), (cx - r, cy + r)]\n",
    "                    elif shape_attr['name'] == 'ellipse':\n",
    "                        cx, cy, rx, ry = shape_attr['cx'], shape_attr['cy'], shape_attr['rx'], shape_attr['ry']\n",
    "                        angle += shape_attr.get(\"theta\", 0)  # Add the rotation angle\n",
    "                        points = [(cx - rx, cy - ry), (cx + rx, cy - ry), (cx + rx, cy + ry), (cx - rx, cy + ry)]\n",
    "\n",
    "                    # Rotate points\n",
    "                    if flip:\n",
    "                        points = [(w - pt[0], pt[1]) for pt in points]\n",
    "                    rotated_points = [rotate_point(pt, (cx, cy), angle) for pt in points]\n",
    "                    min_x = max(0, min(pt[0] for pt in rotated_points))\n",
    "                    max_x = min(w, max(pt[0] for pt in rotated_points))\n",
    "                    min_y = max(0, min(pt[1] for pt in rotated_points))\n",
    "                    max_y = min(h, max(pt[1] for pt in rotated_points))\n",
    "\n",
    "                    x_center = ((min_x + max_x) / 2) / w\n",
    "                    y_center = ((min_y + max_y) / 2) / h\n",
    "                    box_width = (max_x - min_x) / w\n",
    "                    box_height = (max_y - min_y) / h\n",
    "                    file.write(f\"{class_mapping[class_name]} {x_center} {y_center} {box_width} {box_height}\\n\")\n",
    "            with open(transform_info_output_path, \"w\") as info_file:\n",
    "                    # Copies of the image will transform points in the same way\n",
    "                    info_file.write(f\"{angle} {int(flip)}\")\n",
    "    \n",
    "    return class_mapping, annotated_images\n",
    "\n",
    "OUTPUT_PATH = \"yolo_data/\"\n",
    "class_mapping, annotated_images = save_photos(ANNOTATIONS_PATH, DATA_PATH, OUTPUT_PATH)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "662faa2f80eb61b9",
   "metadata": {},
   "source": [
    "We set the class names in the YOLO configuration file to the ones discovered while loading the data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "563b4ed069096a96",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-26T20:24:22.088581Z",
     "start_time": "2024-05-26T20:24:22.086314Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1867 images processed.\n"
     ]
    }
   ],
   "source": [
    "print(f\"{annotated_images} images processed.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "73a63f9dc63594a1",
   "metadata": {},
   "outputs": [],
   "source": [
    "from ruamel.yaml import YAML\n",
    "print(len(class_mapping), class_mapping)\n",
    "\n",
    "# Set the class names\n",
    "yaml = YAML()\n",
    "with open(YOLO_CONFIG_PATH, \"r\") as file:\n",
    "    data = yaml.load(file)\n",
    "    data[\"nc\"] = len(class_mapping)\n",
    "    data[\"names\"] = class_mapping"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4fbd4c7fafc63aff",
   "metadata": {},
   "source": [
    "## Training"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "65fa97a1ae1c78f2",
   "metadata": {
    "jupyter": {
     "is_executing": true
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "New https://pypi.org/project/ultralytics/8.2.25 available 😃 Update with 'pip install -U ultralytics'\n",
      "Ultralytics YOLOv8.2.21 🚀 Python-3.10.0 torch-2.3.0+cu121 CPU (13th Gen Intel Core(TM) i9-13900KF)\n",
      "\u001b[34m\u001b[1mengine/trainer: \u001b[0mtask=detect, mode=train, model=runs/detect/train34/weights/best.pt, data=yolo.yaml, epochs=72, time=None, patience=100, batch=16, imgsz=640, save=True, save_period=-1, cache=False, device=None, workers=8, project=None, name=train36, exist_ok=False, pretrained=True, optimizer=auto, verbose=True, seed=0, deterministic=True, single_cls=False, rect=False, cos_lr=False, close_mosaic=10, resume=False, amp=True, fraction=1.0, profile=False, freeze=None, multi_scale=False, overlap_mask=True, mask_ratio=4, dropout=0.0, val=True, split=val, save_json=False, save_hybrid=False, conf=None, iou=0.7, max_det=300, half=False, dnn=False, plots=True, source=None, vid_stride=1, stream_buffer=False, visualize=False, augment=False, agnostic_nms=False, classes=None, retina_masks=False, embed=None, show=False, save_frames=False, save_txt=False, save_conf=False, save_crop=False, show_labels=True, show_conf=True, show_boxes=True, line_width=None, format=torchscript, keras=False, optimize=False, int8=False, dynamic=False, simplify=False, opset=None, workspace=4, nms=False, lr0=0.01, lrf=0.01, momentum=0.937, weight_decay=0.0005, warmup_epochs=3.0, warmup_momentum=0.8, warmup_bias_lr=0.1, box=7.5, cls=0.5, dfl=1.5, pose=12.0, kobj=1.0, label_smoothing=0.0, nbs=64, hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, degrees=0.0, translate=0.1, scale=0.5, shear=0.0, perspective=0.0, flipud=0.0, fliplr=0.5, bgr=0.0, mosaic=1.0, mixup=0.0, copy_paste=0.0, auto_augment=randaugment, erasing=0.4, crop_fraction=1.0, cfg=None, tracker=botsort.yaml, save_dir=runs/detect/train36\n",
      "\n",
      "                   from  n    params  module                                       arguments                     \n",
      "  0                  -1  1       464  ultralytics.nn.modules.conv.Conv             [3, 16, 3, 2]                 \n",
      "  1                  -1  1      4672  ultralytics.nn.modules.conv.Conv             [16, 32, 3, 2]                \n",
      "  2                  -1  1      7360  ultralytics.nn.modules.block.C2f             [32, 32, 1, True]             \n",
      "  3                  -1  1     18560  ultralytics.nn.modules.conv.Conv             [32, 64, 3, 2]                \n",
      "  4                  -1  2     49664  ultralytics.nn.modules.block.C2f             [64, 64, 2, True]             \n",
      "  5                  -1  1     73984  ultralytics.nn.modules.conv.Conv             [64, 128, 3, 2]               \n",
      "  6                  -1  2    197632  ultralytics.nn.modules.block.C2f             [128, 128, 2, True]           \n",
      "  7                  -1  1    295424  ultralytics.nn.modules.conv.Conv             [128, 256, 3, 2]              \n",
      "  8                  -1  1    460288  ultralytics.nn.modules.block.C2f             [256, 256, 1, True]           \n",
      "  9                  -1  1    164608  ultralytics.nn.modules.block.SPPF            [256, 256, 5]                 \n",
      " 10                  -1  1         0  torch.nn.modules.upsampling.Upsample         [None, 2, 'nearest']          \n",
      " 11             [-1, 6]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           \n",
      " 12                  -1  1    148224  ultralytics.nn.modules.block.C2f             [384, 128, 1]                 \n",
      " 13                  -1  1         0  torch.nn.modules.upsampling.Upsample         [None, 2, 'nearest']          \n",
      " 14             [-1, 4]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           \n",
      " 15                  -1  1     37248  ultralytics.nn.modules.block.C2f             [192, 64, 1]                  \n",
      " 16                  -1  1     36992  ultralytics.nn.modules.conv.Conv             [64, 64, 3, 2]                \n",
      " 17            [-1, 12]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           \n",
      " 18                  -1  1    123648  ultralytics.nn.modules.block.C2f             [192, 128, 1]                 \n",
      " 19                  -1  1    147712  ultralytics.nn.modules.conv.Conv             [128, 128, 3, 2]              \n",
      " 20             [-1, 9]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           \n",
      " 21                  -1  1    493056  ultralytics.nn.modules.block.C2f             [384, 256, 1]                 \n",
      " 22        [15, 18, 21]  1    753262  ultralytics.nn.modules.head.Detect           [10, [64, 128, 256]]          \n",
      "Model summary: 225 layers, 3012798 parameters, 3012782 gradients, 8.2 GFLOPs\n",
      "\n",
      "Transferred 355/355 items from pretrained weights\n",
      "Freezing layer 'model.22.dfl.conv.weight'\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\u001b[34m\u001b[1mtrain: \u001b[0mScanning /home/vlad/Desktop/litewaste/yolo_data.cache... 7144 images, 0 backgrounds, 22 corrupt: 100%|██████████| 7144/71\u001b[0m"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/IMG-20240514-WA0022_1.jpg: ignoring corrupt image/label: negative label values [  -0.017812     -0.0525   -0.035625      -0.105]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/IMG-20240514-WA0022_3.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0525]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/IMG-20240514-WA0030_2.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.1517]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/IMG-20240514-WA0030_3.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.1517]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/IMG-20240514-WA0036_2.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0087]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/dwc_AluCan182_2.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.1089]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/dwc_AluCan184_2.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0864]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/dwc_AluCan186_3.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0073]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/dwc_AluCan953_2.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0103]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/dwc_Glass1,155_1.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [      1.019]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240422-WA0026_1.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [       1.02      1.0113]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240422-WA0026_3.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [       1.02      1.0113]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240422-WA0027_2.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0712]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240422-WA0033_2.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0006]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240513-WA0006_2.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0125      1.0504      1.0033]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240513-WA0013_1.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0025]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240513-WA0013_2.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0025]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240513-WA0018_2.jpg: ignoring corrupt image/label: negative label values [  -0.010937   -0.021875   -0.029687   -0.059375  -0.0003125       -0.05   -0.000625        -0.1    -0.01375     -0.0275]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240513-WA0019_1.jpg: ignoring corrupt image/label: negative label values [   -0.04375     -0.0875]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240513-WA0019_3.jpg: ignoring corrupt image/label: negative label values [   -0.04375     -0.0875]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240513-WA0021_3.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0133      1.0492      1.0633]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240513-WA0023_1.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [      1.015      1.0221      1.0346]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n",
      "\u001b[34m\u001b[1mval: \u001b[0mScanning /home/vlad/Desktop/litewaste/yolo_data.cache... 7144 images, 0 backgrounds, 22 corrupt: 100%|██████████| 7144/7144\u001b[0m"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/IMG-20240514-WA0022_1.jpg: ignoring corrupt image/label: negative label values [  -0.017812     -0.0525   -0.035625      -0.105]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/IMG-20240514-WA0022_3.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0525]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/IMG-20240514-WA0030_2.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.1517]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/IMG-20240514-WA0030_3.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.1517]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/IMG-20240514-WA0036_2.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0087]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/dwc_AluCan182_2.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.1089]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/dwc_AluCan184_2.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0864]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/dwc_AluCan186_3.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0073]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/dwc_AluCan953_2.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0103]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/dwc_Glass1,155_1.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [      1.019]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240422-WA0026_1.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [       1.02      1.0113]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240422-WA0026_3.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [       1.02      1.0113]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240422-WA0027_2.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0712]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240422-WA0033_2.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0006]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240513-WA0006_2.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0125      1.0504      1.0033]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240513-WA0013_1.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0025]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240513-WA0013_2.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0025]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240513-WA0018_2.jpg: ignoring corrupt image/label: negative label values [  -0.010937   -0.021875   -0.029687   -0.059375  -0.0003125       -0.05   -0.000625        -0.1    -0.01375     -0.0275]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240513-WA0019_1.jpg: ignoring corrupt image/label: negative label values [   -0.04375     -0.0875]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240513-WA0019_3.jpg: ignoring corrupt image/label: negative label values [   -0.04375     -0.0875]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240513-WA0021_3.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [     1.0133      1.0492      1.0633]\n",
      "\u001b[34m\u001b[1mtrain: \u001b[0mWARNING ⚠️ /home/vlad/Desktop/litewaste/yolo_data/original_IMG-20240513-WA0023_1.jpg: ignoring corrupt image/label: non-normalized or out of bounds coordinates [      1.015      1.0221      1.0346]\n",
      "Plotting labels to runs/detect/train36/labels.jpg... \n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[34m\u001b[1moptimizer:\u001b[0m 'optimizer=auto' found, ignoring 'lr0=0.01' and 'momentum=0.937' and determining best 'optimizer', 'lr0' and 'momentum' automatically... \n",
      "\u001b[34m\u001b[1moptimizer:\u001b[0m AdamW(lr=0.000714, momentum=0.9) with parameter groups 57 weight(decay=0.0), 64 weight(decay=0.0005), 63 bias(decay=0.0)\n",
      "Image sizes 640 train, 640 val\n",
      "Using 0 dataloader workers\n",
      "Logging results to \u001b[1mruns/detect/train36\u001b[0m\n",
      "Starting training for 72 epochs...\n",
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "       1/72         0G      1.004      1.143      1.422          7        640: 100%|██████████| 446/446 [08:31<00:00,  1.15s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:42<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.844      0.729      0.804      0.592\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "       2/72         0G       1.01      1.156      1.419          3        640: 100%|██████████| 446/446 [08:30<00:00,  1.14s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:45<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.841        0.7      0.801      0.584\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "       3/72         0G      1.024      1.192      1.441          8        640: 100%|██████████| 446/446 [08:30<00:00,  1.14s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:43<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.808      0.695      0.793      0.561\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "       4/72         0G      1.034      1.201      1.441          2        640: 100%|██████████| 446/446 [08:35<00:00,  1.15s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:49<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.781      0.704      0.772      0.541\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "       5/72         0G      1.035      1.215      1.443          7        640: 100%|██████████| 446/446 [08:36<00:00,  1.16s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:54<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.832      0.721      0.806      0.579\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "       6/72         0G      1.029      1.183      1.436          6        640: 100%|██████████| 446/446 [08:36<00:00,  1.16s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:55<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.817      0.724      0.801      0.567\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "       7/72         0G      1.018      1.177       1.43          5        640: 100%|██████████| 446/446 [08:37<00:00,  1.16s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:55<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.853      0.737       0.82      0.589\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "       8/72         0G      1.014      1.168      1.422          5        640: 100%|██████████| 446/446 [08:38<00:00,  1.16s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:53<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.831       0.73      0.808      0.576\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "       9/72         0G      1.011      1.147      1.421          5        640: 100%|██████████| 446/446 [08:37<00:00,  1.16s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:54<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055       0.84       0.72      0.809      0.584\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      10/72         0G       1.01       1.16      1.417          2        640: 100%|██████████| 446/446 [08:38<00:00,  1.16s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:55<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.866      0.696       0.81      0.585\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      11/72         0G     0.9955      1.139      1.411          7        640: 100%|██████████| 446/446 [08:37<00:00,  1.16s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:53<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.853      0.742      0.828      0.599\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      12/72         0G     0.9967      1.142      1.414          2        640: 100%|██████████| 446/446 [08:38<00:00,  1.16s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:54<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.828      0.767       0.82      0.596\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      13/72         0G     0.9846      1.113      1.395          4        640: 100%|██████████| 446/446 [08:36<00:00,  1.16s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:54<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.803       0.78      0.819      0.599\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      14/72         0G     0.9893      1.118      1.401          7        640: 100%|██████████| 446/446 [08:39<00:00,  1.16s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:54<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.789      0.769      0.818      0.602\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      15/72         0G     0.9802      1.096      1.388          5        640: 100%|██████████| 446/446 [08:38<00:00,  1.16s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:55<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.851      0.763      0.835      0.611\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      16/72         0G     0.9781      1.099      1.396          4        640: 100%|██████████| 446/446 [08:39<00:00,  1.17s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:55<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.867      0.748      0.832      0.608\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      17/72         0G      0.968      1.081      1.386          3        640: 100%|██████████| 446/446 [08:40<00:00,  1.17s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:57<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.858      0.741      0.834      0.619\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      18/72         0G     0.9795      1.081      1.391          5        640: 100%|██████████| 446/446 [08:39<00:00,  1.17s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:53<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055       0.87      0.777      0.853       0.64\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      19/72         0G     0.9582      1.065      1.374          2        640: 100%|██████████| 446/446 [08:43<00:00,  1.17s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:54<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.855      0.791      0.848      0.627\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      20/72         0G      0.954      1.066      1.378          3        640: 100%|██████████| 446/446 [08:39<00:00,  1.17s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:55<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.867       0.78      0.855      0.642\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      21/72         0G     0.9503      1.056       1.37          8        640: 100%|██████████| 446/446 [08:38<00:00,  1.16s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:56<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.868      0.769      0.854      0.641\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      22/72         0G     0.9585      1.062      1.373          7        640: 100%|██████████| 446/446 [08:37<00:00,  1.16s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:55<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.882      0.768       0.86      0.651\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      23/72         0G     0.9571      1.054       1.37         10        640: 100%|██████████| 446/446 [08:38<00:00,  1.16s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:55<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.862      0.785      0.857      0.647\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      24/72         0G     0.9373      1.039      1.359          4        640: 100%|██████████| 446/446 [08:39<00:00,  1.16s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:56<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055        0.9      0.792      0.876      0.669\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      25/72         0G     0.9406       1.03       1.36          4        640: 100%|██████████| 446/446 [08:39<00:00,  1.16s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:55<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.876      0.799      0.873      0.666\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      26/72         0G      0.933      1.025       1.35          5        640: 100%|██████████| 446/446 [08:03<00:00,  1.08s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:02<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.887      0.794      0.872      0.667\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      27/72         0G     0.9273      1.016      1.352          9        640: 100%|██████████| 446/446 [07:37<00:00,  1.03s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:01<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.892      0.787       0.87      0.665\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      28/72         0G     0.9358      1.024      1.352         12        640: 100%|██████████| 446/446 [07:37<00:00,  1.03s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:02<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.895      0.801      0.881      0.677\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      29/72         0G     0.9283      1.005      1.349          5        640: 100%|██████████| 446/446 [07:36<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:01<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.878      0.794      0.874      0.673\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      30/72         0G     0.9187       1.01      1.343          6        640: 100%|██████████| 446/446 [07:37<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:00<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.893      0.806      0.887      0.684\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      31/72         0G     0.9106     0.9951       1.34          3        640: 100%|██████████| 446/446 [07:37<00:00,  1.03s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:02<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.894      0.781      0.879      0.684\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      32/72         0G     0.9043     0.9814      1.333          2        640: 100%|██████████| 446/446 [07:35<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:01<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.902      0.804      0.888      0.688\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      33/72         0G      0.912     0.9916      1.335          6        640: 100%|██████████| 446/446 [07:37<00:00,  1.03s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:01<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.889      0.819      0.887       0.69\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      34/72         0G     0.8918     0.9597       1.32          3        640: 100%|██████████| 446/446 [07:36<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:01<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.899      0.799      0.884      0.686\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      35/72         0G     0.8976      0.966      1.328          6        640: 100%|██████████| 446/446 [07:37<00:00,  1.03s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:01<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.896      0.813      0.893      0.696\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      36/72         0G     0.8925     0.9653      1.326          7        640: 100%|██████████| 446/446 [07:36<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:00<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.922      0.799      0.892      0.694\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      37/72         0G     0.8879     0.9598      1.323          4        640: 100%|██████████| 446/446 [07:36<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:01<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.916      0.818      0.896      0.704\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      38/72         0G     0.8827     0.9395      1.318          6        640: 100%|██████████| 446/446 [07:38<00:00,  1.03s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:00<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.898      0.799      0.894      0.704\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      39/72         0G      0.884     0.9523      1.317          7        640: 100%|██████████| 446/446 [07:36<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:01<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.909      0.824      0.899      0.708\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      40/72         0G     0.8809     0.9478      1.316          2        640: 100%|██████████| 446/446 [07:35<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:01<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.912      0.819      0.896      0.703\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      41/72         0G     0.8857     0.9535       1.32          3        640: 100%|██████████| 446/446 [07:34<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:02<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.921      0.798      0.895      0.705\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      42/72         0G      0.869     0.9174      1.301          2        640: 100%|██████████| 446/446 [07:36<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:00<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.921      0.817      0.898      0.708\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      43/72         0G     0.8765     0.9349      1.306          4        640: 100%|██████████| 446/446 [07:38<00:00,  1.03s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:00<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.915      0.817      0.898      0.716\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      44/72         0G     0.8609     0.9166      1.297          4        640: 100%|██████████| 446/446 [07:34<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:01<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.905      0.818      0.906      0.721\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      45/72         0G     0.8562     0.9113      1.295          4        640: 100%|██████████| 446/446 [07:36<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:00<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.908      0.844      0.906      0.722\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      46/72         0G     0.8501     0.9026      1.286          2        640: 100%|██████████| 446/446 [07:34<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:00<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.925      0.813      0.906      0.723\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      47/72         0G     0.8535     0.9097      1.298          3        640: 100%|██████████| 446/446 [07:35<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:01<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.923      0.816      0.907      0.723\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      48/72         0G     0.8441     0.9014      1.286          5        640: 100%|██████████| 446/446 [07:33<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:00<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.925      0.822      0.907      0.726\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      49/72         0G     0.8376     0.8897      1.285          4        640: 100%|██████████| 446/446 [07:34<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:01<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.928      0.835      0.916      0.739\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      50/72         0G     0.8446     0.8874      1.283          2        640: 100%|██████████| 446/446 [07:36<00:00,  1.02s/it]\n",
      "      51/72         0G     0.8396     0.8879      1.282          4        640: 100%|██████████| 446/446 [07:35<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:00<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055       0.93      0.827      0.913      0.735\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      53/72         0G     0.8409     0.8932      1.281          3        640: 100%|██████████| 446/446 [07:34<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:00<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.929      0.837      0.911      0.737\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      54/72         0G     0.8147     0.8631      1.269         11        640: 100%|██████████| 446/446 [07:36<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:00<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.928      0.844      0.915      0.738\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      55/72         0G     0.8325     0.8807      1.277          3        640: 100%|██████████| 446/446 [07:34<00:00,  1.02s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:00<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.922      0.841      0.914      0.738\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      56/72         0G     0.8137     0.8569      1.272         33        640:  57%|█████▋    | 253/446 [04:19<03:18,  1.03s/it]IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:01<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.932      0.855      0.927      0.762\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      71/72         0G      0.673     0.5697       1.22          2        640: 100%|██████████| 446/446 [07:30<00:00,  1.01s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:01<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.933       0.86      0.927      0.764\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "      72/72         0G     0.6813     0.5796       1.23          6        640: 100%|██████████| 446/446 [07:31<00:00,  1.01s/it]\n",
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [03:01<00:00,"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.934      0.865      0.927      0.766\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "72 epochs completed in 13.537 hours.\n",
      "Optimizer stripped from runs/detect/train36/weights/last.pt, 6.3MB\n",
      "Optimizer stripped from runs/detect/train36/weights/best.pt, 6.3MB\n",
      "\n",
      "Validating runs/detect/train36/weights/best.pt...\n",
      "Ultralytics YOLOv8.2.21 🚀 Python-3.10.0 torch-2.3.0+cu121 CPU (13th Gen Intel Core(TM) i9-13900KF)\n",
      "Model summary (fused): 168 layers, 3007598 parameters, 0 gradients, 8.1 GFLOPs\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 223/223 [02:32<00:00,\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                   all       7122       9055      0.934      0.865      0.927      0.766\n",
      "               Textile       7122        224      0.926      0.942      0.972      0.815\n",
      "                 Paper       7122       2305      0.958      0.915      0.965      0.845\n",
      "               Plastic       7122       3120      0.933      0.893      0.946      0.804\n",
      "                 Other       7122        577      0.915      0.821      0.902      0.686\n",
      "                 Metal       7122       1212       0.96      0.845      0.933      0.818\n",
      "               Medical       7122         12       0.96      0.917      0.945      0.779\n",
      "                  Wood       7122        164      0.939      0.866      0.953       0.73\n",
      "                 Glass       7122        351      0.945      0.932      0.975      0.854\n",
      "               Organic       7122        958      0.911      0.768      0.887      0.703\n",
      "            Electronic       7122        132      0.892       0.75      0.794      0.625\n",
      "Speed: 0.5ms preprocess, 18.3ms inference, 0.0ms loss, 0.1ms postprocess per image\n",
      "Results saved to \u001b[1mruns/detect/train36\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "from ultralytics import YOLO\n",
    "\n",
    "model = YOLO(\"runs/detect/train3/weights/best.pt\")\n",
    "\n",
    "results = model.train(data=YOLO_CONFIG_PATH, epochs=72, verbose=True, imgsz=640)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "138880b6a127671a",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-26T20:32:23.797810Z",
     "start_time": "2024-05-26T20:32:23.797762Z"
    }
   },
   "outputs": [],
   "source": [
    "torch.save(model.state_dict(), \"model.pt\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f7f1d169ae7634d5",
   "metadata": {},
   "source": [
    "## Inferencing\n",
    "Retrieve the class mapping that was discovered earlier and used in training."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "78e0a2a59ce4f120",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-27T12:02:53.498360Z",
     "start_time": "2024-05-27T12:02:53.485443Z"
    }
   },
   "outputs": [],
   "source": [
    "# Get the class mapping\n",
    "from ruamel.yaml import YAML\n",
    "\n",
    "yaml = YAML()\n",
    "\n",
    "with open(\"yolo.yaml\", \"r\") as file:\n",
    "    data = yaml.load(file)\n",
    "    class_mapping = data[\"names\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "465e92c274b08cca",
   "metadata": {},
   "source": [
    "### With live webcam feed"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "cf66bcb81e1b29f",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-26T16:53:48.532397Z",
     "start_time": "2024-05-26T16:50:58.288905Z"
    }
   },
   "outputs": [
    {
     "ename": "KeyboardInterrupt",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[20], line 28\u001b[0m\n\u001b[1;32m     25\u001b[0m success, img \u001b[38;5;241m=\u001b[39m cap\u001b[38;5;241m.\u001b[39mread()\n\u001b[1;32m     26\u001b[0m results \u001b[38;5;241m=\u001b[39m model(img, stream\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m, verbose\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m)\n\u001b[0;32m---> 28\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m r \u001b[38;5;129;01min\u001b[39;00m results:\n\u001b[1;32m     29\u001b[0m     boxes \u001b[38;5;241m=\u001b[39m r\u001b[38;5;241m.\u001b[39mboxes\n\u001b[1;32m     31\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m box \u001b[38;5;129;01min\u001b[39;00m boxes:\n",
      "File \u001b[0;32m~/miniconda3/envs/tf/lib/python3.10/site-packages/torch/utils/_contextlib.py:35\u001b[0m, in \u001b[0;36m_wrap_generator.<locals>.generator_context\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m     32\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m     33\u001b[0m     \u001b[38;5;66;03m# Issuing `None` to a generator fires it up\u001b[39;00m\n\u001b[1;32m     34\u001b[0m     \u001b[38;5;28;01mwith\u001b[39;00m ctx_factory():\n\u001b[0;32m---> 35\u001b[0m         response \u001b[38;5;241m=\u001b[39m \u001b[43mgen\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[1;32m     37\u001b[0m     \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[1;32m     38\u001b[0m         \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m     39\u001b[0m             \u001b[38;5;66;03m# Forward the response to our caller and get its next request\u001b[39;00m\n",
      "File \u001b[0;32m~/miniconda3/envs/tf/lib/python3.10/site-packages/ultralytics/engine/predictor.py:248\u001b[0m, in \u001b[0;36mBasePredictor.stream_inference\u001b[0;34m(self, source, model, *args, **kwargs)\u001b[0m\n\u001b[1;32m    246\u001b[0m \u001b[38;5;66;03m# Inference\u001b[39;00m\n\u001b[1;32m    247\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m profilers[\u001b[38;5;241m1\u001b[39m]:\n\u001b[0;32m--> 248\u001b[0m     preds \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minference\u001b[49m\u001b[43m(\u001b[49m\u001b[43mim\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    249\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39margs\u001b[38;5;241m.\u001b[39membed:\n\u001b[1;32m    250\u001b[0m         \u001b[38;5;28;01myield from\u001b[39;00m [preds] \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(preds, torch\u001b[38;5;241m.\u001b[39mTensor) \u001b[38;5;28;01melse\u001b[39;00m preds  \u001b[38;5;66;03m# yield embedding tensors\u001b[39;00m\n",
      "File \u001b[0;32m~/miniconda3/envs/tf/lib/python3.10/site-packages/ultralytics/engine/predictor.py:142\u001b[0m, in \u001b[0;36mBasePredictor.inference\u001b[0;34m(self, im, *args, **kwargs)\u001b[0m\n\u001b[1;32m    136\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Runs inference on a given image using the specified model and arguments.\"\"\"\u001b[39;00m\n\u001b[1;32m    137\u001b[0m visualize \u001b[38;5;241m=\u001b[39m (\n\u001b[1;32m    138\u001b[0m     increment_path(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msave_dir \u001b[38;5;241m/\u001b[39m Path(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mbatch[\u001b[38;5;241m0\u001b[39m][\u001b[38;5;241m0\u001b[39m])\u001b[38;5;241m.\u001b[39mstem, mkdir\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[1;32m    139\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39margs\u001b[38;5;241m.\u001b[39mvisualize \u001b[38;5;129;01mand\u001b[39;00m (\u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msource_type\u001b[38;5;241m.\u001b[39mtensor)\n\u001b[1;32m    140\u001b[0m     \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[1;32m    141\u001b[0m )\n\u001b[0;32m--> 142\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodel\u001b[49m\u001b[43m(\u001b[49m\u001b[43mim\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maugment\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43margs\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43maugment\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvisualize\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mvisualize\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43membed\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43margs\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43membed\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/tf/lib/python3.10/site-packages/torch/nn/modules/module.py:1532\u001b[0m, in \u001b[0;36mModule._wrapped_call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m   1530\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_compiled_call_impl(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)  \u001b[38;5;66;03m# type: ignore[misc]\u001b[39;00m\n\u001b[1;32m   1531\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m-> 1532\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call_impl\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/tf/lib/python3.10/site-packages/torch/nn/modules/module.py:1541\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m   1536\u001b[0m \u001b[38;5;66;03m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[1;32m   1537\u001b[0m \u001b[38;5;66;03m# this function, and just call forward.\u001b[39;00m\n\u001b[1;32m   1538\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m (\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_backward_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_backward_pre_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward_pre_hooks\n\u001b[1;32m   1539\u001b[0m         \u001b[38;5;129;01mor\u001b[39;00m _global_backward_pre_hooks \u001b[38;5;129;01mor\u001b[39;00m _global_backward_hooks\n\u001b[1;32m   1540\u001b[0m         \u001b[38;5;129;01mor\u001b[39;00m _global_forward_hooks \u001b[38;5;129;01mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[0;32m-> 1541\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mforward_call\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m   1543\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m   1544\u001b[0m     result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n",
      "File \u001b[0;32m~/miniconda3/envs/tf/lib/python3.10/site-packages/ultralytics/nn/autobackend.py:453\u001b[0m, in \u001b[0;36mAutoBackend.forward\u001b[0;34m(self, im, augment, visualize, embed)\u001b[0m\n\u001b[1;32m    451\u001b[0m \u001b[38;5;66;03m# PyTorch\u001b[39;00m\n\u001b[1;32m    452\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mpt \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mnn_module:\n\u001b[0;32m--> 453\u001b[0m     y \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodel\u001b[49m\u001b[43m(\u001b[49m\u001b[43mim\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maugment\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43maugment\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvisualize\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mvisualize\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43membed\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43membed\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    455\u001b[0m \u001b[38;5;66;03m# TorchScript\u001b[39;00m\n\u001b[1;32m    456\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mjit:\n",
      "File \u001b[0;32m~/miniconda3/envs/tf/lib/python3.10/site-packages/torch/nn/modules/module.py:1532\u001b[0m, in \u001b[0;36mModule._wrapped_call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m   1530\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_compiled_call_impl(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)  \u001b[38;5;66;03m# type: ignore[misc]\u001b[39;00m\n\u001b[1;32m   1531\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m-> 1532\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call_impl\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/tf/lib/python3.10/site-packages/torch/nn/modules/module.py:1541\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m   1536\u001b[0m \u001b[38;5;66;03m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[1;32m   1537\u001b[0m \u001b[38;5;66;03m# this function, and just call forward.\u001b[39;00m\n\u001b[1;32m   1538\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m (\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_backward_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_backward_pre_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward_pre_hooks\n\u001b[1;32m   1539\u001b[0m         \u001b[38;5;129;01mor\u001b[39;00m _global_backward_pre_hooks \u001b[38;5;129;01mor\u001b[39;00m _global_backward_hooks\n\u001b[1;32m   1540\u001b[0m         \u001b[38;5;129;01mor\u001b[39;00m _global_forward_hooks \u001b[38;5;129;01mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[0;32m-> 1541\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mforward_call\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m   1543\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m   1544\u001b[0m     result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n",
      "File \u001b[0;32m~/miniconda3/envs/tf/lib/python3.10/site-packages/ultralytics/nn/tasks.py:89\u001b[0m, in \u001b[0;36mBaseModel.forward\u001b[0;34m(self, x, *args, **kwargs)\u001b[0m\n\u001b[1;32m     87\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mdict\u001b[39m):  \u001b[38;5;66;03m# for cases of training and validating while training.\u001b[39;00m\n\u001b[1;32m     88\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mloss(x, \u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m---> 89\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpredict\u001b[49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/tf/lib/python3.10/site-packages/ultralytics/nn/tasks.py:107\u001b[0m, in \u001b[0;36mBaseModel.predict\u001b[0;34m(self, x, profile, visualize, augment, embed)\u001b[0m\n\u001b[1;32m    105\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m augment:\n\u001b[1;32m    106\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_predict_augment(x)\n\u001b[0;32m--> 107\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_predict_once\u001b[49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mprofile\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvisualize\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43membed\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/tf/lib/python3.10/site-packages/ultralytics/nn/tasks.py:128\u001b[0m, in \u001b[0;36mBaseModel._predict_once\u001b[0;34m(self, x, profile, visualize, embed)\u001b[0m\n\u001b[1;32m    126\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m profile:\n\u001b[1;32m    127\u001b[0m     \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_profile_one_layer(m, x, dt)\n\u001b[0;32m--> 128\u001b[0m x \u001b[38;5;241m=\u001b[39m \u001b[43mm\u001b[49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m)\u001b[49m  \u001b[38;5;66;03m# run\u001b[39;00m\n\u001b[1;32m    129\u001b[0m y\u001b[38;5;241m.\u001b[39mappend(x \u001b[38;5;28;01mif\u001b[39;00m m\u001b[38;5;241m.\u001b[39mi \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msave \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m)  \u001b[38;5;66;03m# save output\u001b[39;00m\n\u001b[1;32m    130\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m visualize:\n",
      "File \u001b[0;32m~/miniconda3/envs/tf/lib/python3.10/site-packages/torch/nn/modules/module.py:1532\u001b[0m, in \u001b[0;36mModule._wrapped_call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m   1530\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_compiled_call_impl(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)  \u001b[38;5;66;03m# type: ignore[misc]\u001b[39;00m\n\u001b[1;32m   1531\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m-> 1532\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call_impl\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/tf/lib/python3.10/site-packages/torch/nn/modules/module.py:1541\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m   1536\u001b[0m \u001b[38;5;66;03m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[1;32m   1537\u001b[0m \u001b[38;5;66;03m# this function, and just call forward.\u001b[39;00m\n\u001b[1;32m   1538\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m (\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_backward_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_backward_pre_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward_pre_hooks\n\u001b[1;32m   1539\u001b[0m         \u001b[38;5;129;01mor\u001b[39;00m _global_backward_pre_hooks \u001b[38;5;129;01mor\u001b[39;00m _global_backward_hooks\n\u001b[1;32m   1540\u001b[0m         \u001b[38;5;129;01mor\u001b[39;00m _global_forward_hooks \u001b[38;5;129;01mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[0;32m-> 1541\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mforward_call\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m   1543\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m   1544\u001b[0m     result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n",
      "File \u001b[0;32m~/miniconda3/envs/tf/lib/python3.10/site-packages/ultralytics/nn/modules/head.py:47\u001b[0m, in \u001b[0;36mDetect.forward\u001b[0;34m(self, x)\u001b[0m\n\u001b[1;32m     45\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Concatenates and returns predicted bounding boxes and class probabilities.\"\"\"\u001b[39;00m\n\u001b[1;32m     46\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mnl):\n\u001b[0;32m---> 47\u001b[0m     x[i] \u001b[38;5;241m=\u001b[39m torch\u001b[38;5;241m.\u001b[39mcat((\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcv2\u001b[49m\u001b[43m[\u001b[49m\u001b[43mi\u001b[49m\u001b[43m]\u001b[49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m[\u001b[49m\u001b[43mi\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcv3[i](x[i])), \u001b[38;5;241m1\u001b[39m)\n\u001b[1;32m     48\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtraining:  \u001b[38;5;66;03m# Training path\u001b[39;00m\n\u001b[1;32m     49\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m x\n",
      "File \u001b[0;32m~/miniconda3/envs/tf/lib/python3.10/site-packages/torch/nn/modules/module.py:1528\u001b[0m, in \u001b[0;36mModule._wrapped_call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m   1525\u001b[0m             tracing_state\u001b[38;5;241m.\u001b[39mpop_scope()\n\u001b[1;32m   1526\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m result\n\u001b[0;32m-> 1528\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_wrapped_call_impl\u001b[39m(\u001b[38;5;28mself\u001b[39m, \u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[1;32m   1529\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_compiled_call_impl \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m   1530\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_compiled_call_impl(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)  \u001b[38;5;66;03m# type: ignore[misc]\u001b[39;00m\n",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
     ]
    }
   ],
   "source": [
    "from ultralytics import YOLO\n",
    "import os\n",
    "\n",
    "model = YOLO(\"runs/detect/train26/weights/best.pt\")\n",
    "\n",
    "import cv2 as cv\n",
    "import numpy as np\n",
    "import torchvision.transforms as transforms\n",
    "from PIL import Image, ImageFont, ImageDraw\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.patches as patches\n",
    "\n",
    "# Start the webcam\n",
    "import numpy as np\n",
    "import math\n",
    "cap = cv.VideoCapture(0)\n",
    "cap.set(3, 640)\n",
    "cap.set(4, 640)\n",
    "\n",
    "\n",
    "font = ImageFont.truetype(\"/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf\", 20)\n",
    "\n",
    "while True:\n",
    "    success, img = cap.read()\n",
    "    results = model(img, stream=True, verbose=False)\n",
    "\n",
    "    for r in results:\n",
    "        boxes = r.boxes\n",
    "\n",
    "        for box in boxes:\n",
    "            confidence = round(float(box.conf[0] * 100))\n",
    "\n",
    "            # Skip unsure detections\n",
    "            if confidence < 0:\n",
    "                continue\n",
    "            \n",
    "            # Get coordinates and draw the bounding box\n",
    "            x1, y1, x2, y2 = box.xyxy[0]\n",
    "            x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)\n",
    "            \n",
    "            cv.rectangle(img, (x1, y1), (x2, y2), (255, 255, 255), 2)\n",
    "            cv.rectangle(img, (x1-1, y1-1), (x2+1, y2+1), (136, 150, 0), 2)\n",
    "            \n",
    "            cls = int(box.cls[0])\n",
    "\n",
    "            # Object label\n",
    "            img_pil = Image.fromarray(img)\n",
    "            draw = ImageDraw.Draw(img_pil)\n",
    "            draw.text((x1, y1),\n",
    "                      f\"[{confidence}%] {class_mapping[cls]}\",\n",
    "                      font=font,\n",
    "                      fill=(255, 255, 255),\n",
    "                      stroke_width=1,\n",
    "                      stroke_fill=(0, 0, 0))\n",
    "            img = np.array(img_pil)\n",
    "\n",
    "\n",
    "    cv.imshow(\"Webcam capture demo\", img)\n",
    "    if cv.waitKey(1) == 27:    # escape\n",
    "        break\n",
    "\n",
    "# Stop the webcam\n",
    "cap.release()\n",
    "cv.destroyAllWindows()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd61781e5b705868",
   "metadata": {},
   "source": [
    "### From a photo file"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "5c3a7e358cf3efb5",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-27T12:10:16.377820Z",
     "start_time": "2024-05-27T12:10:13.435471Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "0: 640x640 1 Glass, 5.3ms\n",
      "Speed: 2.6ms preprocess, 5.3ms inference, 1.9ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 (no detections), 3.5ms\n",
      "Speed: 1.4ms preprocess, 3.5ms inference, 0.3ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 (no detections), 5.3ms\n",
      "Speed: 1.8ms preprocess, 5.3ms inference, 1.1ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 (no detections), 3.1ms\n",
      "Speed: 1.6ms preprocess, 3.1ms inference, 0.4ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 1 Metal, 3.7ms\n",
      "Speed: 2.5ms preprocess, 3.7ms inference, 6.5ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 (no detections), 6.2ms\n",
      "Speed: 2.0ms preprocess, 6.2ms inference, 0.8ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 (no detections), 2.8ms\n",
      "Speed: 1.5ms preprocess, 2.8ms inference, 0.3ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 480x640 1 Plastic, 3.3ms\n",
      "Speed: 1.3ms preprocess, 3.3ms inference, 0.5ms postprocess per image at shape (1, 3, 480, 640)\n",
      "\n",
      "0: 640x640 5 Plastics, 6.0ms\n",
      "Speed: 3.1ms preprocess, 6.0ms inference, 1.1ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 1 Metal, 3.3ms\n",
      "Speed: 2.0ms preprocess, 3.3ms inference, 5.7ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 1 Plastic, 2.7ms\n",
      "Speed: 1.4ms preprocess, 2.7ms inference, 0.5ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 (no detections), 5.1ms\n",
      "Speed: 3.3ms preprocess, 5.1ms inference, 0.6ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 1 Glass, 4.9ms\n",
      "Speed: 2.1ms preprocess, 4.9ms inference, 1.1ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 1 Plastic, 5.1ms\n",
      "Speed: 1.7ms preprocess, 5.1ms inference, 1.1ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 1 Paper, 5.2ms\n",
      "Speed: 2.9ms preprocess, 5.2ms inference, 1.3ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 1 Glass, 2.6ms\n",
      "Speed: 2.0ms preprocess, 2.6ms inference, 0.8ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 (no detections), 3.3ms\n",
      "Speed: 1.7ms preprocess, 3.3ms inference, 0.3ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 1 Paper, 3.1ms\n",
      "Speed: 2.3ms preprocess, 3.1ms inference, 2.3ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 (no detections), 2.9ms\n",
      "Speed: 1.6ms preprocess, 2.9ms inference, 0.3ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 1 Plastic, 2.8ms\n",
      "Speed: 1.4ms preprocess, 2.8ms inference, 0.5ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 2 Papers, 2.6ms\n",
      "Speed: 1.4ms preprocess, 2.6ms inference, 0.6ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 1 Metal, 2.6ms\n",
      "Speed: 1.5ms preprocess, 2.6ms inference, 0.6ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 1 Glass, 3.0ms\n",
      "Speed: 1.9ms preprocess, 3.0ms inference, 0.6ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 1 Plastic, 2.6ms\n",
      "Speed: 2.2ms preprocess, 2.6ms inference, 0.5ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 1 Plastic, 2.6ms\n",
      "Speed: 1.8ms preprocess, 2.6ms inference, 0.6ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 1 Plastic, 5.4ms\n",
      "Speed: 2.0ms preprocess, 5.4ms inference, 1.7ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 1 Plastic, 2.6ms\n",
      "Speed: 1.8ms preprocess, 2.6ms inference, 0.5ms postprocess per image at shape (1, 3, 640, 640)\n",
      "\n",
      "0: 640x640 1 Plastic, 3.7ms\n",
      "Speed: 3.0ms preprocess, 3.7ms inference, 1.6ms postprocess per image at shape (1, 3, 640, 640)\n"
     ]
    }
   ],
   "source": [
    "from ultralytics import YOLO\n",
    "import os\n",
    "\n",
    "model = YOLO(\"runs/detect/train28/weights/best.pt\")\n",
    "\n",
    "import cv2 as cv\n",
    "import numpy as np\n",
    "import torchvision.transforms as transforms\n",
    "from PIL import Image, ImageFont, ImageDraw\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.patches as patches\n",
    "\n",
    "import numpy as np\n",
    "import math\n",
    "\n",
    "font = ImageFont.truetype(\"/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf\", 20)\n",
    "\n",
    "image_dir = \"./test_data/\"\n",
    "output_dir = \"./output/\"\n",
    "\n",
    "for image_path in os.scandir(image_dir):\n",
    "    img = cv.imread(image_path.path)\n",
    "    results = model(img)\n",
    "    \n",
    "    for r in results:\n",
    "        boxes = r.boxes\n",
    "        \n",
    "        # Geometric mean of the confidence values\n",
    "        min_confidence = np.mean([box.conf[0].cpu() for box in boxes]) * 87.5\n",
    "    \n",
    "        for box in boxes:\n",
    "            confidence = round(float(box.conf[0] * 100))\n",
    "    \n",
    "            # Skip unsure detections\n",
    "            if confidence < min_confidence:\n",
    "                continue\n",
    "            \n",
    "            # Get coordinates and draw the bounding box\n",
    "            x1, y1, x2, y2 = box.xyxy[0]\n",
    "            x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)\n",
    "            \n",
    "            cv.rectangle(img, (x1, y1), (x2, y2), (255, 255, 255), 2)\n",
    "            cv.rectangle(img, (x1-1, y1-1), (x2+1, y2+1), (136, 150, 0), 2)\n",
    "            \n",
    "            cls = int(box.cls[0])\n",
    "    \n",
    "            img_pil = Image.fromarray(img)\n",
    "            draw = ImageDraw.Draw(img_pil)\n",
    "            \n",
    "            draw.text((x1, y1),\n",
    "                      f\"[{confidence}%] {class_mapping[cls]}\",\n",
    "                      font=font,\n",
    "                      fill=(255, 255, 255),\n",
    "                      stroke_width=1,\n",
    "                      stroke_fill=(0, 0, 0))\n",
    "            img = np.array(img_pil)\n",
    "    \n",
    "    cv.imwrite(os.path.join(output_dir, os.path.basename(image_path.path)), img)\n",
    "    #cv.imshow(\"Photo\", img)\n",
    "    #cv.waitKey(27)         # escape\n",
    "    #cv.destroyAllWindows()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9a640c08f07c223f",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
