之前有一篇部落格學習了mixup資料增強,對於提公升模型的效能非常顯著。長江後浪推前浪,這一篇cutmix資料增強居然將其推在沙灘上。簡單回顧下mixup資料增強:從訓練樣本中隨機抽取兩個樣本進行簡單的隨機加權求和,同時樣本的標籤也對應加權求和,然後**結果與加權求和之後的標籤求損失,在反向求導更新引數。
cutmix的處理方式也比較簡單,同樣也是對一對做操作,簡單講就是隨機生成乙個裁剪框box,裁剪掉a圖的相應位置,然後用b相應位置的roi放到a圖中被裁剪的區域形成新的樣本,計算損失時同樣採用加權求和的方式進行求解,最後作者對比了mixup、cutout和baseline,資料上看似乎也是小小地吊打的節奏。
為什麼會這樣呢,**的意思我姑且這樣描述,mixup是直接求和兩張圖,如同附身,鬼影一樣,模型很難學到準確的特徵圖響應分布。而cutmix相當於換某個零件,模型更容易區分異類。
二、演算法細節
演算法的核心過程在**中這樣描述:
m是乙個與影象尺寸一致的由0和1標記的掩碼矩陣,實際就是標記需要裁剪的區域和保留的區域,裁剪的區域值均為0,其餘位置為1,影象a和b組合得到新樣本,最後兩個圖的標籤也對應求加權和(其實這個公式想要表達的是再求接損失時,二者的loss求加權和,這樣說更準確)。那麼問題來了這個裁剪區域的box是如何得到,加權的係數如何確定?
權值同mixup一樣是採用bata分布隨機得到,alpha的值為**中取值為1,這樣加權係數[0-1]就服從beta分布,實際上從**的**實現上看,beta分布真正的用途是為了生成裁剪區域。**這樣描述:
裁剪框box的左上角座標採集服從寬高(w和h)的均勻分布,及隨其採點,box的寬高計算則需要用到beta分布產生的加權係數納悶噠(?
懶得打公式了),這樣裁剪區box的面積與影象面積之比為1-納悶噠。這樣損失的加權和(公式(1))說採用的納悶噠就與面積比相對應。這裡我對**進行了簡答整理,以便更好地嵌入自己的框架:
def rand_bbox(size, lam):
w = size[2]
h = size[3]
cut_rat = np.sqrt(1. - lam)
cut_w = np.int(w * cut_rat)
cut_h = np.int(h * cut_rat)
# uniform
cx = np.random.randint(w)
cy = np.random.randint(h)
bbx1 = np.clip(cx - cut_w // 2, 0, w)
bby1 = np.clip(cy - cut_h // 2, 0, h)
bbx2 = np.clip(cx + cut_w // 2, 0, w)
bby2 = np.clip(cy + cut_h // 2, 0, h)
return bbx1, bby1, bbx2, bby2
def cutmix_data(x, y, alpha=1., use_cuda=true):
if alpha > 0.:
lam = np.random.beta(alpha, alpha)
else:
lam = 1.
batch_size = x.size()[0]
if use_cuda:
index = torch.randperm(batch_size).cuda()
else:
index = torch.randperm(batch_size)
size=x.size()
bbx1, bby1, bbx2, bby2=rand_bbox(size,lam)
x[:, :, bbx1:bbx2, bby1:bby2] = x[index, :, bbx1:bbx2, bby1:bby2]
# adjust lambda to exactly match pixel ratio
lam = 1 - ((bbx2 - bbx1) * (bby2 - bby1) / (x.size()[-1] *x.size()[-2]))
y_a, y_b = y, y[index]
return x, y_a, y_b, lam
嚴格的講,生成的box可能超出影象邊界而被裁減,所以再**中最終的加權係數重新計算了一下:
lam = 1 - ((bbx2 - bbx1) * (bby2 - bby1) / (x.size()[-1] *x.size()[-2]))
訓練過程完整的使用**如下:
if mixtype=='mixup':
inputs, targets_a, targets_b, lam = mixup_data(inputs, targets, args.alpha, use_cuda)
elif mixtype=='cutmix':
inputs, targets_a, targets_b, lam = cutmix_data(inputs, targets, args.alpha, use_cuda)
optimizer.zero_grad()
inputs, targets_a, targets_b = variable(inputs), variable(targets_a), variable(targets_b)
outputs = net(inputs)
loss = criterion(outputs, target_a) * lam + criterion(outputs, target_b) * (1. -lam)
我在最近工作中的私有資料集中進行了試驗,同樣的資料,其他引數一致,僅僅更換mixup為cutmix,模型效能確有提公升。對於困難樣本的效果有很好的提公升。同時心中有乙個疑問,如果在mini-batch中隨機取樣中,樣本對組合新資料時,影象a和b在裁剪區域均為背景區域,且背景區域幾乎相似,而非目標所在區域,這樣訓練強制模型擬合,是否合理,還是會引入雜訊樣?? 求大佬們解答一二。
cutmix: regularization strategy to train strong classifiers with localizable features
資料增強總結
資料增強方式 1 傳統資料增強,包括crop,translate,zoom,hue等 2 gan cyclegan 生成的和真實差距較大,損失函式定義為分類偏差。3 插值式,smote,mixup等演算法生成新 4 遷移學習 5 特徵融合,特徵手動提取 總結 the effectiveness of...
Data augmentation資料增強
mirroring 映象翻轉 最簡單的資料增強方式 random cropping 隨機裁剪 隨機裁剪並不是一種完美的資料增強方式。存在隨機裁剪切那塊看起來不像貓的的可能性,但是實際隨機裁剪效果還不錯,只要隨機裁剪的部分占原的相當大一部分即可。rotation 旋轉 shearing 剪下 loca...
資料增強 自動駕駛中的資料增強
本文摘取了matt cooper對自動駕駛資料增強的一些看法。文章的核心觀點是,針對特定的模型必須分析確定特定的資料增強器,不能把增強器技術黑箱使用,否在會產生過擬合。問題起源 作者在實習的時候實現乙個資料增強器,以改進物件檢測工作。這其中,一種簡單的技術被稱為裁剪正則化。簡而言之,就是在輸入影象中...