網(wǎng)站首頁 編程語言 正文
一、SPP的應(yīng)用的背景
在卷積神經(jīng)網(wǎng)絡(luò)中我們經(jīng)常看到固定輸入的設(shè)計,但是如果我們輸入的不能是固定尺寸的該怎么辦呢?
通常來說,我們有以下幾種方法:
(1)對輸入進行resize操作,讓他們統(tǒng)統(tǒng)變成你設(shè)計的層的輸入規(guī)格那樣。但是這樣過于暴力直接,可能會丟失很多信息或者多出很多不該有的信息(圖片變形等),影響最終的結(jié)果。
(2)替換網(wǎng)絡(luò)中的全連接層,對最后的卷積層使用global average pooling,全局平均池化只和通道數(shù)有關(guān),而與特征圖大小沒有關(guān)系
(3)最后一個當(dāng)然是我們要講的SPP結(jié)構(gòu)啦~
二、SPP結(jié)構(gòu)分析
SPP結(jié)構(gòu)又被稱為空間金字塔池化,能將任意大小的特征圖轉(zhuǎn)換成固定大小的特征向量。
接下來我們來詳述一下SPP是怎么處理滴~
輸入層:首先我們現(xiàn)在有一張任意大小的圖片,其大小為w * h。
輸出層:21個神經(jīng)元 -- 即我們待會希望提取到21個特征。
分析如下圖所示:分別對1 * 1分塊,2?* 2分塊和4?* 4子圖里分別取每一個框內(nèi)的max值(即取藍框框內(nèi)的最大值),這一步就是作最大池化,這樣最后提取出來的特征值(即取出來的最大值)一共有1 * 1 + 2 * 2 + 4 * 4 = 21個。得出的特征再concat在一起。
而在YOLOv5中SPP的結(jié)構(gòu)圖如下圖所示:
其中,前后各多加一個CBL,中間的kernel size分別為1 * 1,5 * 5,9 * 9和13 * 13。
三、SPPF結(jié)構(gòu)分析
(x,y1這些是啥請看下面的代碼)
四、YOLOv5中SPP/SPPF結(jié)構(gòu)源碼解析(內(nèi)含注釋分析)
代碼注釋與上圖的SPP結(jié)構(gòu)相對應(yīng)。
class SPP(nn.Module):
def __init__(self, c1, c2, k=(5, 9, 13)):#這里5,9,13,就是初始化的kernel size
super().__init__()
c_ = c1 // 2 # hidden channels
self.cv1 = Conv(c1, c_, 1, 1)#這里對應(yīng)第一個CBL
self.cv2 = Conv(c_ * (len(k) + 1), c2, 1, 1)#這里對應(yīng)SPP操作里的最后一個CBL
self.m = nn.ModuleList([nn.MaxPool2d(kernel_size=x, stride=1, padding=x // 2) for x in k])
#這里對應(yīng)SPP核心操作,對5 * 5分塊,9 * 9分塊和13 * 13子圖分別取最大池化
def forward(self, x):
x = self.cv1(x)
with warnings.catch_warnings():
warnings.simplefilter('ignore') # suppress torch 1.9.0 max_pool2d() warning忽略警告
return self.cv2(torch.cat([x] + [m(x) for m in self.m], 1))
#torch.cat對應(yīng)concat
SPPF結(jié)構(gòu)
class SPPF(nn.Module):
# Spatial Pyramid Pooling - Fast (SPPF) layer for YOLOv5 by Glenn Jocher
def __init__(self, c1, c2, k=5): # equivalent to SPP(k=(5, 9, 13))
super().__init__()
c_ = c1 // 2 # hidden channels
self.cv1 = Conv(c1, c_, 1, 1)
self.cv2 = Conv(c_ * 4, c2, 1, 1)
self.m = nn.MaxPool2d(kernel_size=k, stride=1, padding=k // 2)
def forward(self, x):
x = self.cv1(x)#先通過CBL進行通道數(shù)的減半
with warnings.catch_warnings():
warnings.simplefilter('ignore') # suppress torch 1.9.0 max_pool2d() warning
y1 = self.m(x)
y2 = self.m(y1)
#上述兩次最大池化
return self.cv2(torch.cat([x, y1, y2, self.m(y2)], 1))
#將原來的x,一次池化后的y1,兩次池化后的y2,3次池化的self.m(y2)先進行拼接,然后再CBL
總結(jié)
原文鏈接:https://blog.csdn.net/weixin_55073640/article/details/122621148
相關(guān)推薦
- 2022-05-10 react使用require圖片無法加載
- 2022-09-01 C++中的Z字形變換問題_C 語言
- 2022-12-27 python中內(nèi)置庫csv的使用及說明_python
- 2022-04-27 Oracle?觸發(fā)器trigger使用案例_oracle
- 2023-03-28 python?label與one-hot之間的互相轉(zhuǎn)換方式_python
- 2024-03-21 Springboot實現(xiàn)接口傳輸加解密
- 2022-06-13 C#多線程之Parallel類的用法_C#教程
- 2022-10-28 Go保證并發(fā)安全底層實現(xiàn)詳解_Golang
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支