昨兒立下來的flag,今天還是要含淚完成的,抓緊時間趕呀!!!
本次用yolov4來實現人佩戴安全帽檢測,若未佩戴安全帽則將人臉框出來,若佩戴安全帽,則將安全帽以及人臉框出來,多說無益,直接看效果吧!!!
效果還是不錯的,那麼接下來就跟我一起進入yolov4的實操吧!!!
一、環境配置
老規矩,環境走起!!!本次採用pytorch框架來實現
- Python: 3.7.4
- Torch==1.2.0
- Keras: 2.2.4
- numpy:1.17.4
還是建議用anaconda通過虛擬環境的方式來快速搭建!
二、數據準備
本次採用安全帽佩戴檢測的數據集,爲voc格式的數據集。數據集含圖片以及需要檢測物體的位置信息。如下圖所示:
三、YoloV4理論介紹
容我在正式開始介紹之前,要個抱抱!
由於yolov4的創新點很多,本次的話主要針對幾個點介紹吧!
- 網絡的改進:主幹特徵提取網絡的改進由DarkNet53變爲CSPDarkNet53;並對特徵提取網絡也進行了改進,使用了SPP和PANet結構
- 數據增強:使用了Mosaic數據增強方式
- LOSS改進:使用CIOU作爲迴歸LOSS
- 激活函數改進:使用了MISH激活函數
- 標籤平滑Smoothing:一種用於防止數據過擬合的trick
- 餘弦退火學習率:可以使網絡收斂速度加快
- 自對抗訓練:自對抗訓練也是一種新的數據增強方法,可以一定程度上抵抗對抗攻擊。
1.網絡改進
a.主幹提取網絡:DarkNet53->CSPDarkNet53
其中具體關於CSPDarkNet53的介紹,可以先去看一下有關CSPNet這個網絡,其用來增強CNN的學習能力。
CSPnet結構並不算複雜,就是將原來的殘差塊的堆疊進行了一個拆分,拆成左右兩部分:
- 主幹部分繼續進行原來的殘差塊的堆疊;
- 另一部分則像一個殘差邊一樣,經過少量處理直接連接到最後。
b.特徵加強網絡SPP
同上,具體有關SPP的介紹,參考SPPNet特徵金字塔這個網絡。
在特徵加強網絡SPP中,分別利用四個不同尺度的最大池化進行處理,其可以它能夠極大地增加感受野,分離出最顯著的上下文特徵。最大池化的池化核大小分別爲13x13、9x9、5x5、1x1(1x1即無處理)。
c.特徵再次加強PANet網絡結構
其在之後又採取了進一步反覆的特徵提取的工作,上採樣,下采樣,拼接等操作,其思路來源於2018年的PANet,一種實例分割算法,其具體結構由反覆提升特徵的意思特徵金字塔從下到上的特徵提取後,還需要實現(b)中從上到下的特徵提取。
2.數據增強方式
採用Mosaic數據增強方式,即
將4張不同的圖片鑲嵌到一張圖中,其優點是:
- 混合四張具有不同語義信息的圖片,可以讓檢測器檢測超出常規語境的目標,增強模型的魯棒性。
- 由於BN是從四張圖片計算得到的,所以可以減少對大的mini-batch的依賴。
3.CIOU迴歸LOSS
IoU是比值的概念即預測框和真實框的交集比並集,對目標物體的scale是不敏感的。然而常用的BBox的迴歸損失優化和IoU優化不是完全等價的,尋常的IoU無法直接優化沒有重疊的部分。
於是有人提出直接使用IOU作爲迴歸優化loss,CIOU是其中非常優秀的一種想法。
CIOU將目標與anchor之間的距離,重疊率、尺度以及懲罰項都考慮進去,使得目標框迴歸變得更加穩定,不會像IoU和GIoU一樣出現訓練過程中發散等問題。而懲罰因子把預測框長寬比擬合目標框的長寬比考慮進去。
4.MISH激活函數
激活函數改爲Mish激活函數
5.Label Smoothing標籤平滑
其主要針對之前的one-hot中存在的問題:
- 無法保證模型的泛化能力,容易造成過擬合;
- 全概率和0概率鼓勵所屬類別和其他類別之間的差距儘可能加大,而由梯度有界可知,這種情況很難適應。會造成模型過於相信預測的類別。
提出的一種針對one-hot的標籤採取的措施:
new_onehot_labels = onehot_labels * (1 - label_smoothing) + label_smoothing / num_classes
例如:原始的標籤是0、1,在平滑後變成0.005(如果是二分類)、0.995,也就是說對分類準確做了一點懲罰,讓模型不可以分類的太準確,太準確容易過擬合。
6.餘弦退火學習率
也是目前在pytorch框架中比較常見的trick,上升的時候使用線性上升,下降的時候模擬cos函數下降。執行多次。
9.自對抗的訓練方式
針對這個還真沒接觸過,看網上的話作用是如下:
自對抗訓練也是一種新的數據增強方法,可以一定程度上抵抗對抗攻擊。其包括兩個階段,每個階段進行一次前向傳播和一次反向傳播。
- 第一階段,CNN通過反向傳播改變圖片信息,而不是改變網絡權值。通過這種方式,CNN可以進行對抗性攻擊,改變原始圖像,造成圖像上沒有目標的假象。
- 第二階段,對修改後的圖像進行正常的目標檢測。
其它的點,看日後有空是否能填坑吧!!!
四、訓練過程
1.準備數據集
準備安全帽數據,使用VOC格式的數據進行訓練
- 訓練前將標籤文件放在VOCdevkit文件夾下的VOC2007文件夾下的Annotation中。
- 訓練前將圖片文件放在VOCdevkit文件夾下的VOC2007文件夾下的JPEGImages中。
- 在訓練前利用
voc2yolo4.py
文件生成對應的txt。
VOCdevkit
-VOC2007
├─ImageSets # 存放數據集列表文件,由voc2yolo3.py文件生成
├─Annotations # 存放數據集中圖片文件
├─JPEGImages # 存放圖片標籤,xml 格式
└─voc2yolo4.py # 用來生成數據集列表文件
2.運行生成Yolov4所需的數據
再運行根目錄voc_annotation.py
,運行前需要將voc_annotation
文件中classes改成你自己的classes。
每一行對應其圖片位置及其真實框的位置
3.修改voc_classes.txt
在訓練前需要修改model_data裏面的voc_classes.txt
文件,需要將classes改成你自己的classes。
4.修改yolo_anchors.txt
運行kmeans_for_anchors.py
生成yolo_anchors.txt
5.運行
運行train.py
或者train_with_tensorboard
即可開始訓練
- 在main函數下:Cosine_lr參數可用於控制使用餘弦退火衰減學習率
- 在main函數下:mosaic參數用於控制實現mosaic數據增強
- 在main函數下:smooth_label用於控制是否實現標籤平滑
- 在main函數下:model_path用於加載預訓練模型
- save_dir用於控制模型保存位置和tensorboard可視化保存的位置
- 訓練分兩次:先凍結模型參數後解凍,兩次採取不同的學習率
6.測試圖片
運行predict_img.py
,輸入圖片路徑即可得到結果。
效果我覺得蠻好的,應該是比yolov3好些吧,當然我也用了efficientdet也嘗試了,還沒測試效果。這次就先到這裏吧!!!
那這次就下次再更新吧,下次更新點一些之前做過的內容吧!!!當然手裏頭還有個抽菸的數據集,等之後拿efficientdet跑跑!!!