日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

GHM解读

發(fā)布時間:2024/4/11 编程问答 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GHM解读 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

收錄于AAAI2019 oral的一篇文章,主要是解決目標(biāo)檢測中的樣本不平衡問題,包括正負(fù)樣本不平衡、難易樣本不平衡,和著名的Focal Loss類似,也是基于交叉熵做的改進(jìn)。此外,本文成文過程參考了知乎上一個精簡的分析,歡迎訪問。

簡介

單階段跟蹤以一個更優(yōu)雅的方式對待目標(biāo)檢測問題,然而它也存在困擾已久的問題,那就是樣本的不均衡從而導(dǎo)致模型訓(xùn)練效果不好,這包括正負(fù)樣本的不平衡和難易樣本的不平衡。這兩種不平衡本質(zhì)上都可以從梯度的層面解釋,因此作者提出了GHM(梯度調(diào)和機制, gradient harmonizing mechanism)來處理這一現(xiàn)象,以此為基礎(chǔ)構(gòu)建的GHM分類損失(GHM-C)和GHM回歸損失(GHM-R)可以輕松嵌入到如交叉熵的分類損失和如Smooth L1的回歸損失中,這兩種損失分別用于anchor的分類和邊界框的修正,實驗表明,在不經(jīng)過費力挑戰(zhàn)超參數(shù)的前提下,GHM-C和GHM-R可以為單階段檢測器帶來實質(zhì)性的改進(jìn),并且超過了使用Focal Loss和Smooth L1的SOTA方法。

  • 論文標(biāo)題

    Gradient Harmonized Single-stage Detector

  • 論文地址

    https://arxiv.org/abs/1811.05181

  • 論文源碼

    https://github.com/libuyu/GHM_Detection

介紹

單階段檢測的出現(xiàn)為目標(biāo)檢測帶來了一種更加高效且優(yōu)雅的范式,但是單階段方法和二階段方法的精度還是存在不小的差距的。造成這種差距的主要原因之一就是單階段檢測器的訓(xùn)練存在正負(fù)樣本和難易樣本的不平衡問題,這里需要注意的是,正負(fù)樣本和難易樣本是兩回事,因此存在正易、正難、負(fù)易和負(fù)難四種樣本。 大量的簡單樣本和背景樣本使得模型的訓(xùn)練不堪重負(fù),但是二階段檢測則不存在這個問題,因為其是基于proposal篩選的。

針對這個問題,OHEM是一個基于難樣本挖掘的方法被廣泛使用,但是這種方法直接放棄了大多數(shù)樣本并且使得訓(xùn)練的效率不高。后來,Focal Loss橫空出世,它通過修改經(jīng)典的交叉熵?fù)p失為一個精心設(shè)計的形式來解決這個問題。但是,Focal Loss采用了兩個超參數(shù),這兩個參數(shù)需要花費大量的精力對其進(jìn)行調(diào)整,并且Focal Loss是一種靜態(tài)損失,它不能自適應(yīng)于數(shù)據(jù)分布的變化,即隨訓(xùn)練過程而改變。

這篇論文中,作者指出類別不平衡最終可以歸為梯度范數(shù)分布的不平衡。如果一個正樣本被很好地分類,那么它是一個簡單樣本,模型從中受益不多,換句話說,該樣本產(chǎn)生的梯度很小。而錯誤分類的樣本無論屬于哪個類都應(yīng)該受到模型足夠的關(guān)注。因此,從全局來看,大量的負(fù)樣本是容易分類的并且難樣本往往是正樣本。因此這兩種不平衡可以粗略概括為屬性不平衡。

作者認(rèn)為梯度范數(shù)的分布可以隱式表達(dá)不同屬性的樣本的不平衡。相對于梯度范數(shù)的樣本密度(下文簡稱梯度密度),梯度密度如上圖的最左側(cè)所示,變化幅度是很大的。首先看圖像的最左側(cè),這里的樣本的梯度范數(shù)比較小但是密度很大,這表示大量的負(fù)易樣本。再看圖像最右側(cè),這里梯度范數(shù)大,數(shù)量相對于左側(cè)的容易樣本少得多,這表示困難樣本。盡管一個容易樣本相對于困難樣本對整體損失的貢獻(xiàn)少,但是架不住數(shù)量大啊,大量的容易樣本的貢獻(xiàn)可能超越了少數(shù)困難樣本的貢獻(xiàn),導(dǎo)致訓(xùn)練效率不高。而且,難樣本的密度比中性樣本的密度稍高。這些非常難的樣本可以視作離群點,因為即使模型收斂,它們依然穩(wěn)定存在。離群點可能會影響模型的穩(wěn)定性,因為它們的梯度可能與其他一般樣本有很大差異。

經(jīng)過上面的梯度范數(shù)分布的分析,作者提出了梯度調(diào)和機制(GHM)來高效訓(xùn)練單階段目標(biāo)檢測器,該策略關(guān)注于不同樣本梯度分布的平衡。GHM首先對具有相似屬性但沒有梯度密度的樣本進(jìn)行統(tǒng)計,然后依據(jù)密度將調(diào)和參數(shù)附加(以乘法的形式)到每個樣本的梯度上。上圖最右側(cè)即為平衡后的結(jié)果,可以看到,GHM可以大大降權(quán)簡單樣本累積的大量梯度同時也可以相對降權(quán)離群點梯度,這使得各類樣本的貢獻(xiàn)度平衡且訓(xùn)練更加穩(wěn)定高效。

GHM

前人工作

首先,來回顧一下單階段檢測的一個關(guān)鍵問題,樣本類型的極度不平衡。對一個候選框而言,p∈[0,1]p \in[0,1]p[0,1]表示模型預(yù)測的概率分布,p?∈{0,1}p^{*} \in\{0,1\}p?{0,1}為一個確定的類真實標(biāo)簽,那么考慮二分交叉熵的標(biāo)準(zhǔn)形式如下,它通常用于分類任務(wù)。

LCE(p,p?)={?log?(p)if?p?=1?log?(1?p)if?p?=0L_{C E}\left(p, p^{*}\right)=\left\{\begin{array}{ll} -\log (p) & \text { if } p^{*}=1 \\ -\log (1-p) & \text { if } p^{*}=0 \end{array}\right. LCE?(p,p?)={?log(p)?log(1?p)??if?p?=1?if?p?=0?

但是,這個形式的交叉熵用于正負(fù)樣本分類是不合理的,因為單階段檢測器通常會產(chǎn)生高達(dá)100k的目標(biāo),能和GT框匹配的正樣本少之又少,因此出現(xiàn)了正負(fù)樣本不平衡的問題,為了解決這個問題,下面的加權(quán)交叉熵被提出。

LCE(p,p?)={?αlog?(p),if?p?=1?(1?α)log?(1?p),if?p?=0L_{C E}\left(p, p^{*}\right)=\left\{\begin{aligned} -\alpha \log (p), & \text { if } p^{*}=1 \\ -(1-\alpha) \log (1-p), & \text { if } p^{*}=0 \end{aligned}\right. LCE?(p,p?)={?αlog(p),?(1?α)log(1?p),??if?p?=1?if?p?=0?

雖然加權(quán)交叉熵平衡了正負(fù)樣本,但是就像上文所說的,樣本還有難易之分,目標(biāo)檢測的候選框其實大量是易分樣本,加權(quán)交叉熵對難易樣本的平衡并沒有太大作用。易分樣本雖然損失很低,但是數(shù)量極多,梯度的累積造成其主導(dǎo)了優(yōu)化的方向,顯然這是不合理的。因此,Focal Loss作者認(rèn)為,易分樣本(置信度高的樣本)對模型效果的提升影響非常小,模型應(yīng)該主要關(guān)注那些難分樣本。這個假設(shè)其實是有一些問題的,GHM就是針對次做了探索,下文再細(xì)說。

那么,Focal Loss如何平衡難易樣本呢,其實很簡單,把高置信度的簡單樣本的損失再降低不就行了,于是有了下面這個中間結(jié)果,通過γ\gammaγ的設(shè)置可以有效衰減高置信度樣本的損失值。

FL={?(1?p)γlog?(p),if?p?=1?pγlog?(1?p),if?p?=0F L=\left\{\begin{aligned} -(1-p)^{\gamma} \log (p), & \text { if } p^{*}=1 \\ -p^{\gamma} \log (1-p), & \text { if } p^{*}=0 \end{aligned}\right. FL={?(1?p)γlog(p),?pγlog(1?p),??if?p?=1?if?p?=0?

這個公式再結(jié)合上加權(quán)交叉熵,不就同時解決了正負(fù)樣本不平衡和難易樣本不平衡兩個問題嘛,于是就有了下面這個Focal Loss的常見形式。實驗表明,γ=2\gamma=2γ=2α=0.25\alpha=0.25α=0.25時效果最佳。

FL={?α(1?p)γlog?(p),if?p?=1?(1?α)pγlog?(1?p),if?p?=0F L=\left\{\begin{array}{ccc} -\alpha(1-p)^{\gamma} \log (p), & \text { if } & p^{*}=1 \\ -(1-\alpha) p^{\gamma} \log (1-p), & \text { if } & p^{*}=0 \end{array}\right. FL={?α(1?p)γlog(p),?(1?α)pγlog(1?p),??if??if??p?=1p?=0?

下面是mmdet實現(xiàn)的pytorch版本的focal loss,這個代碼也比較容易理解,主要對focal loss公式進(jìn)行了拆分實現(xiàn)。

def py_sigmoid_focal_loss(pred,target,weight=None,gamma=2.0,alpha=0.25,reduction='mean',avg_factor=None):pred_sigmoid = pred.sigmoid()target = target.type_as(pred)pt = (1 - pred_sigmoid) * target + pred_sigmoid * (1 - target)focal_weight = (alpha * target + (1 - alpha) * (1 - target)) * pt.pow(gamma)loss = F.binary_cross_entropy_with_logits(pred, target, reduction='none') * focal_weightif weight is not None:if weight.shape != loss.shape:if weight.size(0) == loss.size(0):weight = weight.view(-1, 1)else:assert weight.numel() == loss.numel()weight = weight.view(loss.size(0), -1)assert weight.ndim == loss.ndimloss = weight_reduce_loss(loss, weight, reduction, avg_factor)return

GHM損失

然而,Focal Loss雖然極大的推動了單階段檢測和anchor-free檢測的發(fā)展,但是它也是存在問題的。首先,就是最核心的一個問題:讓模型過分關(guān)注特別難分的樣本肯定是不合適的,因為樣本中存在離群點,模型可能已經(jīng)收斂,但是這些離群點的存在模型仍舊判斷失誤難以正常訓(xùn)練,即使擬合了這樣的樣本模型也是不合理的。其次,Focal Loss的兩個超參數(shù)需要人為設(shè)計,且需要聯(lián)合調(diào)參,因為它倆會互相影響。為了解決這兩個問題,GHM被提了出來,不同于Focal Loss關(guān)注于置信度來衰減損失,GHM從一定置信度的樣本量的角度出發(fā)衰減損失。

那么GHM是如何做的呢?首先,假定xxx是模型輸出且通過sigmoid激活,那么可以可以得到關(guān)于xxx的交叉熵梯度如下,這其實可以視為損失的梯度即為預(yù)測和真值的差距。

?LCE?x={p?1if?p?=1pif?p?=0=p?p?\begin{aligned} \frac{\partial L_{C E}}{\partial x} &=\left\{\begin{array}{ll} p-1 & \text { if } p^{*}=1 \\ p & \text { if } p^{*}=0 \end{array}\right.\\ &=p-p^{*} \end{aligned} ?x?LCE???={p?1p??if?p?=1?if?p?=0?=p?p??

利用上式,可以定義梯度的模ggg如下,這個ggg等于相對于xxx的梯度范數(shù),它的值表示樣本的難易屬性(越大樣本越難),同時也隱含了樣本對全局梯度的影響。這里梯度范數(shù)的定義數(shù)學(xué)上并不嚴(yán)格,只是作者為了方便的說法。

g=∣?LCE?x∣=∣p?p?∣={1?pif?p?=1pif?p?=0g= \left|\frac{\partial L_{C E}}{\partial x}\right| = \left|p-p^{*}\right|=\left\{\begin{array}{ll} 1-p & \text { if } p^{*}=1 \\ p & \text { if } p^{*}=0 \end{array}\right. g=??x?LCE???=p?p?={1?pp??if?p?=1?if?p?=0?

下圖所示即為一個收斂的單階段模型的ggg分布情況,橫軸表示梯度的模,縱軸表示樣本量比例。很直觀地可以看到,ggg很小的樣本數(shù)量非常多,這部分為大量的容易樣本,隨著ggg增加,樣本量迅速減少,但是在ggg接近1的時候,樣本量也不少,這部分屬于困難樣本。需要注意的是,這是一個收斂的模型,也就是說即使模型收斂,這些樣本還是難易區(qū)分,它們屬于離群點,如果模型強行擬合這類樣本會導(dǎo)致其他正常樣本分類精度降低。

依此,GHM提出了自己的核心觀點,的確不應(yīng)該關(guān)注那些數(shù)量很多的容易樣本,但是非常困難的樣本也是不正常的,也不應(yīng)該過分關(guān)注,而且容易樣本和困難樣本的數(shù)量相比于中性樣本都比較多。那么如何同時衰減這兩類樣本呢,其實只要從它們數(shù)量多這個角度出發(fā)就行,就衰減那些數(shù)量多的樣本。那么如何衰減數(shù)量多的呢,那就需要定義一個變量,來衡量某個梯度或者某個梯度范圍內(nèi)的樣本數(shù)量,這個概念其實很類似于“密度”這個概念,因此將其稱為梯度密度,這就有了下面這個這篇文章最核心的公式,梯度密度GD(g)GD(g)GD(g)的定義。

GD(g)=1l?(g)∑k=1Nδ?(gk,g)G D(g)=\frac{1}{l_{\epsilon}(g)} \sum_{k=1}^{N} \delta_{\epsilon}\left(g_{k}, g\right) GD(g)=l??(g)1?k=1N?δ??(gk?,g)

這個式子需要做一些說明。gkg_kgk?表示第kkk個樣本的梯度的模,δ?(x,y)\delta_{\epsilon}(x, y)δ??(x,y)l?(g)l_{\epsilon}(g)l??(g)的定義式如下,前者表示xxx是否在yyy的一個鄰域內(nèi),在的話則為1否則為0,上式中求和后的含義就是gkg_kgk?ggg的范圍內(nèi)的樣本數(shù)目,后者則表示計算樣本量的這個鄰域的區(qū)間長度,它作為標(biāo)準(zhǔn)化因子。因此,梯度密度GDGDGD的含義可以理解為單位模長在ggg附近的樣本數(shù)目。

δ?(x,y)={1if?y??2<=x<y+?20otherwise?\delta_{\epsilon}(x, y)=\left\{\begin{array}{rr} 1 & \text { if } y-\frac{\epsilon}{2}<=x<y+\frac{\epsilon}{2} \\ 0 & \text { otherwise } \end{array}\right. δ??(x,y)={10??if?y?2??<=x<y+2???otherwise??

l?(g)=min?(g+?2,1)?max?(g??2,0)l_{\epsilon}(g)=\min \left(g+\frac{\epsilon}{2}, 1\right)-\max \left(g-\frac{\epsilon}{2}, 0\right) l??(g)=min(g+2??,1)?max(g?2??,0)

有了梯度密度,下面定義最終用在損失調(diào)和上的梯度密度調(diào)和參數(shù),這里的NNN表示樣本總量,為了方便理解,其可以改寫為βi=1GD(gi)/N\beta_{i}=\frac{1}{G D\left(g_{i}\right) / N}βi?=GD(gi?)/N1?,分母GD(gi)/NG D\left(g_{i}\right) / NGD(gi?)/N表示第i個樣本具有鄰域梯度的所有樣本分?jǐn)?shù)的歸一化器。如果樣本關(guān)于梯度均勻分布,對任何的gig_igi?GD(gi)=NGD(g_i) = NGD(gi?)=N并且每個樣本的βi=1\beta_i = 1βi?=1。相反,具有較大密度的樣本則會被歸一化器降權(quán)表示。

βi=NGD(gi)\beta_{i}=\frac{N}{G D\left(g_{i}\right)} βi?=GD(gi?)N?

利用βi\beta_iβi?可以集成到分類損失和回歸損失中從而構(gòu)建新的損失GHM-C Loss,這里的βi\beta_iβi?則作為第iii個樣本的損失加權(quán),最終梯度密度調(diào)和后的分類損失如下式。其實從最后的結(jié)果來看,就是原本的交叉熵乘以該樣本梯度密度的倒數(shù)。

LGHM?C=1N∑i=1NβiLCE(pi,pi?)=∑i=1NLCE(pi,pi?)GD(gi)\begin{aligned} L_{G H M-C} &=\frac{1}{N} \sum_{i=1}^{N} \beta_{i} L_{C E}\left(p_{i}, p_{i}^{*}\right) \\ &=\sum_{i=1}^{N} \frac{L_{C E}\left(p_{i}, p_{i}^{*}\right)}{G D\left(g_{i}\right)} \end{aligned} LGHM?C??=N1?i=1N?βi?LCE?(pi?,pi??)=i=1N?GD(gi?)LCE?(pi?,pi??)??

使用GHM-C和交叉熵以及Focal Loss的梯度范數(shù)調(diào)整效果如下圖,顯然,GHM-C的抑制更加明顯合理。

這里作者還提到了EMA處理的技巧,此外魔改smooth l1可以得到下面的GHM-R損失函數(shù),這里就不展開了。

LGHM?R=1N∑i=1NβiASL1(di)=∑i=1NASL1(di)GD(gri)\begin{aligned} L_{G H M-R} &=\frac{1}{N} \sum_{i=1}^{N} \beta_{i} A S L_{1}\left(d_{i}\right) \\ &=\sum_{i=1}^{N} \frac{A S L_{1}\left(d_{i}\right)}{G D\left(g r_{i}\right)} \end{aligned} LGHM?R??=N1?i=1N?βi?ASL1?(di?)=i=1N?GD(gri?)ASL1?(di?)??

最后,補充一個mmdet關(guān)于GHM Loss的實現(xiàn),它是先將梯度模長劃分為bins個范圍,然后計算每個區(qū)域的便捷edges,接著就很容易判斷梯度模長落在哪個區(qū)間里了,然后按照公式計算權(quán)重乘以原來的交叉熵?fù)p失即可(實現(xiàn)思路和上面的Focal Loss差不多,都是對原本的交叉熵加權(quán))。

class GHMC(nn.Module):def __init__(self, bins=10, momentum=0, use_sigmoid=True, loss_weight=1.0):super(GHMC, self).__init__()self.bins = binsself.momentum = momentumedges = torch.arange(bins + 1).float() / binsself.register_buffer('edges', edges)self.edges[-1] += 1e-6if momentum > 0:acc_sum = torch.zeros(bins)self.register_buffer('acc_sum', acc_sum)self.use_sigmoid = use_sigmoidif not self.use_sigmoid:raise NotImplementedErrorself.loss_weight = loss_weightdef forward(self, pred, target, label_weight, *args, **kwargs):# the target should be binary class labelif pred.dim() != target.dim():target, label_weight = _expand_onehot_labels(target, label_weight, pred.size(-1))target, label_weight = target.float(), label_weight.float()edges = self.edgesmmt = self.momentumweights = torch.zeros_like(pred)# gradient lengthg = torch.abs(pred.sigmoid().detach() - target)valid = label_weight > 0tot = max(valid.float().sum().item(), 1.0)n = 0 # n valid binsfor i in range(self.bins):inds = (g >= edges[i]) & (g < edges[i + 1]) & validnum_in_bin = inds.sum().item()if num_in_bin > 0:if mmt > 0:self.acc_sum[i] = mmt * self.acc_sum[i] \+ (1 - mmt) * num_in_binweights[inds] = tot / self.acc_sum[i]else:weights[inds] = tot / num_in_binn += 1if n > 0:weights = weights / nloss = F.binary_cross_entropy_with_logits(pred, target, weights, reduction='sum') / totreturn loss * self.loss_weight

實驗

實驗配置等細(xì)節(jié)查看原文即可,我這里就給出SOTA方法的漲點結(jié)果圖,可以看到,相比于Focal Loss,漲點效果還是挺明顯的。

總結(jié)

這篇論文針對單階段目標(biāo)檢測的樣本不均衡問題從梯度出發(fā),提出了GHM這一策略,從損失的角度有效改善了此前的Focal Loss。本文也只是我本人從自身出發(fā)對這篇文章進(jìn)行的解讀,想要更詳細(xì)理解的強烈推薦閱讀原論文。最后,如果我的文章對你有所幫助,歡迎一鍵三連,你的支持是我不懈創(chuàng)作的動力。

總結(jié)

以上是生活随笔為你收集整理的GHM解读的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。