# Yolov3 訓練 請先make 這個 darknet https://github.com/pjreddie/darknet make教學可看(https://github.com/AlexeyAB/darknet) Makefile裡面自行修改參數 ``` GPU=1 CUDNN=1 OPENCV=0 (若有安裝opencv [C++, 非opencv-python], 不能使用opencv 3.4.1) OPENMP=1 (GNU Compiler Collection有支援) DEBUG=0 (除錯用,一般用不到,別動) ``` arch提供參考參數如下(若為該架構就uncomment) ``` # GeForce RTX 2080 Ti, RTX 2080, RTX 2070, Quadro RTX 8000, Quadro RTX 6000, Quadro RTX 5000, Tesla T4, XNOR Tensor Cores # ARCH= -gencode arch=compute_75,code=[sm_75,compute_75] # Jetson XAVIER # ARCH= -gencode arch=compute_72,code=[sm_72,compute_72] # Tesla V100, GTX 1180, Titan V, Quadro GV100 # ARCH= -gencode arch=compute_70,code=[sm_70,compute_70] # For Jetson Tx2 or Drive-PX2 uncomment: # ARCH= -gencode arch=compute_62,code=[sm_62,compute_62] # GTX 1080, GTX 1070, GTX 1060, GTX 1050, GTX 1030, Titan Xp, Tesla P40, Tesla P4 # ARCH= -gencode arch=compute_61,code=[sm_61,compute_61] # For Quadro GP100, Tesla P100 # ARCH= -gencode arch=compute_60,code=[sm_60,compute_60] # For Jetson TX1, Tegra X1, DRIVE CX, DRIVE PX : # ARCH= -gencode arch=compute_53,code=[sm_53,compute_53] # For Quadro M6000 , GeForce 900, GTX-970, GTX-980, GTX Titan X : # ARCH= -gencode arch=compute_52,code=[sm_52,compute_52] # For Tesla/Quadro M series : # ARCH= -gencode arch=compute_50,code=[sm_50,compute_50] # For Tesla K80 : # ARCH= -gencode arch=compute_37,code=[sm_37,compute_37] # For Tesla K40 : # ARCH= -gencode arch=compute_35,code=[sm_35,compute_35] # For GeForce 700, GT-730 : # ARCH= -gencode arch=compute_30,code=[sm_30,compute_30] # For GeForce 400, 500, 600, GT-630 : # ARCH= -gencode arch=compute_20,code=[sm_20,compute_30] ``` ## 訓練資料為(假設是VOC格式) DataSet的根目錄我用`path_to_dataset`代替. 首先準備voc dataset, 擺放方式如下: ``` path_to_dataset (dir) │ └───images (dir) │ │ │ │ file001.jpg │ │ file002.jpg │ └ ... │ └───labels_voc (dir) │ │ file001.xml │ │ file002.xml │ └ ... │ └───labels (dir) │ └─(empty) *註: (dir) 為資料夾 ``` 檔名請對齊,file001.jpg 就對應file001.xml ## Step1 VOC to darknet format 下載`label_to_yolo.py`至`path_to_dataset`根目錄: https://gist.github.com/hsuRush/f6689a62a740f0cf3ffa3ff99a79b7df `需改path_to_dataset跟class以及valid_split, valid_split`為train set, valid set切的比例. 若為0.1則比例為9:1. - 跑`python label_to_yolo.py`他會將VOC label資料(在`path_to_dataset/labels_voc`)轉為darknet的格式並放入`path_to_dataset/labels/`,並且會產生train.txt以及test.txt 將產生train.txt以及test.txt放至`path_to_dataset/` ## Step2 Kmeans for anchor box `kmeans.py`: https://gist.github.com/hsuRush/4bf21fff72f00cb7e37c2af3f572a86e 預設`CLUSTERS` = 9 將`path_to_dataset`改為`labels_voc`所在的絕對路徑 將`HEIGHT`, `WIDTH`, `classes`改為你現在DataSet的規格 調整`times`, 他會多跑幾次然後選擇最好的kmeans結果. 好了之後跑`python kmeans.py` 他會輸出一個`k_means_anchor` 將`k_means_anchor`檔案以文本方式打開如下 ``` Accuracy: 89.91% anchors = 69,25, 78,33, 71,29, 44,19, 75,37, 47,23, 58,27, 91,42, 55,22 ``` 將`darknet/cfg/yolov3.cfg` 複製出來, 假設叫yolov3_fruit.cfg 將`69,25, 78,33, 71,29, 44,19, 75,37, 47,23, 58,27, 91,42, 55,22`複製到yolov3_fruit.cfg裡面的`anchors = `. Take yolov3 as exmaple, change [Line 609](https://github.com/pjreddie/darknet/blob/0ff23438c66629deff8df2551baffbbb29987dee/cfg/yolov3.cfg#L609), [Line 695](https://github.com/pjreddie/darknet/blob/0ff23438c66629deff8df2551baffbbb29987dee/cfg/yolov3.cfg#L695), [Line 782](https://github.com/pjreddie/darknet/blob/0ff23438c66629deff8df2551baffbbb29987dee/cfg/yolov3.cfg#L782) 並且yolov3_fruit.cfg有兩處需要修改的地方: 第一處:[yolo]層中classes改成你的類別數(在v3中共三處),假設我使用的是fruit的資料集,有3類,所以`classes=3`。 第二處:[yolo]層前一層的[convolution]層中(在v3中共三處),filters的數量改成(`classes`+4+1 * `CLUSTERS`). Take yolov3 as exmaple, change [Line 610](https://github.com/pjreddie/darknet/blob/0ff23438c66629deff8df2551baffbbb29987dee/cfg/yolov3.cfg#L603), [Line 696](https://github.com/pjreddie/darknet/blob/0ff23438c66629deff8df2551baffbbb29987dee/cfg/yolov3.cfg#L689), [Line 783](https://github.com/pjreddie/darknet/blob/0ff23438c66629deff8df2551baffbbb29987dee/cfg/yolov3.cfg#L776) 所以假設我kmeans跑得是(CLUSTERS=9)是(3+4+1)*9 = 72, 所以改為`filters=72` Take yolov3 as exmaple, change [Line 609](https://github.com/pjreddie/darknet/blob/0ff23438c66629deff8df2551baffbbb29987dee/cfg/yolov3.cfg#L603), [Line 695](https://github.com/pjreddie/darknet/blob/0ff23438c66629deff8df2551baffbbb29987dee/cfg/yolov3.cfg#L689), [Line 782](https://github.com/pjreddie/darknet/blob/0ff23438c66629deff8df2551baffbbb29987dee/cfg/yolov3.cfg#L776) ## Step3 DataSet preparation 創.names 跟.data .names放class的名稱, 例如`darknet/data/fruit.names`的內容為 ``` apple banana pineapple ``` 例如 `darknet/cfg/fruit.data`內容為: ``` classes= 3 (class個數) train = path_to_dataset/train.txt (train.txt的完整路徑) (產生於Step1) valid = path_to_dataset/test.txt (test.txt的完整路徑) (產生於Step1) names = /home/username/darknet/data/fruit.names (fruit.names的完整路徑) backup = /home/username/backup (訓練過程的暫存點checkpoint會存在這,要先創好資料夾先創好資料夾先創好資料夾) ``` # Step 4 Training Settings ![](https://i.imgur.com/DcnClFR.png) 將`yolov3_fruit.cfg`Testing部份如上圖所示`#`字號註解掉, Training無`#`字號。 將`yolov3_fruit.cfg`的max_batches,batch跟steps改成適當的數字 [參考](https://github.com/AlexeyAB/darknet#how-to-train-to-detect-your-custom-objects) 舉例我在cfg裡面設: ``` max_batches = 6000 policy=steps steps=4000,5000 scales=.1,.1 ``` 在make成功darknet的情況下, 在darknet/ 打開terminal * for `linux`: 跑 `./darknet detector train cfg/fruit.data cfg/yolov3_fruit.cfg` * for `window`: 跑 `darknet.exe detector train cfg/fruit.data cfg/yolov3_fruit.cfg` ``-gpu 0,1,2...`` for multi-gpu 訓練的資訊請看 https://chtseng.wordpress.com/2018/09/01/%E5%BB%BA%E7%AB%8B%E8%87%AA%E5%B7%B1%E7%9A%84yolo%E8%BE%A8%E8%AD%98%E6%A8%A1%E5%9E%8B-%E4%BB%A5%E6%9F%91%E6%A9%98%E8%BE%A8%E8%AD%98%E7%82%BA%E4%BE%8B/ 的第八點 # Step 5 訓練好後把cfg的testing 的`#`拿掉 training的部份加上`#` ![](https://i.imgur.com/DcnClFR.png) 若需要使用python inference, 請看 https://github.com/107368002/darknet/blob/48dcb887e8f8a7253e5dcdb4297b19b43b58ea55/python/darknet.py#L48 記得路徑要改 (48行) ``` lib=CDLL("/home/czchen/stevenwork/plate_detection_ML_hw3/darknet/libdarknet.so", RTLD_GLOBAL) ```