<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          實(shí)踐教程|使用YOLO V5訓(xùn)練自動(dòng)駕駛目標(biāo)檢測(cè)網(wǎng)絡(luò)

          共 18845字,需瀏覽 38分鐘

           ·

          2021-11-10 01:19

          ↑ 點(diǎn)擊藍(lán)字?關(guān)注極市平臺(tái)

          作者丨William@知乎(已授權(quán))
          來源丨自動(dòng)駕駛?cè)珬9こ處熤鯇冢?/span>
          https://www.zhihu.com/people/william.hyin/columns
          編輯丨極市平臺(tái)

          極市導(dǎo)讀

          ?

          本文詳細(xì)介紹YOLO V5的網(wǎng)絡(luò)結(jié)構(gòu)及組成模塊,并使用YOLO V5s在BDD100K自動(dòng)駕駛數(shù)據(jù)集上進(jìn)行遷移學(xué)習(xí),搭建屬于自己的自動(dòng)駕駛交通物體對(duì)象識(shí)別網(wǎng)絡(luò)。?>>加入極市CV技術(shù)交流群,走在計(jì)算機(jī)視覺的最前沿

          YOLO 是一種快速緊湊的開源對(duì)象檢測(cè)模型,與其它網(wǎng)絡(luò)相比,同等尺寸下性能更強(qiáng),并且具有很不錯(cuò)的穩(wěn)定性,是第一個(gè)可以預(yù)測(cè)對(duì)象的類別和邊界框的端對(duì)端神經(jīng)網(wǎng)絡(luò)。YOLO 家族一直有著旺盛的生命力,從YOLO V1一直到”V5“,如今已經(jīng)延續(xù)五代,憑借著不斷的創(chuàng)新和完善,一直被計(jì)算機(jī)視覺工程師作為對(duì)象檢測(cè)的首選框架之一。

          Ultralytics于5月27日發(fā)布了YOLOv5 的第一個(gè)正式版本,其性能與YOLO V4不相伯仲,是現(xiàn)今最先進(jìn)的對(duì)象檢測(cè)技術(shù)之一,并在推理速度上是目前最強(qiáng)。

          Ultralyticshttps://github.com/ultralytics/yolov5

          我在前一篇文章:一文讀懂YOLO V5 與 YOLO V4介紹了YOLO V5和YOLO V4的原理,相似點(diǎn)及區(qū)別。

          在本文章中,我會(huì)詳細(xì)介紹YOLO V5的網(wǎng)絡(luò)結(jié)構(gòu)及組成模塊,并使用YOLO V5s對(duì)BDD100K自動(dòng)駕駛數(shù)據(jù)集進(jìn)行遷移學(xué)習(xí),使得訓(xùn)練出的模型能夠識(shí)別包括交通燈顏色在內(nèi)的所有交通對(duì)象。

          Github: https://github.com/williamhyin/yolov5s_bdd100k

          Email: [email protected]

          知乎專欄: 自動(dòng)駕駛?cè)珬9こ處?https://www.zhihu.com/people/william.hyin

          本文分成兩塊:模型結(jié)構(gòu)及遷移學(xué)習(xí)

          • Model architecture
            • Overview
            • Focus
            • BottleneckCSP
            • SPP
            • PANET
          • Transfer learning
            • Data prepration
            • Setup enviorment
            • Configuration
            • Modify model architecture
            • Transfer learning theory
            • Inference

          Model architecture

          YOLO網(wǎng)絡(luò)由三個(gè)主要組件組成:

          1)Backbone -在不同圖像細(xì)粒度上聚合并形成圖像特征的卷積神經(jīng)網(wǎng)絡(luò)。

          2)Neck:一系列混合和組合圖像特征的網(wǎng)絡(luò)層,并將圖像特征傳遞到預(yù)測(cè)層。

          3)Head:對(duì)圖像特征進(jìn)行預(yù)測(cè),生成邊界框和并預(yù)測(cè)類別。

          本文主要采用YOLO V5 1.0結(jié)構(gòu),7月23日作者更新了2.0版本代碼,對(duì)于模型定義做了些改變,我會(huì)后續(xù)進(jìn)行更新。

          YOLO V5 1.0中用到的重要的模塊包括Focus,BottleneckCSP,SPP,PANET。模型的上采樣Upsample是采用nearst兩倍上采樣插值。值得注意的是YOLO V5 1.0最初為COCO數(shù)據(jù)集訓(xùn)練的Pretrained_model 使用的是FPN作為Neck,在6月22日后,Ultralytics已經(jīng)更新模型的Neck為PANET。網(wǎng)上很多的YOLO V5網(wǎng)絡(luò)結(jié)構(gòu)介紹都是基于FPN-NECK,本文的模型訓(xùn)練是基于PANET-NECK,下文中只介紹PANET-NECK。

          對(duì)于YOLO V5,無論是V5s,V5m,V5l還是V5x其Backbone,NeckHead一致。唯一的區(qū)別在與模型的深度和寬度設(shè)置,只需要修改這兩個(gè)參數(shù)就可以調(diào)整模型的網(wǎng)絡(luò)結(jié)構(gòu)。V5l 的參數(shù)是默認(rèn)參數(shù)。

          • depth multiple是用來控制模型的深度,例如V5s的深度是0.33,而V5l的深度是1,也就是說V5l的Bottleneck個(gè)數(shù)是V5s的3倍。
          • width_multiple是用來控制卷積核的個(gè)數(shù),V5s的寬度是0.5,而V5l的寬度是1,表示V5s的卷積核數(shù)量是默認(rèn)設(shè)置的一半,當(dāng)然你也可以設(shè)置到1.25倍,即V5x。例如下面YOLO V5的yaml文件中的backbone的第一層是 [[-1, 1, Focus, [64, 3]],而V5s的寬度是0.5,因此這一層實(shí)際上是[[-1, 1, Focus, [32, 3]]
          • from列參數(shù):-1 代表是從上一層獲得的輸入,-2表示從上兩層獲得的輸入(head同理)。
          • number列參數(shù):1表示只有一個(gè),3表示有三個(gè)相同的模塊。

          下圖為YOLO V5 1.0的網(wǎng)絡(luò)結(jié)構(gòu)圖(默認(rèn)對(duì)應(yīng)YOLO V5l),引用自Laughing-q(https://blog.csdn.net/Q1u1NG)。

          下圖中存在三種括號(hào),其中 In_channel:輸入通道,out_channel:輸出通道,Kernel_size:卷積核大小,Stride:步長(zhǎng),x N代表此模塊的疊加次數(shù),方框外數(shù)字:depth x weight x height,默認(rèn)輸入為寬高為640x640的三通道圖像。


          下文我將詳細(xì)講述Focus,BottleneckCSP,SPP,PANET這幾個(gè)重要模塊,由于本項(xiàng)目使用YOLO V5s網(wǎng)絡(luò)結(jié)構(gòu)訓(xùn)練模型,因此下文中的網(wǎng)絡(luò)圖及實(shí)例都基于YOLO V5s,并且輸入圖像為3x640x640。YOLO V5默認(rèn)depth_multiple=0.33, width_multiple=0.50。即BottleneckCSP中Bottleneck的數(shù)量為默認(rèn)的1/3,而所有卷積操作的卷積核個(gè)數(shù)均為默認(rèn)的1/2。

          Focus

          下圖為YOLO V5s的Focus 隔行采樣拼接結(jié)構(gòu)。


          YOLO V5默認(rèn)3x640x640的輸入,復(fù)制四份,然后通過切片操作將這個(gè)四個(gè)圖片切成了四個(gè)3x320x320的切片,接下來使用concat從深度上連接這四個(gè)切片,輸出為12x320x320,之后再通過卷積核數(shù)為32的卷積層,生成32x320x320的輸出,最后經(jīng)過batch_borm 和leaky_relu將結(jié)果輸入到下一個(gè)卷積層。

          Focus的代碼分析如下

          class?Focus(nn.Module):
          ????#?Focus?wh?information?into?c-space
          ????def?__init__(self,?c1,?c2,?k=1,?s=1,?p=None,?g=1,?act=True):??#?ch_in,?ch_out,?kernel,?stride,?padding,?groups
          ????????super(Focus,?self).__init__()
          ????????self.conv?=?Conv(c1?*?4,?c2,?k,?s,?p,?g,?act)

          ????def?forward(self,?x):??#?x(b,c,w,h)?->?y(b,4c,w/2,h/2)
          ????????return?self.conv(torch.cat([x[...,?::2,?::2],?x[...,?1::2,?::2],?x[...,?::2,?1::2],?x[...,?1::2,?1::2]],?1))

          核心為這段代碼self.conv(torch.cat([x[..., ::2, ::2], x[..., 1::2, ::2], x[..., ::2, 1::2], x[..., 1::2, 1::2]], 1)) 。x[..., ::2, ::2]是黃色部分,x[..., 1::2, ::2],是紅色部分,以此類推。對(duì)于x[..., ::2, ::2]其中第一個(gè)參數(shù)“..."代表深度,也就是說三個(gè)通道都要切,第二個(gè)和第三個(gè)代表不論是寬和高都是每隔一個(gè)采樣。對(duì)于x[..., 1::2, ::2],1::2代表從列位置1開始,也就是每序號(hào)奇數(shù)列采樣。藍(lán)色,綠色的生成方式以此類推。最后用cat連接這些隔行采樣圖,生成通道數(shù)為12的特征圖。

          BottlenneckCSP

          下圖為YOLO V5s的第一個(gè)BottlenneckCSP結(jié)構(gòu)。


          BottlenneckCSP分為兩部分,Bottlenneck以及CSP。

          • Bottlenneck

          Bottlenneck其實(shí)就是經(jīng)典的殘差結(jié)構(gòu),先是1x1的卷積層(conv+batch_norm+leaky relu),然后再是3x3的卷積層,最后通過殘差結(jié)構(gòu)與初始輸入相加。

          值得注意的是YOLO V5通過depth multiple控制模型的深度,例如V5s的深度是0.33,而V5l的深度是1,也就是說V5x的BottlenneckCSP中Bottleneck個(gè)數(shù)是V5s的3倍,模型中第一個(gè)BottlenneckCSP默認(rèn)Bottleneck個(gè)數(shù)x3,對(duì)于V5s只有上圖中的一個(gè)Bottleneck。

          作者的代碼如下,值得注意的是e就是width_multiple,表示當(dāng)前操作卷積核個(gè)數(shù)占默認(rèn)個(gè)數(shù)的比例:

          class?Bottleneck(nn.Module):
          ????#?Standard?bottleneck
          ????def?__init__(self,?c1,?c2,?shortcut=True,?g=1,?e=0.5):??#?ch_in,?ch_out,?shortcut,?groups,?expansion
          ????????super(Bottleneck,?self).__init__()
          ????????c_?=?int(c2?*?e)??#?hidden?channels
          ????????self.cv1?=?Conv(c1,?c_,?1,?1)
          ????????self.cv2?=?Conv(c_,?c2,?3,?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?BottleneckCSP(nn.Module):
          ????#?CSP?Bottleneck?https://github.com/WongKinYiu/CrossStagePartialNetworks
          ????def?__init__(self,?c1,?c2,?n=1,?shortcut=True,?g=1,?e=0.5):??#?ch_in,?ch_out,?number,?shortcut,?groups,?expansion
          ????????super(BottleneckCSP,?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(*[Bottleneck(c_,?c_,?shortcut,?g,?e=1.0)?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))))
          • CSP

          下圖為YOLO V5s的CSP結(jié)構(gòu),也就是說將原輸入分成兩個(gè)分支,分別進(jìn)行卷積操作使得通道數(shù)減半,然后分支一進(jìn)行Bottlenneck x N操作,隨后concat分支一和分支二,從而使得BottlenneckCSP的輸入與輸出是一樣的大小,目的是為了讓模型學(xué)習(xí)到更多的特征。


          很多人都對(duì)yaml文件中[[-1, 3, BottleneckCSP, [1024, False]]False的作用不太理解,其實(shí)這就是關(guān)閉了shortcut的選項(xiàng)。

          def?__init__(self,?c1,?c2,?n=1,?shortcut=True,?g=1,?e=0.5)

          下圖是YOLO V5s 中BottlenneckCSP有無False選項(xiàng)的結(jié)構(gòu)對(duì)比:


          SPP

          下圖為YOLO V5s的SPP結(jié)構(gòu)。


          SPP的輸入是512x20x20,經(jīng)過1x1的卷積層后輸出256x20x20,然后經(jīng)過并列的三個(gè)Maxpool進(jìn)行下采樣,將結(jié)果與其初始特征相加,輸出1024x20x20,最后用512的卷積核將其恢復(fù)到512x20x20。

          作者代碼如下,重點(diǎn)是Maxpool操作:

          class?SPP(nn.Module):
          ????#?Spatial?pyramid?pooling?layer?used?in?YOLOv3-SPP
          ????def?__init__(self,?c1,?c2,?k=(5,?9,?13)):
          ????????super(SPP,?self).__init__()
          ????????c_?=?c1?//?2??#?hidden?channels
          ????????self.cv1?=?Conv(c1,?c_,?1,?1)
          ????????self.cv2?=?Conv(c_?*?(len(k)?+?1),?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):
          ????????x?=?self.cv1(x)
          ????????return?self.cv2(torch.cat([x]?+?[m(x)?for?m?in?self.m],?1))

          PANET

          YOLO V5 1.0最初一版模型使用FPN作為NECK,后續(xù)在6月22號(hào)已經(jīng)全面更新為PANET。PANET基于 Mask R-CNN 和 FPN 框架,加強(qiáng)了信息傳播,具有準(zhǔn)確保留空間信息的能力,這有助于對(duì)像素進(jìn)行適當(dāng)?shù)亩ㄎ灰孕纬裳谀!?/p>

          下圖中pi 代表 CSP 主干網(wǎng)絡(luò)中的一個(gè)特征層

          https://arxiv.org/pdf/1803.01534.pdf

          該網(wǎng)絡(luò)的特征提取器采用了一種新的增強(qiáng)自下向上路徑的 FPN 結(jié)構(gòu),改善了低層特征的傳播(a部分)。第三條通路的每個(gè)階段都將前一階段的特征映射作為輸入,并用3x3卷積層處理它們。輸出通過橫向連接被添加到自上而下通路的同一階段特征圖中,這些特征圖為下一階段提供信息(b部分)。橫向連接,有助于縮短路徑,被稱為shortcut連接。同時(shí)使用適應(yīng)特征池化(Adaptive feature pooling)恢復(fù)每個(gè)候選區(qū)域和所有特征層次之間被破壞的信息路徑,聚合每個(gè)特征層次上的每個(gè)候選區(qū)域,避免被任意分配(c部分)。對(duì)于 Mask-RCNN(e部分),FCN可以保留空間信息并減少網(wǎng)絡(luò)中的參數(shù)數(shù)量,但是由于參數(shù)是為所有空間位置共享的,因此該網(wǎng)路實(shí)際上并未學(xué)習(xí)如何使用像素位置進(jìn)行預(yù)測(cè)。而FC對(duì)位置敏感,可以適應(yīng)不同的空間位置。因此PANet使用來自Fully Convolutional Network (FCN)和Fully-connected layers(FC)的信息提供更準(zhǔn)確的掩碼預(yù)測(cè)。

          YOLO V5借鑒了YOLO V4的修改版PANET結(jié)構(gòu)。

          PANET通常使用自適應(yīng)特征池將相鄰層加在一起,以進(jìn)行掩模預(yù)測(cè)。但是,當(dāng)在YOLOv4中使用PANET時(shí),此方法略麻煩,因此,YOLO V4的作者沒有使用自適應(yīng)特征池添加相鄰層,而是對(duì)其進(jìn)行Concat操作,從而提高了預(yù)測(cè)的準(zhǔn)確性。

          https://arxiv.org/abs/2004.10934

          YOLO V5同樣采用了級(jí)聯(lián)操作。詳情可以參看模型大圖及Netron網(wǎng)絡(luò)圖中對(duì)應(yīng)的Concat操作。

          Transfer learning

          在自定義數(shù)據(jù)集上訓(xùn)練YOLO V5,包括以下幾個(gè)步驟:

          1. 準(zhǔn)備數(shù)據(jù)集
          2. 環(huán)境設(shè)定
          3. 配置/修改文件和目錄結(jié)構(gòu)
          4. 訓(xùn)練
          5. 推理
          6. 結(jié)果

          Data Prepration

          在準(zhǔn)備數(shù)據(jù)集方面,最重要的是明白YOLO家族獨(dú)特的標(biāo)簽數(shù)據(jù)集格式。

          每個(gè)圖片文件.jpg,都有同一命名的標(biāo)簽文件.txt。

          標(biāo)簽文件中每個(gè)對(duì)象獨(dú)占一行,格式為 。

          其中:

          • -表示對(duì)象的類別序號(hào):從0 到 (classes-1)
          • -參照?qǐng)D片寬度和高度的相對(duì)比例(浮點(diǎn)數(shù)值),從0.0到1.0
          • 例如: = / = /
          • 注意: 是矩形的中心,而不是左上角位置。

          如下圖所示:

          https://realelectricwizard.wordpress.com/2019/03/24/training-yolo-v3-on-custom-data-set-on-linux/

          接下來我們要清楚YOLO V5的訓(xùn)練文件結(jié)構(gòu)是什么。

          YOLO V5的標(biāo)簽文件夾和圖像文件夾應(yīng)位于同一目錄下。

          其次自定義數(shù)據(jù)集應(yīng)該分成Train,Valid, Test三個(gè)部分,比例可以按照7:2:1分配。由于BDD100k數(shù)據(jù)集已經(jīng)為我們分好了Train,Valid, Test三部分,因此我們不需要自己分割數(shù)據(jù)集。

          下圖為YOLO V5的訓(xùn)練文件結(jié)構(gòu):


          讓我們來看看BDD100K數(shù)據(jù)集的概覽。

          BDD100K是最大的開放式駕駛視頻數(shù)據(jù)集之一,其中包含10萬個(gè)視頻和10個(gè)任務(wù),目的是方便評(píng)估自動(dòng)駕駛圖像識(shí)別算法的的進(jìn)展。每個(gè)高分辨率視頻一共40秒。該數(shù)據(jù)集包括超過1000個(gè)小時(shí)的駕駛數(shù)據(jù),總共超過1億幀。這些視頻帶有GPU / IMU數(shù)據(jù)以獲取軌跡信息。該數(shù)據(jù)集具有地理,環(huán)境和天氣多樣性,從而能讓模型能夠識(shí)別多種場(chǎng)景,具備更多的泛化能力。這些豐富的戶外場(chǎng)景和復(fù)雜的車輛運(yùn)動(dòng)使感知任務(wù)更具挑戰(zhàn)性。該數(shù)據(jù)集上的任務(wù)包括圖像標(biāo)記,車道檢測(cè),可駕駛區(qū)域分割,道路對(duì)象檢測(cè),語義分割,實(shí)例分割,多對(duì)象檢測(cè)跟蹤,多對(duì)象分割跟蹤,領(lǐng)域自適應(yīng)和模仿學(xué)習(xí)。

          我們可以在BDD100K數(shù)據(jù)網(wǎng)站上下載數(shù)據(jù):https://bdd-data.berkeley.edu/

          Bdd100k的標(biāo)簽是由Scalabel(https://www.scalabel.ai/)生成的JSON格式。

          -?labels?[?]:
          ????-?id:?int32
          ????-?category:?string?(classification)
          ????-?manualShape:?boolean?(whether?the?shape?of?the?label?is?created?or?modified?manually)
          ????-?manualAttributes:?boolean?(whether?the?attribute?of?the?label?is?created?or?modified?manually)
          ????-?score:?float?(the?confidence?or?some?other?ways?of?measuring?the?quality?of?the?label.)
          ????-?attributes:
          ????????-?occluded:?boolean
          ????????-?truncated:?boolean
          ????????-?trafficLightColor:?"red|green|yellow|none"
          ????????-?areaType:?"direct?|?alternative"?(for?driving?area)
          ????????-?laneDirection:?"parallel|vertical"?(for?lanes)
          ????????-?laneStyle:?"solid?|?dashed"?(for?lanes)
          ????????-?laneTypes:?(for?lanes)
          ????-?box2d:
          ???????-?x1:?float
          ???????-?y1:?float
          ???????-?x2:?float
          ???????-?y2:?float

          道路對(duì)象類別包括以下幾類:

          [
          ????"bike",
          ????"bus",
          ????"car",
          ????"motor",
          ????"person",
          ????"rider",
          ????"traffic?light",
          ????"traffic?sign",
          ????"train",
          ????"truck"
          ]

          我們實(shí)際關(guān)注的只有- labels [ ]欄目下的內(nèi)容。

          現(xiàn)在我們可以開始轉(zhuǎn)換Bdd100k的標(biāo)簽為YOLO 格式了。

          Berkerley 提供了Bdd100k數(shù)據(jù)集的標(biāo)簽查看及標(biāo)簽格式轉(zhuǎn)化工具。由于沒有直接從bdd100k轉(zhuǎn)換成YOLO的工具,因此我們首先得使用將bdd100k的標(biāo)簽轉(zhuǎn)換為coco格式,然后再將coco格式轉(zhuǎn)換為yolo格式。

          • bdd to coco

          我的目的是識(shí)別包括不同顏色交通燈在內(nèi)的所有交通對(duì)象,因此我們需要對(duì)原版的bdd2coco.py進(jìn)行一些修改,以獲取交通燈顏色并產(chǎn)生新的類別。

          這是修改完的核心代碼:

          for?label?in?i['labels']:
          ????????????annotation?=?dict()
          ????????????category=label['category']
          ????????????if?(category?==?"traffic?light"):
          ????????????????color?=?label['attributes']['trafficLightColor']
          ????????????????category?=?"tl_"?+?color
          ????????????if?category?in?id_dict.keys():
          ????????????????empty_image?=?False
          ????????????????annotation["iscrowd"]?=?0
          ????????????????annotation["image_id"]?=?image['id']
          ????????????????x1?=?label['box2d']['x1']
          ????????????????y1?=?label['box2d']['y1']
          ????????????????x2?=?label['box2d']['x2']
          ????????????????y2?=?label['box2d']['y2']
          ????????????????annotation['bbox']?=?[x1,?y1,?x2-x1,?y2-y1]
          ????????????????annotation['area']?=?float((x2?-?x1)?*?(y2?-?y1))
          ????????????????annotation['category_id']?=?id_dict[category]
          ????????????????annotation['ignore']?=?0
          ????????????????annotation['id']?=?label['id']
          ????????????????annotation['segmentation']?=?[[x1,?y1,?x1,?y2,?x2,?y2,?x2,?y1]]
          ????????????????annotations.append(annotation)

          在完成bdd100k格式到y(tǒng)olo格式的轉(zhuǎn)換后,會(huì)獲得bdd100k_labels_images_det_coco_train.jsonbdd100k_labels_images_det_coco_val.json兩個(gè)文件。

          • Coco to yolo

          在完成先前的轉(zhuǎn)換之后,我們需要將訓(xùn)練集和驗(yàn)證集的coco格式標(biāo)簽轉(zhuǎn)換為yolo格式。注意需要分別指定訓(xùn)練集和驗(yàn)證集圖片位置,對(duì)應(yīng)的coco標(biāo)簽文件位置,及生成yolo標(biāo)簽的目標(biāo)位置。

          config_train?={
          ????????"datasets":?"COCO",
          ????????"img_path":?"bdd100k_images/bdd100k/images/100k/train",
          ????????"label":?"labels/bdd100k_labels_images_det_coco_train.json",
          ????????"img_type":?".jpg",
          ????????"manipast_path":?"./",
          ????????"output_path":?"labels/trains/",
          ????????"cls_list":?"bdd100k.names",
          ????}
          ????config_valid?={
          ????????"datasets":?"COCO",
          ????????"img_path":?"bdd100k_images/bdd100k/images/100k/val",
          ????????"label":?"labels/bdd100k_labels_images_det_coco_val.json",
          ????????"img_type":?".jpg",
          ????????"manipast_path":?"./",
          ????????"output_path":?"labels/valids/",
          ????????"cls_list":?"bdd100k.names",
          ????}

          除此之外,我們還得將所有的類別寫入bdd100k.names文件。

          person
          rider
          car
          bus
          truck
          bike
          motor
          tl_green
          tl_red
          tl_yellow
          tl_none
          traffic?sign
          train
          tl_green

          運(yùn)行Bdd_preprocessing中的完整代碼可以完成Bdd100k格式標(biāo)簽到Y(jié)OLO標(biāo)簽格式的轉(zhuǎn)換。

          Bdd2coco以及coco2yolo的詳細(xì)說明可以參看bdd100k代碼庫和convert2Yolo代碼庫。

          bdd100k代碼庫:https://github.com/ucbdrive/bdd100k

          convert2Yolo代碼庫:https://github.com/ssaru/convert2Yolo

          為了方便將重心放在YOLO V5模型訓(xùn)練上,我為大家提供了預(yù)處理過后的Bdd100k數(shù)據(jù)集(https://1drv.ms/u/s!An7G4eYRvZzthI5HCnVaEGvrdiDWAw?e=v6C4US),該預(yù)處理過后的數(shù)據(jù)集可以直接用來訓(xùn)練YOLO V5對(duì)象檢測(cè)網(wǎng)絡(luò)。

          Setup environment

          運(yùn)行YOLO V5的第一步是克隆YOLO V5的官方代碼庫。

          YOLO V5 需要的Pytorch版本>=1.5, Python版本3.7, CUDA版本10.2。

          Ultralytics提供了requirement.txt文件來方便新環(huán)境配置。

          通過在shell中運(yùn)行pip install \-r requirement.txt 命令,可以自動(dòng)安裝所有依賴項(xiàng)。

          numpy==1.17
          scipy==1.4.1
          cudatoolkit==10.2.89
          opencv-python
          torch==1.5
          torchvision==0.6.0
          matplotlib
          pycocotools
          tqdm
          pillow
          tensorboard
          pyyaml

          Configuration

          YOLO V5的默認(rèn)YAML文件coco.yaml 中是coco數(shù)據(jù)集所有的類對(duì)象名稱和類數(shù)量(80)。由于我們的目的是基于bdd100k數(shù)據(jù)集來訓(xùn)練檢測(cè)少量特定交通物體的模型,我們不需要訓(xùn)練檢測(cè)80類網(wǎng)絡(luò)的模型,所有我們得重新創(chuàng)建一個(gè)uc_data.yaml文件來描述bdd100k數(shù)據(jù)集的數(shù)據(jù)特性。由于我們模型的輸出不是coco數(shù)據(jù)集的80個(gè)類,而是13類,因此我們得修改此處的輸出類別數(shù)量為13。

          #?here?you?need?to?specify?the?files?train,?test?and?validation?txt?
          train:?bdd100k/images/train
          val:?bdd100k/images/valid
          test:?bdd100k/images/test

          nc:?13
          names:?['person','rider','car','bus','truck','bike','motor','tl_green','tl_red','tl_yellow','tl_none','t_sign','train']

          之后我們會(huì)用到上述YAML文件來訓(xùn)練模型。

          Modify Model arichtecture

          YOLO V5通過models文件家中的cfg文件*.yaml來調(diào)整訓(xùn)練模型的結(jié)構(gòu)。

          由于我們模型的輸出不是coco數(shù)據(jù)集的80個(gè)類,而是13類,因此我們需要修改模型的對(duì)象預(yù)測(cè)層輸出類別數(shù)量為13。

          #?parameters
          nc:?13??#?number?of?classes

          我們可以直接修改YAML文件下各個(gè)組件的細(xì)節(jié)(如數(shù)字),來重新定義自己的模型架構(gòu)。

          #?YOLO?V5s
          #?parameters
          nc:?13??#?number?of?classes
          depth_multiple:?0.33??#?model?depth?multiple
          width_multiple:?0.50??#?layer?channel?multiple

          #?anchors
          anchors:
          ??-?[116,90,?156,198,?373,326]??#?P5/32
          ??-?[30,61,?62,45,?59,119]??#?P4/16
          ??-?[10,13,?16,30,?33,23]??#?P3/8

          #?YOLOv5?backbone
          backbone:
          ??#?[from,?number,?module,?args]
          ??[[-1,?1,?Focus,?[64,?3]],??#?0-P1/2
          ???[-1,?1,?Conv,?[128,?3,?2]],??#?1-P2/4
          ???[-1,?3,?BottleneckCSP,?[128]],
          ???[-1,?1,?Conv,?[256,?3,?2]],??#?3-P3/8
          ???[-1,?9,?BottleneckCSP,?[256]],
          ???[-1,?1,?Conv,?[512,?3,?2]],??#?5-P4/16
          ???[-1,?9,?BottleneckCSP,?[512]],
          ???[-1,?1,?Conv,?[1024,?3,?2]],?#?7-P5/32
          ???[-1,?1,?SPP,?[1024,?[5,?9,?13]]],
          ??]

          #?YOLOv5?head
          head:
          ??[[-1,?3,?BottleneckCSP,?[1024,?False]],??#?9

          ???[-1,?1,?Conv,?[512,?1,?1]],
          ???[-1,?1,?nn.Upsample,?[None,?2,?'nearest']],
          ???[[-1,?6],?1,?Concat,?[1]],??#?cat?backbone?P4
          ???[-1,?3,?BottleneckCSP,?[512,?False]],??#?13

          ???[-1,?1,?Conv,?[256,?1,?1]],
          ???[-1,?1,?nn.Upsample,?[None,?2,?'nearest']],
          ???[[-1,?4],?1,?Concat,?[1]],??#?cat?backbone?P3
          ???[-1,?3,?BottleneckCSP,?[256,?False]],
          ???[-1,?1,?nn.Conv2d,?[na?*?(nc?+?5),?1,?1]],??#?18?(P3/8-small)

          ???[-2,?1,?Conv,?[256,?3,?2]],
          ???[[-1,?14],?1,?Concat,?[1]],??#?cat?head?P4
          ???[-1,?3,?BottleneckCSP,?[512,?False]],
          ???[-1,?1,?nn.Conv2d,?[na?*?(nc?+?5),?1,?1]],??#?22?(P4/16-medium)

          ???[-2,?1,?Conv,?[512,?3,?2]],
          ???[[-1,?10],?1,?Concat,?[1]],??#?cat?head?P5
          ???[-1,?3,?BottleneckCSP,?[1024,?False]],
          ???[-1,?1,?nn.Conv2d,?[na?*?(nc?+?5),?1,?1]],??#?26?(P5/32-large)

          ???[[],?1,?Detect,?[nc,?anchors]],??#?Detect(P5,?P4,?P3)
          ??]

          為了更清楚的了解YOLO V5的模型結(jié)構(gòu),我們使用netron(https://github.com/lutzroeder/netron)來實(shí)現(xiàn)模型可視化,值得注意的是,如果想獲得清晰的網(wǎng)絡(luò)圖,需要將pt文件轉(zhuǎn)化為torchscipt格式。


          以下鏈接為YOLO V5s的網(wǎng)絡(luò)圖:

          由于Bdd100k數(shù)據(jù)集與COCO數(shù)據(jù)的數(shù)據(jù)量級(jí),場(chǎng)景及部分對(duì)象類別相近,因此我并沒有修改模型結(jié)構(gòu)。如果將YOLO V5運(yùn)用在一些小數(shù)據(jù)場(chǎng)景或者對(duì)象類別相差較大的場(chǎng)景如醫(yī)學(xué)視覺,則可以根據(jù)實(shí)際情況增減模型。

          Transfer learning theory

          現(xiàn)在讓我們來了解下本文的重點(diǎn)遷移學(xué)習(xí)。

          什么是遷移學(xué)習(xí)?遷移學(xué)習(xí)(Transfer learning) 顧名思義就是就是把已學(xué)訓(xùn)練好的模型參數(shù)遷移到新的模型來幫助新模型訓(xùn)練??紤]到大部分?jǐn)?shù)據(jù)或任務(wù)是存在相關(guān)性的,所以通過遷移學(xué)習(xí)我們可以將已經(jīng)學(xué)到的模型參數(shù)(也可理解為模型學(xué)到的知識(shí))通過某種方式來分享給新模型從而加快并優(yōu)化模型的學(xué)習(xí)效率不用像大多數(shù)網(wǎng)絡(luò)那樣從零學(xué)習(xí)(starting from scratch,tabula rasa)。

          https://www.zhihu.com/question/41979241/answer/123545914

          再來看看我們面臨的問題,我們已經(jīng)有了YOLO V5模型框架,有了針對(duì)COCO數(shù)據(jù)集預(yù)訓(xùn)練的權(quán)重文件*.pt,Bdd100k的訓(xùn)練數(shù)據(jù)很龐大,而我們需要額外提取紅綠燈的顏色作為新的類別,那怎么樣才能把YOLO V5已經(jīng)學(xué)習(xí)的模型參數(shù)通過某種方式分享給新模型從而加快并優(yōu)化模型的學(xué)習(xí)效率?

          下圖為針對(duì)不同場(chǎng)景的遷移學(xué)習(xí)指南。

          • 如果訓(xùn)練集小,訓(xùn)練數(shù)據(jù)與預(yù)訓(xùn)練數(shù)據(jù)相似,那么我們可以凍住卷積層,直接訓(xùn)練全連接層。
          • 如果訓(xùn)練集小,訓(xùn)練數(shù)據(jù)與預(yù)訓(xùn)練數(shù)據(jù)不相似,那么必須從頭訓(xùn)練卷積層及全連接層。
          • 如果訓(xùn)練集大,訓(xùn)練數(shù)據(jù)與預(yù)訓(xùn)練數(shù)據(jù)相似,那么我們可以使用預(yù)訓(xùn)練的權(quán)重參數(shù)初始化網(wǎng)絡(luò),然后從頭開始訓(xùn)練。
          • 如果訓(xùn)練集大,訓(xùn)練數(shù)據(jù)與預(yù)訓(xùn)練數(shù)據(jù)不相似,那么我們可以使用預(yù)訓(xùn)練的權(quán)重參數(shù)初始化網(wǎng)絡(luò),然后從頭開始訓(xùn)練或者完全不使用預(yù)訓(xùn)練權(quán)重,重新開始從頭訓(xùn)練。
          • 值得注意的是,對(duì)于大數(shù)據(jù)集,不推薦凍住卷積層,直接訓(xùn)練全連接層的方式,這可能會(huì)對(duì)性能造成很大影響。

          我們的情況,符合上述第三種,通常只需要使用預(yù)訓(xùn)練的權(quán)重初始化網(wǎng)絡(luò),然后直接從頭開始訓(xùn)練,從而更快的使模型有效收斂。但是由于之前沒有人公開過對(duì)于Bdd100k數(shù)據(jù)集使用YOLO V5預(yù)訓(xùn)練權(quán)重和不使用其訓(xùn)練權(quán)重的對(duì)比,甚至你也可以說COCO數(shù)據(jù)集80類,而Bdd100k數(shù)據(jù)集13類,兩者大部分類是不相似的。我并不能百分百確定哪個(gè)方案更適合本項(xiàng)目。于是我分別使用YOLO V5s預(yù)訓(xùn)練權(quán)重和不使用其訓(xùn)練權(quán)重來訓(xùn)練基于Bdd100k數(shù)據(jù)集的對(duì)象識(shí)別網(wǎng)絡(luò),并對(duì)比它們的效果。

          Ultralytics(https://github.com/ultralytics/yolov5)一共提供了四個(gè)版本的YOLO V5模型。

          下圖是它們的比較:

          YOLO V5x是非常巨型的網(wǎng)絡(luò),同樣也是訓(xùn)練精度最好的網(wǎng)絡(luò),關(guān)于YOLO V5x與YOLO V4的性能對(duì)比尚未有百分百定論,根據(jù)WongKinYiu的6月22日的Benchmarks結(jié)論,YOLO V4仍然稍微優(yōu)于YOLO V5x,但是根據(jù)最近很多kaggle比賽的同學(xué)反映,YOLO V5的比賽結(jié)果普遍由于YOLO V4,當(dāng)然不排除這是tensorflow和pytorch等版本的YOLO V4優(yōu)化不夠。我覺得YOLO V5最驚艷的是它的速度和尺寸。因此我在本文中只使用YOLO V5s來訓(xùn)練基于Bdd100k自動(dòng)駕駛數(shù)據(jù)集的對(duì)象檢測(cè)深度網(wǎng)絡(luò)。另外一個(gè)影響因素是,Bdd100k的數(shù)據(jù)集龐大,YOLO V5s在 Intel Xeon W-2145 ,64 GB RAM,NVIDIA RTX 2080Ti,batch_size 32, Use RAM cache的情況下訓(xùn)練300 epochs 需要66小時(shí),YOLO V5x是它的三倍。還是等我有時(shí)間再訓(xùn)練下YOLO V5x吧~

          Traininig

          在我們完成所有的準(zhǔn)備工作之后,我們可以開始訓(xùn)練了!

          準(zhǔn)備文件

          • YOLO v5代碼庫
          • 預(yù)處理后的bdd100k數(shù)據(jù)集:將JSON標(biāo)簽轉(zhuǎn)換為YOLO格式,并按照YOLO V5的訓(xùn)練文件結(jié)構(gòu)要求布置
          • custom_yolov5s.yaml:修改后的模型文件
          • uc_data.yaml: 包含訓(xùn)練,驗(yàn)證集的位置,類別數(shù)目及名稱

          訓(xùn)練配置

          • Intel Xeon W-2145 ,64 GB RAM,NVIDIA RTX 2080Ti。

          訓(xùn)練參數(shù)(基于bdd100k數(shù)據(jù)集進(jìn)行分析):

          • — img: 輸入圖像的大小,建議使用640,因?yàn)閷?duì)于交通場(chǎng)景,輸入圖片尺寸過小時(shí),會(huì)導(dǎo)致部分對(duì)象寬高小于3像素,可能會(huì)影響訓(xùn)練精度
          • — batch-size: 批次大小,對(duì)于2080Ti-11GB 或者P100-16GB,輸入img-size 640,batch-size 32為上限
          • — epochs: 訓(xùn)練迭代數(shù),作者建議訓(xùn)練300個(gè)epochs起
          • — data: 創(chuàng)建的 YAML 文件uc_data.yaml
          • — cfg: 模型文件Custom_yolov5s.yaml,需要自己至少修改類別數(shù)量及類別種類
          • — weights: 對(duì)于本項(xiàng)目不使用預(yù)訓(xùn)練權(quán)重,如果需要預(yù)訓(xùn)練權(quán)重,可以訪問此地址
          • — cache-images: 將預(yù)處理后的訓(xùn)練數(shù)據(jù)全部存儲(chǔ)在RAM中,能夠加快訓(xùn)練速度
          • — hyp: 這個(gè)參數(shù)是自定義的hyp.yaml地址,對(duì)于小尺寸數(shù)據(jù),可以更改hyp中optimizer為Adam,并修改配套參數(shù)為作者預(yù)設(shè)的Adam參數(shù)
          • — rect:輸入這個(gè)參數(shù),會(huì)關(guān)閉Mosaic數(shù)據(jù)增強(qiáng)
          • — resume:從上次訓(xùn)練的結(jié)束last.pt繼續(xù)訓(xùn)練
          • — nosave:輸入這個(gè)參數(shù)將存儲(chǔ)最后的checkpoint,可以加快整體訓(xùn)練速度,但是建議關(guān)閉這個(gè)參數(shù),這樣能保留best.pt
          • — notest:只測(cè)試最后一個(gè)epoch,能加快整體訓(xùn)練速度
          • — noautoanchor:關(guān)閉自適應(yīng)自適應(yīng)錨定框,YOLO V5會(huì)自動(dòng)分析當(dāng)前錨定框的 Best Possible Recall (BPR) ,對(duì)于img-size 640,最佳BPR為0.9900,隨著img-size降低,BPR也隨之變差
          • — multi-scale:輸入圖像多尺度訓(xùn)練,在訓(xùn)練過程中,輸入圖像會(huì)自動(dòng)resize至 img-size +/- 50%,能一定程度上防止模型過擬合,但是對(duì)于GPU顯存要求很高,對(duì)于640的img-size至少使用16GB顯存,才能保證運(yùn)行不出錯(cuò)
          • — single-cls:模型的輸出為單一類別,比如我只需要識(shí)別Trunk
          • — device: 選擇使用CUDA或者CPU

          YOLO V5的作者建議至少訓(xùn)練300個(gè)回合,每次訓(xùn)練完成后所有的結(jié)果及權(quán)重會(huì)儲(chǔ)存在runs文件夾下。

          訓(xùn)練過程

          • Train from pre-weight(橘黃色)
          !python?train.py?--img?640?--batch?32?--epochs?300?--data?'./models/uc_data.yaml'?--cfg?./models/custom_yolov5s.yaml?--weights?"./weights/yolov5s.pt"?--name?yolov5s_bdd_prew??--cache
          • Train from scatch(藍(lán)色)
          !python?train.py?--img?640?--batch?32?--epochs?300?--data?'./models/uc_data.yaml'?--cfg?./models/custom_yolov5s.yaml?--weights?""?--name?yolov5s_bdd??--cache

          訓(xùn)練結(jié)果

          • Metrics
          • Train loss
          • Valid loss

          結(jié)果分析

          • Train from pre-weight和Train from scatch的最高mAP_0.5均能達(dá)到46.5%。
          • Train from pre-weight比Train from scatch能更快收斂,但是在250epochs左右兩者已經(jīng)達(dá)到一致。
          • Train from pre-weight和Train from scatch的模型大小均為14.8M,值得注意的是YOLO V5在訓(xùn)練結(jié)束后會(huì)自動(dòng)給模型剪枝,訓(xùn)練過程中的last.pt有58.6M,作者考慮的非常周到。
          • 總的來說Train from pre-weight比Train from scatch能更快收斂,能一定程度上減少訓(xùn)練時(shí)間開銷,對(duì)于和COCO數(shù)據(jù)集相近的數(shù)據(jù)集,可以采用Train from pre-weight,如果時(shí)間充裕,Train from scatch更為妥當(dāng)。

          Inference

          現(xiàn)在我們已經(jīng)完成了模型訓(xùn)練了,讓我們?cè)谝恍﹫D像上測(cè)試它的性能吧。

          檢測(cè)參數(shù):

          • — weights: 訓(xùn)練權(quán)重的路徑
          • — source:推理目標(biāo)的路徑,可以是圖片,視頻,網(wǎng)絡(luò)攝像頭等
          • — source:推理結(jié)果的輸出路徑
          • — img-size:推理圖片的大小
          • — conf-thres:對(duì)象置信閾值,默認(rèn)0.4
          • — iou-thres:NMS的IOU閾值,可以根據(jù)實(shí)際對(duì)象的重疊度調(diào)節(jié),默認(rèn)0.5
          • — device: 選擇使用CUDA或者CPU
          • — view-img:顯示所有推理結(jié)果
          • — save-txt:將每一幀的推理結(jié)果及邊界框的位置,存入*.txt文件
          • — classes:類別過濾,意思是只推理目標(biāo)類別
          • — agnostic-nms:使用agnostic-nms NMS(https://www.quora.com/What-does-
          !python?detect.py?--weights?runs/exp0_yolov5s_bdd_prew/weights/best_yolov5s_bdd_prew.pt??--source?bdd100k/images/test?--save-txt

          為了測(cè)試YOLO V5s的實(shí)時(shí)視頻處理性能,我測(cè)試了一個(gè)4K 道路場(chǎng)景錄制視頻,推理速度高達(dá)7ms/幀。


          點(diǎn)擊下方鏈接可以直接訪問bilibili上的完整視頻:

          https://www.bilibili.com/video/BV1sz4y1Q7wi/

          Summary

          至此我們已經(jīng)了解了YOLO V5的網(wǎng)絡(luò)結(jié)構(gòu),并且基于Bdd100k數(shù)據(jù)集訓(xùn)練了屬于自己的自動(dòng)駕駛對(duì)象檢測(cè)模型。YOLO V5是個(gè)非常棒的開源對(duì)象檢測(cè)網(wǎng)絡(luò),代碼庫的更新速度非???,不管它現(xiàn)階段配不配的上V5的名稱,它都是一個(gè)快速而且強(qiáng)大的對(duì)象檢測(cè)器。YOLO V5值得你去嘗試!

          如果覺得有用,就請(qǐng)分享到朋友圈吧!

          △點(diǎn)擊卡片關(guān)注極市平臺(tái),獲取最新CV干貨

          公眾號(hào)后臺(tái)回復(fù)“CVPR21檢測(cè)”獲取CVPR2021目標(biāo)檢測(cè)論文下載~


          極市干貨
          神經(jīng)網(wǎng)絡(luò):視覺神經(jīng)網(wǎng)絡(luò)模型優(yōu)秀開源工作:timm庫使用方法和最新代碼解讀
          技術(shù)綜述:綜述:神經(jīng)網(wǎng)絡(luò)中 Normalization 的發(fā)展歷程CNN輕量化模型及其設(shè)計(jì)原則綜述
          算法技巧(trick):8點(diǎn)PyTorch提速技巧匯總圖像分類算法優(yōu)化技巧


          #?CV技術(shù)社群邀請(qǐng)函?#

          △長(zhǎng)按添加極市小助手
          添加極市小助手微信(ID : cvmart4)

          備注:姓名-學(xué)校/公司-研究方向-城市(如:小極-北大-目標(biāo)檢測(cè)-深圳)


          即可申請(qǐng)加入極市目標(biāo)檢測(cè)/圖像分割/工業(yè)檢測(cè)/人臉/醫(yī)學(xué)影像/3D/SLAM/自動(dòng)駕駛/超分辨率/姿態(tài)估計(jì)/ReID/GAN/圖像增強(qiáng)/OCR/視頻理解等技術(shù)交流群


          每月大咖直播分享、真實(shí)項(xiàng)目需求對(duì)接、求職內(nèi)推、算法競(jìng)賽、干貨資訊匯總、與?10000+來自港科大、北大、清華、中科院、CMU、騰訊、百度等名校名企視覺開發(fā)者互動(dòng)交流~



          覺得有用麻煩給個(gè)在看啦~??
          瀏覽 61
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  蜜芽av在线观看 欧美成人免费精品 | 欧美三级片在线观看 | 91资源在线播放 | 亚州第一成人网站 | 五月天色色网址 |