네이버 부스트캠프 🔗/⭐주간 학습 정리

[네이버 부스트 캠프 AI Tech]Focal Loss 그리고 Label Smoothing Loss, F1 Loss

Dobby98 2023. 4. 13. 20:58

본 글은 네이버 부스트 캠프 AI Tech 기간동안

개인적으로 배운 내용들을 주단위로 정리한 글입니다

 

본 글의 내용은 새롭게 알게 된 내용을 중심으로 정리하였고

복습 중요도를 선정해서 정리하였습니다

 

✅ Week 6

1. Cross Entropy Loss의 문제점

2. Focal Loss

추가로 알아볼 loss

3. Label Smoothing Loss

4. F1 Loss


이번주 목표 중 하나 : 나의 코드에 사용되는 것들을 알고쓰자!!


1. Cross Entropy Loss의 문제점 

Focal loss를 비롯해서 다양한 loss에 대해서 이야기 해보기전에

필요한 것이 있는데 바로 Cross Entropy Loss의 문제점을 살펴보는 것이다

 

cross entropy loss 수식

대표적으로 딥러닝에서 다중분류 문제를 해결할 때 사용하는 Loss 함수는 Cross Entropy이다

하지만 Cross Entropy도 좋은 손실 함수이지만 

세상의 이치에 따라서 한계점도 존재한다

 

Cross Entropy의 수식을 자세히 살펴보면

P가  1에 가까우면 Cross Entropy는 0에 가까워지고

P값을 0 가깝게 예측을 한다면 무한대가 된다 - loss

 

쉽게 말해서 Cross Entropy는 틀린 정답에 대한 패널티를 부여하는 손실함수이다

하지만 여기서의 한계점이 보이는데

 

바로 올바른 정답은 아무런 보상이 없다는 것이다

 

이러한 상황은 클래스의 분포가 불균형 할 때

예를 들어 한 클래스의 데이터만 많이 존재하고 다른 클래스들의 양이 적을 때

단점으로 작용한다

 


2. Focal Loss

Focal Loss는 이러한 단점을 극복하기 위해서 등장하였다

처음 제안된 논문의 목적은 Object detection 에서 Background의 BBox가 다른 클래스 보다 많은 상태

즉, 클래스의 불균형 상태를 해결하기 위해서 제안되었다

 

수식은 위의 사진에 나타나있다 FL

아이디어는 쉽게 설명할 수 있다

쉽게 맞출 수 있는 Y에 대한 가중치는 줄이고 어려운 문제에 가중치를 늘려서 집중하는 것이다

 

Focal Loss (Focal Loss for Dense Object Detection) 알아보기

gaussian37's blog

gaussian37.github.io

 Easy Example에 대한 Loss의 비중을 낮추는 원리로 작동된다

 

위 블로그 글이 너무 쉽게 정리되어 있다 참고하길 바란다


3. Label Smoothing Loss

 

Label Smoothing

NLP research trends and insights

ratsgo.github.io

 

 

라벨 스무딩(Label smoothing), When Does Label Smoothing Help?

$ \newcommand{\infdiv}{D\infdivx} \newcommand{\comz}{\mathcal{Z}} \newcommand{\vec}{\boldsymbol} $ 딥 러닝의 신뢰도를 개선하기 위한 모델 보정(calibration) 기법 소개 최근 다양한 분야에서 각광 받는 딥 러닝은 성능 면

blog.si-analytics.ai

class LabelSmoothingLoss(nn.Module):
    def __init__(self, classes=3, smoothing=0.0, dim=-1):
        super(LabelSmoothingLoss, self).__init__()
        self.confidence = 1.0 - smoothing
        self.smoothing = smoothing
        self.cls = classes
        self.dim = dim

    def forward(self, pred, target):
        pred = pred.log_softmax(dim=self.dim)
        with torch.no_grad():
            true_dist = torch.zeros_like(pred)
            true_dist.fill_(self.smoothing / (self.cls - 1))
            true_dist.scatter_(1, target.data.unsqueeze(1), self.confidence)
        return torch.mean(torch.sum(-true_dist * pred, dim=self.dim))

https://discuss.pytorch.org/t/is-this-a-correct-implementation-for-focal-loss-in-pytorch/43327/8

4. F1 Loss


 https://gist.github.com/SuperShinyEyes/dcc68a08ff8b615442e3bc6a9b55a354

class F1Loss(nn.Module):
    def __init__(self, classes=3, epsilon=1e-7):
        super().__init__()
        self.classes = classes
        self.epsilon = epsilon

    def forward(self, y_pred, y_true):
        assert y_pred.ndim == 2
        assert y_true.ndim == 1
        y_true = F.one_hot(y_true, self.classes).to(torch.float32)
        y_pred = F.softmax(y_pred, dim=1)

        tp = (y_true * y_pred).sum(dim=0).to(torch.float32)
        tn = ((1 - y_true) * (1 - y_pred)).sum(dim=0).to(torch.float32)
        fp = ((1 - y_true) * y_pred).sum(dim=0).to(torch.float32)
        fn = (y_true * (1 - y_pred)).sum(dim=0).to(torch.float32)

        precision = tp / (tp + fp + self.epsilon)
        recall = tp / (tp + fn + self.epsilon)

        f1 = 2 * (precision * recall) / (precision + recall + self.epsilon)
        f1 = f1.clamp(min=self.epsilon, max=1 - self.epsilon)
        return 1 - f1.mean()