點擊訂閱【人工智慧初學者】,讓我們一起前行
YOLOv4-large在COCO上最高可達55.8 AP!速度也高達15 FPS!YOLOv4-tiny的模型實現了1774 FPS!(在RTX 2080Ti上測試)
作者單位:YOLOv4原班人馬
基於CSP方法的YOLOv4目標檢測方法,可以上下縮放,並且適用於小型和大型網絡,同時保持速度和準確性。基於此本文提出了一種網絡縮放方法,該方法不僅可以修改深度、寬度、解析度,還可以修改網絡的結構。YOLOv4-Large模型達到了最先進的結果:在Tesla V100上以15FPS/s的速度,MS COCO數據集的AP為55.8% AP(73.3%AP50)。這是目前所有已發表文章中COCO數據集的最高準確性。YOLOv4-tiny模型在RTX 2080Ti上以443FPS/s的速度實現了22.0%的AP(42.0%AP50),而使用TensorRT,batchsize=4和FP16精度,YOLOv4-tiny的模型實現了1774FPS/s。
首先對YOLOv4進行了重新設計,提出了YOLOv4-CSP,然後在YOLOv4-CSP的基礎上開發了Scaled-YOLOv4。在提出的Scaled-yolov4中討論了線性縮放模型的上界和下界,並分析了小模型和大模型縮放時需要注意的問題。因此,能夠系統地開發YOLOv4-Large和YOLOv4-Tiny模型。
Scaled-YOLOv4能夠在速度和精度之間實現最好的平衡,能夠在15fps、30fps和60fps的視頻以及嵌入式系統上進行實時對象檢測。
2.1、動機分析在對所提出的對象檢測器進行模型縮放後,下一步是處理將發生變化的定量因素,包括帶有定性因素的參數的數量。這些因素包括模型推理時間、平均精度等。根據使用的設備或資料庫,不同的定性因素會有不同的增益效果。
具體對定量因素的分析和設計,以及在低端設備和高端GPU上的微型對象檢測器的定性因素。可以參見原論文。
2.2、Scaled-YOLOv4設計在本節中將重點放在為一般gpu、低端gpu和高端gpu設計縮放YOLOv4上。
2.2.1、CSP-ized YOLOv41、Backbone
在Residual Block中下採樣卷積計算中不包括跨級過程。因此,可以推斷CSPDarknet每個階段的計算量為
由前式可知,CSPDarknet stage只有在k>1時。CSPDarknet53中每個階段擁有的Residual Layer層數分別為1-2-8-8-4。為了獲得更好的速度/精度折中,這裡將第一個CSP階段轉換為Original Darknet Residual Layer。具體結構如下圖:
2、Neck
為了有效地減少計算量,文中對YOLOv4中的PAN體系結構進行了CSP-ize。PAN結構的計算列表如圖2(a)所示。它主要整合來自不同特徵金字塔的特徵,然後通過兩組反向的Original Darknet Residual Layer,沒有shortcut連接。經過CSP-ize,新的計算列表的架構如圖2(b)所示。這個設計有效地減少了40%的計算量。
3、SPP
SPP模塊最初是插入在neck第一個計算列表組的中間位置。因此,作者也將SPP模塊插入到CSP-PAN的第一個計算列表組的中間位置。
class CrossConv(nn.Module):
# Cross Convolution Downsample
def __init__(self, c1, c2, k=3, s=1, g=1, e=1.0, shortcut=False):
# ch_in, ch_out, kernel, stride, groups, expansion, shortcut
super(CrossConv, self).__init__()
c_ = int(c2 * e) # hidden channels
self.cv1 = Conv(c1, c_, (1, k), (1, s))
self.cv2 = Conv(c_, c2, (k, 1), (s, 1), g=g)
self.add = shortcut and c1 == c2
def forward(self, x):
return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))
class C3(nn.Module):
# Cross Convolution CSP
def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5): # ch_in, ch_out, number, shortcut, groups, expansion
super(C3, self).__init__()
c_ = int(c2 * e) # hidden channels
self.cv1 = Conv(c1, c_, 1, 1)
self.cv2 = nn.Conv2d(c1, c_, 1, 1, bias=False)
self.cv3 = nn.Conv2d(c_, c_, 1, 1, bias=False)
self.cv4 = Conv(2 * c_, c2, 1, 1)
self.bn = nn.BatchNorm2d(2 * c_) # applied to cat(cv2, cv3)
self.act = nn.LeakyReLU(0.1, inplace=True)
self.m = nn.Sequential(*[CrossConv(c_, c_, 3, 1, g, 1.0, shortcut) for _ in range(n)])
def forward(self, x):
y1 = self.cv3(self.m(self.cv1(x)))
y2 = self.cv2(x)
return self.cv4(self.act(self.bn(torch.cat((y1, y2), dim=1))))
class Sum(nn.Module):
# Weighted sum of 2 or more layers https://arxiv.org/abs/1911.09070
def __init__(self, n, weight=False): # n: number of inputs
super(Sum, self).__init__()
self.weight = weight # apply weights boolean
self.iter = range(n - 1) # iter object
if weight:
self.w = nn.Parameter(-torch.arange(1., n) / 2, requires_grad=True) # layer weights
def forward(self, x):
y = x[0] # no weight
if self.weight:
w = torch.sigmoid(self.w) * 2
for i in self.iter:
y = y + x[i + 1] * w[i]
else:
for i in self.iter:
y = y + x[i + 1]
return y
2.3、YOLOv4-tinyYOLOv4-tiny是專為低端GPU設備設計的:
這裡使用PCB架構的CSPOSANet來構成YOLOv4的主幹。設g=b/2為增長率,最終使其增長到b/2+kg = 2b。通過計算得到k=3,其結構如圖3所示。對於每個階段的通道數量和Neck部分了採用YOLOv3-tiny的設計。
2.4、YOLOv4-largeYOLOv4-large是為雲GPU設計的,主要目的是實現高精度的目標檢測。這裡設計了一個完全CSP-ize的模型:YOLOv4-P5,並將其擴展到YOLOv4-P6和YOLOv4-P7。
如圖4所示為YOLOv4-P5、YOLOv4-P6、YOLOv4-P7的結構。作者設計在
實驗表明,當寬度縮放因子為1時,YOLOv4-P6可以在30幀/秒的視頻中達到實時性能。對於YOLOv4-P7來說,當寬度縮放因子等於1.25時,它可以在15fps的視頻中達到實時性能。
3、實驗結果3.1、CSP-ized消融實驗3.2、YOLOv4-tiny消融實驗
3.3、SOTA實驗對比參考
[1] Real-time object detection method based on improved YOLOv4-tiny