改进YOLOv5系列:6.修改Soft-NMS,Soft-CIoUNMS,Soft-SIoUNMS,Soft-DIoUNMS,Soft-EIoUNMS,Soft-GIoUNMS...

助力论文改进 、 不同数据集涨点、创新点改进

  • YOLOAir项目:基于 YOLOv5 代码框架,结合不同模块来构建不同的YOLO目标检测模型。
  • 本项目包含大量的改进方式,降低改进难度,改进点包含BackboneNeckHead注意力机制IoU损失函数NMSLoss计算方式自注意力机制数据增强部分激活函数等部分,详情可以关注 YOLOAir 的说明文档。
  • 同时附带各种改进点原理及对应的代码改进方式教程,用户可根据自身情况快速排列组合,在不同的数据集上实验, 应用组合写论文!

新的仓库链接:YOLOAir仓库:https://github.com/iscyy/yoloair
可以 forkstar,持续同步更新完善


本篇是《关于一系列Soft-NMS》的修改 演示

包括:NMS、Soft-NMS、Soft-SIoUNMS、Soft-CIoUNMS、Soft-DIoUNMS、Soft-EIoUNMS、Soft-GIoUNMS

使用YOLOv5网络作为示范,可以无缝加入到 YOLOv7、YOLOX、YOLOR、YOLOv4、Scaled_YOLOv4、YOLOv3等一系列YOLO算法模块


文章目录

    • Soft-NMS相关理论部分
    • 1.改为:Soft-NMS
    • 2.修改:Soft CIoU-NMS
    • 3.修改:Soft DIoU-NMS
    • 4.修改:Soft EIoU-NMS
    • 5.修改:Soft SIoU-NMS
    • 6.修改:Soft GIoU-NMS


Soft-NMS相关理论部分

理论部分论文:https://arxiv.org/abs/1704.04503)

在NMS算法中,直接将IoU 超过阈值的检测框的得分设置为 0,而 soft NMS 则将其得分进行惩罚衰减,有两种衰减方式。第一种是使用1-IoU与得分的乘积作为衰减后的值,但这种方式在略低于阈值和略高于阈值的部分,经过惩罚衰减函数后,很容易导致得分排序的顺序打乱,合理的惩罚函数应该是具有高IoU的有高的惩罚,低IoU的有低的惩罚,它们中间应该是逐渐过渡的,因此提出高斯惩罚函数。


1.改为:Soft-NMS

general.py文件中增加

代码
def soft_nms(prediction, conf_thres=0.25, iou_thres=0.45, multi_label=False):
    """Runs Non-Maximum Suppression (NMS) on inference results

    Returns:
         list of detections, on (n,6) tensor per image [xyxy, conf, cls]
    """

    nc = prediction.shape[2] - 5  # number of classes

    # Checks
    assert 0 <= conf_thres <= 1, f'Invalid Confidence threshold {conf_thres}, valid values are between 0.0 and 1.0'
    assert 0 <= iou_thres <= 1, f'Invalid IoU {iou_thres}, valid values are between 0.0 and 1.0'

    # Settings
    min_wh, max_wh = 2, 4096  # (pixels) minimum and maximum box width and height
    time_limit = 10.0  # seconds to quit after

    multi_label &= nc > 1  # multiple labels per box (adds 0.5ms/img)
    soft_nms = True

    t = time.time()
    output = [torch.zeros((0, 6), device=prediction.device)] * prediction.shape[0]
    for xi, x in enumerate(prediction):  # image index, image inference
        x = x[x[:, 4] > conf_thres]  # confidence
        x = x[(x[:, 2:4] > min_wh).all(1) & (x[:, 2:4] < max_wh).all(1)]
        if len(x) == 0:
            continue
        # Compute conf
        x[:, 5:] *= x[:, 4:5]  # conf = obj_conf * cls_conf
        # Box (center x, center y, width, height) to (x1, y1, x2, y2)
        box = xywh2xyxy(x[:, :4])
        # Detections matrix nx6 (xyxy, conf, cls)
        if multi_label:
            i, j = (x[:, 5:] > conf_thres).nonzero(as_tuple=False).T
            x = torch.cat((box[i], x[i, j + 5].unsqueeze(1), j.float().unsqueeze(1)), 1)
        else:  # best class only
            conf, j = x[:, 5:].max(1)
            x = torch.cat((box, conf.unsqueeze(1), j.float().unsqueeze(1)), 1)[conf.view(-1) > conf_thres]
        if len(x) == 0:
            continue
        x = x[x[:, 4].argsort(descending=True)]  # sort by confidence
        # Batched NMS
        det_max = []
        cls = x[:, -1]   # classes
        for c in cls.unique():
            dc = x[cls == c]
            n = len(dc)
            #print(n)
            if n == 1:
                det_max.append(dc)
                continue
            elif n > 30000:
                dc = dc[:30000]
            if soft_nms:
                sigma = 0.5
                while len(dc):
                    det_max.append(dc[:1])
                    if len(dc) == 1:
                        break
                    iou = bbox_iou(dc[0], dc[1:]) # 修改
                    dc = dc[1:]
                    dc[:, 4] *= torch.exp(-iou ** 2 / sigma)
                    dc = dc[dc[:, 4] > conf_thres]
        if len(det_max):
            det_max = torch.cat(det_max)
            #output[xi] = det_max[(-det_max[:, 4]).argsort()]
            output[xi] = det_max[(-det_max[:, 4]).argsort()]
        if (time.time() - t) > time_limit:
            print(f'WARNING: NMS time limit {time_limit}s exceeded')
            break  # time limit exceeded
    return output

val.py
out = non_max_suppression(out, conf_thres, iou_thres, labels=lb, multi_label=True, agnostic=single_cls)
替换为
out = soft_nms(out, conf_thres, iou_thres, multi_label=True)调用
即可


2.修改:Soft CIoU-NMS


def soft_nms(prediction, conf_thres=0.25, iou_thres=0.45, multi_label=False):函数中,
找到
iou = bbox_iou(dc[0], dc[1:])这句,
将其替换为
iou = bbox_iou(dc[0], dc[1:], CIoU=True)即可


3.修改:Soft DIoU-NMS


def soft_nms(prediction, conf_thres=0.25, iou_thres=0.45, multi_label=False):
函数中,
找到
iou = bbox_iou(dc[0], dc[1:])这句,
将其替换为
iou = bbox_iou(dc[0], dc[1:], DIoU=True)即可


4.修改:Soft EIoU-NMS


def soft_nms(prediction, conf_thres=0.25, iou_thres=0.45, multi_label=False):
函数中,
找到
iou = bbox_iou(dc[0], dc[1:])这句,
将其替换为
iou = bbox_iou(dc[0], dc[1:], EIoU=True)即可


5.修改:Soft SIoU-NMS


def soft_nms(prediction, conf_thres=0.25, iou_thres=0.45, multi_label=False):
函数中,
找到
iou = bbox_iou(dc[0], dc[1:])这句,
将其替换为
iou = bbox_iou(dc[0], dc[1:], SIoU=True)即可


6.修改:Soft GIoU-NMS


def soft_nms(prediction, conf_thres=0.25, iou_thres=0.45, multi_label=False):
函数中,
找到
iou = bbox_iou(dc[0], dc[1:])这句,
将其替换为
iou = bbox_iou(dc[0], dc[1:], GIoU=True)即可

参考用PyTorch实现CIoU NMS,DIoU NMS和GIoU NMS博文的末尾提示
不过试了一下,效果很一般,看看就行了,当作分享吧

你可能感兴趣的:(深度学习,人工智能)