《YOLOV4&5原理與源代碼解析之二:DropBlock與標簽平滑方法》


Abstract

  dropout被廣泛地用作全連接層的正則化技術,但是對於卷積層,通常不太有效。dropout在卷積層不work的原因可能是由於卷積層的特征圖中相鄰位置元素在空間上共享語義信息,所以盡管某個單元被dropout掉,但與其相鄰的元素依然可以保有該位置的語義信息,信息仍然可以在卷積網絡中流通。因此,針對卷積網絡,我們需要一種結構形式的dropout來正則化,即按塊來丟棄。在本文中,我們引入DropBlock,這是一種結構化的dropout形式,它將feature map相鄰區域中的單元放在一起drop掉。我們發現,除了卷積層外,在跳躍連接中應用DropbBlock可以提高精確度。此外,在訓練過程中,逐漸增加dropped unit的數量會導致更好的准確性和對超參數選擇的魯棒性。大量實驗表明,DropBlock在卷積網絡的正則化中比dropout有更好的性能。

簡單來講,就是避免過擬合,隨機殺死一些神經元,類似隨機森林剪枝。

 

Introduction

  dropout的主要缺點是它隨機drop特征。雖然這對於全連接層是有效的(YOLOV2版本開始,已經沒有FC了,而是采用conv代替;原因是:FC參數多,不易收斂,計算量大,而conv參數少),但是對於卷積層則是無效的,因為卷積層的特征在空間上是相關的。當這些特性相互關聯時,即使有dropout,有關輸入的信息仍然可以發送到下一層,這會導致網絡overfit。這種直覺表明,為了更好地規范卷積網絡,需要一種更結構化的dropout形式。

在本文中,我們引入DropBlock,這是一種結構形式的dropout,它對卷積網絡的正則化特別有效。在DropBlock中,一個block中的features,即feature map中的的一個相鄰區域,被放在一起drop掉。如圖1所示:

 

一、DropBlock(丟棄單元鄰域的區塊)

 

簡單翻譯一下:

如上圖一:(a)是神經網絡輸入圖片。(b)、(c)中的淺綠色區域包含激活層(這些激活層則包含輸入圖片的語義信息)。在刪除語義信息的時候(類似於模型剪枝,以增強泛化精度),dropout采用的是隨機刪除激活層的像素值,

這種方法不一定有效,這是因為被隨機選中的像素,其鄰域保留了與其十分接近的信息,這些信息也會導致網絡模型overfit。相反,隨機刪除一些連續的像素塊,如圖(c),是一種更好的策略(直接把狗頭和狗腿刪除),這種方法稱為dropblock。

block_size:表示dropout的方塊的大小(長,寬),當block_size=1,DropBlock 退化為傳統的dropout,正常可以取3,5,7,如下圖

γ:表示了隨機drop的中間點的概率

feat_size:featureMap大小,如下圖

keep_prob:設置閾值概率,所有低於這個值的元素都會去掉。

         注:如下圖,綠色部分就是要dropout的區域,為了防止dropblock的時候越界,在此給出,如右圖一個像素dropblock的邊長(也稱為:有效種子區域的大小)計算公式:

(feat_size - block_size + 1)

         例如:這里feat_size = 10,block_size = 6,dropblock一個像素鄰域邊長為(10 - 6 + 1)

 

 小結:綠色框表示GT box,簡單來說就是使用伯努利分布在綠色框內隨機生成一個mask,在mask中所有值為0的位置生成一個以其為中心的大小為 block_szie x block_size 的矩形區域,然后將這些區域丟棄。

 

對於上述公式的解釋:

保證DropBlock drop的元素個數和傳統dropout drop的元素個數相等;

傳統dropout drop的元素個數為:(1-keep_prob)*(feat_size^2);

DropBlock drop的元素個數為:γ*(block_size^2) *(feat_size-block_size+1)^2;

 DropBlock的主要細微差別在於,DropBlock中會有一些重疊,所以上面的方程只是一個近似值。

 最后,來看看dropblock對推理過程的性能影響;

           從上面的圖中可以明顯看出,與其他曲線相比,在綠色曲線(沒有經過DropBlock訓練的模型)的推理過程中,隨着保持概率的降低,隨着坡度越陡,驗證精度會迅速下降。由於在block大小為1時,DropBlock與Dropout相似,因此,在block大小為1時,隨着保持概率的降低,驗證准確性迅速下降,DropBlock在刪除語義信息方面更加有效。簡單的理解:對於dropout中刪除的單元,由於在鄰域中可以“找回”,所以dropout對訓練的影響“無關痛癢”;而dropblock恰好相反,即:影響較大。

另一方面,從上圖得出結論:訓練的時候,block_size相對大一點比較好,推理預測的時候,設置的小一點比較好。

 

  Dropout已經被玩出花了。。。作者也很貼心的在文章里一個個說明跟比較。

一句話概括各種dropout方法:

Dropout [1]:完全隨機扔

SpatialDropout [2]:按channel隨機扔

Stochastic Depth [3]:按res block隨機扔

DropBlock [4]:每個feature map上按spatial塊隨機扔

Cutout [5]:在input層按spatial塊隨機扔

DropConnect [6]:只在連接處扔,神經元不扔。

.........下一個在哪扔?

 

二、標簽平滑方法

 

Label smoothing

在分類任務中,某個樣本的one-hot(二進制串)標簽為

[公式]

即所屬類別的置信度為1,其余類別都為0。比如在手寫數字識別中,"7"的one-hot標簽為:

[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0]

Soft-Max與交叉熵:一般地,網絡的經過FC層得到w、b等權重參數,在經過SoftMax就能得到一個多分類的概率分布(所有概率值之和為1),例如:
SoftMax預測值yi = [0.1, 0.8, 0.05, 0.05, 0];假定 label為:y_ = [0 1 0 0 0],將yi、y_代入交叉熵公式,便得到這兩個分布的差異,交叉熵越小,表示yi、y_越接近,反之,你懂。在很多網絡中,計算loss的時,采用的是交叉熵,
而不是MSE(交叉熵的loss形式便於求導);當然,在預測的時候,僅計算SoftMax。

回到正題:
“當你認為絕對正確時,你可能就完全錯了”——不知道誰說的。

  比如:二分類,認為樣本為正樣本,標注為1,過於絕對,容易過擬合;好比一個人,過於自信,就是自負,一旦自負,遲早判斷失誤!

       例如,將上述的(0, 1)定義為(0.05, 0.95),這樣標簽變得平滑,有種將離散變量轉為連續變量的意思,類似於“像素插值”。

 

   如上圖,分別是標簽平滑前后的樣本分布圖(聚類得到,僅為驗證),左圖,類別之間的“間隔”很小,靠近相鄰空間的位置,可區分性小;模型容易過擬合,右邊分類間隔大,可區分性大,類似與SVM中的“最大分類間隔”。

  在訓練過程中,模型習慣於對其預測結果“過於自信”,這會增加過擬合風險。另外,數據集中可能包含標注錯誤的數據,所以模型在訓練過程中需要對標簽持有懷疑態度。為此,可以在訓練中引入一種標簽平滑方法,將hard標簽轉換為soft標簽(即1 → 1 - 平滑因子),來降低模型對標簽的信心。soft標簽為

[公式]

其中 K 為類別數量, [公式] ​為平滑因子它是一個很小的常數。假設平滑因子為0.09,則經過標簽平滑后,"7"的one-hot標簽變為:

# 平滑后各個置信度之和仍為1 [0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.91, 0.01, 0.01]

標簽平滑是一種正則化方法,可以防止模型在訓練期間過於自信,降低過擬合風險。Label Smoothing參考代碼:

 1 class LabelSmoothingLoss(nn.Module):
 2     def __init__(self, num_classes, smoothing=0.0, dim=-1):
 3         super(LabelSmoothingLoss, self).__init__()
 4         self.confidence = 1.0 - smoothing
 5         self.smoothing = smoothing
 6         self.num_classes = num_classes
 7         self.dim = dim
 8 
 9     def forward(self, pred, gt):
10         pred = pred.log_softmax(dim=self.dim)
11         with torch.no_grad():
12             true_label = torch.zeros_like(pred)
13             true_label.fill_(self.smoothing / (self.num_classes - 1))
14             true_label.scatter_(1, gt.unsqueeze(1), self.confidence)
15         return torch.mean(torch.sum(-true_label * pred, dim=self.dim))

reference:

 

dropblock:

https://zhuanlan.zhihu.com/p/142299442

https://my.oschina.net/u/1416903/blog/4537523

 https://www.yuque.com/kjle6/feoy5e/qp2p4i

伯努利簡單推導:

https://www.cnblogs.com/ehomeshasha/p/3820512.html

標簽平滑:

https://zhuanlan.zhihu.com/p/239934468

dropout的綜述總結:

https://www.zhihu.com/question/300940578/answer/523516718

 SoftMax與交叉熵:

https://zhuanlan.zhihu.com/p/27223959


免責聲明!

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



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