colorstr() updates (#1909)
Browse files* W&B ImportError message fix
* colorstr() updates
* colorstr() updates
* colorstr() default to 'blue', 'bold'
* train: magenta
* train: blue
- test.py +3 -2
- train.py +11 -10
- utils/autoanchor.py +2 -2
- utils/datasets.py +27 -27
- utils/general.py +2 -3
- utils/plots.py +1 -1
test.py
CHANGED
@@ -12,7 +12,7 @@ from tqdm import tqdm
|
|
12 |
from models.experimental import attempt_load
|
13 |
from utils.datasets import create_dataloader
|
14 |
from utils.general import coco80_to_coco91_class, check_dataset, check_file, check_img_size, check_requirements, \
|
15 |
-
box_iou, non_max_suppression, scale_coords, xyxy2xywh, xywh2xyxy, set_logging, increment_path
|
16 |
from utils.loss import compute_loss
|
17 |
from utils.metrics import ap_per_class, ConfusionMatrix
|
18 |
from utils.plots import plot_images, output_to_target, plot_study_txt
|
@@ -86,7 +86,8 @@ def test(data,
|
|
86 |
img = torch.zeros((1, 3, imgsz, imgsz), device=device) # init img
|
87 |
_ = model(img.half() if half else img) if device.type != 'cpu' else None # run once
|
88 |
path = data['test'] if opt.task == 'test' else data['val'] # path to val/test images
|
89 |
-
dataloader = create_dataloader(path, imgsz, batch_size, model.stride.max(), opt, pad=0.5, rect=True
|
|
|
90 |
|
91 |
seen = 0
|
92 |
confusion_matrix = ConfusionMatrix(nc=nc)
|
|
|
12 |
from models.experimental import attempt_load
|
13 |
from utils.datasets import create_dataloader
|
14 |
from utils.general import coco80_to_coco91_class, check_dataset, check_file, check_img_size, check_requirements, \
|
15 |
+
box_iou, non_max_suppression, scale_coords, xyxy2xywh, xywh2xyxy, set_logging, increment_path, colorstr
|
16 |
from utils.loss import compute_loss
|
17 |
from utils.metrics import ap_per_class, ConfusionMatrix
|
18 |
from utils.plots import plot_images, output_to_target, plot_study_txt
|
|
|
86 |
img = torch.zeros((1, 3, imgsz, imgsz), device=device) # init img
|
87 |
_ = model(img.half() if half else img) if device.type != 'cpu' else None # run once
|
88 |
path = data['test'] if opt.task == 'test' else data['val'] # path to val/test images
|
89 |
+
dataloader = create_dataloader(path, imgsz, batch_size, model.stride.max(), opt, pad=0.5, rect=True,
|
90 |
+
prefix=colorstr('test: ' if opt.task == 'test' else 'val: '))[0]
|
91 |
|
92 |
seen = 0
|
93 |
confusion_matrix = ConfusionMatrix(nc=nc)
|
train.py
CHANGED
@@ -36,15 +36,9 @@ from utils.torch_utils import ModelEMA, select_device, intersect_dicts, torch_di
|
|
36 |
|
37 |
logger = logging.getLogger(__name__)
|
38 |
|
39 |
-
try:
|
40 |
-
import wandb
|
41 |
-
except ImportError:
|
42 |
-
wandb = None
|
43 |
-
logger.info("Install Weights & Biases for experiment logging via 'pip install wandb' (recommended)")
|
44 |
-
|
45 |
|
46 |
def train(hyp, opt, device, tb_writer=None, wandb=None):
|
47 |
-
logger.info(colorstr('
|
48 |
save_dir, epochs, batch_size, total_batch_size, weights, rank = \
|
49 |
Path(opt.save_dir), opt.epochs, opt.batch_size, opt.total_batch_size, opt.weights, opt.global_rank
|
50 |
|
@@ -189,7 +183,7 @@ def train(hyp, opt, device, tb_writer=None, wandb=None):
|
|
189 |
dataloader, dataset = create_dataloader(train_path, imgsz, batch_size, gs, opt,
|
190 |
hyp=hyp, augment=True, cache=opt.cache_images, rect=opt.rect, rank=rank,
|
191 |
world_size=opt.world_size, workers=opt.workers,
|
192 |
-
image_weights=opt.image_weights, quad=opt.quad)
|
193 |
mlc = np.concatenate(dataset.labels, 0)[:, 0].max() # max label class
|
194 |
nb = len(dataloader) # number of batches
|
195 |
assert mlc < nc, 'Label class %g exceeds nc=%g in %s. Possible class labels are 0-%g' % (mlc, nc, opt.data, nc - 1)
|
@@ -198,8 +192,9 @@ def train(hyp, opt, device, tb_writer=None, wandb=None):
|
|
198 |
if rank in [-1, 0]:
|
199 |
ema.updates = start_epoch * nb // accumulate # set EMA updates
|
200 |
testloader = create_dataloader(test_path, imgsz_test, total_batch_size, gs, opt, # testloader
|
201 |
-
hyp=hyp, cache=opt.cache_images and not opt.notest, rect=True,
|
202 |
-
|
|
|
203 |
|
204 |
if not opt.resume:
|
205 |
labels = np.concatenate(dataset.labels, 0)
|
@@ -514,6 +509,12 @@ if __name__ == '__main__':
|
|
514 |
|
515 |
# Train
|
516 |
logger.info(opt)
|
|
|
|
|
|
|
|
|
|
|
|
|
517 |
if not opt.evolve:
|
518 |
tb_writer = None # init loggers
|
519 |
if opt.global_rank in [-1, 0]:
|
|
|
36 |
|
37 |
logger = logging.getLogger(__name__)
|
38 |
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
|
40 |
def train(hyp, opt, device, tb_writer=None, wandb=None):
|
41 |
+
logger.info(colorstr('Hyperparameters: ') + ', '.join(f'{k}={v}' for k, v in hyp.items()))
|
42 |
save_dir, epochs, batch_size, total_batch_size, weights, rank = \
|
43 |
Path(opt.save_dir), opt.epochs, opt.batch_size, opt.total_batch_size, opt.weights, opt.global_rank
|
44 |
|
|
|
183 |
dataloader, dataset = create_dataloader(train_path, imgsz, batch_size, gs, opt,
|
184 |
hyp=hyp, augment=True, cache=opt.cache_images, rect=opt.rect, rank=rank,
|
185 |
world_size=opt.world_size, workers=opt.workers,
|
186 |
+
image_weights=opt.image_weights, quad=opt.quad, prefix=colorstr('train: '))
|
187 |
mlc = np.concatenate(dataset.labels, 0)[:, 0].max() # max label class
|
188 |
nb = len(dataloader) # number of batches
|
189 |
assert mlc < nc, 'Label class %g exceeds nc=%g in %s. Possible class labels are 0-%g' % (mlc, nc, opt.data, nc - 1)
|
|
|
192 |
if rank in [-1, 0]:
|
193 |
ema.updates = start_epoch * nb // accumulate # set EMA updates
|
194 |
testloader = create_dataloader(test_path, imgsz_test, total_batch_size, gs, opt, # testloader
|
195 |
+
hyp=hyp, cache=opt.cache_images and not opt.notest, rect=True, rank=-1,
|
196 |
+
world_size=opt.world_size, workers=opt.workers,
|
197 |
+
pad=0.5, prefix=colorstr('val: '))[0]
|
198 |
|
199 |
if not opt.resume:
|
200 |
labels = np.concatenate(dataset.labels, 0)
|
|
|
509 |
|
510 |
# Train
|
511 |
logger.info(opt)
|
512 |
+
try:
|
513 |
+
import wandb
|
514 |
+
except ImportError:
|
515 |
+
wandb = None
|
516 |
+
prefix = colorstr('wandb: ')
|
517 |
+
logger.info(f"{prefix}Install Weights & Biases for YOLOv5 logging with 'pip install wandb' (recommended)")
|
518 |
if not opt.evolve:
|
519 |
tb_writer = None # init loggers
|
520 |
if opt.global_rank in [-1, 0]:
|
utils/autoanchor.py
CHANGED
@@ -22,7 +22,7 @@ def check_anchor_order(m):
|
|
22 |
|
23 |
def check_anchors(dataset, model, thr=4.0, imgsz=640):
|
24 |
# Check anchor fit to data, recompute if necessary
|
25 |
-
prefix = colorstr('
|
26 |
print(f'\n{prefix}Analyzing anchors... ', end='')
|
27 |
m = model.module.model[-1] if hasattr(model, 'module') else model.model[-1] # Detect()
|
28 |
shapes = imgsz * dataset.shapes / dataset.shapes.max(1, keepdims=True)
|
@@ -73,7 +73,7 @@ def kmean_anchors(path='./data/coco128.yaml', n=9, img_size=640, thr=4.0, gen=10
|
|
73 |
from utils.autoanchor import *; _ = kmean_anchors()
|
74 |
"""
|
75 |
thr = 1. / thr
|
76 |
-
prefix = colorstr('
|
77 |
|
78 |
def metric(k, wh): # compute metrics
|
79 |
r = wh[:, None] / k[None]
|
|
|
22 |
|
23 |
def check_anchors(dataset, model, thr=4.0, imgsz=640):
|
24 |
# Check anchor fit to data, recompute if necessary
|
25 |
+
prefix = colorstr('autoanchor: ')
|
26 |
print(f'\n{prefix}Analyzing anchors... ', end='')
|
27 |
m = model.module.model[-1] if hasattr(model, 'module') else model.model[-1] # Detect()
|
28 |
shapes = imgsz * dataset.shapes / dataset.shapes.max(1, keepdims=True)
|
|
|
73 |
from utils.autoanchor import *; _ = kmean_anchors()
|
74 |
"""
|
75 |
thr = 1. / thr
|
76 |
+
prefix = colorstr('autoanchor: ')
|
77 |
|
78 |
def metric(k, wh): # compute metrics
|
79 |
r = wh[:, None] / k[None]
|
utils/datasets.py
CHANGED
@@ -56,7 +56,7 @@ def exif_size(img):
|
|
56 |
|
57 |
|
58 |
def create_dataloader(path, imgsz, batch_size, stride, opt, hyp=None, augment=False, cache=False, pad=0.0, rect=False,
|
59 |
-
rank=-1, world_size=1, workers=8, image_weights=False, quad=False):
|
60 |
# Make sure only the first process in DDP process the dataset first, and the following others can use the cache
|
61 |
with torch_distributed_zero_first(rank):
|
62 |
dataset = LoadImagesAndLabels(path, imgsz, batch_size,
|
@@ -67,8 +67,8 @@ def create_dataloader(path, imgsz, batch_size, stride, opt, hyp=None, augment=Fa
|
|
67 |
single_cls=opt.single_cls,
|
68 |
stride=int(stride),
|
69 |
pad=pad,
|
70 |
-
|
71 |
-
|
72 |
|
73 |
batch_size = min(batch_size, len(dataset))
|
74 |
nw = min([os.cpu_count() // world_size, batch_size if batch_size > 1 else 0, workers]) # number of workers
|
@@ -129,7 +129,7 @@ class LoadImages: # for inference
|
|
129 |
elif os.path.isfile(p):
|
130 |
files = [p] # files
|
131 |
else:
|
132 |
-
raise Exception('ERROR:
|
133 |
|
134 |
images = [x for x in files if x.split('.')[-1].lower() in img_formats]
|
135 |
videos = [x for x in files if x.split('.')[-1].lower() in vid_formats]
|
@@ -144,8 +144,8 @@ class LoadImages: # for inference
|
|
144 |
self.new_video(videos[0]) # new video
|
145 |
else:
|
146 |
self.cap = None
|
147 |
-
assert self.nf > 0, 'No images or videos found in
|
148 |
-
|
149 |
|
150 |
def __iter__(self):
|
151 |
self.count = 0
|
@@ -171,14 +171,14 @@ class LoadImages: # for inference
|
|
171 |
ret_val, img0 = self.cap.read()
|
172 |
|
173 |
self.frame += 1
|
174 |
-
print('video
|
175 |
|
176 |
else:
|
177 |
# Read image
|
178 |
self.count += 1
|
179 |
img0 = cv2.imread(path) # BGR
|
180 |
assert img0 is not None, 'Image Not Found ' + path
|
181 |
-
print('image
|
182 |
|
183 |
# Padded resize
|
184 |
img = letterbox(img0, new_shape=self.img_size)[0]
|
@@ -238,9 +238,9 @@ class LoadWebcam: # for inference
|
|
238 |
break
|
239 |
|
240 |
# Print
|
241 |
-
assert ret_val, 'Camera Error
|
242 |
img_path = 'webcam.jpg'
|
243 |
-
print('webcam
|
244 |
|
245 |
# Padded resize
|
246 |
img = letterbox(img0, new_shape=self.img_size)[0]
|
@@ -271,15 +271,15 @@ class LoadStreams: # multiple IP or RTSP cameras
|
|
271 |
self.sources = [clean_str(x) for x in sources] # clean source names for later
|
272 |
for i, s in enumerate(sources):
|
273 |
# Start the thread to read frames from the video stream
|
274 |
-
print('
|
275 |
cap = cv2.VideoCapture(eval(s) if s.isnumeric() else s)
|
276 |
-
assert cap.isOpened(), 'Failed to open
|
277 |
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
278 |
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
279 |
fps = cap.get(cv2.CAP_PROP_FPS) % 100
|
280 |
_, self.imgs[i] = cap.read() # guarantee first frame
|
281 |
thread = Thread(target=self.update, args=([i, cap]), daemon=True)
|
282 |
-
print(' success (
|
283 |
thread.start()
|
284 |
print('') # newline
|
285 |
|
@@ -336,7 +336,7 @@ def img2label_paths(img_paths):
|
|
336 |
|
337 |
class LoadImagesAndLabels(Dataset): # for training/testing
|
338 |
def __init__(self, path, img_size=640, batch_size=16, augment=False, hyp=None, rect=False, image_weights=False,
|
339 |
-
cache_images=False, single_cls=False, stride=32, pad=0.0,
|
340 |
self.img_size = img_size
|
341 |
self.augment = augment
|
342 |
self.hyp = hyp
|
@@ -358,11 +358,11 @@ class LoadImagesAndLabels(Dataset): # for training/testing
|
|
358 |
parent = str(p.parent) + os.sep
|
359 |
f += [x.replace('./', parent) if x.startswith('./') else x for x in t] # local to global path
|
360 |
else:
|
361 |
-
raise Exception('
|
362 |
self.img_files = sorted([x.replace('/', os.sep) for x in f if x.split('.')[-1].lower() in img_formats])
|
363 |
-
assert self.img_files, 'No images found'
|
364 |
except Exception as e:
|
365 |
-
raise Exception('Error loading data from
|
366 |
|
367 |
# Check cache
|
368 |
self.label_files = img2label_paths(self.img_files) # labels
|
@@ -370,15 +370,15 @@ class LoadImagesAndLabels(Dataset): # for training/testing
|
|
370 |
if cache_path.is_file():
|
371 |
cache = torch.load(cache_path) # load
|
372 |
if cache['hash'] != get_hash(self.label_files + self.img_files) or 'results' not in cache: # changed
|
373 |
-
cache = self.cache_labels(cache_path) # re-cache
|
374 |
else:
|
375 |
-
cache = self.cache_labels(cache_path) # cache
|
376 |
|
377 |
# Display cache
|
378 |
[nf, nm, ne, nc, n] = cache.pop('results') # found, missing, empty, corrupted, total
|
379 |
desc = f"Scanning '{cache_path}' for images and labels... {nf} found, {nm} missing, {ne} empty, {nc} corrupted"
|
380 |
-
tqdm(None, desc=desc, total=n, initial=n)
|
381 |
-
assert nf > 0 or not augment, f'No labels
|
382 |
|
383 |
# Read cache
|
384 |
cache.pop('hash') # remove hash
|
@@ -432,9 +432,9 @@ class LoadImagesAndLabels(Dataset): # for training/testing
|
|
432 |
for i, x in pbar:
|
433 |
self.imgs[i], self.img_hw0[i], self.img_hw[i] = x # img, hw_original, hw_resized = load_image(self, i)
|
434 |
gb += self.imgs[i].nbytes
|
435 |
-
pbar.desc = 'Caching images (
|
436 |
|
437 |
-
def cache_labels(self, path=Path('./labels.cache')):
|
438 |
# Cache dataset labels, check images and read shapes
|
439 |
x = {} # dict
|
440 |
nm, nf, ne, nc = 0, 0, 0, 0 # number missing, found, empty, duplicate
|
@@ -466,18 +466,18 @@ class LoadImagesAndLabels(Dataset): # for training/testing
|
|
466 |
x[im_file] = [l, shape]
|
467 |
except Exception as e:
|
468 |
nc += 1
|
469 |
-
print('WARNING: Ignoring corrupted image and/or label
|
470 |
|
471 |
-
pbar.desc = f"Scanning '{path.parent / path.stem}' for images and labels... " \
|
472 |
f"{nf} found, {nm} missing, {ne} empty, {nc} corrupted"
|
473 |
|
474 |
if nf == 0:
|
475 |
-
print(f'WARNING: No labels found in {path}. See {help_url}')
|
476 |
|
477 |
x['hash'] = get_hash(self.label_files + self.img_files)
|
478 |
x['results'] = [nf, nm, ne, nc, i + 1]
|
479 |
torch.save(x, path) # save for next time
|
480 |
-
logging.info(f
|
481 |
return x
|
482 |
|
483 |
def __len__(self):
|
|
|
56 |
|
57 |
|
58 |
def create_dataloader(path, imgsz, batch_size, stride, opt, hyp=None, augment=False, cache=False, pad=0.0, rect=False,
|
59 |
+
rank=-1, world_size=1, workers=8, image_weights=False, quad=False, prefix=''):
|
60 |
# Make sure only the first process in DDP process the dataset first, and the following others can use the cache
|
61 |
with torch_distributed_zero_first(rank):
|
62 |
dataset = LoadImagesAndLabels(path, imgsz, batch_size,
|
|
|
67 |
single_cls=opt.single_cls,
|
68 |
stride=int(stride),
|
69 |
pad=pad,
|
70 |
+
image_weights=image_weights,
|
71 |
+
prefix=prefix)
|
72 |
|
73 |
batch_size = min(batch_size, len(dataset))
|
74 |
nw = min([os.cpu_count() // world_size, batch_size if batch_size > 1 else 0, workers]) # number of workers
|
|
|
129 |
elif os.path.isfile(p):
|
130 |
files = [p] # files
|
131 |
else:
|
132 |
+
raise Exception(f'ERROR: {p} does not exist')
|
133 |
|
134 |
images = [x for x in files if x.split('.')[-1].lower() in img_formats]
|
135 |
videos = [x for x in files if x.split('.')[-1].lower() in vid_formats]
|
|
|
144 |
self.new_video(videos[0]) # new video
|
145 |
else:
|
146 |
self.cap = None
|
147 |
+
assert self.nf > 0, f'No images or videos found in {p}. ' \
|
148 |
+
f'Supported formats are:\nimages: {img_formats}\nvideos: {vid_formats}'
|
149 |
|
150 |
def __iter__(self):
|
151 |
self.count = 0
|
|
|
171 |
ret_val, img0 = self.cap.read()
|
172 |
|
173 |
self.frame += 1
|
174 |
+
print(f'video {self.count + 1}/{self.nf} ({self.frame}/{self.nframes}) {path}: ', end='')
|
175 |
|
176 |
else:
|
177 |
# Read image
|
178 |
self.count += 1
|
179 |
img0 = cv2.imread(path) # BGR
|
180 |
assert img0 is not None, 'Image Not Found ' + path
|
181 |
+
print(f'image {self.count}/{self.nf} {path}: ', end='')
|
182 |
|
183 |
# Padded resize
|
184 |
img = letterbox(img0, new_shape=self.img_size)[0]
|
|
|
238 |
break
|
239 |
|
240 |
# Print
|
241 |
+
assert ret_val, f'Camera Error {self.pipe}'
|
242 |
img_path = 'webcam.jpg'
|
243 |
+
print(f'webcam {self.count}: ', end='')
|
244 |
|
245 |
# Padded resize
|
246 |
img = letterbox(img0, new_shape=self.img_size)[0]
|
|
|
271 |
self.sources = [clean_str(x) for x in sources] # clean source names for later
|
272 |
for i, s in enumerate(sources):
|
273 |
# Start the thread to read frames from the video stream
|
274 |
+
print(f'{i + 1}/{n}: {s}... ', end='')
|
275 |
cap = cv2.VideoCapture(eval(s) if s.isnumeric() else s)
|
276 |
+
assert cap.isOpened(), f'Failed to open {s}'
|
277 |
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
278 |
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
279 |
fps = cap.get(cv2.CAP_PROP_FPS) % 100
|
280 |
_, self.imgs[i] = cap.read() # guarantee first frame
|
281 |
thread = Thread(target=self.update, args=([i, cap]), daemon=True)
|
282 |
+
print(f' success ({w}x{h} at {fps:.2f} FPS).')
|
283 |
thread.start()
|
284 |
print('') # newline
|
285 |
|
|
|
336 |
|
337 |
class LoadImagesAndLabels(Dataset): # for training/testing
|
338 |
def __init__(self, path, img_size=640, batch_size=16, augment=False, hyp=None, rect=False, image_weights=False,
|
339 |
+
cache_images=False, single_cls=False, stride=32, pad=0.0, prefix=''):
|
340 |
self.img_size = img_size
|
341 |
self.augment = augment
|
342 |
self.hyp = hyp
|
|
|
358 |
parent = str(p.parent) + os.sep
|
359 |
f += [x.replace('./', parent) if x.startswith('./') else x for x in t] # local to global path
|
360 |
else:
|
361 |
+
raise Exception(f'{prefix}{p} does not exist')
|
362 |
self.img_files = sorted([x.replace('/', os.sep) for x in f if x.split('.')[-1].lower() in img_formats])
|
363 |
+
assert self.img_files, f'{prefix}No images found'
|
364 |
except Exception as e:
|
365 |
+
raise Exception(f'{prefix}Error loading data from {path}: {e}\nSee {help_url}')
|
366 |
|
367 |
# Check cache
|
368 |
self.label_files = img2label_paths(self.img_files) # labels
|
|
|
370 |
if cache_path.is_file():
|
371 |
cache = torch.load(cache_path) # load
|
372 |
if cache['hash'] != get_hash(self.label_files + self.img_files) or 'results' not in cache: # changed
|
373 |
+
cache = self.cache_labels(cache_path, prefix) # re-cache
|
374 |
else:
|
375 |
+
cache = self.cache_labels(cache_path, prefix) # cache
|
376 |
|
377 |
# Display cache
|
378 |
[nf, nm, ne, nc, n] = cache.pop('results') # found, missing, empty, corrupted, total
|
379 |
desc = f"Scanning '{cache_path}' for images and labels... {nf} found, {nm} missing, {ne} empty, {nc} corrupted"
|
380 |
+
tqdm(None, desc=prefix + desc, total=n, initial=n)
|
381 |
+
assert nf > 0 or not augment, f'{prefix}No labels in {cache_path}. Can not train without labels. See {help_url}'
|
382 |
|
383 |
# Read cache
|
384 |
cache.pop('hash') # remove hash
|
|
|
432 |
for i, x in pbar:
|
433 |
self.imgs[i], self.img_hw0[i], self.img_hw[i] = x # img, hw_original, hw_resized = load_image(self, i)
|
434 |
gb += self.imgs[i].nbytes
|
435 |
+
pbar.desc = f'{prefix}Caching images ({gb / 1E9:.1f}GB)'
|
436 |
|
437 |
+
def cache_labels(self, path=Path('./labels.cache'), prefix=''):
|
438 |
# Cache dataset labels, check images and read shapes
|
439 |
x = {} # dict
|
440 |
nm, nf, ne, nc = 0, 0, 0, 0 # number missing, found, empty, duplicate
|
|
|
466 |
x[im_file] = [l, shape]
|
467 |
except Exception as e:
|
468 |
nc += 1
|
469 |
+
print(f'{prefix}WARNING: Ignoring corrupted image and/or label {im_file}: {e}')
|
470 |
|
471 |
+
pbar.desc = f"{prefix}Scanning '{path.parent / path.stem}' for images and labels... " \
|
472 |
f"{nf} found, {nm} missing, {ne} empty, {nc} corrupted"
|
473 |
|
474 |
if nf == 0:
|
475 |
+
print(f'{prefix}WARNING: No labels found in {path}. See {help_url}')
|
476 |
|
477 |
x['hash'] = get_hash(self.label_files + self.img_files)
|
478 |
x['results'] = [nf, nm, ne, nc, i + 1]
|
479 |
torch.save(x, path) # save for next time
|
480 |
+
logging.info(f'{prefix}New cache created: {path}')
|
481 |
return x
|
482 |
|
483 |
def __len__(self):
|
utils/general.py
CHANGED
@@ -118,7 +118,7 @@ def one_cycle(y1=0.0, y2=1.0, steps=100):
|
|
118 |
|
119 |
def colorstr(*input):
|
120 |
# Colors a string https://en.wikipedia.org/wiki/ANSI_escape_code, i.e. colorstr('blue', 'hello world')
|
121 |
-
*
|
122 |
colors = {'black': '\033[30m', # basic colors
|
123 |
'red': '\033[31m',
|
124 |
'green': '\033[32m',
|
@@ -138,8 +138,7 @@ def colorstr(*input):
|
|
138 |
'end': '\033[0m', # misc
|
139 |
'bold': '\033[1m',
|
140 |
'underline': '\033[4m'}
|
141 |
-
|
142 |
-
return ''.join(colors[x] for x in prefix) + f'{string}' + colors['end']
|
143 |
|
144 |
|
145 |
def labels_to_class_weights(labels, nc=80):
|
|
|
118 |
|
119 |
def colorstr(*input):
|
120 |
# Colors a string https://en.wikipedia.org/wiki/ANSI_escape_code, i.e. colorstr('blue', 'hello world')
|
121 |
+
*args, string = input if len(input) > 1 else ('blue', 'bold', input[0]) # color arguments, string
|
122 |
colors = {'black': '\033[30m', # basic colors
|
123 |
'red': '\033[31m',
|
124 |
'green': '\033[32m',
|
|
|
138 |
'end': '\033[0m', # misc
|
139 |
'bold': '\033[1m',
|
140 |
'underline': '\033[4m'}
|
141 |
+
return ''.join(colors[x] for x in args) + f'{string}' + colors['end']
|
|
|
142 |
|
143 |
|
144 |
def labels_to_class_weights(labels, nc=80):
|
utils/plots.py
CHANGED
@@ -245,9 +245,9 @@ def plot_study_txt(path='study/', x=None): # from utils.plots import *; plot_st
|
|
245 |
'k.-', linewidth=2, markersize=8, alpha=.25, label='EfficientDet')
|
246 |
|
247 |
ax2.grid()
|
|
|
248 |
ax2.set_xlim(0, 30)
|
249 |
ax2.set_ylim(29, 51)
|
250 |
-
ax2.set_yticks(np.arange(30, 55, 5))
|
251 |
ax2.set_xlabel('GPU Speed (ms/img)')
|
252 |
ax2.set_ylabel('COCO AP val')
|
253 |
ax2.legend(loc='lower right')
|
|
|
245 |
'k.-', linewidth=2, markersize=8, alpha=.25, label='EfficientDet')
|
246 |
|
247 |
ax2.grid()
|
248 |
+
ax2.set_yticks(np.arange(30, 60, 5))
|
249 |
ax2.set_xlim(0, 30)
|
250 |
ax2.set_ylim(29, 51)
|
|
|
251 |
ax2.set_xlabel('GPU Speed (ms/img)')
|
252 |
ax2.set_ylabel('COCO AP val')
|
253 |
ax2.legend(loc='lower right')
|