Fix HUBDatasetStats for no-label edge cases (#4583)

main
Glenn Jocher 2 years ago committed by GitHub
parent 2db35afad5
commit f755ba88c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      docs/datasets/detect/index.md
  2. 4
      docs/datasets/obb/index.md
  3. 10
      docs/datasets/pose/index.md
  4. 22
      docs/datasets/segment/index.md
  5. 2
      docs/modes/predict.md
  6. 2
      docs/quickstart.md
  7. 2
      setup.py
  8. 2
      ultralytics/data/base.py
  9. 8
      ultralytics/data/dataset.py
  10. 11
      ultralytics/data/utils.py

@ -93,10 +93,14 @@ 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:
!!! example ""
=== "Python"
```python
from ultralytics.data.converter import convert_coco
convert_coco(labels_dir='../coco/annotations/')
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.

@ -69,6 +69,10 @@ 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:
!!! example ""
=== "Python"
```python
from ultralytics.data.converter import convert_dota_to_yolo_obb

@ -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:
!!! example ""
=== "Python"
```python
from ultralytics.data.converter import convert_coco
convert_coco(labels_dir='../coco/annotations/', use_keypoints=True)
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.

@ -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, `<class-index>` is the index of the class for the object, and `<x1> <y1> <x2> <y2> ... <xn> <yn>` 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**: `<class-index> <x1> <y1> <x2> <y2> <x3> <y3>`
### Dataset YAML format
@ -103,10 +101,14 @@ 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:
!!! example ""
=== "Python"
```python
from ultralytics.data.converter import convert_coco
convert_coco(labels_dir='../coco/annotations/', use_segments=True)
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,6 +123,10 @@ 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:
!!! example ""
=== "Python"
```python
from ultralytics.data.annotator import auto_annotate

@ -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

@ -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

@ -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',

@ -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:

@ -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:

@ -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',

Loading…
Cancel
Save