We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
ImportError: cannot import name 'draw_bounding_boxes' from 'torchvision.utils'
### Search before asking

- [X] I have searched the YOLOv5 [issues](https://github.com/ultralytics/yolov5/issues) and found no similar bug report.


### YOLOv5 Component

Training

### Bug

![image](https://user-images.githubusercontent.com/68814215/183353020-07a5ae3e-ecd8-4c81-be9d-fd40caea15b2.png)


### Environment

_No response_

### Minimal Reproducible Example

_No response_

### Additional

_No response_

### Are you willing to submit a PR?

- [ ] Yes I'd like to help by submitting a PR!

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `utils/loggers/clearml/clearml_utils.py`
Content:
```
1 """Main Logger class for ClearML experiment tracking."""
2 import glob
3 import re
4 from pathlib import Path
5 
6 import yaml
7 from torchvision.transforms import ToPILImage
8 
9 try:
10     import clearml
11     from clearml import Dataset, Task
12     from torchvision.utils import draw_bounding_boxes  # WARNING: requires torchvision>=0.9.0
13 
14     assert hasattr(clearml, '__version__')  # verify package import not local dir
15 except (ImportError, AssertionError):
16     clearml = None
17 
18 
19 def construct_dataset(clearml_info_string):
20     dataset_id = clearml_info_string.replace('clearml://', '')
21     dataset = Dataset.get(dataset_id=dataset_id)
22     dataset_root_path = Path(dataset.get_local_copy())
23 
24     # We'll search for the yaml file definition in the dataset
25     yaml_filenames = list(glob.glob(str(dataset_root_path / "*.yaml")) + glob.glob(str(dataset_root_path / "*.yml")))
26     if len(yaml_filenames) > 1:
27         raise ValueError('More than one yaml file was found in the dataset root, cannot determine which one contains '
28                          'the dataset definition this way.')
29     elif len(yaml_filenames) == 0:
30         raise ValueError('No yaml definition found in dataset root path, check that there is a correct yaml file '
31                          'inside the dataset root path.')
32     with open(yaml_filenames[0]) as f:
33         dataset_definition = yaml.safe_load(f)
34 
35     assert set(dataset_definition.keys()).issuperset(
36         {'train', 'test', 'val', 'nc', 'names'}
37     ), "The right keys were not found in the yaml file, make sure it at least has the following keys: ('train', 'test', 'val', 'nc', 'names')"
38 
39     data_dict = dict()
40     data_dict['train'] = str(
41         (dataset_root_path / dataset_definition['train']).resolve()) if dataset_definition['train'] else None
42     data_dict['test'] = str(
43         (dataset_root_path / dataset_definition['test']).resolve()) if dataset_definition['test'] else None
44     data_dict['val'] = str(
45         (dataset_root_path / dataset_definition['val']).resolve()) if dataset_definition['val'] else None
46     data_dict['nc'] = dataset_definition['nc']
47     data_dict['names'] = dataset_definition['names']
48 
49     return data_dict
50 
51 
52 class ClearmlLogger:
53     """Log training runs, datasets, models, and predictions to ClearML.
54 
55     This logger sends information to ClearML at app.clear.ml or to your own hosted server. By default,
56     this information includes hyperparameters, system configuration and metrics, model metrics, code information and
57     basic data metrics and analyses.
58 
59     By providing additional command line arguments to train.py, datasets,
60     models and predictions can also be logged.
61     """
62 
63     def __init__(self, opt, hyp):
64         """
65         - Initialize ClearML Task, this object will capture the experiment
66         - Upload dataset version to ClearML Data if opt.upload_dataset is True
67 
68         arguments:
69         opt (namespace) -- Commandline arguments for this run
70         hyp (dict) -- Hyperparameters for this run
71 
72         """
73         self.current_epoch = 0
74         # Keep tracked of amount of logged images to enforce a limit
75         self.current_epoch_logged_images = set()
76         # Maximum number of images to log to clearML per epoch
77         self.max_imgs_to_log_per_epoch = 16
78         # Get the interval of epochs when bounding box images should be logged
79         self.bbox_interval = opt.bbox_interval
80         self.clearml = clearml
81         self.task = None
82         self.data_dict = None
83         if self.clearml:
84             self.task = Task.init(
85                 project_name='YOLOv5',
86                 task_name='training',
87                 tags=['YOLOv5'],
88                 output_uri=True,
89                 auto_connect_frameworks={'pytorch': False}
90                 # We disconnect pytorch auto-detection, because we added manual model save points in the code
91             )
92             # ClearML's hooks will already grab all general parameters
93             # Only the hyperparameters coming from the yaml config file
94             # will have to be added manually!
95             self.task.connect(hyp, name='Hyperparameters')
96 
97             # Get ClearML Dataset Version if requested
98             if opt.data.startswith('clearml://'):
99                 # data_dict should have the following keys:
100                 # names, nc (number of classes), test, train, val (all three relative paths to ../datasets)
101                 self.data_dict = construct_dataset(opt.data)
102                 # Set data to data_dict because wandb will crash without this information and opt is the best way
103                 # to give it to them
104                 opt.data = self.data_dict
105 
106     def log_debug_samples(self, files, title='Debug Samples'):
107         """
108         Log files (images) as debug samples in the ClearML task.
109 
110         arguments:
111         files (List(PosixPath)) a list of file paths in PosixPath format
112         title (str) A title that groups together images with the same values
113         """
114         for f in files:
115             if f.exists():
116                 it = re.search(r'_batch(\d+)', f.name)
117                 iteration = int(it.groups()[0]) if it else 0
118                 self.task.get_logger().report_image(title=title,
119                                                     series=f.name.replace(it.group(), ''),
120                                                     local_path=str(f),
121                                                     iteration=iteration)
122 
123     def log_image_with_boxes(self, image_path, boxes, class_names, image):
124         """
125         Draw the bounding boxes on a single image and report the result as a ClearML debug sample
126 
127         arguments:
128         image_path (PosixPath) the path the original image file
129         boxes (list): list of scaled predictions in the format - [xmin, ymin, xmax, ymax, confidence, class]
130         class_names (dict): dict containing mapping of class int to class name
131         image (Tensor): A torch tensor containing the actual image data
132         """
133         if len(self.current_epoch_logged_images) < self.max_imgs_to_log_per_epoch and self.current_epoch >= 0:
134             # Log every bbox_interval times and deduplicate for any intermittend extra eval runs
135             if self.current_epoch % self.bbox_interval == 0 and image_path not in self.current_epoch_logged_images:
136                 converter = ToPILImage()
137                 labels = []
138                 for conf, class_nr in zip(boxes[:, 4], boxes[:, 5]):
139                     class_name = class_names[int(class_nr)]
140                     confidence = round(float(conf) * 100, 2)
141                     labels.append(f"{class_name}: {confidence}%")
142                 annotated_image = converter(
143                     draw_bounding_boxes(image=image.mul(255).clamp(0, 255).byte().cpu(),
144                                         boxes=boxes[:, :4],
145                                         labels=labels))
146                 self.task.get_logger().report_image(title='Bounding Boxes',
147                                                     series=image_path.name,
148                                                     iteration=self.current_epoch,
149                                                     image=annotated_image)
150                 self.current_epoch_logged_images.add(image_path)
151
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/utils/loggers/clearml/clearml_utils.py b/utils/loggers/clearml/clearml_utils.py
--- a/utils/loggers/clearml/clearml_utils.py
+++ b/utils/loggers/clearml/clearml_utils.py
@@ -3,20 +3,22 @@
 import re
 from pathlib import Path
 
+import numpy as np
 import yaml
-from torchvision.transforms import ToPILImage
+
+from utils.plots import Annotator, colors
 
 try:
     import clearml
     from clearml import Dataset, Task
-    from torchvision.utils import draw_bounding_boxes  # WARNING: requires torchvision>=0.9.0
-
     assert hasattr(clearml, '__version__')  # verify package import not local dir
 except (ImportError, AssertionError):
     clearml = None
 
 
 def construct_dataset(clearml_info_string):
+    """Load in a clearml dataset and fill the internal data_dict with its contents.
+    """
     dataset_id = clearml_info_string.replace('clearml://', '')
     dataset = Dataset.get(dataset_id=dataset_id)
     dataset_root_path = Path(dataset.get_local_copy())
@@ -120,9 +122,9 @@
                                                     local_path=str(f),
                                                     iteration=iteration)
 
-    def log_image_with_boxes(self, image_path, boxes, class_names, image):
+    def log_image_with_boxes(self, image_path, boxes, class_names, image, conf_threshold=0.25):
         """
-        Draw the bounding boxes on a single image and report the result as a ClearML debug sample
+        Draw the bounding boxes on a single image and report the result as a ClearML debug sample.
 
         arguments:
         image_path (PosixPath) the path the original image file
@@ -133,16 +135,20 @@
         if len(self.current_epoch_logged_images) < self.max_imgs_to_log_per_epoch and self.current_epoch >= 0:
             # Log every bbox_interval times and deduplicate for any intermittend extra eval runs
             if self.current_epoch % self.bbox_interval == 0 and image_path not in self.current_epoch_logged_images:
-                converter = ToPILImage()
-                labels = []
-                for conf, class_nr in zip(boxes[:, 4], boxes[:, 5]):
+                im = np.ascontiguousarray(np.moveaxis(image.mul(255).clamp(0, 255).byte().cpu().numpy(), 0, 2))
+                annotator = Annotator(im=im, pil=True)
+                for i, (conf, class_nr, box) in enumerate(zip(boxes[:, 4], boxes[:, 5], boxes[:, :4])):
+                    color = colors(i)
+
                     class_name = class_names[int(class_nr)]
                     confidence = round(float(conf) * 100, 2)
-                    labels.append(f"{class_name}: {confidence}%")
-                annotated_image = converter(
-                    draw_bounding_boxes(image=image.mul(255).clamp(0, 255).byte().cpu(),
-                                        boxes=boxes[:, :4],
-                                        labels=labels))
+                    label = f"{class_name}: {confidence}%"
+
+                    if confidence > conf_threshold:
+                        annotator.rectangle(box.cpu().numpy(), outline=color)
+                        annotator.box_label(box.cpu().numpy(), label=label, color=color)
+
+                annotated_image = annotator.result()
                 self.task.get_logger().report_image(title='Bounding Boxes',
                                                     series=image_path.name,
                                                     iteration=self.current_epoch,

{"golden_diff": "diff --git a/utils/loggers/clearml/clearml_utils.py b/utils/loggers/clearml/clearml_utils.py\n--- a/utils/loggers/clearml/clearml_utils.py\n+++ b/utils/loggers/clearml/clearml_utils.py\n@@ -3,20 +3,22 @@\n import re\n from pathlib import Path\n \n+import numpy as np\n import yaml\n-from torchvision.transforms import ToPILImage\n+\n+from utils.plots import Annotator, colors\n \n try:\n     import clearml\n     from clearml import Dataset, Task\n-    from torchvision.utils import draw_bounding_boxes  # WARNING: requires torchvision>=0.9.0\n-\n     assert hasattr(clearml, '__version__')  # verify package import not local dir\n except (ImportError, AssertionError):\n     clearml = None\n \n \n def construct_dataset(clearml_info_string):\n+    \"\"\"Load in a clearml dataset and fill the internal data_dict with its contents.\n+    \"\"\"\n     dataset_id = clearml_info_string.replace('clearml://', '')\n     dataset = Dataset.get(dataset_id=dataset_id)\n     dataset_root_path = Path(dataset.get_local_copy())\n@@ -120,9 +122,9 @@\n                                                     local_path=str(f),\n                                                     iteration=iteration)\n \n-    def log_image_with_boxes(self, image_path, boxes, class_names, image):\n+    def log_image_with_boxes(self, image_path, boxes, class_names, image, conf_threshold=0.25):\n         \"\"\"\n-        Draw the bounding boxes on a single image and report the result as a ClearML debug sample\n+        Draw the bounding boxes on a single image and report the result as a ClearML debug sample.\n \n         arguments:\n         image_path (PosixPath) the path the original image file\n@@ -133,16 +135,20 @@\n         if len(self.current_epoch_logged_images) < self.max_imgs_to_log_per_epoch and self.current_epoch >= 0:\n             # Log every bbox_interval times and deduplicate for any intermittend extra eval runs\n             if self.current_epoch % self.bbox_interval == 0 and image_path not in self.current_epoch_logged_images:\n-                converter = ToPILImage()\n-                labels = []\n-                for conf, class_nr in zip(boxes[:, 4], boxes[:, 5]):\n+                im = np.ascontiguousarray(np.moveaxis(image.mul(255).clamp(0, 255).byte().cpu().numpy(), 0, 2))\n+                annotator = Annotator(im=im, pil=True)\n+                for i, (conf, class_nr, box) in enumerate(zip(boxes[:, 4], boxes[:, 5], boxes[:, :4])):\n+                    color = colors(i)\n+\n                     class_name = class_names[int(class_nr)]\n                     confidence = round(float(conf) * 100, 2)\n-                    labels.append(f\"{class_name}: {confidence}%\")\n-                annotated_image = converter(\n-                    draw_bounding_boxes(image=image.mul(255).clamp(0, 255).byte().cpu(),\n-                                        boxes=boxes[:, :4],\n-                                        labels=labels))\n+                    label = f\"{class_name}: {confidence}%\"\n+\n+                    if confidence > conf_threshold:\n+                        annotator.rectangle(box.cpu().numpy(), outline=color)\n+                        annotator.box_label(box.cpu().numpy(), label=label, color=color)\n+\n+                annotated_image = annotator.result()\n                 self.task.get_logger().report_image(title='Bounding Boxes',\n                                                     series=image_path.name,\n                                                     iteration=self.current_epoch,\n", "issue": "ImportError: cannot import name 'draw_bounding_boxes' from 'torchvision.utils'\n### Search before asking\n\n- [X] I have searched the YOLOv5 [issues](https://github.com/ultralytics/yolov5/issues) and found no similar bug report.\n\n\n### YOLOv5 Component\n\nTraining\n\n### Bug\n\n![image](https://user-images.githubusercontent.com/68814215/183353020-07a5ae3e-ecd8-4c81-be9d-fd40caea15b2.png)\r\n\n\n### Environment\n\n_No response_\n\n### Minimal Reproducible Example\n\n_No response_\n\n### Additional\n\n_No response_\n\n### Are you willing to submit a PR?\n\n- [ ] Yes I'd like to help by submitting a PR!\n", "before_files": [{"content": "\"\"\"Main Logger class for ClearML experiment tracking.\"\"\"\nimport glob\nimport re\nfrom pathlib import Path\n\nimport yaml\nfrom torchvision.transforms import ToPILImage\n\ntry:\n    import clearml\n    from clearml import Dataset, Task\n    from torchvision.utils import draw_bounding_boxes  # WARNING: requires torchvision>=0.9.0\n\n    assert hasattr(clearml, '__version__')  # verify package import not local dir\nexcept (ImportError, AssertionError):\n    clearml = None\n\n\ndef construct_dataset(clearml_info_string):\n    dataset_id = clearml_info_string.replace('clearml://', '')\n    dataset = Dataset.get(dataset_id=dataset_id)\n    dataset_root_path = Path(dataset.get_local_copy())\n\n    # We'll search for the yaml file definition in the dataset\n    yaml_filenames = list(glob.glob(str(dataset_root_path / \"*.yaml\")) + glob.glob(str(dataset_root_path / \"*.yml\")))\n    if len(yaml_filenames) > 1:\n        raise ValueError('More than one yaml file was found in the dataset root, cannot determine which one contains '\n                         'the dataset definition this way.')\n    elif len(yaml_filenames) == 0:\n        raise ValueError('No yaml definition found in dataset root path, check that there is a correct yaml file '\n                         'inside the dataset root path.')\n    with open(yaml_filenames[0]) as f:\n        dataset_definition = yaml.safe_load(f)\n\n    assert set(dataset_definition.keys()).issuperset(\n        {'train', 'test', 'val', 'nc', 'names'}\n    ), \"The right keys were not found in the yaml file, make sure it at least has the following keys: ('train', 'test', 'val', 'nc', 'names')\"\n\n    data_dict = dict()\n    data_dict['train'] = str(\n        (dataset_root_path / dataset_definition['train']).resolve()) if dataset_definition['train'] else None\n    data_dict['test'] = str(\n        (dataset_root_path / dataset_definition['test']).resolve()) if dataset_definition['test'] else None\n    data_dict['val'] = str(\n        (dataset_root_path / dataset_definition['val']).resolve()) if dataset_definition['val'] else None\n    data_dict['nc'] = dataset_definition['nc']\n    data_dict['names'] = dataset_definition['names']\n\n    return data_dict\n\n\nclass ClearmlLogger:\n    \"\"\"Log training runs, datasets, models, and predictions to ClearML.\n\n    This logger sends information to ClearML at app.clear.ml or to your own hosted server. By default,\n    this information includes hyperparameters, system configuration and metrics, model metrics, code information and\n    basic data metrics and analyses.\n\n    By providing additional command line arguments to train.py, datasets,\n    models and predictions can also be logged.\n    \"\"\"\n\n    def __init__(self, opt, hyp):\n        \"\"\"\n        - Initialize ClearML Task, this object will capture the experiment\n        - Upload dataset version to ClearML Data if opt.upload_dataset is True\n\n        arguments:\n        opt (namespace) -- Commandline arguments for this run\n        hyp (dict) -- Hyperparameters for this run\n\n        \"\"\"\n        self.current_epoch = 0\n        # Keep tracked of amount of logged images to enforce a limit\n        self.current_epoch_logged_images = set()\n        # Maximum number of images to log to clearML per epoch\n        self.max_imgs_to_log_per_epoch = 16\n        # Get the interval of epochs when bounding box images should be logged\n        self.bbox_interval = opt.bbox_interval\n        self.clearml = clearml\n        self.task = None\n        self.data_dict = None\n        if self.clearml:\n            self.task = Task.init(\n                project_name='YOLOv5',\n                task_name='training',\n                tags=['YOLOv5'],\n                output_uri=True,\n                auto_connect_frameworks={'pytorch': False}\n                # We disconnect pytorch auto-detection, because we added manual model save points in the code\n            )\n            # ClearML's hooks will already grab all general parameters\n            # Only the hyperparameters coming from the yaml config file\n            # will have to be added manually!\n            self.task.connect(hyp, name='Hyperparameters')\n\n            # Get ClearML Dataset Version if requested\n            if opt.data.startswith('clearml://'):\n                # data_dict should have the following keys:\n                # names, nc (number of classes), test, train, val (all three relative paths to ../datasets)\n                self.data_dict = construct_dataset(opt.data)\n                # Set data to data_dict because wandb will crash without this information and opt is the best way\n                # to give it to them\n                opt.data = self.data_dict\n\n    def log_debug_samples(self, files, title='Debug Samples'):\n        \"\"\"\n        Log files (images) as debug samples in the ClearML task.\n\n        arguments:\n        files (List(PosixPath)) a list of file paths in PosixPath format\n        title (str) A title that groups together images with the same values\n        \"\"\"\n        for f in files:\n            if f.exists():\n                it = re.search(r'_batch(\\d+)', f.name)\n                iteration = int(it.groups()[0]) if it else 0\n                self.task.get_logger().report_image(title=title,\n                                                    series=f.name.replace(it.group(), ''),\n                                                    local_path=str(f),\n                                                    iteration=iteration)\n\n    def log_image_with_boxes(self, image_path, boxes, class_names, image):\n        \"\"\"\n        Draw the bounding boxes on a single image and report the result as a ClearML debug sample\n\n        arguments:\n        image_path (PosixPath) the path the original image file\n        boxes (list): list of scaled predictions in the format - [xmin, ymin, xmax, ymax, confidence, class]\n        class_names (dict): dict containing mapping of class int to class name\n        image (Tensor): A torch tensor containing the actual image data\n        \"\"\"\n        if len(self.current_epoch_logged_images) < self.max_imgs_to_log_per_epoch and self.current_epoch >= 0:\n            # Log every bbox_interval times and deduplicate for any intermittend extra eval runs\n            if self.current_epoch % self.bbox_interval == 0 and image_path not in self.current_epoch_logged_images:\n                converter = ToPILImage()\n                labels = []\n                for conf, class_nr in zip(boxes[:, 4], boxes[:, 5]):\n                    class_name = class_names[int(class_nr)]\n                    confidence = round(float(conf) * 100, 2)\n                    labels.append(f\"{class_name}: {confidence}%\")\n                annotated_image = converter(\n                    draw_bounding_boxes(image=image.mul(255).clamp(0, 255).byte().cpu(),\n                                        boxes=boxes[:, :4],\n                                        labels=labels))\n                self.task.get_logger().report_image(title='Bounding Boxes',\n                                                    series=image_path.name,\n                                                    iteration=self.current_epoch,\n                                                    image=annotated_image)\n                self.current_epoch_logged_images.add(image_path)\n", "path": "utils/loggers/clearml/clearml_utils.py"}], "after_files": [{"content": "\"\"\"Main Logger class for ClearML experiment tracking.\"\"\"\nimport glob\nimport re\nfrom pathlib import Path\n\nimport numpy as np\nimport yaml\n\nfrom utils.plots import Annotator, colors\n\ntry:\n    import clearml\n    from clearml import Dataset, Task\n    assert hasattr(clearml, '__version__')  # verify package import not local dir\nexcept (ImportError, AssertionError):\n    clearml = None\n\n\ndef construct_dataset(clearml_info_string):\n    \"\"\"Load in a clearml dataset and fill the internal data_dict with its contents.\n    \"\"\"\n    dataset_id = clearml_info_string.replace('clearml://', '')\n    dataset = Dataset.get(dataset_id=dataset_id)\n    dataset_root_path = Path(dataset.get_local_copy())\n\n    # We'll search for the yaml file definition in the dataset\n    yaml_filenames = list(glob.glob(str(dataset_root_path / \"*.yaml\")) + glob.glob(str(dataset_root_path / \"*.yml\")))\n    if len(yaml_filenames) > 1:\n        raise ValueError('More than one yaml file was found in the dataset root, cannot determine which one contains '\n                         'the dataset definition this way.')\n    elif len(yaml_filenames) == 0:\n        raise ValueError('No yaml definition found in dataset root path, check that there is a correct yaml file '\n                         'inside the dataset root path.')\n    with open(yaml_filenames[0]) as f:\n        dataset_definition = yaml.safe_load(f)\n\n    assert set(dataset_definition.keys()).issuperset(\n        {'train', 'test', 'val', 'nc', 'names'}\n    ), \"The right keys were not found in the yaml file, make sure it at least has the following keys: ('train', 'test', 'val', 'nc', 'names')\"\n\n    data_dict = dict()\n    data_dict['train'] = str(\n        (dataset_root_path / dataset_definition['train']).resolve()) if dataset_definition['train'] else None\n    data_dict['test'] = str(\n        (dataset_root_path / dataset_definition['test']).resolve()) if dataset_definition['test'] else None\n    data_dict['val'] = str(\n        (dataset_root_path / dataset_definition['val']).resolve()) if dataset_definition['val'] else None\n    data_dict['nc'] = dataset_definition['nc']\n    data_dict['names'] = dataset_definition['names']\n\n    return data_dict\n\n\nclass ClearmlLogger:\n    \"\"\"Log training runs, datasets, models, and predictions to ClearML.\n\n    This logger sends information to ClearML at app.clear.ml or to your own hosted server. By default,\n    this information includes hyperparameters, system configuration and metrics, model metrics, code information and\n    basic data metrics and analyses.\n\n    By providing additional command line arguments to train.py, datasets,\n    models and predictions can also be logged.\n    \"\"\"\n\n    def __init__(self, opt, hyp):\n        \"\"\"\n        - Initialize ClearML Task, this object will capture the experiment\n        - Upload dataset version to ClearML Data if opt.upload_dataset is True\n\n        arguments:\n        opt (namespace) -- Commandline arguments for this run\n        hyp (dict) -- Hyperparameters for this run\n\n        \"\"\"\n        self.current_epoch = 0\n        # Keep tracked of amount of logged images to enforce a limit\n        self.current_epoch_logged_images = set()\n        # Maximum number of images to log to clearML per epoch\n        self.max_imgs_to_log_per_epoch = 16\n        # Get the interval of epochs when bounding box images should be logged\n        self.bbox_interval = opt.bbox_interval\n        self.clearml = clearml\n        self.task = None\n        self.data_dict = None\n        if self.clearml:\n            self.task = Task.init(\n                project_name='YOLOv5',\n                task_name='training',\n                tags=['YOLOv5'],\n                output_uri=True,\n                auto_connect_frameworks={'pytorch': False}\n                # We disconnect pytorch auto-detection, because we added manual model save points in the code\n            )\n            # ClearML's hooks will already grab all general parameters\n            # Only the hyperparameters coming from the yaml config file\n            # will have to be added manually!\n            self.task.connect(hyp, name='Hyperparameters')\n\n            # Get ClearML Dataset Version if requested\n            if opt.data.startswith('clearml://'):\n                # data_dict should have the following keys:\n                # names, nc (number of classes), test, train, val (all three relative paths to ../datasets)\n                self.data_dict = construct_dataset(opt.data)\n                # Set data to data_dict because wandb will crash without this information and opt is the best way\n                # to give it to them\n                opt.data = self.data_dict\n\n    def log_debug_samples(self, files, title='Debug Samples'):\n        \"\"\"\n        Log files (images) as debug samples in the ClearML task.\n\n        arguments:\n        files (List(PosixPath)) a list of file paths in PosixPath format\n        title (str) A title that groups together images with the same values\n        \"\"\"\n        for f in files:\n            if f.exists():\n                it = re.search(r'_batch(\\d+)', f.name)\n                iteration = int(it.groups()[0]) if it else 0\n                self.task.get_logger().report_image(title=title,\n                                                    series=f.name.replace(it.group(), ''),\n                                                    local_path=str(f),\n                                                    iteration=iteration)\n\n    def log_image_with_boxes(self, image_path, boxes, class_names, image, conf_threshold=0.25):\n        \"\"\"\n        Draw the bounding boxes on a single image and report the result as a ClearML debug sample.\n\n        arguments:\n        image_path (PosixPath) the path the original image file\n        boxes (list): list of scaled predictions in the format - [xmin, ymin, xmax, ymax, confidence, class]\n        class_names (dict): dict containing mapping of class int to class name\n        image (Tensor): A torch tensor containing the actual image data\n        \"\"\"\n        if len(self.current_epoch_logged_images) < self.max_imgs_to_log_per_epoch and self.current_epoch >= 0:\n            # Log every bbox_interval times and deduplicate for any intermittend extra eval runs\n            if self.current_epoch % self.bbox_interval == 0 and image_path not in self.current_epoch_logged_images:\n                im = np.ascontiguousarray(np.moveaxis(image.mul(255).clamp(0, 255).byte().cpu().numpy(), 0, 2))\n                annotator = Annotator(im=im, pil=True)\n                for i, (conf, class_nr, box) in enumerate(zip(boxes[:, 4], boxes[:, 5], boxes[:, :4])):\n                    color = colors(i)\n\n                    class_name = class_names[int(class_nr)]\n                    confidence = round(float(conf) * 100, 2)\n                    label = f\"{class_name}: {confidence}%\"\n\n                    if confidence > conf_threshold:\n                        annotator.rectangle(box.cpu().numpy(), outline=color)\n                        annotator.box_label(box.cpu().numpy(), label=label, color=color)\n\n                annotated_image = annotator.result()\n                self.task.get_logger().report_image(title='Bounding Boxes',\n                                                    series=image_path.name,\n                                                    iteration=self.current_epoch,\n                                                    image=annotated_image)\n                self.current_epoch_logged_images.add(image_path)\n", "path": "utils/loggers/clearml/clearml_utils.py"}]}