[mobilenetv1+k210]Yolov2目標檢測網絡分析與項目總結

寫在前面:大家好,我是小董。前段時間學業繁忙,好久沒更新博客啦。今天結合自己正在做的項目,和大家聊一聊Yolov2網絡,以及對我現在正在做的項目做個總結。

相信Yolo網絡大家都很熟悉,從V1到V2引入了anchor(我理解中文翻譯是先驗框,也就是通過kmeans聚類算法,得到與數據集中bbox最接近的五個框,網絡由V1的直接預測box座標,變爲預測bbox框相對於anchor的偏移量。一個cell有5個anchor)。V3自己也不是很瞭解,但據自己看的博客和資料來看,V3和V2實際上差不多,只不過anchor變爲了9個,然後kmeans聚類的尺度變爲/原圖尺度。(v2的尺度爲/fmap,這是個極易忽略的地方)(當然,也有很多這裏沒提到的改進,具體的變化,大家可以看看相關paper.)

網上有很多文章和博客介紹Yolo網絡,在這裏,我就不再次重述了。接下來總結下整個項目(攥寫本文時,項目還沒做完,所以本文的意義可能是爲後面還未做的工作提供個工作思路):

項目需求:

實現對用戶上傳數據集的自動訓練(Yolov2),並部署在AIOT芯片上。

TODO(目前實現的會畫✔,未實現畫X)

(✔) 0.使用微軟VoTT目標檢測標定軟件進行數據集標定。(看了網上不少目標檢測數據集標定,都是用labelimg這款開源軟件進行標定,從而生成xml文件。)爲什麼使用VoTT進行數據集標定?經過我的使用,它有如下好處:1.可直接生成含有圖像數據的TFRecord文件(對使用TF框架的我,真的是福音。同時,這樣的數據集打包方式,能夠大大減少後期用戶上傳的數據集目錄結構混亂的機率)。2.支持對視頻的標定。3.使用非常方便,導致標定速度要比用labelimg快很多。
——
(✔)1.數據集增強。在本項目的背景下,不可能要求用戶上傳很大的數據集(比如幾百MB,幾GB的量級),所以數據增強對於提升模型的魯棒性很重要。這裏我才用的平移,增加噪聲,旋轉,剪切操作。
——
(✔)2.基於K-means聚類算法的anchor(先驗框)計算。v2引入了anchor後,讓網絡收斂得更快了。(爲什麼會這樣?根據我的理解加上生動的例子,就比如你想去城市中的某個建築,在指路的時候,V1這個人給你提供的幫助是,告訴你這個建築的經緯度座標。而V2這個人告訴你的是這個建築相對於你現在位置的偏移量。顯然,V2提供的方式,相比於V1提供的方式對於人腦的計算量更小些。[這個例子可能有些不恰當QAQ])
——
(✔)3.loss函數。經過我對Yolo網絡的理解,我發現,整個Yolo網絡的核心就是它的loss函數,這個loss的計算無疑凝結着yolo網絡最精髓的地方。(當然,它也是最需要時間去理解的地方)。相比於滑動窗口實現目標檢測,相比於我之前通過opencv獲取邊緣形態學特徵+目標分類而實現的多位手寫數字識別(效果:https://www.bilibili.com/video/BV1WE411G7hx)。Yolo的處理速度是真的非常快了。而這個比較快的處理速度,來源於構建yolo的神經網絡,這個網絡的收斂,又來自於loss計算。所以大家在學習過程中,務必搞清楚loss函數。
——
(✔)4.部署到生產環境中(比如加errorlog,加守護進程等等)
ps:訓練過程中還有很多其他操作,這個TODO主要整理比較關鍵的操作。

個人認爲比較重要的細枝末節

1.IOU計算

在Yolov2的loss計算中,每個cell有5個anchor,那麼究竟該由哪個anchor來負責預測目標信息呢?答案是採用與GT(ground truth,也就是fmap尺度的box)IOU最大的anchor進行目標信息的預測。在計算時候,不考慮box的座標位置。將GT和anchor移到同一原點進行計算,注意,參與計算的數值都是歸一化後的。
計算過程圖示如下:
在這裏插入圖片描述
代碼如下:
在這裏插入圖片描述
簡單說一下上述代碼,首先獲得所有anchor的寬度和高度數據,然後根據上面的計算圖示,我們要計算A1和A2的面積,假設A1是長寬都比較小的box,那麼a1的w和h的值,必定等於anchor和GT中最小的W和最小的H。再把這兩個最小的w,h相乘,就得到了交集面積A1。那麼A2的處理也是同理了。根據IOU=交集面積/並集面積。可以得到如下公式:IOU=A1/(A1(GT面積)+A2-A1(交集面積))。
注意,如上的A1並不能約去,因爲他們的數學意義是不同的。一個爲交集面積,一個爲GT面積。在如上的情況下,二者的值是相等的。但是在如下的情況下,二者值並不相等:
在這裏插入圖片描述

2.YoloV2網絡輸出到底是啥?

Yolov2網絡輸出爲一個fmap,fmap的深度爲5*(1+4+classes(分類個數)),如下花了一張圖,方便大家理解。(在這裏要多說一句,某個深度表示什麼,完全取決於loss函數計算,也就是你讓某個濾波器取擬合什麼數據,它所預測的就是什麼數據)
在這裏插入圖片描述PS:很多人對這個xywhc的含義不太瞭解,爲了防止大家再次踩坑,用中文描述一下吧。xy是bbox中心相對於Cell左上角座標的偏移量。wh是bbox寬度相對於anchor的偏移量。c是bbox的置信度。

3.NMS(Non Max Supression|非極大值抑制)

很多剛剛接觸yolo的同學可能會問,爲啥我網絡輸出那麼多框啊QAQ,真就滿屏都是框。例如,下面的圖片(當然,置信度不會都像下面這樣高。樓主出現如下錯誤,主要是因爲loss函數理解有些問題,導致不能很好的適配maixpy固件裏封裝好的nms算法。)
在這裏插入圖片描述
出現如上滿屏是框的問題,主要是由於沒有對網絡輸出卷積層做NMS。那麼好奇的孩子可能會問,爲什麼不做NMS就會出現這樣的問題呢?假設grid_w=10,grid_h=10,那麼整個圖像就有100個Cell,在yolov2中,每個cell有5個anchor,所以理論上網絡會輸出500個bbox。所以,假如沒有NMS,出現如上情況是正常的。
那麼NMS用來幹啥的?,NMS,非極大值抑制。從它的名字就可以很清楚的知道它的作用。有兩個關鍵詞,第一個是“非極大值”,對於yolo來說,評估bbox是否可靠的的參數,就是它的置信度。所以這裏的極大值指得是置信度。第二個關鍵詞“抑制”,抑制是什麼意思呢?表面上說,就是阻擋某個東西。
那麼把這六個字連起來,NMS的作用就很明顯了。對不是極大的置信度進行抑制。
很多人看到這裏,可能會說,這不簡單嘛?找出最大的置信度的框。能有這樣的想法很正常,我當初也是這樣想的。不過QAQ,實際上不是這樣的。更準確的說法是,設定一個置信度閾值,找出置信度高於這個置信度閾值的框。
現在是不是感覺NMS其實也不是那麼難理解,不過看到這裏,纔剛剛說完NMS算法的一半。另外一半同樣也比較重要。仔細推敲上文的NMS方法,我們會發現個BUG,那就是,萬一超過置信度閾值的框依舊很多呢?那不也是會導致滿屏是框嗎???(黑人問號表情包???)
那麼我們還需要對這些高於置信度閾值的框做第二步操作,也就是合併操作。設置一個IOU閾值,假如兩個框的交併比大於這個IOU閾值。我們就讓它兩合併。可以預見的是,這樣合併着合併着,框就會變得很少了。下面是這個過程的簡圖:希望促進大家理解
在這裏插入圖片描述

以上對NMS第二部操作理解有誤,訂正如下:

經過對代碼的優化,漸漸發現,pc端的nms實際效果很差(loss很小)。這明顯是不符合邏輯的,於是開始檢查nms的邏輯,又查閱了下資料。發現自己對nms的第二步操作理解有誤。正確的第二步操作應該是假設上圖的box1和box2的iou(交併比)大於iou閾值(此處爲0.4),則認爲他們mark的是同一個目標,則留下置信度最高的框,另外一個框去掉。(也就是假如box1的置信度爲0.9,box2的置信度爲0.8,iou大於0.4,則選擇box1,丟掉box2)

_

NMS非極大值抑制算法就是幹了這兩件事情,是不是也沒那麼神祕。接下來要吹一波tensorflow了。tensorflow有個NMS的API,可以供大家直接調用QAQ。(太香啦)
以下爲API的文檔(地址在:https://tensorflow.google.cn/api_docs/python/tf/image/non_max_suppression?hl=en),有需要的朋友,可以自己去查閱。
在這裏插入圖片描述

以上便是對Yolov2網絡,以及自己所在做項目的一個簡單總結。如果文中有理解偏差的地方,歡迎各位前輩指正。

經過近三週的一路折騰,踩坑,填坑。最後的效果總算出來些了。

由於用了Mobilenet,效果上自然和原論文裏的darknet19無法比。loss最低0.5左右,在pc上nms後,效果如上。通過nncase量化後,跑在k210上的效果慘不忍睹。還在繼續優化模型中。根據測試,loss收斂到0.01量級能有比較好的效果。
以下爲PC端效果視頻:
https://www.bilibili.com/video/BV1Za4y1v7Lp
(繼續優化,如果各位前輩有好的優化建議,也歡迎私信我)

2020.4.27

avg loss = 0.07,K210上跑的效果圖(視頻見:https://www.bilibili.com/video/BV1B64y1M73y),感覺框很多,並且置信度都很高。繼續優化。經過和大佬的交流,發現可能是mobilenet不方便nncase量化(用mobilenet做基網絡的同學要注意啦)。
在這裏插入圖片描述

還有個問題就是中間的Cell響應比較好,邊緣的cell基本沒有響應了。仔細想了下,由於數據增強後,我的四周pad操作,導致四周基本沒啥數據。下一步將會下調數據增強的權重(樓主之前訓練集全靠數據增強QAQ)
下一波的TODO就是:

1.降低數據增強的權重,增加數據集數量,再次用mb測試效果。
2.若1.的效果仍不樂觀,則採用tiny-yolov2中的darknet爲基網絡。

2020.5.1

今天是五一勞動節,祝大家勞動節快樂呀。勞動節,當然是勞動啦。最近把上面的兩個TODO都試了下,首先是1.,本來想降低data augment的權重的,但是無意間發現,自己的augment操作中存在些不不利於網絡收斂的操作。(比如cut out,直接把一個目標cut了3/4)。然後改了改,發現效果還不錯。於是試了下多類別的目標檢測,結果類別的prediction又炸了QAQ(心累中…),明天有時間繼續研究。
其次是2.我發現用了tiny-yolov2中的基網絡,效果還沒有mb好。QAQ,果斷直接放棄,應該是大佬之前大佬所說的tiny-yolov2效果好,是因爲網絡被大佬重新優化過。(但是我優化技術不行呀)
效果:https://www.bilibili.com/video/BV1Xt4y127Xz
下一波的TODO:

優化class的loss函數

2020.5.5

經過幾天的優化QAQ,本項目的主體程序搭建驗證完畢。離上線還有一些代碼需要寫和debug。後天就開始考試了QAQ。爭取在五月底左右上線吧。以下爲loss曲線,如果大家在訓練過程中,loss曲線不長這樣,可能是因爲:1.數據集標定錯誤(/加載錯誤),2.loss函數錯誤 這樣兩個錯誤引起的。(別問我爲啥知道,因爲這兩個坑我都踩過QAQ)
在這裏插入圖片描述

效果視頻:https://www.bilibili.com/video/BV1oC4y1W7qo

很多小夥伴,面對mb和tiny-yolov2,開始有選擇困難症了QAQ。於是,我對它兩做了個測試。(除了基網絡不同,其他都是相同的,因爲數據集只有1class,所以class loss爲0)

MB:

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

Tiny_yolov2:

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

從最後的結果來看QAQ,tiny yolov2效果好一些QAQ。,但是mb的網絡小一些(alpha=0.25)

k210 Image_H 64像素對齊

maixpy輸出特徵圖數據解析-踩坑點:豎屏左上角爲座標原點(HWC240,320,3)

2020.5.15優化結果

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章