Focal Loss升級 | E-Focal Loss讓Focal Loss動態(tài)化,類別極端不平衡也可以輕松解決


盡管最近長尾目標檢測取得了成功,但幾乎所有的長尾目標檢測器都是基于兩階段范式開發(fā)的。在實踐中,一階段檢測器在行業(yè)中更為普遍,因為它們有一個簡單和快速的Pipeline,易于部署。然而,在長尾情況下,這一工作迄今還沒有得到探索。
在本文中,研究了一階段檢測器在這種情況下是否表現(xiàn)良好。作者發(fā)現(xiàn),阻礙一階段檢測器取得優(yōu)異性能的主要障礙是:在長尾數(shù)據(jù)分布下,類別存在不同程度的正負不平衡問題。傳統(tǒng)的Focal Loss以所有類別中的相同調(diào)制因子來平衡訓練過程,因此無法處理長尾問題。
為了解決這個問題,本文提出了均衡Focal Loss(EFL),根據(jù)不同類別的正負樣本的不平衡程度,獨立地重新平衡不同類別樣本的損失貢獻。具體來說,EFL采用了一個與類別相關(guān)的調(diào)制因子,可以根據(jù)不同類別的訓練狀態(tài)進行動態(tài)調(diào)整。在具有挑戰(zhàn)性的LVISv1基準上進行的大量實驗證明了所提出的方法的有效性。通過端到端訓練,EFL在總體AP方面達到了29.2%,并在罕見類別上獲得了顯著的性能改進,超過了所有現(xiàn)有的最先進的方法。
開源地址:https://github.com/ModelTC/EOD
1簡介
長尾目標檢測是一項具有挑戰(zhàn)性的任務,近年來越來越受到關(guān)注。在長尾場景中,數(shù)據(jù)通常帶有一個Zipfian分布(例如LVIS),其中有幾個頭類包含大量的實例,并主導了訓練過程。相比之下,大量的尾類缺乏實例,因此表現(xiàn)不佳。長尾目標檢測的常用解決方案是數(shù)據(jù)重采樣、解耦訓練和損失重加權(quán)。盡管在緩解長尾不平衡問題方面取得了成功,但幾乎所有的長尾物體檢測器都是基于R-CNN推廣的兩階段方法開發(fā)的。在實踐中,一階段檢測器比兩階段檢測器更適合于現(xiàn)實場景,因為它們計算效率高且易于部署。然而,在這方面還沒有相關(guān)的工作。

與包含區(qū)域建議網(wǎng)絡(RPN)的兩階段方法,在將建議提供給最終的分類器之前過濾掉大多數(shù)背景樣本相比,一階段檢測器直接檢測規(guī)則的、密集的候選位置集上的目標。如圖1所示,由于密集的預測模式,在一階段檢測器中引入了極端的前景-背景不平衡問題。結(jié)合長尾場景下的前景類別(即類別的前景樣本)不平衡問題,嚴重損害了一階段檢測器的性能。
Focal Loss是解決前景-背景不平衡問題的一種常規(guī)解決方法。它側(cè)重于硬前景樣本的學習,并減少了簡單背景樣本的影響。這種損失再分配技術(shù)在類別平衡分布下效果很好,但不足以處理長尾情況下前景類別間的不平衡問題。為了解決這個問題,作者從兩階段中現(xiàn)有的解決方案(如EQLv2)開始,將它們調(diào)整在一階段檢測器中一起處理Focal Loss。作者發(fā)現(xiàn)這些解決方案與它們在兩階段檢測器上的應用相比,只帶來了微小的改進(見表1)。然后,作者認為,簡單地結(jié)合現(xiàn)有的解決方案與Focal Loss,不能同時解決這兩種類型的不平衡問題。通過比較不同數(shù)據(jù)分布中正樣本與負樣本的比值(見圖2),進一步認識到這些不平衡問題的本質(zhì)是類別之間的正負不平衡程度不一致。罕見類別比頻繁類別遭受更嚴重的正負失衡,因此需要更多的重視。
在本文中,提出了均衡Focal Loss(EFL),通過將一個類別相關(guān)的調(diào)制因子引入Focal Loss。具有兩個解耦的動態(tài)因子(即聚焦因子和加權(quán)因子)的調(diào)制因子獨立處理不同類別的正負不平衡。focusing factor根據(jù)硬正樣本對應類別的不平衡程度,決定了對硬正樣本的學習集中度。加權(quán)因子增加了稀有類別的影響,確保了稀有樣本的損失貢獻不會被頻繁的樣本所淹沒。這兩個因素的協(xié)同作用使EFL在長尾場景中應用一階段檢測器時,能夠均勻地克服前景-背景不平衡和前景類別不平衡。
在具有挑戰(zhàn)性的LVISv1基準測試上進行了廣泛的實驗。通過簡單有效的起始訓練,達到29.2%的AP,超過了現(xiàn)有的長尾目標檢測方法。在開放圖像上的實驗結(jié)果也證明了方法的泛化能力。
綜上所述,主要貢獻可以總結(jié)如下:
是第一個研究單階段長尾目標檢測的工作; 提出了一種新的均衡Focal Loss,它用一個類別相關(guān)的調(diào)制因子擴展了原始的Focal Loss。它是一種廣義的Focal Loss形式,可以同時解決前景-背景不平衡和前景類別不平衡的問題; 在LVISv1基準測試上進行了廣泛的實驗,結(jié)果證明了方法的有效性。它建立了一種新的先進技術(shù),可以很好地應用于任何單階段檢測器。
2相關(guān)工作
2.1 普通目標檢測
近年來,由于卷積神經(jīng)網(wǎng)絡的巨大成功,計算機視覺社區(qū)在目標檢測方面有了顯著的進步?,F(xiàn)代目標檢測框架大致可分為兩階段方法和一階段方法。
1、兩階段目標檢測
隨著快速RCNN的出現(xiàn),兩階段方法在現(xiàn)代目標檢測中占據(jù)了主導地位。兩階段檢測器首先通過區(qū)域建議機制(如選擇性搜索或RPN)生成目標建議,然后根據(jù)這些建議執(zhí)行特征圖的空間提取,以便進一步預測。由于這個建議機制,大量的背景樣本被過濾掉了。在之后,大多數(shù)兩階段檢測器的分類器在前景和背景樣本的相對平衡的分布上進行訓練,比例為1:3。
2、一階段目標檢測
一般來說,一階段目標檢測器有一個簡單和快速的訓練管道,更接近真實世界的應用。在單階段的場景中,檢測器直接從特征圖中預測檢測框。一階段目標檢測器的分類器在一個有大約104到105個候選樣本的密集集合上進行訓練,但只有少數(shù)候選樣本是前景樣本。有研究試圖從困難樣本挖掘的視角或更復雜的重采樣/重稱重方案來解決極端的前景-背景不平衡問題。
Focal Loss及其衍生重塑了標準的交叉熵損失,從而減輕了分配給良好分類樣本的損失,并集中對硬樣本進行訓練。受益于Focal Loss,一階段目標檢測器實現(xiàn)了非常接近兩階段目標檢測器方法的性能,同時具有更高的推理速度。最近,也有學者嘗試從標簽分配的角度來提高性能。
而本文提出的EFL可以很好地應用于這些單階段框架,并在長尾場景中帶來顯著的性能提高。
2.2 ?Long-Tailed 目標檢測
與一般的目標檢測相比,長尾目標檢測是一項更加復雜的任務,因為它存在著前景類別之間的極端不平衡。解決這種不平衡的一個直接方法是在訓練期間執(zhí)行數(shù)據(jù)重采樣。重復因子采樣(RFS)對來自尾部類的訓練數(shù)據(jù)進行過采樣,而對來自圖像級的頭部類的訓練數(shù)據(jù)進行過采樣。
有學者以解耦的方式訓練檢測器,并從實例級別提出了一個具有類平衡采樣器的額外分類分支。Forest R-CNN重新采樣從RPN與不同的NMS閾值的建議。其他工作是通過元學習方式或記憶增強方式實現(xiàn)數(shù)據(jù)重采樣。
損失重加權(quán)是解決長尾分布問題的另一種廣泛應用的解決方案。有研究者提出了均衡損失(EQL),它減輕了頭類對尾類的梯度抑制。EQLv2是EQL的一個升級版,它采用了一種新的梯度引導機制來重新衡量每個類別的損失貢獻。
也有學者從無統(tǒng)計的角度解釋了長尾分布問題,并提出了自適應類抑制損失(ACSL)。DisAlign提出了一種廣義的重加權(quán)方法,在損失設計之前引入了一個平衡類。除了數(shù)據(jù)重采樣和損失重加權(quán)外,許多優(yōu)秀的工作還從不同的角度進行了嘗試,如解耦訓練、邊緣修改、增量學習和因果推理。
然而,所有這些方法都是用兩階段目標檢測器開發(fā)的,到目前為止還沒有關(guān)于單階段長尾目標檢測的相關(guān)工作。本文提出了基于單階段的長尾目標檢測的第一個解決方案。它簡單而有效地超越了所有現(xiàn)有的方法。
3本文方法
3.1 再看Focal Loss
在一階段目標檢測器中,F(xiàn)ocal Loss是前景-背景不平衡問題的解決方案。它重新分配了易樣本和難樣本的損失貢獻,大大削弱了大多數(shù)背景樣本的影響。二分類Focal Loss公式為:

表示一個候選目標的預測置信度得分,而術(shù)語是平衡正樣本和負樣本的重要性的參數(shù)。調(diào)節(jié)因子是Focal Loss的關(guān)鍵組成部分。通過預測分數(shù)和Focal參數(shù),降低了簡單樣本的損失,側(cè)重于困難樣本的學習。
大量的陰性樣本易于分類,而陽性樣本通常很難分類。因此,陽性樣本與陰性樣本之間的不平衡可以大致看作是容易樣本與困難樣本之間的不平衡。Focal參數(shù)決定了Focal Loss的影響。它可以從等式中得出結(jié)論:一個大的將大大減少大多數(shù)陰性樣本的損失貢獻,從而提高陽性樣本的影響。這一結(jié)論表明,陽性樣本與陰性樣本之間的不平衡程度越高,的期望值越大。
當涉及到多類情況時,F(xiàn)ocal Loss被應用于C分類器,這些分類器作用于每個實例的s型函數(shù)轉(zhuǎn)換的輸出日志。C是類別的數(shù)量,這意味著一個分類器負責一個特定的類別,即一個二元分類任務。由于Focal Loss同樣對待具有相同調(diào)制因子的所有類別的學習,因此它未能處理長尾不平衡問題(見表2)。
3.2 Equalized Focal Loss
在長尾數(shù)據(jù)集(即LVIS)中,除了前景-背景不平衡外,一階段檢測器的分類器還存在前景類別之間的不平衡。

如圖2所示,如果從y軸上看,正樣本與負樣本的比值遠小于零,這主要揭示了前景和背景樣本之間的不平衡。這里將該比值的值稱為正負不平衡度。從x軸的角度可以看出,不同類別之間的不平衡程度存在很大差異,說明前景類別之間的不平衡。
顯然,在數(shù)據(jù)分布(即COCO)中,所有類別的不平衡程度是相似的。因此,F(xiàn)ocal Loss使用相同的調(diào)制因子就足夠了。相反,這些不平衡的程度在長尾數(shù)據(jù)的情況下是不同的。罕見類別比常見類別遭受更嚴重的正負失衡。如表1中所示。大多數(shù)一階段檢測器在罕見類別上的表現(xiàn)比在頻繁類別上更差。這說明,同一調(diào)制因子并不適用于所有不同程度的不平衡問題。
1、Focusing Factor
在此基礎上,提出了均衡Focal Loss(EFL),該方法采用類別相關(guān)Focusing Factor來解決不同類別的正負不平衡。將第類的損失表述為:

其中和與在Focal Loss中的相同。
參數(shù)是第類的Focusing Factor,它在Focal Loss中起著與類似的作用。正如在前面提到的不同的值對應于不同程度的正向-負向不平衡問題。這里采用一個大的來緩解嚴重的正負失衡問題。對于有輕微不平衡的頻繁類別,一個小的是合適的。Focusing Factor被解耦為2個組件,特別是一個與類別無關(guān)的參數(shù)和一個與類別相關(guān)的參數(shù):

其中,表示控制分類器基本行為的平衡數(shù)據(jù)場景中的Focusing Factor。參數(shù)≥0是一個與第類不平衡度相關(guān)的變量參數(shù)。它決定了學習的注意力集中在正負不平衡問題上。受EQLv2的啟發(fā),采用了梯度引導的機制來選擇。參數(shù)表示第類正樣本與負樣本的累積梯度比。
值較大表示第j類(例如頻繁)是訓練平衡,較小值表示類別(例如罕見)是訓練不平衡。為了滿足對的要求,將的值定義在[0,1]范圍內(nèi),并采用來反轉(zhuǎn)其分布。超參數(shù)s是決定EFL中上限的縮放因子。與Focal Loss相比,EFL可以獨立處理每個類別的正負不平衡問題,從而帶來性能的提升(見表3)。
2、Weighting Factor
即使使用了Focusing Factor ,仍然有2個障礙損失的性能:
對于二元分類任務,更大的適用于更嚴重的正負不平衡問題。而在多類的情況下,如圖3a所示,對于相同的,的值越大,損失就越小。這導致了這樣一個事實:當想要增加對學習一個具有嚴重的正負不平衡的類別的注意力時,必須犧牲它在整個訓練過程中所做的部分損失貢獻。這種困境阻礙了稀有類別獲得優(yōu)異的表現(xiàn)。 當較小時,來自不同F(xiàn)ocusing Factor的不同類別樣本的損失將收斂到一個相似的值。實際上,期望罕見的困難樣本比頻繁的困難樣本做出更多的損失貢獻,因為它們是稀缺的,并且不能主導訓練過程。
于是作者提出了Weighting Factor,通過重新平衡不同類別的損失貢獻來緩解上述問題。與Focusing Factor相似為罕見類別分配了一個較大的權(quán)重因子值,以提高其損失貢獻,同時保持頻繁類別的權(quán)重因子接近于1。具體地說,將第類的Weighting Factor設置為,以與Focusing Factor相一致。EFL的最終公式為:

如圖3b所示,使用Weighting Factor,EFL顯著增加了稀有類別的損失貢獻。同時,與頻繁的困難樣本相比,它更側(cè)重于罕見的困難樣本的學習。
Focusing Factor和Weighting Factor構(gòu)成了EFL的與類別相關(guān)的調(diào)節(jié)因子。它使分類器能夠根據(jù)樣本的訓練狀態(tài)和對應的類別狀態(tài)動態(tài)調(diào)整樣本的損失貢獻。Focusing Factor和Weighting Factor在EFL中均有重要作用。同時,在平衡數(shù)據(jù)分布中,所有的EFL都相當于Focal Loss。這種吸引人的特性使得EFL可以很好地應用于不同的數(shù)據(jù)分布和數(shù)據(jù)采樣器之中。
PyTorch實現(xiàn)如下:
@LOSSES_REGISTRY.register('equalized_focal_loss')
class?EqualizedFocalLoss(GeneralizedCrossEntropyLoss):
????def?__init__(self,
?????????????????name='equalized_focal_loss',
?????????????????reduction='mean',
?????????????????loss_weight=1.0,
?????????????????ignore_index=-1,
?????????????????num_classes=1204,
?????????????????focal_gamma=2.0,
?????????????????focal_alpha=0.25,
?????????????????scale_factor=8.0,
?????????????????fpn_levels=5):
????????activation_type?=?'sigmoid'
????????GeneralizedCrossEntropyLoss.__init__(self,
?????????????????????????????????????????????name=name,
?????????????????????????????????????????????reduction=reduction,
?????????????????????????????????????????????loss_weight=loss_weight,
?????????????????????????????????????????????activation_type=activation_type,
?????????????????????????????????????????????ignore_index=ignore_index)
????????#?Focal?Loss的超參數(shù)
????????self.focal_gamma?=?focal_gamma
????????self.focal_alpha?=?focal_alpha
????????#?ignore?bg?class?and?ignore?idx
????????self.num_classes?=?num_classes?-?1
????????#?EFL損失函數(shù)的超參數(shù)
????????self.scale_factor?=?scale_factor
????????#?初始化正負樣本的梯度變量
????????self.register_buffer('pos_grad',?torch.zeros(self.num_classes))
????????self.register_buffer('neg_grad',?torch.zeros(self.num_classes))
????????#?初始化正負樣本變量
????????self.register_buffer('pos_neg',?torch.ones(self.num_classes))
????????#?grad?collect
????????self.grad_buffer?=?[]
????????self.fpn_levels?=?fpn_levels
????????logger.info("build?EqualizedFocalLoss,?focal_alpha:?{focal_alpha},?focal_gamma:?{focal_gamma},scale_factor:?{scale_factor}")
????def?forward(self,?input,?target,?reduction,?normalizer=None):
????????self.n_c?=?input.shape[-1]
????????self.input?=?input.reshape(-1,?self.n_c)
????????self.target?=?target.reshape(-1)
????????self.n_i,?_?=?self.input.size()
????????def?expand_label(pred,?gt_classes):
????????????target?=?pred.new_zeros(self.n_i,?self.n_c?+?1)
????????????target[torch.arange(self.n_i),?gt_classes]?=?1
????????????return?target[:,?1:]
????????expand_target?=?expand_label(self.input,?self.target)
????????sample_mask?=?(self.target?!=?self.ignore_index)
????????inputs?=?self.input[sample_mask]
????????targets?=?expand_target[sample_mask]
????????self.cache_mask?=?sample_mask
????????self.cache_target?=?expand_target
????????pred?=?torch.sigmoid(inputs)
????????pred_t?=?pred?*?targets?+?(1?-?pred)?*?(1?-?targets)
??# map_val為:1-g^j
????????map_val?=?1?-?self.pos_neg.detach()
????????# dy_gamma為:gamma^j
????????dy_gamma?=?self.focal_gamma?+?self.scale_factor?*?map_val
????????
????????#?focusing?factor
????????ff?=?dy_gamma.view(1,?-1).expand(self.n_i,?self.n_c)[sample_mask]
????????
????????#?weighting?factor
????????wf?=?ff?/?self.focal_gamma
????????#?ce_loss
????????ce_loss?=?-torch.log(pred_t)
????????cls_loss?=?ce_loss?*?torch.pow((1?-?pred_t),?ff.detach())?*?wf.detach()
????????if?self.focal_alpha?>=?0:
????????????alpha_t?=?self.focal_alpha?*?targets?+?(1?-?self.focal_alpha)?*?(1?-?targets)
????????????cls_loss?=?alpha_t?*?cls_loss
????????if?normalizer?is?None:
????????????normalizer?=?1.0
????????return?_reduce(cls_loss,?reduction,?normalizer=normalizer)
????
?#?收集梯度,用于梯度引導的機制
????def?collect_grad(self,?grad_in):
????????bs?=?grad_in.shape[0]
????????self.grad_buffer.append(grad_in.detach().permute(0,?2,?3,?1).reshape(bs,?-1,?self.num_classes))
????????if?len(self.grad_buffer)?==?self.fpn_levels:
????????????target?=?self.cache_target[self.cache_mask]
????????????grad?=?torch.cat(self.grad_buffer[::-1],?dim=1).reshape(-1,?self.num_classes)
????????????grad?=?torch.abs(grad)[self.cache_mask]
????????????pos_grad?=?torch.sum(grad?*?target,?dim=0)
????????????neg_grad?=?torch.sum(grad?*?(1?-?target),?dim=0)
????????????allreduce(pos_grad)
????????????allreduce(neg_grad)
???#?正樣本的梯度
????????????self.pos_grad?+=?pos_grad
????????????#?負樣本的梯度
????????????self.neg_grad?+=?neg_grad
????????????#?self.pos_neg=g_j:表示第j類正樣本與負樣本的累積梯度比
????????????self.pos_neg?=?torch.clamp(self.pos_grad?/?(self.neg_grad?+?1e-10),?min=0,?max=1)
????????????self.grad_buffer?=?[]
4實驗
4.1 消融實驗研究
1、EFL中組件的影響

在EFL中有2個組成部分,即focusing factor和weighting factor。為了演示每個組件的效果,用提出的改進Baseline通過2倍計劃和重復因子采樣器來訓練模型。如表3所示focusing factor和weighting factor在EFL訓練過程中均有重要作用:
對于focusing factor,AP從25.7%提高到26.2%的AP。同時,在罕見類別上有顯著提高,AP提高了3.4%,說明其在緩解嚴重的正負失衡問題方面的有效性。
對于weighting factor,通過在EFL中所有類別中設置focusing factor始終為來觀察其影響。因此,weighting factor的函數(shù)也可以看作是一種結(jié)合Focal Loss的重加權(quán)方法。正如預期的那樣,weighting factor比改進的Baseline高出0.4%。
通過這2個組件的協(xié)同作用,EFL顯著提高了改進的Baseline的性能,從25.7%AP提高到27.5%AP。
2、EFL中超參數(shù)的影響

這里研究了不同s值的影響,發(fā)現(xiàn)s=8的性能最好。如表4中可以看出,幾乎所有的s≥0都可以提高改進后Baseline的性能。更重要的是,s可以在很大的范圍內(nèi)保持相對較高的性能。這表明EFL是超參數(shù)不敏感的。
3、EFL中組件對于Baseline的提升影響

這些模型都是用提出的EFL進行訓練的。如表5所示,同樣的配置和訓練過程,并帶來了一些性能的提高(+0.3%AP)。IoU分支和增加的Anchor尺度分別使原始EFL提高了1.0%AP和0.7%AP。值得注意的是,與Tab1中的ATSS相比,即使沒有穩(wěn)定和改進的設置,EFL仍然帶來了顯著的性能改善(從24.7%AP到25.8%AP,+1.1%AP)。結(jié)合這些設置,性能改進進一步提高。如Tab2所示,本文的方法比改進的Baseline值高出1.8%。
4.2 LVIS v1實驗

如Tab2所示,使用ResNet-50-FPN,本文提出的方法實現(xiàn)了總體27.5%的AP,將提出的改進Baseline提高了1.8%的AP,甚至在罕見類別上提高了5.9%。結(jié)果表明,EFL能夠很好地處理稀有類的極正負失衡問題。
與EQL、EQLv2和SeesawLoss等其他端到端方法相比,本文方法的性能分別為2.4%、2.0%AP和1.1%AP。 與cRT和BAGS等解耦訓練方法相比,本文方法以優(yōu)雅的端到端訓練策略(2.7%AP和1.5%AP)。除了高性能外,還保留了一階段檢測器的簡單、快速、易于部署等優(yōu)點。
4.3 模型分析
1、與其他一階段檢測器結(jié)合

為了演示EFL在不同階段檢測器上的泛化能力,分別將其與RetinaNet、FCOS?、PAA和改進的Baseline相結(jié)合。如表6所示,EFL在所有這些方法測試中都表現(xiàn)良好。與表1中的EQLv2和focal loss組合相比,提出的EFL相對于原檢測器保持了穩(wěn)定的較大性能提高(約+2% AP)。此外,EFL極大地提高了這些檢測器在稀有類別上的性能,這表明在解決長尾分布問題方面的實力。
2、一個更明顯的決策邊界

研究了EFL是否比罕見類別分類器上的Focal Loss具有更明顯的決策邊界。由于決策邊界不能直觀地顯示,因此采用類別間正樣本和負樣本之間的經(jīng)驗邊界來反映這些邊界。邊際是通過用每個類別的正樣本的平均預測分數(shù)減去負樣本的平均預測分數(shù)來計算的。由于EFL非常關(guān)注罕見類別的正負失衡問題,因此在EFL中,這些類別的陽性樣本與陰性樣本之間的差距應該很突出。如圖4所示,在罕見類別中,陽性樣本和陰性樣本之間保持了較小的邊緣。相比之下,提出的EFL增加了所有類別的邊界,特別是對于稀有類別,帶來了更明顯的決策邊界。
5參考
[1].Equalized Focal Loss for Dense Long-Tailed Object Detection
6推薦閱讀
往期推薦
長按掃描下方二維碼添加小助手。
可以一起討論遇到的問題
聲明:轉(zhuǎn)載請說明出處
掃描下方二維碼關(guān)注【集智書童】公眾號,獲取更多實踐項目源碼和論文解讀,非常期待你我的相遇,讓我們以夢為馬,砥礪前行!

