Skip to content

Commit

Permalink
Remove duplicate line in setup.cfg (ultralytics#9380)
Browse files Browse the repository at this point in the history
  • Loading branch information
vivienness committed Sep 14, 2022
1 parent a4ed988 commit 8480211
Show file tree
Hide file tree
Showing 6 changed files with 471 additions and 12 deletions.
27 changes: 27 additions & 0 deletions data/dt.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
# COCO 2017 dataset http://cocodataset.org by Microsoft
# Example usage: python train.py --data coco.yaml
# parent
# ├── yolov5
# └── datasets
# └── coco ← downloads here (20.1 GB)


# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: D:\detection\datasets\union2voc_multiClass\yolo_dataset # dataset root dir
train: train.txt # train images (relative to 'path') 118287 images
val: val.txt # val images (relative to 'path') 5000 images
test: test.txt # 20288 of 40670 images, submit to https://competitions.codalab.org/competitions/20794

# Classes
names:
0: Car
1: Bus
2: Cyclist
3: Pedestrian
4: driverless_car
5: Truck
6: Tricyclist
7: Trafficcone

# Download script/URL (optional)
Binary file added log/confusion_matrix_c30.0_i50.0.npy
Binary file not shown.
27 changes: 20 additions & 7 deletions utils/dataloaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ def create_dataloader(path,
image_weights=False,
quad=False,
prefix='',
shuffle=False):
shuffle=False,
size_conf=None):
if rect and shuffle:
LOGGER.warning('WARNING: --rect is incompatible with DataLoader shuffle, setting shuffle=False')
shuffle = False
Expand All @@ -131,7 +132,8 @@ def create_dataloader(path,
stride=int(stride),
pad=pad,
image_weights=image_weights,
prefix=prefix)
prefix=prefix,
size_conf=size_conf)

batch_size = min(batch_size, len(dataset))
nd = torch.cuda.device_count() # number of CUDA devices
Expand Down Expand Up @@ -393,7 +395,8 @@ def __init__(self,
single_cls=False,
stride=32,
pad=0.0,
prefix=''):
prefix='',
size_conf=None):
self.img_size = img_size
self.augment = augment
self.hyp = hyp
Expand Down Expand Up @@ -430,11 +433,12 @@ def __init__(self,
self.label_files = img2label_paths(self.im_files) # labels
cache_path = (p if p.is_file() else Path(self.label_files[0]).parent).with_suffix('.cache')
try:
cache_path.unlink() # remove old cache
cache, exists = np.load(cache_path, allow_pickle=True).item(), True # load dict
assert cache['version'] == self.cache_version # matches current version
assert cache['hash'] == get_hash(self.label_files + self.im_files) # identical hash
except Exception:
cache, exists = self.cache_labels(cache_path, prefix), False # run cache ops
cache, exists = self.cache_labels(cache_path, prefix, size_conf), False # run cache ops

# Display cache
nf, nm, ne, nc, n = cache.pop('results') # found, missing, empty, corrupt, total
Expand Down Expand Up @@ -517,13 +521,14 @@ def __init__(self,
pbar.desc = f'{prefix}Caching images ({gb / 1E9:.1f}GB {cache_images})'
pbar.close()

def cache_labels(self, path=Path('./labels.cache'), prefix=''):
def cache_labels(self, path=Path('./labels.cache'), prefix='', size_conf=None):
# Cache dataset labels, check images and read shapes
x = {} # dict
nm, nf, ne, nc, msgs = 0, 0, 0, 0, [] # number missing, found, empty, corrupt, messages
desc = f"{prefix}Scanning '{path.parent / path.stem}' images and labels..."
with Pool(NUM_THREADS) as pool:
pbar = tqdm(pool.imap(verify_image_label, zip(self.im_files, self.label_files, repeat(prefix))),
pbar = tqdm(pool.imap(verify_image_label,
zip(self.im_files, self.label_files, repeat(prefix), repeat(size_conf))),
desc=desc,
total=len(self.im_files),
bar_format=BAR_FORMAT)
Expand Down Expand Up @@ -902,7 +907,7 @@ def autosplit(path=DATASETS_DIR / 'coco128/images', weights=(0.9, 0.1, 0.0), ann

def verify_image_label(args):
# Verify one image-label pair
im_file, lb_file, prefix = args
im_file, lb_file, prefix, size_conf = args
nm, nf, ne, nc, msg, segments = 0, 0, 0, 0, '', [] # number (missing, found, empty, corrupt), message, segments
try:
# verify images
Expand All @@ -928,6 +933,14 @@ def verify_image_label(args):
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)
if size_conf is not None:
size_thres = np.array([size_conf[int(i)] for i in lb[:, 0]], dtype=np.float32) ** 2
areas = (lb[:, 3:] * np.array(shape, dtype=np.float32)).prod(1)
idx = (areas > size_thres[:, 0]) & (areas <= size_thres[:, 1])
if idx.any():
lb = lb[idx.T]
else:
lb = np.zeros((0, 5), dtype=np.float32)
nl = len(lb)
if nl:
assert lb.shape[1] == 5, f'labels require 5 columns, {lb.shape[1]} columns detected'
Expand Down
9 changes: 5 additions & 4 deletions utils/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ def ap_per_class(tp, conf, pred_cls, target_cls, plot=False, save_dir='.', names
i = smooth(f1.mean(0), 0.1).argmax() # max F1 index
p, r, f1 = p[:, i], r[:, i], f1[:, i]
tp = (r * nt).round() # true positives
fn = nt - tp
fp = (tp / (p + eps) - tp).round() # false positives
return tp, fp, p, r, f1, ap, unique_classes.astype(int)
return tp, fp, fn, p, r, f1, ap, unique_classes.astype(int)


def compute_ap(recall, precision):
Expand Down Expand Up @@ -177,14 +178,14 @@ def process_batch(self, detections, labels):
if not any(m1 == i):
self.matrix[dc, self.nc] += 1 # background FN

def matrix(self):
def get_matrix(self):
return self.matrix

def tp_fp(self):
tp = self.matrix.diagonal() # true positives
fp = self.matrix.sum(1) - tp # false positives
# fn = self.matrix.sum(0) - tp # false negatives (missed detections)
return tp[:-1], fp[:-1] # remove background class
fn = self.matrix.sum(0) - tp # false negatives (missed detections)
return tp[:-1], fp[:-1], fn[:-1] # remove background class

@TryExcept('WARNING: ConfusionMatrix plot failure: ')
def plot(self, normalize=True, save_dir='', names=()):
Expand Down
2 changes: 1 addition & 1 deletion val.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ def run(
# Compute metrics
stats = [torch.cat(x, 0).cpu().numpy() for x in zip(*stats)] # to numpy
if len(stats) and stats[0].any():
tp, fp, p, r, f1, ap, ap_class = ap_per_class(*stats, plot=plots, save_dir=save_dir, names=names)
tp, fp, fn, p, r, f1, ap, ap_class = ap_per_class(*stats, plot=plots, save_dir=save_dir, names=names)
ap50, ap = ap[:, 0], ap.mean(1) # AP@0.5, AP@0.5:0.95
mp, mr, map50, map = p.mean(), r.mean(), ap50.mean(), ap.mean()
nt = np.bincount(stats[3].astype(int), minlength=nc) # number of targets per class
Expand Down
Loading

0 comments on commit 8480211

Please sign in to comment.