removed xy/wh loss reporting

This commit is contained in:
Glenn Jocher 2019-08-24 16:43:43 +02:00
parent 852487654f
commit 39dcf0d561
4 changed files with 26 additions and 46 deletions

View File

@ -55,7 +55,7 @@ def test(cfg,
seen = 0 seen = 0
model.eval() model.eval()
coco91class = coco80_to_coco91_class() coco91class = coco80_to_coco91_class()
s = ('%30s' + '%10s' * 6) % ('Class', 'Images', 'Targets', 'P', 'R', 'mAP', 'F1') s = ('%20s' + '%10s' * 6) % ('Class', 'Images', 'Targets', 'P', 'R', 'mAP', 'F1')
p, r, f1, mp, mr, map, mf1 = 0., 0., 0., 0., 0., 0., 0. p, r, f1, mp, mr, map, mf1 = 0., 0., 0., 0., 0., 0., 0.
loss = torch.zeros(3) loss = torch.zeros(3)
jdict, stats, ap, ap_class = [], [], [], [] jdict, stats, ap, ap_class = [], [], [], []
@ -73,7 +73,7 @@ def test(cfg,
# Compute loss # Compute loss
if hasattr(model, 'hyp'): # if model has loss hyperparameters if hasattr(model, 'hyp'): # if model has loss hyperparameters
loss += compute_loss(train_out, targets, model)[1][[0, 2, 3]].cpu() # GIoU, obj, cls loss += compute_loss(train_out, targets, model)[1][:3].cpu() # GIoU, obj, cls
# Run NMS # Run NMS
output = non_max_suppression(inf_out, conf_thres=conf_thres, nms_thres=nms_thres) output = non_max_suppression(inf_out, conf_thres=conf_thres, nms_thres=nms_thres)
@ -155,7 +155,7 @@ def test(cfg,
nt = torch.zeros(1) nt = torch.zeros(1)
# Print results # Print results
pf = '%30s' + '%10.3g' * 6 # print format pf = '%20s' + '%10.3g' * 6 # print format
print(pf % ('all', seen, nt.sum(), mp, mr, map, mf1)) print(pf % ('all', seen, nt.sum(), mp, mr, map, mf1))
# Print results per class # Print results per class

View File

@ -16,28 +16,8 @@ try: # Mixed precision training https://github.com/NVIDIA/apex
except: except:
mixed_precision = False # not installed mixed_precision = False # not installed
# 320 --epochs 1
# 0.109 0.297 0.150 0.126 7.04 1.666 4.062 0.1845 42.6 3.34 12.61 8.338 0.2705 0.001 -4 0.9 0.0005 a 320 giou + best_anchor False
# 0.223 0.218 0.138 0.189 9.28 1.153 4.376 0.08263 24.28 3.05 20.93 2.842 0.2759 0.001357 -5.036 0.9158 0.0005722 b mAP/F1 - 50/50 weighting
# 0.231 0.215 0.135 0.191 9.51 1.432 3.007 0.06082 24.87 3.477 24.13 2.802 0.3436 0.001127 -5.036 0.9232 0.0005874 c
# 0.246 0.194 0.128 0.192 8.12 1.101 3.954 0.0817 22.83 3.967 19.83 1.779 0.3352 0.000895 -5.036 0.9238 0.0007973 d
# 0.187 0.237 0.144 0.186 14.6 1.607 4.202 0.09439 39.27 3.726 31.26 2.634 0.273 0.001542 -5.036 0.8364 0.0008393 e
# 0.250 0.217 0.136 0.195 3.3 1.2 2 0.604 15.7 3.67 20 1.36 0.194 0.00128 -4 0.95 0.000201 0.8 0.388 1.2 0.119 0.0589 0.401 f
# 0.269 0.225 0.149 0.218 6.71 1.13 5.25 0.246 22.4 3.64 17.8 1.31 0.256 0.00146 -4 0.936 0.00042 0.123 0.18 1.81 0.0987 0.0788 0.441 g
# 0.179 0.274 0.165 0.187 7.95 1.22 7.62 0.224 17 5.71 17.7 3.28 0.295 0.00136 -4 0.875 0.000319 0.131 0.208 2.14 0.14 0.0773 0.228 h
# 0.296 0.228 0.152 0.220 5.18 1.43 4.27 0.265 11.7 4.81 11.5 1.56 0.281 0.0013 -4 0.944 0.000427 0.0599 0.142 1.03 0.0552 0.0555 0.434 i
# 320 --epochs 2
# 0.242 0.296 0.196 0.231 5.67 0.8541 4.286 0.1539 21.61 1.957 22.9 2.894 0.3689 0.001844 -4 0.913 0.000467 # ha 0.417 mAP @ epoch 100
# 0.298 0.244 0.167 0.247 4.99 0.8896 4.067 0.1694 21.41 2.033 25.61 1.783 0.4115 0.00128 -4 0.950 0.000377 # hb
# 0.268 0.268 0.178 0.240 4.36 1.104 5.596 0.2087 14.47 2.599 16.27 2.406 0.4114 0.001585 -4 0.950 0.000524 # hc
# 0.161 0.327 0.190 0.193 7.82 1.153 4.062 0.1845 24.28 3.05 20.93 2.842 0.2759 0.001357 -4 0.916 0.000572 # hd 0.438 mAP @ epoch 100
# Hyperparameters (j-series, 50.5 mAP yolov3-320) evolved by @ktian08 https://github.com/ultralytics/yolov3/issues/310 # Hyperparameters (j-series, 50.5 mAP yolov3-320) evolved by @ktian08 https://github.com/ultralytics/yolov3/issues/310
# Transfer learning edge layers: 0.1 lr0, 0.9 momentum
hyp = {'giou': 1.582, # giou loss gain hyp = {'giou': 1.582, # giou loss gain
'xy': 4.688, # xy loss gain
'wh': 0.1857, # wh loss gain
'cls': 27.76, # cls loss gain (CE=~1.0, uCE=~20) 'cls': 27.76, # cls loss gain (CE=~1.0, uCE=~20)
'cls_pw': 1.446, # cls BCELoss positive_weight 'cls_pw': 1.446, # cls BCELoss positive_weight
'obj': 21.35, # obj loss gain (*=80 for uBCE with 80 classes) 'obj': 21.35, # obj loss gain (*=80 for uBCE with 80 classes)
@ -125,10 +105,11 @@ def train():
# possible weights are 'yolov3.weights', 'yolov3-tiny.conv.15', 'darknet53.conv.74' etc. # possible weights are 'yolov3.weights', 'yolov3-tiny.conv.15', 'darknet53.conv.74' etc.
cutoff = load_darknet_weights(model, weights) cutoff = load_darknet_weights(model, weights)
if opt.transfer: # transfer learning if opt.transfer: # transfer learning edge (yolo) layers
nf = int(model.module_defs[model.yolo_layers[0] - 1]['filters']) # yolo layer size (i.e. 255) nf = int(model.module_defs[model.yolo_layers[0] - 1]['filters']) # yolo layer size (i.e. 255)
for x in optimizer.param_groups: # lower parameter count can handle more aggressive training hyps for x in optimizer.param_groups:
# lower param count allows more aggressive training settings: ~0.1 lr0, ~0.9 momentum
x['lr'] *= 10 x['lr'] *= 10
x['momentum'] *= 0.9 x['momentum'] *= 0.9
@ -197,13 +178,12 @@ def train():
model_info(model, report='summary') # 'full' or 'summary' model_info(model, report='summary') # 'full' or 'summary'
nb = len(dataloader) nb = len(dataloader)
maps = np.zeros(nc) # mAP per class maps = np.zeros(nc) # mAP per class
results = (0, 0, 0, 0, 0, 0, 0) # P, R, mAP, F1, test_loss results = (0, 0, 0, 0, 0, 0, 0, 0) # 'P', 'R', 'mAP', 'F1', 'val GIoU', 'val Objectness', 'val Classification'
t0 = time.time() t0 = time.time()
for epoch in range(start_epoch, epochs): # epoch ------------------------------------------------------------------ for epoch in range(start_epoch, epochs): # epoch ------------------------------------------------------------------
model.train() model.train()
print(('\n' + '%10s' * 9) % print(('\n' + '%10s' * 8) % ('Epoch', 'gpu_mem', 'GIoU', 'obj', 'cls', 'total', 'targets', 'img_size'))
('Epoch', 'gpu_mem', 'GIoU/xy', 'wh', 'obj', 'cls', 'total', 'targets', 'img_size'))
# Update scheduler # Update scheduler
if epoch > 0: if epoch > 0:
@ -222,7 +202,7 @@ def train():
image_weights = labels_to_image_weights(dataset.labels, nc=nc, class_weights=w) image_weights = labels_to_image_weights(dataset.labels, nc=nc, class_weights=w)
dataset.indices = random.choices(range(dataset.n), weights=image_weights, k=dataset.n) # rand weighted idx dataset.indices = random.choices(range(dataset.n), weights=image_weights, k=dataset.n) # rand weighted idx
mloss = torch.zeros(5).to(device) # mean losses mloss = torch.zeros(4).to(device) # mean losses
pbar = tqdm(enumerate(dataloader), total=nb) # progress bar pbar = tqdm(enumerate(dataloader), total=nb) # progress bar
for i, (imgs, targets, paths, _) in pbar: # batch ------------------------------------------------------------- for i, (imgs, targets, paths, _) in pbar: # batch -------------------------------------------------------------
ni = i + nb * epoch # number integrated batches (since train start) ni = i + nb * epoch # number integrated batches (since train start)
@ -280,7 +260,7 @@ def train():
# Print batch results # Print batch results
mloss = (mloss * i + loss_items) / (i + 1) # update mean losses mloss = (mloss * i + loss_items) / (i + 1) # update mean losses
mem = torch.cuda.memory_cached() / 1E9 if torch.cuda.is_available() else 0 # (GB) mem = torch.cuda.memory_cached() / 1E9 if torch.cuda.is_available() else 0 # (GB)
s = ('%10s' * 2 + '%10.3g' * 7) % ( s = ('%10s' * 2 + '%10.3g' * 6) % (
'%g/%g' % (epoch, epochs - 1), '%.3gG' % mem, *mloss, len(targets), img_size) '%g/%g' % (epoch, epochs - 1), '%.3gG' % mem, *mloss, len(targets), img_size)
pbar.set_description(s) pbar.set_description(s)
@ -298,13 +278,13 @@ def train():
# Write epoch results # Write epoch results
with open('results.txt', 'a') as file: with open('results.txt', 'a') as file:
file.write(s + '%11.3g' * 7 % results + '\n') # P, R, mAP, F1, test_losses=(GIoU, obj, cls) file.write(s + '%10.3g' * 7 % results + '\n') # P, R, mAP, F1, test_losses=(GIoU, obj, cls)
# Write Tensorboard results # Write Tensorboard results
if tb_writer: if tb_writer:
x = list(mloss[:5]) + list(results[:7]) x = list(mloss) + list(results)
titles = ['GIoU/XY', 'Width/Height', 'Objectness', 'Classification', 'Train loss', 'Precision', 'Recall', titles = ['GIoU', 'Objectness', 'Classification', 'Train loss',
'mAP', 'F1', 'val GIoU', 'val Objectness', 'val Classification'] 'Precision', 'Recall', 'mAP', 'F1', 'val GIoU', 'val Objectness', 'val Classification']
for xi, title in zip(x, titles): for xi, title in zip(x, titles):
tb_writer.add_scalar(title, xi, epoch) tb_writer.add_scalar(title, xi, epoch)

View File

@ -16,7 +16,7 @@ sudo shutdown
# Re-clone # Re-clone
rm -rf yolov3 # Warning: remove existing rm -rf yolov3 # Warning: remove existing
git clone https://github.com/ultralytics/yolov3 # master git clone https://github.com/ultralytics/yolov3 && cd yolov3 # master
# git clone -b test --depth 1 https://github.com/ultralytics/yolov3 test # branch # git clone -b test --depth 1 https://github.com/ultralytics/yolov3 test # branch
# Train # Train

View File

@ -374,7 +374,7 @@ def compute_loss(p, targets, model): # predictions, targets, model
lobj *= k * h['obj'] lobj *= k * h['obj']
lcls *= k * h['cls'] lcls *= k * h['cls']
loss = lbox + lobj + lcls loss = lbox + lobj + lcls
return loss, torch.cat((lbox, ft([0]), lobj, lcls, loss)).detach() return loss, torch.cat((lbox, lobj, lcls, loss)).detach()
def build_targets(model, targets): def build_targets(model, targets):
@ -661,9 +661,9 @@ def kmeans_targets(path='../coco/trainvalno5k.txt', n=9, img_size=416): # from
def print_mutation(hyp, results, bucket=''): def print_mutation(hyp, results, bucket=''):
# Print mutation results to evolve.txt (for use with train.py --evolve) # Print mutation results to evolve.txt (for use with train.py --evolve)
a = '%11s' * len(hyp) % tuple(hyp.keys()) # hyperparam keys a = '%10s' * len(hyp) % tuple(hyp.keys()) # hyperparam keys
b = '%11.3g' * len(hyp) % tuple(hyp.values()) # hyperparam values b = '%10.3g' * len(hyp) % tuple(hyp.values()) # hyperparam values
c = '%11.3g' * len(results) % results # results (P, R, mAP, F1, test_loss) c = '%10.3g' * len(results) % results # results (P, R, mAP, F1, test_loss)
print('\n%s\n%s\nEvolved fitness: %s\n' % (a, b, c)) print('\n%s\n%s\nEvolved fitness: %s\n' % (a, b, c))
if bucket: if bucket:
@ -672,7 +672,7 @@ def print_mutation(hyp, results, bucket=''):
with open('evolve.txt', 'a') as f: # append result with open('evolve.txt', 'a') as f: # append result
f.write(c + b + '\n') f.write(c + b + '\n')
x = np.unique(np.loadtxt('evolve.txt', ndmin=2), axis=0) # load unique rows x = np.unique(np.loadtxt('evolve.txt', ndmin=2), axis=0) # load unique rows
np.savetxt('evolve.txt', x[np.argsort(-fitness(x))], '%11.3g') # save sort by fitness np.savetxt('evolve.txt', x[np.argsort(-fitness(x))], '%10.3g') # save sort by fitness
if bucket: if bucket:
os.system('gsutil cp evolve.txt gs://%s' % bucket) # upload evolve.txt os.system('gsutil cp evolve.txt gs://%s' % bucket) # upload evolve.txt
@ -680,7 +680,7 @@ def print_mutation(hyp, results, bucket=''):
def fitness(x): def fitness(x):
# Returns fitness (for use with results.txt or evolve.txt) # Returns fitness (for use with results.txt or evolve.txt)
return 0.50 * x[:, 2] + 0.50 * x[:, 3] # fitness = 0.9 * mAP + 0.1 * F1 return 0.50 * x[:, 2] + 0.50 * x[:, 3] # fitness = 0.5 * mAP + 0.5 * F1
# Plotting functions --------------------------------------------------------------------------------------------------- # Plotting functions ---------------------------------------------------------------------------------------------------
@ -803,10 +803,10 @@ def plot_results(start=0, stop=0): # from utils.utils import *; plot_results()
# Plot training results files 'results*.txt' # Plot training results files 'results*.txt'
fig, ax = plt.subplots(2, 5, figsize=(14, 7)) fig, ax = plt.subplots(2, 5, figsize=(14, 7))
ax = ax.ravel() ax = ax.ravel()
s = ['GIoU', 'Confidence', 'Classification', 'Precision', 'Recall', s = ['GIoU', 'Objectness', 'Classification', 'Precision', 'Recall',
'val GIoU', 'val Confidence', 'val Classification', 'mAP', 'F1'] 'val GIoU', 'val Objectness', 'val Classification', 'mAP', 'F1']
for f in sorted(glob.glob('results*.txt') + glob.glob('../../Downloads/results*.txt')): for f in sorted(glob.glob('results*.txt') + glob.glob('../../Downloads/results*.txt')):
results = np.loadtxt(f, usecols=[2, 4, 5, 9, 10, 13, 14, 15, 11, 12], ndmin=2).T results = np.loadtxt(f, usecols=[2, 3, 4, 8, 9, 12, 13, 14, 10, 11], ndmin=2).T
n = results.shape[1] # number of rows n = results.shape[1] # number of rows
x = range(start, min(stop, n) if stop else n) x = range(start, min(stop, n) if stop else n)
for i in range(10): for i in range(10):
@ -826,9 +826,9 @@ def plot_results(start=0, stop=0): # from utils.utils import *; plot_results()
def plot_results_overlay(start=0, stop=0): # from utils.utils import *; plot_results_overlay() def plot_results_overlay(start=0, stop=0): # from utils.utils import *; plot_results_overlay()
# Plot training results files 'results*.txt', overlaying train and val losses # Plot training results files 'results*.txt', overlaying train and val losses
s = ['train', 'train', 'train', 'Precision', 'mAP', 'val', 'val', 'val', 'Recall', 'F1'] # legends s = ['train', 'train', 'train', 'Precision', 'mAP', 'val', 'val', 'val', 'Recall', 'F1'] # legends
t = ['GIoU', 'Confidence', 'Classification', 'P-R', 'mAP-F1'] # titles t = ['GIoU', 'Objectness', 'Classification', 'P-R', 'mAP-F1'] # titles
for f in sorted(glob.glob('results*.txt') + glob.glob('../../Downloads/results*.txt')): for f in sorted(glob.glob('results*.txt') + glob.glob('../../Downloads/results*.txt')):
results = np.loadtxt(f, usecols=[2, 4, 5, 9, 11, 13, 14, 15, 10, 12], ndmin=2).T results = np.loadtxt(f, usecols=[2, 3, 4, 8, 9, 12, 13, 14, 10, 11], ndmin=2).T
n = results.shape[1] # number of rows n = results.shape[1] # number of rows
x = range(start, min(stop, n) if stop else n) x = range(start, min(stop, n) if stop else n)
fig, ax = plt.subplots(1, 5, figsize=(14, 3.5)) fig, ax = plt.subplots(1, 5, figsize=(14, 3.5))