0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基礎(chǔ)積累:圖像分割損失函數(shù)最全面、最詳細(xì)總結(jié),含代碼

電子設(shè)計(jì) ? 來源:電子設(shè)計(jì) ? 作者:電子設(shè)計(jì) ? 2020-12-15 00:11 ? 次閱讀

作者:SFXiang
首發(fā):AI算法修煉營

這是一篇關(guān)于圖像分割損失函數(shù)的總結(jié),具體包括:

Binary Cross Entropy

Weighted Cross Entropy

Balanced Cross Entropy

Dice Loss

Focal loss

Tversky loss

Focal Tversky loss

log-cosh dice loss (本文提出的新?lián)p失函數(shù))

代碼地址:https://github.com/shruti-jadon/Semantic-Segmentation-Loss-Functions
項(xiàng)目推薦:https://github.com/JunMa11/SegLoss

圖像分割一直是一個(gè)活躍的研究領(lǐng)域,因?yàn)樗锌赡苄迯?fù)醫(yī)療領(lǐng)域的漏洞,并幫助大眾。在過去的5年里,各種論文提出了不同的目標(biāo)損失函數(shù),用于不同的情況下,如偏差數(shù)據(jù),稀疏分割等。在本文中,總結(jié)了大多數(shù)廣泛用于圖像分割的損失函數(shù),并列出了它們可以幫助模型更快速、更好的收斂模型的情況。此外,本文還介紹了一種新的log-cosh dice損失函數(shù),并將其在NBFS skull-stripping數(shù)據(jù)集上與廣泛使用的損失函數(shù)進(jìn)行了性能比較。某些損失函數(shù)在所有數(shù)據(jù)集上都表現(xiàn)良好,在未知分布數(shù)據(jù)集上可以作為一個(gè)很好的選擇。

簡介

深度學(xué)習(xí)徹底改變了從軟件到制造業(yè)的各個(gè)行業(yè)。深度學(xué)習(xí)在醫(yī)學(xué)界的應(yīng)用也十分廣泛,例如使用U-Net進(jìn)行腫瘤分割、使用SegNet進(jìn)行癌癥檢測(cè)等。在這些應(yīng)用中,圖像分割是至關(guān)重要的,分割后的圖像除了告訴我們存在某種疾病外,還展示了它到底存在于何處,這為實(shí)現(xiàn)自動(dòng)檢測(cè)CT掃描中的病變等功能提供基礎(chǔ)保障。

圖像分割可以定義為像素級(jí)別的分類任務(wù)。圖像由各種像素組成,這些像素組合在一起定義了圖像中的不同元素,因此將這些像素分類為一類元素的方法稱為語義圖像分割。在設(shè)計(jì)基于復(fù)雜圖像分割的深度學(xué)習(xí)架構(gòu)時(shí),通常會(huì)遇到了一個(gè)至關(guān)重要的選擇,即選擇哪個(gè)損失/目標(biāo)函數(shù),因?yàn)樗鼈儠?huì)激發(fā)算法的學(xué)習(xí)過程。損失函數(shù)的選擇對(duì)于任何架構(gòu)學(xué)習(xí)正確的目標(biāo)都是至關(guān)重要的,因此自2012年以來,各種研究人員開始設(shè)計(jì)針對(duì)特定領(lǐng)域的損失函數(shù),以為其數(shù)據(jù)集獲得更好的結(jié)果。

在本文中,總結(jié)了15種基于圖像分割的損失函數(shù)。被證明可以在不同領(lǐng)域提供最新技術(shù)成果。這些損失函數(shù)可大致分為4類:基于分布的損失函數(shù),基于區(qū)域的損失函數(shù),基于邊界的損失函數(shù)和基于復(fù)合的損失函數(shù)(Distribution-based,Region-based, Boundary-based, and Compounded)。

本文還討論了確定哪種目標(biāo)/損失函數(shù)在場(chǎng)景中可能有用的條件。除此之外,還提出了一種新的log-cosh dice損失函數(shù)用于圖像語義分割。為了展示其效率,還比較了NBFS頭骨剝離數(shù)據(jù)集上所有損失函數(shù)的性能。

Distribution-based loss

1. Binary Cross-Entropy:二進(jìn)制交叉熵?fù)p失函數(shù)

交叉熵定義為對(duì)給定隨機(jī)變量或事件集的兩個(gè)概率分布之間的差異的度量。它被廣泛用于分類任務(wù),并且由于分割是像素級(jí)分類,因此效果很好。在多分類任務(wù)中,經(jīng)常采用 softmax 激活函數(shù)+交叉熵?fù)p失函數(shù),因?yàn)榻徊骒孛枋隽藘蓚€(gè)概率分布的差異,然而神經(jīng)網(wǎng)絡(luò)輸出的是向量,并不是概率分布的形式。所以需要 softmax激活函數(shù)將一個(gè)向量進(jìn)行“歸一化”成概率分布的形式,再采用交叉熵?fù)p失函數(shù)計(jì)算 loss。

交叉熵?fù)p失函數(shù)可以用在大多數(shù)語義分割場(chǎng)景中,但它有一個(gè)明顯的缺點(diǎn):當(dāng)圖像分割任務(wù)只需要分割前景和背景兩種情況。當(dāng)前景像素的數(shù)量遠(yuǎn)遠(yuǎn)小于背景像素的數(shù)量時(shí),即的數(shù)量遠(yuǎn)大于的數(shù)量,損失函數(shù)中的成分就會(huì)占據(jù)主導(dǎo),使得模型嚴(yán)重偏向背景,導(dǎo)致效果不好。

#二值交叉熵,這里輸入要經(jīng)過sigmoid處理  
importtorch  
importtorch.nnasnn  
importtorch.nn.functionalasF  
nn.BCELoss(F.sigmoid(input),target)  
#多分類交叉熵,用這個(gè)loss前面不需要加Softmax層  
nn.CrossEntropyLoss(input,target)

2、Weighted Binary Cross-Entropy加權(quán)交叉熵?fù)p失函數(shù)

classWeightedCrossEntropyLoss(torch.nn.CrossEntropyLoss):  
"""  
NetworkhastohaveNONONLINEARITY!  
"""  
def__init__(self,weight=None):  
super(WeightedCrossEntropyLoss,self).__init__()  
self.weight=weight  
  
defforward(self,inp,target):  
target=target.long()  
num_classes=inp.size()[1]  
  
i0=1  
i1=2  
  
whilei1

3、Balanced Cross-Entropy平衡交叉熵?fù)p失函數(shù)

與加權(quán)交叉熵?fù)p失函數(shù)類似,但平衡交叉熵?fù)p失函數(shù)對(duì)負(fù)樣本也進(jìn)行加權(quán)。

4、Focal Loss

Focal loss是在目標(biāo)檢測(cè)領(lǐng)域提出來的。其目的是關(guān)注難例(也就是給難分類的樣本較大的權(quán)重)。對(duì)于正樣本,使預(yù)測(cè)概率大的樣本(簡單樣本)得到的loss變小,而預(yù)測(cè)概率小的樣本(難例)loss變得大,從而加強(qiáng)對(duì)難例的關(guān)注度。但引入了額外參數(shù),增加了調(diào)參難度。

classFocalLoss(nn.Module):  
"""  
copyfrom:https://github.com/Hsuxu/Loss_ToolBox-PyTorch/blob/master/FocalLoss/FocalLoss.py  
ThisisaimplementationofFocalLosswithsmoothlabelcrossentropysupportedwhichisproposedin  
'FocalLossforDenseObjectDetection.(https://arxiv.org/abs/1708.02002)'  
Focal_Loss=-1*alpha*(1-pt)*log(pt)  
:paramnum_class:  
:paramalpha:(tensor)3Dor4Dthescalarfactorforthiscriterion  
:paramgamma:(float,double)gamma>0reducestherelativelossforwell-classifiedexamples(p>0.5)puttingmore  
focusonhardmisclassifiedexample  
:paramsmooth:(float,double)smoothvaluewhencrossentropy  
:parambalance_index:(int)balanceclassindex,shouldbespecificwhenalphaisfloat  
:paramsize_average:(bool,optional)Bydefault,thelossesareaveragedovereachlosselementinthebatch.  
"""  
  
def__init__(self,apply_nonlin=None,alpha=None,gamma=2,balance_index=0,smooth=1e-5,size_average=True):  
super(FocalLoss,self).__init__()  
self.apply_nonlin=apply_nonlin  
self.alpha=alpha  
self.gamma=gamma  
self.balance_index=balance_index  
self.smooth=smooth  
self.size_average=size_average  
  
ifself.smoothisnotNone:  
ifself.smooth1.0:  
raiseValueError('smoothvalueshouldbein[0,1]')  
  
defforward(self,logit,target):  
ifself.apply_nonlinisnotNone:  
logit=self.apply_nonlin(logit)  
num_class=logit.shape[1]  
  
iflogit.dim()>2:  
#N,C,d1,d2->N,C,m(m=d1*d2*...)  
logit=logit.view(logit.size(0),logit.size(1),-1)  
logit=logit.permute(0,2,1).contiguous()  
logit=logit.view(-1,logit.size(-1))  
target=torch.squeeze(target,1)  
target=target.view(-1,1)  
#print(logit.shape,target.shape)  
#  
alpha=self.alpha  
  
ifalphaisNone:  
alpha=torch.ones(num_class,1)  
elifisinstance(alpha,(list,np.ndarray)):  
assertlen(alpha)==num_class  
alpha=torch.FloatTensor(alpha).view(num_class,1)  
alpha=alpha/alpha.sum()  
elifisinstance(alpha,float):  
alpha=torch.ones(num_class,1)  
alpha=alpha*(1-self.alpha)  
alpha[self.balance_index]=self.alpha  
  
else:  
raiseTypeError('Notsupportalphatype')  
  
ifalpha.device!=logit.device:  
alpha=alpha.to(logit.device)  
  
idx=target.cpu().long()  
  
one_hot_key=torch.FloatTensor(target.size(0),num_class).zero_()  
one_hot_key=one_hot_key.scatter_(1,idx,1)  
ifone_hot_key.device!=logit.device:  
one_hot_key=one_hot_key.to(logit.device)  
  
ifself.smooth:  
one_hot_key=torch.clamp(  
one_hot_key,self.smooth/(num_class-1),1.0-self.smooth)  
pt=(one_hot_key*logit).sum(1)+self.smooth  
logpt=pt.log()  
  
gamma=self.gamma  
  
alpha=alpha[idx]  
alpha=torch.squeeze(alpha)  
loss=-1*alpha*torch.pow((1-pt),gamma)*logpt  
  
ifself.size_average:  
loss=loss.mean()  
else:  
loss=loss.sum()  
returnloss

5、Distance map derived loss penalty term距離圖得出的損失懲罰項(xiàng)

可以將距離圖定義為ground truth與預(yù)測(cè)圖之間的距離(歐幾里得距離、絕對(duì)距離等)。合并映射的方法有2種,一種是創(chuàng)建神經(jīng)網(wǎng)絡(luò)架構(gòu),在該算法中有一個(gè)用于分割的重建head,或者將其引入損失函數(shù)。遵循相同的理論,可以從GT mask得出的距離圖,并創(chuàng)建了一個(gè)基于懲罰的自定義損失函數(shù)。使用這種方法,可以很容易地將網(wǎng)絡(luò)引導(dǎo)到難以分割的邊界區(qū)域。損失函數(shù)定義為:

classDisPenalizedCE(torch.nn.Module):  
"""  
Onlyforbinary3Dsegmentation  
NetworkhastohaveNONONLINEARITY!  
"""  
  
defforward(self,inp,target):  
#print(inp.shape,target.shape)#(batch,2,xyz),(batch,2,xyz)  
#computedistancemapofgroundtruth  
withtorch.no_grad():  
dist=compute_edts_forPenalizedLoss(target.cpu().numpy()>0.5)+1.0  
  
dist=torch.from_numpy(dist)  
ifdist.device!=inp.device:  
dist=dist.to(inp.device).type(torch.float32)  
dist=dist.view(-1,)  
  
target=target.long()  
num_classes=inp.size()[1]  
  
i0=1  
i1=2  
  
whilei1

Region-based loss

1、Dice Loss

Dice系數(shù)是計(jì)算機(jī)視覺界廣泛使用的度量標(biāo)準(zhǔn),用于計(jì)算兩個(gè)圖像之間的相似度。在2016年的時(shí)候,它也被改編為損失函數(shù),稱為Dice損失。

defget_tp_fp_fn(net_output,gt,axes=None,mask=None,square=False):  
"""  
net_outputmustbe(b,c,x,y(,z)))  
gtmustbealabelmap(shape(b,1,x,y(,z))ORshape(b,x,y(,z)))oronehotencoding(b,c,x,y(,z))  
ifmaskisprovideditmusthaveshape(b,1,x,y(,z)))  
:paramnet_output:  
:paramgt:  
:paramaxes:  
:parammask:maskmustbe1forvalidpixelsand0forinvalidpixels  
:paramsquare:ifTruethenfp,tpandfnwillbesquaredbeforesummation  
:return:  
"""  
ifaxesisNone:  
axes=tuple(range(2,len(net_output.size())))  
  
shp_x=net_output.shape  
shp_y=gt.shape  
  
withtorch.no_grad():  
iflen(shp_x)!=len(shp_y):  
gt=gt.view((shp_y[0],1,*shp_y[1:]))  
  
ifall([i==jfori,jinzip(net_output.shape,gt.shape)]):  
#ifthisisthecasethengtisprobablyalreadyaonehotencoding  
y_onehot=gt  
else:  
gt=gt.long()  
y_onehot=torch.zeros(shp_x)  
ifnet_output.device.type=="cuda":  
y_onehot=y_onehot.cuda(net_output.device.index)  
y_onehot.scatter_(1,gt,1)  
  
tp=net_output*y_onehot  
fp=net_output*(1-y_onehot)  
fn=(1-net_output)*y_onehot  
  
ifmaskisnotNone:  
tp=torch.stack(tuple(x_i*mask[:,0]forx_iintorch.unbind(tp,dim=1)),dim=1)  
fp=torch.stack(tuple(x_i*mask[:,0]forx_iintorch.unbind(fp,dim=1)),dim=1)  
fn=torch.stack(tuple(x_i*mask[:,0]forx_iintorch.unbind(fn,dim=1)),dim=1)  
  
ifsquare:  
tp=tp**2  
fp=fp**2  
fn=fn**2  
  
tp=sum_tensor(tp,axes,keepdim=False)  
fp=sum_tensor(fp,axes,keepdim=False)  
fn=sum_tensor(fn,axes,keepdim=False)  
  
returntp,fp,fn  
  
  
classSoftDiceLoss(nn.Module):  
def__init__(self,apply_nonlin=None,batch_dice=False,do_bg=True,smooth=1.,  
square=False):  
"""  
paper:https://arxiv.org/pdf/1606.04797.pdf  
"""  
super(SoftDiceLoss,self).__init__()  
  
self.square=square  
self.do_bg=do_bg  
self.batch_dice=batch_dice  
self.apply_nonlin=apply_nonlin  
self.smooth=smooth  
  
defforward(self,x,y,loss_mask=None):  
shp_x=x.shape  
  
ifself.batch_dice:  
axes=[0]+list(range(2,len(shp_x)))  
else:  
axes=list(range(2,len(shp_x)))  
  
ifself.apply_nonlinisnotNone:  
x=self.apply_nonlin(x)  
  
tp,fp,fn=get_tp_fp_fn(x,y,axes,loss_mask,self.square)  
  
dc=(2*tp+self.smooth)/(2*tp+fp+fn+self.smooth)  
  
ifnotself.do_bg:  
ifself.batch_dice:  
dc=dc[1:]  
else:  
dc=dc[:,1:]  
dc=dc.mean()  
  
return-dc

2、Tversky Loss

Tversky系數(shù)是Dice系數(shù)和 Jaccard 系數(shù)的一種推廣。當(dāng)設(shè)置α=β=0.5,此時(shí)Tversky系數(shù)就是Dice系數(shù)。而當(dāng)設(shè)置α=β=1時(shí),此時(shí)Tversky系數(shù)就是Jaccard系數(shù)。α和β分別控制假陰性和假陽性。通過調(diào)整α和β,可以控制假陽性和假陰性之間的平衡。

classTverskyLoss(nn.Module):  
def__init__(self,apply_nonlin=None,batch_dice=False,do_bg=True,smooth=1.,  
square=False):  
"""  
paper:https://arxiv.org/pdf/1706.05721.pdf  
"""  
super(TverskyLoss,self).__init__()  
  
self.square=square  
self.do_bg=do_bg  
self.batch_dice=batch_dice  
self.apply_nonlin=apply_nonlin  
self.smooth=smooth  
self.alpha=0.3  
self.beta=0.7  
  
defforward(self,x,y,loss_mask=None):  
shp_x=x.shape  
  
ifself.batch_dice:  
axes=[0]+list(range(2,len(shp_x)))  
else:  
axes=list(range(2,len(shp_x)))  
  
ifself.apply_nonlinisnotNone:  
x=self.apply_nonlin(x)  
  
tp,fp,fn=get_tp_fp_fn(x,y,axes,loss_mask,self.square)  
  
  
tversky=(tp+self.smooth)/(tp+self.alpha*fp+self.beta*fn+self.smooth)  
  
ifnotself.do_bg:  
ifself.batch_dice:  
tversky=tversky[1:]  
else:  
tversky=tversky[:,1:]  
tversky=tversky.mean()  
  
return-tversky  

3、Focal Tversky Loss

與“Focal loss”相似,后者著重于通過降低易用/常見損失的權(quán)重來說明困難的例子。Focal Tversky Loss還嘗試借助γ系數(shù)來學(xué)習(xí)諸如在ROI(感興趣區(qū)域)較小的情況下的困難示例,如下所示:

classFocalTversky_loss(nn.Module):  
"""  
paper:https://arxiv.org/pdf/1810.07842.pdf  
authorcode:https://github.com/nabsabraham/focal-tversky-unet/blob/347d39117c24540400dfe80d106d2fb06d2b99e1/losses.py#L65  
"""  
def__init__(self,tversky_kwargs,gamma=0.75):  
super(FocalTversky_loss,self).__init__()  
self.gamma=gamma  
self.tversky=TverskyLoss(**tversky_kwargs)  
  
defforward(self,net_output,target):  
tversky_loss=1+self.tversky(net_output,target)#=1-tversky(net_output,target)  
focal_tversky=torch.pow(tversky_loss,self.gamma)  
returnfocal_tversky  

4、Sensitivity Specificity Loss

首先敏感性就是召回率,檢測(cè)出確實(shí)有病的能力:

特異性,檢測(cè)出確實(shí)沒病的能力:

而Sensitivity Specificity Loss為:

classSSLoss(nn.Module):  
def__init__(self,apply_nonlin=None,batch_dice=False,do_bg=True,smooth=1.,  
square=False):  
"""  
Sensitivity-Specifityloss  
paper:http://www.rogertam.ca/Brosch_MICCAI_2015.pdf  
tfcode:https://github.com/NifTK/NiftyNet/blob/df0f86733357fdc92bbc191c8fec0dcf49aa5499/niftynet/layer/loss_segmentation.py#L392  
"""  
super(SSLoss,self).__init__()  
  
self.square=square  
self.do_bg=do_bg  
self.batch_dice=batch_dice  
self.apply_nonlin=apply_nonlin  
self.smooth=smooth  
self.r=0.1#weightparameterinSSpaper  
  
defforward(self,net_output,gt,loss_mask=None):  
shp_x=net_output.shape  
shp_y=gt.shape  
#class_num=shp_x[1]  
  
withtorch.no_grad():  
iflen(shp_x)!=len(shp_y):  
gt=gt.view((shp_y[0],1,*shp_y[1:]))  
  
ifall([i==jfori,jinzip(net_output.shape,gt.shape)]):  
#ifthisisthecasethengtisprobablyalreadyaonehotencoding  
y_onehot=gt  
else:  
gt=gt.long()  
y_onehot=torch.zeros(shp_x)  
ifnet_output.device.type=="cuda":  
y_onehot=y_onehot.cuda(net_output.device.index)  
y_onehot.scatter_(1,gt,1)  
  
ifself.batch_dice:  
axes=[0]+list(range(2,len(shp_x)))  
else:  
axes=list(range(2,len(shp_x)))  
  
ifself.apply_nonlinisnotNone:  
softmax_output=self.apply_nonlin(net_output)  
  
#noobjectvalue  
bg_onehot=1-y_onehot  
squared_error=(y_onehot-softmax_output)**2  
specificity_part=sum_tensor(squared_error*y_onehot,axes)/(sum_tensor(y_onehot,axes)+self.smooth)  
sensitivity_part=sum_tensor(squared_error*bg_onehot,axes)/(sum_tensor(bg_onehot,axes)+self.smooth)  
  
ss=self.r*specificity_part+(1-self.r)*sensitivity_part  
  
ifnotself.do_bg:  
ifself.batch_dice:  
ss=ss[1:]  
else:  
ss=ss[:,1:]  
ss=ss.mean()  
  
returnss

5、Log-Cosh Dice Loss(本文提出的損失函數(shù))

Dice系數(shù)是一種用于評(píng)估分割輸出的度量標(biāo)準(zhǔn)。它也已修改為損失函數(shù),因?yàn)樗梢詫?shí)現(xiàn)分割目標(biāo)的數(shù)學(xué)表示。但是由于其非凸性,它多次都無法獲得最佳結(jié)果。Lovsz-softmax損失旨在通過添加使用Lovsz擴(kuò)展的平滑來解決非凸損失函數(shù)的問題。同時(shí),Log-Cosh方法已廣泛用于基于回歸的問題中,以平滑曲線。

將Cosh(x)函數(shù)和Log(x)函數(shù)合并,可以得到Log-Cosh Dice Loss:

deflog_cosh_dice_loss(self,y_true,y_pred):  
x=self.dice_loss(y_true,y_pred)  
returntf.math.log((torch.exp(x)+torch.exp(-x))/2.0)  

Boundary-based loss

1、Shape-aware Loss

顧名思義,Shape-aware Loss考慮了形狀。通常,所有損失函數(shù)都在像素級(jí)起作用,Shape-aware Loss會(huì)計(jì)算平均點(diǎn)到曲線的歐幾里得距離,即預(yù)測(cè)分割到ground truth的曲線周圍點(diǎn)之間的歐式距離,并將其用作交叉熵?fù)p失函數(shù)的系數(shù),具體定義如下:(CE指交叉熵?fù)p失函數(shù))

classDistBinaryDiceLoss(nn.Module):  
"""  
DistancemappenalizedDiceloss  
Motivatedby:https://openreview.net/forum?id=B1eIcvS45V  
DistanceMapLossPenaltyTermforSemanticSegmentation  
"""  
def__init__(self,smooth=1e-5):  
super(DistBinaryDiceLoss,self).__init__()  
self.smooth=smooth  
  
defforward(self,net_output,gt):  
"""  
net_output:(batch_size,2,x,y,z)  
target:groundtruth,shape:(batch_size,1,x,y,z)  
"""  
net_output=softmax_helper(net_output)  
#onehotcodeforgt  
withtorch.no_grad():  
iflen(net_output.shape)!=len(gt.shape):  
gt=gt.view((gt.shape[0],1,*gt.shape[1:]))  
  
ifall([i==jfori,jinzip(net_output.shape,gt.shape)]):  
#ifthisisthecasethengtisprobablyalreadyaonehotencoding  
y_onehot=gt  
else:  
gt=gt.long()  
y_onehot=torch.zeros(net_output.shape)  
ifnet_output.device.type=="cuda":  
y_onehot=y_onehot.cuda(net_output.device.index)  
y_onehot.scatter_(1,gt,1)  
  
gt_temp=gt[:,0,...].type(torch.float32)  
withtorch.no_grad():  
dist=compute_edts_forPenalizedLoss(gt_temp.cpu().numpy()>0.5)+1.0  
#print('dist.shape:',dist.shape)  
dist=torch.from_numpy(dist)  
  
ifdist.device!=net_output.device:  
dist=dist.to(net_output.device).type(torch.float32)  
  
tp=net_output*y_onehot  
tp=torch.sum(tp[:,1,...]*dist,(1,2,3))  
  
dc=(2*tp+self.smooth)/(torch.sum(net_output[:,1,...],(1,2,3))+torch.sum(y_onehot[:,1,...],(1,2,3))+self.smooth)  
  
dc=dc.mean()  
  
return-dc  

2、Hausdorff Distance Loss

Hausdorff Distance Loss(HD)是分割方法用來跟蹤模型性能的度量。

任何分割模型的目的都是為了最大化Hausdorff距離,但是由于其非凸性,因此并未廣泛用作損失函數(shù)。有研究者提出了基于Hausdorff距離的損失函數(shù)的3個(gè)變量,它們都結(jié)合了度量用例,并確保損失函數(shù)易于處理。

classHDDTBinaryLoss(nn.Module):  
def__init__(self):  
"""  
computehaudorfflossforbinarysegmentation  
https://arxiv.org/pdf/1904.10030v1.pdf  
"""  
super(HDDTBinaryLoss,self).__init__()  
  
  
defforward(self,net_output,target):  
"""  
net_output:(batch_size,2,x,y,z)  
target:groundtruth,shape:(batch_size,1,x,y,z)  
"""  
net_output=softmax_helper(net_output)  
pc=net_output[:,1,...].type(torch.float32)  
gt=target[:,0,...].type(torch.float32)  
withtorch.no_grad():  
pc_dist=compute_edts_forhdloss(pc.cpu().numpy()>0.5)  
gt_dist=compute_edts_forhdloss(gt.cpu().numpy()>0.5)  
#print('pc_dist.shape:',pc_dist.shape)  
  
pred_error=(gt-pc)**2  
dist=pc_dist**2+gt_dist**2#/alpha=2ineq(8)  
  
dist=torch.from_numpy(dist)  
ifdist.device!=pred_error.device:  
dist=dist.to(pred_error.device).type(torch.float32)  
  
multipled=torch.einsum("bxyz,bxyz->bxyz",pred_error,dist)  
hd_loss=multipled.mean()  
  
returnhd_loss

Compounded loss

1、Exponential Logarithmic Loss

指數(shù)對(duì)數(shù)損失函數(shù)集中于使用骰子損失和交叉熵?fù)p失的組合公式來預(yù)測(cè)不那么精確的結(jié)構(gòu)。對(duì)骰子損失和熵?fù)p失進(jìn)行指數(shù)和對(duì)數(shù)轉(zhuǎn)換,以合并更精細(xì)的分割邊界和準(zhǔn)確的數(shù)據(jù)分布的好處。它定義為:

2、Combo Loss

組合損失定義為Dice loss和修正的交叉熵的加權(quán)和。它試圖利用Dice損失解決類不平衡問題的靈活性,同時(shí)使用交叉熵進(jìn)行曲線平滑。定義為:(DL指Dice Loss)

審核編輯 黃昊宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 圖像分割
    +關(guān)注

    關(guān)注

    4

    文章

    180

    瀏覽量

    17930
  • 深度學(xué)習(xí)
    +關(guān)注

    關(guān)注

    73

    文章

    5422

    瀏覽量

    120593
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    圖像分割圖像定位的c語言算法代碼

    各位大哥,誰能幫小弟介紹一些有圖像分割圖像定位的c語言代碼的資料,萬分感謝。小弟最近在研究圖像方面的東西,可是書上講的大多是理論,具體
    發(fā)表于 12-16 09:18

    【Firefly RK3399試用體驗(yàn)】之三——基于閾值的圖像分割

    。下面結(jié)合SimpleCV中的binarize()函數(shù)進(jìn)行圖像的二值化分割,這個(gè)函數(shù)利用Otsu算法來進(jìn)行圖像
    發(fā)表于 07-06 20:30

    TensorFlow損失函數(shù)(定義和使用)詳解

    的情況下,損失函數(shù)定義為交叉熵。輸出 Y 的維數(shù)等于訓(xùn)練數(shù)據(jù)集中類別的數(shù)量,其中 P 為類別數(shù)量:如果想把 L1 正則化加到損失上,那么代碼如下:對(duì)于 L2 正則化,
    發(fā)表于 07-28 14:38

    圖像分割—基于圖的圖像分割

    圖像分割—基于圖的圖像分割圖像分割—基于圖的圖像
    發(fā)表于 11-19 16:17 ?0次下載

    基于Matlab圖像分割的研究

    特性的分割、邊緣分割、指紋圖像分割方法進(jìn)行了詳細(xì)的分析比較,分別對(duì)這些方法進(jìn)行了圖像仿真,并分
    發(fā)表于 01-04 15:10 ?0次下載

    圖像分割圖像邊緣檢測(cè)

     圖像分割的研究多年來一直受到人們的高度重視,至今提出了各種類型的分割算法。Pal把圖像分割算法分成了6類:閾值
    發(fā)表于 12-19 09:29 ?1.1w次閱讀
    <b class='flag-5'>圖像</b><b class='flag-5'>分割</b>和<b class='flag-5'>圖像</b>邊緣檢測(cè)

    圖像分割的基本方法解析

    本文詳細(xì)介紹了圖像分割的基本方法有:基于邊緣的圖像分割方法、閾值分割方法、區(qū)域
    發(fā)表于 12-20 11:06 ?10.9w次閱讀
    <b class='flag-5'>圖像</b><b class='flag-5'>分割</b>的基本方法解析

    基于水平集的牙齒CT圖像分割技術(shù)

    水平集函數(shù)中各能量項(xiàng)進(jìn)行研究,并通過對(duì)比實(shí)驗(yàn)體現(xiàn)水平集方法的優(yōu)越性。基于水平集的牙齒CT圖像分割方法中水平集函數(shù)的能量項(xiàng)主要包括:競(jìng)爭(zhēng)能量項(xiàng)、梯度能量項(xiàng)、形狀約束能量項(xiàng)、全局先驗(yàn)灰度能
    發(fā)表于 12-22 15:57 ?2次下載
    基于水平集的牙齒CT<b class='flag-5'>圖像</b><b class='flag-5'>分割</b>技術(shù)

    基于內(nèi)容的圖像分割方法綜述

    的方法、基于像素聚類的方法和語義分割方法這3種類型并分別加以介紹對(duì)每類方法所包含的典型算法,尤其是最近幾年利用深度網(wǎng)絡(luò)技術(shù)的語義圖像分割方法的基本思想、優(yōu)缺點(diǎn)進(jìn)行了分析、對(duì)比和總結(jié).介
    發(fā)表于 01-02 16:52 ?2次下載
    基于內(nèi)容的<b class='flag-5'>圖像</b><b class='flag-5'>分割</b>方法綜述

    分析總結(jié)基于深度神經(jīng)網(wǎng)絡(luò)的圖像語義分割方法

    隨著深度學(xué)習(xí)技術(shù)的快速發(fā)展及其在語義分割領(lǐng)域的廣泛應(yīng)用,語義分割效果得到顯著提升。對(duì)基于深度神經(jīng)網(wǎng)絡(luò)的圖像語義分割方法進(jìn)行分析與總結(jié),根據(jù)網(wǎng)
    發(fā)表于 03-19 14:14 ?21次下載
    分析<b class='flag-5'>總結(jié)</b>基于深度神經(jīng)網(wǎng)絡(luò)的<b class='flag-5'>圖像</b>語義<b class='flag-5'>分割</b>方法

    沒你想的那么難 | 一文讀懂圖像分割

    DerrickMwiti在一篇文章中,就什么是圖像分割圖像分割架構(gòu)、圖像分割
    的頭像 發(fā)表于 05-16 09:21 ?783次閱讀
    沒你想的那么難 | 一文讀懂<b class='flag-5'>圖像</b><b class='flag-5'>分割</b>

    什么是圖像分割?圖像分割的體系結(jié)構(gòu)和方法

    圖像分割(Image Segmentation)是計(jì)算機(jī)視覺領(lǐng)域中的一項(xiàng)重要基礎(chǔ)技術(shù),是圖像理解中的重要一環(huán)。前端時(shí)間,數(shù)據(jù)科學(xué)家Derrick Mwiti在一篇文章中,就什么是圖像
    的頭像 發(fā)表于 08-18 10:34 ?4634次閱讀
    什么是<b class='flag-5'>圖像</b><b class='flag-5'>分割</b>?<b class='flag-5'>圖像</b><b class='flag-5'>分割</b>的體系結(jié)構(gòu)和方法

    最全綜述:圖像分割算法

    閾值法的基本思想是基于圖像的灰度特征來計(jì)算一個(gè)或多個(gè)灰度閾值,并將圖像中每個(gè)像素的灰度值與閾值作比較,最后將像素根據(jù)比較結(jié)果分到合適的類別中。因此,該方法最為關(guān)鍵的一步就是按照某個(gè)準(zhǔn)則函數(shù)來求解最佳灰度閾值。
    的頭像 發(fā)表于 11-03 16:04 ?622次閱讀
    <b class='flag-5'>最全</b>綜述:<b class='flag-5'>圖像</b><b class='flag-5'>分割</b>算法

    圖像分割與語義分割中的CNN模型綜述

    圖像分割與語義分割是計(jì)算機(jī)視覺領(lǐng)域的重要任務(wù),旨在將圖像劃分為多個(gè)具有特定語義含義的區(qū)域或?qū)ο?。卷積神經(jīng)網(wǎng)絡(luò)(CNN)作為深度學(xué)習(xí)的一種核心模型,在
    的頭像 發(fā)表于 07-09 11:51 ?340次閱讀

    圖像分割和語義分割的區(qū)別與聯(lián)系

    圖像分割和語義分割是計(jì)算機(jī)視覺領(lǐng)域中兩個(gè)重要的概念,它們?cè)?b class='flag-5'>圖像處理和分析中發(fā)揮著關(guān)鍵作用。 1. 圖像
    的頭像 發(fā)表于 07-17 09:55 ?330次閱讀