日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

FPN详述

發(fā)布時(shí)間:2024/4/11 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 FPN详述 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

簡(jiǎn)介

為了使用更多的語義信息,目標(biāo)檢測(cè)模型一般在卷積神經(jīng)網(wǎng)絡(luò)最后一層的特征圖上進(jìn)行后續(xù)操作(隨著不斷地下采樣,語義信息更豐富,空間信息更稀少),而這一層對(duì)應(yīng)的下采樣率一般是比較大的,如16或者32。這就造成原始圖像上地小目標(biāo)在特征圖上有效信息較少,小物體檢測(cè)性能急劇下降,這就是目標(biāo)檢測(cè)中的多尺度問題,這個(gè)問題很直觀,小目標(biāo)在原圖中對(duì)應(yīng)的像素本就不多,下采樣后很難找到對(duì)應(yīng)信息。

為了解決多尺度問題,關(guān)鍵在于如何獲取多尺度的特征,從數(shù)據(jù)準(zhǔn)備的角度出發(fā)有圖像金字塔這一策略,它的想法就是將圖像調(diào)整為多個(gè)尺度,不同尺度圖像對(duì)應(yīng)不同的特征,這個(gè)思路的缺點(diǎn)就是計(jì)算量非常之大。不過,它也為后來的一些方法提供了思考,要知道,卷積神經(jīng)網(wǎng)絡(luò)層層遞進(jìn),尺度和語義信息不斷變化的過程就是一個(gè)金字塔結(jié)構(gòu),如何能夠有效融合不同層卷積生成的特征圖,應(yīng)該可以較好地改善多尺度檢測(cè)問題,FPN(Feature Pyramid Network)就是以此為出發(fā)點(diǎn)誕生的工作,極大地推動(dòng)了后來目標(biāo)檢測(cè)的發(fā)展。

  • 論文標(biāo)題

    Feature Pyramid Networks for Object Detection

  • 論文地址

    http://arxiv.org/abs/1612.03144

  • 論文源碼

    https://github.com/jwyang/fpn.pytorch(非官方)

網(wǎng)絡(luò)結(jié)構(gòu)

FPN的結(jié)構(gòu)如下圖所示,主要有自下而上、自上而下、橫向連接和卷積融合四個(gè)操作流程,我們一個(gè)個(gè)來看。不過,在此之前先對(duì)下圖做一些必要的說明,圖中最左側(cè)的一列表示輸入圖像經(jīng)過多個(gè)stage的卷積層不斷下采樣修改特征圖的過程,其中C1為最淺幾層,空間尺度大語義信息極少,一般不做考慮。

首先,來看最左側(cè)的自下而上的操作,這個(gè)流是一個(gè)普通的ResNet網(wǎng)絡(luò),用來提取語義信息,C1至C5代表網(wǎng)絡(luò)的5個(gè)stage(即不同的卷積層),每個(gè)stage內(nèi)部特征圖尺寸不變,從C1到C5特征圖尺寸遞減。由這個(gè)卷積網(wǎng)絡(luò)提取特征的過程,就是自下而上的過程。

接著,我們來看中間那個(gè)自上而下操作,首先,對(duì)最小的特征圖進(jìn)行1x1卷積降維通道得到P5,然后對(duì)P5依此進(jìn)行上采樣得到P4、P3和P2,這個(gè)步驟是為了保證P4、P3和P2與C4、C3和C2長(zhǎng)寬相同,以方便后面的逐元素相加。需要注意的是,這里的上采樣實(shí)際上是最近鄰上采樣(臨近元素復(fù)制),而不是線性插值。

然后,就是所謂的橫向連接(Lateral Connection),這個(gè)步驟的目的就是將上采樣后的高語義特征與下采樣之前對(duì)應(yīng)大小的定位細(xì)節(jié)特征進(jìn)行融合。不過,上采樣的尺寸雖然和淺層特征圖一樣,但是通道數(shù)是不同的,因此為了相加,需要將C2、C3和C4通過1x1卷積調(diào)整和P2、P3和P4通道數(shù)目一致,均為256。繼而逐元素相加得到真正的P2、P3和P4,這個(gè)過程就叫做橫向連接。

最后就是卷積融合的過程,得到相加的P2、P3和P4之后,再通過3x3卷積對(duì)這三個(gè)特征圖進(jìn)行變換以消除上采樣過程帶來的重疊效應(yīng),生成最終的P2、P3和P4,它們與P5一同輸出進(jìn)行后續(xù)任務(wù)。

至此,FPN網(wǎng)絡(luò)結(jié)構(gòu)最核心的部分就講完了,不過實(shí)際目標(biāo)檢測(cè)需要在特征圖上進(jìn)行RoI特征提取(通過anchor等),而FPN有四個(gè)特征圖,因此選用哪個(gè)就是值得考慮的。FPPN的方案是,對(duì)于不同尺寸的RoI區(qū)域,使用不同的特征圖,大尺寸RoI需要更加精細(xì)的語義信息,即使深層特征圖也會(huì)有較多信息保留,如在P5上進(jìn)行;而小尺寸RoI因?yàn)槌叽缧?#xff0c;高語義信息很難定位,因此采樣淺層特征圖,如P2。

實(shí)驗(yàn)

在檢測(cè)網(wǎng)絡(luò)中,將neck換為FPN,獲得了非常恐怖的效果提升,包括后來的anchor-free的發(fā)展,也與FPN的成功是分不開的。

代碼實(shí)現(xiàn)

FPN實(shí)現(xiàn)起來不是很難,很多工具箱都做了封裝,這里就給出一個(gè)比較使用的PyTorch實(shí)現(xiàn)版本。

import torch.nn as nn import torch.nn.functional as Fclass Bottleneck(nn.Module):expansion = 4def __init__(self, in_planes, planes, stride=1, downsample=None):super(Bottleneck, self).__init__()self.bottleneck = nn.Sequential(nn.Conv2d(in_planes, planes, 1, bias=False),nn.BatchNorm2d(planes),nn.ReLU(inplace=True),nn.Conv2d(planes, planes, 3, stride, 1, bias=False),nn.BatchNorm2d(planes),nn.ReLU(inplace=True),nn.Conv2d(planes, self.expansion * planes, 1, bias=False),nn.BatchNorm2d(self.expansion * planes),)self.relu = nn.ReLU(inplace=True)self.downsample = downsampledef forward(self, x):identity = xout = self.bottleneck(x)if self.downsample is not None:identity = self.downsample(x)out += identityout = self.relu(out)return outclass FPN(nn.Module):def __init__(self, layers):super(FPN, self).__init__()self.inplanes = 64self.conv1 = nn.Conv2d(3, 64, 7, 2, 3, bias=False)self.bn1 = nn.BatchNorm2d(64)self.relu = nn.ReLU(inplace=True)self.maxpool = nn.MaxPool2d(3, 2, 1)self.layer1 = self._make_layer(64, layers[0])self.layer2 = self._make_layer(128, layers[1], 2)self.layer3 = self._make_layer(256, layers[2], 2)self.layer4 = self._make_layer(512, layers[3], 2)self.toplayer = nn.Conv2d(2048, 256, 1, 1, 0)self.smooth1 = nn.Conv2d(256, 256, 3, 1, 1)self.smooth2 = nn.Conv2d(256, 256, 3, 1, 1)self.smooth3 = nn.Conv2d(256, 256, 3, 1, 1)self.latlayer1 = nn.Conv2d(1024, 256, 1, 1, 0)self.latlayer2 = nn.Conv2d(512, 256, 1, 1, 0)self.latlayer3 = nn.Conv2d(256, 256, 1, 1, 0)def _make_layer(self, planes, blocks, stride=1):downsample = Noneif stride != 1 or self.inplanes != Bottleneck.expansion * planes:downsample = nn.Sequential(nn.Conv2d(self.inplanes, Bottleneck.expansion * planes, 1, stride, bias=False),nn.BatchNorm2d(Bottleneck.expansion * planes))layers = []layers.append(Bottleneck(self.inplanes, planes, stride, downsample))self.inplanes = planes * Bottleneck.expansionfor i in range(1, blocks):layers.append(Bottleneck(self.inplanes, planes))return nn.Sequential(*layers)def _upsample_add(self, x, y):_, _, H, W = y.shapereturn F.upsample(x, size=(H, W), mode='bilinear') + ydef forward(self, x):c1 = self.maxpool(self.relu(self.bn1(self.conv1(x))))c2 = self.layer1(c1)c3 = self.layer2(c2)c4 = self.layer3(c3)c5 = self.layer4(c4)p5 = self.toplayer(c5)p4 = self._upsample_add(p5, self.latlayer1(c4))p3 = self._upsample_add(p4, self.latlayer2(c3))p2 = self._upsample_add(p3, self.latlayer3(c2))p4 = self.smooth1(p4)p3 = self.smooth2(p3)p2 = self.smooth3(p2)return p2, p3, p4, p5if __name__ == '__main__':fpn = FPN([3, 4, 6, 3])print(fpn)

總結(jié)

FPN通過金字塔結(jié)構(gòu)將深層語義信息回傳補(bǔ)充淺層語義信息,從而獲得了高分辨率、強(qiáng)語義的多層特征,在小目標(biāo)檢測(cè)、實(shí)例分割領(lǐng)域有著不俗的表現(xiàn)。本文涉及的代碼都可以在我的Github找到,歡迎star或者fork。

總結(jié)

以上是生活随笔為你收集整理的FPN详述的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。