`ultralytics 8.0.26` new YOLOv5u models (#771)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Adrian Boguszewski <adrian.boguszewski@intel.com>
single_channel
Glenn Jocher 2 years ago committed by GitHub
parent b83374b42d
commit fa8811dcee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -3,7 +3,7 @@
# Image is CUDA-optimized for YOLOv8 single/multi-GPU training and inference
# Start FROM NVIDIA PyTorch image https://ngc.nvidia.com/catalog/containers/nvidia:pytorch
FROM nvcr.io/nvidia/pytorch:22.12-py3
FROM nvcr.io/nvidia/pytorch:23.01-py3
# Downloads to user config dir
ADD https://ultralytics.com/assets/Arial.ttf https://ultralytics.com/assets/Arial.Unicode.ttf /root/.config/Ultralytics/
@ -26,7 +26,7 @@ RUN git clone https://github.com/ultralytics/ultralytics /usr/src/ultralytics
# Install pip packages
RUN python -m pip install --upgrade pip wheel
RUN pip install --no-cache ultralytics albumentations comet gsutil notebook 'opencv-python<4.6.0.66'
RUN pip install --no-cache ultralytics albumentations comet gsutil notebook
# Set environment variables
ENV OMP_NUM_THREADS=1

@ -30,7 +30,7 @@ RUN pip install --no-cache ultralytics gsutil notebook \
tensorflow-aarch64
# tensorflowjs \
# onnx onnx-simplifier onnxruntime \
# coremltools openvino-dev \
# coremltools openvino-dev>=2022.3 \
# Cleanup
ENV DEBIAN_FRONTEND teletype

@ -28,7 +28,7 @@ COPY requirements.txt .
RUN python3 -m pip install --upgrade pip wheel
RUN pip install --no-cache ultralytics albumentations gsutil notebook \
coremltools onnx onnx-simplifier onnxruntime tensorflow-cpu \
# openvino-dev tensorflowjs \
# openvino-dev>=2022.3 tensorflowjs \
--extra-index-url https://download.pytorch.org/whl/cpu
# Cleanup

@ -67,7 +67,7 @@
"import ultralytics\n",
"ultralytics.checks()"
],
"execution_count": 1,
"execution_count": null,
"outputs": [
{
"output_type": "stream",
@ -116,7 +116,7 @@
"# Run inference on an image with YOLOv8n\n",
"!yolo predict model=yolov8n.pt source='https://ultralytics.com/images/zidane.jpg'"
],
"execution_count": 2,
"execution_count": null,
"outputs": [
{
"output_type": "stream",
@ -183,7 +183,7 @@
"# Validate YOLOv8n on COCO128 val\n",
"!yolo val model=yolov8n.pt data=coco128.yaml"
],
"execution_count": 3,
"execution_count": null,
"outputs": [
{
"output_type": "stream",
@ -306,7 +306,7 @@
"# Train YOLOv8n on COCO128 for 3 epochs\n",
"!yolo train model=yolov8n.pt data=coco128.yaml epochs=3 imgsz=640"
],
"execution_count": 4,
"execution_count": null,
"outputs": [
{
"output_type": "stream",
@ -495,7 +495,7 @@
"id": "CYIjW4igCjqD",
"outputId": "69cab2fb-cbfa-4acf-8e29-9c4fb6f4a38f"
},
"execution_count": 5,
"execution_count": null,
"outputs": [
{
"output_type": "stream",
@ -666,6 +666,19 @@
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"source": [
"# Validate multiple models\n",
"for x in 'nsmlx':\n",
" !yolo val model=yolov8{x}.pt data=coco.yaml"
],
"metadata": {
"id": "Wdc6t_bfzDDk"
},
"execution_count": null,
"outputs": []
}
]
}

@ -31,7 +31,7 @@ seaborn>=0.11.0
# scikit-learn==0.19.2 # CoreML quantization
# tensorflow>=2.4.1 # TF exports (-cpu, -aarch64, -macos)
# tensorflowjs>=3.9.0 # TF.js export
# openvino-dev>=2022.1 # OpenVINO export
# openvino-dev>=2022.3 # OpenVINO export
# Extras --------------------------------------
ipython # interactive notebook

@ -150,14 +150,14 @@ def test_predict_callback_and_setup():
# results -> List[batch_size]
path, _, im0s, _, _ = predictor.batch
# print('on_predict_batch_end', im0s[0].shape)
bs = [predictor.bs for i in range(0, len(path))]
bs = [predictor.bs for _ in range(len(path))]
predictor.results = zip(predictor.results, im0s, bs)
model = YOLO("yolov8n.pt")
model.add_callback("on_predict_batch_end", on_predict_batch_end)
dataset = load_inference_source(source=SOURCE, transforms=model.transforms)
bs = dataset.bs # access predictor properties
bs = dataset.bs # noqa access predictor properties
results = model.predict(dataset, stream=True) # source already setup
for _, (result, im0, bs) in enumerate(results):
print('test_callback', im0.shape)

@ -1,6 +1,6 @@
# Ultralytics YOLO 🚀, GPL-3.0 license
__version__ = "8.0.25"
__version__ = "8.0.26"
from ultralytics.yolo.engine.model import YOLO
from ultralytics.yolo.utils import ops

@ -148,7 +148,7 @@ def argument_error(arg):
return SyntaxError(f"'{arg}' is not a valid YOLO argument.\n{CLI_HELP_MSG}")
def entrypoint(debug=False):
def entrypoint(debug=''):
"""
This function is the ultralytics package entrypoint, it's responsible for parsing the command line arguments passed
to the package.
@ -163,7 +163,7 @@ def entrypoint(debug=False):
It uses the package's default cfg and initializes it using the passed overrides.
Then it calls the CLI function with the composed cfg
"""
args = ['train', 'model=yolov8n.pt', 'data=coco128.yaml', 'imgsz=32', 'epochs=1'] if debug else sys.argv[1:]
args = (debug.split(' ') if debug else sys.argv)[1:]
if not args: # no arguments passed
LOGGER.info(CLI_HELP_MSG)
return
@ -275,4 +275,5 @@ def copy_default_cfg():
if __name__ == '__main__':
entrypoint(debug=True)
# entrypoint(debug='yolo predict model=yolov8n.pt')
entrypoint(debug='')

@ -13,7 +13,7 @@ import cv2
import numpy as np
import requests
import torch
from PIL import Image, ImageOps
from PIL import Image
from ultralytics.yolo.data.augment import LetterBox
from ultralytics.yolo.data.utils import IMG_FORMATS, VID_FORMATS
@ -61,9 +61,11 @@ class LoadStreams:
self.frames[i] = max(int(cap.get(cv2.CAP_PROP_FRAME_COUNT)), 0) or float('inf') # infinite stream fallback
self.fps[i] = max((fps if math.isfinite(fps) else 0) % 100, 0) or 30 # 30 FPS fallback
_, self.imgs[i] = cap.read() # guarantee first frame
success, self.imgs[i] = cap.read() # guarantee first frame
if not success or self.imgs[i] is None:
raise ConnectionError(f'{st}Failed to read images from {s}')
self.threads[i] = Thread(target=self.update, args=([i, cap, s]), daemon=True)
LOGGER.info(f"{st} Success ({self.frames[i]} frames {w}x{h} at {self.fps[i]:.2f} FPS)")
LOGGER.info(f"{st}Success ({self.frames[i]} frames of shape {w}x{h} at {self.fps[i]:.2f} FPS)")
self.threads[i].start()
LOGGER.info('') # newline
@ -221,15 +223,15 @@ class LoadImages:
self.mode = 'video'
for _ in range(self.vid_stride):
self.cap.grab()
ret_val, im0 = self.cap.retrieve()
while not ret_val:
success, im0 = self.cap.retrieve()
while not success:
self.count += 1
self.cap.release()
if self.count == self.nf: # last video
raise StopIteration
path = self.files[self.count]
self._new_video(path)
ret_val, im0 = self.cap.read()
success, im0 = self.cap.read()
self.frame += 1
# im0 = self._cv2_rotate(im0) # for use if cv2 autorotation is False
@ -330,14 +332,14 @@ def autocast_list(source):
Merges a list of source of different types into a list of numpy arrays or PIL images
"""
files = []
for _, im in enumerate(source):
for im in source:
if isinstance(im, (str, Path)): # filename or uri
files.append(Image.open(requests.get(im, stream=True).raw if str(im).startswith('http') else im))
elif isinstance(im, (Image.Image, np.ndarray)): # PIL or np Image
files.append(im)
else:
raise Exception(
"Unsupported type encountered! See docs for supported types https://docs.ultralytics.com/predict")
raise TypeError(f"type {type(im).__name__} is not a supported Ultralytics prediction source type. \n"
f"See https://docs.ultralytics.com/predict for supported source types.")
return files

@ -1,22 +1,18 @@
#!/bin/bash
# Ultralytics YOLO 🚀, GPL-3.0 license
# Download latest models from https://github.com/ultralytics/yolov5/releases
# Example usage: bash data/scripts/download_weights.sh
# Download latest models from https://github.com/ultralytics/assets/releases
# Example usage: bash ultralytics/yolo/data/scripts/download_weights.sh
# parent
# └── yolov5
# ├── yolov5s.pt ← downloads here
# ├── yolov5m.pt
# └── weights
# ├── yolov8n.pt ← downloads here
# ├── yolov8s.pt
# └── ...
python - <<EOF
from utils.downloads import attempt_download
from ultralytics.yolo.utils.downloads import attempt_download_asset
p5 = list('nsmlx') # P5 models
p6 = [f'{x}6' for x in p5] # P6 models
cls = [f'{x}-cls' for x in p5] # classification models
seg = [f'{x}-seg' for x in p5] # classification models
for x in p5 + p6 + cls + seg:
attempt_download(f'weights/yolov5{x}.pt')
assets = [f'yolov8{size}{suffix}.pt' for size in 'nsmlx' for suffix in ('', '-cls', '-seg')]
for x in assets:
attempt_download_asset(f'weights/{x}')
EOF

@ -319,15 +319,20 @@ class Exporter:
@try_export
def _export_openvino(self, prefix=colorstr('OpenVINO:')):
# YOLOv8 OpenVINO export
check_requirements('openvino-dev') # requires openvino-dev: https://pypi.org/project/openvino-dev/
check_requirements('openvino-dev>=2022.3') # requires openvino-dev: https://pypi.org/project/openvino-dev/
import openvino.runtime as ov # noqa
from openvino.tools import mo # noqa
LOGGER.info(f'\n{prefix} starting export with openvino {ov.__version__}...')
f = str(self.file).replace(self.file.suffix, f'_openvino_model{os.sep}')
f_onnx = self.file.with_suffix('.onnx')
f_ov = str(Path(f) / self.file.with_suffix('.xml').name)
cmd = f"mo --input_model {f_onnx} --output_dir {f} {'--compress_to_fp16' * self.args.half}"
subprocess.run(cmd.split(), check=True, env=os.environ) # export
ov_model = mo.convert_model(f_onnx,
model_name=self.pretty_name,
framework="onnx",
compress_to_fp16=self.args.half) # export
ov.serialize(ov_model, f_ov) # save
yaml_save(Path(f) / self.file.with_suffix('.yaml').name, self.metadata) # add metadata.yaml
return f, None

@ -58,7 +58,13 @@ def check_imgsz(imgsz, stride=32, min_dim=1, floor=0):
stride = int(stride.max() if isinstance(stride, torch.Tensor) else stride)
# Convert image size to list if it is an integer
imgsz = [imgsz] if isinstance(imgsz, int) else list(imgsz)
if isinstance(imgsz, int):
imgsz = [imgsz]
elif isinstance(imgsz, (list, tuple)):
imgsz = list(imgsz)
else:
raise TypeError(f"'imgsz={imgsz}' is of invalid type {type(imgsz).__name__}. "
f"Valid imgsz types are int i.e. 'imgsz=640' or list i.e. 'imgsz=[640,640]'")
# Make image size a multiple of the stride
sz = [max(math.ceil(x / stride) * stride, floor) for x in imgsz]

@ -1,6 +1,7 @@
# Ultralytics YOLO 🚀, GPL-3.0 license
import contextlib
import re
import subprocess
from itertools import repeat
from multiprocessing.pool import ThreadPool
@ -118,7 +119,18 @@ def attempt_download_asset(file, repo='ultralytics/assets', release='v0.0.0'):
response = requests.get(f'https://api.github.com/repos/{repository}/releases/{version}').json() # github api
return response['tag_name'], [x['name'] for x in response['assets']] # tag, assets
file = Path(str(file).strip().replace("'", ''))
# YOLOv3/5u updates
file = str(file)
if 'yolov3' in file or 'yolov5' in file and 'u' not in file:
original_file = file
file = re.sub(r"(.*yolov5([nsmlx]))\.pt", "\\1u.pt", file) # i.e. yolov5n.pt -> yolov5nu.pt
file = re.sub(r"(.*yolov3(|-tiny|-spp))\.pt", "\\1u.pt", file) # i.e. yolov3-spp.pt -> yolov3-sppu.pt
if file != original_file:
LOGGER.info(f"PRO TIP 💡 Replace 'model={original_file}' with new 'model={file}'.\nYOLOv5 'u' models are "
f"trained with https://github.com/ultralytics/ultralytics and feature improved performance vs "
f"standard YOLOv5 models trained with https://github.com/ultralytics/yolov5.\n")
file = Path(file.strip().replace("'", ''))
if file.exists():
return str(file)
elif (SETTINGS['weights_dir'] / file).exists():
@ -136,7 +148,9 @@ def attempt_download_asset(file, repo='ultralytics/assets', release='v0.0.0'):
return file
# GitHub assets
assets = [f'yolov8{size}{suffix}.pt' for size in 'nsmlx' for suffix in ('', '6', '-cls', '-seg')] # default
assets = [f'yolov8{size}{suffix}.pt' for size in 'nsmlx' for suffix in ('', '6', '-cls', '-seg')] + \
[f'yolov5{size}u.pt' for size in 'nsmlx'] + \
[f'yolov3{size}u.pt' for size in ('', '-spp', '-tiny')]
try:
tag, assets = github_assets(repo, release)
except Exception:

@ -72,15 +72,11 @@ class SegmentationPredictor(DetectionPredictor):
im_gpu=torch.as_tensor(im0, dtype=torch.float16).to(self.device).permute(2, 0, 1).flip(0).contiguous() /
255 if self.args.retina_masks else im[idx])
# Segments
if self.args.save_txt:
segments = mask.segments
# Write results
for j, d in enumerate(reversed(det)):
cls, conf = d.cls.squeeze(), d.conf.squeeze()
if self.args.save_txt: # Write to file
seg = segments[j].copy()
seg = mask.segments[len(det) - j - 1].copy() # reversed mask.segments
seg = seg.reshape(-1) # (n,2) to (n*2)
line = (cls, *seg, conf) if self.args.save_conf else (cls, *seg) # label format
with open(f'{self.txt_path}.txt', 'a') as f:

Loading…
Cancel
Save