目標檢測實戰項目『程式碼實戰篇』
- 2019 年 11 月 25 日
- 筆記
本文建議閱讀時間 20min
深度學習的三駕馬車:數據、模型、算力。本文將從這三方面,實現 YOLO 目標檢測,讓自己的數據跑起來
數據
一個深度學習項目最好的初始狀態是擁有漂亮的數據,但是一般情況下很難達到這種條件,往往需要根據自己項目的需求尋找相應的數據。對於目標檢測項目來說,漂亮的數據應該是按照規範的標註。那麼有數據卻沒有標註怎麼辦,我們推薦一款開源的標註工具 LabelImg ,有著方便的 GUI 介面,可以方便打開一個文件夾,對相應的圖片做標註,標註完成以後,支援 PascalVOC 或者 YOLO 格式導出,非常的方便。

Labelimg
想嘗試一下本項目,苦於沒數據怎麼辦?有數據不想標註,想看一下本項目的效果怎麼辦?這都不是問題,文末聯繫我,為你準備了兩份數據!
模型
目標檢測分為 Two-stage 和 One-stage 顧名思義就是兩步完成還是一步完成(發展歷程就是從 Two-stage 到 One-stage 的過程)
One-stage 和 Two-stage 各有千秋,One-stage 因為沒有候選框生成步驟,所以速度會更快,速度更快意味著喪失了部分的精度,Two-stage 因為有候選框的選取過程,所以精度會更高,喪失部分精度,果然是魚與熊掌不可兼得。
常見的 One-stage 演算法有 OverFeat、YOLOv1、YOLOv2、YOLOv3、SSD 和 RetinaNet 等。
本文以 YOLOv3 為主要實踐對象,一步一步通過開源的項目,使用 YOLOv3 訓練自己的數據(完整的項目會在文末放出)
- 數據準備
巧婦難為無米之炊,沒有數據,再優越的模型也無用武之地。
如果自己有原始的數據,但是沒有標註,就可以使用 Labelimg 進行標註,輸出的結果是一個 xml 文件。大致的文件結構如下:它包含的資訊有圖片的高寬通道數各個目標在原始圖片的位置以及標籤。

xml 文件
如果你已經有了標註的數據,就可以根據 xml 文件生成一個 txt 文件來進行訓練,txt 文件的格式如下:第一個值代表類別標籤的索引,後面四個值是原始圖片上目標折算後的數值,我們就是根據這些數據來訓練模型。

txt 數據文件
生成後可以用以下公式對轉換前後的數據進行簡單的驗證,保證數據的準確性(具體的折算過程可以看文末的參考資料):
生成的 txt 內容如下(舉例一條): label <1> <2> <3> <4> 可以用以下公式簡單驗證一下生成的 txt 和與原始的 xml 文件是否轉換正確:其中 label 是類別在 data/custom/classes.names 的索引, <> 代表縮放後的比例係數 <1>*w = (xmax-xmin)/2 + xmin <2>*h = (ymax-ymin)/2 + ymin <3> = (xmax-xmin)/w <4> = (ymax-ymin)/h
對於如何根據 xml 標註文件生成 txt 數據文件,我們這邊有份參考腳本可以幫助你:
閱讀 readme.md
中的內容,按照 1、2、3、4 腳本運行,保證你啥問題都沒有
│ 1_init.py │ 2_createID.py │ 3_trans.py │ 4_to_train_val_txt.py │ classes.names │ readme.md │ train.txt │ valid.txt │ ├─images │ train.jpg │ └─labels train.txt
- YOLOv3 模型搭建
我們先來看一下 YOLO 的設計流程,對整個項目的大局有一定的掌控
- 配置數據文件
classes= 1 # 目標檢測的類別數量,有多少類 就設置多少類 train=data/custom/train.txt # 訓練集的圖片名稱,放在 train.txt 文件下,每一行是一張圖片的名稱 valid=data/custom/valid.txt # 訓練集的圖片名稱 names=data/custom/classes.names # 每個類別的名字,一行一個
- 模型初始化
YOLOv3 使用的是 Darknet53 的結構,是一個全卷積的模型,可以擁抱任何大小的輸入,但是必須是 32 的整數倍。Darknet 結果圖如下:

darknet53 結構圖 圖片來自互聯網,侵刪
本文使用的深度學習框架是 Pytorch 項目中讀取 Darknet53 模型的方式是通過讀取配置文件,格式如下,並把它載入帶 Pytorch 定義的模型中

Darknet53 配置文件
- 載入預訓練模型的參數 :從預訓練模型開始訓練
- 數據載入器配置
- 訓練模型、保存模型等
- 預測
- 程式碼配置演練
接下來我們就開始真正配置我們的參數,實現檢測自定義的數據,先展示一下整個項目的目錄結構
│ detect.py │ detect_2.py # 檢測程式碼 │ models.py # 構建模型 │ readme.md │ requirements.txt # 必須的依賴包 │ test.py # 測試程式碼 │ train.py # 訓練程式碼 │ ├─config # 配置文件 │ coco.data │ create_custom_model.sh │ custom.data │ yolov3-tiny.cfg │ yolov3.cfg │ ├─data # 數據集 │ │ coco.names │ │ get_coco_dataset.sh │ │ │ ├─custom │ │ │ 1_init.py │ │ │ 2_createID.py │ │ │ 3_trans.py │ │ │ 4_to_train_val_txt.py │ │ │ classes.names │ │ │ readme.md │ │ │ train.txt │ │ │ valid.txt │ │ │ │ │ ├─images │ │ │ train.jpg │ │ │ │ │ └─labels │ │ train.txt │ │ │ └─samples │ dog.jpg │ ├─utils # 依賴包 │ │ augmentations.py │ │ datasets.py │ │ logger.py │ │ parse_config.py │ │ utils.py │ │ __init__.py │ ├─weights # 預訓練權重 │ download_weights.sh
- 安裝依賴
pip3 install -r requirements.txt # 整個項目需要的依賴包 pip install terminaltables
- 修改配置文件
$ cd config/ # Navigate to config dir # Will create custom model 'yolov3-custom.cfg' $ bash create_custom_model.sh <num-classes> # num-classes 類別數目參數
- 修改數據配置文件
classes= 2 # 類別數 train=data/custom/train.txt valid=data/custom/valid.txt names=data/custom/classes.names
- 訓練
# 訓練命令 python train.py --model_def config/yolov3-custom.cfg --data_config config/custom.data --pretrained_weights weights/darknet53.conv.74 # 添加其他參數請見 train.py 文件 # 從中斷的地方開始訓練 python train.py --model_def config/yolov3-custom.cfg --data_config config/custom.data --pretrained_weights checkpoints/yolov3_ckpt_299.pth --epoch
- 測試
# 測試: python detect_2.py --image_folder data/samples/ --weights_path checkpoints/yolov3_ckpt_25.pth --model_def config/yolov3-custom.cfg --class_path data/custom/classes.names
以上就是整個項目的架構思路,如果你還看不懂,沒關係,貼心的我為你們準備了詳細的文檔說明,並在部分程式碼處加了詳細的解釋
本項目已經開源在:https://github.com/FLyingLSJ/Computer_Vision_Project/tree/master/Object_Detection/yolo_demo/PyTorch-YOLOv3-master
訓練步驟文檔:

訓練步驟文檔
數據集準備步驟文檔

數據集準備步驟文檔
以下是該程式碼在某數據競賽平台獲得的成績,該比賽是對是否有戴安全帽進行檢測,其中有些數據是在教室進行採集的,以下的成績說明,YOLO 對小目標和密集的目標檢測效果並不好

本程式碼排名



其中前 3 名排名如下:

大佬排名
算力
以上說完兩駕馬車了,還有一駕算力馬車,目標檢測對於算力的要求相對高點,我用的是下面這台設備,用了快 9 個小時

參考
- https://github.com/scutan90/DeepLearning-500-questions/blob/master/
- https://github.com/tzutalin/labelImg 數據標註
- https://blog.csdn.net/xiao_lxl/article/details/85342707 VOC 數據格式含義(生成的 txt 數據格式的含義)
- https://github.com/eriklindernoren/PyTorch-YOLOv3
- YOLO 部落格地址:https://blog.paperspace.com/how-to-implement-a-yolo-object-detector-in-pytorch/
- 機器之心翻譯:https://www.jiqizhixin.com/articles/2018-04-23-3
- YOLO 源碼解析:https://zhuanlan.zhihu.com/p/49981816
- YOLO 解讀:https://zhuanlan.zhihu.com/p/76802514