不废话,上干货!
第一步:在genneral.py最后添加Soft-NMS代码
#-----------------------------------这是Soft_NMS计算方法 start ---------------------------------------------------------------------
def my_soft_nms(bboxes, scores, iou_thresh=0.5, sigma=0.5, score_threshold=0.25):
bboxes = bboxes.contiguous()
x1 = bboxes[:, 0]
y1 = bboxes[:, 1]
x2 = bboxes[:, 2]
y2 = bboxes[:, 3]
# 计算每个box的面积
areas = (x2 - x1 + 1) * (y2 - y1 + 1)
# 首先对所有得分进行一次降序排列,仅此一次,以提高后续查找最大值速度. oeder为降序排列后的索引
_, order = scores.sort(0, descending=True)
# NMS后,保存留下来的边框
keep = []
while order.numel() > 0:
if order.numel() == 1: # 仅剩最后一个box的索引
i = order.item()
keep.append(i)
break
else:
i = order[0].item() # 保留首个得分最大的边框box索引,i为scores中实际坐标
keep.append(i)
# 巧妙使用tersor.clamp()函数求取order中当前框[0]之外每一个边框,与当前框[0]的最大值和最小值
xx1 = x1[order[1:]].clamp(min=x1[i])
yy1 = y1[order[1:]].clamp(min=y1[i])
xx2 = x2[order[1:]].clamp(max=x2[i])
yy2 = y2[order[1:]].clamp(max=y2[i])
# 求取order中其他每一个边框与当前边框的交集面积
inter = (xx2 - xx1).clamp(min=0) * (yy2 - yy1).clamp(min=0)
# 计算order中其他每一个框与当前框的IoU
iou = inter / (areas[i] + areas[order[1:]] - inter) # 共order.numel()-1个
idx = (iou > iou_thresh).nonzero().squeeze() # 获取order中IoU大于阈值的其他边框的索引
if idx.numel() > 0:
iou = iou[idx]
newScores = torch.exp(-torch.pow(iou, 2) / sigma) # 计算边框的得分衰减
scores[order[idx + 1]] *= newScores # 更新那些IoU大于阈值的边框的得分
newOrder = (scores[order[1:]] > score_threshold).nonzero().squeeze()
if newOrder.numel() == 0:
break
else:
newScores = scores[order[newOrder + 1]]
maxScoreIndex = torch.argmax(newScores)
if maxScoreIndex != 0:
newOrder[[0, maxScoreIndex],] = newOrder[[maxScoreIndex, 0],]
# 更新order.
order = order[newOrder + 1]
# 返回保留下来的所有边框的索引值,类型torch.LongTensor
return torch.LongTensor(keep)
#-----------------------------------这是Soft_NMS计算方法 ---------------------------------------------------------------------
第二步:在genneral.py里找到这句替换成这句
#---------------------------------原版NMS计算----------------------------------
#i = torchvision.ops.nms(boxes, scores, iou_thres) # NMS
# ---------------------------------改进soft_nms计算----------------------------------
i = my_soft_nms(boxes, scores, iou_thres) # NMS
# ---------------------------------改进soft_nms计算----------------------------------