From 2bfea0c980d563e085c0de0d1c2aa79d83f8765f Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Sun, 21 Apr 2019 20:35:11 +0200 Subject: [PATCH] updates --- test.py | 2 +- train.py | 47 +++++++++++++++++++++++++++++------------------ utils/datasets.py | 22 ++++++++++++++++++++-- utils/utils.py | 10 +++++----- 4 files changed, 55 insertions(+), 26 deletions(-) diff --git a/test.py b/test.py index e78d6be1..f218e7e9 100644 --- a/test.py +++ b/test.py @@ -93,7 +93,7 @@ def test( # [{"image_id": 42, "category_id": 18, "bbox": [258.15, 41.29, 348.26, 243.78], "score": 0.236}, ... image_id = int(Path(paths[si]).stem.split('_')[-1]) box = pred[:, :4].clone() # xyxy - scale_coords(img_size, box, shapes[si]) # to original shape + scale_coords(imgs[si].shape, box, shapes[si]) # to original shape box = xyxy2xywh(box) # xywh box[:, :2] -= box[:, 2:] / 2 # xy center to top-left corner for di, d in enumerate(pred): diff --git a/train.py b/train.py index 7d28e0e9..1bf730d8 100644 --- a/train.py +++ b/train.py @@ -11,20 +11,34 @@ from utils.datasets import * from utils.utils import * # Hyperparameters -# 0.852 0.94 0.924 0.883 1.33 8.52 0.06833 0.01524 0.01509 0.9013 0.1003 0.001325 -3.853 0.8948 0.0004053 # hyp -hyp = {'k': 8.52, # loss multiple - 'xy': 0.06833, # xy loss fraction - 'wh': 0.01524, # wh loss fraction - 'cls': 0.01509, # cls loss fraction - 'conf': 0.9013, # conf loss fraction - 'iou_t': 0.1003, # iou target-anchor training threshold - 'lr0': 0.001325, # initial learning rate - 'lrf': -3.853, # final learning rate = lr0 * (10 ** lrf) - 'momentum': 0.8948, # SGD momentum - 'weight_decay': 0.0004053, # optimizer weight decay +# 0.861 0.956 0.936 0.897 1.51 10.39 0.1367 0.01057 0.01181 0.8409 0.1287 0.001028 -3.441 0.9127 0.0004841 +hyp = {'k': 10.39, # loss multiple + 'xy': 0.1367, # xy loss fraction + 'wh': 0.01057, # wh loss fraction + 'cls': 0.01181, # cls loss fraction + 'conf': 0.8409, # conf loss fraction + 'iou_t': 0.1287, # iou target-anchor training threshold + 'lr0': 0.001028, # initial learning rate + 'lrf': -3.441, # final learning rate = lr0 * (10 ** lrf) + 'momentum': 0.9127, # SGD momentum + 'weight_decay': 0.0004841, # optimizer weight decay } +# 0.856 0.95 0.935 0.887 1.3 8.488 0.1081 0.01351 0.01351 0.8649 0.1 0.001 -3 0.9 0.0005 +# hyp = {'k': 8.4875, # loss multiple +# 'xy': 0.108108, # xy loss fraction +# 'wh': 0.013514, # wh loss fraction +# 'cls': 0.013514, # cls loss fraction +# 'conf': 0.86486, # conf loss fraction +# 'iou_t': 0.1, # iou target-anchor training threshold +# 'lr0': 0.001, # initial learning rate +# 'lrf': -3., # final learning rate = lr0 * (10 ** lrf) +# 'momentum': 0.9, # SGD momentum +# 'weight_decay': 0.0005, # optimizer weight decay +# } + + def train( cfg, data_cfg, @@ -89,12 +103,9 @@ def train( # Scheduler (reduce lr at epochs 218, 245, i.e. batches 400k, 450k) # lf = lambda x: 1 - x / epochs # linear ramp to zero # lf = lambda x: 10 ** (-2 * x / epochs) # exp ramp to lr0 * 1e-2 - # lf = lambda x: 1 - 10 ** (hyp['lrf'] * (1 - x / epochs)) # inv exp ramp to lr0 * 1e-2 - # scheduler = optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=lf, last_epoch=start_epoch - 1) - scheduler = optim.lr_scheduler.MultiStepLR(optimizer, - milestones=[218, 245], - gamma=0.1, - last_epoch=start_epoch - 1) + lf = lambda x: 1 - 10 ** (hyp['lrf'] * (1 - x / epochs)) # inv exp ramp to lr0 * 1e-2 + scheduler = optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=lf, last_epoch=start_epoch - 1) + # scheduler = optim.lr_scheduler.MultiStepLR(optimizer,milestones=[218, 245],gamma=0.1,last_epoch=start_epoch - 1) # Plot lr schedule # y = [] @@ -311,7 +322,7 @@ if __name__ == '__main__': # Mutate hyperparameters old_hyp = hyp.copy() init_seeds(seed=int(time.time())) - s = [.2, .2, .2, .2, .2, .2, .2, .2, .02, .2] + s = [.2, .2, .2, .2, .2, .3, .2, .2, .02, .3] for i, k in enumerate(hyp.keys()): x = (np.random.randn(1) * s[i] + 1) ** 1.1 # plt.hist(x.ravel(), 100) hyp[k] = hyp[k] * float(x) # vary by about 30% 1sigma diff --git a/utils/datasets.py b/utils/datasets.py index 5b92f103..174dc6c7 100755 --- a/utils/datasets.py +++ b/utils/datasets.py @@ -74,7 +74,7 @@ class LoadImages: # for inference print('image %g/%g %s: ' % (self.count, self.nF, path), end='') # Padded resize - img, _, _, _ = letterbox(img0, height=self.height) + img, _, _, _ = letterbox_rect(img0, height=self.height) # Normalize RGB img = img[:, :, ::-1].transpose(2, 0, 1) # BGR to RGB @@ -239,9 +239,11 @@ def letterbox(img, height=416, color=(127.5, 127.5, 127.5)): # Resize a rectangular image to a padded square shape = img.shape[:2] # shape = [height, width] ratio = float(height) / max(shape) # ratio = old / new - new_shape = (round(shape[1] * ratio), round(shape[0] * ratio)) + new_shape = (round(shape[1] * ratio), round(shape[0] * ratio)) # new_shape = [width, height] + dw = (height - new_shape[0]) / 2 # width padding dh = (height - new_shape[1]) / 2 # height padding + top, bottom = round(dh - 0.1), round(dh + 0.1) left, right = round(dw - 0.1), round(dw + 0.1) img = cv2.resize(img, new_shape, interpolation=cv2.INTER_AREA) # resized, no border @@ -249,6 +251,22 @@ def letterbox(img, height=416, color=(127.5, 127.5, 127.5)): return img, ratio, dw, dh +def letterbox_rect(img, height=416, color=(127.5, 127.5, 127.5)): + # Resize a rectangular image to a 32 pixel multiple rectangle + shape = img.shape[:2] # shape = [height, width] + ratio = float(height) / max(shape) # ratio = old / new + new_shape = (round(shape[1] * ratio), round(shape[0] * ratio)) # new_shape = [width, height] + + dw = np.mod(height - new_shape[0], 32) / 2 # width padding + dh = np.mod(height - new_shape[1], 32) / 2 # height padding + + top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1)) + left, right = int(round(dw - 0.1)), int(round(dw + 0.1)) + img = cv2.resize(img, new_shape, interpolation=cv2.INTER_AREA) # resized, no border + img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color) # padded square + return img, ratio, dw, dh + + def random_affine(img, targets=(), degrees=(-10, 10), translate=(.1, .1), scale=(.9, 1.1), shear=(-2, 2), borderValue=(127.5, 127.5, 127.5)): # torchvision.transforms.RandomAffine(degrees=(-10, 10), translate=(.1, .1), scale=(.9, 1.1), shear=(-10, 10)) diff --git a/utils/utils.py b/utils/utils.py index c78dcc50..bd348b9a 100755 --- a/utils/utils.py +++ b/utils/utils.py @@ -100,11 +100,11 @@ def xywh2xyxy(x): return y -def scale_coords(img_size, coords, img0_shape): - # Rescale x1, y1, x2, y2 from 416 to image size - gain = float(img_size) / max(img0_shape) # gain = old / new - pad_x = (img_size - img0_shape[1] * gain) / 2 # width padding - pad_y = (img_size - img0_shape[0] * gain) / 2 # height padding +def scale_coords(img1_shape, coords, img0_shape): + # Rescale coords1 (xyxy) from img1_shape to img0_shape + gain = max(img1_shape[1:3]) / max(img0_shape[:2]) # gain = old / new + pad_x = (img1_shape[2] - img0_shape[1] * gain) / 2 # width padding + pad_y = (img1_shape[1] - img0_shape[0] * gain) / 2 # height padding coords[:, [0, 2]] -= pad_x coords[:, [1, 3]] -= pad_y coords[:, :4] /= gain