網站首頁 編程語言 正文
1. 下載darknet源碼
在命令窗口(terminal)中進入你想存放darknet源碼的路徑,然后在該路徑下輸入依次輸入以下命令:
git clone https://github.com/pjreddie/darknet
cd darknet
上述命令首先從darknet的源碼地址復制一份源碼到本地,下載下來的是一個名為darknet的文件。然后進入這個名為darknet的文件夾。
2. 修改darknet的Makefile文件
Note:如果不需要darknet在GPU上運行,則略過此步驟,只需執行make命令。 在命令窗口輸入以下命令打開Makefile文件:
vi Makefile
將Makefile文件開頭的GPU=0改為GPU=1,如下所示:
GPU=1
CUDNN=0
OPENCV=0
OPENMP=0
DEBUG=0
修改完之后,需要執行make命令才可以生效。
make
3. 準備數據集
在./darknet/scripts文件夾下創建文件夾,命名為VOCdevkit,然后再在VOCdevkit文件夾下創建一系列文件夾,整個目錄結構如下所示:
VOCdevkit
-VOC2019 # 這個文件夾的年份可以自己取
--Annotations # 在這個文件夾下存放所有的xml文件
--ImageSets
---Main # 在這個文件夾下新建兩個TXT文件
----train.txt
----val.txt
--JPEGImages # 在這個文件夾下存放所有的圖片文件
上述文件及文件夾創建好之后,下面來對我們的數據集生成train.txt和val.txt,這兩個文件中存放訓練圖像和測試圖像的文件名(不含.jpg后綴)。 新建一個creat_train_val_txt.py文件(名字可以自己隨便取),然后將以下代碼復制進去(注意相應路徑的修改)
#coding:utf-8
import os
from os import listdir, getcwd
from os.path import join
if __name__ == '__main__': # 只有在文件作為腳本文件直接執行時才執行下面代碼
source_folder='/home/tukrin/zhl/darknet/scripts/VOCdevkit/VOC2019/JPEGImages/' #圖片保存的路徑
dest='/home/tukrin/zhl/darknet/scripts/VOCdevkit/VOC2019/ImageSets/Main/train.txt' #寫有圖片的名字的路徑
dest2='/home/tukrin/zhl/darknet/scripts/VOCdevkit/VOC2019/ImageSets/Main/val.txt' #寫有圖片的名字的路徑
file_list=os.listdir(source_folder) #獲取各圖片的名稱
train_file=open(dest,'a') #追加寫打開
val_file=open(dest2,'a') #追加寫打開
count = 0
for file_obj in file_list:
count += 1
file_path=os.path.join(source_folder,file_obj) #路徑拼接 指向 圖片文件的路徑
file_name,file_extend=os.path.splitext(file_obj) #分離文件名與擴展名 file_name為去掉擴展名的圖片名稱
# file_num=int(file_name)
if(count<800):
train_file.write(file_name+'\n') #寫入去掉擴展名的文件名名稱 前800個作為 訓練集數據
else :
val_file.write(file_name+'\n') #寫入去掉擴展名的文件名名稱 后面的作為 驗證集數據
train_file.close() #關閉文件
val_file.close() #關閉文件
制作好creat_train_val_txt.py文件后,在命令行執行該文件:
python creat_train_val_txt.py
執行完畢之后可以看到剛剛我們新建的train.txt和val.txt文件中被寫進了我們的數據集圖片的文件名。
4. 修改voc_label.py
打開scripts文件夾下的 voc_label.py 文件,修改信息:#要修改的地方 共三處
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
#要修改的地方
sets=[('2019', 'train'), ('2019', 'val')] # 此處的2019對應前面新建文件夾時的2019,train和val對應兩個TXT文件的文件名
#要修改的地方
classes =["car", "people"] # 此處為數據集的類別名稱,一定要與xml文件中的類別名稱一致,有幾類就寫幾類
def convert(size, box):#size是圖片的尺寸 box是矩形的四個點
dw = 1./size[0] # 歸一化的時候就是使用寬度除以整個image_size的寬度
dh = 1./size[1] # 歸一化的時候就是使用高度除以整個image_size的高度
x = (box[0] + box[1])/2.0 # 使用(xmin+xmax)/2得到x的中心點
y = (box[2] + box[3])/2.0 # 使用(ymin+ymax)/2得到y的中心點
w = box[1] - box[0] # 然后寬度就是使用xmax-xmin計算得到
h = box[3] - box[2] # 然后高度就是使用ymax-ymin計算得到
x = x*dw# 歸一化
w = w*dw# 歸一化
y = y*dh# 歸一化
h = h*dh# 歸一化
return (x,y,w,h)
def convert_annotation(year, image_id):
in_file = open('VOCdevkit/VOC%s/Annotations/%s.xml'%(year, image_id))
out_file = open('VOCdevkit/VOC%s/labels/%s.txt'%(year, image_id), 'w')#此時文件是如何形成的? open的時候自動建立
root = tree.getroot()#獲得root節點
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
for obj in root.iter('object'):
difficult = obj.find('difficult').text
cls = obj.find('name').text
if cls not in classes or int(difficult) == 1:
continue
cls_id = classes.index(cls)
xmlbox = obj.find('bndbox')
b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))
bb = convert((w,h), b)
out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
wd = getcwd()
for year, image_set in sets:
if not os.path.exists('VOCdevkit/VOC%s/labels/'%(year)):#如果沒有存在這個文件
os.makedirs('VOCdevkit/VOC%s/labels/'%(year))#創建這個路徑 來存放txt標簽
image_ids = open('VOCdevkit/VOC%s/ImageSets/Main/%s.txt'%(year, image_set)).read().strip().split()#此時文件是如何形成的? 通過另一個腳本文件與圖片名稱生成的
list_file = open('%s_%s.txt'%(year, image_set), 'w')#這個文件可能是自己建的? open的時候自動建立
for image_id in image_ids:
list_file.write('%s/VOCdevkit/VOC%s/JPEGImages/%s.jpg\n'%(wd, year, image_id))
convert_annotation(year, image_id)
list_file.close()
#要修改的地方
os.system("cat 2019_train.txt 2019_val.txt > train.txt") # 此處是將兩個txt連接成一個txt,如果你訓練時不用val.txt中的數據,可以注釋掉這句話。
# os.system("cat 2007_train.txt 2007_val.txt 2007_test.txt 2012_train.txt 2012_val.txt > train.all.txt")# 另外,刪除另外一條os.system(...)語句。
保存修改后,運行該文件:
python voc_label.py
執行完畢之后,會生成2018_train.txt、2018_val.txt、train.txt 三個文件,如下圖:
在labels文件夾下會生成圖片對應的txt形式的圖片標注信息
5. 下載預訓練模型
為了加速訓練過程,可以在darknet官網上下載預訓練模型,在該預訓練模型上再進行訓練。 在命令窗口輸入以下命令:
wget https://pjreddie.com/media/files/darknet53.conv.74
文件保存在script文件夾下即可
6. 修改./darknet/cfg/voc.data文件
classes= 2 # 你的數據集的類別數
train = /home/tukrin/zhl/darknet/scripts/2019_train.txt # 第4步中生成的txt文件路徑
valid = /home/tukrin/zhl/darknet/scripts/2019_val.txt # 第4步中生成的txt文件路徑
names = /home/tukrin/zhl/darknet/data/voc.names # voc.names 的文件路徑
backup = /home/tukrin/zhl/darknet/backup/ #backup文件夾的路徑 訓練的權重將保存在這
7. 修改./darknet/data/voc.name文件
將voc.name文件做如下修改:
car
people
內容為你的數據集的類別名稱,注意和xml文件中的類別名稱一致。
8. 修改./darknet/cfg/yolov3-voc.cfg文件
該文件為網絡結構文件。 首先修改開頭處如下:
[net]
# Testing
# batch=1
# subdivisions=1
# Training
batch=64
subdivisions=16
即,將訓練模式打開,將測試模式的語句注釋掉。
其中subdivisions為將一個batch(此處為64)分成多大的小batch。如果訓練時提示超出內存,則可以相應的改小這兩個參數的值。
接著視情況修改開頭處的超參數(學習率,迭代次數等):
width=416
height=416
channels=3
momentum=0.9
decay=0.0005
angle=0
saturation = 1.5
exposure = 1.5
hue=.1
learning_rate=0.001
burn_in=1000
max_batches = 50200 # 迭代次數
policy=steps
steps=40000,45000 # 在指定迭代次數時進行學習率衰減
scales=.1,.1 # 學習率衰減率 此處是0.1
然后再該文件的底部部分,找到如下語句進行如下修改:
......
[convolutional]
size=1
stride=1
pad=1
filters=21 ....................# 修改為 3 * (類別數 + 5),此處類別數為2,所以設置為 3*(2+5)=21
activation=linear
[yolo]
mask = 6,7,8
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
classes=2 .....................# 修改類別數
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=1
......
[convolutional]
size=1
stride=1
pad=1
filters=21 .....................# 同上
activation=linear
[yolo]
mask = 3,4,5
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
classes=2 .....................# 同上
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=1
......
[convolutional]
size=1
stride=1
pad=1
filters=21 .....................# 同上
activation=linear
[yolo]
mask = 0,1,2
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
classes=2 .....................# 同上
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=1
有三處[yolo]的上面的[convolutional]的filters要改 和[yolo]的classes要改開始訓練
9. 開始訓練
在 ./darknet 目錄下,在命令窗口中執行以下命令,其中 -gpus 0, 1 用來指定參與訓練的GPU編號,可以省略。填0 或1
./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg scripts/darknet53.conv.74 -gpus 0,1
10.訓練終止后繼續訓練方法
假如訓練由于意外情況,如顯存不夠終止了,可以通過加載中間權重文件,進而繼續訓練 中間權重文件在backup文件夾中
把9步權重文件的路徑換為backup中文件即可
./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_900.weights -gpus 0,1
backup里文件保存規則: 訓練1000次之前每100次保存一次。所以上面圖片出現了100~900的權重中間文件。 訓練1000次之后每10000次保存一次。 yolov3-voc.backup 會保持100整數倍的訓練結果。 所以在1000次之后想繼續訓練的話應該加載 yolov3-voc.backup文件。注意此文件不能作為檢查模型使用。
原文鏈接:https://juejin.cn/post/7168455293167697957
相關推薦
- 2023-11-22 python文件打開時的訪問模式
- 2022-06-08 Spring Cloud Nacos NacosWatch
- 2024-02-26 IDEA設置字體大小
- 2022-10-20 C++?float、double判斷是否等于0問題_C 語言
- 2023-04-20 Error in mounted hook: “TypeError: Cannot read pro
- 2022-12-08 利用C語言編寫一個無限循環語句_C 語言
- 2022-12-29 react中將html字符串渲染到頁面的實現方式_React
- 2022-07-06 如何使用Python?OpenCV提取物體輪廓詳解_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支