2021-08-15 03:17:51 +08:00
|
|
|
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
|
|
|
|
"""
|
|
|
|
Dataloaders and dataset utils
|
|
|
|
"""
|
2020-11-14 18:50:32 +08:00
|
|
|
|
2022-07-25 22:52:28 +08:00
|
|
|
import contextlib
|
2020-05-30 08:04:54 +08:00
|
|
|
import glob
|
2021-05-26 20:26:52 +08:00
|
|
|
import hashlib
|
2021-06-12 19:26:41 +08:00
|
|
|
import json
|
2022-01-05 11:32:42 +08:00
|
|
|
import math
|
2020-05-30 08:04:54 +08:00
|
|
|
import os
|
|
|
|
import random
|
|
|
|
import shutil
|
|
|
|
import time
|
2020-11-07 09:18:18 +08:00
|
|
|
from itertools import repeat
|
2021-11-05 00:24:25 +08:00
|
|
|
from multiprocessing.pool import Pool, ThreadPool
|
2020-05-30 08:04:54 +08:00
|
|
|
from pathlib import Path
|
|
|
|
from threading import Thread
|
2022-03-20 21:18:05 +08:00
|
|
|
from urllib.parse import urlparse
|
2021-09-25 23:52:36 +08:00
|
|
|
from zipfile import ZipFile
|
2020-05-30 08:04:54 +08:00
|
|
|
|
|
|
|
import numpy as np
|
|
|
|
import torch
|
2021-01-05 11:54:09 +08:00
|
|
|
import torch.nn.functional as F
|
New YOLOv5 Classification Models (#8956)
* Update
* Logger step fix: Increment step with epochs (#8654)
* enhance
* revert
* allow training from scratch
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update --img argument from train.py
single line
* fix image size from 640 to 128
* suport custom dataloader and augmentation
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* format
* Update dataloaders.py
* Single line return, single line comment, remove unused argument
* address PR comments
* fix spelling
* don't augment eval set
* use fstring
* update augmentations.py
* new maning convention for transforms
* reverse if statement, inline ops
* reverse if statement, inline ops
* updates
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update dataloaders
* Remove additional if statement
* Remove is_train as redundant
* Cleanup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Cleanup2
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update augmentations.py
* fix: imshow clip warning
* update
* Revert ToTensorV2 removal
* Update classifier.py
* Update normalize values, revert uint8
* normalize image using cv2
* remove dedundant comment
* Update classifier.py
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* replace print with logger
* commit steps
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Allow logging models from GenericLogger (#8676)
* enhance
* revert
* allow training from scratch
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update --img argument from train.py
single line
* fix image size from 640 to 128
* suport custom dataloader and augmentation
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* format
* Update dataloaders.py
* Single line return, single line comment, remove unused argument
* address PR comments
* fix spelling
* don't augment eval set
* use fstring
* update augmentations.py
* new maning convention for transforms
* reverse if statement, inline ops
* reverse if statement, inline ops
* updates
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update dataloaders
* Remove additional if statement
* Remove is_train as redundant
* Cleanup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Cleanup2
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update augmentations.py
* fix: imshow clip warning
* update
* Revert ToTensorV2 removal
* Update classifier.py
* Update normalize values, revert uint8
* normalize image using cv2
* remove dedundant comment
* Update classifier.py
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* replace print with logger
* commit steps
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* support final model logging
* update
* update
* update
* update
* remove curses
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update __init__.py
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
* Update
* Update
* Update
* Update
* Update dataset download
* Update dataset download
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Pass imgsz to classify_transforms()
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Cos scheduler
* Cos scheduler
* Remove unused args
* Update
* Add seed
* Add seed
* Update
* Update
* Add run(), main()
* Merge master
* Merge master
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Create YOLOv5 BaseModel class (#8829)
* Create BaseModel
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* fix
* Hub load device fix
* Update
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* Add experiment
* Merge master
* Attach names
* weight decay = 1e-4
* weight decay = 5e-5
* update smart_optimizer console printout
* fashion-mnist fix
* Merge master
* Update Table
* Update Table
* Remove destroy process group
* add kwargs to forward()
* fuse fix for resnet50
* nc, names fix for resnet50
* nc, names fix for resnet50
* ONNX CPU inference fix
* revert
* cuda
* if augment or visualize
* if augment or visualize
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* New smart_inference_mode()
* Update README
* Refactor into /classify dir
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* reset defaults
* reset defaults
* fix gpu predict
* warmup
* ema half fix
* spacing
* remove data
* remove cache
* remove denormalize
* save run settings
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* verbose false on initial plots
* new save_yaml() function
* Update ci-testing.yml
* Path(data) CI fix
* Separate classification CI
* fix val
* fix val
* fix val
* smartCrossEntropyLoss
* skip validation on hub load
* autodownload with working dir root
* str(data)
* Dataset usage example
* im_show normalize
* im_show normalize
* add imagenet simple names to multibackend
* Add validation speeds
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* 24-space names
* Update bash scripts
* Update permissions
* Add bash script arguments
* remove verbose
* TRT data fix
* names generator fix
* optimize if names
* update usage
* Add local loading
* Verbose=False
* update names printing
* Add Usage examples
* Add Usage examples
* Add Usage examples
* Add Usage examples
* named_children
* reshape_classifier_outputs
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update
* update
* fix CI
* fix incorrect class substitution
* fix incorrect class substitution
* remove denormalize
* ravel fix
* cleanup
* update opt file printing
* update opt file printing
* update defaults
* add opt to checkpoint
* Add warning
* Add comment
* plot half bug fix
* Use NotImplementedError
* fix export shape report
* Fix TRT load
* cleanup CI
* profile comment
* CI fix
* Add cls models
* avoid inplace error
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Fix usage examples
* Update README
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
Co-authored-by: Ayush Chaurasia <ayush.chaurarsia@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-17 17:59:01 +08:00
|
|
|
import torchvision
|
2021-06-09 05:09:45 +08:00
|
|
|
import yaml
|
2021-11-05 00:24:25 +08:00
|
|
|
from PIL import ExifTags, Image, ImageOps
|
2021-11-13 20:07:32 +08:00
|
|
|
from torch.utils.data import DataLoader, Dataset, dataloader, distributed
|
2022-04-27 06:00:01 +08:00
|
|
|
from tqdm import tqdm
|
2020-05-30 08:04:54 +08:00
|
|
|
|
New YOLOv5 Classification Models (#8956)
* Update
* Logger step fix: Increment step with epochs (#8654)
* enhance
* revert
* allow training from scratch
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update --img argument from train.py
single line
* fix image size from 640 to 128
* suport custom dataloader and augmentation
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* format
* Update dataloaders.py
* Single line return, single line comment, remove unused argument
* address PR comments
* fix spelling
* don't augment eval set
* use fstring
* update augmentations.py
* new maning convention for transforms
* reverse if statement, inline ops
* reverse if statement, inline ops
* updates
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update dataloaders
* Remove additional if statement
* Remove is_train as redundant
* Cleanup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Cleanup2
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update augmentations.py
* fix: imshow clip warning
* update
* Revert ToTensorV2 removal
* Update classifier.py
* Update normalize values, revert uint8
* normalize image using cv2
* remove dedundant comment
* Update classifier.py
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* replace print with logger
* commit steps
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Allow logging models from GenericLogger (#8676)
* enhance
* revert
* allow training from scratch
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update --img argument from train.py
single line
* fix image size from 640 to 128
* suport custom dataloader and augmentation
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* format
* Update dataloaders.py
* Single line return, single line comment, remove unused argument
* address PR comments
* fix spelling
* don't augment eval set
* use fstring
* update augmentations.py
* new maning convention for transforms
* reverse if statement, inline ops
* reverse if statement, inline ops
* updates
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update dataloaders
* Remove additional if statement
* Remove is_train as redundant
* Cleanup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Cleanup2
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update augmentations.py
* fix: imshow clip warning
* update
* Revert ToTensorV2 removal
* Update classifier.py
* Update normalize values, revert uint8
* normalize image using cv2
* remove dedundant comment
* Update classifier.py
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* replace print with logger
* commit steps
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* support final model logging
* update
* update
* update
* update
* remove curses
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update __init__.py
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
* Update
* Update
* Update
* Update
* Update dataset download
* Update dataset download
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Pass imgsz to classify_transforms()
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Cos scheduler
* Cos scheduler
* Remove unused args
* Update
* Add seed
* Add seed
* Update
* Update
* Add run(), main()
* Merge master
* Merge master
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Create YOLOv5 BaseModel class (#8829)
* Create BaseModel
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* fix
* Hub load device fix
* Update
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* Add experiment
* Merge master
* Attach names
* weight decay = 1e-4
* weight decay = 5e-5
* update smart_optimizer console printout
* fashion-mnist fix
* Merge master
* Update Table
* Update Table
* Remove destroy process group
* add kwargs to forward()
* fuse fix for resnet50
* nc, names fix for resnet50
* nc, names fix for resnet50
* ONNX CPU inference fix
* revert
* cuda
* if augment or visualize
* if augment or visualize
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* New smart_inference_mode()
* Update README
* Refactor into /classify dir
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* reset defaults
* reset defaults
* fix gpu predict
* warmup
* ema half fix
* spacing
* remove data
* remove cache
* remove denormalize
* save run settings
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* verbose false on initial plots
* new save_yaml() function
* Update ci-testing.yml
* Path(data) CI fix
* Separate classification CI
* fix val
* fix val
* fix val
* smartCrossEntropyLoss
* skip validation on hub load
* autodownload with working dir root
* str(data)
* Dataset usage example
* im_show normalize
* im_show normalize
* add imagenet simple names to multibackend
* Add validation speeds
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* 24-space names
* Update bash scripts
* Update permissions
* Add bash script arguments
* remove verbose
* TRT data fix
* names generator fix
* optimize if names
* update usage
* Add local loading
* Verbose=False
* update names printing
* Add Usage examples
* Add Usage examples
* Add Usage examples
* Add Usage examples
* named_children
* reshape_classifier_outputs
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update
* update
* fix CI
* fix incorrect class substitution
* fix incorrect class substitution
* remove denormalize
* ravel fix
* cleanup
* update opt file printing
* update opt file printing
* update defaults
* add opt to checkpoint
* Add warning
* Add comment
* plot half bug fix
* Use NotImplementedError
* fix export shape report
* Fix TRT load
* cleanup CI
* profile comment
* CI fix
* Add cls models
* avoid inplace error
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Fix usage examples
* Update README
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
Co-authored-by: Ayush Chaurasia <ayush.chaurarsia@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-17 17:59:01 +08:00
|
|
|
from utils.augmentations import (Albumentations, augment_hsv, classify_albumentations, classify_transforms, copy_paste,
|
|
|
|
letterbox, mixup, random_perspective)
|
2022-02-09 05:20:44 +08:00
|
|
|
from utils.general import (DATASETS_DIR, LOGGER, NUM_THREADS, check_dataset, check_requirements, check_yaml, clean_str,
|
2022-06-14 20:28:21 +08:00
|
|
|
cv2, is_colab, is_kaggle, segments2boxes, xyn2xy, xywh2xyxy, xywhn2xyxy, xyxy2xywhn)
|
2022-01-28 15:18:01 +08:00
|
|
|
from utils.torch_utils import torch_distributed_zero_first
|
2020-05-30 08:04:54 +08:00
|
|
|
|
2020-11-14 18:50:32 +08:00
|
|
|
# Parameters
|
2022-08-19 21:07:04 +08:00
|
|
|
HELP_URL = 'See https://github.com/ultralytics/yolov5/wiki/Train-Custom-Data'
|
2022-08-31 23:31:13 +08:00
|
|
|
IMG_FORMATS = 'bmp', 'dng', 'jpeg', 'jpg', 'mpo', 'png', 'tif', 'tiff', 'webp', 'pfm' # include image suffixes
|
2022-03-04 21:10:13 +08:00
|
|
|
VID_FORMATS = 'asf', 'avi', 'gif', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'ts', 'wmv' # include video suffixes
|
2022-03-15 23:32:56 +08:00
|
|
|
BAR_FORMAT = '{l_bar}{bar:10}{r_bar}{bar:-10b}' # tqdm bar format
|
2022-04-07 22:44:08 +08:00
|
|
|
LOCAL_RANK = int(os.getenv('LOCAL_RANK', -1)) # https://pytorch.org/docs/stable/elastic/run.html
|
2022-09-01 20:30:21 +08:00
|
|
|
PIN_MEMORY = str(os.getenv('PIN_MEMORY', True)).lower() == 'true' # global pin_memory for dataloaders
|
2020-05-30 08:04:54 +08:00
|
|
|
|
|
|
|
# Get orientation exif tag
|
|
|
|
for orientation in ExifTags.TAGS.keys():
|
|
|
|
if ExifTags.TAGS[orientation] == 'Orientation':
|
|
|
|
break
|
|
|
|
|
|
|
|
|
2021-05-26 20:26:52 +08:00
|
|
|
def get_hash(paths):
|
|
|
|
# Returns a single hash value of a list of paths (files or dirs)
|
|
|
|
size = sum(os.path.getsize(p) for p in paths if os.path.exists(p)) # sizes
|
|
|
|
h = hashlib.md5(str(size).encode()) # hash sizes
|
|
|
|
h.update(''.join(paths).encode()) # hash paths
|
|
|
|
return h.hexdigest() # return hash
|
2020-07-10 11:07:16 +08:00
|
|
|
|
|
|
|
|
2020-05-30 08:04:54 +08:00
|
|
|
def exif_size(img):
|
|
|
|
# Returns exif-corrected PIL size
|
|
|
|
s = img.size # (width, height)
|
2022-07-25 22:52:28 +08:00
|
|
|
with contextlib.suppress(Exception):
|
2020-05-30 08:04:54 +08:00
|
|
|
rotation = dict(img._getexif().items())[orientation]
|
2022-05-15 22:38:26 +08:00
|
|
|
if rotation in [6, 8]: # rotation 270 or 90
|
2020-05-30 08:04:54 +08:00
|
|
|
s = (s[1], s[0])
|
|
|
|
return s
|
|
|
|
|
|
|
|
|
2021-07-02 19:25:54 +08:00
|
|
|
def exif_transpose(image):
|
|
|
|
"""
|
|
|
|
Transpose a PIL image accordingly if it has an EXIF Orientation tag.
|
2021-10-21 03:35:47 +08:00
|
|
|
Inplace version of https://github.com/python-pillow/Pillow/blob/master/src/PIL/ImageOps.py exif_transpose()
|
2021-07-02 19:25:54 +08:00
|
|
|
|
|
|
|
:param image: The image to transpose.
|
|
|
|
:return: An image.
|
|
|
|
"""
|
|
|
|
exif = image.getexif()
|
|
|
|
orientation = exif.get(0x0112, 1) # default 1
|
|
|
|
if orientation > 1:
|
2022-03-31 22:52:34 +08:00
|
|
|
method = {
|
|
|
|
2: Image.FLIP_LEFT_RIGHT,
|
|
|
|
3: Image.ROTATE_180,
|
|
|
|
4: Image.FLIP_TOP_BOTTOM,
|
|
|
|
5: Image.TRANSPOSE,
|
|
|
|
6: Image.ROTATE_270,
|
|
|
|
7: Image.TRANSVERSE,
|
2022-09-01 20:30:21 +08:00
|
|
|
8: Image.ROTATE_90}.get(orientation)
|
2021-07-02 19:25:54 +08:00
|
|
|
if method is not None:
|
|
|
|
image = image.transpose(method)
|
|
|
|
del exif[0x0112]
|
|
|
|
image.info["exif"] = exif.tobytes()
|
|
|
|
return image
|
|
|
|
|
|
|
|
|
2022-07-23 07:25:17 +08:00
|
|
|
def seed_worker(worker_id):
|
|
|
|
# Set dataloader worker seed https://pytorch.org/docs/stable/notes/randomness.html#dataloader
|
|
|
|
worker_seed = torch.initial_seed() % 2 ** 32
|
|
|
|
np.random.seed(worker_seed)
|
|
|
|
random.seed(worker_seed)
|
|
|
|
|
|
|
|
|
2022-03-31 22:52:34 +08:00
|
|
|
def create_dataloader(path,
|
|
|
|
imgsz,
|
|
|
|
batch_size,
|
|
|
|
stride,
|
|
|
|
single_cls=False,
|
|
|
|
hyp=None,
|
|
|
|
augment=False,
|
|
|
|
cache=False,
|
|
|
|
pad=0.0,
|
|
|
|
rect=False,
|
|
|
|
rank=-1,
|
|
|
|
workers=8,
|
|
|
|
image_weights=False,
|
|
|
|
quad=False,
|
|
|
|
prefix='',
|
|
|
|
shuffle=False):
|
2021-11-13 20:07:32 +08:00
|
|
|
if rect and shuffle:
|
|
|
|
LOGGER.warning('WARNING: --rect is incompatible with DataLoader shuffle, setting shuffle=False')
|
|
|
|
shuffle = False
|
|
|
|
with torch_distributed_zero_first(rank): # init dataset *.cache only once if DDP
|
2022-03-31 22:52:34 +08:00
|
|
|
dataset = LoadImagesAndLabels(
|
|
|
|
path,
|
|
|
|
imgsz,
|
|
|
|
batch_size,
|
|
|
|
augment=augment, # augmentation
|
|
|
|
hyp=hyp, # hyperparameters
|
|
|
|
rect=rect, # rectangular batches
|
|
|
|
cache_images=cache,
|
|
|
|
single_cls=single_cls,
|
|
|
|
stride=int(stride),
|
|
|
|
pad=pad,
|
|
|
|
image_weights=image_weights,
|
|
|
|
prefix=prefix)
|
2020-06-27 09:56:13 +08:00
|
|
|
|
|
|
|
batch_size = min(batch_size, len(dataset))
|
2022-01-28 15:18:01 +08:00
|
|
|
nd = torch.cuda.device_count() # number of CUDA devices
|
2022-02-21 04:47:46 +08:00
|
|
|
nw = min([os.cpu_count() // max(nd, 1), batch_size if batch_size > 1 else 0, workers]) # number of workers
|
2021-11-13 20:07:32 +08:00
|
|
|
sampler = None if rank == -1 else distributed.DistributedSampler(dataset, shuffle=shuffle)
|
|
|
|
loader = DataLoader if image_weights else InfiniteDataLoader # only DataLoader allows for attribute updates
|
2022-07-23 07:25:17 +08:00
|
|
|
generator = torch.Generator()
|
|
|
|
generator.manual_seed(0)
|
2021-11-13 20:07:32 +08:00
|
|
|
return loader(dataset,
|
|
|
|
batch_size=batch_size,
|
|
|
|
shuffle=shuffle and sampler is None,
|
|
|
|
num_workers=nw,
|
|
|
|
sampler=sampler,
|
2022-09-01 20:30:21 +08:00
|
|
|
pin_memory=PIN_MEMORY,
|
2022-07-23 07:25:17 +08:00
|
|
|
collate_fn=LoadImagesAndLabels.collate_fn4 if quad else LoadImagesAndLabels.collate_fn,
|
|
|
|
worker_init_fn=seed_worker,
|
|
|
|
generator=generator), dataset
|
2021-11-13 20:07:32 +08:00
|
|
|
|
|
|
|
|
|
|
|
class InfiniteDataLoader(dataloader.DataLoader):
|
2020-11-14 18:50:32 +08:00
|
|
|
""" Dataloader that reuses workers
|
2020-09-01 02:01:25 +08:00
|
|
|
|
2020-11-14 18:50:32 +08:00
|
|
|
Uses same syntax as vanilla DataLoader
|
2020-09-02 08:02:47 +08:00
|
|
|
"""
|
2022-04-05 04:47:00 +08:00
|
|
|
|
2020-09-01 02:01:25 +08:00
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
super().__init__(*args, **kwargs)
|
2020-09-11 03:27:35 +08:00
|
|
|
object.__setattr__(self, 'batch_sampler', _RepeatSampler(self.batch_sampler))
|
2020-09-01 02:01:25 +08:00
|
|
|
self.iterator = super().__iter__()
|
|
|
|
|
|
|
|
def __len__(self):
|
|
|
|
return len(self.batch_sampler.sampler)
|
|
|
|
|
|
|
|
def __iter__(self):
|
2022-05-15 22:38:26 +08:00
|
|
|
for _ in range(len(self)):
|
2020-09-01 02:01:25 +08:00
|
|
|
yield next(self.iterator)
|
|
|
|
|
|
|
|
|
2021-10-29 00:35:01 +08:00
|
|
|
class _RepeatSampler:
|
2020-11-14 18:50:32 +08:00
|
|
|
""" Sampler that repeats forever
|
2020-09-01 02:01:25 +08:00
|
|
|
|
2020-09-11 03:27:35 +08:00
|
|
|
Args:
|
|
|
|
sampler (Sampler)
|
|
|
|
"""
|
2022-04-05 04:47:00 +08:00
|
|
|
|
2020-09-11 03:27:35 +08:00
|
|
|
def __init__(self, sampler):
|
|
|
|
self.sampler = sampler
|
2020-09-01 02:01:25 +08:00
|
|
|
|
2020-09-11 03:27:35 +08:00
|
|
|
def __iter__(self):
|
|
|
|
while True:
|
|
|
|
yield from iter(self.sampler)
|
2020-09-01 02:01:25 +08:00
|
|
|
|
|
|
|
|
2021-10-08 07:04:08 +08:00
|
|
|
class LoadImages:
|
|
|
|
# YOLOv5 image/video dataloader, i.e. `python detect.py --source image.jpg/vid.mp4`
|
2022-09-04 23:15:53 +08:00
|
|
|
def __init__(self, path, img_size=640, stride=32, auto=True, transforms=None, vid_stride=1):
|
2022-07-08 20:32:40 +08:00
|
|
|
files = []
|
|
|
|
for p in sorted(path) if isinstance(path, (list, tuple)) else [path]:
|
|
|
|
p = str(Path(p).resolve())
|
|
|
|
if '*' in p:
|
|
|
|
files.extend(sorted(glob.glob(p, recursive=True))) # glob
|
|
|
|
elif os.path.isdir(p):
|
|
|
|
files.extend(sorted(glob.glob(os.path.join(p, '*.*')))) # dir
|
|
|
|
elif os.path.isfile(p):
|
|
|
|
files.append(p) # files
|
|
|
|
else:
|
|
|
|
raise FileNotFoundError(f'{p} does not exist')
|
2020-05-30 08:04:54 +08:00
|
|
|
|
2021-07-19 16:43:01 +08:00
|
|
|
images = [x for x in files if x.split('.')[-1].lower() in IMG_FORMATS]
|
|
|
|
videos = [x for x in files if x.split('.')[-1].lower() in VID_FORMATS]
|
2020-07-13 05:14:51 +08:00
|
|
|
ni, nv = len(images), len(videos)
|
2020-05-30 08:04:54 +08:00
|
|
|
|
|
|
|
self.img_size = img_size
|
2021-01-31 05:47:23 +08:00
|
|
|
self.stride = stride
|
2020-05-30 08:04:54 +08:00
|
|
|
self.files = images + videos
|
2020-07-13 05:14:51 +08:00
|
|
|
self.nf = ni + nv # number of files
|
|
|
|
self.video_flag = [False] * ni + [True] * nv
|
2020-12-12 07:45:32 +08:00
|
|
|
self.mode = 'image'
|
Add TensorFlow and TFLite export (#1127)
* Add models/tf.py for TensorFlow and TFLite export
* Set auto=False for int8 calibration
* Update requirements.txt for TensorFlow and TFLite export
* Read anchors directly from PyTorch weights
* Add --tf-nms to append NMS in TensorFlow SavedModel and GraphDef export
* Remove check_anchor_order, check_file, set_logging from import
* Reformat code and optimize imports
* Autodownload model and check cfg
* update --source path, img-size to 320, single output
* Adjust representative_dataset
* Put representative dataset in tfl_int8 block
* detect.py TF inference
* weights to string
* weights to string
* cleanup tf.py
* Add --dynamic-batch-size
* Add xywh normalization to reduce calibration error
* Update requirements.txt
TensorFlow 2.3.1 -> 2.4.0 to avoid int8 quantization error
* Fix imports
Move C3 from models.experimental to models.common
* Add models/tf.py for TensorFlow and TFLite export
* Set auto=False for int8 calibration
* Update requirements.txt for TensorFlow and TFLite export
* Read anchors directly from PyTorch weights
* Add --tf-nms to append NMS in TensorFlow SavedModel and GraphDef export
* Remove check_anchor_order, check_file, set_logging from import
* Reformat code and optimize imports
* Autodownload model and check cfg
* update --source path, img-size to 320, single output
* Adjust representative_dataset
* detect.py TF inference
* Put representative dataset in tfl_int8 block
* weights to string
* weights to string
* cleanup tf.py
* Add --dynamic-batch-size
* Add xywh normalization to reduce calibration error
* Update requirements.txt
TensorFlow 2.3.1 -> 2.4.0 to avoid int8 quantization error
* Fix imports
Move C3 from models.experimental to models.common
* implement C3() and SiLU()
* Fix reshape dim to support dynamic batching
* Add epsilon argument in tf_BN, which is different between TF and PT
* Set stride to None if not using PyTorch, and do not warmup without PyTorch
* Add list support in check_img_size()
* Add list input support in detect.py
* sys.path.append('./') to run from yolov5/
* Add int8 quantization support for TensorFlow 2.5
* Add get_coco128.sh
* Remove --no-tfl-detect in models/tf.py (Use tf-android-tfl-detect branch for EdgeTPU)
* Update requirements.txt
* Replace torch.load() with attempt_load()
* Update requirements.txt
* Add --tf-raw-resize to set half_pixel_centers=False
* Add --agnostic-nms for TF class-agnostic NMS
* Cleanup after merge
* Cleanup2 after merge
* Cleanup3 after merge
* Add tf.py docstring with credit and usage
* pb saved_model and tflite use only one model in detect.py
* Add use cases in docstring of tf.py
* Remove redundant `stride` definition
* Remove keras direct import
* Fix `check_requirements(('tensorflow>=2.4.1',))`
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
2021-08-17 19:18:16 +08:00
|
|
|
self.auto = auto
|
2022-08-18 04:41:43 +08:00
|
|
|
self.transforms = transforms # optional
|
2022-09-04 23:15:53 +08:00
|
|
|
self.vid_stride = vid_stride # video frame-rate stride
|
2020-05-30 08:04:54 +08:00
|
|
|
if any(videos):
|
2022-09-02 04:30:26 +08:00
|
|
|
self._new_video(videos[0]) # new video
|
2020-05-30 08:04:54 +08:00
|
|
|
else:
|
|
|
|
self.cap = None
|
2021-01-13 02:33:15 +08:00
|
|
|
assert self.nf > 0, f'No images or videos found in {p}. ' \
|
2021-07-19 16:43:01 +08:00
|
|
|
f'Supported formats are:\nimages: {IMG_FORMATS}\nvideos: {VID_FORMATS}'
|
2020-05-30 08:04:54 +08:00
|
|
|
|
|
|
|
def __iter__(self):
|
|
|
|
self.count = 0
|
|
|
|
return self
|
|
|
|
|
|
|
|
def __next__(self):
|
2020-07-13 05:14:51 +08:00
|
|
|
if self.count == self.nf:
|
2020-05-30 08:04:54 +08:00
|
|
|
raise StopIteration
|
|
|
|
path = self.files[self.count]
|
|
|
|
|
|
|
|
if self.video_flag[self.count]:
|
|
|
|
# Read video
|
|
|
|
self.mode = 'video'
|
2022-08-18 04:41:43 +08:00
|
|
|
ret_val, im0 = self.cap.read()
|
2022-09-04 23:15:53 +08:00
|
|
|
self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.vid_stride * (self.frame + 1)) # read at vid_stride
|
2021-12-02 17:57:39 +08:00
|
|
|
while not ret_val:
|
2020-05-30 08:04:54 +08:00
|
|
|
self.count += 1
|
|
|
|
self.cap.release()
|
2020-07-13 05:14:51 +08:00
|
|
|
if self.count == self.nf: # last video
|
2020-05-30 08:04:54 +08:00
|
|
|
raise StopIteration
|
2022-05-15 22:38:26 +08:00
|
|
|
path = self.files[self.count]
|
2022-09-02 04:30:26 +08:00
|
|
|
self._new_video(path)
|
2022-08-18 04:41:43 +08:00
|
|
|
ret_val, im0 = self.cap.read()
|
2020-05-30 08:04:54 +08:00
|
|
|
|
|
|
|
self.frame += 1
|
2022-09-04 23:15:53 +08:00
|
|
|
# im0 = self._cv2_rotate(im0) # for use if cv2 autorotation is False
|
2021-11-02 01:22:13 +08:00
|
|
|
s = f'video {self.count + 1}/{self.nf} ({self.frame}/{self.frames}) {path}: '
|
2020-05-30 08:04:54 +08:00
|
|
|
|
|
|
|
else:
|
|
|
|
# Read image
|
|
|
|
self.count += 1
|
2022-08-18 04:41:43 +08:00
|
|
|
im0 = cv2.imread(path) # BGR
|
|
|
|
assert im0 is not None, f'Image Not Found {path}'
|
2021-11-02 01:22:13 +08:00
|
|
|
s = f'image {self.count}/{self.nf} {path}: '
|
2020-05-30 08:04:54 +08:00
|
|
|
|
2022-08-18 04:41:43 +08:00
|
|
|
if self.transforms:
|
2022-08-30 21:17:58 +08:00
|
|
|
im = self.transforms(im0) # transforms
|
2022-08-18 04:41:43 +08:00
|
|
|
else:
|
|
|
|
im = letterbox(im0, self.img_size, stride=self.stride, auto=self.auto)[0] # padded resize
|
|
|
|
im = im.transpose((2, 0, 1))[::-1] # HWC to CHW, BGR to RGB
|
|
|
|
im = np.ascontiguousarray(im) # contiguous
|
2020-05-30 08:04:54 +08:00
|
|
|
|
2022-08-18 04:41:43 +08:00
|
|
|
return path, im, im0, self.cap, s
|
2020-05-30 08:04:54 +08:00
|
|
|
|
2022-09-02 04:30:26 +08:00
|
|
|
def _new_video(self, path):
|
|
|
|
# Create a new video capture object
|
2020-05-30 08:04:54 +08:00
|
|
|
self.frame = 0
|
|
|
|
self.cap = cv2.VideoCapture(path)
|
2022-09-04 23:15:53 +08:00
|
|
|
self.frames = int(self.cap.get(cv2.CAP_PROP_FRAME_COUNT) / self.vid_stride)
|
2022-09-02 04:30:26 +08:00
|
|
|
self.orientation = int(self.cap.get(cv2.CAP_PROP_ORIENTATION_META)) # rotation degrees
|
|
|
|
# self.cap.set(cv2.CAP_PROP_ORIENTATION_AUTO, 0) # disable https://github.com/ultralytics/yolov5/issues/8493
|
|
|
|
|
|
|
|
def _cv2_rotate(self, im):
|
|
|
|
# Rotate a cv2 video manually
|
|
|
|
if self.orientation == 0:
|
|
|
|
return cv2.rotate(im, cv2.ROTATE_90_CLOCKWISE)
|
|
|
|
elif self.orientation == 180:
|
|
|
|
return cv2.rotate(im, cv2.ROTATE_90_COUNTERCLOCKWISE)
|
|
|
|
elif self.orientation == 90:
|
|
|
|
return cv2.rotate(im, cv2.ROTATE_180)
|
|
|
|
return im
|
2020-05-30 08:04:54 +08:00
|
|
|
|
|
|
|
def __len__(self):
|
2020-07-13 05:14:51 +08:00
|
|
|
return self.nf # number of files
|
2020-05-30 08:04:54 +08:00
|
|
|
|
|
|
|
|
2021-10-08 07:04:08 +08:00
|
|
|
class LoadStreams:
|
|
|
|
# YOLOv5 streamloader, i.e. `python detect.py --source 'rtsp://example.com/media.mp4' # RTSP, RTMP, HTTP streams`
|
2022-09-04 23:15:53 +08:00
|
|
|
def __init__(self, sources='streams.txt', img_size=640, stride=32, auto=True, transforms=None, vid_stride=1):
|
2022-09-02 20:12:10 +08:00
|
|
|
torch.backends.cudnn.benchmark = True # faster for fixed-size inference
|
2020-12-12 07:45:32 +08:00
|
|
|
self.mode = 'stream'
|
2020-05-30 08:04:54 +08:00
|
|
|
self.img_size = img_size
|
2021-01-31 05:47:23 +08:00
|
|
|
self.stride = stride
|
2022-09-04 23:15:53 +08:00
|
|
|
self.vid_stride = vid_stride # video frame-rate stride
|
2022-09-02 20:12:10 +08:00
|
|
|
sources = Path(sources).read_text().rsplit() if Path(sources).is_file() else [sources]
|
2020-05-30 08:04:54 +08:00
|
|
|
n = len(sources)
|
2020-12-18 09:20:20 +08:00
|
|
|
self.sources = [clean_str(x) for x in sources] # clean source names for later
|
2022-09-02 20:12:10 +08:00
|
|
|
self.imgs, self.fps, self.frames, self.threads = [None] * n, [0] * n, [0] * n, [None] * n
|
2021-04-16 23:58:28 +08:00
|
|
|
for i, s in enumerate(sources): # index, source
|
|
|
|
# Start thread to read frames from video stream
|
2021-11-02 01:22:13 +08:00
|
|
|
st = f'{i + 1}/{n}: {s}... '
|
2022-04-02 03:38:49 +08:00
|
|
|
if urlparse(s).hostname in ('www.youtube.com', 'youtube.com', 'youtu.be'): # if source is YouTube video
|
2022-02-11 20:46:20 +08:00
|
|
|
check_requirements(('pafy', 'youtube_dl==2020.12.2'))
|
2021-04-12 00:53:40 +08:00
|
|
|
import pafy
|
2021-04-16 23:58:28 +08:00
|
|
|
s = pafy.new(s).getbest(preftype="mp4").url # YouTube URL
|
|
|
|
s = eval(s) if s.isnumeric() else s # i.e. s = '0' local webcam
|
2022-06-14 20:28:21 +08:00
|
|
|
if s == 0:
|
|
|
|
assert not is_colab(), '--source 0 webcam unsupported on Colab. Rerun command in a local environment.'
|
|
|
|
assert not is_kaggle(), '--source 0 webcam unsupported on Kaggle. Rerun command in a local environment.'
|
2021-04-16 23:58:28 +08:00
|
|
|
cap = cv2.VideoCapture(s)
|
2021-11-02 01:22:13 +08:00
|
|
|
assert cap.isOpened(), f'{st}Failed to open {s}'
|
2020-05-30 08:04:54 +08:00
|
|
|
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
|
|
|
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
2022-01-05 11:32:42 +08:00
|
|
|
fps = cap.get(cv2.CAP_PROP_FPS) # warning: may return 0 or nan
|
2021-05-23 20:55:42 +08:00
|
|
|
self.frames[i] = max(int(cap.get(cv2.CAP_PROP_FRAME_COUNT)), 0) or float('inf') # infinite stream fallback
|
2022-01-05 11:32:42 +08:00
|
|
|
self.fps[i] = max((fps if math.isfinite(fps) else 0) % 100, 0) or 30 # 30 FPS fallback
|
2021-04-12 00:53:40 +08:00
|
|
|
|
2020-05-30 08:04:54 +08:00
|
|
|
_, self.imgs[i] = cap.read() # guarantee first frame
|
2021-10-08 14:26:43 +08:00
|
|
|
self.threads[i] = Thread(target=self.update, args=([i, cap, s]), daemon=True)
|
2021-11-02 01:22:13 +08:00
|
|
|
LOGGER.info(f"{st} Success ({self.frames[i]} frames {w}x{h} at {self.fps[i]:.2f} FPS)")
|
2021-05-21 22:51:07 +08:00
|
|
|
self.threads[i].start()
|
2021-11-02 01:22:13 +08:00
|
|
|
LOGGER.info('') # newline
|
2020-05-30 08:04:54 +08:00
|
|
|
|
|
|
|
# check for common shapes
|
2022-08-23 20:37:46 +08:00
|
|
|
s = np.stack([letterbox(x, img_size, stride=stride, auto=auto)[0].shape for x in self.imgs])
|
2020-05-30 08:04:54 +08:00
|
|
|
self.rect = np.unique(s, axis=0).shape[0] == 1 # rect inference if all shapes equal
|
2022-08-23 20:37:46 +08:00
|
|
|
self.auto = auto and self.rect
|
|
|
|
self.transforms = transforms # optional
|
2020-05-30 08:04:54 +08:00
|
|
|
if not self.rect:
|
2021-11-02 01:22:13 +08:00
|
|
|
LOGGER.warning('WARNING: Stream shapes differ. For optimal performance supply similarly-shaped streams.')
|
2020-05-30 08:04:54 +08:00
|
|
|
|
2021-10-08 14:26:43 +08:00
|
|
|
def update(self, i, cap, stream):
|
2021-05-21 22:51:07 +08:00
|
|
|
# Read stream `i` frames in daemon thread
|
2022-09-04 23:15:53 +08:00
|
|
|
n, f = 0, self.frames[i] # frame number, frame array
|
2021-05-21 22:51:07 +08:00
|
|
|
while cap.isOpened() and n < f:
|
2020-05-30 08:04:54 +08:00
|
|
|
n += 1
|
2022-09-02 20:12:10 +08:00
|
|
|
cap.grab() # .read() = .grab() followed by .retrieve()
|
2022-09-04 23:15:53 +08:00
|
|
|
if n % self.vid_stride == 0:
|
2021-02-16 03:02:20 +08:00
|
|
|
success, im = cap.retrieve()
|
2021-10-08 14:26:43 +08:00
|
|
|
if success:
|
|
|
|
self.imgs[i] = im
|
|
|
|
else:
|
2021-11-08 23:32:15 +08:00
|
|
|
LOGGER.warning('WARNING: Video stream unresponsive, please check your IP camera connection.')
|
2021-12-02 17:51:19 +08:00
|
|
|
self.imgs[i] = np.zeros_like(self.imgs[i])
|
2021-10-08 14:26:43 +08:00
|
|
|
cap.open(stream) # re-open stream if signal was lost
|
2022-06-17 23:59:27 +08:00
|
|
|
time.sleep(0.0) # wait time
|
2020-05-30 08:04:54 +08:00
|
|
|
|
|
|
|
def __iter__(self):
|
|
|
|
self.count = -1
|
|
|
|
return self
|
|
|
|
|
|
|
|
def __next__(self):
|
|
|
|
self.count += 1
|
2021-05-21 22:51:07 +08:00
|
|
|
if not all(x.is_alive() for x in self.threads) or cv2.waitKey(1) == ord('q'): # q to quit
|
2020-05-30 08:04:54 +08:00
|
|
|
cv2.destroyAllWindows()
|
|
|
|
raise StopIteration
|
|
|
|
|
2022-08-23 20:37:46 +08:00
|
|
|
im0 = self.imgs.copy()
|
|
|
|
if self.transforms:
|
2022-08-30 21:17:58 +08:00
|
|
|
im = np.stack([self.transforms(x) for x in im0]) # transforms
|
2022-08-23 20:37:46 +08:00
|
|
|
else:
|
|
|
|
im = np.stack([letterbox(x, self.img_size, stride=self.stride, auto=self.auto)[0] for x in im0]) # resize
|
|
|
|
im = im[..., ::-1].transpose((0, 3, 1, 2)) # BGR to RGB, BHWC to BCHW
|
|
|
|
im = np.ascontiguousarray(im) # contiguous
|
2020-05-30 08:04:54 +08:00
|
|
|
|
2022-08-23 20:37:46 +08:00
|
|
|
return self.sources, im, im0, None, ''
|
2020-05-30 08:04:54 +08:00
|
|
|
|
|
|
|
def __len__(self):
|
2021-07-04 18:55:57 +08:00
|
|
|
return len(self.sources) # 1E12 frames = 32 streams at 30 FPS for 30 years
|
2020-05-30 08:04:54 +08:00
|
|
|
|
|
|
|
|
2020-11-24 23:13:04 +08:00
|
|
|
def img2label_paths(img_paths):
|
|
|
|
# Define label paths as a function of image paths
|
2022-05-15 22:38:26 +08:00
|
|
|
sa, sb = f'{os.sep}images{os.sep}', f'{os.sep}labels{os.sep}' # /images/, /labels/ substrings
|
2021-06-22 04:50:56 +08:00
|
|
|
return [sb.join(x.rsplit(sa, 1)).rsplit('.', 1)[0] + '.txt' for x in img_paths]
|
2020-11-24 23:13:04 +08:00
|
|
|
|
|
|
|
|
2021-10-08 07:04:08 +08:00
|
|
|
class LoadImagesAndLabels(Dataset):
|
|
|
|
# YOLOv5 train_loader/val_loader, loads images and labels for training and validation
|
2021-10-16 03:32:08 +08:00
|
|
|
cache_version = 0.6 # dataset labels *.cache version
|
2022-05-13 20:26:11 +08:00
|
|
|
rand_interp_methods = [cv2.INTER_NEAREST, cv2.INTER_LINEAR, cv2.INTER_CUBIC, cv2.INTER_AREA, cv2.INTER_LANCZOS4]
|
2021-09-18 00:01:52 +08:00
|
|
|
|
2022-03-31 22:52:34 +08:00
|
|
|
def __init__(self,
|
|
|
|
path,
|
|
|
|
img_size=640,
|
|
|
|
batch_size=16,
|
|
|
|
augment=False,
|
|
|
|
hyp=None,
|
|
|
|
rect=False,
|
|
|
|
image_weights=False,
|
|
|
|
cache_images=False,
|
|
|
|
single_cls=False,
|
|
|
|
stride=32,
|
|
|
|
pad=0.0,
|
|
|
|
prefix=''):
|
2020-10-24 21:09:19 +08:00
|
|
|
self.img_size = img_size
|
|
|
|
self.augment = augment
|
|
|
|
self.hyp = hyp
|
|
|
|
self.image_weights = image_weights
|
|
|
|
self.rect = False if image_weights else rect
|
|
|
|
self.mosaic = self.augment and not self.rect # load 4 images at a time into a mosaic (only during training)
|
|
|
|
self.mosaic_border = [-img_size // 2, -img_size // 2]
|
|
|
|
self.stride = stride
|
2021-02-02 13:38:41 +08:00
|
|
|
self.path = path
|
2021-07-06 00:01:54 +08:00
|
|
|
self.albumentations = Albumentations() if augment else None
|
2021-02-06 01:06:23 +08:00
|
|
|
|
2020-05-30 08:04:54 +08:00
|
|
|
try:
|
2020-07-10 11:07:16 +08:00
|
|
|
f = [] # image files
|
2020-07-10 04:45:55 +08:00
|
|
|
for p in path if isinstance(path, list) else [path]:
|
2020-11-16 23:24:57 +08:00
|
|
|
p = Path(p) # os-agnostic
|
|
|
|
if p.is_dir(): # dir
|
|
|
|
f += glob.glob(str(p / '**' / '*.*'), recursive=True)
|
2021-10-21 01:25:33 +08:00
|
|
|
# f = list(p.rglob('*.*')) # pathlib
|
2020-11-16 23:24:57 +08:00
|
|
|
elif p.is_file(): # file
|
2021-10-29 00:35:01 +08:00
|
|
|
with open(p) as t:
|
2020-11-29 18:58:14 +08:00
|
|
|
t = t.read().strip().splitlines()
|
2020-11-16 23:24:57 +08:00
|
|
|
parent = str(p.parent) + os.sep
|
2020-07-10 04:45:55 +08:00
|
|
|
f += [x.replace('./', parent) if x.startswith('./') else x for x in t] # local to global path
|
2021-02-06 01:06:23 +08:00
|
|
|
# f += [p.parent / x.lstrip(os.sep) for x in t] # local to global path (pathlib)
|
2020-07-09 17:52:12 +08:00
|
|
|
else:
|
2022-07-08 20:32:40 +08:00
|
|
|
raise FileNotFoundError(f'{prefix}{p} does not exist')
|
2022-03-06 23:16:17 +08:00
|
|
|
self.im_files = sorted(x.replace('/', os.sep) for x in f if x.split('.')[-1].lower() in IMG_FORMATS)
|
2021-10-21 01:25:33 +08:00
|
|
|
# self.img_files = sorted([x for x in f if x.suffix[1:].lower() in IMG_FORMATS]) # pathlib
|
2022-03-06 23:16:17 +08:00
|
|
|
assert self.im_files, f'{prefix}No images found'
|
2020-07-10 07:28:20 +08:00
|
|
|
except Exception as e:
|
2022-08-19 21:07:04 +08:00
|
|
|
raise Exception(f'{prefix}Error loading data from {path}: {e}\n{HELP_URL}')
|
2020-05-30 08:04:54 +08:00
|
|
|
|
2020-07-10 11:07:16 +08:00
|
|
|
# Check cache
|
2022-03-06 23:16:17 +08:00
|
|
|
self.label_files = img2label_paths(self.im_files) # labels
|
2021-07-10 20:18:46 +08:00
|
|
|
cache_path = (p if p.is_file() else Path(self.label_files[0]).parent).with_suffix('.cache')
|
|
|
|
try:
|
|
|
|
cache, exists = np.load(cache_path, allow_pickle=True).item(), True # load dict
|
2022-06-30 22:19:22 +08:00
|
|
|
assert cache['version'] == self.cache_version # matches current version
|
|
|
|
assert cache['hash'] == get_hash(self.label_files + self.im_files) # identical hash
|
2022-02-05 22:22:59 +08:00
|
|
|
except Exception:
|
2022-06-30 22:19:22 +08:00
|
|
|
cache, exists = self.cache_labels(cache_path, prefix), False # run cache ops
|
2020-06-14 06:05:41 +08:00
|
|
|
|
2020-11-24 23:13:04 +08:00
|
|
|
# Display cache
|
2022-01-19 04:49:26 +08:00
|
|
|
nf, nm, ne, nc, n = cache.pop('results') # found, missing, empty, corrupt, total
|
2022-05-15 22:38:26 +08:00
|
|
|
if exists and LOCAL_RANK in {-1, 0}:
|
2022-01-19 04:49:26 +08:00
|
|
|
d = f"Scanning '{cache_path}' images and labels... {nf} found, {nm} missing, {ne} empty, {nc} corrupt"
|
2022-03-15 23:32:56 +08:00
|
|
|
tqdm(None, desc=prefix + d, total=n, initial=n, bar_format=BAR_FORMAT) # display cache results
|
2021-06-18 16:21:47 +08:00
|
|
|
if cache['msgs']:
|
2021-11-08 23:32:15 +08:00
|
|
|
LOGGER.info('\n'.join(cache['msgs'])) # display warnings
|
2022-08-19 21:07:04 +08:00
|
|
|
assert nf > 0 or not augment, f'{prefix}No labels found in {cache_path}, can not start training. {HELP_URL}'
|
2020-11-24 23:13:04 +08:00
|
|
|
|
2020-10-24 20:50:50 +08:00
|
|
|
# Read cache
|
2021-06-18 16:21:47 +08:00
|
|
|
[cache.pop(k) for k in ('hash', 'version', 'msgs')] # remove items
|
2021-02-12 13:22:45 +08:00
|
|
|
labels, shapes, self.segments = zip(*cache.values())
|
2022-08-19 21:07:04 +08:00
|
|
|
nl = len(np.concatenate(labels, 0)) # number of labels
|
|
|
|
assert nl > 0 or not augment, f'{prefix}All labels empty in {cache_path}, can not start training. {HELP_URL}'
|
2020-07-10 11:07:16 +08:00
|
|
|
self.labels = list(labels)
|
2022-08-04 23:06:08 +08:00
|
|
|
self.shapes = np.array(shapes)
|
2022-03-06 23:16:17 +08:00
|
|
|
self.im_files = list(cache.keys()) # update
|
2020-10-24 20:50:50 +08:00
|
|
|
self.label_files = img2label_paths(cache.keys()) # update
|
2020-10-24 21:09:19 +08:00
|
|
|
n = len(shapes) # number of images
|
2022-09-07 15:11:30 +08:00
|
|
|
bi = np.floor(np.arange(n) / batch_size).astype(int) # batch index
|
2020-10-24 21:09:19 +08:00
|
|
|
nb = bi[-1] + 1 # number of batches
|
|
|
|
self.batch = bi # batch index of image
|
|
|
|
self.n = n
|
2020-11-26 18:49:01 +08:00
|
|
|
self.indices = range(n)
|
2020-10-24 21:09:19 +08:00
|
|
|
|
2021-10-14 06:48:54 +08:00
|
|
|
# Update labels
|
|
|
|
include_class = [] # filter labels to include only these classes (optional)
|
|
|
|
include_class_array = np.array(include_class).reshape(1, -1)
|
|
|
|
for i, (label, segment) in enumerate(zip(self.labels, self.segments)):
|
|
|
|
if include_class:
|
|
|
|
j = (label[:, 0:1] == include_class_array).any(1)
|
|
|
|
self.labels[i] = label[j]
|
|
|
|
if segment:
|
|
|
|
self.segments[i] = segment[j]
|
|
|
|
if single_cls: # single-class training, merge all classes into 0
|
|
|
|
self.labels[i][:, 0] = 0
|
|
|
|
if segment:
|
|
|
|
self.segments[i][:, 0] = 0
|
|
|
|
|
2020-10-24 20:50:50 +08:00
|
|
|
# Rectangular Training
|
2020-05-30 08:04:54 +08:00
|
|
|
if self.rect:
|
|
|
|
# Sort by aspect ratio
|
2020-06-14 06:05:41 +08:00
|
|
|
s = self.shapes # wh
|
2020-05-30 08:04:54 +08:00
|
|
|
ar = s[:, 1] / s[:, 0] # aspect ratio
|
|
|
|
irect = ar.argsort()
|
2022-03-06 23:16:17 +08:00
|
|
|
self.im_files = [self.im_files[i] for i in irect]
|
2020-05-30 08:04:54 +08:00
|
|
|
self.label_files = [self.label_files[i] for i in irect]
|
2020-07-10 11:39:11 +08:00
|
|
|
self.labels = [self.labels[i] for i in irect]
|
YOLOv5 segmentation model support (#9052)
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Fix duplicate plots.py
* Fix check_font()
* # torch.use_deterministic_algorithms(True)
* update doc detect->predict
* Resolve precommit for segment/train and segment/val
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Resolve precommit for utils/segment
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Resolve precommit min_wh
* Resolve precommit utils/segment/plots
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Resolve precommit utils/segment/general
* Align NMS-seg closer to NMS
* restore deterministic init_seeds code
* remove easydict dependency
* update
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* restore output_to_target mask
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update
* cleanup
* Remove unused ImageFont import
* Unified NMS
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* DetectMultiBackend compatibility
* segment/predict.py update
* update plot colors
* fix bbox shifted
* sort bbox by confidence
* enable overlap by default
* Merge detect/segment output_to_target() function
* Start segmentation CI
* fix plots
* Update ci-testing.yml
* fix training whitespace
* optimize process mask functions (can we merge both?)
* Update predict/detect
* Update plot_images
* Update plot_images_and_masks
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* fix
* Add train to CI
* fix precommit
* fix precommit CI
* fix precommit pycocotools
* fix val float issues
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* fix masks float float issues
* suppress errors
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* fix no-predictions plotting bug
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Add CSV Logger
* fix val len(plot_masks)
* speed up evaluation
* fix process_mask
* fix plots
* update segment/utils build_targets
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* optimize utils/segment/general crop()
* optimize utils/segment/general crop() 2
* minor updates
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* torch.where revert
* downsample only if different shape
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* loss cleanup
* loss cleanup 2
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* loss cleanup 3
* update project names
* Rename -seg yamls from _underscore to -dash
* prepare for yolov5n-seg.pt
* precommit space fix
* add coco128-seg.yaml
* update coco128-seg comments
* cleanup val.py
* Major val.py cleanup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* precommit fix
* precommit fix
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* optional pycocotools
* remove CI pip install pycocotools (auto-installed now)
* seg yaml fix
* optimize mask_iou() and masks_iou()
* threaded fix
* Major train.py update
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Major segments/val/process_batch() update
* yolov5/val updates from segment
* process_batch numpy/tensor fix
* opt-in to pycocotools with --save-json
* threaded pycocotools ops for 2x speed increase
* Avoid permute contiguous if possible
* Add max_det=300 argument to both val.py and segment/val.py
* fix onnx_dynamic
* speed up pycocotools ops
* faster process_mask(upsample=True) for predict
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* eliminate permutations for process_mask(upsample=True)
* eliminate permute-contiguous in crop(), use native dimension order
* cleanup comment
* Add Proto() module
* fix class count
* fix anchor order
* broadcast mask_gti in loss for speed
* Cleanup seg loss
* faster indexing
* faster indexing fix
* faster indexing fix2
* revert faster indexing
* fix validation plotting
* Loss cleanup and mxyxy simplification
* Loss cleanup and mxyxy simplification 2
* revert validation plotting
* replace missing tanh
* Eliminate last permutation
* delete unneeded .float()
* Remove MaskIOULoss and crop(if HWC)
* Final v6.3 SegmentationModel architecture updates
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Add support for TF export
* remove debugger trace
* add call
* update
* update
* Merge master
* Merge master
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update dataloaders.py
* Restore CI
* Update dataloaders.py
* Fix TF/TFLite export for segmentation model
* Merge master
* Cleanup predict.py mask plotting
* cleanup scale_masks()
* rename scale_masks to scale_image
* cleanup/optimize plot_masks
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Add Annotator.masks()
* Annotator.masks() fix
* Update plots.py
* Annotator mask optimization
* Rename crop() to crop_mask()
* Do not crop in predict.py
* crop always
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Merge master
* Add vid-stride from master PR
* Update seg model outputs
* Update seg model outputs
* Add segmentation benchmarks
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Add segmentation benchmarks
* Add segmentation benchmarks
* Add segmentation benchmarks
* Fix DetectMultiBackend for OpenVINO
* update Annotator.masks
* fix val plot
* revert val plot
* clean up
* revert pil
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Fix CI error
* fix predict log
* remove upsample
* update interpolate
* fix validation plot logging
* Annotator.masks() cleanup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Remove segmentation_model definition
* Restore 0.99999 decimals
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
Co-authored-by: Laughing-q <1185102784@qq.com>
Co-authored-by: Jiacong Fang <zldrobit@126.com>
2022-09-16 06:12:46 +08:00
|
|
|
self.segments = [self.segments[i] for i in irect]
|
2020-05-30 08:04:54 +08:00
|
|
|
self.shapes = s[irect] # wh
|
|
|
|
ar = ar[irect]
|
|
|
|
|
|
|
|
# Set training image shapes
|
|
|
|
shapes = [[1, 1]] * nb
|
|
|
|
for i in range(nb):
|
|
|
|
ari = ar[bi == i]
|
|
|
|
mini, maxi = ari.min(), ari.max()
|
|
|
|
if maxi < 1:
|
|
|
|
shapes[i] = [maxi, 1]
|
|
|
|
elif mini > 1:
|
|
|
|
shapes[i] = [1, 1 / mini]
|
|
|
|
|
2022-09-07 15:11:30 +08:00
|
|
|
self.batch_shapes = np.ceil(np.array(shapes) * img_size / stride + pad).astype(int) * stride
|
2020-05-30 08:04:54 +08:00
|
|
|
|
2022-02-08 01:59:26 +08:00
|
|
|
# Cache images into RAM/disk for faster training (WARNING: large datasets may exceed system resources)
|
2022-03-06 23:16:17 +08:00
|
|
|
self.ims = [None] * n
|
|
|
|
self.npy_files = [Path(f).with_suffix('.npy') for f in self.im_files]
|
2020-07-10 11:07:16 +08:00
|
|
|
if cache_images:
|
2020-05-30 08:04:54 +08:00
|
|
|
gb = 0 # Gigabytes of cached images
|
2022-03-06 23:16:17 +08:00
|
|
|
self.im_hw0, self.im_hw = [None] * n, [None] * n
|
|
|
|
fcn = self.cache_images_to_disk if cache_images == 'disk' else self.load_image
|
|
|
|
results = ThreadPool(NUM_THREADS).imap(fcn, range(n))
|
2022-04-16 21:12:38 +08:00
|
|
|
pbar = tqdm(enumerate(results), total=n, bar_format=BAR_FORMAT, disable=LOCAL_RANK > 0)
|
2020-11-07 09:18:18 +08:00
|
|
|
for i, x in pbar:
|
2021-08-03 00:47:24 +08:00
|
|
|
if cache_images == 'disk':
|
2022-03-06 23:16:17 +08:00
|
|
|
gb += self.npy_files[i].stat().st_size
|
2022-02-08 01:59:26 +08:00
|
|
|
else: # 'ram'
|
2022-03-06 23:16:17 +08:00
|
|
|
self.ims[i], self.im_hw0[i], self.im_hw[i] = x # im, hw_orig, hw_resized = load_image(self, i)
|
|
|
|
gb += self.ims[i].nbytes
|
2021-08-03 00:47:24 +08:00
|
|
|
pbar.desc = f'{prefix}Caching images ({gb / 1E9:.1f}GB {cache_images})'
|
2021-03-29 18:21:25 +08:00
|
|
|
pbar.close()
|
2021-04-12 00:53:40 +08:00
|
|
|
|
2021-01-13 02:33:15 +08:00
|
|
|
def cache_labels(self, path=Path('./labels.cache'), prefix=''):
|
2020-07-10 11:07:16 +08:00
|
|
|
# Cache dataset labels, check images and read shapes
|
|
|
|
x = {} # dict
|
2021-06-18 16:21:47 +08:00
|
|
|
nm, nf, ne, nc, msgs = 0, 0, 0, 0, [] # number missing, found, empty, corrupt, messages
|
2021-06-09 00:00:21 +08:00
|
|
|
desc = f"{prefix}Scanning '{path.parent / path.stem}' images and labels..."
|
2021-07-19 16:43:01 +08:00
|
|
|
with Pool(NUM_THREADS) as pool:
|
2022-03-06 23:16:17 +08:00
|
|
|
pbar = tqdm(pool.imap(verify_image_label, zip(self.im_files, self.label_files, repeat(prefix))),
|
2022-03-31 22:52:34 +08:00
|
|
|
desc=desc,
|
|
|
|
total=len(self.im_files),
|
|
|
|
bar_format=BAR_FORMAT)
|
2022-02-05 22:22:59 +08:00
|
|
|
for im_file, lb, shape, segments, nm_f, nf_f, ne_f, nc_f, msg in pbar:
|
2021-06-09 00:36:40 +08:00
|
|
|
nm += nm_f
|
|
|
|
nf += nf_f
|
|
|
|
ne += ne_f
|
|
|
|
nc += nc_f
|
2021-06-09 00:00:21 +08:00
|
|
|
if im_file:
|
2022-02-05 22:22:59 +08:00
|
|
|
x[im_file] = [lb, shape, segments]
|
2021-06-18 16:21:47 +08:00
|
|
|
if msg:
|
|
|
|
msgs.append(msg)
|
2022-01-19 04:49:26 +08:00
|
|
|
pbar.desc = f"{desc}{nf} found, {nm} missing, {ne} empty, {nc} corrupt"
|
2021-04-12 00:53:40 +08:00
|
|
|
|
2021-06-09 00:36:40 +08:00
|
|
|
pbar.close()
|
2021-06-18 16:21:47 +08:00
|
|
|
if msgs:
|
2021-11-08 23:32:15 +08:00
|
|
|
LOGGER.info('\n'.join(msgs))
|
2020-11-24 23:13:04 +08:00
|
|
|
if nf == 0:
|
2022-08-19 21:07:04 +08:00
|
|
|
LOGGER.warning(f'{prefix}WARNING: No labels found in {path}. {HELP_URL}')
|
2022-03-06 23:16:17 +08:00
|
|
|
x['hash'] = get_hash(self.label_files + self.im_files)
|
|
|
|
x['results'] = nf, nm, ne, nc, len(self.im_files)
|
2021-06-18 16:21:47 +08:00
|
|
|
x['msgs'] = msgs # warnings
|
2021-09-18 00:01:52 +08:00
|
|
|
x['version'] = self.cache_version # cache version
|
2021-04-30 06:56:44 +08:00
|
|
|
try:
|
2021-07-10 20:18:46 +08:00
|
|
|
np.save(path, x) # save cache for next time
|
|
|
|
path.with_suffix('.cache.npy').rename(path) # remove .npy suffix
|
2021-11-08 23:32:15 +08:00
|
|
|
LOGGER.info(f'{prefix}New cache created: {path}')
|
2021-04-30 06:56:44 +08:00
|
|
|
except Exception as e:
|
2021-11-08 23:32:15 +08:00
|
|
|
LOGGER.warning(f'{prefix}WARNING: Cache directory {path.parent} is not writeable: {e}') # not writeable
|
2020-07-10 11:07:16 +08:00
|
|
|
return x
|
2020-05-30 08:04:54 +08:00
|
|
|
|
|
|
|
def __len__(self):
|
2022-03-06 23:16:17 +08:00
|
|
|
return len(self.im_files)
|
2020-05-30 08:04:54 +08:00
|
|
|
|
|
|
|
# def __iter__(self):
|
|
|
|
# self.count = -1
|
2020-11-24 23:13:04 +08:00
|
|
|
# print('ran dataset iter')
|
2020-05-30 08:04:54 +08:00
|
|
|
# #self.shuffled_vector = np.random.permutation(self.nF) if self.augment else np.arange(self.nF)
|
|
|
|
# return self
|
|
|
|
|
|
|
|
def __getitem__(self, index):
|
2020-11-26 18:49:01 +08:00
|
|
|
index = self.indices[index] # linear, shuffled, or image_weights
|
2020-05-30 08:04:54 +08:00
|
|
|
|
|
|
|
hyp = self.hyp
|
2020-09-14 05:03:54 +08:00
|
|
|
mosaic = self.mosaic and random.random() < hyp['mosaic']
|
|
|
|
if mosaic:
|
2020-05-30 08:04:54 +08:00
|
|
|
# Load mosaic
|
2022-02-08 01:59:26 +08:00
|
|
|
img, labels = self.load_mosaic(index)
|
2020-05-30 08:04:54 +08:00
|
|
|
shapes = None
|
|
|
|
|
2021-07-05 00:14:04 +08:00
|
|
|
# MixUp augmentation
|
2020-08-02 04:47:54 +08:00
|
|
|
if random.random() < hyp['mixup']:
|
2022-02-08 01:59:26 +08:00
|
|
|
img, labels = mixup(img, labels, *self.load_mosaic(random.randint(0, self.n - 1)))
|
2021-07-05 00:14:04 +08:00
|
|
|
|
2020-05-30 08:04:54 +08:00
|
|
|
else:
|
|
|
|
# Load image
|
2022-02-08 01:59:26 +08:00
|
|
|
img, (h0, w0), (h, w) = self.load_image(index)
|
2020-05-30 08:04:54 +08:00
|
|
|
|
|
|
|
# Letterbox
|
|
|
|
shape = self.batch_shapes[self.batch[index]] if self.rect else self.img_size # final letterboxed shape
|
|
|
|
img, ratio, pad = letterbox(img, shape, auto=False, scaleup=self.augment)
|
|
|
|
shapes = (h0, w0), ((h / h0, w / w0), pad) # for COCO mAP rescaling
|
|
|
|
|
2021-01-20 05:33:52 +08:00
|
|
|
labels = self.labels[index].copy()
|
|
|
|
if labels.size: # normalized xywh to pixel xyxy format
|
|
|
|
labels[:, 1:] = xywhn2xyxy(labels[:, 1:], ratio[0] * w, ratio[1] * h, padw=pad[0], padh=pad[1])
|
2020-05-30 08:04:54 +08:00
|
|
|
|
2021-07-06 00:01:54 +08:00
|
|
|
if self.augment:
|
2022-03-31 22:52:34 +08:00
|
|
|
img, labels = random_perspective(img,
|
|
|
|
labels,
|
2020-08-01 06:53:52 +08:00
|
|
|
degrees=hyp['degrees'],
|
|
|
|
translate=hyp['translate'],
|
|
|
|
scale=hyp['scale'],
|
2020-08-02 04:47:54 +08:00
|
|
|
shear=hyp['shear'],
|
|
|
|
perspective=hyp['perspective'])
|
2020-05-30 08:04:54 +08:00
|
|
|
|
2021-07-06 00:01:54 +08:00
|
|
|
nl = len(labels) # number of labels
|
|
|
|
if nl:
|
2021-07-11 01:50:53 +08:00
|
|
|
labels[:, 1:5] = xyxy2xywhn(labels[:, 1:5], w=img.shape[1], h=img.shape[0], clip=True, eps=1E-3)
|
2020-05-30 08:04:54 +08:00
|
|
|
|
|
|
|
if self.augment:
|
2021-07-06 00:01:54 +08:00
|
|
|
# Albumentations
|
|
|
|
img, labels = self.albumentations(img, labels)
|
2021-08-26 21:51:04 +08:00
|
|
|
nl = len(labels) # update after albumentations
|
2021-07-06 00:01:54 +08:00
|
|
|
|
|
|
|
# HSV color-space
|
|
|
|
augment_hsv(img, hgain=hyp['hsv_h'], sgain=hyp['hsv_s'], vgain=hyp['hsv_v'])
|
|
|
|
|
|
|
|
# Flip up-down
|
2020-08-02 04:47:54 +08:00
|
|
|
if random.random() < hyp['flipud']:
|
2020-05-30 08:04:54 +08:00
|
|
|
img = np.flipud(img)
|
2021-07-06 00:01:54 +08:00
|
|
|
if nl:
|
2020-05-30 08:04:54 +08:00
|
|
|
labels[:, 2] = 1 - labels[:, 2]
|
|
|
|
|
2021-07-06 00:01:54 +08:00
|
|
|
# Flip left-right
|
2020-08-02 04:47:54 +08:00
|
|
|
if random.random() < hyp['fliplr']:
|
|
|
|
img = np.fliplr(img)
|
2021-07-06 00:01:54 +08:00
|
|
|
if nl:
|
2020-08-02 04:47:54 +08:00
|
|
|
labels[:, 1] = 1 - labels[:, 1]
|
|
|
|
|
2021-07-06 00:01:54 +08:00
|
|
|
# Cutouts
|
2021-07-12 21:54:43 +08:00
|
|
|
# labels = cutout(img, labels, p=0.5)
|
2021-12-03 22:28:14 +08:00
|
|
|
# nl = len(labels) # update after cutout
|
2021-07-06 00:01:54 +08:00
|
|
|
|
|
|
|
labels_out = torch.zeros((nl, 6))
|
|
|
|
if nl:
|
2020-05-30 08:04:54 +08:00
|
|
|
labels_out[:, 1:] = torch.from_numpy(labels)
|
|
|
|
|
|
|
|
# Convert
|
2021-07-05 02:12:32 +08:00
|
|
|
img = img.transpose((2, 0, 1))[::-1] # HWC to CHW, BGR to RGB
|
2020-05-30 08:04:54 +08:00
|
|
|
img = np.ascontiguousarray(img)
|
|
|
|
|
2022-03-06 23:16:17 +08:00
|
|
|
return torch.from_numpy(img), labels_out, self.im_files[index], shapes
|
2020-05-30 08:04:54 +08:00
|
|
|
|
2022-02-08 01:59:26 +08:00
|
|
|
def load_image(self, i):
|
2022-03-06 23:16:17 +08:00
|
|
|
# Loads 1 image from dataset index 'i', returns (im, original hw, resized hw)
|
|
|
|
im, f, fn = self.ims[i], self.im_files[i], self.npy_files[i],
|
2022-02-08 01:59:26 +08:00
|
|
|
if im is None: # not cached in RAM
|
2022-03-06 23:16:17 +08:00
|
|
|
if fn.exists(): # load npy
|
|
|
|
im = np.load(fn)
|
2022-02-08 01:59:26 +08:00
|
|
|
else: # read image
|
|
|
|
im = cv2.imread(f) # BGR
|
|
|
|
assert im is not None, f'Image Not Found {f}'
|
|
|
|
h0, w0 = im.shape[:2] # orig hw
|
|
|
|
r = self.img_size / max(h0, w0) # ratio
|
|
|
|
if r != 1: # if sizes are not equal
|
2022-05-20 18:59:05 +08:00
|
|
|
interp = cv2.INTER_LINEAR if (self.augment or r > 1) else cv2.INTER_AREA
|
2022-05-13 20:26:11 +08:00
|
|
|
im = cv2.resize(im, (int(w0 * r), int(h0 * r)), interpolation=interp)
|
2022-02-08 01:59:26 +08:00
|
|
|
return im, (h0, w0), im.shape[:2] # im, hw_original, hw_resized
|
2022-07-25 06:02:09 +08:00
|
|
|
return self.ims[i], self.im_hw0[i], self.im_hw[i] # im, hw_original, hw_resized
|
2022-03-06 23:16:17 +08:00
|
|
|
|
|
|
|
def cache_images_to_disk(self, i):
|
|
|
|
# Saves an image as an *.npy file for faster loading
|
|
|
|
f = self.npy_files[i]
|
|
|
|
if not f.exists():
|
|
|
|
np.save(f.as_posix(), cv2.imread(self.im_files[i]))
|
2022-02-08 01:59:26 +08:00
|
|
|
|
|
|
|
def load_mosaic(self, index):
|
|
|
|
# YOLOv5 4-mosaic loader. Loads 1 image + 3 random images into a 4-image mosaic
|
|
|
|
labels4, segments4 = [], []
|
|
|
|
s = self.img_size
|
|
|
|
yc, xc = (int(random.uniform(-x, 2 * s + x)) for x in self.mosaic_border) # mosaic center x, y
|
|
|
|
indices = [index] + random.choices(self.indices, k=3) # 3 additional image indices
|
|
|
|
random.shuffle(indices)
|
|
|
|
for i, index in enumerate(indices):
|
|
|
|
# Load image
|
|
|
|
img, _, (h, w) = self.load_image(index)
|
|
|
|
|
|
|
|
# place img in img4
|
|
|
|
if i == 0: # top left
|
|
|
|
img4 = np.full((s * 2, s * 2, img.shape[2]), 114, dtype=np.uint8) # base image with 4 tiles
|
|
|
|
x1a, y1a, x2a, y2a = max(xc - w, 0), max(yc - h, 0), xc, yc # xmin, ymin, xmax, ymax (large image)
|
|
|
|
x1b, y1b, x2b, y2b = w - (x2a - x1a), h - (y2a - y1a), w, h # xmin, ymin, xmax, ymax (small image)
|
|
|
|
elif i == 1: # top right
|
|
|
|
x1a, y1a, x2a, y2a = xc, max(yc - h, 0), min(xc + w, s * 2), yc
|
|
|
|
x1b, y1b, x2b, y2b = 0, h - (y2a - y1a), min(w, x2a - x1a), h
|
|
|
|
elif i == 2: # bottom left
|
|
|
|
x1a, y1a, x2a, y2a = max(xc - w, 0), yc, xc, min(s * 2, yc + h)
|
|
|
|
x1b, y1b, x2b, y2b = w - (x2a - x1a), 0, w, min(y2a - y1a, h)
|
|
|
|
elif i == 3: # bottom right
|
|
|
|
x1a, y1a, x2a, y2a = xc, yc, min(xc + w, s * 2), min(s * 2, yc + h)
|
|
|
|
x1b, y1b, x2b, y2b = 0, 0, min(w, x2a - x1a), min(y2a - y1a, h)
|
|
|
|
|
|
|
|
img4[y1a:y2a, x1a:x2a] = img[y1b:y2b, x1b:x2b] # img4[ymin:ymax, xmin:xmax]
|
|
|
|
padw = x1a - x1b
|
|
|
|
padh = y1a - y1b
|
|
|
|
|
|
|
|
# Labels
|
|
|
|
labels, segments = self.labels[index].copy(), self.segments[index].copy()
|
|
|
|
if labels.size:
|
|
|
|
labels[:, 1:] = xywhn2xyxy(labels[:, 1:], w, h, padw, padh) # normalized xywh to pixel xyxy format
|
|
|
|
segments = [xyn2xy(x, w, h, padw, padh) for x in segments]
|
|
|
|
labels4.append(labels)
|
|
|
|
segments4.extend(segments)
|
|
|
|
|
|
|
|
# Concat/clip labels
|
|
|
|
labels4 = np.concatenate(labels4, 0)
|
|
|
|
for x in (labels4[:, 1:], *segments4):
|
|
|
|
np.clip(x, 0, 2 * s, out=x) # clip when using random_perspective()
|
|
|
|
# img4, labels4 = replicate(img4, labels4) # replicate
|
|
|
|
|
|
|
|
# Augment
|
|
|
|
img4, labels4, segments4 = copy_paste(img4, labels4, segments4, p=self.hyp['copy_paste'])
|
2022-03-31 22:52:34 +08:00
|
|
|
img4, labels4 = random_perspective(img4,
|
|
|
|
labels4,
|
|
|
|
segments4,
|
2022-02-08 01:59:26 +08:00
|
|
|
degrees=self.hyp['degrees'],
|
|
|
|
translate=self.hyp['translate'],
|
|
|
|
scale=self.hyp['scale'],
|
|
|
|
shear=self.hyp['shear'],
|
|
|
|
perspective=self.hyp['perspective'],
|
|
|
|
border=self.mosaic_border) # border to remove
|
|
|
|
|
|
|
|
return img4, labels4
|
|
|
|
|
|
|
|
def load_mosaic9(self, index):
|
|
|
|
# YOLOv5 9-mosaic loader. Loads 1 image + 8 random images into a 9-image mosaic
|
|
|
|
labels9, segments9 = [], []
|
|
|
|
s = self.img_size
|
|
|
|
indices = [index] + random.choices(self.indices, k=8) # 8 additional image indices
|
|
|
|
random.shuffle(indices)
|
|
|
|
hp, wp = -1, -1 # height, width previous
|
|
|
|
for i, index in enumerate(indices):
|
|
|
|
# Load image
|
|
|
|
img, _, (h, w) = self.load_image(index)
|
|
|
|
|
|
|
|
# place img in img9
|
|
|
|
if i == 0: # center
|
|
|
|
img9 = np.full((s * 3, s * 3, img.shape[2]), 114, dtype=np.uint8) # base image with 4 tiles
|
|
|
|
h0, w0 = h, w
|
|
|
|
c = s, s, s + w, s + h # xmin, ymin, xmax, ymax (base) coordinates
|
|
|
|
elif i == 1: # top
|
|
|
|
c = s, s - h, s + w, s
|
|
|
|
elif i == 2: # top right
|
|
|
|
c = s + wp, s - h, s + wp + w, s
|
|
|
|
elif i == 3: # right
|
|
|
|
c = s + w0, s, s + w0 + w, s + h
|
|
|
|
elif i == 4: # bottom right
|
|
|
|
c = s + w0, s + hp, s + w0 + w, s + hp + h
|
|
|
|
elif i == 5: # bottom
|
|
|
|
c = s + w0 - w, s + h0, s + w0, s + h0 + h
|
|
|
|
elif i == 6: # bottom left
|
|
|
|
c = s + w0 - wp - w, s + h0, s + w0 - wp, s + h0 + h
|
|
|
|
elif i == 7: # left
|
|
|
|
c = s - w, s + h0 - h, s, s + h0
|
|
|
|
elif i == 8: # top left
|
|
|
|
c = s - w, s + h0 - hp - h, s, s + h0 - hp
|
|
|
|
|
|
|
|
padx, pady = c[:2]
|
|
|
|
x1, y1, x2, y2 = (max(x, 0) for x in c) # allocate coords
|
|
|
|
|
|
|
|
# Labels
|
|
|
|
labels, segments = self.labels[index].copy(), self.segments[index].copy()
|
|
|
|
if labels.size:
|
|
|
|
labels[:, 1:] = xywhn2xyxy(labels[:, 1:], w, h, padx, pady) # normalized xywh to pixel xyxy format
|
|
|
|
segments = [xyn2xy(x, w, h, padx, pady) for x in segments]
|
|
|
|
labels9.append(labels)
|
|
|
|
segments9.extend(segments)
|
|
|
|
|
|
|
|
# Image
|
|
|
|
img9[y1:y2, x1:x2] = img[y1 - pady:, x1 - padx:] # img9[ymin:ymax, xmin:xmax]
|
|
|
|
hp, wp = h, w # height, width previous
|
|
|
|
|
|
|
|
# Offset
|
|
|
|
yc, xc = (int(random.uniform(0, s)) for _ in self.mosaic_border) # mosaic center x, y
|
|
|
|
img9 = img9[yc:yc + 2 * s, xc:xc + 2 * s]
|
|
|
|
|
|
|
|
# Concat/clip labels
|
|
|
|
labels9 = np.concatenate(labels9, 0)
|
|
|
|
labels9[:, [1, 3]] -= xc
|
|
|
|
labels9[:, [2, 4]] -= yc
|
|
|
|
c = np.array([xc, yc]) # centers
|
|
|
|
segments9 = [x - c for x in segments9]
|
|
|
|
|
|
|
|
for x in (labels9[:, 1:], *segments9):
|
|
|
|
np.clip(x, 0, 2 * s, out=x) # clip when using random_perspective()
|
|
|
|
# img9, labels9 = replicate(img9, labels9) # replicate
|
|
|
|
|
|
|
|
# Augment
|
2022-03-31 22:52:34 +08:00
|
|
|
img9, labels9 = random_perspective(img9,
|
|
|
|
labels9,
|
|
|
|
segments9,
|
2022-02-08 01:59:26 +08:00
|
|
|
degrees=self.hyp['degrees'],
|
|
|
|
translate=self.hyp['translate'],
|
|
|
|
scale=self.hyp['scale'],
|
|
|
|
shear=self.hyp['shear'],
|
|
|
|
perspective=self.hyp['perspective'],
|
|
|
|
border=self.mosaic_border) # border to remove
|
|
|
|
|
|
|
|
return img9, labels9
|
|
|
|
|
2020-05-30 08:04:54 +08:00
|
|
|
@staticmethod
|
|
|
|
def collate_fn(batch):
|
2022-03-06 23:16:17 +08:00
|
|
|
im, label, path, shapes = zip(*batch) # transposed
|
2022-02-05 22:22:59 +08:00
|
|
|
for i, lb in enumerate(label):
|
|
|
|
lb[:, 0] = i # add target image index for build_targets()
|
2022-03-06 23:16:17 +08:00
|
|
|
return torch.stack(im, 0), torch.cat(label, 0), path, shapes
|
2020-05-30 08:04:54 +08:00
|
|
|
|
2021-01-05 11:54:09 +08:00
|
|
|
@staticmethod
|
|
|
|
def collate_fn4(batch):
|
2022-08-23 20:37:46 +08:00
|
|
|
im, label, path, shapes = zip(*batch) # transposed
|
2021-01-05 11:54:09 +08:00
|
|
|
n = len(shapes) // 4
|
2022-03-06 23:16:17 +08:00
|
|
|
im4, label4, path4, shapes4 = [], [], path[:n], shapes[:n]
|
2021-01-05 11:54:09 +08:00
|
|
|
|
2021-11-04 06:36:53 +08:00
|
|
|
ho = torch.tensor([[0.0, 0, 0, 1, 0, 0]])
|
|
|
|
wo = torch.tensor([[0.0, 0, 1, 0, 0, 0]])
|
|
|
|
s = torch.tensor([[1, 1, 0.5, 0.5, 0.5, 0.5]]) # scale
|
2021-01-05 11:54:09 +08:00
|
|
|
for i in range(n): # zidane torch.zeros(16,3,720,1280) # BCHW
|
|
|
|
i *= 4
|
|
|
|
if random.random() < 0.5:
|
2022-08-23 20:37:46 +08:00
|
|
|
im1 = F.interpolate(im[i].unsqueeze(0).float(), scale_factor=2.0, mode='bilinear',
|
|
|
|
align_corners=False)[0].type(im[i].type())
|
2022-02-05 22:22:59 +08:00
|
|
|
lb = label[i]
|
2021-01-05 11:54:09 +08:00
|
|
|
else:
|
2022-08-23 20:37:46 +08:00
|
|
|
im1 = torch.cat((torch.cat((im[i], im[i + 1]), 1), torch.cat((im[i + 2], im[i + 3]), 1)), 2)
|
2022-02-05 22:22:59 +08:00
|
|
|
lb = torch.cat((label[i], label[i + 1] + ho, label[i + 2] + wo, label[i + 3] + ho + wo), 0) * s
|
2022-08-23 20:37:46 +08:00
|
|
|
im4.append(im1)
|
2022-02-05 22:22:59 +08:00
|
|
|
label4.append(lb)
|
2021-01-05 11:54:09 +08:00
|
|
|
|
2022-02-05 22:22:59 +08:00
|
|
|
for i, lb in enumerate(label4):
|
|
|
|
lb[:, 0] = i # add target image index for build_targets()
|
2021-01-05 11:54:09 +08:00
|
|
|
|
2022-03-06 23:16:17 +08:00
|
|
|
return torch.stack(im4, 0), torch.cat(label4, 0), path4, shapes4
|
2021-01-05 11:54:09 +08:00
|
|
|
|
2020-05-30 08:04:54 +08:00
|
|
|
|
2020-07-24 13:49:54 +08:00
|
|
|
# Ancillary functions --------------------------------------------------------------------------------------------------
|
2022-02-09 05:20:44 +08:00
|
|
|
def flatten_recursive(path=DATASETS_DIR / 'coco128'):
|
2020-11-09 19:24:11 +08:00
|
|
|
# Flatten a recursive directory by bringing all files to top level
|
2022-07-25 22:52:28 +08:00
|
|
|
new_path = Path(f'{str(path)}_flat')
|
|
|
|
if os.path.exists(new_path):
|
|
|
|
shutil.rmtree(new_path) # delete output folder
|
|
|
|
os.makedirs(new_path) # make new output folder
|
|
|
|
for file in tqdm(glob.glob(f'{str(Path(path))}/**/*.*', recursive=True)):
|
2020-11-09 19:24:11 +08:00
|
|
|
shutil.copyfile(file, new_path / Path(file).name)
|
2020-11-24 00:18:21 +08:00
|
|
|
|
|
|
|
|
2022-06-12 01:30:54 +08:00
|
|
|
def extract_boxes(path=DATASETS_DIR / 'coco128'): # from utils.dataloaders import *; extract_boxes()
|
2020-11-24 23:13:04 +08:00
|
|
|
# Convert detection dataset into classification dataset, with one directory per class
|
|
|
|
path = Path(path) # images dir
|
New YOLOv5 Classification Models (#8956)
* Update
* Logger step fix: Increment step with epochs (#8654)
* enhance
* revert
* allow training from scratch
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update --img argument from train.py
single line
* fix image size from 640 to 128
* suport custom dataloader and augmentation
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* format
* Update dataloaders.py
* Single line return, single line comment, remove unused argument
* address PR comments
* fix spelling
* don't augment eval set
* use fstring
* update augmentations.py
* new maning convention for transforms
* reverse if statement, inline ops
* reverse if statement, inline ops
* updates
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update dataloaders
* Remove additional if statement
* Remove is_train as redundant
* Cleanup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Cleanup2
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update augmentations.py
* fix: imshow clip warning
* update
* Revert ToTensorV2 removal
* Update classifier.py
* Update normalize values, revert uint8
* normalize image using cv2
* remove dedundant comment
* Update classifier.py
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* replace print with logger
* commit steps
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Allow logging models from GenericLogger (#8676)
* enhance
* revert
* allow training from scratch
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update --img argument from train.py
single line
* fix image size from 640 to 128
* suport custom dataloader and augmentation
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* format
* Update dataloaders.py
* Single line return, single line comment, remove unused argument
* address PR comments
* fix spelling
* don't augment eval set
* use fstring
* update augmentations.py
* new maning convention for transforms
* reverse if statement, inline ops
* reverse if statement, inline ops
* updates
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update dataloaders
* Remove additional if statement
* Remove is_train as redundant
* Cleanup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Cleanup2
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update augmentations.py
* fix: imshow clip warning
* update
* Revert ToTensorV2 removal
* Update classifier.py
* Update normalize values, revert uint8
* normalize image using cv2
* remove dedundant comment
* Update classifier.py
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* replace print with logger
* commit steps
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* support final model logging
* update
* update
* update
* update
* remove curses
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update __init__.py
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
* Update
* Update
* Update
* Update
* Update dataset download
* Update dataset download
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Pass imgsz to classify_transforms()
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Cos scheduler
* Cos scheduler
* Remove unused args
* Update
* Add seed
* Add seed
* Update
* Update
* Add run(), main()
* Merge master
* Merge master
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Create YOLOv5 BaseModel class (#8829)
* Create BaseModel
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* fix
* Hub load device fix
* Update
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* Add experiment
* Merge master
* Attach names
* weight decay = 1e-4
* weight decay = 5e-5
* update smart_optimizer console printout
* fashion-mnist fix
* Merge master
* Update Table
* Update Table
* Remove destroy process group
* add kwargs to forward()
* fuse fix for resnet50
* nc, names fix for resnet50
* nc, names fix for resnet50
* ONNX CPU inference fix
* revert
* cuda
* if augment or visualize
* if augment or visualize
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* New smart_inference_mode()
* Update README
* Refactor into /classify dir
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* reset defaults
* reset defaults
* fix gpu predict
* warmup
* ema half fix
* spacing
* remove data
* remove cache
* remove denormalize
* save run settings
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* verbose false on initial plots
* new save_yaml() function
* Update ci-testing.yml
* Path(data) CI fix
* Separate classification CI
* fix val
* fix val
* fix val
* smartCrossEntropyLoss
* skip validation on hub load
* autodownload with working dir root
* str(data)
* Dataset usage example
* im_show normalize
* im_show normalize
* add imagenet simple names to multibackend
* Add validation speeds
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* 24-space names
* Update bash scripts
* Update permissions
* Add bash script arguments
* remove verbose
* TRT data fix
* names generator fix
* optimize if names
* update usage
* Add local loading
* Verbose=False
* update names printing
* Add Usage examples
* Add Usage examples
* Add Usage examples
* Add Usage examples
* named_children
* reshape_classifier_outputs
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update
* update
* fix CI
* fix incorrect class substitution
* fix incorrect class substitution
* remove denormalize
* ravel fix
* cleanup
* update opt file printing
* update opt file printing
* update defaults
* add opt to checkpoint
* Add warning
* Add comment
* plot half bug fix
* Use NotImplementedError
* fix export shape report
* Fix TRT load
* cleanup CI
* profile comment
* CI fix
* Add cls models
* avoid inplace error
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Fix usage examples
* Update README
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
Co-authored-by: Ayush Chaurasia <ayush.chaurarsia@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-17 17:59:01 +08:00
|
|
|
shutil.rmtree(path / 'classification') if (path / 'classification').is_dir() else None # remove existing
|
2020-11-24 23:13:04 +08:00
|
|
|
files = list(path.rglob('*.*'))
|
|
|
|
n = len(files) # number of files
|
|
|
|
for im_file in tqdm(files, total=n):
|
2021-07-19 16:43:01 +08:00
|
|
|
if im_file.suffix[1:] in IMG_FORMATS:
|
2020-11-24 23:13:04 +08:00
|
|
|
# image
|
|
|
|
im = cv2.imread(str(im_file))[..., ::-1] # BGR to RGB
|
|
|
|
h, w = im.shape[:2]
|
|
|
|
|
|
|
|
# labels
|
|
|
|
lb_file = Path(img2label_paths([str(im_file)])[0])
|
|
|
|
if Path(lb_file).exists():
|
2021-10-29 00:35:01 +08:00
|
|
|
with open(lb_file) as f:
|
2020-11-29 18:59:52 +08:00
|
|
|
lb = np.array([x.split() for x in f.read().strip().splitlines()], dtype=np.float32) # labels
|
2020-11-24 23:13:04 +08:00
|
|
|
|
|
|
|
for j, x in enumerate(lb):
|
|
|
|
c = int(x[0]) # class
|
|
|
|
f = (path / 'classifier') / f'{c}' / f'{path.stem}_{im_file.stem}_{j}.jpg' # new filename
|
|
|
|
if not f.parent.is_dir():
|
|
|
|
f.parent.mkdir(parents=True)
|
|
|
|
|
|
|
|
b = x[1:] * [w, h, w, h] # box
|
|
|
|
# b[2:] = b[2:].max() # rectangle to square
|
|
|
|
b[2:] = b[2:] * 1.2 + 3 # pad
|
2022-09-07 15:11:30 +08:00
|
|
|
b = xywh2xyxy(b.reshape(-1, 4)).ravel().astype(int)
|
2020-11-24 23:13:04 +08:00
|
|
|
|
|
|
|
b[[0, 2]] = np.clip(b[[0, 2]], 0, w) # clip boxes outside of image
|
|
|
|
b[[1, 3]] = np.clip(b[[1, 3]], 0, h)
|
|
|
|
assert cv2.imwrite(str(f), im[b[1]:b[3], b[0]:b[2]]), f'box failure in {f}'
|
|
|
|
|
2021-04-12 00:53:40 +08:00
|
|
|
|
2022-02-09 05:20:44 +08:00
|
|
|
def autosplit(path=DATASETS_DIR / 'coco128/images', weights=(0.9, 0.1, 0.0), annotated_only=False):
|
2020-11-24 01:35:25 +08:00
|
|
|
""" Autosplit a dataset into train/val/test splits and save path/autosplit_*.txt files
|
2022-06-12 01:30:54 +08:00
|
|
|
Usage: from utils.dataloaders import *; autosplit()
|
Update autosplit() with annotated_only option (#2466)
* Be able to create dataset from annotated images only
Add the ability to create a dataset/splits only with images that have an annotation file, i.e a .txt file, associated to it. As we talked about this, the absence of a txt file could mean two things:
* either the image wasn't yet labelled by someone,
* either there is no object to detect.
When it's easy to create small datasets, when you have to create datasets with thousands of images (and more coming), it's hard to track where you at and you don't want to wait to have all of them annotated before starting to train. Which means some images would lack txt files and annotations, resulting in label inconsistency as you say in #2313. By adding the annotated_only argument to the function, people could create, if they want to, datasets/splits only with images that were labelled, for sure.
* Cleanup and update print()
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
2021-03-15 08:11:27 +08:00
|
|
|
Arguments
|
2021-06-26 06:49:05 +08:00
|
|
|
path: Path to images directory
|
|
|
|
weights: Train, val, test weights (list, tuple)
|
|
|
|
annotated_only: Only use images with an annotated txt file
|
2020-11-24 00:18:21 +08:00
|
|
|
"""
|
|
|
|
path = Path(path) # images dir
|
2021-10-29 00:35:01 +08:00
|
|
|
files = sorted(x for x in path.rglob('*.*') if x.suffix[1:].lower() in IMG_FORMATS) # image files only
|
2020-11-24 01:35:25 +08:00
|
|
|
n = len(files) # number of files
|
2021-06-26 06:49:05 +08:00
|
|
|
random.seed(0) # for reproducibility
|
2020-11-24 01:35:25 +08:00
|
|
|
indices = random.choices([0, 1, 2], weights=weights, k=n) # assign each image to a split
|
Update autosplit() with annotated_only option (#2466)
* Be able to create dataset from annotated images only
Add the ability to create a dataset/splits only with images that have an annotation file, i.e a .txt file, associated to it. As we talked about this, the absence of a txt file could mean two things:
* either the image wasn't yet labelled by someone,
* either there is no object to detect.
When it's easy to create small datasets, when you have to create datasets with thousands of images (and more coming), it's hard to track where you at and you don't want to wait to have all of them annotated before starting to train. Which means some images would lack txt files and annotations, resulting in label inconsistency as you say in #2313. By adding the annotated_only argument to the function, people could create, if they want to, datasets/splits only with images that were labelled, for sure.
* Cleanup and update print()
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
2021-03-15 08:11:27 +08:00
|
|
|
|
2020-11-24 00:18:21 +08:00
|
|
|
txt = ['autosplit_train.txt', 'autosplit_val.txt', 'autosplit_test.txt'] # 3 txt files
|
2022-08-31 03:57:36 +08:00
|
|
|
for x in txt:
|
|
|
|
if (path.parent / x).exists():
|
|
|
|
(path.parent / x).unlink() # remove existing
|
Update autosplit() with annotated_only option (#2466)
* Be able to create dataset from annotated images only
Add the ability to create a dataset/splits only with images that have an annotation file, i.e a .txt file, associated to it. As we talked about this, the absence of a txt file could mean two things:
* either the image wasn't yet labelled by someone,
* either there is no object to detect.
When it's easy to create small datasets, when you have to create datasets with thousands of images (and more coming), it's hard to track where you at and you don't want to wait to have all of them annotated before starting to train. Which means some images would lack txt files and annotations, resulting in label inconsistency as you say in #2313. By adding the annotated_only argument to the function, people could create, if they want to, datasets/splits only with images that were labelled, for sure.
* Cleanup and update print()
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
2021-03-15 08:11:27 +08:00
|
|
|
|
|
|
|
print(f'Autosplitting images from {path}' + ', using *.txt labeled images only' * annotated_only)
|
2020-11-24 01:35:25 +08:00
|
|
|
for i, img in tqdm(zip(indices, files), total=n):
|
Update autosplit() with annotated_only option (#2466)
* Be able to create dataset from annotated images only
Add the ability to create a dataset/splits only with images that have an annotation file, i.e a .txt file, associated to it. As we talked about this, the absence of a txt file could mean two things:
* either the image wasn't yet labelled by someone,
* either there is no object to detect.
When it's easy to create small datasets, when you have to create datasets with thousands of images (and more coming), it's hard to track where you at and you don't want to wait to have all of them annotated before starting to train. Which means some images would lack txt files and annotations, resulting in label inconsistency as you say in #2313. By adding the annotated_only argument to the function, people could create, if they want to, datasets/splits only with images that were labelled, for sure.
* Cleanup and update print()
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
2021-03-15 08:11:27 +08:00
|
|
|
if not annotated_only or Path(img2label_paths([str(img)])[0]).exists(): # check label
|
2021-06-26 06:49:05 +08:00
|
|
|
with open(path.parent / txt[i], 'a') as f:
|
2022-07-25 22:52:28 +08:00
|
|
|
f.write(f'./{img.relative_to(path.parent).as_posix()}' + '\n') # add image to txt file
|
2021-06-09 00:00:21 +08:00
|
|
|
|
|
|
|
|
2021-06-16 17:12:15 +08:00
|
|
|
def verify_image_label(args):
|
2021-06-09 00:00:21 +08:00
|
|
|
# Verify one image-label pair
|
2021-06-16 17:12:15 +08:00
|
|
|
im_file, lb_file, prefix = args
|
2021-08-26 21:51:04 +08:00
|
|
|
nm, nf, ne, nc, msg, segments = 0, 0, 0, 0, '', [] # number (missing, found, empty, corrupt), message, segments
|
2021-06-09 00:00:21 +08:00
|
|
|
try:
|
|
|
|
# verify images
|
|
|
|
im = Image.open(im_file)
|
|
|
|
im.verify() # PIL verify
|
|
|
|
shape = exif_size(im) # image size
|
|
|
|
assert (shape[0] > 9) & (shape[1] > 9), f'image size {shape} <10 pixels'
|
2021-07-19 16:43:01 +08:00
|
|
|
assert im.format.lower() in IMG_FORMATS, f'invalid image format {im.format}'
|
2021-06-16 19:31:26 +08:00
|
|
|
if im.format.lower() in ('jpg', 'jpeg'):
|
|
|
|
with open(im_file, 'rb') as f:
|
|
|
|
f.seek(-2, 2)
|
2021-08-26 21:51:04 +08:00
|
|
|
if f.read() != b'\xff\xd9': # corrupt JPEG
|
2021-10-21 03:35:47 +08:00
|
|
|
ImageOps.exif_transpose(Image.open(im_file)).save(im_file, 'JPEG', subsampling=0, quality=100)
|
2021-10-16 03:32:08 +08:00
|
|
|
msg = f'{prefix}WARNING: {im_file}: corrupt JPEG restored and saved'
|
2021-06-09 00:00:21 +08:00
|
|
|
|
|
|
|
# verify labels
|
|
|
|
if os.path.isfile(lb_file):
|
|
|
|
nf = 1 # label found
|
2021-10-29 00:35:01 +08:00
|
|
|
with open(lb_file) as f:
|
2022-02-05 22:22:59 +08:00
|
|
|
lb = [x.split() for x in f.read().strip().splitlines() if len(x)]
|
2022-03-11 01:41:47 +08:00
|
|
|
if any(len(x) > 6 for x in lb): # is segment
|
2022-02-05 22:22:59 +08:00
|
|
|
classes = np.array([x[0] for x in lb], dtype=np.float32)
|
|
|
|
segments = [np.array(x[1:], dtype=np.float32).reshape(-1, 2) for x in lb] # (cls, xy1...)
|
|
|
|
lb = np.concatenate((classes.reshape(-1, 1), segments2boxes(segments)), 1) # (cls, xywh)
|
|
|
|
lb = np.array(lb, dtype=np.float32)
|
|
|
|
nl = len(lb)
|
2021-10-16 03:32:08 +08:00
|
|
|
if nl:
|
2022-02-05 22:22:59 +08:00
|
|
|
assert lb.shape[1] == 5, f'labels require 5 columns, {lb.shape[1]} columns detected'
|
|
|
|
assert (lb >= 0).all(), f'negative label values {lb[lb < 0]}'
|
|
|
|
assert (lb[:, 1:] <= 1).all(), f'non-normalized or out of bounds coordinates {lb[:, 1:][lb[:, 1:] > 1]}'
|
|
|
|
_, i = np.unique(lb, axis=0, return_index=True)
|
2021-11-11 07:15:17 +08:00
|
|
|
if len(i) < nl: # duplicate row check
|
2022-02-05 22:22:59 +08:00
|
|
|
lb = lb[i] # remove duplicates
|
2021-11-11 07:15:17 +08:00
|
|
|
if segments:
|
2022-08-30 19:40:51 +08:00
|
|
|
segments = [segments[x] for x in i]
|
2021-11-11 07:15:17 +08:00
|
|
|
msg = f'{prefix}WARNING: {im_file}: {nl - len(i)} duplicate labels removed'
|
2021-06-09 00:00:21 +08:00
|
|
|
else:
|
|
|
|
ne = 1 # label empty
|
2022-02-05 22:22:59 +08:00
|
|
|
lb = np.zeros((0, 5), dtype=np.float32)
|
2021-06-09 00:00:21 +08:00
|
|
|
else:
|
|
|
|
nm = 1 # label missing
|
2022-02-05 22:22:59 +08:00
|
|
|
lb = np.zeros((0, 5), dtype=np.float32)
|
|
|
|
return im_file, lb, shape, segments, nm, nf, ne, nc, msg
|
2021-06-09 00:00:21 +08:00
|
|
|
except Exception as e:
|
|
|
|
nc = 1
|
2021-10-16 03:32:08 +08:00
|
|
|
msg = f'{prefix}WARNING: {im_file}: ignoring corrupt image/label: {e}'
|
2021-06-18 16:21:47 +08:00
|
|
|
return [None, None, None, None, nm, nf, ne, nc, msg]
|
2021-06-09 05:09:45 +08:00
|
|
|
|
|
|
|
|
2022-07-26 00:20:01 +08:00
|
|
|
class HUBDatasetStats():
|
2021-06-09 05:09:45 +08:00
|
|
|
""" Return dataset statistics dictionary with images and instances counts per split per class
|
2021-07-28 08:04:10 +08:00
|
|
|
To run in parent directory: export PYTHONPATH="$PWD/yolov5"
|
2022-07-26 00:20:01 +08:00
|
|
|
Usage1: from utils.dataloaders import *; HUBDatasetStats('coco128.yaml', autodownload=True)
|
|
|
|
Usage2: from utils.dataloaders import *; HUBDatasetStats('path/to/coco128_with_yaml.zip')
|
2021-06-09 05:09:45 +08:00
|
|
|
Arguments
|
2021-07-08 17:42:30 +08:00
|
|
|
path: Path to data.yaml or data.zip (with data.yaml inside data.zip)
|
2021-06-09 16:56:11 +08:00
|
|
|
autodownload: Attempt to download dataset if not found locally
|
2021-06-09 05:09:45 +08:00
|
|
|
"""
|
2022-04-05 04:47:00 +08:00
|
|
|
|
2022-07-26 00:20:01 +08:00
|
|
|
def __init__(self, path='coco128.yaml', autodownload=False):
|
|
|
|
# Initialize class
|
|
|
|
zipped, data_dir, yaml_path = self._unzip(Path(path))
|
|
|
|
try:
|
|
|
|
with open(check_yaml(yaml_path), errors='ignore') as f:
|
|
|
|
data = yaml.safe_load(f) # data dict
|
|
|
|
if zipped:
|
|
|
|
data['path'] = data_dir
|
|
|
|
except Exception as e:
|
|
|
|
raise Exception("error/HUB/dataset_stats/yaml_load") from e
|
|
|
|
|
|
|
|
check_dataset(data, autodownload) # download dataset if missing
|
|
|
|
self.hub_dir = Path(data['path'] + '-hub')
|
|
|
|
self.im_dir = self.hub_dir / 'images'
|
|
|
|
self.im_dir.mkdir(parents=True, exist_ok=True) # makes /images
|
2022-08-17 23:52:53 +08:00
|
|
|
self.stats = {'nc': data['nc'], 'names': list(data['names'].values())} # statistics dictionary
|
2022-07-26 00:20:01 +08:00
|
|
|
self.data = data
|
2021-06-17 19:59:52 +08:00
|
|
|
|
2022-07-26 00:20:01 +08:00
|
|
|
@staticmethod
|
2022-06-12 01:30:54 +08:00
|
|
|
def _find_yaml(dir):
|
|
|
|
# Return data.yaml file
|
|
|
|
files = list(dir.glob('*.yaml')) or list(dir.rglob('*.yaml')) # try root level first and then recursive
|
|
|
|
assert files, f'No *.yaml file found in {dir}'
|
|
|
|
if len(files) > 1:
|
|
|
|
files = [f for f in files if f.stem == dir.stem] # prefer *.yaml files that match dir name
|
|
|
|
assert files, f'Multiple *.yaml files found in {dir}, only 1 *.yaml file allowed'
|
|
|
|
assert len(files) == 1, f'Multiple *.yaml files found: {files}, only 1 *.yaml file allowed in {dir}'
|
|
|
|
return files[0]
|
|
|
|
|
2022-07-26 00:20:01 +08:00
|
|
|
def _unzip(self, path):
|
2022-06-12 01:30:54 +08:00
|
|
|
# Unzip data.zip
|
2022-07-25 22:52:28 +08:00
|
|
|
if not str(path).endswith('.zip'): # path is data.yaml
|
2021-07-08 17:42:30 +08:00
|
|
|
return False, None, path
|
2022-07-25 22:52:28 +08:00
|
|
|
assert Path(path).is_file(), f'Error unzipping {path}, file not found'
|
|
|
|
ZipFile(path).extractall(path=path.parent) # unzip
|
|
|
|
dir = path.with_suffix('') # dataset directory == zip name
|
|
|
|
assert dir.is_dir(), f'Error unzipping {path}, {dir} not found. path/to/abc.zip MUST unzip to path/to/abc/'
|
2022-07-26 00:20:01 +08:00
|
|
|
return True, str(dir), self._find_yaml(dir) # zipped, data_dir, yaml_path
|
2021-07-08 17:42:30 +08:00
|
|
|
|
2022-07-26 00:20:01 +08:00
|
|
|
def _hub_ops(self, f, max_dim=1920):
|
2021-10-09 15:12:59 +08:00
|
|
|
# HUB ops for 1 image 'f': resize and save at reduced quality in /dataset-hub for web/app viewing
|
2022-07-26 00:20:01 +08:00
|
|
|
f_new = self.im_dir / Path(f).name # dataset-hub image filename
|
2021-10-09 15:12:59 +08:00
|
|
|
try: # use PIL
|
|
|
|
im = Image.open(f)
|
|
|
|
r = max_dim / max(im.height, im.width) # ratio
|
|
|
|
if r < 1.0: # image too large
|
|
|
|
im = im.resize((int(im.width * r), int(im.height * r)))
|
2022-08-05 20:45:41 +08:00
|
|
|
im.save(f_new, 'JPEG', quality=50, optimize=True) # save
|
2021-10-09 15:12:59 +08:00
|
|
|
except Exception as e: # use OpenCV
|
|
|
|
print(f'WARNING: HUB ops PIL failure {f}: {e}')
|
|
|
|
im = cv2.imread(f)
|
|
|
|
im_height, im_width = im.shape[:2]
|
|
|
|
r = max_dim / max(im_height, im_width) # ratio
|
|
|
|
if r < 1.0: # image too large
|
2021-11-29 20:15:36 +08:00
|
|
|
im = cv2.resize(im, (int(im_width * r), int(im_height * r)), interpolation=cv2.INTER_AREA)
|
2021-10-09 15:12:59 +08:00
|
|
|
cv2.imwrite(str(f_new), im)
|
2021-07-28 08:04:10 +08:00
|
|
|
|
2022-07-26 00:20:01 +08:00
|
|
|
def get_json(self, save=False, verbose=False):
|
|
|
|
# Return dataset JSON for Ultralytics HUB
|
|
|
|
def _round(labels):
|
|
|
|
# Update labels to integer class and 6 decimal place floats
|
|
|
|
return [[int(c), *(round(x, 4) for x in points)] for c, *points in labels]
|
|
|
|
|
|
|
|
for split in 'train', 'val', 'test':
|
|
|
|
if self.data.get(split) is None:
|
|
|
|
self.stats[split] = None # i.e. no test set
|
|
|
|
continue
|
|
|
|
dataset = LoadImagesAndLabels(self.data[split]) # load dataset
|
|
|
|
x = np.array([
|
|
|
|
np.bincount(label[:, 0].astype(int), minlength=self.data['nc'])
|
|
|
|
for label in tqdm(dataset.labels, total=dataset.n, desc='Statistics')]) # shape(128x80)
|
|
|
|
self.stats[split] = {
|
|
|
|
'instance_stats': {
|
|
|
|
'total': int(x.sum()),
|
|
|
|
'per_class': x.sum(0).tolist()},
|
|
|
|
'image_stats': {
|
|
|
|
'total': dataset.n,
|
|
|
|
'unlabelled': int(np.all(x == 0, 1).sum()),
|
|
|
|
'per_class': (x > 0).sum(0).tolist()},
|
|
|
|
'labels': [{
|
|
|
|
str(Path(k).name): _round(v.tolist())} for k, v in zip(dataset.im_files, dataset.labels)]}
|
|
|
|
|
|
|
|
# Save, print and return
|
|
|
|
if save:
|
|
|
|
stats_path = self.hub_dir / 'stats.json'
|
|
|
|
print(f'Saving {stats_path.resolve()}...')
|
|
|
|
with open(stats_path, 'w') as f:
|
|
|
|
json.dump(self.stats, f) # save stats.json
|
|
|
|
if verbose:
|
|
|
|
print(json.dumps(self.stats, indent=2, sort_keys=False))
|
|
|
|
return self.stats
|
|
|
|
|
|
|
|
def process_images(self):
|
|
|
|
# Compress images for Ultralytics HUB
|
|
|
|
for split in 'train', 'val', 'test':
|
|
|
|
if self.data.get(split) is None:
|
|
|
|
continue
|
|
|
|
dataset = LoadImagesAndLabels(self.data[split]) # load dataset
|
|
|
|
desc = f'{split} images'
|
|
|
|
for _ in tqdm(ThreadPool(NUM_THREADS).imap(self._hub_ops, dataset.im_files), total=dataset.n, desc=desc):
|
2021-07-28 08:04:10 +08:00
|
|
|
pass
|
2022-07-26 00:20:01 +08:00
|
|
|
print(f'Done. All images saved to {self.im_dir}')
|
|
|
|
return self.im_dir
|
New YOLOv5 Classification Models (#8956)
* Update
* Logger step fix: Increment step with epochs (#8654)
* enhance
* revert
* allow training from scratch
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update --img argument from train.py
single line
* fix image size from 640 to 128
* suport custom dataloader and augmentation
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* format
* Update dataloaders.py
* Single line return, single line comment, remove unused argument
* address PR comments
* fix spelling
* don't augment eval set
* use fstring
* update augmentations.py
* new maning convention for transforms
* reverse if statement, inline ops
* reverse if statement, inline ops
* updates
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update dataloaders
* Remove additional if statement
* Remove is_train as redundant
* Cleanup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Cleanup2
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update augmentations.py
* fix: imshow clip warning
* update
* Revert ToTensorV2 removal
* Update classifier.py
* Update normalize values, revert uint8
* normalize image using cv2
* remove dedundant comment
* Update classifier.py
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* replace print with logger
* commit steps
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Allow logging models from GenericLogger (#8676)
* enhance
* revert
* allow training from scratch
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update --img argument from train.py
single line
* fix image size from 640 to 128
* suport custom dataloader and augmentation
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* format
* Update dataloaders.py
* Single line return, single line comment, remove unused argument
* address PR comments
* fix spelling
* don't augment eval set
* use fstring
* update augmentations.py
* new maning convention for transforms
* reverse if statement, inline ops
* reverse if statement, inline ops
* updates
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update dataloaders
* Remove additional if statement
* Remove is_train as redundant
* Cleanup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Cleanup2
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update augmentations.py
* fix: imshow clip warning
* update
* Revert ToTensorV2 removal
* Update classifier.py
* Update normalize values, revert uint8
* normalize image using cv2
* remove dedundant comment
* Update classifier.py
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* replace print with logger
* commit steps
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* support final model logging
* update
* update
* update
* update
* remove curses
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update __init__.py
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
* Update
* Update
* Update
* Update
* Update dataset download
* Update dataset download
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Pass imgsz to classify_transforms()
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Cos scheduler
* Cos scheduler
* Remove unused args
* Update
* Add seed
* Add seed
* Update
* Update
* Add run(), main()
* Merge master
* Merge master
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Create YOLOv5 BaseModel class (#8829)
* Create BaseModel
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* fix
* Hub load device fix
* Update
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* Add experiment
* Merge master
* Attach names
* weight decay = 1e-4
* weight decay = 5e-5
* update smart_optimizer console printout
* fashion-mnist fix
* Merge master
* Update Table
* Update Table
* Remove destroy process group
* add kwargs to forward()
* fuse fix for resnet50
* nc, names fix for resnet50
* nc, names fix for resnet50
* ONNX CPU inference fix
* revert
* cuda
* if augment or visualize
* if augment or visualize
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* New smart_inference_mode()
* Update README
* Refactor into /classify dir
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* reset defaults
* reset defaults
* fix gpu predict
* warmup
* ema half fix
* spacing
* remove data
* remove cache
* remove denormalize
* save run settings
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* verbose false on initial plots
* new save_yaml() function
* Update ci-testing.yml
* Path(data) CI fix
* Separate classification CI
* fix val
* fix val
* fix val
* smartCrossEntropyLoss
* skip validation on hub load
* autodownload with working dir root
* str(data)
* Dataset usage example
* im_show normalize
* im_show normalize
* add imagenet simple names to multibackend
* Add validation speeds
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* 24-space names
* Update bash scripts
* Update permissions
* Add bash script arguments
* remove verbose
* TRT data fix
* names generator fix
* optimize if names
* update usage
* Add local loading
* Verbose=False
* update names printing
* Add Usage examples
* Add Usage examples
* Add Usage examples
* Add Usage examples
* named_children
* reshape_classifier_outputs
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update
* update
* fix CI
* fix incorrect class substitution
* fix incorrect class substitution
* remove denormalize
* ravel fix
* cleanup
* update opt file printing
* update opt file printing
* update defaults
* add opt to checkpoint
* Add warning
* Add comment
* plot half bug fix
* Use NotImplementedError
* fix export shape report
* Fix TRT load
* cleanup CI
* profile comment
* CI fix
* Add cls models
* avoid inplace error
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Fix usage examples
* Update README
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
Co-authored-by: Ayush Chaurasia <ayush.chaurarsia@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-17 17:59:01 +08:00
|
|
|
|
|
|
|
|
|
|
|
# Classification dataloaders -------------------------------------------------------------------------------------------
|
|
|
|
class ClassificationDataset(torchvision.datasets.ImageFolder):
|
|
|
|
"""
|
|
|
|
YOLOv5 Classification Dataset.
|
|
|
|
Arguments
|
|
|
|
root: Dataset path
|
|
|
|
transform: torchvision transforms, used by default
|
|
|
|
album_transform: Albumentations transforms, used if installed
|
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(self, root, augment, imgsz, cache=False):
|
|
|
|
super().__init__(root=root)
|
|
|
|
self.torch_transforms = classify_transforms(imgsz)
|
|
|
|
self.album_transforms = classify_albumentations(augment, imgsz) if augment else None
|
|
|
|
self.cache_ram = cache is True or cache == 'ram'
|
|
|
|
self.cache_disk = cache == 'disk'
|
|
|
|
self.samples = [list(x) + [Path(x[0]).with_suffix('.npy'), None] for x in self.samples] # file, index, npy, im
|
|
|
|
|
|
|
|
def __getitem__(self, i):
|
|
|
|
f, j, fn, im = self.samples[i] # filename, index, filename.with_suffix('.npy'), image
|
2022-08-30 21:17:58 +08:00
|
|
|
if self.cache_ram and im is None:
|
|
|
|
im = self.samples[i][3] = cv2.imread(f)
|
|
|
|
elif self.cache_disk:
|
|
|
|
if not fn.exists(): # load npy
|
|
|
|
np.save(fn.as_posix(), cv2.imread(f))
|
|
|
|
im = np.load(fn)
|
|
|
|
else: # read image
|
|
|
|
im = cv2.imread(f) # BGR
|
New YOLOv5 Classification Models (#8956)
* Update
* Logger step fix: Increment step with epochs (#8654)
* enhance
* revert
* allow training from scratch
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update --img argument from train.py
single line
* fix image size from 640 to 128
* suport custom dataloader and augmentation
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* format
* Update dataloaders.py
* Single line return, single line comment, remove unused argument
* address PR comments
* fix spelling
* don't augment eval set
* use fstring
* update augmentations.py
* new maning convention for transforms
* reverse if statement, inline ops
* reverse if statement, inline ops
* updates
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update dataloaders
* Remove additional if statement
* Remove is_train as redundant
* Cleanup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Cleanup2
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update augmentations.py
* fix: imshow clip warning
* update
* Revert ToTensorV2 removal
* Update classifier.py
* Update normalize values, revert uint8
* normalize image using cv2
* remove dedundant comment
* Update classifier.py
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* replace print with logger
* commit steps
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Allow logging models from GenericLogger (#8676)
* enhance
* revert
* allow training from scratch
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update --img argument from train.py
single line
* fix image size from 640 to 128
* suport custom dataloader and augmentation
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* format
* Update dataloaders.py
* Single line return, single line comment, remove unused argument
* address PR comments
* fix spelling
* don't augment eval set
* use fstring
* update augmentations.py
* new maning convention for transforms
* reverse if statement, inline ops
* reverse if statement, inline ops
* updates
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update dataloaders
* Remove additional if statement
* Remove is_train as redundant
* Cleanup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Cleanup2
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update augmentations.py
* fix: imshow clip warning
* update
* Revert ToTensorV2 removal
* Update classifier.py
* Update normalize values, revert uint8
* normalize image using cv2
* remove dedundant comment
* Update classifier.py
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* replace print with logger
* commit steps
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* support final model logging
* update
* update
* update
* update
* remove curses
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update __init__.py
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
* Update
* Update
* Update
* Update
* Update dataset download
* Update dataset download
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Pass imgsz to classify_transforms()
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Cos scheduler
* Cos scheduler
* Remove unused args
* Update
* Add seed
* Add seed
* Update
* Update
* Add run(), main()
* Merge master
* Merge master
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Create YOLOv5 BaseModel class (#8829)
* Create BaseModel
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* fix
* Hub load device fix
* Update
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* Add experiment
* Merge master
* Attach names
* weight decay = 1e-4
* weight decay = 5e-5
* update smart_optimizer console printout
* fashion-mnist fix
* Merge master
* Update Table
* Update Table
* Remove destroy process group
* add kwargs to forward()
* fuse fix for resnet50
* nc, names fix for resnet50
* nc, names fix for resnet50
* ONNX CPU inference fix
* revert
* cuda
* if augment or visualize
* if augment or visualize
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* New smart_inference_mode()
* Update README
* Refactor into /classify dir
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* reset defaults
* reset defaults
* fix gpu predict
* warmup
* ema half fix
* spacing
* remove data
* remove cache
* remove denormalize
* save run settings
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* verbose false on initial plots
* new save_yaml() function
* Update ci-testing.yml
* Path(data) CI fix
* Separate classification CI
* fix val
* fix val
* fix val
* smartCrossEntropyLoss
* skip validation on hub load
* autodownload with working dir root
* str(data)
* Dataset usage example
* im_show normalize
* im_show normalize
* add imagenet simple names to multibackend
* Add validation speeds
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* 24-space names
* Update bash scripts
* Update permissions
* Add bash script arguments
* remove verbose
* TRT data fix
* names generator fix
* optimize if names
* update usage
* Add local loading
* Verbose=False
* update names printing
* Add Usage examples
* Add Usage examples
* Add Usage examples
* Add Usage examples
* named_children
* reshape_classifier_outputs
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update
* update
* fix CI
* fix incorrect class substitution
* fix incorrect class substitution
* remove denormalize
* ravel fix
* cleanup
* update opt file printing
* update opt file printing
* update defaults
* add opt to checkpoint
* Add warning
* Add comment
* plot half bug fix
* Use NotImplementedError
* fix export shape report
* Fix TRT load
* cleanup CI
* profile comment
* CI fix
* Add cls models
* avoid inplace error
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Fix usage examples
* Update README
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
Co-authored-by: Ayush Chaurasia <ayush.chaurarsia@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-17 17:59:01 +08:00
|
|
|
if self.album_transforms:
|
|
|
|
sample = self.album_transforms(image=cv2.cvtColor(im, cv2.COLOR_BGR2RGB))["image"]
|
|
|
|
else:
|
2022-08-30 21:17:58 +08:00
|
|
|
sample = self.torch_transforms(im)
|
New YOLOv5 Classification Models (#8956)
* Update
* Logger step fix: Increment step with epochs (#8654)
* enhance
* revert
* allow training from scratch
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update --img argument from train.py
single line
* fix image size from 640 to 128
* suport custom dataloader and augmentation
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* format
* Update dataloaders.py
* Single line return, single line comment, remove unused argument
* address PR comments
* fix spelling
* don't augment eval set
* use fstring
* update augmentations.py
* new maning convention for transforms
* reverse if statement, inline ops
* reverse if statement, inline ops
* updates
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update dataloaders
* Remove additional if statement
* Remove is_train as redundant
* Cleanup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Cleanup2
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update augmentations.py
* fix: imshow clip warning
* update
* Revert ToTensorV2 removal
* Update classifier.py
* Update normalize values, revert uint8
* normalize image using cv2
* remove dedundant comment
* Update classifier.py
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* replace print with logger
* commit steps
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Allow logging models from GenericLogger (#8676)
* enhance
* revert
* allow training from scratch
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update --img argument from train.py
single line
* fix image size from 640 to 128
* suport custom dataloader and augmentation
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* format
* Update dataloaders.py
* Single line return, single line comment, remove unused argument
* address PR comments
* fix spelling
* don't augment eval set
* use fstring
* update augmentations.py
* new maning convention for transforms
* reverse if statement, inline ops
* reverse if statement, inline ops
* updates
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update dataloaders
* Remove additional if statement
* Remove is_train as redundant
* Cleanup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Cleanup2
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update augmentations.py
* fix: imshow clip warning
* update
* Revert ToTensorV2 removal
* Update classifier.py
* Update normalize values, revert uint8
* normalize image using cv2
* remove dedundant comment
* Update classifier.py
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* replace print with logger
* commit steps
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* support final model logging
* update
* update
* update
* update
* remove curses
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update __init__.py
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
* Update
* Update
* Update
* Update
* Update dataset download
* Update dataset download
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Pass imgsz to classify_transforms()
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Cos scheduler
* Cos scheduler
* Remove unused args
* Update
* Add seed
* Add seed
* Update
* Update
* Add run(), main()
* Merge master
* Merge master
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Create YOLOv5 BaseModel class (#8829)
* Create BaseModel
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* fix
* Hub load device fix
* Update
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* Add experiment
* Merge master
* Attach names
* weight decay = 1e-4
* weight decay = 5e-5
* update smart_optimizer console printout
* fashion-mnist fix
* Merge master
* Update Table
* Update Table
* Remove destroy process group
* add kwargs to forward()
* fuse fix for resnet50
* nc, names fix for resnet50
* nc, names fix for resnet50
* ONNX CPU inference fix
* revert
* cuda
* if augment or visualize
* if augment or visualize
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* New smart_inference_mode()
* Update README
* Refactor into /classify dir
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* reset defaults
* reset defaults
* fix gpu predict
* warmup
* ema half fix
* spacing
* remove data
* remove cache
* remove denormalize
* save run settings
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* verbose false on initial plots
* new save_yaml() function
* Update ci-testing.yml
* Path(data) CI fix
* Separate classification CI
* fix val
* fix val
* fix val
* smartCrossEntropyLoss
* skip validation on hub load
* autodownload with working dir root
* str(data)
* Dataset usage example
* im_show normalize
* im_show normalize
* add imagenet simple names to multibackend
* Add validation speeds
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* 24-space names
* Update bash scripts
* Update permissions
* Add bash script arguments
* remove verbose
* TRT data fix
* names generator fix
* optimize if names
* update usage
* Add local loading
* Verbose=False
* update names printing
* Add Usage examples
* Add Usage examples
* Add Usage examples
* Add Usage examples
* named_children
* reshape_classifier_outputs
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update
* update
* fix CI
* fix incorrect class substitution
* fix incorrect class substitution
* remove denormalize
* ravel fix
* cleanup
* update opt file printing
* update opt file printing
* update defaults
* add opt to checkpoint
* Add warning
* Add comment
* plot half bug fix
* Use NotImplementedError
* fix export shape report
* Fix TRT load
* cleanup CI
* profile comment
* CI fix
* Add cls models
* avoid inplace error
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Fix usage examples
* Update README
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
Co-authored-by: Ayush Chaurasia <ayush.chaurarsia@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-17 17:59:01 +08:00
|
|
|
return sample, j
|
|
|
|
|
|
|
|
|
|
|
|
def create_classification_dataloader(path,
|
|
|
|
imgsz=224,
|
|
|
|
batch_size=16,
|
|
|
|
augment=True,
|
|
|
|
cache=False,
|
|
|
|
rank=-1,
|
|
|
|
workers=8,
|
|
|
|
shuffle=True):
|
|
|
|
# Returns Dataloader object to be used with YOLOv5 Classifier
|
|
|
|
with torch_distributed_zero_first(rank): # init dataset *.cache only once if DDP
|
|
|
|
dataset = ClassificationDataset(root=path, imgsz=imgsz, augment=augment, cache=cache)
|
|
|
|
batch_size = min(batch_size, len(dataset))
|
|
|
|
nd = torch.cuda.device_count()
|
|
|
|
nw = min([os.cpu_count() // max(nd, 1), batch_size if batch_size > 1 else 0, workers])
|
|
|
|
sampler = None if rank == -1 else distributed.DistributedSampler(dataset, shuffle=shuffle)
|
|
|
|
generator = torch.Generator()
|
|
|
|
generator.manual_seed(0)
|
|
|
|
return InfiniteDataLoader(dataset,
|
|
|
|
batch_size=batch_size,
|
|
|
|
shuffle=shuffle and sampler is None,
|
|
|
|
num_workers=nw,
|
|
|
|
sampler=sampler,
|
2022-09-01 20:30:21 +08:00
|
|
|
pin_memory=PIN_MEMORY,
|
New YOLOv5 Classification Models (#8956)
* Update
* Logger step fix: Increment step with epochs (#8654)
* enhance
* revert
* allow training from scratch
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update --img argument from train.py
single line
* fix image size from 640 to 128
* suport custom dataloader and augmentation
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* format
* Update dataloaders.py
* Single line return, single line comment, remove unused argument
* address PR comments
* fix spelling
* don't augment eval set
* use fstring
* update augmentations.py
* new maning convention for transforms
* reverse if statement, inline ops
* reverse if statement, inline ops
* updates
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update dataloaders
* Remove additional if statement
* Remove is_train as redundant
* Cleanup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Cleanup2
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update augmentations.py
* fix: imshow clip warning
* update
* Revert ToTensorV2 removal
* Update classifier.py
* Update normalize values, revert uint8
* normalize image using cv2
* remove dedundant comment
* Update classifier.py
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* replace print with logger
* commit steps
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Allow logging models from GenericLogger (#8676)
* enhance
* revert
* allow training from scratch
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update --img argument from train.py
single line
* fix image size from 640 to 128
* suport custom dataloader and augmentation
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* format
* Update dataloaders.py
* Single line return, single line comment, remove unused argument
* address PR comments
* fix spelling
* don't augment eval set
* use fstring
* update augmentations.py
* new maning convention for transforms
* reverse if statement, inline ops
* reverse if statement, inline ops
* updates
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update dataloaders
* Remove additional if statement
* Remove is_train as redundant
* Cleanup
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Cleanup2
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update augmentations.py
* fix: imshow clip warning
* update
* Revert ToTensorV2 removal
* Update classifier.py
* Update normalize values, revert uint8
* normalize image using cv2
* remove dedundant comment
* Update classifier.py
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* replace print with logger
* commit steps
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* support final model logging
* update
* update
* update
* update
* remove curses
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update classifier.py
* Update __init__.py
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com>
* Update
* Update
* Update
* Update
* Update dataset download
* Update dataset download
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Pass imgsz to classify_transforms()
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Cos scheduler
* Cos scheduler
* Remove unused args
* Update
* Add seed
* Add seed
* Update
* Update
* Add run(), main()
* Merge master
* Merge master
* Update
* Update
* Update
* Update
* Update
* Update
* Update
* Create YOLOv5 BaseModel class (#8829)
* Create BaseModel
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* fix
* Hub load device fix
* Update
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
* Add experiment
* Merge master
* Attach names
* weight decay = 1e-4
* weight decay = 5e-5
* update smart_optimizer console printout
* fashion-mnist fix
* Merge master
* Update Table
* Update Table
* Remove destroy process group
* add kwargs to forward()
* fuse fix for resnet50
* nc, names fix for resnet50
* nc, names fix for resnet50
* ONNX CPU inference fix
* revert
* cuda
* if augment or visualize
* if augment or visualize
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* New smart_inference_mode()
* Update README
* Refactor into /classify dir
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* reset defaults
* reset defaults
* fix gpu predict
* warmup
* ema half fix
* spacing
* remove data
* remove cache
* remove denormalize
* save run settings
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* verbose false on initial plots
* new save_yaml() function
* Update ci-testing.yml
* Path(data) CI fix
* Separate classification CI
* fix val
* fix val
* fix val
* smartCrossEntropyLoss
* skip validation on hub load
* autodownload with working dir root
* str(data)
* Dataset usage example
* im_show normalize
* im_show normalize
* add imagenet simple names to multibackend
* Add validation speeds
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* 24-space names
* Update bash scripts
* Update permissions
* Add bash script arguments
* remove verbose
* TRT data fix
* names generator fix
* optimize if names
* update usage
* Add local loading
* Verbose=False
* update names printing
* Add Usage examples
* Add Usage examples
* Add Usage examples
* Add Usage examples
* named_children
* reshape_classifier_outputs
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* update
* update
* fix CI
* fix incorrect class substitution
* fix incorrect class substitution
* remove denormalize
* ravel fix
* cleanup
* update opt file printing
* update opt file printing
* update defaults
* add opt to checkpoint
* Add warning
* Add comment
* plot half bug fix
* Use NotImplementedError
* fix export shape report
* Fix TRT load
* cleanup CI
* profile comment
* CI fix
* Add cls models
* avoid inplace error
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Fix usage examples
* Update README
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
* Update README
Co-authored-by: Ayush Chaurasia <ayush.chaurarsia@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-17 17:59:01 +08:00
|
|
|
worker_init_fn=seed_worker,
|
|
|
|
generator=generator) # or DataLoader(persistent_workers=True)
|