[論文理解]Focal Loss for Dense Object Detection(Retina Net)


Focal Loss for Dense Object Detection

Intro

這又是一篇與何凱明大神有關的作品,文章主要解決了one-stage網絡識別率普遍低於two-stage網絡的問題,其指出其根本原因是樣本類別不均衡導致,一針見血,通過改變傳統的loss(CE)變為focal loss,瞬間提升了one-stage網絡的准確率。與此同時,為了測試該loss對網絡改進的影響,文章還特地設計了一個網絡,retina net,證明了其想法。

Problems

  1. 為啥one-stage網絡的准確率普遍會低於two-stage呢?

文章指出,one-stage網絡是在訓練階段,極度不平衡的類別數量導致准確率下降,一張圖片里box為目標類別的樣本就那么點,而是背景沒有目標的樣本卻遠遠高於目標樣本,這導致分類為背景的樣本數目占據樣本數目極大部分,因此,這種不平衡導致了模型會把更多的重心放在背景樣本的學習上去。常規的做法可以是負樣本挖掘,來維持正負樣本1:3的比例,這似乎起到了點作用。但是,本文的做法是改變原有的loss,提出新的loss來解決。由於容易被分類的負樣本的數量非常龐大,所以這些樣本就會左右梯度的方向,繼而使得模型更專注於分負樣本而非具體的類別。

  1. 為啥two-stage的准確率不會受到樣本類別不均衡的影響呢?

因為two-stage網絡一般會經歷類似rpn網絡,第一個網絡已經濾去了大多數背景樣本,在第二個網絡里負樣本的數量大量減少,因此對分類的影響也會減少。但two-stage網絡仍然有大量負樣本,只是不均衡程度減輕了,所以,這是識別准確率不高的根本原因在於樣本類別是否均衡。

Loss

下面給一張圖,來說明下作者到底是怎么想的。對於普通的ce loss,由於負樣本數量巨大,正樣本很少,所以負樣本被錯分為正樣本的的loss會占據loss的主導。那么好的做法就是,盡量減少負樣本loss所占的比例,或者增大正樣本被錯分為負樣本的loss所占的比例。於是本文的想法大致就成型了。

首先要讓正負樣本所占的比例均衡,沒有使用負樣本挖掘等手段,本文直接在ce loss前面乘以一個參數α,這樣可以方便控制正負樣本loss所占的比例,即如果gt為1也就是正樣本,那么下式表示的就是正樣本被錯分為負樣本的loss,我們乘以alpha用於調整這個loss的大小,顯然應該放大這個loss:

然而,盡管這樣做可以做可以起到一些作用,如果分類的結果接近正確,比如正樣本以0.9的概率被分為正樣本,但是0.9和1之間也是有loss的,這部分loss也會因為前面乘了一個alpha被放大,這其實是我們不希望看到的,因為這一部分已經被分的足夠好了,盡管乘了alpha,但預測為0.4的正樣本和預測為0.6的正樣本的loss相差是不大的,我們希望把這個差距拉開,希望看到的是,被分類的足夠好的樣本loss不需要太大的alpha權重,而被錯分嚴重的,比如預測概率小於0.5的正樣本,我們需要將他的loss放大,錯分越嚴重loss應該被放大的越多,因此可以用下面的指數函數來實現:

由上面的圖可以看出,當γ為5的時候,預測概率小於0.5的正樣本因為前面乘了個指數的關系可以將loss放到很大,而大於0.5的分類的很好的正樣本的loss會乘一個接近0的東西,這就很符合我們的要求。

然后,最終的loss長這個樣子:

Trick

類別不平衡問題在訓練最開始階段會導致訓練不是很穩定,這是因為我們一般初始化參數的時候都會認為參數其結果服從一個先驗分布,一般我們就認為是正太分布,對於分類的最后一層,我們的初始化就是讓每個類別的概率都相等,這樣做的結果是在反向過程中會使得訓練初期訓練不穩定,因為負樣本非常多,你讓各種類別概率相等之后顯然是增加了負樣本分錯的數目,也就是增加了負樣本在訓練時候的loss,所以好的做法是讓最后一層的分布符合正樣本相對負樣本的分布,這樣做能夠保證訓練初期的穩定性。

RetinaNet Detector

retinanet的網絡結構是在FPN的每個特征層后面接兩個子網絡,分別是classification subnet 和 bbox regression subnet。

前者是先用四次C個3*3的卷積核卷積+relu激活,然后用KA個3*3的卷積核卷積,用sigmoid來激活最后一層,對每個特征層進行類別預測。KA是K種類別A個anchor的預測結果,實驗中設置C = 256。

后者也差不多,也是接一個FCN(不含全連接的全卷積),最后預測的是4*A個量,這個與faster rcnn中的類似。

與RPN相比的話,retinanet並沒有共享預測類別的網絡權重和回歸網絡的權重,因為作者說他們這樣不共享網絡權重最終得到的准確率遠比調整超參效果要好。

網絡結構如圖:

OHEM

(Online Hard Example Mining)OHEM是來幫助two-stage網路訓練的方法,OHEM作用是在NMS之前,先將各個樣本的loss排序,只留下loss較大的樣本繼續NMS,這樣做也可以更加專注於錯分樣本的訓練,但是其也有缺點,其直接扔掉了簡單樣本,顯然會導致簡單樣本的訓練出現問題。作者通過實驗說明了FL比OHEM更加有效。

Code

'''
@Descripttion: This is Aoru Xue's demo, which is only for reference.
@version: 
@Author: Aoru Xue
@Date: 2018-12-26 08:04:34
@LastEditors  : Aoru Xue
@LastEditTime : 2018-12-26 08:16:09
'''
import torch
import torch.nn as nn

class FocalLoss(nn.Module):
    def __init__(self,gamma = 0.5):
        super(FocalLoss, self).__init__()
        self.gamma = gamma
    def forward(self,x,y):# (b,len) (b,1)
        '''
        FL = -(1-pt)**gamma * log(pt) if gt == 1
           = -pt**gamma * log(1-pt) if gt == 0
        利用乘法省去if
        '''
        pt = torch.sigmoid(x).view(-1,)

        losses = -(1 - pt)**self.gamma * torch.log(pt) * y - pt**self.gamma * torch.log(1-pt) * (1-y)
        return torch.sum(losses)

if __name__ == '__main__':
    focal_loss = FocalLoss()
    x = torch.Tensor([[0.1,0.5,0.7,0.8]])
    y = torch.LongTensor([[1,0,1,0]])
    loss = focal_loss(x,y)
    print(loss)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM