diff --git a/docs/datasets/detect/index.md b/docs/datasets/detect/index.md index f93e6b01..448a8321 100644 --- a/docs/datasets/detect/index.md +++ b/docs/datasets/detect/index.md @@ -93,11 +93,15 @@ If you have your own dataset and would like to use it for training detection mod You can easily convert labels from the popular COCO dataset format to the YOLO format using the following code snippet: -```python -from ultralytics.data.converter import convert_coco +!!! example "" -convert_coco(labels_dir='../coco/annotations/') -``` + === "Python" + + ```python + from ultralytics.data.converter import convert_coco + + convert_coco(labels_dir='path/to/coco/annotations/') + ``` This conversion tool can be used to convert the COCO dataset or any dataset in the COCO format to the Ultralytics YOLO format. diff --git a/docs/datasets/obb/index.md b/docs/datasets/obb/index.md index d74f03cc..bb0a691d 100644 --- a/docs/datasets/obb/index.md +++ b/docs/datasets/obb/index.md @@ -69,11 +69,15 @@ For those looking to introduce their own datasets with oriented bounding boxes, Transitioning labels from the DOTA dataset format to the YOLO OBB format can be achieved with this script: -```python -from ultralytics.data.converter import convert_dota_to_yolo_obb +!!! example "" -convert_dota_to_yolo_obb('path/to/DOTA') -``` + === "Python" + + ```python + from ultralytics.data.converter import convert_dota_to_yolo_obb + + convert_dota_to_yolo_obb('path/to/DOTA') + ``` This conversion mechanism is instrumental for datasets in the DOTA format, ensuring alignment with the Ultralytics YOLO OBB format. diff --git a/docs/datasets/pose/index.md b/docs/datasets/pose/index.md index 56a6c35e..7e51afe3 100644 --- a/docs/datasets/pose/index.md +++ b/docs/datasets/pose/index.md @@ -10,9 +10,7 @@ keywords: Ultralytics, YOLO, pose estimation, datasets, training, YAML, keypoint ### Ultralytics YOLO format -** Label Format ** - -The dataset format used for training YOLO pose models is as follows: +The dataset label format used for training YOLO pose models is as follows: 1. One text file per image: Each image in the dataset has a corresponding text file with the same name as the image file and the ".txt" extension. 2. One row per object: Each row in the text file corresponds to one object instance in the image. @@ -119,10 +117,14 @@ If you have your own dataset and would like to use it for training pose estimati Ultralytics provides a convenient conversion tool to convert labels from the popular COCO dataset format to YOLO format: -```python -from ultralytics.data.converter import convert_coco +!!! example "" -convert_coco(labels_dir='../coco/annotations/', use_keypoints=True) -``` + === "Python" + + ```python + from ultralytics.data.converter import convert_coco + + convert_coco(labels_dir='path/to/coco/annotations/', use_keypoints=True) + ``` This conversion tool can be used to convert the COCO dataset or any dataset in the COCO format to the Ultralytics YOLO format. The `use_keypoints` parameter specifies whether to include keypoints (for pose estimation) in the converted labels. diff --git a/docs/datasets/segment/index.md b/docs/datasets/segment/index.md index 915feca4..b87dc6e5 100644 --- a/docs/datasets/segment/index.md +++ b/docs/datasets/segment/index.md @@ -10,9 +10,7 @@ keywords: Ultralytics, YOLO, Instance Segmentation, Dataset, YAML, COCO, Auto-An ### Ultralytics YOLO format -** Label Format ** - -The dataset format used for training YOLO segmentation models is as follows: +The dataset label format used for training YOLO segmentation models is as follows: 1. One text file per image: Each image in the dataset has a corresponding text file with the same name as the image file and the ".txt" extension. 2. One row per object: Each row in the text file corresponds to one object instance in the image. @@ -28,16 +26,16 @@ The format for a single row in the segmentation dataset file is as follows: In this format, `` is the index of the class for the object, and ` ... ` are the bounding coordinates of the object's segmentation mask. The coordinates are separated by spaces. -Here is an example of the YOLO dataset format for a single image with two object instances: +Here is an example of the YOLO dataset format for a single image with two objects made up of a 3-point segment and a 5-point segment. ``` -0 0.6812 0.48541 0.67 0.4875 0.67656 0.487 0.675 0.489 0.66 -1 0.5046 0.0 0.5015 0.004 0.4984 0.00416 0.4937 0.010 0.492 0.0104 +0 0.681 0.485 0.670 0.487 0.676 0.487 +1 0.504 0.000 0.501 0.004 0.498 0.004 0.493 0.010 0.492 0.0104 ``` !!! tip "Tip" - - The length of each row does not have to be equal. + - The length of each row does **not** have to be equal. - Each segmentation label must have a **minimum of 3 xy points**: ` ` ### Dataset YAML format @@ -103,11 +101,15 @@ If you have your own dataset and would like to use it for training segmentation You can easily convert labels from the popular COCO dataset format to the YOLO format using the following code snippet: -```python -from ultralytics.data.converter import convert_coco +!!! example "" -convert_coco(labels_dir='../coco/annotations/', use_segments=True) -``` + === "Python" + + ```python + from ultralytics.data.converter import convert_coco + + convert_coco(labels_dir='path/to/coco/annotations/', use_segments=True) + ``` This conversion tool can be used to convert the COCO dataset or any dataset in the COCO format to the Ultralytics YOLO format. @@ -121,11 +123,15 @@ Auto-annotation is an essential feature that allows you to generate a segmentati To auto-annotate your dataset using the Ultralytics framework, you can use the `auto_annotate` function as shown below: -```python -from ultralytics.data.annotator import auto_annotate +!!! example "" -auto_annotate(data="path/to/images", det_model="yolov8x.pt", sam_model='sam_b.pt') -``` + === "Python" + + ```python + from ultralytics.data.annotator import auto_annotate + + auto_annotate(data="path/to/images", det_model="yolov8x.pt", sam_model='sam_b.pt') + ``` | Argument | Type | Description | Default | |------------|---------------------|---------------------------------------------------------------------------------------------------------|--------------| diff --git a/docs/modes/predict.md b/docs/modes/predict.md index e373d01a..5981db98 100644 --- a/docs/modes/predict.md +++ b/docs/modes/predict.md @@ -264,7 +264,7 @@ Below are code examples for using each source type: ``` === "Streams" - Run inference on remote streaming sources using RTSP, RTMP, and IP address protocols. If mutliple streams are provided in a `*.streams` text file then batched inference will run, i.e. 8 streams will run at batch-size 8, otherwise single streams will run at batch-size 1. + Run inference on remote streaming sources using RTSP, RTMP, and IP address protocols. If multiple streams are provided in a `*.streams` text file then batched inference will run, i.e. 8 streams will run at batch-size 8, otherwise single streams will run at batch-size 1. ```python from ultralytics import YOLO diff --git a/docs/quickstart.md b/docs/quickstart.md index 2a6bd5d7..bde75e78 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -41,7 +41,7 @@ Ultralytics provides various installation methods including pip, conda, and Dock !!! note - If you are installing in a CUDA environment best practice is to install `ultralytics`, `pytorch` and `pytorch-cuda` in the same command to allow the conda package manager to resolve any conflicts, or else to install `pytorch-cuda` last to allow it override the CPU-specific `pytorch` package if necesary. + If you are installing in a CUDA environment best practice is to install `ultralytics`, `pytorch` and `pytorch-cuda` in the same command to allow the conda package manager to resolve any conflicts, or else to install `pytorch-cuda` last to allow it override the CPU-specific `pytorch` package if necessary. ```bash # Install all packages together using conda conda install -c conda-forge -c pytorch -c nvidia ultralytics pytorch torchvision pytorch-cuda=11.8 diff --git a/setup.py b/setup.py index 22d7f462..d4f6e996 100644 --- a/setup.py +++ b/setup.py @@ -47,7 +47,7 @@ setup( 'mkdocs-material', 'mkdocstrings[python]', 'mkdocs-redirects', # for 301 redirects - 'mkdocs-ultralytics-plugin>=0.0.25', # for meta descriptions and images, dates and authors + 'mkdocs-ultralytics-plugin>=0.0.26', # for meta descriptions and images, dates and authors ], 'export': [ 'coremltools>=7.0.b1', diff --git a/ultralytics/data/base.py b/ultralytics/data/base.py index bfc3cc19..3fbb82bf 100644 --- a/ultralytics/data/base.py +++ b/ultralytics/data/base.py @@ -115,7 +115,7 @@ class BaseDataset(Dataset): raise FileNotFoundError(f'{self.prefix}{p} does not exist') im_files = sorted(x.replace('/', os.sep) for x in f if x.split('.')[-1].lower() in IMG_FORMATS) # self.img_files = sorted([x for x in f if x.suffix[1:].lower() in IMG_FORMATS]) # pathlib - assert im_files, f'{self.prefix}No images found' + assert im_files, f'{self.prefix}No images found in {img_path}' except Exception as e: raise FileNotFoundError(f'{self.prefix}Error loading data from {img_path}\n{HELP_URL}') from e if self.fraction < 1: diff --git a/ultralytics/data/dataset.py b/ultralytics/data/dataset.py index cf3a7ce9..515c4823 100644 --- a/ultralytics/data/dataset.py +++ b/ultralytics/data/dataset.py @@ -110,13 +110,12 @@ class YOLODataset(BaseDataset): tqdm(None, desc=self.prefix + d, total=n, initial=n, bar_format=TQDM_BAR_FORMAT) # display results if cache['msgs']: LOGGER.info('\n'.join(cache['msgs'])) # display warnings - if nf == 0: # number of labels found - raise FileNotFoundError(f'{self.prefix}No labels found in {cache_path}, can not start training. {HELP_URL}') # Read cache [cache.pop(k) for k in ('hash', 'version', 'msgs')] # remove items labels = cache['labels'] - assert len(labels), f'No valid labels found, please check your dataset. {HELP_URL}' + if not labels: + LOGGER.warning(f'WARNING ⚠️ No images found in {cache_path}, training may not work correctly. {HELP_URL}') self.im_files = [lb['im_file'] for lb in labels] # update im_files # Check if the dataset is all boxes or all segments @@ -130,10 +129,9 @@ class YOLODataset(BaseDataset): for lb in labels: lb['segments'] = [] if len_cls == 0: - raise ValueError(f'All labels empty in {cache_path}, can not start training without labels. {HELP_URL}') + LOGGER.warning(f'WARNING ⚠️ No labels found in {cache_path}, training may not work correctly. {HELP_URL}') return labels - # TODO: use hyp config to set all these augmentations def build_transforms(self, hyp=None): """Builds and appends transforms to the list.""" if self.augment: diff --git a/ultralytics/data/utils.py b/ultralytics/data/utils.py index 05b291ba..552b0784 100644 --- a/ultralytics/data/utils.py +++ b/ultralytics/data/utils.py @@ -447,10 +447,17 @@ class HUBDatasetStats: return [[int(c[0]), *(round(float(x), 4) for x in points)] for c, points in zipped] for split in 'train', 'val', 'test': - if self.data.get(split) is None: - self.stats[split] = None # i.e. no test set + self.stats[split] = None # predefine + path = self.data.get(split) + + # Check split + if path is None: # no split + continue + files = [f for f in Path(path).rglob('*.*') if f.suffix[1:].lower() in IMG_FORMATS] # image files in split + if not files: # no images continue + # Get dataset statistics dataset = YOLODataset(img_path=self.data[split], data=self.data, use_segments=self.task == 'segment',