This commit is contained in:
Glenn Jocher 2019-05-08 13:06:24 +02:00
parent 9ee59fe694
commit a8f0a3fede
6 changed files with 5050 additions and 45 deletions

2
.gitignore vendored
View File

@ -29,7 +29,7 @@ data/*
!data/coco_*.txt !data/coco_*.txt
!data/trainvalno5k.shapes !data/trainvalno5k.shapes
!data/5k.shapes !data/5k.shapes
!data/5k.txt
pycocotools/* pycocotools/*
results*.txt results*.txt

5000
data/5k.txt Normal file

File diff suppressed because it is too large Load Diff

6
data/coco_1k5k.data Normal file
View File

@ -0,0 +1,6 @@
classes=80
train=./data/coco_1000img.txt
valid=./data/5k.txt
names=data/coco.names
backup=backup/
eval=coco

View File

@ -11,34 +11,32 @@ from utils.datasets import *
from utils.utils import * from utils.utils import *
# Hyperparameters # Hyperparameters
# 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 # Evolved with python3 train.py --evolve --data data/coco_1k5k.data --epochs 50 --img-size 320
hyp = {'k': 10.39, # loss multiple hyp = {'xy': 0.5, # xy loss gain
'xy': 0.1367, # xy loss fraction 'wh': 0.0625, # wh loss gain
'wh': 0.01057, # wh loss fraction 'cls': 0.0625, # cls loss gain
'cls': 0.01181, # cls loss fraction 'conf': 4, # conf loss gain
'conf': 0.8409, # conf loss fraction 'iou_t': 0.1, # iou target-anchor training threshold
'iou_t': 0.1287, # iou target-anchor training threshold 'lr0': 0.001, # initial learning rate
'lr0': 0.001028, # initial learning rate 'lrf': -5., # final learning rate = lr0 * (10 ** lrf)
'lrf': -3.441, # final learning rate = lr0 * (10 ** lrf) 'momentum': 0.9, # SGD momentum
'momentum': 0.9127, # SGD momentum 'weight_decay': 0.0005, # optimizer weight decay
'weight_decay': 0.0004841, # optimizer weight decay
} }
# Original
# 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 = {'xy': 0.5, # xy loss gain
# hyp = {'k': 8.4875, # loss multiple # 'wh': 0.0625, # wh loss gain
# 'xy': 0.108108, # xy loss fraction # 'cls': 0.0625, # cls loss gain
# 'wh': 0.013514, # wh loss fraction # 'conf': 4, # conf loss gain
# 'cls': 0.013514, # cls loss fraction
# 'conf': 0.86486, # conf loss fraction
# 'iou_t': 0.1, # iou target-anchor training threshold # 'iou_t': 0.1, # iou target-anchor training threshold
# 'lr0': 0.001, # initial learning rate # 'lr0': 0.001, # initial learning rate
# 'lrf': -3., # final learning rate = lr0 * (10 ** lrf) # 'lrf': -5., # final learning rate = lr0 * (10 ** lrf)
# 'momentum': 0.9, # SGD momentum # 'momentum': 0.9, # SGD momentum
# 'weight_decay': 0.0005, # optimizer weight decay # 'weight_decay': 0.0005, # optimizer weight decay
# } # }
def train( def train(
cfg, cfg,
data_cfg, data_cfg,
@ -279,7 +277,7 @@ if __name__ == '__main__':
parser.add_argument('--batch-size', type=int, default=16, help='size of each image batch') parser.add_argument('--batch-size', type=int, default=16, help='size of each image batch')
parser.add_argument('--accumulate', type=int, default=1, help='accumulate gradient x batches before optimizing') parser.add_argument('--accumulate', type=int, default=1, help='accumulate gradient x batches before optimizing')
parser.add_argument('--cfg', type=str, default='cfg/yolov3-spp.cfg', help='cfg file path') parser.add_argument('--cfg', type=str, default='cfg/yolov3-spp.cfg', help='cfg file path')
parser.add_argument('--data-cfg', type=str, default='data/coco.data', help='coco.data file path') parser.add_argument('--data-cfg', type=str, default='data/coco_100img.data', help='coco.data file path')
parser.add_argument('--multi-scale', action='store_true', help='random image sizes per batch 320 - 608') parser.add_argument('--multi-scale', action='store_true', help='random image sizes per batch 320 - 608')
parser.add_argument('--img-size', type=int, default=416, help='inference size (pixels)') parser.add_argument('--img-size', type=int, default=416, help='inference size (pixels)')
parser.add_argument('--resume', action='store_true', help='resume training flag') parser.add_argument('--resume', action='store_true', help='resume training flag')
@ -326,7 +324,7 @@ if __name__ == '__main__':
# Mutate hyperparameters # Mutate hyperparameters
old_hyp = hyp.copy() old_hyp = hyp.copy()
init_seeds(seed=int(time.time())) init_seeds(seed=int(time.time()))
s = [.2, .2, .2, .2, .2, .3, .2, .2, .02, .3] s = [.2, .2, .2, .2, .2, .3, .2, .2, .01, .3]
for i, k in enumerate(hyp.keys()): for i, k in enumerate(hyp.keys()):
x = (np.random.randn(1) * s[i] + 1) ** 1.1 # plt.hist(x.ravel(), 100) 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 hyp[k] = hyp[k] * float(x) # vary by about 30% 1sigma
@ -337,12 +335,6 @@ if __name__ == '__main__':
for k, v in zip(keys, limits): for k, v in zip(keys, limits):
hyp[k] = np.clip(hyp[k], v[0], v[1]) hyp[k] = np.clip(hyp[k], v[0], v[1])
# Normalize loss components (sum to 1)
keys = ['xy', 'wh', 'cls', 'conf']
s = sum([v for k, v in hyp.items() if k in keys])
for k in keys:
hyp[k] /= s
# Determine mutation fitness # Determine mutation fitness
results = train( results = train(
opt.cfg, opt.cfg,
@ -368,13 +360,17 @@ if __name__ == '__main__':
else: else:
hyp = old_hyp.copy() # reset hyp to hyp = old_hyp.copy() # reset hyp to
# # Plot results # Plot results
# import numpy as np import numpy as np
# import matplotlib.pyplot as plt import matplotlib.pyplot as plt
# a = np.loadtxt('evolve_1000val.txt')
# a = np.loadtxt('evolve.txt') x = a[:, 2] * a[:, 3] # metric = mAP * F1
# x = a[:, 3] weights = (x - x.min()) ** 2
# fig = plt.figure(figsize=(14, 7)) fig = plt.figure(figsize=(14, 7))
# for i in range(1, 10): for i in range(len(hyp)):
# plt.subplot(2, 5, i) y = a[:, i + 5]
# plt.plot(x, a[:, i + 5], '.') mu = (y * weights).sum() / weights.sum()
plt.subplot(2, 5, i+1)
plt.plot(x.max(), mu, 'o')
plt.plot(x, y, '.')
print(list(hyp.keys())[i],'%.4g' % mu)

View File

@ -130,7 +130,7 @@ class LoadWebcam: # for inference
class LoadImagesAndLabels(Dataset): # for training/testing class LoadImagesAndLabels(Dataset): # for training/testing
def __init__(self, path, img_size=416, batch_size=16, augment=False, rect=False): def __init__(self, path, img_size=416, batch_size=16, augment=False, rect=True):
with open(path, 'r') as f: with open(path, 'r') as f:
img_files = f.read().splitlines() img_files = f.read().splitlines()
self.img_files = list(filter(lambda x: len(x) > 0, img_files)) self.img_files = list(filter(lambda x: len(x) > 0, img_files))
@ -181,8 +181,8 @@ class LoadImagesAndLabels(Dataset): # for training/testing
self.batch = bi # batch index of image self.batch = bi # batch index of image
# Preload images # Preload images
# if n < 200: # preload all images into memory if possible if n < 1001: # preload all images into memory if possible
# self.imgs = [cv2.imread(img_files[i]) for i in range(n)] self.imgs = [cv2.imread(self.img_files[i]) for i in range(n)]
# Preload labels (required for weighted CE training) # Preload labels (required for weighted CE training)
self.labels = [np.zeros((0, 5))] * n self.labels = [np.zeros((0, 5))] * n
@ -201,11 +201,14 @@ class LoadImagesAndLabels(Dataset): # for training/testing
img_path = self.img_files[index] img_path = self.img_files[index]
label_path = self.label_files[index] label_path = self.label_files[index]
# if hasattr(self, 'imgs'): # preloaded # Load image
# img = self.imgs[index] # BGR if hasattr(self, 'imgs'): # preloaded
img = cv2.imread(img_path) # BGR img = self.imgs[index]
else:
img = cv2.imread(img_path) # BGR
assert img is not None, 'File Not Found ' + img_path assert img is not None, 'File Not Found ' + img_path
# Augment colorspace
augment_hsv = True augment_hsv = True
if self.augment and augment_hsv: if self.augment and augment_hsv:
# SV augmentation by 50% # SV augmentation by 50%

View File

@ -265,7 +265,7 @@ def compute_loss(p, targets, model): # predictions, targets, model
# Compute losses # Compute losses
h = model.hyp # hyperparameters h = model.hyp # hyperparameters
bs = p[0].shape[0] # batch size bs = p[0].shape[0] # batch size
k = h['k'] * bs # loss gain k = bs # loss gain
for i, pi0 in enumerate(p): # layer i predictions, i for i, pi0 in enumerate(p): # layer i predictions, i
b, a, gj, gi = indices[i] # image, anchor, gridy, gridx b, a, gj, gi = indices[i] # image, anchor, gridy, gridx
tconf = torch.zeros_like(pi0[..., 0]) # conf tconf = torch.zeros_like(pi0[..., 0]) # conf