一、背景
物體檢測是計算機視覺領域的一個重要研究方向,在人工智能領域有廣泛應用。Yolov5是一種基於深度學習的物體檢測方法,具有高效、高精度等特點。其中,Yolov5s相對來說計算量較小、速度較快。本文就將分析Yolov5s的網絡結構和部件組成,以此來深入了解提高物體檢測準確性和速度的技術手段。
二、Yolov5s網絡結構與組成部件
Yolov5s是基於深度卷積神經網絡(DCNN)的物體檢測算法,其網絡結構由一串卷積層和一些附加的輔助層組成。相對於傳統的RCNN、Fast RCNN、Faster RCNN和SSD等物體檢測算法,Yolov5s具有如下優點:
1. 高效
由於採用了一些基於新型卷積模塊的加速技術,如CSP(Cross Stage Partial)模塊,Yolov5s相較於傳統的物體檢測算法速度更快、計算量更小。
2. 準確性高
Yolov5s的backbone使用了較為新穎的SPP(Spatial Pyramid Pooling)模塊。相較於其他物體檢測算法中的backbone(如ResNet、DarkNet等),SPP可以將多種大小的特徵圖組合在一起,生成一個全局的特徵描述,因此對於小物體、遮擋、光照等問題有較強的魯棒性。此外,Yolov5s還使用了多尺度訓練的方法,針對不同尺度的物體,進行了適當的處理,提高了分類和定位的準確性。
3. 網絡結構清晰
Yolov5s的網絡結構非常清晰,模塊化程度較高,便於調整和設計相應模型。此外,Yolov5s中還有許多較為新穎的卷積模型,如CSP模塊等,可以為後續的模型設計提供參考。
下面我們將詳細介紹Yolov5s的網絡結構和組成部件。
1. Backbone
Yolov5s的backbone使用了較為新穎的SPP模塊,這是一個空間金字塔池化模塊,可以將多個不同大小的特徵圖進行組合,生成全局的特徵描述。SPP的含義是空間金字塔池化,其主要思想是在不影響特徵圖大小的情況下,對各個尺度的特徵圖進行最大值池化,得到固定維度的全局特徵描述,這使得網絡在特徵提取方面更具有魯棒性。SPP模塊的通道數量是其入口的四倍。此外,為了提高感受野,backbone還使用了一段空洞卷積層。
class SpatialPyramidPooling(Module):
def __init__(self, pool_sizes=(5, 9, 13)):
super().__init__()
self.max_concats, self.pools = len(pool_sizes) + 1, nn.ModuleList()
for p in pool_sizes:
self.pools.append(nn.MaxPool2d(kernel_size=p, stride=1, padding=p // 2))
self.pools.append(nn.MaxPool2d(kernel_size=1, stride=1))
def forward(self, x):
outs = [x]
for p in self.pools:
outs.append(F.interpolate(p(x), size=x.shape[-2:], mode='bilinear', align_corners=False))
return torch.cat(outs, dim=1)
2. Head
Yolov5s的Head主要包含三個部分:FPN、PAN和YOLO Detection層。其中,FPN是一種特徵金字塔網絡模型,負責提取特徵圖中的更加抽象的特徵,以便更好地進行目標分類和檢測。PAN(Path Aggregation Network)是一種路徑聚合模型,主要用於調整不同特徵金字塔之間的大小和通道數,使其能夠適應不同大小的目標檢測。而YOLO Detection層是一個檢測層,主要是負責計算邊界框的坐標值、置信度以及類別概率值。具體來說,YOLO Detection層通過三個卷積層來對特徵圖進行處理,即先進行1×1卷積,再進行3×3卷積,最後返回坐標值、置信度和類別概率值等相關信息。
class Detect(nn.Module):
stride = None # strides computed during build
export = False # onnx export
def __init__(self, nc, anchors, stride=32):
super(Detect, self).__init__()
self.nc = nc # number of classes
self.no = nc + 5 # number of outputs per anchor
self.nl = len(anchors) # number of detection layers
self.na = len(anchors[0]) // 2 # number of anchors per layer
self.grid = [torch.zeros(1)] * self.nl # init grid
a = torch.tensor(anchors).float().view(self.nl, -1, 2)
self.register_buffer('anchors', a)
self.register_buffer('anchor_grid', a.clone().view(self.nl, 1, -1, 1, 1, 2))
self.m = nn.ModuleList(nn.Conv2d(x, self.no * self.na, 1) for x in [512, 256, 256]) # three conv layers
def forward(self, x):
z = []
self.grid = [torch.zeros(1)] * self.nl
for i in range(self.nl):
x[i] = self.m[i](x[i]) # conv
bs, _, ny, nx = x[i].shape # x(bs,255,20,20) to x(bs,3,20,20,85)
x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()
if self.grid[i].shape[2:4] != x[i].shape[2:4]:
self.grid[i] = self._make_grid(nx, ny).to(x[i].device)
y = x[i].sigmoid()
y[..., 0:2] = (y[..., 0:2] * 2. - 0.5 + self.grid[i]) * self.stride[i] # xy
y[..., 2:4] = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i] # wh
z.append(y.view(bs, -1, self.no))
return torch.cat(z, 1)
3. Neck
Yolov5s的Neck是一個由CSP模塊、SPP模塊和PAN模塊附加而來的部分,其主要功能是信息的優化和整合。CSP模塊是一種含多層卷積的模塊化架構,其主要思想是將相鄰卷積層的通道數量分成兩部分進行計算,增加了模型的複雜性,但也保證了模型的穩定性。SPP模塊已經在Backbone中介紹了,不再贅述。PAN模塊主要是針對高層次和低層次的特徵圖之間的邊界問題,採用了雙線性插值和上/下採樣來調整特徵圖的size。
class SPP(nn.Module):
def __init__(self, c1, c2, k=(5, 9, 13)):
super(SPP, self).__init__()
c_ = c2 // 2 # hidden channels
self.cv1 = BasicBlock(c1, c_, 1, 1)
self.cv2 = BasicBlock(c_ * (2 + len(k)), c2, 1, 1)
self.m = nn.ModuleList([nn.MaxPool2d(kernel_size=x, stride=1, padding=x // 2) for x in k])
def forward(self, x):
y = torch.cat([x] + [m(x) for m in self.m], 1)
return self.cv2(self.cv1(y))
4. 總網絡結構示意圖
下圖是Yolov5s的總網絡結構示意圖,可以清晰地看到其各個部分的層數和組成方式。
三、總結
本文對Yolov5s網絡結構進行了詳細的解析,從多個方面分析了其優點和組成部件,有助於讀者了解現代物體檢測算法和深度學習技術的發展現狀。由於Yolov5s具有高效、高速、高準確性等特點,未來還將有更廣泛的應用和研究空間。
原創文章,作者:DTSB,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/146555.html