ultralytics 8.0.82__py3-none-any.whl → 8.0.84__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ultralytics might be problematic. Click here for more details.
- ultralytics/__init__.py +1 -1
- ultralytics/yolo/data/base.py +31 -10
- ultralytics/yolo/engine/model.py +8 -12
- ultralytics/yolo/engine/results.py +33 -9
- ultralytics/yolo/utils/__init__.py +23 -0
- ultralytics/yolo/utils/callbacks/base.py +2 -1
- ultralytics/yolo/utils/callbacks/mlflow.py +1 -9
- ultralytics/yolo/utils/callbacks/neptune.py +105 -0
- ultralytics/yolo/utils/instance.py +2 -2
- {ultralytics-8.0.82.dist-info → ultralytics-8.0.84.dist-info}/METADATA +11 -3
- {ultralytics-8.0.82.dist-info → ultralytics-8.0.84.dist-info}/RECORD +15 -14
- {ultralytics-8.0.82.dist-info → ultralytics-8.0.84.dist-info}/LICENSE +0 -0
- {ultralytics-8.0.82.dist-info → ultralytics-8.0.84.dist-info}/WHEEL +0 -0
- {ultralytics-8.0.82.dist-info → ultralytics-8.0.84.dist-info}/entry_points.txt +0 -0
- {ultralytics-8.0.82.dist-info → ultralytics-8.0.84.dist-info}/top_level.txt +0 -0
ultralytics/__init__.py
CHANGED
ultralytics/yolo/data/base.py
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import glob
|
|
4
4
|
import math
|
|
5
5
|
import os
|
|
6
|
+
import random
|
|
6
7
|
from copy import deepcopy
|
|
7
8
|
from multiprocessing.pool import ThreadPool
|
|
8
9
|
from pathlib import Path
|
|
@@ -10,10 +11,11 @@ from typing import Optional
|
|
|
10
11
|
|
|
11
12
|
import cv2
|
|
12
13
|
import numpy as np
|
|
14
|
+
import psutil
|
|
13
15
|
from torch.utils.data import Dataset
|
|
14
16
|
from tqdm import tqdm
|
|
15
17
|
|
|
16
|
-
from ..utils import LOCAL_RANK, NUM_THREADS, TQDM_BAR_FORMAT
|
|
18
|
+
from ..utils import LOCAL_RANK, LOGGER, NUM_THREADS, TQDM_BAR_FORMAT
|
|
17
19
|
from .utils import HELP_URL, IMG_FORMATS
|
|
18
20
|
|
|
19
21
|
|
|
@@ -63,14 +65,10 @@ class BaseDataset(Dataset):
|
|
|
63
65
|
self.augment = augment
|
|
64
66
|
self.single_cls = single_cls
|
|
65
67
|
self.prefix = prefix
|
|
66
|
-
|
|
67
68
|
self.im_files = self.get_img_files(self.img_path)
|
|
68
69
|
self.labels = self.get_labels()
|
|
69
70
|
self.update_labels(include_class=classes) # single_cls and include_class
|
|
70
|
-
|
|
71
|
-
self.ni = len(self.labels)
|
|
72
|
-
|
|
73
|
-
# Rect stuff
|
|
71
|
+
self.ni = len(self.labels) # number of images
|
|
74
72
|
self.rect = rect
|
|
75
73
|
self.batch_size = batch_size
|
|
76
74
|
self.stride = stride
|
|
@@ -80,6 +78,8 @@ class BaseDataset(Dataset):
|
|
|
80
78
|
self.set_rectangle()
|
|
81
79
|
|
|
82
80
|
# Cache stuff
|
|
81
|
+
if cache == 'ram' and not self.check_cache_ram():
|
|
82
|
+
cache = False
|
|
83
83
|
self.ims = [None] * self.ni
|
|
84
84
|
self.npy_files = [Path(f).with_suffix('.npy') for f in self.im_files]
|
|
85
85
|
if cache:
|
|
@@ -120,11 +120,14 @@ class BaseDataset(Dataset):
|
|
|
120
120
|
cls = self.labels[i]['cls']
|
|
121
121
|
bboxes = self.labels[i]['bboxes']
|
|
122
122
|
segments = self.labels[i]['segments']
|
|
123
|
+
keypoints = self.labels[i]['keypoints']
|
|
123
124
|
j = (cls == include_class_array).any(1)
|
|
124
125
|
self.labels[i]['cls'] = cls[j]
|
|
125
126
|
self.labels[i]['bboxes'] = bboxes[j]
|
|
126
127
|
if segments:
|
|
127
128
|
self.labels[i]['segments'] = [segments[si] for si, idx in enumerate(j) if idx]
|
|
129
|
+
if keypoints is not None:
|
|
130
|
+
self.labels[i]['keypoints'] = keypoints[j]
|
|
128
131
|
if self.single_cls:
|
|
129
132
|
self.labels[i]['cls'][:, 0] = 0
|
|
130
133
|
|
|
@@ -148,7 +151,7 @@ class BaseDataset(Dataset):
|
|
|
148
151
|
|
|
149
152
|
def cache_images(self, cache):
|
|
150
153
|
"""Cache images to memory or disk."""
|
|
151
|
-
gb = 0 #
|
|
154
|
+
b, gb = 0, 1 << 30 # bytes of cached images, bytes per gigabytes
|
|
152
155
|
self.im_hw0, self.im_hw = [None] * self.ni, [None] * self.ni
|
|
153
156
|
fcn = self.cache_images_to_disk if cache == 'disk' else self.load_image
|
|
154
157
|
with ThreadPool(NUM_THREADS) as pool:
|
|
@@ -156,11 +159,11 @@ class BaseDataset(Dataset):
|
|
|
156
159
|
pbar = tqdm(enumerate(results), total=self.ni, bar_format=TQDM_BAR_FORMAT, disable=LOCAL_RANK > 0)
|
|
157
160
|
for i, x in pbar:
|
|
158
161
|
if cache == 'disk':
|
|
159
|
-
|
|
162
|
+
b += self.npy_files[i].stat().st_size
|
|
160
163
|
else: # 'ram'
|
|
161
164
|
self.ims[i], self.im_hw0[i], self.im_hw[i] = x # im, hw_orig, hw_resized = load_image(self, i)
|
|
162
|
-
|
|
163
|
-
pbar.desc = f'{self.prefix}Caching images ({
|
|
165
|
+
b += self.ims[i].nbytes
|
|
166
|
+
pbar.desc = f'{self.prefix}Caching images ({b / gb:.1f}GB {cache})'
|
|
164
167
|
pbar.close()
|
|
165
168
|
|
|
166
169
|
def cache_images_to_disk(self, i):
|
|
@@ -169,6 +172,24 @@ class BaseDataset(Dataset):
|
|
|
169
172
|
if not f.exists():
|
|
170
173
|
np.save(f.as_posix(), cv2.imread(self.im_files[i]))
|
|
171
174
|
|
|
175
|
+
def check_cache_ram(self, safety_margin=0.5):
|
|
176
|
+
"""Check image caching requirements vs available memory."""
|
|
177
|
+
b, gb = 0, 1 << 30 # bytes of cached images, bytes per gigabytes
|
|
178
|
+
n = min(self.ni, 30) # extrapolate from 30 random images
|
|
179
|
+
for _ in range(n):
|
|
180
|
+
im = cv2.imread(random.choice(self.im_files)) # sample image
|
|
181
|
+
ratio = self.imgsz / max(im.shape[0], im.shape[1]) # max(h, w) # ratio
|
|
182
|
+
b += im.nbytes * ratio ** 2
|
|
183
|
+
mem_required = b * self.ni / n * (1 + safety_margin) # GB required to cache dataset into RAM
|
|
184
|
+
mem = psutil.virtual_memory()
|
|
185
|
+
cache = mem_required < mem.available # to cache or not to cache, that is the question
|
|
186
|
+
if not cache:
|
|
187
|
+
LOGGER.info(f'{self.prefix}{mem_required / gb:.1f}GB RAM required to cache images '
|
|
188
|
+
f'with {int(safety_margin * 100)}% safety margin but only '
|
|
189
|
+
f'{mem.available / gb:.1f}/{mem.total / gb:.1f}GB available, '
|
|
190
|
+
f"{'caching images ✅' if cache else 'not caching images ⚠️'}")
|
|
191
|
+
return cache
|
|
192
|
+
|
|
172
193
|
def set_rectangle(self):
|
|
173
194
|
"""Sets the shape of bounding boxes for YOLO detections as rectangles."""
|
|
174
195
|
bi = np.floor(np.arange(self.ni) / self.batch_size).astype(int) # batch index
|
ultralytics/yolo/engine/model.py
CHANGED
|
@@ -469,31 +469,27 @@ class YOLO:
|
|
|
469
469
|
|
|
470
470
|
@property
|
|
471
471
|
def names(self):
|
|
472
|
-
"""
|
|
473
|
-
Returns class names of the loaded model.
|
|
474
|
-
"""
|
|
472
|
+
"""Returns class names of the loaded model."""
|
|
475
473
|
return self.model.names if hasattr(self.model, 'names') else None
|
|
476
474
|
|
|
477
475
|
@property
|
|
478
476
|
def device(self):
|
|
479
|
-
"""
|
|
480
|
-
Returns device if PyTorch model
|
|
481
|
-
"""
|
|
477
|
+
"""Returns device if PyTorch model."""
|
|
482
478
|
return next(self.model.parameters()).device if isinstance(self.model, nn.Module) else None
|
|
483
479
|
|
|
484
480
|
@property
|
|
485
481
|
def transforms(self):
|
|
486
|
-
"""
|
|
487
|
-
Returns transform of the loaded model.
|
|
488
|
-
"""
|
|
482
|
+
"""Returns transform of the loaded model."""
|
|
489
483
|
return self.model.transforms if hasattr(self.model, 'transforms') else None
|
|
490
484
|
|
|
491
485
|
def add_callback(self, event: str, func):
|
|
492
|
-
"""
|
|
493
|
-
Add callback
|
|
494
|
-
"""
|
|
486
|
+
"""Add a callback."""
|
|
495
487
|
self.callbacks[event].append(func)
|
|
496
488
|
|
|
489
|
+
def clear_callback(self, event: str):
|
|
490
|
+
"""Clear all event callbacks."""
|
|
491
|
+
self.callbacks[event] = []
|
|
492
|
+
|
|
497
493
|
@staticmethod
|
|
498
494
|
def _reset_ckpt_args(args):
|
|
499
495
|
"""Reset arguments when loading a PyTorch model."""
|
|
@@ -97,11 +97,6 @@ class Results(SimpleClass):
|
|
|
97
97
|
self.path = path
|
|
98
98
|
self._keys = ('boxes', 'masks', 'probs', 'keypoints')
|
|
99
99
|
|
|
100
|
-
def pandas(self):
|
|
101
|
-
"""Convert the results to a pandas DataFrame."""
|
|
102
|
-
pass
|
|
103
|
-
# TODO masks.pandas + boxes.pandas + cls.pandas
|
|
104
|
-
|
|
105
100
|
def __getitem__(self, idx):
|
|
106
101
|
"""Return a Results object for the specified index."""
|
|
107
102
|
r = self.new()
|
|
@@ -315,6 +310,35 @@ class Results(SimpleClass):
|
|
|
315
310
|
file=save_dir / self.names[int(d.cls)] / f'{file_name.stem}.jpg',
|
|
316
311
|
BGR=True)
|
|
317
312
|
|
|
313
|
+
def pandas(self):
|
|
314
|
+
"""Convert the object to a pandas DataFrame (not yet implemented)."""
|
|
315
|
+
LOGGER.warning("WARNING ⚠️ 'Results.pandas' method is not yet implemented.")
|
|
316
|
+
|
|
317
|
+
def tojson(self, normalize=False):
|
|
318
|
+
"""Convert the object to JSON format."""
|
|
319
|
+
import json
|
|
320
|
+
|
|
321
|
+
# Create list of detection dictionaries
|
|
322
|
+
results = []
|
|
323
|
+
data = self.boxes.data.cpu().tolist()
|
|
324
|
+
h, w = self.orig_shape if normalize else (1, 1)
|
|
325
|
+
for i, row in enumerate(data):
|
|
326
|
+
box = {'x1': row[0] / w, 'y1': row[1] / h, 'x2': row[2] / w, 'y2': row[3] / h}
|
|
327
|
+
conf = row[4]
|
|
328
|
+
id = int(row[5])
|
|
329
|
+
name = self.names[id]
|
|
330
|
+
result = {'name': name, 'class': id, 'confidence': conf, 'box': box}
|
|
331
|
+
if self.masks:
|
|
332
|
+
x, y = self.masks.xy[i][:, 0], self.masks.xy[i][:, 1] # numpy array
|
|
333
|
+
result['segments'] = {'x': (x / w).tolist(), 'y': (y / h).tolist()}
|
|
334
|
+
if self.keypoints is not None:
|
|
335
|
+
x, y, visible = self.keypoints[i].cpu().unbind(dim=1) # torch Tensor
|
|
336
|
+
result['keypoints'] = {'x': (x / w).tolist(), 'y': (y / h).tolist(), 'visible': visible.tolist()}
|
|
337
|
+
results.append(result)
|
|
338
|
+
|
|
339
|
+
# Convert detections to JSON
|
|
340
|
+
return json.dumps(results, indent=2)
|
|
341
|
+
|
|
318
342
|
|
|
319
343
|
class Boxes(BaseTensor):
|
|
320
344
|
"""
|
|
@@ -397,10 +421,6 @@ class Boxes(BaseTensor):
|
|
|
397
421
|
"""Return the boxes in xywh format normalized by original image size."""
|
|
398
422
|
return self.xywh / self.orig_shape[[1, 0, 1, 0]]
|
|
399
423
|
|
|
400
|
-
def pandas(self):
|
|
401
|
-
"""Convert the object to a pandas DataFrame (not yet implemented)."""
|
|
402
|
-
LOGGER.info('results.pandas() method not yet implemented')
|
|
403
|
-
|
|
404
424
|
@property
|
|
405
425
|
def boxes(self):
|
|
406
426
|
"""Return the raw bboxes tensor (deprecated)."""
|
|
@@ -466,3 +486,7 @@ class Masks(BaseTensor):
|
|
|
466
486
|
"""Return the raw masks tensor (deprecated)."""
|
|
467
487
|
LOGGER.warning("WARNING ⚠️ 'Masks.masks' is deprecated. Use 'Masks.data' instead.")
|
|
468
488
|
return self.data
|
|
489
|
+
|
|
490
|
+
def pandas(self):
|
|
491
|
+
"""Convert the object to a pandas DataFrame (not yet implemented)."""
|
|
492
|
+
LOGGER.warning("WARNING ⚠️ 'Masks.pandas' method is not yet implemented.")
|
|
@@ -734,3 +734,26 @@ ENVIRONMENT = 'Colab' if is_colab() else 'Kaggle' if is_kaggle() else 'Jupyter'
|
|
|
734
734
|
'Docker' if is_docker() else platform.system()
|
|
735
735
|
TESTS_RUNNING = is_pytest_running() or is_github_actions_ci()
|
|
736
736
|
set_sentry()
|
|
737
|
+
|
|
738
|
+
# OpenCV Multilanguage-friendly functions ------------------------------------------------------------------------------------
|
|
739
|
+
imshow_ = cv2.imshow # copy to avoid recursion errors
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
def imread(filename, flags=cv2.IMREAD_COLOR):
|
|
743
|
+
return cv2.imdecode(np.fromfile(filename, np.uint8), flags)
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
def imwrite(filename, img):
|
|
747
|
+
try:
|
|
748
|
+
cv2.imencode(Path(filename).suffix, img)[1].tofile(filename)
|
|
749
|
+
return True
|
|
750
|
+
except Exception:
|
|
751
|
+
return False
|
|
752
|
+
|
|
753
|
+
|
|
754
|
+
def imshow(path, im):
|
|
755
|
+
imshow_(path.encode('unicode_escape').decode(), im)
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
if Path(inspect.stack()[0].filename).parent.parent.as_posix() in inspect.stack()[-1].filename:
|
|
759
|
+
cv2.imread, cv2.imwrite, cv2.imshow = imread, imwrite, imshow # redefine
|
|
@@ -200,11 +200,12 @@ def add_integration_callbacks(instance):
|
|
|
200
200
|
from .comet import callbacks as comet_callbacks
|
|
201
201
|
from .hub import callbacks as hub_callbacks
|
|
202
202
|
from .mlflow import callbacks as mf_callbacks
|
|
203
|
+
from .neptune import callbacks as neptune_callbacks
|
|
203
204
|
from .raytune import callbacks as tune_callbacks
|
|
204
205
|
from .tensorboard import callbacks as tb_callbacks
|
|
205
206
|
from .wb import callbacks as wb_callbacks
|
|
206
207
|
|
|
207
|
-
for x in clearml_callbacks, comet_callbacks, hub_callbacks, tb_callbacks, mf_callbacks, tune_callbacks, wb_callbacks:
|
|
208
|
+
for x in clearml_callbacks, comet_callbacks, hub_callbacks, tb_callbacks, mf_callbacks, tune_callbacks, wb_callbacks, neptune_callbacks:
|
|
208
209
|
for k, v in x.items():
|
|
209
210
|
if v not in instance.callbacks[k]: # prevent duplicate callbacks addition
|
|
210
211
|
instance.callbacks[k].append(v) # callback[name].append(func)
|
|
@@ -52,19 +52,12 @@ def on_fit_epoch_end(trainer):
|
|
|
52
52
|
run.log_metrics(metrics=metrics_dict, step=trainer.epoch)
|
|
53
53
|
|
|
54
54
|
|
|
55
|
-
def on_model_save(trainer):
|
|
56
|
-
"""Logs model and metrics to mlflow on save."""
|
|
57
|
-
if mlflow:
|
|
58
|
-
run.log_artifact(trainer.last)
|
|
59
|
-
|
|
60
|
-
|
|
61
55
|
def on_train_end(trainer):
|
|
62
56
|
"""Called at end of train loop to log model artifact info."""
|
|
63
57
|
if mlflow:
|
|
64
58
|
root_dir = Path(__file__).resolve().parents[3]
|
|
59
|
+
run.log_artifact(trainer.last)
|
|
65
60
|
run.log_artifact(trainer.best)
|
|
66
|
-
model_uri = f'runs:/{run_id}/'
|
|
67
|
-
run.register_model(model_uri, experiment_name)
|
|
68
61
|
run.pyfunc.log_model(artifact_path=experiment_name,
|
|
69
62
|
code_path=[str(root_dir)],
|
|
70
63
|
artifacts={'model_path': str(trainer.save_dir)},
|
|
@@ -74,5 +67,4 @@ def on_train_end(trainer):
|
|
|
74
67
|
callbacks = {
|
|
75
68
|
'on_pretrain_routine_end': on_pretrain_routine_end,
|
|
76
69
|
'on_fit_epoch_end': on_fit_epoch_end,
|
|
77
|
-
'on_model_save': on_model_save,
|
|
78
70
|
'on_train_end': on_train_end} if mlflow else {}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Ultralytics YOLO 🚀, AGPL-3.0 license
|
|
2
|
+
import matplotlib.image as mpimg
|
|
3
|
+
import matplotlib.pyplot as plt
|
|
4
|
+
|
|
5
|
+
from ultralytics.yolo.utils import LOGGER, TESTS_RUNNING
|
|
6
|
+
from ultralytics.yolo.utils.torch_utils import get_flops, get_num_params
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
import neptune
|
|
10
|
+
from neptune.types import File
|
|
11
|
+
|
|
12
|
+
assert not TESTS_RUNNING # do not log pytest
|
|
13
|
+
assert hasattr(neptune, '__version__')
|
|
14
|
+
except (ImportError, AssertionError):
|
|
15
|
+
neptune = None
|
|
16
|
+
|
|
17
|
+
run = None # NeptuneAI experiment logger instance
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _log_scalars(scalars, step=0):
|
|
21
|
+
"""Log scalars to the NeptuneAI experiment logger."""
|
|
22
|
+
if run:
|
|
23
|
+
for k, v in scalars.items():
|
|
24
|
+
run[k].append(value=v, step=step)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _log_images(imgs_dict, group=''):
|
|
28
|
+
"""Log scalars to the NeptuneAI experiment logger."""
|
|
29
|
+
if run:
|
|
30
|
+
for k, v in imgs_dict.items():
|
|
31
|
+
run[f'{group}/{k}'].upload(File(v))
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _log_plot(title, plot_path):
|
|
35
|
+
"""Log plots to the NeptuneAI experiment logger."""
|
|
36
|
+
"""
|
|
37
|
+
Log image as plot in the plot section of NeptuneAI
|
|
38
|
+
|
|
39
|
+
arguments:
|
|
40
|
+
title (str) Title of the plot
|
|
41
|
+
plot_path (PosixPath or str) Path to the saved image file
|
|
42
|
+
"""
|
|
43
|
+
img = mpimg.imread(plot_path)
|
|
44
|
+
fig = plt.figure()
|
|
45
|
+
ax = fig.add_axes([0, 0, 1, 1], frameon=False, aspect='auto', xticks=[], yticks=[]) # no ticks
|
|
46
|
+
ax.imshow(img)
|
|
47
|
+
run[f'Plots/{title}'].upload(fig)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def on_pretrain_routine_start(trainer):
|
|
51
|
+
"""Callback function called before the training routine starts."""
|
|
52
|
+
try:
|
|
53
|
+
global run
|
|
54
|
+
run = neptune.init_run(project=trainer.args.project or 'YOLOv8', name=trainer.args.name, tags=['YOLOv8'])
|
|
55
|
+
run['Configuration/Hyperparameters'] = {k: '' if v is None else v for k, v in vars(trainer.args).items()}
|
|
56
|
+
except Exception as e:
|
|
57
|
+
LOGGER.warning(f'WARNING ⚠️ NeptuneAI installed but not initialized correctly, not logging this run. {e}')
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def on_train_epoch_end(trainer):
|
|
61
|
+
"""Callback function called at end of each training epoch."""
|
|
62
|
+
_log_scalars(trainer.label_loss_items(trainer.tloss, prefix='train'), trainer.epoch + 1)
|
|
63
|
+
_log_scalars(trainer.lr, trainer.epoch + 1)
|
|
64
|
+
if trainer.epoch == 1:
|
|
65
|
+
_log_images({f.stem: str(f) for f in trainer.save_dir.glob('train_batch*.jpg')}, 'Mosaic')
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def on_fit_epoch_end(trainer):
|
|
69
|
+
"""Callback function called at end of each fit (train+val) epoch."""
|
|
70
|
+
if run and trainer.epoch == 0:
|
|
71
|
+
model_info = {
|
|
72
|
+
'parameters': get_num_params(trainer.model),
|
|
73
|
+
'GFLOPs': round(get_flops(trainer.model), 3),
|
|
74
|
+
'speed(ms)': round(trainer.validator.speed['inference'], 3)}
|
|
75
|
+
run['Configuration/Model'] = model_info
|
|
76
|
+
_log_scalars(trainer.metrics, trainer.epoch + 1)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def on_val_end(validator):
|
|
80
|
+
"""Callback function called at end of each validation."""
|
|
81
|
+
if run:
|
|
82
|
+
# Log val_labels and val_pred
|
|
83
|
+
_log_images({f.stem: str(f) for f in validator.save_dir.glob('val*.jpg')}, 'Validation')
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def on_train_end(trainer):
|
|
87
|
+
"""Callback function called at end of training."""
|
|
88
|
+
if run:
|
|
89
|
+
# Log final results, CM matrix + PR plots
|
|
90
|
+
files = ['results.png', 'confusion_matrix.png', *(f'{x}_curve.png' for x in ('F1', 'PR', 'P', 'R'))]
|
|
91
|
+
files = [(trainer.save_dir / f) for f in files if (trainer.save_dir / f).exists()] # filter
|
|
92
|
+
for f in files:
|
|
93
|
+
_log_plot(title=f.stem, plot_path=f)
|
|
94
|
+
# Log the final model
|
|
95
|
+
run[f'weights/{trainer.args.name or trainer.args.task}/{str(trainer.best.name)}'].upload(File(str(
|
|
96
|
+
trainer.best)))
|
|
97
|
+
run.stop()
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
callbacks = {
|
|
101
|
+
'on_pretrain_routine_start': on_pretrain_routine_start,
|
|
102
|
+
'on_train_epoch_end': on_train_epoch_end,
|
|
103
|
+
'on_fit_epoch_end': on_fit_epoch_end,
|
|
104
|
+
'on_val_end': on_val_end,
|
|
105
|
+
'on_train_end': on_train_end} if neptune else {}
|
|
@@ -34,7 +34,7 @@ class Bboxes:
|
|
|
34
34
|
"""Now only numpy is supported."""
|
|
35
35
|
|
|
36
36
|
def __init__(self, bboxes, format='xyxy') -> None:
|
|
37
|
-
assert format in _formats
|
|
37
|
+
assert format in _formats, f'Invalid bounding box format: {format}, format must be one of {_formats}'
|
|
38
38
|
bboxes = bboxes[None, :] if bboxes.ndim == 1 else bboxes
|
|
39
39
|
assert bboxes.ndim == 2
|
|
40
40
|
assert bboxes.shape[1] == 4
|
|
@@ -66,7 +66,7 @@ class Bboxes:
|
|
|
66
66
|
|
|
67
67
|
def convert(self, format):
|
|
68
68
|
"""Converts bounding box format from one type to another."""
|
|
69
|
-
assert format in _formats
|
|
69
|
+
assert format in _formats, f'Invalid bounding box format: {format}, format must be one of {_formats}'
|
|
70
70
|
if self.format == format:
|
|
71
71
|
return
|
|
72
72
|
elif self.format == 'xyxy':
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ultralytics
|
|
3
|
-
Version: 8.0.
|
|
3
|
+
Version: 8.0.84
|
|
4
4
|
Summary: Ultralytics YOLOv8
|
|
5
5
|
Home-page: https://github.com/ultralytics/ultralytics
|
|
6
6
|
Author: Ultralytics
|
|
@@ -78,7 +78,9 @@ Requires-Dist: tensorflowjs ; extra == 'export'
|
|
|
78
78
|
</div>
|
|
79
79
|
<br>
|
|
80
80
|
|
|
81
|
-
[Ultralytics
|
|
81
|
+
[Ultralytics](https://ultralytics.com) [YOLOv8](https://github.com/ultralytics/ultralytics) is a cutting-edge, state-of-the-art (SOTA) model that builds upon the success of previous YOLO versions and introduces new features and improvements to further boost performance and flexibility. YOLOv8 is designed to be fast, accurate, and easy to use, making it an excellent choice for a wide range of object detection and tracking, instance segmentation, image classification and pose estimation tasks.
|
|
82
|
+
|
|
83
|
+
We hope that the resources here will help you get the most out of YOLOv8. Please browse the YOLOv8 <a href="https://docs.ultralytics.com/">Docs</a> for details, raise an issue on <a href="https://github.com/ultralytics/ultralytics">GitHub</a> for support, and join our <a href="https://discord.gg/n6cFeSPZdD">Discord</a> community for questions and discussions!
|
|
82
84
|
|
|
83
85
|
To request an Enterprise License please complete the form at [Ultralytics Licensing](https://ultralytics.com/license).
|
|
84
86
|
|
|
@@ -102,6 +104,9 @@ To request an Enterprise License please complete the form at [Ultralytics Licens
|
|
|
102
104
|
<img src="https://github.com/ultralytics/assets/raw/main/social/logo-transparent.png" width="2%" alt="" />
|
|
103
105
|
<a href="https://www.instagram.com/ultralytics/" style="text-decoration:none;">
|
|
104
106
|
<img src="https://github.com/ultralytics/assets/raw/main/social/logo-social-instagram.png" width="2%" alt="" /></a>
|
|
107
|
+
<img src="https://github.com/ultralytics/assets/raw/main/social/logo-transparent.png" width="2%" alt="" />
|
|
108
|
+
<a href="https://discord.gg/n6cFeSPZdD" style="text-decoration:none;">
|
|
109
|
+
<img src="https://github.com/ultralytics/assets/blob/main/social/logo-social-discord.png" width="2%" alt="" /></a>
|
|
105
110
|
</div>
|
|
106
111
|
</div>
|
|
107
112
|
|
|
@@ -290,7 +295,7 @@ YOLOv8 is available under two different licenses:
|
|
|
290
295
|
|
|
291
296
|
## <div align="center">Contact</div>
|
|
292
297
|
|
|
293
|
-
For YOLOv8 bug reports and feature requests please visit [GitHub Issues](https://github.com/ultralytics/ultralytics/issues)
|
|
298
|
+
For YOLOv8 bug reports and feature requests please visit [GitHub Issues](https://github.com/ultralytics/ultralytics/issues), and join our [Discord](https://discord.gg/n6cFeSPZdD) community for questions and discussions!
|
|
294
299
|
|
|
295
300
|
<br>
|
|
296
301
|
<div align="center">
|
|
@@ -311,4 +316,7 @@ For YOLOv8 bug reports and feature requests please visit [GitHub Issues](https:/
|
|
|
311
316
|
<img src="https://github.com/ultralytics/assets/raw/main/social/logo-transparent.png" width="3%" alt="" />
|
|
312
317
|
<a href="https://www.instagram.com/ultralytics/" style="text-decoration:none;">
|
|
313
318
|
<img src="https://github.com/ultralytics/assets/raw/main/social/logo-social-instagram.png" width="3%" alt="" /></a>
|
|
319
|
+
<img src="https://github.com/ultralytics/assets/raw/main/social/logo-transparent.png" width="3%" alt="" />
|
|
320
|
+
<a href="https://discord.gg/n6cFeSPZdD" style="text-decoration:none;">
|
|
321
|
+
<img src="https://github.com/ultralytics/assets/blob/main/social/logo-social-discord.png" width="3%" alt="" /></a>
|
|
314
322
|
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
ultralytics/__init__.py,sha256=
|
|
1
|
+
ultralytics/__init__.py,sha256=yFl5HzLsNajIugI41L5fKqAPHPCHjQJPjkhCa3vGb1g,287
|
|
2
2
|
ultralytics/assets/bus.jpg,sha256=wCAZxJecGR63Od3ZRERe9Aja1Weayrb9Ug751DS_vGM,137419
|
|
3
3
|
ultralytics/assets/zidane.jpg,sha256=Ftc4aeMmen1O0A3o6GCDO9FlfBslLpTAw0gnetx7bts,50427
|
|
4
4
|
ultralytics/datasets/Argoverse.yaml,sha256=Q6hKRtI52JOYt4qmjkeo192mmgSkuCdOnfiUTxtBy5A,2751
|
|
@@ -54,7 +54,7 @@ ultralytics/yolo/cfg/__init__.py,sha256=ChytO9nlSVzGq9OFX2aG0YcwFKEG-F8sBEzYm3ET
|
|
|
54
54
|
ultralytics/yolo/cfg/default.yaml,sha256=xDD9Pq8oyS2D5E0vbPapophm6arUA0BfFz-Jf0Y9jTU,6238
|
|
55
55
|
ultralytics/yolo/data/__init__.py,sha256=vxjtAx1Y5fPnnJNJsMIHFmwZ0nnmS_R9iNaR1dS57jw,484
|
|
56
56
|
ultralytics/yolo/data/augment.py,sha256=mc10LnwfBqh-ZtWFSd5Kz1VBC4CDFIwqwz492c0XV0I,33512
|
|
57
|
-
ultralytics/yolo/data/base.py,sha256=
|
|
57
|
+
ultralytics/yolo/data/base.py,sha256=5L5O-3SoKnWdZHapud9zm9G4BxheJ_PXCbkfZsWbzBA,11709
|
|
58
58
|
ultralytics/yolo/data/build.py,sha256=n8daI3j7QwAkybKEGeAXvL0Hx44Q67PWL7XiU-GgxvQ,9166
|
|
59
59
|
ultralytics/yolo/data/dataset.py,sha256=6mRxLJKemncS0Guuv5SBkwJB2iPjP8GHmvMxyE3xn8Y,13392
|
|
60
60
|
ultralytics/yolo/data/dataset_wrappers.py,sha256=1IheItG9kjZP4U1sXbu69lYyt1bIgcyPf-whj_Nyzrw,1816
|
|
@@ -65,12 +65,12 @@ ultralytics/yolo/data/dataloaders/v5augmentations.py,sha256=t39RSuHCDCX4MV9EkIoJ
|
|
|
65
65
|
ultralytics/yolo/data/dataloaders/v5loader.py,sha256=1NbTtGxxo98qdHQJq1ZToei7f8qFZ04ffpv__hiVTKI,51257
|
|
66
66
|
ultralytics/yolo/engine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
67
67
|
ultralytics/yolo/engine/exporter.py,sha256=huzPGXx4dV6_s1Pe9fbqJh6q0A1GZFRjS1--5VcQlRU,40265
|
|
68
|
-
ultralytics/yolo/engine/model.py,sha256=
|
|
68
|
+
ultralytics/yolo/engine/model.py,sha256=oIfJA6sZ7UH1ZEpMQ-IqHXcS-3a_f9qeBR4ymRIHstI,21939
|
|
69
69
|
ultralytics/yolo/engine/predictor.py,sha256=ez0Fyrpu2hAw-CgoYcolXiSmSa9hO1lLAdEymWZSbqE,15529
|
|
70
|
-
ultralytics/yolo/engine/results.py,sha256=
|
|
70
|
+
ultralytics/yolo/engine/results.py,sha256=N2BKrCzCOgW8MFdnlvN_FvZE2-rbCGEqjPnSelpvFtk,20324
|
|
71
71
|
ultralytics/yolo/engine/trainer.py,sha256=W-NNeN_bflCkelrdNhYojIejWWEdh3FU1C5S-Ir_In0,31004
|
|
72
72
|
ultralytics/yolo/engine/validator.py,sha256=-kHek5qxXmcB6oLliTN3K7WwZTQQ2108xbhBDKx3jrE,11305
|
|
73
|
-
ultralytics/yolo/utils/__init__.py,sha256=
|
|
73
|
+
ultralytics/yolo/utils/__init__.py,sha256=iKPMM22JSjCwVNR_nJDoEOf8oz2s_DEzfS3VfirmkVg,26962
|
|
74
74
|
ultralytics/yolo/utils/autobatch.py,sha256=-8eEMRN9KyX9nslL5XAC2gMTFAH5YFA33q6nnQDj1qU,3846
|
|
75
75
|
ultralytics/yolo/utils/benchmarks.py,sha256=tWNAUO2PNJJJ9axJlkzckSNoQOLPP-nzqiydOKwcBVo,6676
|
|
76
76
|
ultralytics/yolo/utils/checks.py,sha256=taWu08pyjYEjZQFYo9ZJmACFgOFqaKDXi12qftE9DfU,14827
|
|
@@ -78,7 +78,7 @@ ultralytics/yolo/utils/dist.py,sha256=TGI8LHq7tedBnHVK8jgm50IvgUIsAtx7Zca8K2c1jN
|
|
|
78
78
|
ultralytics/yolo/utils/downloads.py,sha256=ggUlGG-Dl1y-e_KY83_i1j-23fXK48I5yv1MeZ_F_4s,11431
|
|
79
79
|
ultralytics/yolo/utils/errors.py,sha256=u8NUGZbWVrr4O3ez6UXnabNb_zRwJUPJqDOUSpmX3-k,317
|
|
80
80
|
ultralytics/yolo/utils/files.py,sha256=kZP5kykAUwveBinJvhvLSSWkU9vGM7EAoC0EXpaxbIE,3316
|
|
81
|
-
ultralytics/yolo/utils/instance.py,sha256=
|
|
81
|
+
ultralytics/yolo/utils/instance.py,sha256=S2vvc1vjNHHshFf4d3kwl8DvKsRo6ck38wDcf7eQYuI,14176
|
|
82
82
|
ultralytics/yolo/utils/loss.py,sha256=Ejdi8DXCDK57UG6FsM4mAIh05d7U9qzx_7bmhGoddiA,3195
|
|
83
83
|
ultralytics/yolo/utils/metrics.py,sha256=qMh9E9K4WzFJQdkosWCqCXHg0XirusDquWFienzOm2s,41829
|
|
84
84
|
ultralytics/yolo/utils/ops.py,sha256=UQDe4TCR56NsSPEeeW1-ZJKYMOrtadClPxP_XXWiNFM,28191
|
|
@@ -87,11 +87,12 @@ ultralytics/yolo/utils/tal.py,sha256=G0evBDn7jFPFljXt0SSBzZNa6rnbGJ8cEqspMyQ7Q6A
|
|
|
87
87
|
ultralytics/yolo/utils/torch_utils.py,sha256=GvNtGNyQB1wYc4t2_HA8AuvmIeMgNpNFPrGjuRQdb7U,20019
|
|
88
88
|
ultralytics/yolo/utils/tuner.py,sha256=LymX0Ub1O2rsi6H0iopo64hGJGFLvkJ1DDII4QEZav4,2302
|
|
89
89
|
ultralytics/yolo/utils/callbacks/__init__.py,sha256=9NgdqFgjXrL5RN8GpyQtu6EQcDffuEGRpU2IWeY7kjI,171
|
|
90
|
-
ultralytics/yolo/utils/callbacks/base.py,sha256=
|
|
90
|
+
ultralytics/yolo/utils/callbacks/base.py,sha256=re7n1msL99jauXNr4eFY3IgJ0mlfa56EOPLHf5Q2H7A,5630
|
|
91
91
|
ultralytics/yolo/utils/callbacks/clearml.py,sha256=DqdbrOj4jy5qgIrrJIdzj2AzMqHmTGeVtQOuFDo0XBg,5831
|
|
92
92
|
ultralytics/yolo/utils/callbacks/comet.py,sha256=cjOCTbfcWwarbQtOctv57l297L0-D7qP2MLL3tgVUE8,12971
|
|
93
93
|
ultralytics/yolo/utils/callbacks/hub.py,sha256=gCxuhzmcYc3OYag2S6pJhvkqQQJjr1l-kT1XDXvocWE,3633
|
|
94
|
-
ultralytics/yolo/utils/callbacks/mlflow.py,sha256=
|
|
94
|
+
ultralytics/yolo/utils/callbacks/mlflow.py,sha256=fCp4zNefamIzqZpOkoG2UqKVkeuIX41_em2Uw33iasY,2493
|
|
95
|
+
ultralytics/yolo/utils/callbacks/neptune.py,sha256=h40qnGm4GpYNCAP8-KMuJD3Qxc0jA3tULVnIvpRm0i8,3830
|
|
95
96
|
ultralytics/yolo/utils/callbacks/raytune.py,sha256=zvoB6HB_eoyLTScaMRj50ypLVplO3Kp8GF2fYritpWs,452
|
|
96
97
|
ultralytics/yolo/utils/callbacks/tensorboard.py,sha256=S6ZpSWklbG5lSjnwDEyC4qGvcCIsAH1vLO5z9DiNrYk,1524
|
|
97
98
|
ultralytics/yolo/utils/callbacks/wb.py,sha256=x9rvAcJxJf34Zp2oX2IOdqt81d8rS9Iiwb6VCegzJns,1869
|
|
@@ -112,9 +113,9 @@ ultralytics/yolo/v8/segment/__init__.py,sha256=TOdf3ju-D5hSi-PYMpETFmv-wyhIRKGuj
|
|
|
112
113
|
ultralytics/yolo/v8/segment/predict.py,sha256=u0UhoeSQIpygbHDoKA7YAc1jGw5HeFT955WrqeKg_aw,2685
|
|
113
114
|
ultralytics/yolo/v8/segment/train.py,sha256=Sccpul7l4v9mQ89BJQsTwQLX_5QdGpB0BStUGHIepjI,8283
|
|
114
115
|
ultralytics/yolo/v8/segment/val.py,sha256=qkZE0gXt6PQTFY7tFPL2sTe9PKok95yJ8YFI2e-nahY,12776
|
|
115
|
-
ultralytics-8.0.
|
|
116
|
-
ultralytics-8.0.
|
|
117
|
-
ultralytics-8.0.
|
|
118
|
-
ultralytics-8.0.
|
|
119
|
-
ultralytics-8.0.
|
|
120
|
-
ultralytics-8.0.
|
|
116
|
+
ultralytics-8.0.84.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
|
117
|
+
ultralytics-8.0.84.dist-info/METADATA,sha256=1cjE2I2mJngkhG0hUIrhsbvVIy2PmrY7o1JaY1U-Lgw,26660
|
|
118
|
+
ultralytics-8.0.84.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
|
119
|
+
ultralytics-8.0.84.dist-info/entry_points.txt,sha256=Ck1F6qKNokeHozQD5pmaFgXHL6dKyC2qCdyXao2e6Yg,103
|
|
120
|
+
ultralytics-8.0.84.dist-info/top_level.txt,sha256=XP49TwiMw4QGsvTLSYiJhz1xF_k7ev5mQ8jJXaXi45Q,12
|
|
121
|
+
ultralytics-8.0.84.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|