yolov3如何配置和使用
⑴ 高大上的YOLOV3對象檢測演算法,使用python也可輕松實現
繼續我們的目標檢測演算法的分享,前期我們介紹了SSD目標檢測演算法的python實現以及Faster-RCNN目標檢測演算法的python實現以及yolo目標檢測演算法的darknet的window環境安裝,本期我們簡單介紹一下如何使用python來進行YOLOV3的對象檢測演算法
YOLOV3的基礎知識大家可以參考往期文章,本期重點介紹如何使用python來實現
1、初始化模型
14-16 行:
模型的初始化依然使用cv下的DNN模型來載入模型,需要注意的是CV的版本需要大於3.4.2
5-8行:
初始化模型在coco上的label以便後期圖片識別使用
10-12行:
初始化圖片顯示方框的顏色
2、載入圖片,進行圖片識別
輸入識別的圖片進行圖片識別,這部分代碼跟往期的SSD 以及RCNN目標檢測演算法類似
19-20行:輸入圖片,獲取圖片的長度與寬度
25-29行:計算圖片的blob值,輸入神經網路,進行前向反饋預測圖片
只不過net.forward裡面是ln, 神經網路的所有out層
3、遍歷所有的out層,獲取檢測圖片的label與置信度
遍歷out層,獲取檢測到的label值以及置信度,檢測到這里YOLOV3以及把所有的檢測計算完成,但是由於yolov3對重疊圖片或者靠的比較近的圖片檢測存在一定的問題,使用YOLOV3使用非最大值抑制來抑制弱的重疊邊界
竟然把墨鏡識別了手機,體現了YOLOV3在重疊圖片識別的缺點
4、應用非最大值抑制來抑制弱的重疊邊界,顯示圖片
56: 使用 非最大值抑制來抑制弱的重疊邊界
58-59行:遍歷所有圖片
61-62行:提取檢測圖片的BOX
64-68行:顯示圖片信息
70-71行:顯示圖片
利用python來實現YOLOV3,與SSD 以及RCNN代碼有很多類似的地方,大家可以參考往期的文章進行對比學習,把代碼執行一遍
進行視頻識別的思路:從視頻中提取圖片,進行圖片識別,識別完成後,再把識別的結果實時體現在視頻中,這部分代碼結合前期的視頻識別,大家可以參考多進程視頻實時識別篇,因為沒有多進程,檢測速度很慢,視頻看著比較卡
1、初始化模型以及視頻流
2、從視頻中提取圖片,進行圖片的blob值計算,進行神經網路的預測
3、提取檢測到圖片的置信度以及ID值
4、 應用非最大值抑制來抑制弱的重疊邊界,顯示圖片
5、關閉資源,顯示圖片處理信息
每個目標檢測演算法都有自己的優缺點,個人感覺,在精度要求不是太高的情況下SSD檢測演算法可以實現較快的速度實現,畢竟精度差不多的情況下,我們希望速度越快越好
⑵ yolov3對顯卡的要求
他對於顯卡的要求不是特別高,現在hd5650都可以完全支持。
⑶ 目標檢測-YOLOv3
傳統的目標檢測演算法適用的場景有限,而且維護成本很大。深度學習方法應用於目標檢測,不僅演算法適應性好,還可以進行遷移學習,降低成本。
深度學習目標檢測演算法中,基於錨框(Anchor)的方法主要分為 一階段 方法和 兩階段 方法。
兩階段 方法先對感興趣的區域進行選擇,然後進一步對候選框內做分類和回歸,最終輸出選擇的框以及對應的分類。兩階段的模型有R-CNN系列,比如 R-CNN,Fast-RCNN,Faster-RCNN 等。兩階段模型的優點是精度高,但是速度及較慢。
一階段 方法直接對anchor進行回歸和分類,得到最終目標框和類別,演算法有 YOLOv2,v3,SSD,RetinaNet 等。一階段模型的推理速度較快,但是相對的精度會下降一些。
此外還有一些 anchor-free 的方法,包括基於關鍵點的檢測演算法以及基於中心檢測演算法等。
下面是一些基礎概念和縮寫:
BBox :Bounding Box 邊界框
Anchor :錨框
RoI : Region of Interest 特定的感興趣區域
Region Proposal : 候選區域
RPN : Region proposal network 提取候選區域的網路
IoU : Intersaction over Union (Area of Overlap/ Area of Union) 交並比,預測框的質量
mAP :mean average precision
NMS :non-maximum suppression 非極大值抑制
YOLO系列的模型在保有一定精度的基礎上擁有很快的推理速度,在下面圖中YOLOv3的推理速度遠超其他模型,因此在實時監測領域中有很好的應用。
YOLO的名字來源於you only look once,從名字上就道出了YOLO的精髓。
YOLOv1將圖像劃分為S*S個網路,物體真實框的中心落在哪個網格上,哪個網格對應的錨框就負責檢測物體。
每個網格會預測一個邊界框以及對應的置信度,這里的置信度反映的是模型認為這個框里包含著物體的把握以及它預測到這個物體的精確程度。所以置信度就等於 。如果物體不存在,那麼置信度應該等於零。
每個邊界框會預測5個值 。(x,y)坐標表示框相對於網格單元邊界的中心。 w,y是相對於整個圖像預測寬度和高度。 最後,置信度預測表示預測框與任何真實框之間的IOU。
YOLOv2在v1的基礎上進行了優化,骨幹網路使用了DarkNet19,並且將輸入圖片給尺寸從224增大到448,並且將網路結構設為全卷積網路結構加上Batch Norm,使用了Kmeans聚類方法來計算anchor,引入了多尺度訓練,使網路在訓練過程中學習不同尺度的圖像。不過待改進的地方有在小目標上召回率不高,靠近的群體目標檢測效果不好,檢測精度還有優化空間。
YOLOv3使用了更加深的骨幹網路DarkNet53,同時加入了多尺度預測,在COCO數據集上聚類; 9中不同尺度的anchor,在分類上使用sigmoid激活函數,支持了目標的多分類。YOLOv3的優點是推理速度快,性價比高,通用性強;缺點是召回率較低,定位精度較差,對於靠近或者遮擋的群體、小物體的檢測能力相對較弱。
YOLOv3在v1的基礎上做了很多改動。
邊界框預測
YOLOv3使用聚類預測到的邊界框作為錨框。網路為邊界框預測4個坐標值 ,如果單元格從圖像的左上角偏移了 ,並且先驗邊界框的寬度和高度為 ,則預測如下圖:
YOLOv3給每個邊界框用邏輯回歸預測一個objectness score,如果某個邊界框和真實框重合度比其他都高,那麼它的objectness score應該是1。而其他框雖然也與真實框有重疊,會被忽略掉。
類別預測
使用的是sigmoid函數,沒有用softmax因為沒必要。
不同尺度的預測
YOLOv3使用k-means聚類來確定bounding box priors,選擇了9個clusters和3個scales,然後在整個scales上均勻分割clusters。在COCO數據集上,9個cluster分別為(10×13),(16×30),(33×23),(30×61),(62×45),(59×119),(116×90) ,(156×198),(373×326)。
特徵提取
YOLOv3使用了Darknet-53,特點是加入了殘差,比之前的網路更深了(有53層卷積層所以叫Darknet-53)。
借一張圖看一下YOLOv3的整個流程:
每個輸出分支上對應著三個尺寸的先驗框(總共3 3=9種尺度)。經過32倍下采樣的網格,每一個網格對應著輸入圖像上32 32的區域,適合檢測尺寸較大的目標,而8倍下采樣的網格適合檢測尺寸小的目標。
輸出特徵的高度H和寬度W,相當於將圖像劃分為H*W個網格,而不是直接在圖像上畫網格。也就是說32倍下采樣之後得到的 ,相當於在輸入圖像上劃一個 的網格,每一個網格對應著輸出特徵圖上的一個點。
特徵圖的C通道上表示預測框的信息,包括坐標信息 ,目標置信度,分類。
C=B*(1+4+class_num),B為特徵圖上分配的錨框個數。
損失函數有三個,分類損失,定位損失和objectness損失。分類使用sigmoid激活函數,loss是sigmoid cross entropy。定位損失在x,y上使用sigmoid函數和sigmoid cross entropy損失,在w,h上使用L1損失。objectness損失用的是sigmoid激活函數和sigmoid cross entropy損失。
對於與真實框重疊的框,三種損失都要計算
對於沒有真實框重疊的框,只計算objectness(0);對於與真實框重疊但不是最匹配的框,忽略它們。
⑷ 目標檢測演算法(R-CNN,fast R-CNN,faster R-CNN,yolo,SSD,yoloV2,yoloV3)
深度學習目前已經應用到了各個領域,應用場景大體分為三類:物體識別,目標檢測,自然語言處理。 目標檢測可以理解為是物體識別和物體定位的綜合 ,不僅僅要識別出物體屬於哪個分類,更重要的是得到物體在圖片中的具體位置。
2014年R-CNN演算法被提出,基本奠定了two-stage方式在目標檢測領域的應用。它的演算法結構如下圖
演算法步驟如下:
R-CNN較傳統的目標檢測演算法獲得了50%的性能提升,在使用VGG-16模型作為物體識別模型情況下,在voc2007數據集上可以取得66%的准確率,已經算還不錯的一個成績了。其最大的問題是速度很慢,內存佔用量很大,主要原因有兩個
針對R-CNN的部分問題,2015年微軟提出了Fast R-CNN演算法,它主要優化了兩個問題。
R-CNN和fast R-CNN均存在一個問題,那就是 由選擇性搜索來生成候選框,這個演算法很慢 。而且R-CNN中生成的2000個左右的候選框全部需要經過一次卷積神經網路,也就是需要經過2000次左右的CNN網路,這個是十分耗時的(fast R-CNN已經做了改進,只需要對整圖經過一次CNN網路)。這也是導致這兩個演算法檢測速度較慢的最主要原因。
faster R-CNN 針對這個問題, 提出了RPN網路來進行候選框的獲取,從而擺脫了選擇性搜索演算法,也只需要一次卷積層操作,從而大大提高了識別速度 。這個演算法十分復雜,我們會詳細分析。它的基本結構如下圖
主要分為四個步驟:
使用VGG-16卷積模型的網路結構:
卷積層採用的VGG-16模型,先將PxQ的原始圖片,縮放裁剪為MxN的圖片,然後經過13個conv-relu層,其中會穿插4個max-pooling層。所有的卷積的kernel都是3x3的,padding為1,stride為1。pooling層kernel為2x2, padding為0,stride為2。
MxN的圖片,經過卷積層後,變為了(M/16) x (N/16)的feature map了。
faster R-CNN拋棄了R-CNN中的選擇性搜索(selective search)方法,使用RPN層來生成候選框,能極大的提升候選框的生成速度。RPN層先經過3x3的卷積運算,然後分為兩路。一路用來判斷候選框是前景還是背景,它先reshape成一維向量,然後softmax來判斷是前景還是背景,然後reshape恢復為二維feature map。另一路用來確定候選框的位置,通過bounding box regression實現,後面再詳細講。兩路計算結束後,挑選出前景候選框(因為物體在前景中),並利用計算得到的候選框位置,得到我們感興趣的特徵子圖proposal。
卷積層提取原始圖像信息,得到了256個feature map,經過RPN層的3x3卷積後,仍然為256個feature map。但是每個點融合了周圍3x3的空間信息。對每個feature map上的一個點,生成k個anchor(k默認為9)。anchor分為前景和背景兩類(我們先不去管它具體是飛機還是汽車,只用區分它是前景還是背景即可)。anchor有[x,y,w,h]四個坐標偏移量,x,y表示中心點坐標,w和h表示寬度和高度。這樣,對於feature map上的每個點,就得到了k個大小形狀各不相同的選區region。
對於生成的anchors,我們首先要判斷它是前景還是背景。由於感興趣的物體位於前景中,故經過這一步之後,我們就可以舍棄背景anchors了。大部分的anchors都是屬於背景,故這一步可以篩選掉很多無用的anchor,從而減少全連接層的計算量。
對於經過了3x3的卷積後得到的256個feature map,先經過1x1的卷積,變換為18個feature map。然後reshape為一維向量,經過softmax判斷是前景還是背景。此處reshape的唯一作用就是讓數據可以進行softmax計算。然後輸出識別得到的前景anchors。
另一路用來確定候選框的位置,也就是anchors的[x,y,w,h]坐標值。如下圖所示,紅色代表我們當前的選區,綠色代表真實的選區。雖然我們當前的選取能夠大概框選出飛機,但離綠色的真實位置和形狀還是有很大差別,故需要對生成的anchors進行調整。這個過程我們稱為bounding box regression。
假設紅色框的坐標為[x,y,w,h], 綠色框,也就是目標框的坐標為[Gx, Gy,Gw,Gh], 我們要建立一個變換,使得[x,y,w,h]能夠變為[Gx, Gy,Gw,Gh]。最簡單的思路是,先做平移,使得中心點接近,然後進行縮放,使得w和h接近。如下:
我們要學習的就是dx dy dw dh這四個變換。由於是線性變換,我們可以用線性回歸來建模。設定loss和優化方法後,就可以利用深度學習進行訓練,並得到模型了。對於空間位置loss,我們一般採用均方差演算法,而不是交叉熵(交叉熵使用在分類預測中)。優化方法可以採用自適應梯度下降演算法Adam。
得到了前景anchors,並確定了他們的位置和形狀後,我們就可以輸出前景的特徵子圖proposal了。步驟如下:
1,得到前景anchors和他們的[x y w h]坐標。
2,按照anchors為前景的不同概率,從大到小排序,選取前pre_nms_topN個anchors,比如前6000個
3,剔除非常小的anchors。
4,通過NMS非極大值抑制,從anchors中找出置信度較高的。這個主要是為了解決選取交疊問題。首先計算每一個選區面積,然後根據他們在softmax中的score(也就是是否為前景的概率)進行排序,將score最大的選區放入隊列中。接下來,計算其餘選區與當前最大score選區的IOU(IOU為兩box交集面積除以兩box並集面積,它衡量了兩個box之間重疊程度)。去除IOU大於設定閾值的選區。這樣就解決了選區重疊問題。
5,選取前post_nms_topN個結果作為最終選區proposal進行輸出,比如300個。
經過這一步之後,物體定位應該就基本結束了,剩下的就是物體識別了。
和fast R-CNN中類似,這一層主要解決之前得到的proposal大小形狀各不相同,導致沒法做全連接。全連接計算只能對確定的shape進行運算,故必須使proposal大小形狀變為相同。通過裁剪和縮放的手段,可以解決這個問題,但會帶來信息丟失和圖片形變問題。我們使用ROI pooling可以有效的解決這個問題。
ROI pooling中,如果目標輸出為MxN,則在水平和豎直方向上,將輸入proposal劃分為MxN份,每一份取最大值,從而得到MxN的輸出特徵圖。
ROI Pooling層後的特徵圖,通過全連接層與softmax,就可以計算屬於哪個具體類別,比如人,狗,飛機,並可以得到cls_prob概率向量。同時再次利用bounding box regression精細調整proposal位置,得到bbox_pred,用於回歸更加精確的目標檢測框。
這樣就完成了faster R-CNN的整個過程了。演算法還是相當復雜的,對於每個細節需要反復理解。faster R-CNN使用resNet101模型作為卷積層,在voc2012數據集上可以達到83.8%的准確率,超過yolo ssd和yoloV2。其最大的問題是速度偏慢,每秒只能處理5幀,達不到實時性要求。
針對於two-stage目標檢測演算法普遍存在的運算速度慢的缺點, yolo創造性的提出了one-stage。也就是將物體分類和物體定位在一個步驟中完成。 yolo直接在輸出層回歸bounding box的位置和bounding box所屬類別,從而實現one-stage。通過這種方式, yolo可實現45幀每秒的運算速度,完全能滿足實時性要求 (達到24幀每秒,人眼就認為是連續的)。它的網路結構如下圖:
主要分為三個部分:卷積層,目標檢測層,NMS篩選層。
採用Google inceptionV1網路,對應到上圖中的第一個階段,共20層。這一層主要是進行特徵提取,從而提高模型泛化能力。但作者對inceptionV1進行了改造,他沒有使用inception mole結構,而是用一個1x1的卷積,並聯一個3x3的卷積來替代。(可以認為只使用了inception mole中的一個分支,應該是為了簡化網路結構)
先經過4個卷積層和2個全連接層,最後生成7x7x30的輸出。先經過4個卷積層的目的是為了提高模型泛化能力。yolo將一副448x448的原圖分割成了7x7個網格,每個網格要預測兩個bounding box的坐標(x,y,w,h)和box內包含物體的置信度confidence,以及物體屬於20類別中每一類的概率(yolo的訓練數據為voc2012,它是一個20分類的數據集)。所以一個網格對應的參數為(4x2+2+20) = 30。如下圖
其中前一項表示有無人工標記的物體落入了網格內,如果有則為1,否則為0。第二項代表bounding box和真實標記的box之間的重合度。它等於兩個box面積交集,除以面積並集。值越大則box越接近真實位置。
分類信息: yolo的目標訓練集為voc2012,它是一個20分類的目標檢測數據集 。常用目標檢測數據集如下表:
| Name | # Images (trainval) | # Classes | Last updated |
| --------------- | ------------------- | --------- | ------------ |
| ImageNet | 450k | 200 | 2015 |
| COCO | 120K | 90 | 2014 |
| Pascal VOC | 12k | 20 | 2012 |
| Oxford-IIIT Pet | 7K | 37 | 2012 |
| KITTI Vision | 7K | 3 | |
每個網格還需要預測它屬於20分類中每一個類別的概率。分類信息是針對每個網格的,而不是bounding box。故只需要20個,而不是40個。而confidence則是針對bounding box的,它只表示box內是否有物體,而不需要預測物體是20分類中的哪一個,故只需要2個參數。雖然分類信息和confidence都是概率,但表達含義完全不同。
篩選層是為了在多個結果中(多個bounding box)篩選出最合適的幾個,這個方法和faster R-CNN 中基本相同。都是先過濾掉score低於閾值的box,對剩下的box進行NMS非極大值抑制,去除掉重疊度比較高的box(NMS具體演算法可以回顧上面faster R-CNN小節)。這樣就得到了最終的最合適的幾個box和他們的類別。
yolo的損失函數包含三部分,位置誤差,confidence誤差,分類誤差。具體公式如下:
誤差均採用了均方差演算法,其實我認為,位置誤差應該採用均方差演算法,而分類誤差應該採用交叉熵。由於物體位置只有4個參數,而類別有20個參數,他們的累加和不同。如果賦予相同的權重,顯然不合理。故yolo中位置誤差權重為5,類別誤差權重為1。由於我們不是特別關心不包含物體的bounding box,故賦予不包含物體的box的置信度confidence誤差的權重為0.5,包含物體的權重則為1。
Faster R-CNN准確率mAP較高,漏檢率recall較低,但速度較慢。而yolo則相反,速度快,但准確率和漏檢率不盡人意。SSD綜合了他們的優缺點,對輸入300x300的圖像,在voc2007數據集上test,能夠達到58 幀每秒( Titan X 的 GPU ),72.1%的mAP。
SSD網路結構如下圖:
和yolo一樣,也分為三部分:卷積層,目標檢測層和NMS篩選層
SSD論文採用了VGG16的基礎網路,其實這也是幾乎所有目標檢測神經網路的慣用方法。先用一個CNN網路來提取特徵,然後再進行後續的目標定位和目標分類識別。
這一層由5個卷積層和一個平均池化層組成。去掉了最後的全連接層。SSD認為目標檢測中的物體,只與周圍信息相關,它的感受野不是全局的,故沒必要也不應該做全連接。SSD的特點如下。
每一個卷積層,都會輸出不同大小感受野的feature map。在這些不同尺度的feature map上,進行目標位置和類別的訓練和預測,從而達到 多尺度檢測 的目的,可以克服yolo對於寬高比不常見的物體,識別准確率較低的問題。而yolo中,只在最後一個卷積層上做目標位置和類別的訓練和預測。這是SSD相對於yolo能提高准確率的一個關鍵所在。
如上所示,在每個卷積層上都會進行目標檢測和分類,最後由NMS進行篩選,輸出最終的結果。多尺度feature map上做目標檢測,就相當於多了很多寬高比例的bounding box,可以大大提高泛化能力。
和faster R-CNN相似,SSD也提出了anchor的概念。卷積輸出的feature map,每個點對應為原圖的一個區域的中心點。以這個點為中心,構造出6個寬高比例不同,大小不同的anchor(SSD中稱為default box)。每個anchor對應4個位置參數(x,y,w,h)和21個類別概率(voc訓練集為20分類問題,在加上anchor是否為背景,共21分類)。如下圖所示:
另外,在訓練階段,SSD將正負樣本比例定位1:3。訓練集給定了輸入圖像以及每個物體的真實區域(ground true box),將default box和真實box最接近的選為正樣本。然後在剩下的default box中選擇任意一個與真實box IOU大於0.5的,作為正樣本。而其他的則作為負樣本。由於絕大部分的box為負樣本,會導致正負失衡,故根據每個box類別概率排序,使正負比例保持在1:3。SSD認為這個策略提高了4%的准確率
另外,SSD採用了數據增強。生成與目標物體真實box間IOU為0.1 0.3 0.5 0.7 0.9的patch,隨機選取這些patch參與訓練,並對他們進行隨機水平翻轉等操作。SSD認為這個策略提高了8.8%的准確率。
和yolo的篩選層基本一致,同樣先過濾掉類別概率低於閾值的default box,再採用NMS非極大值抑制,篩掉重疊度較高的。只不過SSD綜合了各個不同feature map上的目標檢測輸出的default box。
SSD基本已經可以滿足我們手機端上實時物體檢測需求了,TensorFlow在Android上的目標檢測官方模型ssd_mobilenet_v1_android_export.pb,就是通過SSD演算法實現的。它的基礎卷積網路採用的是mobileNet,適合在終端上部署和運行。
針對yolo准確率不高,容易漏檢,對長寬比不常見物體效果差等問題,結合SSD的特點,提出了yoloV2。它主要還是採用了yolo的網路結構,在其基礎上做了一些優化和改進,如下
網路採用DarkNet-19:19層,裡麵包含了大量3x3卷積,同時借鑒inceptionV1,加入1x1卷積核全局平均池化層。結構如下
yolo和yoloV2隻能識別20類物體,為了優化這個問題,提出了yolo9000,可以識別9000類物體。它在yoloV2基礎上,進行了imageNet和coco的聯合訓練。這種方式充分利用imageNet可以識別1000類物體和coco可以進行目標位置檢測的優點。當使用imageNet訓練時,只更新物體分類相關的參數。而使用coco時,則更新全部所有參數。
YOLOv3可以說出來直接吊打一切圖像檢測演算法。比同期的DSSD(反卷積SSD), FPN(feature pyramid networks)准確率更高或相仿,速度是其1/3.。
YOLOv3的改動主要有如下幾點:
不過如果要求更精準的預測邊框,採用COCO AP做評估標準的話,YOLO3在精確率上的表現就弱了一些。如下圖所示。
當前目標檢測模型演算法也是層出不窮。在two-stage領域, 2017年Facebook提出了mask R-CNN 。CMU也提出了A-Fast-RCNN 演算法,將對抗學習引入到目標檢測領域。Face++也提出了Light-Head R-CNN,主要探討了 R-CNN 如何在物體檢測中平衡精確度和速度。
one-stage領域也是百花齊放,2017年首爾大學提出 R-SSD 演算法,主要解決小尺寸物體檢測效果差的問題。清華大學提出了 RON 演算法,結合 two stage 名的方法和 one stage 方法的優勢,更加關注多尺度對象定位和負空間樣本挖掘問題。
目標檢測領域的深度學習演算法,需要進行目標定位和物體識別,演算法相對來說還是很復雜的。當前各種新演算法也是層不出窮,但模型之間有很強的延續性,大部分模型演算法都是借鑒了前人的思想,站在巨人的肩膀上。我們需要知道經典模型的特點,這些tricks是為了解決什麼問題,以及為什麼解決了這些問題。這樣才能舉一反三,萬變不離其宗。綜合下來,目標檢測領域主要的難點如下:
一文讀懂目標檢測AI演算法:R-CNN,faster R-CNN,yolo,SSD,yoloV2
從YOLOv1到v3的進化之路
SSD-Tensorflow超詳細解析【一】:載入模型對圖片進行測試 https://blog.csdn.net/k87974/article/details/80606407
YOLO https://pjreddie.com/darknet/yolo/ https://github.com/pjreddie/darknet
C#項目參考:https://github.com/AlturosDestinations/Alturos.Yolo
項目實踐貼個圖。
⑸ 一文幫你搞定Yolov3
我們知道傳統機器學習中如果要預測出一條簡訊是否為垃圾簡訊,我們會把很多條簡訊拿來做訓練樣本,然後每條簡訊的標簽是用0和1來標注他是否為垃圾簡訊。通過將這些訓練樣本及對應的標簽輸入到機器學習模型中,使得模型能夠學習怎樣判別一條簡訊是否為垃圾簡訊,從而當隨便拿一條簡訊輸入到模型中,就能判斷這個簡訊是否為垃圾簡訊了。
Yolov3演算法的訓練方法與傳統機器學習演算法訓練的本質是一樣的。
Yolov3中用來訓練的樣本實際上是一群框,yolov3通過訓練這群樣本框,讓模型能夠學習到如何將這群樣本框挪動位置來框住圖片中真實的物體。從而當隨便拿一張圖片,yolov3都能將這張圖片中的物體給框住,並判斷其類別。
這群樣本框是怎麼定義的,這群框的樣本標簽又該如何定義,我們接下來給大家介紹。
Yolov3的多尺度預測
Yolov3通過對圖片卷積提取特徵後會得到三個尺度的feature map,這三個尺度的feature map分別是13*13,26*26,52*52.然後對每個feature map的每個cell下分配三個anchor box,anchor box的尺寸有(10x13),(16x30),(33x23),(30x61),(62x45),(59x119),(116x90),(156x198),(373x326)這九種。怎麼把這9個anchor box分配給3個feature map.我們可以通過如下分析得到:(10*13),(16*30),(33*23)屬於小尺度的anchor box,主要用於檢測小尺寸的物體,而feature map中52*52的感受野最小,適合檢測小的物體,所以把(10*13),(16*30),(33*23)分配給52*52的feature map,(30x61),(62x45),(59x119)屬於中等尺度的anchor box,主要用於檢測中等尺寸的物體,所以把他分配給26*26(負責檢測中等尺寸物體的feature map),(116x90),(156x198),(373x326)屬於較大尺度的anchor box,主要用於檢測較大尺寸的物體,所以把他分配給13*13(負責檢測較大尺寸物體的feature map)的feature map.將上述anchor box分配好後,我們可以利用公式計算出anchor box在原圖中的位置。這群在三個feature map的每一個cell下的anchor box,實際上就是我們模型的訓練樣本。如果將這群anchor box都還原回原圖,每張圖片上差不多有1萬多個anchor box.我們都知道訓練樣本是要有樣本標簽的,那麼yolov3是如何給訓練樣本(這群anchor box)打上標簽呢?
如何給樣本打標簽
但是每張圖片上就有1萬多個anchor box,而且一張圖片上可能有多個gt box.gt box就是我們對圖片中標記的樣本框。如果每一個anchor box都要打上gt box的標簽,就會有兩個問題,其一:anchor box與gt box之間如何對應?其二:每一張圖片有一萬多anchor box要訓練,yolov3演算法效率豈不太低。
為此yolov3採用了中心負責制,即gt box中心落在哪個cell,就由該cell上面的某個anchor box用來負責預測該gt box中的物體。
注意:不是每個cell下面都有3個anchor box嗎,為什麼只由某個anchor box負責預測該gt box呢?其實,這也很好解釋,如果對一堆anchor box做位置移動,使其接近gtbox。那麼肯定是與gt box重合度高的anchor box在做適當的坐標修正後比較接近該gt box.因此,每個gt box都要與anchor box計算交並比,找到與其交並比最大的anchor box來負責預測該gt box.
那具體來說一下操作流程:
首先生成13*13*3*(80+5),26*26*3*(80+5),52*52*3(80+5)這樣維度大小的三個零矩陣。
對訓練樣本圖片做循環,在每次循環中再對gtbox做循環,在每次gtbox循環中再對9個anchor box做循環。舉個例子,有10張圖片,每張圖片上有3個gtbox(這個gtbox就是我們對樣本圖片上的物體進行標注的框),用9個anchor box與gt box計算iou,找到最大的iou對應的anchor box.例如,第四個anchor box與gt box的iou最大,而我們已經知道第四個anchor box分配給了26*26的feature map.所以當前這個gt box中的物體由26*26這個feature map中某個cell中的anchor box負責預測。
怎麼找到這個cell呢?
將gt box所在的原圖image劃分成26*26的網格,看gt box的中心落在哪個cell上,feature map上對應的那個cell就負責預測這個gtbox中的物體。假設中心落在第四行第三列上。
那麼圖片中該gtbox中的物體由26*26的feature map中的(4,3)的這個cell裡面的第一個anchor box來預測。因此我們只用將該gtbox的坐標,類別,置信度填入該anchor box 對應的位置就好了,因為這是我們的anchor box要達到的目標。注意:我們填入的並不是gt box的坐標,而是gt box與anchorbox的坐標之間通過編碼公式換算出來的一種值。而第二個anchor box與第三個anchor box不負責預測物體,所以全部填0.
Yolov3的預測值
Yolov3中的預測值在3個feature map與3*3的filter卷積得到的結果中取得。以26*26的feature map為例,26*26*256的feature map和3*3*256*(3*85)做卷積運算,輸出26*26*(3*85)的預測值.這個85中80是預測的anchor box中屬於每一類別的概率,4是gtbox與anchor box之間的偏移量,1是置信度,是這個anchor box中有無物體的概率和anchor box與其對應的gt box之間iou的乘積。
損失計算
上面將yolov3的樣本標簽,及每個樣本的預測值做了解釋,接下來就是如何計算損失了。Yolov3的損失函數包括三部分,坐標損失,置信度損失和分類損失。把樣本分為了正負樣本。
通常我們把不需要負責預測物體的anchorbox稱作負樣本。負樣本不需要計算坐標損失和分類損失,只需要計算置信度損失,而負樣本的置信度的目標值是0,就是說我這個框的置信度目標的預測值接近0,就是讓演算法去學習讓這個框不包含物體。
而把需要負責預測物體的anchorbox稱作正樣本,正樣本需要計算坐標損失,置信度損失和分類損失。
正負樣本的區分
在yolov3中我們把anchor box樣本分為正樣本,負樣本和忽略樣本。anchor box樣本標簽中置信度為1的anchor box,稱為正樣本,置信度為0的anchor box,稱為負樣本。忽略樣本則是從負樣本中抽取出來的,如何理解呢?
由於yolov3使用了多尺度預測,不同尺度的特徵圖之間可能會出現重復檢測的部分。例如有一個物體狗的gt box在訓練時與13*13的feature map中的某個anchor box對應。此時在訓練模型的預測值中,恰好26*26的feature map中的某個anchor box與該gtbox的iou達到0.93。而模型中我們讓這個anchor box的置信度標簽為0,網路學習結果肯定會不理想。所以我們的處理辦法是,將這種與gtbox之間 iou較大(大過設定的閾值,如0.5),但又不負責預測物體的anchor box稱之為忽略樣本,不納入損失計算。
在負樣本中挖掘出忽略樣本的步驟如下:
讓所有的預測的縮放比(tx,ty,tw,th)與對應的anchorbox 進行解碼,得到對應的預測框,我們稱為bbox.
讓這些bbox與當前預測的圖片上的所有gtbox (假設有v個)計算交並比,就可以讓每個bbox有對應的v個分數。對每個預測框取v個分數中的最大值,即可以得到best_score,這個best_score就是與這個anchor box交並比最大的那個gt box,他們之間的交並比。
將anchor box置信度標簽為0,但best_score>閾值的部分設置為忽略樣本,不參與損失計算。
而anchor box置信度標簽為0,但best_score<閾值的部分才是參與損失計算的負樣本。
2.Yolov3的預測流程
預測流程:
模型輸出三種尺度的預測結果,分別為13*13*3*(80+5),26*26*3*(80+5),52*52*3(80+5)。此處以batch*13*13*(3*85)為例進行說明。
將輸出的batch*13*13*(3*85),用輸出的置信度和類別概率相乘,得到篩選各個bbox框的score值。
對篩選的物體檢測框,進行非極大值抑制演算法來刪掉對同一類物體重合度較高的框,然後選出最後的最優框。
非極大值抑制的計算步驟:
1:設置閾值
2:對每類對象
2.1:選取該類中概率最大的框,然後用這個框與該類中的其他框計算iou,iou大於閾值則剔除,把這個最大的框放入輸出列表中,這個最大的框也剔除出去
2.2:在餘下的該類框中再選出概率最大的框,重復2.1的操作
2.3:返回步驟2,繼續下一類對象
⑹ Yolov3理論詳解
Yolo系列採用了one-stage的識別方案,故名思意,就是一個階段,圖像進來之後,卷積提取特徵,到和labels計算損失,他就一個階段。相教於fasterrcnn,masterrcnn等需要生成大量候選框的two-stage方案,在識別速度上還是比較到位的,這樣就使得它非常的實用,傳說被美軍應用在了導彈識別方面,傳說的很玄乎,也確實,無論在速度還是准確率,yolov3都做的非常不錯。
我們看下yolov3的結構,先附上一張整體結構圖。
從上到下我們走一遍YOLOV3流程。
1.A位置,當圖像輸入進來以後,圖像的尺寸並不是正方形的,為了後面的計算方便,我們首先把他轉換成能被32整除的正方形。為什麼是32,整個網路要經過16次放縮變換(步長為2的卷積操作{替代池化}),最後得到的特徵圖尺寸是11*11 或者12*12或者14*14這樣的方格。每次轉換稱的正方形圖像並不是固定尺寸,這樣就增強了網路適應不同大小圖像的能力.
2.B位置, 一個conv2d是Convolution卷積+Batch Normalization+Leaky_relu激活的組合。Batch Normalization歸一化替代正則,提升模型收斂速度。Leaky_relu軟路激活解決了relu激活時負數不學習的問題。
從A位置進來416*416*3的圖像,經過了32(32個卷積核)*3*3(卷積核的尺寸3*3) 步長為1的卷積操作之後,變成了416*416*32的輸出。
3.B到C過程中,我們看到圖像尺寸從416*416轉換成208*208,中間有一層步長為2的卷積層,來替代池化層。比單純的用池化層效果要好一些。
4.C位置,這里是卷積和殘差連接的組合,yolov3的殘差連接是同模塊內的殘差連接,shape相同才能連接。
C位置以下的resnet層 ,我們就不再說明了,原理和連接都是一致的。越往下,特徵圖的尺寸約小,特徵核的層數越多。
5.我們看下E位置的尺寸是13*13*1024,D位置的尺寸是26*26*512 ,越往下的層越能識別大物體,而上面的層越能識別小物體,我們把上下兩層相加,使得它同時具備了識別大物體和小物體的能力。上下兩層即E層和D層怎麼融合呢,我們把E層上采樣,變成26*26*256,這樣他就能和D層首尾相連進行拼合了。
6.拼合以後我們看到到了F位置,注意F位置的尺寸 (batch_size,26,26,75),分類數是 70 ,這里卻是75,多出來的五個就是,x,y,w,h,conf(是物體與不是物體的判斷)。
7.YOLO層是一個預測值和Lables目標值相減求損失的層。
yolov3一共有三個YOLO層分別去訓練網路,為什麼有三個,較小的特徵圖有比較大的視野,教大的特徵圖有比較小的視野,這樣yolo3就擁有了既能識別大目標也能識別小目標的能力,同時,一個點既能是一種分類,也可以屬於另外的分類.
8.好了,pytorch執行loss.back(),反向傳播,就開始訓練了。
⑺ YOLOv3 深入理解
YOLOv3沒有太多的創新,主要是借鑒一些好的方案融合到YOLO裡面。不過效果還是不錯的,在保持速度優勢的前提下,提升了預測精度,尤其是加強了對小物體的識別能力。
本文主要講v3的改進,由於是以v1和v2為基礎,關於YOLO1和YOLO2的部分析請移步 YOLO v1深入理解 和 YOLOv2 / YOLO9000 深入理解 。
YOLO3主要的改進有:調整了網路結構;利用多尺度特徵進行對象檢測;對象分類用Logistic取代了softmax。
在基本的圖像特徵提取方面,YOLO3採用了稱之為Darknet-53的網路結構(含有53個卷積層),它借鑒了殘差網路resial network的做法,在一些層之間設置了快捷鏈路(shortcut connections)。
上圖的Darknet-53網路採用256*256*3作為輸入,最左側那一列的1、2、8等數字表示多少個重復的殘差組件。每個殘差組件有兩個卷積層和一個快捷鏈路,示意圖如下:
YOLO2曾採用passthrough結構來檢測細粒度特徵,在YOLO3更進一步採用了3個不同尺度的特徵圖來進行對象檢測。
結合上圖看,卷積網路在79層後,經過下方幾個黃色的卷積層得到一種尺度的檢測結果。相比輸入圖像,這里用於檢測的特徵圖有32倍的下采樣。比如輸入是416*416的話,這里的特徵圖就是13*13了。由於下采樣倍數高,這里特徵圖的感受野比較大,因此適合檢測圖像中尺寸比較大的對象。
為了實現細粒度的檢測,第79層的特徵圖又開始作上采樣(從79層往右開始上采樣卷積),然後與第61層特徵圖融合(Concatenation),這樣得到第91層較細粒度的特徵圖,同樣經過幾個卷積層後得到相對輸入圖像16倍下采樣的特徵圖。它具有中等尺度的感受野,適合檢測中等尺度的對象。
最後,第91層特徵圖再次上采樣,並與第36層特徵圖融合(Concatenation),最後得到相對輸入圖像8倍下采樣的特徵圖。它的感受野最小,適合檢測小尺寸的對象。
隨著輸出的特徵圖的數量和尺度的變化,先驗框的尺寸也需要相應的調整。YOLO2已經開始採用K-means聚類得到先驗框的尺寸,YOLO3延續了這種方法,為每種下采樣尺度設定3種先驗框,總共聚類出9種尺寸的先驗框。在COCO數據集這9個先驗框是:(10x13),(16x30),(33x23),(30x61),(62x45),(59x119),(116x90),(156x198),(373x326)。
分配上,在最小的13*13特徵圖上(有最大的感受野)應用較大的先驗框(116x90),(156x198),(373x326),適合檢測較大的對象。中等的26*26特徵圖上(中等感受野)應用中等的先驗框(30x61),(62x45),(59x119),適合檢測中等大小的對象。較大的52*52特徵圖上(較小的感受野)應用較小的先驗框(10x13),(16x30),(33x23),適合檢測較小的對象。
感受一下9種先驗框的尺寸,下圖中藍色框為聚類得到的先驗框。黃色框式ground truth,紅框是對象中心點所在的網格。
預測對象類別時不使用softmax,改成使用logistic的輸出進行預測。這樣能夠支持多標簽對象(比如一個人有Woman 和 Person兩個標簽)。
不考慮神經網路結構細節的話,總的來說,對於一個輸入圖像,YOLO3將其映射到3個尺度的輸出張量,代表圖像各個位置存在各種對象的概率。
我們看一下YOLO3共進行了多少個預測。對於一個416*416的輸入圖像,在每個尺度的特徵圖的每個網格設置3個先驗框,總共有 13*13*3 + 26*26*3 + 52*52*3 = 10647 個預測。每一個預測是一個(4+1+80)=85維向量,這個85維向量包含邊框坐標(4個數值),邊框置信度(1個數值),對象類別的概率(對於COCO數據集,有80種對象)。
對比一下,YOLO2採用13*13*5 = 845個預測,YOLO3的嘗試預測邊框數量增加了10多倍,而且是在不同解析度上進行,所以mAP以及對小物體的檢測效果有一定的提升。
YOLO3借鑒了殘差網路結構,形成更深的網路層次,以及多尺度檢測,提升了mAP及小物體檢測效果。如果採用COCO mAP50做評估指標(不是太介意預測框的准確性的話),YOLO3的表現相當驚人,如下圖所示,在精確度相當的情況下,YOLOv3的速度是其它模型的3、4倍。
不過如果要求更精準的預測邊框,採用COCO AP做評估標準的話,YOLO3在精確率上的表現就弱了一些。如下圖所示。
[1] YOLOv3: An Incremental Improvement
[2] Deep Resial Learning for Image Recognition
[3] What』s new in YOLO v3?
[4] How to implement a YOLO (v3) object detector from scratch in PyTorch
⑻ 跑yolo3需要多少顯存
訓練你可以通過設置batch_szie(一次訓練所選取的樣本數),以及改變演算法結構來控制顯存的佔用。
對於運行yolov3,需要1.7g左右的顯存