論文信息
論文題目:Referring Camouflaged Object Detection
論文鏈接:https://arxiv.org/pdf/2306.07532
代碼鏈接:https://github.com/zhangxuying1004/RefCOD
錄用期刊:TPAMI 2025
論文單位:南開大學
ps:下文中為論文翻譯及本人解讀相結合(一些論文中說的比較清楚的就直接用原話了,有的地方我自己解釋了下,也不是照搬原文的)
摘要
我們考慮參考偽裝物體檢測(Ref-COD)的問題,這是一個新任務,旨在基于一組包含顯著目標物體的參考圖像分割指定的偽裝物體。我們首先組裝了一個大規模數據集,稱為R2C7K,它包含7K張圖像,覆蓋現實場景中的64個物體類別。然后,我們開發了一個簡單但強大的雙分支框架,命名為R2CNet,其中參考分支嵌入來自參考圖像的目標物體共同表示,分割分支在共同表示的指導下識別和分割偽裝物體。特別地,我們設計了一個參考掩碼生成(RMG)模塊來生成像素級先驗掩碼和一個參考特征增強(RFE)模塊來增強識別指定偽裝物體的能力。廣泛的實驗表明,我們的Ref-COD方法在分割指定偽裝物體和識別目標物體主體方面優于其COD對應方法。我們的代碼和數據集公開在https://github.com/zhangxuying1004/RefCOD
引言
引言部分就是介紹了一下COD的背景,但是本文做的“參考-偽裝物體檢測”其實是一個新的任務或者說一類新方法吧,所以作者在引言中給出的使用場景是:
一個典型例子是探險者尋找特定物種,但大多數物種可能與其他類似物體一起深藏。在這種情況下,如果我們有關于目標的參考信息,尋找過程將變得有方向性且更容易。
emm,這個理由感覺也不是太站得住腳?
但總之:Ref-COD利用參考信息指導指定偽裝物體的識別
關鍵問題在于哪種形式的信息適合作為參考。本文選的是顯著物體。理由如下:
現有的方法有基于文本參考的參考表達分割[11],和基于圖像參考的少樣本分割[12]。
然而,無論是包含指定偽裝物體的標注圖像,還是現有圖像的詳細文本描述,其獲取過程都耗時費力,阻礙了這些方法向COD的遷移。考慮到網上很容易找到帶顯著目標的圖像,我們提出一個簡單問題:我們能否利用突出物體的圖像來幫助更好地識別指定偽裝物體?
受此問題啟發,我們提出一個新穎的Ref-COD基準。我們的意圖是利用日益先進的顯著物體檢測(SOD)研究,從參考圖像中獲取目標物體的共同表示,用于指導指定偽裝物體的分割。圖1說明了標準COD與我們Ref-COD之間的任務關系。
具體來說,Ref-COD將COD過程從盲目檢測偽裝場景中的差異物體,轉變為有目的地匹配目標物體。
為了全面研究這一新基準,我們構建了一個大規模數據集,命名為R2C7K,其中包含大量無版權爭議的現實場景樣本。該數據集的基本信息如下:
1)它包含7K張圖像,覆蓋64個物體類別;
2)它由兩個子集組成,即包含偽裝物體的圖像組成的Camo子集和包含顯著物體的圖像組成的Ref子集;
3)Ref子集中每個類別的圖像數量固定,而Camo子集中的則不固定。
為了研究參考信息在Ref-COD中的作用,我們設計了一個雙分支網絡架構,并開發了一個簡單但有效的框架,命名為R2CNet。
該框架包括一個參考分支和一個分割分支。
參考分支旨在從包含顯著物體的參考圖像中捕獲目標物體的共同表示,這些表示將用于識別指定偽裝物體。
特別地,我們構建了一個參考掩碼生成(RMG)模塊來生成像素級參考信息。在該模塊中,參考分支的共同表示與分割分支的視覺特征在每個位置進行密集比較,以生成參考先驗掩碼。
然而,即使屬于同一類別,偽裝物體與顯著物體之間可能存在外觀差異,這可能增加準確識別偽裝物體的難度。為了克服這一缺點,我們采用雙源信息融合策略來消除兩個信息源之間的差異。
此外,我們還設計了一個參考特征增強(RFE)模塊,在參考掩碼指導下實現多尺度視覺特征之間的交互,并進一步突出目標物體。
總結而言,本文的貢獻可歸納如下:
- 我們提出了一個新基準,稱為Ref-COD。據我們所知,這是首次嘗試橋接SOD和COD,并利用顯著物體圖像分割指定偽裝物體。
- 我們構建了一個大規模數據集,命名為R2C7K,可為Ref-COD研究提供數據基礎和更深見解。
- 我們設計了一個用于Ref-COD研究的新框架,命名為R2CNet,其優異的實驗結果表明它為這一新主題提供了有效解決方案。
相關工作
首先介紹COD,然后介紹SOD主,最后描述不同參考信息形式的參考物體分割研究。
前面倆不說了,看下這個參考物體分割
參考物體分割意味著在給定圖像中基于某種形式的參考(例如圖像和文本)分割視覺物體。
介紹了兩種做法:少樣本分割和文本參考
少樣本分割(FSS)探索基于包含同一類別物體的標注圖像指導的物體分割。模型在大量像素標記為基礎類的圖像(查詢集)上訓練,并在給定少量標注樣本(支持集)的情況下對未見類進行密集像素預測。特別地,大多數現有FSS網絡包括兩個分支,即支持分支和查詢分支,以提取支持圖像和查詢圖像的特征,并實現它們之間的交互。FSS研究的開創性工作由[68]提出,其中支持分支直接預測分割查詢分支最后一層的權重。然后,[69]提出掩碼平均池化操作以提取代表性支持特征,這被后續工作廣泛采用。最近,大量工作[12],[70],[71]在凍結骨干網絡上構建強大模塊,以提升模型對未見類別的適應性。
參考表達分割(RES)探索基于文本表達的物體分割。RES旨在基于表達分割視覺物體,其網絡也采用雙分支架構。首個工作由[11]引入,其中視覺和語言特征分別由視覺編碼器和語言編碼器提取,其拼接用于生成分割掩碼。隨后,一系列基于多級視覺特征[72]、多模態LSTM[73]、注意力機制[74],[75]、協作網絡[76]的方法相繼融入RES,以生成高質量結果。此外,[77]采用文本描述作為參考,以豐富圖像內容實現更好的固定預測。
在本文中,提出的Ref-COD也屬于參考物體分割任務。然而,與現有方法不同,其參考信息的收集不費力。具體來說,它既不需要收集包含目標偽裝物體的罕見且難標注圖像,也不需要為現有COD數據集標注詳細文本描述,這便于學術界和工業界跟進。
數據集
R2C7K數據集包含6,615個樣本,覆蓋64個類別,其中Camo子集由5,015個樣本組成,Ref子集有1,600個樣本。注意,該數據集的每個類別包含固定數量的參考圖像(即25張),而每個類別中的COD圖像數量分布不均。
對于Ref子集,每個類別隨機選擇20個樣本用于訓練,剩余5個樣本用于測試;對于Camo子集,來自COD10K訓練集的樣本也用于訓練,屬于測試集的樣本用于測試。來自NC4K的樣本隨機分配到訓練和測試集,以確保這兩個劃分中每個類別至少包含6個樣本。
框架
我們的R2CNet框架的總體架構,由兩個分支組成,即綠色的參考分支和橙色的分割分支。在參考分支中,通過將視覺特征與SOD網絡生成的前景圖進行掩蔽和合并,從圖像中獲得指定對象的共同表示。在分割分支中,使用編碼器最后三層的視覺特征來表示給定的圖像。然后,在設計良好的RMG模塊中融合并比較這兩種特征表示,以生成掩模先驗,該先驗用于豐富不同尺度之間的視覺特征,以突出我們RFE模塊中的偽裝目標。最后,將豐富的特征輸入解碼器以生成最終的分割圖。
概述:
- 輸入分為兩部分,第一部分是包含偽裝物體的圖像,記作IcamoI^{camo}Icamo,另一部分包含少量顯著目標物體的參考圖像,記作IrefI^{ref}Iref,共有K張,{Iiref}i=1K\{I^{ref}_i\}^K_{i=1}{Iiref?}i=1K?。其中IcamoI^{camo}Icamo來自數據集的Camo子集,包含指定類別c的偽裝物體,同時IrefI^{ref}Iref來自Ref子集,其顯著物體屬于類別c。
- Ref-COD的輸出是一個二值掩碼MsegM^{seg}Mseg,用于IcamoI^{camo}Icamo中類別c的偽裝物體。
具體來說:
參考圖像分支:
輸入圖像后,編碼器和解碼器分別得到兩個特征,記作 {Fkref}k=1K\{F_{k}^{ref}\}_{k=1}^{K}{Fkref?}k=1K?和{Mkref}k=1K\{M_{k}^{ref}\}_{k=1}^{K}{Mkref?}k=1K?。把編碼器得到的特征稱為視覺特征,大小為H32×W32\frac{H}{32} \times \frac{W}{32}32H?×32W? ,解碼器得到的稱為前景掩碼。
這兩個特征,送入MAP模塊(masked average pooling ,MAP)
MAP函數是參考分支中的核心操作,用于從參考圖像中提取目標物體的共同表示。
首先使用雙線性下采樣操作Fdown(?)\mathcal{F}_{\text{down}}(\cdot)Fdown?(?)對前景掩碼 {Mkref}k=1K\{M_{k}^{ref}\}_{k=1}^{K}{Mkref?}k=1K?進行下采樣,采樣到和視覺特征一樣大小H32×W32\frac{H}{32} \times \frac{W}{32}32H?×32W?,然后與視覺特征逐元素相乘,隨后沿空間維度求和,得到掩碼區域的聚合特征,最后使用1x1卷積進行通道壓縮
最后對FkobjF^{obj}_kFkobj?做平均池化,得到最終輸出: E∈Rcd×1×1E \in \mathbb{R}^{c_d \times 1 \times 1}E∈Rcd?×1×1 是目標物體的嵌入向量,用于指導分割分支定位指定偽裝物體。
ps:這一部分是離線計算完成的,作者先對這些顯著物體圖像進行特征提取,使用的網絡是ICON-R,提取完了特征做了MAP計算之后,直接把這些特征存儲在本地,在訓練網絡的過程中直接從本地讀取。
├── R2C7K ├── Camo ├── train # training set of camo-subset with 64 categories. └── test # tesing set of camo-subset with 64 categories. ├── Ref ├── Images # all images of ref-subset with 64 categories.├── RefFeat_ICON-R # all object representations of ref-subset with 64 categories. └── Saliency_ICON-R # all foreground maps of ref-subset with 64 categories.
看數據結構,其中RefFeat_ICON-R就是事先存儲好的特征,訓練時候直接讀取。
分割分支:
分割分支也是編碼器-解碼器結構。
作者在論文中說,這里編碼器直接用的resnet50
“事實上,我們發現在所提方案下,即使一個簡單的分割網絡也能表現良好。因此,采用ResNet-50[84]作為編碼器,并選擇其后三層的特征作為視覺表示”
解碼器也很簡單,是一個卷積頭,由兩個卷積層組成用于識別偽裝物體。
重點是,兩個新模塊,即參考掩碼生成(RMG)和參考特征增強(RFE),它們添加在編碼器和解碼器之間,以利用參考分支的共同表示來顯式分割偽裝目標。
編碼器的后三層特征,記作2 3 4:
這些特征與參考分支的輸出一起輸入RMG模塊,以生成融合特征和參考掩碼。
RMG模塊
首先是一個8維的相對位置編碼:
受多模態融合近期工作[72],[85]的啟發,我們通過在共同表示和視覺特征之間執行雙源信息融合(DSF),具體來說,視覺特征的每個位置與一個8維嵌入向量拼接,
?
def _make_coord(self, batch, height, width):xv, yv = torch.meshgrid([torch.arange(0,height), torch.arange(0,width)])xv_min = (xv.float()*2 - width)/widthyv_min = (yv.float()*2 - height)/heightxv_max = ((xv+1).float()*2 - width)/widthyv_max = ((yv+1).float()*2 - height)/heightxv_ctr = (xv_min+xv_max)/2yv_ctr = (yv_min+yv_max)/2hmap = torch.ones(height, width)*(1./height)wmap = torch.ones(height, width)*(1./width)coord = torch.autograd.Variable(torch.cat([xv_min.unsqueeze(0), yv_min.unsqueeze(0),\xv_max.unsqueeze(0), yv_max.unsqueeze(0),\xv_ctr.unsqueeze(0), yv_ctr.unsqueeze(0),\hmap.unsqueeze(0), wmap.unsqueeze(0)], dim=0))coord = coord.unsqueeze(0).repeat(batch,1,1,1)return coord
位置編碼直接與視覺特征cat起來,
然后就是仿射變換# y = gamma * x + beta
其中這個gamma和beta呢都是由E生成的(E就是參考分支的特征)
代碼:
# y = gamma * x + betabeta2 = torch.tanh(self.beta_proj2(ref_x.squeeze())).view(bs, -1, 1, 1).expand_as(x2)gamma2 = torch.tanh(self.gamma_proj2(ref_x.squeeze())).view(bs, -1, 1, 1).expand_as(x2)beta3 = torch.tanh(self.beta_proj3(ref_x.squeeze())).view(bs, -1, 1, 1).expand_as(x3)gamma3 = torch.tanh(self.gamma_proj3(ref_x.squeeze())).view(bs, -1, 1, 1).expand_as(x3)beta4 = torch.tanh(self.beta_proj4(ref_x.squeeze())).view(bs, -1, 1, 1).expand_as(x4)gamma4 = torch.tanh(self.gamma_proj4(ref_x.squeeze())).view(bs, -1, 1, 1).expand_as(x4)x2 = self.fusion_process2(F.relu(gamma2 * x2 + beta2))x3 = self.fusion_process3(F.relu(gamma3 * x3 + beta3))x4 = self.fusion_process4(F.relu(gamma4 * x4 + beta4))
然后就是多尺度融合,就是自底向上融合,只不過融合的時候使用的是ConvLSTM
# MSFx4_h, x4_c = self.upsample4(x4), self.upsample4(x4)x3_h, x3_c = self.lstmcell43(input_tensor=x3, cur_state=[x4_h, x4_c])# print('x3: ', x3_h.shape)x3_h, x3_c = self.upsample3(x3_h), self.upsample3(x3_c)x2_h, x2_c = self.lstmcell32(input_tensor=x2, cur_state=[x3_h, x3_c])# print('x2: ', x2_h.shape)return x2_h
融合完了返回一個最上層的特征即可
ConvLSTMCell代碼如下:
# convlstm
class ConvLSTMCell(nn.Module):def __init__(self, input_dim, hidden_dim, kernel_size, bias):"""Initialize ConvLSTM cell.Parameters----------input_dim: intNumber of channels of input tensor.hidden_dim: intNumber of channels of hidden state.kernel_size: (int, int)Size of the convolutional kernel.bias: boolWhether or not to add the bias."""super(ConvLSTMCell, self).__init__()self.input_dim = input_dimself.hidden_dim = hidden_dimself.kernel_size = kernel_sizeself.padding = kernel_size[0] // 2, kernel_size[1] // 2self.bias = biasself.conv = nn.Conv2d(in_channels=self.input_dim + self.hidden_dim,out_channels=4 * self.hidden_dim,kernel_size=self.kernel_size,padding=self.padding,bias=self.bias)def forward(self, input_tensor, cur_state):h_cur, c_cur = cur_statecombined = torch.cat([input_tensor, h_cur], dim=1) # concatenate along channel axiscombined_conv = self.conv(combined)cc_i, cc_f, cc_o, cc_g = torch.split(combined_conv, self.hidden_dim, dim=1)i = torch.sigmoid(cc_i)f = torch.sigmoid(cc_f)o = torch.sigmoid(cc_o)g = torch.tanh(cc_g)c_next = f * c_cur + i * gh_next = o * torch.tanh(c_next)return h_next, c_nextdef init_hidden(self, batch_size, image_size):height, width = image_sizereturn (torch.zeros(batch_size, self.hidden_dim, height, width, device=self.conv.weight.device),torch.zeros(batch_size, self.hidden_dim, height, width, device=self.conv.weight.device))
這個融合特征就是這個模塊的輸出。記作FfF^fFf
但是這個模塊還有一個輸出:參考掩碼
看圖可以看到還有一個TM, Target Matching
操作,就是用來生成參考掩碼的
目標匹配(Target Matching)??模塊,通過動態卷積操作計算分割分支特征與參考表示之間的相似度,生成??參考先驗掩碼(referring prior mask)??,為后續特征增強提供定位指導。
具體來說,把參考特征當作卷積核來對視覺特征進行卷積,將卷積結果拼接在一起,然后歸一化與激活處理
# 目標匹配計算
mask = torch.cat([ # 拼接batch內所有樣本的結果F.conv2d( # 動態卷積操作x2_h[i].unsqueeze(0), # 融合特征 [1, C, H, W]ref_x[i].unsqueeze(0) # 共同表示 [1, C, 1, 1] 作為卷積核) for i in range(bs) # 遍歷batch中每個樣本
], 0) # 沿batch維度拼接# 歸一化與激活處理
mask = self.relevance_acti( # LeakyReLU激活self.relevance_norm(mask) # BatchNorm2d歸一化
)
可以看下論文里原話的描述:
他就是說將參考特征與融合特征的每一個位置進行比較,用來生成參考掩膜,記作HmH^mHm。
我的理解就是:這里這個卷積核是1x1的,就是說他和融合特征的每一個位置去進行計算,
RFE模塊
參考特征增強模塊用于在不同尺度上豐富視覺特征。
具體來說,首先將上一階段產生的先驗掩碼 (prior mask,HmH^mHm) 和融合特征 (fusion features,FfF^fFf) 分別調整尺寸至與前述三個特征圖(即 {H2j+1×W2j+1}j=24\left\{\frac{H}{2^{j+1}}\times\frac{W}{2^{j+1}}\right\}_{j=2}^{4}{2j+1H?×2j+1W?}j=24?)相同的形狀。
然后,將同一尺度上調整尺寸后的掩碼和特征圖通過拼接 (concatenation) 進行融合。不同尺度的輸出特征表示為 {Fjscale}j=24\left\{F_{j}^{\text{scale}}\right\}_{j=2}^{4}{Fjscale?}j=24?(其中 Fjscale∈Rcd×H2j+1×W2j+1F_{j}^{\text{scale}}\in R^{c_{d}\times\frac{H}{2^{j+1}}\times\frac{W}{2^{j+1}}}Fjscale?∈Rcd?×2j+1H?×2j+1W?),這些特征也被拼接在一起,以增強識別偽裝目標的能力。我們將最終增強后的特征表示為 Fenr?∈?Rcd×H8×W8F^{enr}\,\in\,R^{c_{d}\times\frac{H}{8}\times\frac{W}{8}}Fenr∈Rcd?×8H?×8W?。
如PFENet[70]所述,細粒度特征圖中的微小目標在下采樣過程中可能會變得模糊不清。因此,我們構建了一條跨尺度路徑 (cross-scale path, CSP),從精細特征跨越到粗糙特征,以實現它們之間的交互。
此外,為了確保生成的增強特征 FenrF^{enr}Fenr 更加魯棒,我們還對 {Fjscale}j=24\left\{F_{j}^{scale}\right\}_{j=2}^{4}{Fjscale?}j=24? 施加了監督,其對應的預測圖表示為 {Mjscale}j=24\left\{M_{j}^{scale}\right\}_{j=2}^{4}{Mjscale?}j=24?(其中 Mjscale∈R1×H×WM_{j}^{scale}\in R^{1\times H\times W}Mjscale?∈R1×H×W)。
這個增強后的特征,直接降低到1通道,尺寸調整為原始圖像大小,就作為預測圖了。
具體的細節參考代碼中的注釋:
class RFE(nn.Module):''' Referring Feature Enrichment (RFE) ModuleFollow implementation of https://github.com/dvlab-research/PFENet/blob/master/model/PFENet.py'''def __init__(self, d_model=64):super(RFE, self).__init__()self.d_model = d_modelself.pyramid_bins = [44, 22, 11] # 352 // 8, 352 // 16, 352 // 32self.avgpool_list = [nn.AdaptiveAvgPool2d(bin_) for bin_ in self.pyramid_bins if bin_ > 1]self.init_merge = []self.alpha_conv = []self.beta_conv = []self.inner_cls = []for idx in range(len(self.pyramid_bins)):if idx > 0:self.alpha_conv.append(nn.Sequential(nn.Conv2d(self.d_model*2, self.d_model, kernel_size=1, stride=1, padding=0, bias=False),nn.BatchNorm2d(self.d_model),nn.ReLU())) self.init_merge.append(nn.Sequential(nn.Conv2d(self.d_model + 1, self.d_model, kernel_size=1, padding=0, bias=False),nn.BatchNorm2d(self.d_model),nn.ReLU(inplace=True),)) # 局部特征增強模塊:就是兩個3x3的卷積 self.beta_conv.append(nn.Sequential(nn.Conv2d(self.d_model, self.d_model, kernel_size=3, padding=1, bias=False),nn.BatchNorm2d(self.d_model),nn.ReLU(inplace=True),nn.Conv2d(self.d_model, self.d_model, kernel_size=3, padding=1, bias=False),nn.BatchNorm2d(self.d_model),nn.ReLU(inplace=True))) self.inner_cls.append(nn.Sequential(nn.Conv2d(self.d_model, self.d_model, kernel_size=3, padding=1, bias=False),nn.BatchNorm2d(self.d_model),nn.ReLU(inplace=True),nn.Dropout2d(p=0.1), nn.Conv2d(self.d_model, 1, kernel_size=1))) self.init_merge = nn.ModuleList(self.init_merge) self.alpha_conv = nn.ModuleList(self.alpha_conv)self.beta_conv = nn.ModuleList(self.beta_conv)self.inner_cls = nn.ModuleList(self.inner_cls)self.pyramid_cat_conv = nn.Sequential(nn.Conv2d(self.d_model*len(self.pyramid_bins), self.d_model, kernel_size=1, padding=0, bias=False),nn.BatchNorm2d(self.d_model),nn.ReLU(inplace=True), ) self.conv_block = nn.Sequential(nn.Conv2d(self.d_model, self.d_model, kernel_size=3, padding=1, bias=False),nn.BatchNorm2d(self.d_model),nn.ReLU(inplace=True), nn.Conv2d(self.d_model, self.d_model, kernel_size=3, padding=1, bias=False),nn.BatchNorm2d(self.d_model),nn.ReLU(inplace=True), ) def forward(self, feats, mask):'''feats: [bs, 64, 44, 44]sf: [bs, 1, 44, 44]'''inner_out_list = [] # 存儲各尺度預測結果pyramid_feat_list = [] # 存儲各尺度處理后的特征# 多尺度處理循環for idx, tmp_bin in enumerate(self.pyramid_bins):if tmp_bin <= 1.0: # 這個tmp_bin上面定義了,取值為44、22、11,不可能小于1.0 這里應該是一個拓展,如果小于1.0的話就代表比例,就按照比例計算,實際暫時沒用到這個bin_ = int(feats.shape[2] * tmp_bin)feats_bin = nn.AdaptiveAvgPool2d(bin)(feats)else: # 常規下采樣(平均池化 并調整到設定的尺寸)bin_ = tmp_binfeats_bin = self.avgpool_list[idx](feats)# 掩碼下采樣mask_bin = F.interpolate(mask, size=(bin_, bin_), mode='bilinear', align_corners=True)# 特征+掩碼 進行融合merge_feat_bin = torch.cat([feats_bin, mask_bin], 1) # 通道拼接merge_feat_bin = self.init_merge[idx](merge_feat_bin) # 1×1卷積融合if idx >= 1: # 從第二個尺度開始 要額外進行跨尺度融合(當前尺度+上一尺度)pre_feat_bin = pyramid_feat_list[idx-1].clone() # 獲取上一尺度處理后的特征# 上采樣至當前尺度尺寸pre_feat_bin = F.interpolate(pre_feat_bin, size=(bin_, bin_), mode='bilinear', align_corners=True)# 拼接當前特征和上一尺度特征rec_feat_bin = torch.cat([merge_feat_bin, pre_feat_bin], 1)# 特征融合(1×1卷積)+ 殘差連接merge_feat_bin = self.alpha_conv[idx-1](rec_feat_bin) + merge_feat_bin # beta_conv:就是過兩個3x3的卷積merge_feat_bin = self.beta_conv[idx](merge_feat_bin) + merge_feat_bin# 輔助預測(多尺度監督) 這里輸出一個監督圖 inner_out_bin = self.inner_cls[idx](merge_feat_bin)# 特征上采樣(恢復至輸入尺寸)merge_feat_bin = F.interpolate(merge_feat_bin, size=(feats.size(2), feats.size(3)), mode='bilinear', align_corners=True)# # 保存當前尺度結果(中間的監督圖)inner_out_list.append(inner_out_bin)# 保存處理后的特征pyramid_feat_list.append(merge_feat_bin)# 拼接所有尺度的特征 再卷積降通道feats_refine = self.pyramid_cat_conv(torch.cat(pyramid_feat_list, 1))# 再過倆卷積 + 殘差連接feats_refine = self.conv_block(feats_refine) + feats_refine return feats_refine, inner_out_list
損失函數
BCE+IoU
但是前面有四個預測圖做bce,這里他沒有設置權重,就直接相加了
實驗
這個實驗是這樣的,先看前兩行,baseline是沒有參考信息的,就是編碼器-解碼器結構,然后逐級融合,得到分割結果。第二行是帶參考信息的,可以看到效果好了很多。然后就是,分為了單目標和多目標,來看效果。
下面的都是在現有的方法上去應用參考信息,可以看到效果都有提升。
消融實驗