---
# System prepended metadata

title: Darknet 訓練 tiny-YOLO V2 V3 心得

---

# Darknet 訓練 tiny-YOLO V2 V3 心得
這邊是推薦使用 AlexeyAB 大大 `fork` 的版本，有很多教學，十分詳細。
https://github.com/AlexeyAB/darknet
## YOLOv2-tiny
## 事前準備
* 一堆要被訓練的圖片 (要是 jpg 格式，放到 images 資料夾)
* 可以標注訓練目標檔案的工具，coco or voc 都可以，反正最後都要想辦法轉成 yolo 要的 txt 。(我是用 labelImage 弄出 voc dataset，之後再轉換成 yolo 要的格式)
放到 annotations 資料夾
* darknet clone 這個版本 https://github.com/AlexeyAB/darknet
## convert voc to yolo
使用 `convert2Yolo` https://github.com/ssaru/convert2Yolo
把 voc 轉換成 yolo
再把所有的圖片 & 轉換出來的 txt 放到同一個資料夾裡頭

## 建立 `obj.data` `obj.names` `train.txt` `test.txt`
建立一個 `obj.data` 檔案如下
```
train = /home/nono/ABDarknet/build/darknet/x64/data/bxb/train.txt (訓練所需要的檔案，待會會用程式生出來)
valid = /home/nono/ABDarknet/build/darknet/x64/data/bxb/test.txt (訓練所需要的檔案，待會會用程式生出來)
names = /home/nono/ABDarknet/build/darknet/x64/data/bxb/obj.names (包含所有 classes 檔案)
backup = /home/nono/ABDarknet/build/darknet/x64/data/bxb/weights/ (此為訓練出來的權重檔要存放的目錄)
```

使用 `initTrainData.py` 來產生 `train.txt` & `test.txt`

`initTrainData.py` 如下

這支程式做的事情，主要就是把某個資料夾裡頭的檔案都讀出來，然後判斷看看有沒有都有兩個檔案。

如果有顯示一些檔名，代表那個檔案可能有問題缺少 jpg or xml 檔。

最後挑 80% 寫入 `train.txt`
20% 寫入 `test.txt`

```python
from os import listdir
from os import getcwd
from os.path import isfile, join
from random import shuffle
mypath = './yolo'
onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]

my_dict = {}
print('check file is well')
for filename in onlyfiles:
  onlyname = filename.split('.', 1)
  if my_dict.__contains__(onlyname[0]) == False:
    my_dict[onlyname[0]] = 0
  else:
    my_dict[onlyname[0]]+=1
for i in my_dict:
  if my_dict[i] < 1:
    print(i)

print('create train.txt and test.text')
train_file_len = int(len(my_dict) * 0.8)
train_file = open('train.txt', mode='w')
test_file = open('test.txt', mode='w')
cwd = getcwd()
for i, filename in enumerate(my_dict):
  if i < train_file_len:
    train_file.write(cwd + '/yolo/' + filename+'.jpg\n')
  else:
    test_file.write(cwd + '/yolo/' + filename+'.jpg\n')
test_file.close()
train_file.close()
```

完成的 train.txt 大概長這樣，就是一堆圖片的路徑。
```
/home/nono/ABDarknet/build/darknet/x64/data/bxb/yolo/P_20190618_111032.jpg
/home/nono/ABDarknet/build/darknet/x64/data/bxb/yolo/P_20190624_085736.jpg
/home/nono/ABDarknet/build/darknet/x64/data/bxb/yolo/P_20190624_085038.jpg
/home/nono/ABDarknet/build/darknet/x64/data/bxb/yolo/az5.jpg
/home/nono/ABDarknet/build/darknet/x64/data/bxb/yolo/P_20190618_111053.jpg
/home/nono/ABDarknet/build/darknet/x64/data/bxb/yolo/zxc2.jpg
/home/nono/ABDarknet/build/darknet/x64/data/bxb/yolo/qa5.jpg
```

## 開始訓練
去看 AB 大大 github 的 README 寫得很清楚
https://github.com/AlexeyAB/darknet

所以只簡單敘述過程，和容易出問題的地方

### 編譯 darknet
要注意 Makefile 裡頭有一些設定要開啟，像是 GPU OpenCV 之類的，還有要記得設定 nvcc 的路徑，不然會編譯失敗。

![](https://i.imgur.com/40vPYM6.png)

### 改寫 cfg
使用 cfg 必須要複製原本的一份，不能用原始的
像我要訓練 yolov2-tiny 
我就要去複製 yolov2-tiny.cfg -> yolov2-tiny-c2.cfg
再來更改 yolov2-tiny-c2.cfg
記得 filter & classes 該改的要改

### Out of mamory
若發生類似此錯誤造成訓練停止，可能為 GPU 記憶體不足，可在降低 .cfg 檔案中訓練的 `batch` & 增加 `subdivisions`


### 提醒
建議在訓練前完整的看過 https://github.com/AlexeyAB/darknet

寫的很完整很詳細，必看！
* 如何訓練
* 何時停止
* annotation 要怎麼準備
* 如何訓練更好的結果

都有






