最先由RGB在論文《Training Region-based Object Detectors with Online Hard Example Mining》中提出,用於fast-rcnn訓練中,具備必定訓練效果;git
論文地址:https://arxiv.org/pdf/1604.03540.pdfgithub
實驗地址:https://github.com/firrice/OHEM網絡
主要思想:一個batch的輸入通過網絡的前向傳播後,有一些困難樣本loss較大,咱們能夠對loss進行降序排序,取前K個認爲是hard example,而後有兩種方案:spa
(1)第一種比較簡單,最終loss只取前K個,其餘置0,而後進行BP:3d
一個例子以下:code
def ohem_loss(output , label, loss_class , K_hard): batch_size = output.size()[0] loss = loss_class(output , label) sorted_loss , index = torch.sort(loss , descending = True) if(K_hard < batch_size): hard_index = index[ : K_hard] final_loss = loss[hard_index].sum() / K_hard else: final_loss = loss.sum() / batch_size return final_loss
第一種的缺點是雖然置0,但BP中依然會爲之分配內存,爲了提高效率引入下面第二種方案。component
(2)第二種方案,以fast-rcnn的pipeline爲例,訓練兩個ROI net的副本,權值共享,以下:blog
具體來講:排序
1 將Fast RCNN分紅兩個components:ConvNet和RoINet. ConvNet爲共享的底層卷積層,RoINet爲RoI Pooling後的層,包括全鏈接層;ip
2 對於每張輸入圖像,經前向傳播,用ConvNet得到feature maps(這裏爲RoI Pooling層的輸入);
3 將事先計算好的proposals,經RoI Pooling層投影到feature maps上,獲取固定的特徵輸出做爲全鏈接層的輸入;
須要注意的是,論文說,爲了減小顯存以及後向傳播的時間,這裏的RoINet是有兩個的,它們共享權重,
RoINet1是隻讀(只進行forward),RoINet2進行forward和backward:
a 將原圖的全部props扔到RoINet1,計算它們的loss(這裏有兩個loss:cls和det);
b 根據loss從高到低排序,以及利用NMS,來選出前K個props(K由論文裏的N和B參數決定)
爲何要用NMS? 顯然對於那些高度overlap的props經RoI的投影后,
其在feature maps上的位置和大小是差很少同樣的,容易致使loss double counting問題
c 將選出的K個props(能夠理解成hard examples)扔到RoINet2,
這時的RoINet2和Fast RCNN的RoINet同樣,計算K個props的loss,並回傳梯度/殘差給ConvNet,來更新整個網絡