yolov5 regress updates to yolov3

This commit is contained in:
Glenn Jocher 2020-05-17 15:19:33 -07:00
parent c8f4ee6c46
commit 316d99c377
4 changed files with 19 additions and 45 deletions

View File

@ -6,7 +6,7 @@ from utils.utils import *
def detect(save_img=False): def detect(save_img=False):
img_size = (320, 192) if ONNX_EXPORT else opt.img_size # (320, 192) or (416, 256) or (608, 352) for (height, width) imgsz = (320, 192) if ONNX_EXPORT else opt.img_size # (320, 192) or (416, 256) or (608, 352) for (height, width)
out, source, weights, half, view_img, save_txt = opt.output, opt.source, opt.weights, opt.half, opt.view_img, opt.save_txt out, source, weights, half, view_img, save_txt = opt.output, opt.source, opt.weights, opt.half, opt.view_img, opt.save_txt
webcam = source == '0' or source.startswith('rtsp') or source.startswith('http') or source.endswith('.txt') webcam = source == '0' or source.startswith('rtsp') or source.startswith('http') or source.endswith('.txt')
@ -17,7 +17,7 @@ def detect(save_img=False):
os.makedirs(out) # make new output folder os.makedirs(out) # make new output folder
# Initialize model # Initialize model
model = Darknet(opt.cfg, img_size) model = Darknet(opt.cfg, imgsz)
# Load weights # Load weights
attempt_download(weights) attempt_download(weights)
@ -42,7 +42,7 @@ def detect(save_img=False):
# Export mode # Export mode
if ONNX_EXPORT: if ONNX_EXPORT:
model.fuse() model.fuse()
img = torch.zeros((1, 3) + img_size) # (1, 3, 320, 192) img = torch.zeros((1, 3) + imgsz) # (1, 3, 320, 192)
f = opt.weights.replace(opt.weights.split('.')[-1], 'onnx') # *.onnx filename f = opt.weights.replace(opt.weights.split('.')[-1], 'onnx') # *.onnx filename
torch.onnx.export(model, img, f, verbose=False, opset_version=11, torch.onnx.export(model, img, f, verbose=False, opset_version=11,
input_names=['images'], output_names=['classes', 'boxes']) input_names=['images'], output_names=['classes', 'boxes'])
@ -64,10 +64,10 @@ def detect(save_img=False):
if webcam: if webcam:
view_img = True view_img = True
torch.backends.cudnn.benchmark = True # set True to speed up constant image size inference torch.backends.cudnn.benchmark = True # set True to speed up constant image size inference
dataset = LoadStreams(source, img_size=img_size) dataset = LoadStreams(source, img_size=imgsz)
else: else:
save_img = True save_img = True
dataset = LoadImages(source, img_size=img_size) dataset = LoadImages(source, img_size=imgsz)
# Get names and colors # Get names and colors
names = load_classes(opt.names) names = load_classes(opt.names)
@ -75,7 +75,7 @@ def detect(save_img=False):
# Run inference # Run inference
t0 = time.time() t0 = time.time()
img = torch.zeros((1, 3, img_size, img_size), device=device) # init img img = torch.zeros((1, 3, imgsz, imgsz), device=device) # init img
_ = model(img.half() if half else img.float()) if device.type != 'cpu' else None # run once _ = model(img.half() if half else img.float()) if device.type != 'cpu' else None # run once
for path, img, im0s, vid_cap in dataset: for path, img, im0s, vid_cap in dataset:
img = torch.from_numpy(img).to(device) img = torch.from_numpy(img).to(device)
@ -112,7 +112,7 @@ def detect(save_img=False):
s += '%gx%g ' % img.shape[2:] # print string s += '%gx%g ' % img.shape[2:] # print string
gn = torch.tensor(im0s.shape)[[1, 0, 1, 0]] #  normalization gain whwh gn = torch.tensor(im0s.shape)[[1, 0, 1, 0]] #  normalization gain whwh
if det is not None and len(det): if det is not None and len(det):
# Rescale boxes from img_size to im0 size # Rescale boxes from imgsz to im0 size
det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round() det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round()
# Print results # Print results

40
test.py
View File

@ -12,7 +12,7 @@ def test(cfg,
data, data,
weights=None, weights=None,
batch_size=16, batch_size=16,
img_size=416, imgsz=416,
conf_thres=0.001, conf_thres=0.001,
iou_thres=0.6, # for nms iou_thres=0.6, # for nms
save_json=False, save_json=False,
@ -30,7 +30,7 @@ def test(cfg,
os.remove(f) os.remove(f)
# Initialize model # Initialize model
model = Darknet(cfg, img_size) model = Darknet(cfg, imgsz)
# Load weights # Load weights
attempt_download(weights) attempt_download(weights)
@ -60,7 +60,7 @@ def test(cfg,
# Dataloader # Dataloader
if dataloader is None: if dataloader is None:
dataset = LoadImagesAndLabels(path, img_size, batch_size, rect=True, single_cls=opt.single_cls) dataset = LoadImagesAndLabels(path, imgsz, batch_size, rect=True, single_cls=opt.single_cls)
batch_size = min(batch_size, len(dataset)) batch_size = min(batch_size, len(dataset))
dataloader = DataLoader(dataset, dataloader = DataLoader(dataset,
batch_size=batch_size, batch_size=batch_size,
@ -70,7 +70,7 @@ def test(cfg,
seen = 0 seen = 0
model.eval() model.eval()
_ = model(torch.zeros((1, 3, img_size, img_size), device=device)) if device.type != 'cpu' else None # run once _ = model(torch.zeros((1, 3, imgsz, imgsz), device=device)) if device.type != 'cpu' else None # run once
coco91class = coco80_to_coco91_class() coco91class = coco80_to_coco91_class()
s = ('%20s' + '%10s' * 6) % ('Class', 'Images', 'Targets', 'P', 'R', 'mAP@0.5', 'F1') s = ('%20s' + '%10s' * 6) % ('Class', 'Images', 'Targets', 'P', 'R', 'mAP@0.5', 'F1')
p, r, f1, mp, mr, map, mf1, t0, t1 = 0., 0., 0., 0., 0., 0., 0., 0., 0. p, r, f1, mp, mr, map, mf1, t0, t1 = 0., 0., 0., 0., 0., 0., 0., 0., 0.
@ -191,7 +191,7 @@ def test(cfg,
# Print speeds # Print speeds
if verbose or save_json: if verbose or save_json:
t = tuple(x / seen * 1E3 for x in (t0, t1, t0 + t1)) + (img_size, img_size, batch_size) # tuple t = tuple(x / seen * 1E3 for x in (t0, t1, t0 + t1)) + (imgsz, imgsz, batch_size) # tuple
print('Speed: %.1f/%.1f/%.1f ms inference/NMS/total per %gx%g image at batch-size %g' % t) print('Speed: %.1f/%.1f/%.1f ms inference/NMS/total per %gx%g image at batch-size %g' % t)
# Save JSON # Save JSON
@ -259,35 +259,11 @@ if __name__ == '__main__':
opt.single_cls, opt.single_cls,
opt.augment) opt.augment)
elif opt.task == 'benchmark': # mAPs at 320-608 at conf 0.5 and 0.7 elif opt.task == 'benchmark': # mAPs at 256-640 at conf 0.5 and 0.7
y = [] y = []
for i in [320, 416, 512, 608]: # img-size for i in list(range(256, 640, 128)): # img-size
for j in [0.5, 0.7]: # iou-thres for j in [0.6, 0.7]: # iou-thres
t = time.time() t = time.time()
r = test(opt.cfg, opt.data, opt.weights, opt.batch_size, i, opt.conf_thres, j, opt.save_json)[0] r = test(opt.cfg, opt.data, opt.weights, opt.batch_size, i, opt.conf_thres, j, opt.save_json)[0]
y.append(r + (time.time() - t,)) y.append(r + (time.time() - t,))
np.savetxt('benchmark.txt', y, fmt='%10.4g') # y = np.loadtxt('study.txt') np.savetxt('benchmark.txt', y, fmt='%10.4g') # y = np.loadtxt('study.txt')
elif opt.task == 'study': # Parameter study
y = []
x = np.arange(0.4, 0.9, 0.05) # iou-thres
for i in x:
t = time.time()
r = test(opt.cfg, opt.data, opt.weights, opt.batch_size, opt.img_size, opt.conf_thres, i, opt.save_json)[0]
y.append(r + (time.time() - t,))
np.savetxt('study.txt', y, fmt='%10.4g') # y = np.loadtxt('study.txt')
# Plot
fig, ax = plt.subplots(3, 1, figsize=(6, 6))
y = np.stack(y, 0)
ax[0].plot(x, y[:, 2], marker='.', label='mAP@0.5')
ax[0].set_ylabel('mAP')
ax[1].plot(x, y[:, 3], marker='.', label='mAP@0.5:0.95')
ax[1].set_ylabel('mAP')
ax[2].plot(x, y[:, -1], marker='.', label='time')
ax[2].set_ylabel('time (s)')
for i in range(3):
ax[i].legend()
ax[i].set_xlabel('iou_thr')
fig.tight_layout()
plt.savefig('study.jpg', dpi=200)

View File

@ -32,7 +32,7 @@ hyp = {'giou': 3.54, # giou loss gain
'lr0': 0.01, # initial learning rate (SGD=5E-3, Adam=5E-4) 'lr0': 0.01, # initial learning rate (SGD=5E-3, Adam=5E-4)
'lrf': 0.0005, # final learning rate (with cos scheduler) 'lrf': 0.0005, # final learning rate (with cos scheduler)
'momentum': 0.937, # SGD momentum 'momentum': 0.937, # SGD momentum
'weight_decay': 0.000484, # optimizer weight decay 'weight_decay': 0.0005, # optimizer weight decay
'fl_gamma': 0.0, # focal loss gamma (efficientDet default is gamma=1.5) 'fl_gamma': 0.0, # focal loss gamma (efficientDet default is gamma=1.5)
'hsv_h': 0.0138, # image HSV-Hue augmentation (fraction) 'hsv_h': 0.0138, # image HSV-Hue augmentation (fraction)
'hsv_s': 0.678, # image HSV-Saturation augmentation (fraction) 'hsv_s': 0.678, # image HSV-Saturation augmentation (fraction)
@ -311,7 +311,7 @@ def train(hyp):
results, maps = test.test(cfg, results, maps = test.test(cfg,
data, data,
batch_size=batch_size, batch_size=batch_size,
img_size=imgsz_test, imgsz=imgsz_test,
model=ema.ema, model=ema.ema,
save_json=final_epoch and is_coco, save_json=final_epoch and is_coco,
single_cls=opt.single_cls, single_cls=opt.single_cls,

View File

@ -365,9 +365,8 @@ def compute_loss(p, targets, model): # predictions, targets, model
nb = b.shape[0] # number of targets nb = b.shape[0] # number of targets
if nb: if nb:
nt += nb nt += nb # cumulative targets
ps = pi[b, a, gj, gi] # prediction subset corresponding to targets ps = pi[b, a, gj, gi] # prediction subset corresponding to targets
# ps[:, 2:4] = torch.sigmoid(ps[:, 2:4]) # wh power loss (uncomment)
# GIoU # GIoU
pxy = torch.sigmoid(ps[:, 0:2]) pxy = torch.sigmoid(ps[:, 0:2])
@ -408,7 +407,6 @@ def compute_loss(p, targets, model): # predictions, targets, model
def build_targets(p, targets, model): def build_targets(p, targets, model):
# Build targets for compute_loss(), input targets(image,class,x,y,w,h) # Build targets for compute_loss(), input targets(image,class,x,y,w,h)
nt = targets.shape[0] nt = targets.shape[0]
tcls, tbox, indices, anch = [], [], [], [] tcls, tbox, indices, anch = [], [], [], []
gain = torch.ones(6, device=targets.device) # normalized to gridspace gain gain = torch.ones(6, device=targets.device) # normalized to gridspace gain
@ -647,7 +645,7 @@ def coco_single_class_labels(path='../coco/labels/train2014/', label_class=43):
shutil.copyfile(src=img_file, dst='new/images/' + Path(file).name.replace('txt', 'jpg')) # copy images shutil.copyfile(src=img_file, dst='new/images/' + Path(file).name.replace('txt', 'jpg')) # copy images
def kmean_anchors(path='./data/coco64.txt', n=9, img_size=(320, 1024), thr=0.20, gen=1000): def kmean_anchors(path='./data/coco64.txt', n=9, img_size=(640, 640), thr=0.20, gen=1000):
# Creates kmeans anchors for use in *.cfg files: from utils.utils import *; _ = kmean_anchors() # Creates kmeans anchors for use in *.cfg files: from utils.utils import *; _ = kmean_anchors()
# n: number of anchors # n: number of anchors
# img_size: (min, max) image size used for multi-scale training (can be same values) # img_size: (min, max) image size used for multi-scale training (can be same values)