#coding=utf-8 import xml.etree.ElementTree as ET import numpy as np
defiou(box, clusters): """ 计算一个ground truth边界盒和k个先验框(Anchor)的交并比(IOU)值。 参数box: 元组或者数据,代表ground truth的长宽。 参数clusters: 形如(k,2)的numpy数组,其中k是聚类Anchor框的个数 返回:ground truth和每个Anchor框的交并比。 """ x = np.minimum(clusters[:, 0], box[0]) y = np.minimum(clusters[:, 1], box[1]) if np.count_nonzero(x == 0) > 0or np.count_nonzero(y == 0) > 0: raise ValueError("Box has no area") intersection = x * y box_area = box[0] * box[1] cluster_area = clusters[:, 0] * clusters[:, 1] iou_ = intersection / (box_area + cluster_area - intersection) return iou_
defavg_iou(boxes, clusters): """ 计算一个ground truth和k个Anchor的交并比的均值。 """ return np.mean([np.max(iou(boxes[i], clusters)) for i in range(boxes.shape[0])])
defkmean_anchors(path='./2007_train.txt', n=5, img_size=(416, 416)): # from utils.utils import *; _ = kmean_anchors() # Produces a list of target kmeans suitable for use in *.cfg files from utils.datasets import LoadImagesAndLabels thr = 0.20# IoU threshold
defprint_results(thr, wh, k): k = k[np.argsort(k.prod(1))] # sort small to large iou = wh_iou(torch.Tensor(wh), torch.Tensor(k)) max_iou, min_iou = iou.max(1)[0], iou.min(1)[0] bpr, aat = (max_iou > thr).float().mean(), ( iou > thr).float().mean() * n # best possible recall, anch > thr print('%.2f iou_thr: %.3f best possible recall, %.2f anchors > thr' % (thr, bpr, aat)) print( 'kmeans anchors (n=%g, img_size=%s, IoU=%.3f/%.3f/%.3f-min/mean/best): ' % (n, img_size, min_iou.mean(), iou.mean(), max_iou.mean()), end='') for i, x in enumerate(k): print('%i,%i' % (round(x[0]), round(x[1])), end=', 'if i < len(k) - 1else'\n') # use in *.cfg return k
deffitness(thr, wh, k):# mutation fitness iou = wh_iou(wh, torch.Tensor(k)).max(1)[0] # max iou bpr = (iou > thr).float().mean() # best possible recall return iou.mean() * bpr # product
# Get label wh wh = [] dataset = LoadImagesAndLabels(path, augment=True, rect=True, cache_labels=True) nr = 1if img_size[0] == img_size[1] else10# number augmentation repetitions for s, l in zip(dataset.shapes, dataset.labels): wh.append(l[:, 3:5] * (s / s.max())) # image normalized to letterbox normalized wh wh = np.concatenate(wh, 0).repeat(nr, axis=0) # augment 10x wh *= np.random.uniform(img_size[0], img_size[1], size=(wh.shape[0], 1)) # normalized to pixels (multi-scale)
# Darknet yolov3.cfg anchors use_darknet = False if use_darknet: k = np.array([[10, 13], [16, 30], [33, 23], [30, 61], [62, 45], [59, 119], [116, 90], [156, 198], [373, 326]]) else: # Kmeans calculation from scipy.cluster.vq import kmeans print('Running kmeans for %g anchors on %g points...' % (n, len(wh))) s = wh.std(0) # sigmas for whitening k, dist = kmeans(wh / s, n, iter=30) # points, mean distance k *= s k = print_results(thr, wh, k) # Evolve wh = torch.Tensor(wh) f, ng = fitness(thr, wh, k), 2000# fitness, generations for _ in tqdm(range(ng), desc='Evolving anchors'): kg = ( k.copy() * (1 + np.random.random() * np.random.randn(*k.shape) * 0.30)).clip( min=2.0) fg = fitness(thr, wh, kg) if fg > f: f, k = fg, kg.copy() print_results(thr, wh, k) k = print_results(thr, wh, k)
从分背景结果来看,确实sea训练数据很少的结果很好,mAP提高了2个点,但是complex_cloud等mAP有所下降。总结一下就是对于训练集中数据很少的背景类mAP有提升,但是其他本身数量就很多的背景mAP略微下降或者保持。第二个:在图片中任意位置复制小目标修改后的版本地址:https://github.com/pprp/SimpleCVReproduction/tree/master/SmallObjectAugmentation具体实现思路就是,先将所有小目标抠出来备用。然后在图像上复制这些小目标,要求两两之间重合率不能达到一个阈值并且复制的位置不能超出图像边界。效果如下:(这个是示意图,比较夸张,复制的个数比较多这种做法来自当时比较新的论文《Augmentation for small object detection》,文中最好的结果是复制了1-2次。实际我们项目中也试过1次、2次、3次到多次的结果,都不尽如人意,结果太差就没有记录下来。。(话说论文中展示的效果最佳组合是原图+增强后的图,并且最好的结果也就提高了1个百分点)╮(╯﹏╰)╭
# 去除以#开头的,属于注释部分的内容 # lines = [x for x in lines if x and not x.startswith('#')] # lines = [x.rstrip().lstrip() for x in lines]
lines_nums = [] layers_nums = []
layer_cnt = -1
for num, line in enumerate(lines): if line.startswith('['): layer_cnt += 1 layers_nums.append(layer_cnt) lines_nums.append(num+layer_cnt) print(line) # s = s.join("") # s = s.join(line) for i,num in enumerate(layers_nums): print(lines_nums[i], num) lines.insert(lines_nums[i]-1, '# layer-%d\n' % (num-1)) fo = open(new_save_name, 'w') fo.write(''.join(lines)) fo.close() f.close()