主頁 >  其他 > 二階段目標檢測網路-FPN 詳解

二階段目標檢測網路-FPN 詳解

2022-12-17 06:42:15 其他

  • 論文背景
  • 引言(Introduction)
  • 特征金字塔網路 FPN
    • FPN網路建立
    • Anchor錨框生成規則
  • 實驗
  • 代碼解讀
  • 參考資料

本篇文章是論文閱讀筆記和網路理解心得總結而來,部分資料和圖參考論文和網路資料

論文背景

FPN(feature pyramid networks) 是何凱明等作者提出的適用于多尺度目標檢測演算法,原來多數的 object detection 演算法(比如 faster rcnn)都是只采用頂層特征做預測,但我們知道低層的特征語意資訊比較少,但是目標位置準確;高層的特征語意資訊比較豐富,但是目標位置比較粗略,另外雖然也有些演算法采用多尺度特征融合的方式,但是一般是采用融合后的特征做預測,而本文不一樣的地方在于預測是在不同特征層獨立進行的,

引言(Introduction)

4種金字塔結構

從上圖可以看出,(a)使用影像金字塔構建特征金字塔,每個影像尺度上的特征都是獨立計算的,速度很慢,(b)最近的檢測系統選擇(比如 Faster RCNN)只使用單一尺度特征進行更快的檢測,(c)另一種方法是重用 ConvNet(卷積層)計算的金字塔特征層次結構(比如 SSD),就好像它是一個特征化的影像金字塔,(d)我們提出的特征金字塔網路(FPN)與(b)和(c)類似,但更準確,在該圖中,特征映射用藍色輪廓表示,較粗的輪廓表示語意上較強的特征

特征金字塔網路 FPN

作者提出的 FPN 結構如下圖:這個金字塔結構包括一個自底向上的線路,一個自頂向下的線路和橫向連接(lateral connections)

fpn結構示意圖

自底向上其實就是卷積網路的前向程序,在前向程序中,feature map 的大小在經過某些層后會改變,而在經過其他一些層的時候不會改變,作者將不改變 feature map 大小的層歸為一個 stage,因此這里金字塔結構中每次抽取的特征都是每個 stage 的最后一個層的輸出,在代碼中我們可以看到共有C1、C2、C3、C4、C5五個特征圖,C1C2 的特征圖大小是一樣的,所以,FPN 的建立也是基于從 C2C5 這四個特征層上,

自頂向下的程序采用上采樣(upsampling)進行,而橫向連接則是將上采樣的結果和自底向上生成的相同大小的 feature map 進行融合(merge),在融合之后還會再采用 3*3 的卷積核對每個融合結果進行卷積,目的是消除上采樣的混疊效應(aliasing effect),并假設生成的 feature map 結果是 P2,P3,P4,P5,和原來自底向上的卷積結果 C2,C3,C4,C5一一對應,

這里貼一個 ResNet 的結構圖:論文中作者采用 conv2_x,conv3_x,conv4_x 和 conv5_x 的輸出,對應 C1,C2,C3,C4,C5,因此類似 Conv2就可以看做一個stage,

resnet結構引數圖

FPN網路建立

這里自己沒有總結,因為已經有篇博文總結得很不錯了,在這,

通過 ResNet50 網路,得到圖片不同階段的特征圖,最后利用 C2,C3,C4,C5 建立特征圖金字塔結構:

  1. 將 C5 經過 256 個 1*1 的卷積核操作得到:32*32*256,記為 P5;
  2. 將 P5 進行步長為 2 的上采樣得到 64*64*256,再與 C4 經過的 256 個 1*1 卷積核操作得到的結果相加,得到 64*64*256,記為 P4;
  3. 將 P4 進行步長為 2 的上采樣得到 128*128*256,再與 C3 經過的 256 個 1*1 卷積核操作得到的結果相加,得到 128*128*256,記為 P3;
  4. 將 P3 進行步長為 2 的上采樣得到 256*256*256,再與 C2 經過的 256 個 1*1 卷積核操作得到的結果相加,得到 256*256*256,記為 P2;
  5. 將 P5 進行步長為 2 的最大池化操作得到:16*16*256,記為 P6;

結合從 P2 到 P6 特征圖的大小,如果原圖大小 1024*1024, 那各個特征圖對應到原圖的步長依次為 [P2,P3,P4,P5,P6]=>[4,8,16,32,64],

Anchor錨框生成規則

Faster RCNN 采用 FPN 的網路作 backbone 后,錨框的生成規則也會有所改變,基于上一步得到的特征圖 [P2,P3,P4,P5,P6],再介紹下采用 FPN 的 Faster RCNN(或者 Mask RCNN)網路中 Anchor 錨框的生成,根據原始碼中介紹的規則,與之前 Faster-RCNN 中的生成規則有一點差別,

  1. 遍歷 P2 到 P6 這五個特征層,以每個特征圖上的每個像素點都生成 Anchor 錨框;
  2. 以 P2 層為例,P2 層的特征圖大小為 256*256,相對于原圖的步長為4,這樣 P2上的每個像素點都可以生成一個基于坐標陣列 [0,0,3,3] 即 4*4 面積為 16 大小的Anchor錨框,當然,可以設定一個比例 SCALE,將這個基礎的錨框放大或者縮小,比如,這里設定 P2 層對應的縮放比例為 16,那邊生成的錨框大小就是長和寬都擴大16倍,從 4*4 變成 64*64,面積從 16 變成 4096,當然在保證面積不變的前提下,長寬比可以變換為 32*128、64*64 或 128*32,這樣以長、寬比率 RATIO = [0.5,1,2] 完成了三種變換,這樣一個像素點都可以生成3個Anchor錨框,在 Faster-RCNN 中可以將 Anchor scale 也可以設定為多個值,而在MasK RCNN 中則是每一特征層只對應著一個 Anchor scale即對應著上述所設定的 16
  3. P2 層每個像素點位中心,對應到原圖上,則可生成 256*256*3(長寬三種變換) = 196608 個錨框;
  4. P3 層每個像素點為中心,對應到原圖上,則可生成 128*128*3 = 49152 個錨框;
  5. P4 層每個像素點為中心,對應到原圖上,則可生成 64*64*3 = 12288 個錨框;
  6. P5 層每個像素點為中心,對應到原圖上,則生成 32*32*3 = 3072 個錨框;
  7. P6 層每個像素點為中心,對應到原圖上,則生成 16*16*3 = 768 個錨框,

從 P2 到 P6 層一共可以在原圖上生成 \(196608 + 49152 + 12288 + 3072 + 768 = 261888\)Anchor 錨框,

實驗

看看加入FPN 的 RPN 網路的有效性,如下表 Table1,網路這些結果都是基于 ResNet-50,評價標準采用 AR,AR 表示 Average Recall,AR 右上角的 100 表示每張影像有 100 個 anchor,AR 的右下角 s,m,l 表示 COCO 資料集中 object 的大小分別是小,中,大,feature 列的大括號 {} 表示每層獨立預測,

對比試驗

從(a)(b)(c)的對比可以看出 FPN 的作用確實很明顯,另外(a)和(b)的對比可以看出高層特征并非比低一層的特征有效,

(d)表示只有橫向連接,而沒有自頂向下的程序,也就是僅僅對自底向上(bottom-up)的每一層結果做一個 1*1 的橫向連接和 3*3 的卷積得到最終的結果,有點像 Fig1 的(b),從 feature 列可以看出預測還是分層獨立的,作者推測(d)的結果并不好的原因在于在自底向上的不同層之間的 semantic gaps 比較大,

(e)表示有自頂向下的程序,但是沒有橫向連接,即向下程序沒有融合原來的特征,這樣效果也不好的原因在于目標的 location 特征在經過多次降采樣和上采樣程序后變得更加不準確,

(f)采用 finest level 層做預測(參考 Fig2 的上面那個結構),即經過多次特征上采樣和融合到最后一步生成的特征用于預測,主要是證明金字塔分層獨立預測的表達能力,顯然 finest level 的效果不如 FPN 好,原因在于 PRN 網路是一個視窗大小固定的滑動視窗檢測器,因此在金字塔的不同層滑動可以增加其對尺度變化的魯棒性,另外(f)有更多的 anchor,說明增加 anchor 的數量并不能有效提高準確率

Figure2

代碼解讀

這里給出一個基于 PytorchFPN 網路的代碼,來自這里,

## ResNet的block
class Bottleneck(nn.Module):
    expansion = 4
    def __init__(self, in_planes, planes, stride=1):
        super(Bottleneck, self).__init__()
        self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=1, bias=False)
        self.bn1 = nn.BatchNorm2d(planes)
        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(planes)
        self.conv3 = nn.Conv2d(planes, self.expansion*planes, kernel_size=1, bias=False)
        self.bn3 = nn.BatchNorm2d(self.expansion*planes)
        self.shortcut = nn.Sequential()
        if stride != 1 or in_planes != self.expansion*planes:
            self.shortcut = nn.Sequential(
                nn.Conv2d(in_planes, self.expansion*planes, kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(self.expansion*planes)
            )
    def forward(self, x):
        out = F.relu(self.bn1(self.conv1(x)))
        out = F.relu(self.bn2(self.conv2(out)))
        out = self.bn3(self.conv3(out))
        out += self.shortcut(x)
        out = F.relu(out)
        return out
class FPN(nn.Module):
    def __init__(self, block, num_blocks):
        super(FPN, self).__init__()
        self.in_planes = 64
        self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False)
        self.bn1 = nn.BatchNorm2d(64)
        # Bottom-up layers, backbone of the network
        self.layer1 = self._make_layer(block, 64, num_blocks[0], stride=1)
        self.layer2 = self._make_layer(block, 128, num_blocks[1], stride=2)
        self.layer3 = self._make_layer(block, 256, num_blocks[2], stride=2)
        self.layer4 = self._make_layer(block, 512, num_blocks[3], stride=2)
        # Top layer
        # 我們需要在C5后面接一個1x1, 256 conv,得到金字塔最頂端的feature
        self.toplayer = nn.Conv2d(2048, 256, kernel_size=1, stride=1, padding=0) # Reduce channels
        # Smooth layers
        # 這個是上面引文中提到的抗aliasing的3x3卷積
        self.smooth1 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)
        self.smooth2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)
        self.smooth3 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)
        # Lateral layers
        # 為了匹配channel dimension引入的1x1卷積
        # 注意這些backbone之外的extra conv,輸出都是256 channel
        self.latlayer1 = nn.Conv2d(1024, 256, kernel_size=1, stride=1, padding=0)
        self.latlayer2 = nn.Conv2d( 512, 256, kernel_size=1, stride=1, padding=0)
        self.latlayer3 = nn.Conv2d( 256, 256, kernel_size=1, stride=1, padding=0)
    def _make_layer(self, block, planes, num_blocks, stride):
        strides = [stride] + [1]*(num_blocks-1)
        layers = []
        for stride in strides:
            layers.append(block(self.in_planes, planes, stride))
            self.in_planes = planes * block.expansion
        return nn.Sequential(*layers)
    ## FPN的lateral connection部分: upsample以后,element-wise相加
    def _upsample_add(self, x, y):
        '''Upsample and add two feature maps.
        Args:
          x: (Variable) top feature map to be upsampled.
          y: (Variable) lateral feature map.
        Returns:
          (Variable) added feature map.
        Note in PyTorch, when input size is odd, the upsampled feature map
        with `F.upsample(..., scale_factor=2, mode='nearest')`
        maybe not equal to the lateral feature map size.
        e.g.
        original input size: [N,_,15,15] ->
        conv2d feature map size: [N,_,8,8] ->
        upsampled feature map size: [N,_,16,16]
        So we choose bilinear upsample which supports arbitrary output sizes.
        '''
        _,_,H,W = y.size()
        return F.upsample(x, size=(H,W), mode='bilinear') + y
    def forward(self, x):
        # Bottom-up
        c1 = F.relu(self.bn1(self.conv1(x)))
        c1 = F.max_pool2d(c1, kernel_size=3, stride=2, padding=1)
        c2 = self.layer1(c1)
        c3 = self.layer2(c2)
        c4 = self.layer3(c3)
        c5 = self.layer4(c4)
        # Top-down
        # P5: 金字塔最頂上的feature
        p5 = self.toplayer(c5)
        # P4: 上一層 p5 + 側邊來的 c4
        # 其余同理
        p4 = self._upsample_add(p5, self.latlayer1(c4))
        p3 = self._upsample_add(p4, self.latlayer2(c3))
        p2 = self._upsample_add(p3, self.latlayer3(c2))
        # Smooth
        # 輸出做一下smooth
        p4 = self.smooth1(p4)
        p3 = self.smooth2(p3)
        p2 = self.smooth3(p2)
        return p2, p3, p4, p5

參考資料

  • FPN(feature pyramid networks)演算法講解
  • Mask RCNN 源代碼決議 (1) - 整體思路
  • Mask RCNN 學習筆記
  • 論文 - Feature Pyramid Networks for Object Detection (FPN)

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/540148.html

標籤:其他

上一篇:【機器學習】李宏毅——自注意力機制(Self-attention)

下一篇:PreSTU:一個專門為場景文本理解而設計的簡單預訓練模型

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more