From a02b7e6273b53f99536f3cefafc159e05bec2428 Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Sun, 30 Jul 2023 03:34:48 +0200 Subject: [PATCH] `ultralytics 8.0.145` Windows URL fix and Pose MPS warning (#4034) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- docker/Dockerfile-jetson | 4 ++-- ultralytics/__init__.py | 2 +- ultralytics/data/utils.py | 2 +- ultralytics/models/yolo/classify/train.py | 11 ++++++----- ultralytics/models/yolo/classify/val.py | 13 +++++++------ ultralytics/models/yolo/pose/predict.py | 5 ++++- ultralytics/models/yolo/pose/train.py | 6 +++++- ultralytics/models/yolo/pose/val.py | 3 +++ ultralytics/utils/__init__.py | 2 +- 9 files changed, 30 insertions(+), 18 deletions(-) diff --git a/docker/Dockerfile-jetson b/docker/Dockerfile-jetson index 0b7fd175..0a3603de 100644 --- a/docker/Dockerfile-jetson +++ b/docker/Dockerfile-jetson @@ -43,5 +43,5 @@ ENV OMP_NUM_THREADS=1 # Run # t=ultralytics/ultralytics:latest-jetson && sudo docker run -it --ipc=host $t -# Pull and Run with local volume mounted -# t=ultralytics/ultralytics:jetson && sudo docker pull $t && sudo docker run -it --runtime=nvidia $t +# Pull and Run with NVIDIA runtime +# t=ultralytics/ultralytics:latest-jetson && sudo docker pull $t && sudo docker run -it --ipc=host --runtime=nvidia $t diff --git a/ultralytics/__init__.py b/ultralytics/__init__.py index 30e238b7..b18d89ca 100644 --- a/ultralytics/__init__.py +++ b/ultralytics/__init__.py @@ -1,6 +1,6 @@ # Ultralytics YOLO 🚀, AGPL-3.0 license -__version__ = '8.0.144' +__version__ = '8.0.145' from ultralytics.hub import start from ultralytics.models import RTDETR, SAM, YOLO diff --git a/ultralytics/data/utils.py b/ultralytics/data/utils.py index 9c036e0e..f2b72a4d 100644 --- a/ultralytics/data/utils.py +++ b/ultralytics/data/utils.py @@ -244,7 +244,7 @@ def check_det_dataset(dataset, autodownload=True): val = [Path(x).resolve() for x in (val if isinstance(val, list) else [val])] # val path if not all(x.exists() for x in val): name = clean_url(dataset) # dataset name with URL auth stripped - m = f"\nDataset '{name}' images not found ⚠️, missing paths %s" % [str(x) for x in val if not x.exists()] + m = f"\nDataset '{name}' images not found ⚠️, missing path '{[x for x in val if not x.exists()][0]}'" if s and autodownload: LOGGER.warning(m) else: diff --git a/ultralytics/models/yolo/classify/train.py b/ultralytics/models/yolo/classify/train.py index 21101b5e..0494708a 100644 --- a/ultralytics/models/yolo/classify/train.py +++ b/ultralytics/models/yolo/classify/train.py @@ -135,11 +135,12 @@ class ClassificationTrainer(BaseTrainer): def plot_training_samples(self, batch, ni): """Plots training samples with their annotations.""" - plot_images(images=batch['img'], - batch_idx=torch.arange(len(batch['img'])), - cls=batch['cls'].squeeze(-1), - fname=self.save_dir / f'train_batch{ni}.jpg', - on_plot=self.on_plot) + plot_images( + images=batch['img'], + batch_idx=torch.arange(len(batch['img'])), + cls=batch['cls'].view(-1), # warning: use .view(), not .squeeze() for Classify models + fname=self.save_dir / f'train_batch{ni}.jpg', + on_plot=self.on_plot) def train(cfg=DEFAULT_CFG, use_python=False): diff --git a/ultralytics/models/yolo/classify/val.py b/ultralytics/models/yolo/classify/val.py index 76c47003..41fa9f31 100644 --- a/ultralytics/models/yolo/classify/val.py +++ b/ultralytics/models/yolo/classify/val.py @@ -74,12 +74,13 @@ class ClassificationValidator(BaseValidator): def plot_val_samples(self, batch, ni): """Plot validation image samples.""" - plot_images(images=batch['img'], - batch_idx=torch.arange(len(batch['img'])), - cls=batch['cls'].squeeze(-1), - fname=self.save_dir / f'val_batch{ni}_labels.jpg', - names=self.names, - on_plot=self.on_plot) + plot_images( + images=batch['img'], + batch_idx=torch.arange(len(batch['img'])), + cls=batch['cls'].view(-1), # warning: use .view(), not .squeeze() for Classify models + fname=self.save_dir / f'val_batch{ni}_labels.jpg', + names=self.names, + on_plot=self.on_plot) def plot_predictions(self, batch, preds, ni): """Plots predicted bounding boxes on input images and saves the result.""" diff --git a/ultralytics/models/yolo/pose/predict.py b/ultralytics/models/yolo/pose/predict.py index fe7f383a..709e9d9e 100644 --- a/ultralytics/models/yolo/pose/predict.py +++ b/ultralytics/models/yolo/pose/predict.py @@ -2,7 +2,7 @@ from ultralytics.engine.results import Results from ultralytics.models.yolo.detect.predict import DetectionPredictor -from ultralytics.utils import DEFAULT_CFG, ROOT, ops +from ultralytics.utils import DEFAULT_CFG, LOGGER, ROOT, ops class PosePredictor(DetectionPredictor): @@ -10,6 +10,9 @@ class PosePredictor(DetectionPredictor): def __init__(self, cfg=DEFAULT_CFG, overrides=None, _callbacks=None): super().__init__(cfg, overrides, _callbacks) self.args.task = 'pose' + if isinstance(self.args.device, str) and self.args.device.lower() == 'mps': + LOGGER.warning("WARNING ⚠️ Apple MPS known Pose bug. Recommend 'device=cpu' for Pose models. " + 'See https://github.com/ultralytics/ultralytics/issues/4031.') def postprocess(self, preds, img, orig_imgs): """Return detection results for a given input image or list of images.""" diff --git a/ultralytics/models/yolo/pose/train.py b/ultralytics/models/yolo/pose/train.py index df4a4af5..72f0a642 100644 --- a/ultralytics/models/yolo/pose/train.py +++ b/ultralytics/models/yolo/pose/train.py @@ -4,7 +4,7 @@ from copy import copy from ultralytics.models import yolo from ultralytics.nn.tasks import PoseModel -from ultralytics.utils import DEFAULT_CFG +from ultralytics.utils import DEFAULT_CFG, LOGGER from ultralytics.utils.plotting import plot_images, plot_results @@ -18,6 +18,10 @@ class PoseTrainer(yolo.detect.DetectionTrainer): overrides['task'] = 'pose' super().__init__(cfg, overrides, _callbacks) + if isinstance(self.args.device, str) and self.args.device.lower() == 'mps': + LOGGER.warning("WARNING ⚠️ Apple MPS known Pose bug. Recommend 'device=cpu' for Pose models. " + 'See https://github.com/ultralytics/ultralytics/issues/4031.') + def get_model(self, cfg=None, weights=None, verbose=True): """Get pose estimation model with specified configuration and weights.""" model = PoseModel(cfg, ch=3, nc=self.data['nc'], data_kpt_shape=self.data['kpt_shape'], verbose=verbose) diff --git a/ultralytics/models/yolo/pose/val.py b/ultralytics/models/yolo/pose/val.py index 1fd5f329..34390a33 100644 --- a/ultralytics/models/yolo/pose/val.py +++ b/ultralytics/models/yolo/pose/val.py @@ -19,6 +19,9 @@ class PoseValidator(DetectionValidator): super().__init__(dataloader, save_dir, pbar, args, _callbacks) self.args.task = 'pose' self.metrics = PoseMetrics(save_dir=self.save_dir, on_plot=self.on_plot) + if isinstance(self.args.device, str) and self.args.device.lower() == 'mps': + LOGGER.warning("WARNING ⚠️ Apple MPS known Pose bug. Recommend 'device=cpu' for Pose models. " + 'See https://github.com/ultralytics/ultralytics/issues/4031.') def preprocess(self, batch): """Preprocesses the batch by converting the 'keypoints' data into a float and moving it to the device.""" diff --git a/ultralytics/utils/__init__.py b/ultralytics/utils/__init__.py index 1f391c84..9a63d431 100644 --- a/ultralytics/utils/__init__.py +++ b/ultralytics/utils/__init__.py @@ -824,7 +824,7 @@ def deprecation_warn(arg, new_arg, version=None): def clean_url(url): """Strip auth from URL, i.e. https://url.com/file.txt?auth -> https://url.com/file.txt.""" - url = str(Path(url)).replace(':/', '://') # Pathlib turns :// -> :/ + url = Path(url).as_posix().replace(':/', '://') # Pathlib turns :// -> :/, as_posix() for Windows return urllib.parse.unquote(url).split('?')[0] # '%2F' to '/', split https://url.com/file.txt?auth