AI Research Topic/Object Detection

[Object Detection] Soft NMS

꾸준희 2020. 3. 8. 22:35
728x90
반응형

 

 

Paper : https://arxiv.org/pdf/1704.04503.pdf

불러오는 중입니다...

 

Soft NMS

 

기존 NMS 는 가장 높은 confidence 를 가지는 bbox 를 찾고, 같은 클래스 인 bbox 들 중 겹치는 영역이 일정 비율 이상인 (iou > threshold) bbox 를 제거해서 중복된 detection 결과를 없앤다. 이러한 hard 한 NMS 방식은 실제로 존재하는 object 를 제거함으로써 mAP 가 낮아지는 문제가 있다. 일례로 아래 왼쪽 그림 처럼 같은 클래스인 말(horse) 들이 겹쳐져 있고, confidence 가 각 0.8 / 0.9 / 0.8 이 나왔을 때, 가운데 말만 남고 나머지 말의 detection 결과는 없어질 수 있다.

 

그래서 일정 비율 이상인 (iou > threshold) 겹치는 bbox 들의 confidence를 0 으로 만들어 없애지 말고, confidence 를 줄여서 최종 mAP 를 향상 시키자는 개념이다. 아래 오른쪽 그림과 같이 사이드에 있는 말들의 confidence 즉, score 가 각각 0.4 로 낮아짐을 확인 할 수 있다. 

 

 

 

 

 

 

 

Soft NMS pytorch 구현 

def soft_nms_pytorch(dets, box_scores, sigma=0.5, thresh=0.001, cuda=0):
    """
    Build a pytorch implement of Soft NMS algorithm.
    # Augments
        dets:        boxes coordinate tensor (format:[y1, x1, y2, x2])
        box_scores:  box score tensors
        sigma:       variance of Gaussian function
        thresh:      score thresh
        cuda:        CUDA flag
    # Return
        the index of the selected boxes
    """

    # Indexes concatenate boxes with the last column
    N = dets.shape[0]
    if cuda:
        indexes = torch.arange(0, N, dtype=torch.float).cuda().view(N, 1)
    else:
        indexes = torch.arange(0, N, dtype=torch.float).view(N, 1)
    dets = torch.cat((dets, indexes), dim=1)

    # The order of boxes coordinate is [y1,x1,y2,x2]
    y1 = dets[:, 0]
    x1 = dets[:, 1]
    y2 = dets[:, 2]
    x2 = dets[:, 3]
    scores = box_scores
    areas = (x2 - x1 + 1) * (y2 - y1 + 1)

    for i in range(N):
        # intermediate parameters for later parameters exchange
        tscore = scores[i].clone()
        pos = i + 1

        if i != N - 1:
            maxscore, maxpos = torch.max(scores[pos:], dim=0)
            if tscore < maxscore:
                dets[i], dets[maxpos.item() + i + 1] = dets[maxpos.item() + i + 1].clone(), dets[i].clone()
                scores[i], scores[maxpos.item() + i + 1] = scores[maxpos.item() + i + 1].clone(), scores[i].clone()
                areas[i], areas[maxpos + i + 1] = areas[maxpos + i + 1].clone(), areas[i].clone()

        # IoU calculate
        yy1 = np.maximum(dets[i, 0].to("cpu").numpy(), dets[pos:, 0].to("cpu").numpy())
        xx1 = np.maximum(dets[i, 1].to("cpu").numpy(), dets[pos:, 1].to("cpu").numpy())
        yy2 = np.minimum(dets[i, 2].to("cpu").numpy(), dets[pos:, 2].to("cpu").numpy())
        xx2 = np.minimum(dets[i, 3].to("cpu").numpy(), dets[pos:, 3].to("cpu").numpy())
        
        w = np.maximum(0.0, xx2 - xx1 + 1)
        h = np.maximum(0.0, yy2 - yy1 + 1)
        inter = torch.tensor(w * h).cuda() if cuda else torch.tensor(w * h)
        ovr = torch.div(inter, (areas[i] + areas[pos:] - inter))

        # Gaussian decay
        weight = torch.exp(-(ovr * ovr) / sigma)
        scores[pos:] = weight * scores[pos:]

    # select the boxes and keep the corresponding indexes
    keep = dets[:, 4][scores > thresh].int()

    return keep

 

 

참고자료 1 : https://github.com/DocF/Soft-NMS/blob/master/softnms_pytorch.py

 

DocF/Soft-NMS

Python and Pytorch two implements of Soft NMS algorithm - DocF/Soft-NMS

github.com

 

 

참고자료 2 : https://medium.com/@lsrock125/improving-object-detection-with-one-line-of-code-%EB%A6%AC%EB%B7%B0-696cfb07c9f6

 

Improving Object Detection With One Line of Code 리뷰

요약

medium.com

 

 

참고자료 3 : https://towardsdatascience.com/non-maximum-suppression-nms-93ce178e177c

 

Non-maximum Suppression (NMS)

A Technique to remove duplicates and false positives in object detection

towardsdatascience.com

 

728x90
반응형
1 2 3 4 5 6 7 8 9 ··· 21