Yolov10:詳解、部署、應(yīng)用一站式齊全!
一、前言
在過去的幾年里,YOLOs由于其在計(jì)算成本和檢測(cè)性能之間的有效平衡,已成為實(shí)時(shí)目標(biāo)檢測(cè)領(lǐng)域的主導(dǎo)范式。研究人員探索了YOLO的架構(gòu)設(shè)計(jì)、優(yōu)化目標(biāo)、數(shù)據(jù)擴(kuò)充策略等,取得了顯著進(jìn)展。然而,依賴非極大值抑制(NMS)進(jìn)行后處理阻礙了YOLO的端到端部署,并對(duì)推理延遲產(chǎn)生不利影響。
此外,YOLOs中各種組件的設(shè)計(jì)缺乏全面徹底的檢查,導(dǎo)致明顯的計(jì)算冗余,限制了模型的能力。它提供了次優(yōu)的效率,以及相當(dāng)大的性能改進(jìn)潛力。在這項(xiàng)工作中,目標(biāo)是從后處理和模型架構(gòu)兩個(gè)方面進(jìn)一步提高YOLO的性能效率邊界。為此,首先提出了YOLOs無NMS訓(xùn)練的一致雙重分配,它同時(shí)帶來了有競(jìng)爭(zhēng)力的性能和低推理延遲。此外還介紹了YOLO的整體效率精度驅(qū)動(dòng)模型設(shè)計(jì)策略。
從效率和精度兩個(gè)角度對(duì)YOLO的各個(gè)組件進(jìn)行了全面優(yōu)化,大大減少了計(jì)算開銷,增強(qiáng)了能力。工作成果是新一代用于實(shí)時(shí)端到端目標(biāo)檢測(cè)的YOLO系列,稱為YOLOv10。大量實(shí)驗(yàn)表明,YOLOv10在各種模型尺度上都達(dá)到了最先進(jìn)的性能和效率。例如,在COCO上的類似AP下,YOLOv10-Sis1.8比RT-DETR-R18快1.8倍,同時(shí)享受的參數(shù)和FLOP數(shù)量少2.8倍。與YOLOv9-C相比,在相同的性能下,YOLOv10-B的延遲減少了46%,參數(shù)減少了25%。
二、背景
實(shí)時(shí)物體檢測(cè)一直是計(jì)算機(jī)視覺領(lǐng)域的研究熱點(diǎn),其目的是在低延遲下準(zhǔn)確預(yù)測(cè)圖像中物體的類別和位置。它被廣泛應(yīng)用于各種實(shí)際應(yīng)用,包括自動(dòng)駕駛、機(jī)器人導(dǎo)航和物體跟蹤等。近年來,研究人員專注于設(shè)計(jì)基于CNN的物體檢測(cè)器,以實(shí)現(xiàn)實(shí)時(shí)檢測(cè)。
其中,YOLOs由于其在性能和效率之間的巧妙平衡而越來越受歡迎。YOLO的檢測(cè)流水線由兩部分組成:模型前向處理和NMS后處理。然而,這兩種方法仍然存在不足,導(dǎo)致準(zhǔn)確性和延遲邊界不理想。具體而言,YOLO通常在訓(xùn)練期間采用一對(duì)多標(biāo)簽分配策略,其中一個(gè)基本事實(shí)對(duì)象對(duì)應(yīng)于多個(gè)正樣本。盡管產(chǎn)生了優(yōu)越的性能,但這種方法需要NMS在推理過程中選擇最佳的正預(yù)測(cè)。這降低了推理速度,并使性能對(duì)NMS的超參數(shù)敏感,從而阻止YOLO實(shí)現(xiàn)最佳的端到端部署。解決這個(gè)問題的一條途徑是采用最近引入的端到端DETR架構(gòu)。例如,RT-DETR提供了一種高效的混合編碼器和不確定性最小的查詢選擇,將DETR推向了實(shí)時(shí)應(yīng)用領(lǐng)域。然而,部署DETR的固有復(fù)雜性阻礙了其實(shí)現(xiàn)精度和速度之間最佳平衡的能力。另一條線是探索基于CNN的檢測(cè)器的端到端檢測(cè),它通常利用一對(duì)一的分配策略來抑制冗余預(yù)測(cè)。
然而,它們通常會(huì)引入額外的推理開銷或?qū)崿F(xiàn)次優(yōu)性能。此外,模型架構(gòu)設(shè)計(jì)仍然是YOLO面臨的一個(gè)基本挑戰(zhàn),它對(duì)準(zhǔn)確性和速度有著重要影響。為了實(shí)現(xiàn)更高效、更有效的模型架構(gòu),研究人員探索了不同的設(shè)計(jì)策略。為增強(qiáng)特征提取能力,為主干提供了各種主要計(jì)算單元,包括DarkNet、CSPNet、EfficientRep和ELAN等。對(duì)于頸部,探索了PAN、BiC、GD和RepGFPN等,以增強(qiáng)多尺度特征融合。此外,還研究了模型縮放策略和重新參數(shù)化技術(shù)。盡管這些努力取得了顯著進(jìn)展,但仍然缺乏從效率和準(zhǔn)確性角度對(duì)YOLO中的各種組件進(jìn)行全面檢查。因此,YOLO中仍然存在相當(dāng)大的計(jì)算冗余,導(dǎo)致參數(shù)利用效率低下和效率次優(yōu)。此外,由此產(chǎn)生的約束模型能力也導(dǎo)致較差的性能,為精度改進(jìn)留下了充足的空間。
三、新技術(shù)
Consistent Dual Assignments for NMS-free Training
在訓(xùn)練期間,YOLOs通常利用TAL為每個(gè)實(shí)例分配多個(gè)陽性樣本。一對(duì)多分配的采用產(chǎn)生了豐富的監(jiān)控信號(hào),有助于優(yōu)化并實(shí)現(xiàn)卓越的性能。然而,YOLO必須依賴NMS后處理,這導(dǎo)致部署的推理效率不理想。雖然以前的工作探索一對(duì)一匹配來抑制冗余預(yù)測(cè),但它們通常會(huì)引入額外的推理開銷或產(chǎn)生次優(yōu)性能。在這項(xiàng)工作中,為YOLO提供了一種無NMS的訓(xùn)練策略,該策略具有雙標(biāo)簽分配和一致的匹配度量,實(shí)現(xiàn)了高效率和有競(jìng)爭(zhēng)力的性能。
- Dual label assignments
與一對(duì)多分配不同,一對(duì)一匹配只為每個(gè)地面實(shí)況分配一個(gè)預(yù)測(cè),避免了NMS的后處理。然而,它導(dǎo)致監(jiān)督不力,從而導(dǎo)致精度和收斂速度不理想。幸運(yùn)的是,這種不足可以通過一對(duì)多分配來彌補(bǔ)。為了實(shí)現(xiàn)這一點(diǎn),為YOLO引入了雙重標(biāo)簽分配,以結(jié)合兩種策略中的最佳策略。具體而言,如下圖(a)所示。
為YOLO引入了另一個(gè)一對(duì)一的頭。它保留了與原始一對(duì)多分支相同的結(jié)構(gòu)并采用了相同的優(yōu)化目標(biāo),但利用一對(duì)一匹配來獲得標(biāo)簽分配。在訓(xùn)練過程中,兩個(gè)頭部與模型共同優(yōu)化,讓骨干和頸部享受到一對(duì)多任務(wù)提供的豐富監(jiān)督。在推理過程中,丟棄一對(duì)多的頭,并利用一對(duì)一的頭進(jìn)行預(yù)測(cè)。這使得YOLO能夠進(jìn)行端到端部署,而不會(huì)產(chǎn)生任何額外的推理成本。此外,在一對(duì)一的匹配中,采用了前一名的選擇,在較少的額外訓(xùn)練時(shí)間下實(shí)現(xiàn)了與Hungarian matching相同的性能。
- Consistent matching metric
在分配過程中,一對(duì)一和一對(duì)多方法都利用一個(gè)指標(biāo)來定量評(píng)估預(yù)測(cè)和實(shí)例之間的一致性水平。為了實(shí)現(xiàn)兩個(gè)分支的預(yù)測(cè)感知匹配,使用統(tǒng)一的匹配度量:
在雙標(biāo)簽分配中,一對(duì)多分支比一對(duì)一分支提供更豐富的監(jiān)控信號(hào)。直觀地說,如果能夠?qū)⒁粚?duì)一頭部的監(jiān)管與一對(duì)多頭部的監(jiān)管相協(xié)調(diào),就可以朝著一對(duì)多的頭部優(yōu)化的方向?qū)σ粚?duì)一的頭部進(jìn)行優(yōu)化。因此,一對(duì)一頭部可以在推理過程中提供改進(jìn)的樣本質(zhì)量,從而獲得更好的性能。為此,首先分析了兩個(gè)之間的監(jiān)管差距。由于訓(xùn)練過程中的隨機(jī)性,一開始就用兩個(gè)用相同值初始化的頭開始檢查,并產(chǎn)生相同的預(yù)測(cè),即一對(duì)一的頭和一對(duì)多的頭為每個(gè)預(yù)測(cè)實(shí)例對(duì)生成相同的p和IoU。注意到兩個(gè)分支的回歸目標(biāo)。
當(dāng)to2m,i=u*時(shí),它達(dá)到最小值,即,i是中的最佳正樣本?, 如上圖(a)所示。為了實(shí)現(xiàn)這一點(diǎn),提出了一致的匹配度量,即αo2o=r·αo2m和βo2o=r·βo2m,這意味著mo2o=mro2m。因此,一對(duì)多頭部的最佳陽性樣本也是一對(duì)一頭部的最佳樣本。因此,兩個(gè)頭部可以一致且和諧地進(jìn)行優(yōu)化。為了簡單起見,默認(rèn)取r=1,即αo2o=αo2m和βo2o=βo2m。為了驗(yàn)證改進(jìn)的監(jiān)督對(duì)齊,在訓(xùn)練后計(jì)算一對(duì)多結(jié)果的前1/5/10內(nèi)的一對(duì)一匹配對(duì)的數(shù)量。如上圖(b),在一致匹配方法下,對(duì)準(zhǔn)得到改善。
由于篇幅有限,YOLOv10 的一大創(chuàng)新點(diǎn)便是引入了一種雙重標(biāo)簽分配策略,其核心思想便是在訓(xùn)練階段使用一對(duì)多的檢測(cè)頭提供更多的正樣本來豐富模型的訓(xùn)練;而在推理階段則通過梯度截?cái)嗟姆绞剑袚Q為一對(duì)一的檢測(cè)頭,如此一來便不在需要 NMS 后處理,在保持性能的同時(shí)減少了推理開銷。原理其實(shí)不難,可以看下代碼理解下:
#https://github.com/THU-MIG/yolov10/blob/main/ultralytics/nn/modules/head.py
class v10Detect(Detect):
max_det = -1
def __init__(self, nc=80, ch=()):
super().__init__(nc, ch)
c3 = max(ch[0], min(self.nc, 100)) # channels
self.cv3 = nn.ModuleList(nn.Sequential(nn.Sequential(Conv(x, x, 3, g=x), Conv(x, c3, 1)), \
nn.Sequential(Conv(c3, c3, 3, g=c3), Conv(c3, c3, 1)), \
nn.Conv2d(c3, self.nc, 1)) for i, x in enumerate(ch))
self.one2one_cv2 = copy.deepcopy(self.cv2)
self.one2one_cv3 = copy.deepcopy(self.cv3)
def forward(self, x):
one2one = self.forward_feat([xi.detach() for xi in x], self.one2one_cv2, self.one2one_cv3)
if not self.export:
one2many = super().forward(x)
if not self.training:
one2one = self.inference(one2one)
if not self.export:
return {'one2many': one2many, 'one2one': one2one}
else:
assert(self.max_det != -1)
boxes, scores, labels = ops.v10postprocess(one2one.permute(0, 2, 1), self.max_det, self.nc)
return torch.cat([boxes, scores.unsqueeze(-1), labels.unsqueeze(-1)], dim=-1)
else:
return {'one2many': one2many, 'one2one': one2one}
def bias_init(self):
super().bias_init()
'''Initialize Detect() biases, WARNING: requires stride availability.'''
m = self # self.model[-1] # Detect() module
# cf = torch.bincount(torch.tensor(np.concatenate(dataset.labels, 0)[:, 0]).long(), minlength=nc) + 1
# ncf = math.log(0.6 / (m.nc - 0.999999)) if cf is None else torch.log(cf / cf.sum()) # nominal class frequency
for a, b, s in zip(m.one2one_cv2, m.one2one_cv3, m.stride): # from
a[-1].bias.data[:] = 1.0 # box
b[-1].bias.data[: m.nc] = math.log(5 / m.nc / (640 / s) ** 2) # cls (.01 objects, 80 classes, 640 img)
Holistic Efficiency-Accuracy Driven Model Design
架構(gòu)改進(jìn):
- Backbone & Neck:使用了先進(jìn)的結(jié)構(gòu)如 CSPNet 作為骨干網(wǎng)絡(luò),和 PAN 作為頸部網(wǎng)絡(luò),優(yōu)化了特征提取和多尺度特征融合。
- 大卷積核與分區(qū)自注意力:這些技術(shù)用于增強(qiáng)模型從大范圍上下文中學(xué)習(xí)的能力,提高檢測(cè)準(zhǔn)確性而不顯著增加計(jì)算成本。
- 整體效率:引入空間-通道解耦下采樣和基于秩引導(dǎo)的模塊設(shè)計(jì),減少計(jì)算冗余,提高整體模型效率。
四、實(shí)驗(yàn)
與最先進(jìn)的比較。潛伏性是通過官方預(yù)訓(xùn)練的模型來測(cè)量的。潛在的基因測(cè)試在具有前處理的模型的前處理中保持了潛在性。?是指YOLOv10的結(jié)果,其本身對(duì)許多訓(xùn)練NMS來說都是如此。以下是所有結(jié)果,無需添加先進(jìn)的訓(xùn)練技術(shù),如知識(shí)提取或PGI或公平比較:
五、部署測(cè)試
首先,按照官方主頁將環(huán)境配置好,注意這里 python 版本至少需要 3.9 及以上,torch 版本可以根據(jù)自己本地機(jī)器安裝合適的版本,默認(rèn)下載的是 2.0.1:
conda create -n yolov10 pythnotallow=3.9
conda activate yolov10
pip install -r requirements.txt
pip install -e .
安裝完成之后,我們簡單執(zhí)行下推理命令測(cè)試下效果:
yolo predict model=yolov10s.pt source=ultralytics/assets/bus.jpg
讓我們嘗試部署一下,譬如先導(dǎo)出個(gè) onnx 模型出來看看:
yolo export model=yolov10s.pt format=onnx opset=13 simplify
好了,接下來通過執(zhí)行 pip install netron 安裝個(gè)可視化工具來看看導(dǎo)出的節(jié)點(diǎn)信息:
# run python fisrt
import netron
netron.start('/path/to/yolov10s.onnx')
先直接通過 Ultralytics 框架預(yù)測(cè)一個(gè)測(cè)試下能否正常推理:
yolo predict model=yolov10s.onnx source=ultralytics/assets/bus.jpg
大家可以對(duì)比下上面的運(yùn)行結(jié)果,可以看出 performance 是有些許的下降。問題不大,讓我們基于 onnxruntime 寫一個(gè)簡單的推理腳本,代碼地址如下,有興趣的可以自行查看:
# 推理腳本
https://github.com/CVHub520/X-AnyLabeling/blob/main/tools/export_yolov10_onnx.py
# onnx 模型權(quán)重
https://github.com/CVHub520/X-AnyLabeling/releases/tag/v2.3.6