two-stage-anchor-based-faster-rcnn进阶-mask rcnn:Mask R-CNN
paper:https://arxiv.org/abs/1703.06870
code:https://github.com/matterport/Mask_RCNN
? ? mask rcnn是基于faster rcnn的改進的一種實例分割算法(得到目標實例同時也生成bbox,檢測結果也刷出新高),由目標檢測算法直接引申到實例分割領域,典型的top-down,也叫做 detect-then-segment,顧名思義,先檢測后分割。在實例分割上一度領先獨領風騷,即便是放在現在,mask rcnn的效果也是各個SOTA算法發表的必備比對數據,本文主要描述我對mask rcnn的理解。
? ? mask-rcnn是基于faster-rcnn的改進,faster-rcnn此篇文章就不回顧了,需要了解的話去看我前2篇文章。
模型總體結構:
? ? 先上結構圖(來源:https://www.cnblogs.com/haimingv/p/12490957.html)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? 結構與faster rcnn一脈相承,利用backbone獲取feature_map后,第一階段利用RPN獲取propossals,第二階段基于proposals利用mask rcnn獨有的Roi Align將proposals映射回原圖,再對這些proposals進行bobx regression、classcification、instance segmentation。
? ? 與faster rcnn的區別:
? ? 1、將faster rcnn的Roi Pooling模塊修改為Roi Align模塊,修復了像素級的映射損失
? ? 2、將faster rcnn的cls+reg任務增加為cls+reg+instance_seg的3個任務
? ? 3、backbone:增加了fpn結構(當年的sota結構)
? ? 4、引入mask loss:稍后細節一下討論
整體模型架構圖(相當詳細,圖片來源:https://www.cnblogs.com/haimingv/p/12490957.html-后續的模塊分析基于本張圖進行):
詳細模塊解讀:
? ? 1、backbone+fpn:
? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? 上圖為基于resnet101的fpn的結構,renet中的基礎shortcut?block應該是bottleneck,由backbone得到c1-c5后:
? ? ? ? ?將c5進行1*1的卷積減少通道數至256生成p5,p5進行3*3的卷積生成256通道數p5;
? ? ? ? ?p5上采樣*2 + c4進行1*1卷積減少通道數至256生成p4,p4進行3*3卷積生成256通道數p4,
? ? ? ? ?p4上采樣*2 + c3進行1*1卷積減少通道數至256生成p3,p3進行3*3卷積生成256通道數p3,
? ? ? ? ?p3上采樣*2 + c2進行1*1卷積減少通道數至256生成p2,p2進行3*3卷積生成256通道數p2,
? ? ? ? ?p5還要進行一次最大池化尺寸/2生成p6(僅rpn使用);
? ? ? ? 即[p2,p3,p4,p5,p6] -> RPN, [p2,p3,p4,p5] -> mask rcnn
? ? 2、anchors機制和proposals機制
? ? ? ? RPN利用[p2,p3,p4,p5,p6]這5個尺度,每個尺度上的特征圖生成3個anchors,比例是[0.5, 1, 2],然后將5個尺度上的anchors疊加成為RPN所使用的anchors;
? ? ? ? RPN在5個尺度上的每個特征圖經過RPN網絡生成兩部分結果,第一部分是rpn_class_logits(每個anchors對應的BG/FG類別logits)和rpn_class_prob(每個anchors的類別置信度),第二部分是rpn_box(每個anchors的偏移量[dy, dx, log(dh), log(dw)]),得到每個尺度的類別和偏移,然后將五個尺度疊加合成RPN網絡輸出的類別和偏移;
? ? ? ? 接下來判定需要生成的預選框(proposals),將RPN網絡生成的偏移量更新給anchors,并生成經過細化/nms(非極大抑制)后的歸一化預選框,為之后的訓練(2000個)/預測(1000個)使用;
? ? ? ??
? ? 3、RoiAlign模塊
? ? ? ? Rol Align很好的解決了 RoI Pooling操作中兩次量化造成的像素級的誤差問題(mis-alignment),此處先簡單分析一下RoI Pooling的原理:
? ? ? ? 3.1、RoI Pooling
? ? ? ? ? ? 在faster rcnn中,anchors經過proposals layer成為proposal,經過RoI Pooling進行size的歸一化然后進入固定input-size的全連接網絡,步驟如下:
? ? ? ? ? ? 1、將proposal映射到feature map對應位置
? ? ? ? ? ? 2、將映射后的區域劃分為相同到校的sections
? ? ? ? ? ? 3、對每個sections進行max pooling操作??
? ? ? ? 3.2、RoI Pooling的問題所在
? ? ? ? ? ? RoI pooling的作用時根據proposal(初步bbox)的位置坐標在特征圖中將相應區域池化為固定size(7*7)的feature-map,然后進行后續的分類和bbox回歸工作。? ? ?
? ? ? ? ? ? 從上文的顏色對誤差來源進行分析:
? ?? ? ? ? ?1、將候選邊界框邊界量化為整數點的feature-map坐標值。假定gt為[665*665],下采樣32倍,則RoI Pooling將其變為665/32=20.78后-四舍五入等于20,則gt在32倍feature-map上的值為[20,20](此例見下圖的第一部分)。
? ? ? ? ? ? 2、將量化后的邊界區域(feature-map坐標值-proposal)平均分成k*k(固定size)個單元(固定feature-map)。假定gt在32被feature-map上的坐標為[20,20],池化為7*7時,則量化后的邊界區域平均分割為7*7個矩形區域,每個矩形區域邊緣為2.86,但是池化時只能將其量化為2,2*7=14,還有6個單位的feature被直接忽略掉了,則候選區域在最終做分類和回歸任務時明顯出現了極大的偏差,如下圖的綠色feature為真正使用到的,綠色框之外的全部被忽視掉了。
? ? ? ? ? ? 簡單來說,整形坐標在映射到整形feature-map,會出現第一次誤差,在做固定尺寸的max-pool時,會出現第二次誤差。
? ? ? ? ? ? 圖片來源:https://blog.csdn.net/wangdongwei0/article/details/85268965
? ? ? ? ? ? ? ? ??
? ? ? ? 3.3、Roi Align的主要思想和方法
? ? ? ? 取消量化操作。
? ? ? ? 1、遍歷每一個候選區域,保持浮點邊界,不做量化
? ? ? ? 2、將候選區域分割為k*k個單元,每個單元的邊界也不做量化
? ? ? ? 3、將每個單元中固定規則固定四個坐標位置,用雙線性插值的方法計算出這4個位置的值,然后進行最大池化操作(詳細理解見下文)。
? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ?如上圖所示,固定的4個坐標位置指的是每一個矩形單元(bin)中按照固定規則確定的位置,比如采樣點是1,則就是單元的中心點,如果采樣點是4,就是把這個單元平均分割成4個小方塊以后它們分別的中心點,如上圖所示,顯然這些采樣點通常為浮點型數,因此利用插值的方法得到他們的像素而不是之前的直接量化后讀取,在相關實驗中,作者發現將采樣點設為4會獲得最佳性能,甚至直接設為1在性能上也相差無幾。
? ? ? ?Roi Pooling是直接全部取整,則第一步獲得到的proposal自然就是整形坐標,也可以直接讀取到對應位置的特征,劃分成bins以后,然后roi pooling直接利用這些劃分bins的特征進行最大池化得到固定尺寸的feature。
? ? ? ?RoI Align是全部使用浮點,然后使用浮點劃分位置,得到位置后,劃分好bins,對每個bins進行4個點的采樣,每個點都使用距離最近的四個像素點(feature點)進行雙線性插值得到,依次對4個點完成操作后,在對這4個值進行max-pool得到固定尺寸的feature。
? ? ? ?具體形象化流程如下:https://blog.csdn.net/qinghuaci666/article/details/80900882(以下的Roi Align為摘自該鏈接的理解,侵刪,該鏈接進一步的給出了曠視針對只采樣4個點進行插值的精度進一步改進方法)
? ? ? ?從左至右依次順序執行:
? ? 更進一步的,給出一個7*7的執行實例:
? ? 輸出7*7的fix featrue:
? ? 1、劃分7*7的bin(我們可以直接精確的映射到feature map來劃分bin,不用第一次量化)? ? ? ? ??
? ? 2、每個bin中采樣4個點,雙線性插值?
? ? 3、對每個bin4個點做max或average pooling
# pytorch
# 這是pytorch做法先采樣到14*14,然后max pooling到7*7
pre_pool_size = cfg.POOLING_SIZE * 2
grid = F.affine_grid(theta, torch.Size((rois.size(0), 1, pre_pool_size, pre_pool_size)))
crops = F.grid_sample(bottom.expand(rois.size(0), bottom.size(1), bottom.size(2), bottom.size(3)), grid, mode=mode)
crops = F.max_pool2d(crops, 2, 2)
# tensorflow
pooled.append(tf.image.crop_and_resize(
? ? ? ? ? ? ? ? feature_maps[i], level_boxes, box_indices, self.pool_shape,
? ? ? ? ? ? ? ? method="bilinear"))
?4、head部分
總體框架圖如上,將生成的rois放入head網絡,網絡分為兩部分,
? ? 第一部分是fc層的生成2個結果,一個是類別(class+bg)-class-prob,一個是坐標回歸(每個rois的坐標偏移量[dy, dx, log(dh), log(dw)]);
? ? 第二部分是全卷積分割網絡生成mask結果,大小為28*28*channels(class_num)的mask圖,通道數為分類數。
? ? 訓練的時候然后開始進行loss函數的計算,而推理階段forward過程結束。
?
模型損失函數:
mask分支對于每個RoI有K*m*m?維度的輸出。K個(類別數)分辨率為m*m的二值mask。
因此作者利用了a per-pixel sigmoid,并且定義 Lmask 為平均二值交叉熵損失(the average binary cross-entropy loss).
對于一個屬于第k個類別的RoI, Lmask 僅僅考慮第k個mask(其他的掩模輸入不會貢獻到損失函數中)。這樣的定義會允許對每個類別都會生成掩模,并且不會存在類間競爭
參考:
https://blog.csdn.net/qinghuaci666/article/details/80900882
總結
以上是生活随笔為你收集整理的two-stage-anchor-based-faster-rcnn进阶-mask rcnn:Mask R-CNN的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C# 使用SDL2实现Mp4文件播放音视
- 下一篇: linux提交abaqus作业,命令行提