Head vs breakz

[인공지능] - Focal Loss for Dense Object Detection 본문

Head/인공지능

[인공지능] - Focal Loss for Dense Object Detection

headbreakz 2020. 5. 4. 19:56

https://arxiv.org/abs/1708.02002

 

Focal Loss for Dense Object Detection

The highest accuracy object detectors to date are based on a two-stage approach popularized by R-CNN, where a classifier is applied to a sparse set of candidate object locations. In contrast, one-stage detectors that are applied over a regular, dense sampl

arxiv.org

Abstract

 two stage detection은 높은 정확도를 보여주며, one stage detection의 경우 빠르고 간편하지만 정확도에서는 two stage detection에 비해 부족하다. class의 불균형이 이러한 문제를 발생시키는 것을 확인하였고, cross entropy loss의 재 구성을 통해 분류가 잘 된 예제에 loss에 대해 가중시켜 class 불균형을 해결하고자 한다.

Focal loss는 적은 예제에 대한 훈련에 초점을 맞춰서 훈련 중의 다수의 예제들이 많은 수를 차지 하는 것을 방지한다. 효과를 평가하기 위해서 RetinaNet을 설계하여 훈련한다.

불균등한 데이터를 사용하는 학습에 대해서 다수보다는 소수의 집중하여, 더욱 소수의 데이터에 반응 하도록 하는 방법 같다.

 

Introduction

 현재 R-CNN 프레임 워크 같은 유명한 Obeject Detectors는 2가지 과정를 기초로 두고 있는데, 첫번째는 물체의 후보군을 찾는 과정, 두번째는  후보군에 대해서 분류하는 과정을 두고 있다. 이러한 two stage 프레임워크는 지속적으로 정확성을 올리고 있다. 

 Two stage의 성공에 , one stage의 detection는 비슷한 정확도를 하지 못할까? 라는 의문이 생겼고 YOLO, SSD 같은 현재의 one stage detection에서는 two stage의 10~ 40% 이내의 정확도의 빠른 detector를 보여주고 있다.

이 논문에서는 one stage가 two stage를 따라 잡기위한 방법을 제시한다. 높은 정확도를 방해하는 class의 불균형을 식별하고 제거하여, 새로운 손실 함수를 제안한다. one-stage object detector인 RetinaNet을 사용하여 증명을 하였다. 

one stage가 two stage 정도의 정확도를 내기 위해, 데이터 불균형으로 인해 발생되는 문제점을 손실 함수를 재 정의하여 해결하고자 한다!

 

Related Work

  • Classic Object Detectors

  • Two- stage Detectors

  • One- stage Detectors

  • Class Imbalance

    •  불균형은 2가지 문제점을 발생시키는데, 유용하지 않은 정보에 대해 접근하여 모델 학습에 비효율성을 발생시키고, 수 많은 정보들이 한쪽으로 몰리면서 모델을 이끌어 간다. 결국 다수의 정보가 훈련을 이끌어 가게 되면서 정작 필요한 부분은 사용하지 못하는 문제가 발생하게 된다. 

  • Robust Estimation

    • Robust loss function의 경우 큰 오차를 가지는 이상치에 대해서 기여도를 낮추는 손실 함수이다. 

 

CODE (keras)

from keras import backend as K
import tensorflow as tf

# Compatible with tensorflow backend

def focal_loss(gamma=2., alpha=.25):
	def focal_loss_fixed(y_true, y_pred):
		pt_1 = tf.where(tf.equal(y_true, 1), y_pred, tf.ones_like(y_pred))
		pt_0 = tf.where(tf.equal(y_true, 0), y_pred, tf.zeros_like(y_pred))
		return -K.mean(alpha * K.pow(1. - pt_1, gamma) * K.log(pt_1)) - K.mean((1 - alpha) * K.pow(pt_0, gamma) * K.log(1. - pt_0))
	return focal_loss_fixed
    
    
model.compile(optimizer=optimizer, loss=[focal_loss(alpha=.25, gamma=2)])
    

CODE (pytorch)

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
 
class FocalLoss(nn.Module):
  def init(self, gamma=0, alpha=None, size_average=True):
  super(FocalLoss, self).init()
  self.gamma = gamma
  self.alpha = alpha
  if isinstance(alpha,(float,int,long)): self.alpha = torch.Tensor([alpha,1-alpha])
  if isinstance(alpha,list): self.alpha = torch.Tensor(alpha)
  self.size_average = size_average
 
  def forward(self, input, target):
      if input.dim()>2:
          input = input.view(input.size(0),input.size(1),-1)  # N,C,H,W => N,C,H*W
          input = input.transpose(1,2)    # N,C,H*W => N,H*W,C
          input = input.contiguous().view(-1,input.size(2))   # N,H*W,C => N*H*W,C
      target = target.view(-1,1)
 
      logpt = F.log_softmax(input)
      logpt = logpt.gather(1,target)
      logpt = logpt.view(-1)
      pt = Variable(logpt.data.exp())
 
      if self.alpha is not None:
          if self.alpha.type()!=input.data.type():
              self.alpha = self.alpha.type_as(input.data)
          at = self.alpha.gather(0,target.data.view(-1))
          logpt = logpt * Variable(at)
 
      loss = -1 * (1-pt)**self.gamma * logpt
      if self.size_average: return loss.mean()
      else: return loss.sum()

 


도움 & 참조

https://wordbe.tistory.com/entry/ML-Cross-entropyCategorical-Binary%EC%9D%98-%EC%9D%B4%ED%95%B4

Comments