table of Contents
step1 production data collection
step2 training model
step3 test
step4 visual training log
Darknet depth learning framework is an open source neural network framework written in C and CUDA proposed by Joseph Redmon, specific environmental structures written before can refer to the article: https: //blog.csdn.net/stjuliet/article/details/87731998
the basic environment to build successful, you can make your own using the training dataset own yolo a model.
Appear in the text of the labeled use of good data sets from: https: //blog.csdn.net/maweifei/article/details/81137563
step1 production data collection
1,
(1) according to https://blog.csdn.net/stjuliet/article/details/89339814
prepared data set 1, (1) (2) prepared in two steps good own set of data,
then use the following code xml file format conversion marked as txt formats:
Import xml.etree.ElementTree aS ET
Import pickle
Import os
from os Import listdir, getcwd
from the Join os.path Import
classes = [ "people", " front", "side", "back"] # Here is your name all categories of
myRoot = r'E: \ Tensorflow_Codes' # Here is the root directory of your project
xmlRoot = myRoot + r '\ Annotations'
txtRoot = R & lt myroot + '\ Labels'
imageRoot = R & lt myroot + '\ JPEGImages'
def getFile_name(file_dir):
L=[]
for root, dirs, files in os.walk(file_dir):
print(files)
for file in files:
if os.path.splitext(file)[1] == ‘.jpg’:
L.append(os.path.splitext(file)[0]) #L.append(os.path.join(root, file))
return L
def convert(size, box):
dw = 1. / size[0]
dh = 1. / size[1]
x = (box[0] + box[1]) / 2.0
y = (box[2] + box[3]) / 2.0
w = box[1] - box[0]
h = box[3] - box[2]
x = x * dw
w = w * dw
y = y * dh
h = h * dh
return (x, y, w, h)
def convert_annotation(image_id):
in_file = open(xmlRoot + ‘\%s.xml’ % (image_id))
out_file = open(txtRoot + '\\%s.txt' % (image_id), 'w') # 生成txt格式文件
tree = ET.parse(in_file)
root = tree.getroot()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
for obj in root.iter('object'):
cls = obj.find('name').text
if cls not in classes:
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')
#image_ids_train = open(‘D:/darknet-master/scripts/VOCdevkit/voc/list.txt’).read().strip().split(’’,’’) # list格式只有000000 000001
image_ids_train = getFile_name(imageRoot)
image_ids_val = open(’/home/*****/darknet/scripts/VOCdevkit/voc/list’).read().strip().split()
list_file_train = open(myRoot +r’\ImageSets\Main\train.txt’, ‘w’)
#list_file_val = open(‘boat_val.txt’, ‘w’)
image_id in image_ids_train for:
list_file_train.write (imageRoot + '\% s.jpg \ the n-'% (image_id))
convert_annotation (image_id)
list_file_train.close () # generate only a training set, to decide according to their own circumstances
for image_id in image_ids_val:
list_file_val.write(’/home/*****/darknet/boat_detect/images/%s.jpg\n’%(image_id))
convert_annotation(image_id)
list_file_val.close()
(2) conversion is successful, the darknet-master \ build \ darknet \ x64 \ data \ folder, create a folder obj, used to store the original training data and picture data marked txt formats
2,
in the darknet-master \ build \ darknet \ x64 \ data \ train.txt new folder, a path (absolute and relative paths can be) stored in the original training images, the last part of the code in step 1 also includes automatically into the train.txt Code (need to first myRoot \ imageSets \ Main \ under a new train.txt file before execution):
3,
the darknet-master \ build \ darknet \ x64 folder under the new yolo-obj.cfg file (can be copied directly yolov3.cfg, then rename yolo-obj.cfg):
Search yolo, appeared a total of three times, each a yolo blocks modified as follows:
filter = (+ classes. 5). 3 * is calculated according to their categories where
classes classified according to their number set
default random 1, if the memory is less than the recommended to 4G 0
4,
the darknet-master \ build \ darknet \ x64 \ data \ New obj.names file folder, write your own class data sets:
5,
the darknet-master \ build \ darknet x64 data \ folder under the new obj.data file, write the number of categories, the training data set file path, file category labels, training model save path \ \:
6, Makefile file under the modified darknet-master directory:
step2 training model
. 1,
Win + R & lt opening operation terminal input cmd, switch to darknet-master \ build \ the darknet \ x64 directory, enter the command to begin training:
TEE is a command for outputting the log file in a training Linux system (first in darknet-master \ build \ darknet \ x64 the first create a folder visualization), but this command in the windows system does not work, it is necessary to join the extra configuration command:
link: https: //pan.baidu.com/ s / 1R3bZCEqXGHNDNggs9m93Rw extraction code: ef8t
after downloading the archive, unzip, copy UnxUtils \ usr \ local \ wbi folder tee.exe file to the C: \ Windows \ System32 can be.
Train Data Detector darknet.exe / obj.data Yolo-obj.cfg 2> &. 1 | TEE Visualization / train_yolov3.log
. 1
2,
after the start of training, to observe changes in the loss curve, the last generated weights file located darknet-master \ build \ darknet \ x64 \ under the backup directory.
step3 test
As the selected sample less (30 pictures), the number of iterations 1000, the final loss of about 5, predictions very general.
----------------
step4 visual training diary
The third step in the training process the training output log file train_yolov3.log, according to this document may further draw the loss curve, IOU curve for model analysis.
Codes are as follows:
import pandas as pd
import matplotlib.pyplot as plt
import os
g_log_path = "train_yolov3.log" # here to modify your training log filename
extract_log DEF (the log_file, new_log_file, key_word):
'' '
: param the log_file: log file
: param new_log_file: selected information available log files
: param key_word: extract the log information according to the keyword
: return:
' ''
with Open (the log_file , "r") AS f:
with Open (new_log_file, "w") AS train_log:
for Line in f:
# remove the multi-gpu synchronization log
IF "Syncing" in Line:
the Continue
# removing NaN log
IF "NaN" in Line :
the Continue
IF key_word in Line:
train_log.write (Line)
f.close ()
train_log.close ()
def drawAvgLoss(loss_log_path):
‘’’
:param loss_log_path: 提取到的loss日志信息文件
:return: 画loss曲线图
‘’’
line_cnt = 0
for count, line in enumerate(open(loss_log_path, “rU”)):
line_cnt += 1
result = pd.read_csv(loss_log_path, skiprows=[iter_num for iter_num in range(line_cnt) if ((iter_num < 500))],
error_bad_lines=False,
names=[“loss”, “avg”, “rate”, “seconds”, “images”])
result[“avg”] = result[“avg”].str.split(" ").str.get(1)
result[“avg”] = pd.to_numeric(result[“avg”])
fig = plt.figure(1, figsize=(6, 4))
ax = fig.add_subplot(1, 1, 1)
ax.plot(result["avg"].values, label="Avg Loss", color="#ff7043")
ax.legend(loc="best")
ax.set_title("Avg Loss Curve")
ax.set_xlabel("Batches")
ax.set_ylabel("Avg Loss")
def drawIOU(iou_log_path):
‘’’
:param iou_log_path: 提取到的iou日志信息文件
:return: 画iou曲线图
‘’’
line_cnt = 0
for count, line in enumerate(open(iou_log_path, “rU”)):
line_cnt += 1
result = pd.read_csv(iou_log_path, skiprows=[x for x in range(line_cnt) if (x % 39 != 0 | (x < 5000))],
error_bad_lines=False,
names=[“Region Avg IOU”, “Class”, “Obj”, “No Obj”, “Avg Recall”, “count”])
result[“Region Avg IOU”] = result[“Region Avg IOU”].str.split(": ").str.get(1)
result["Region Avg IOU"] = pd.to_numeric(result["Region Avg IOU"])
result_iou = result["Region Avg IOU"].values
# 平滑iou曲线
for i in range(len(result_iou) - 1):
iou = result_iou[i]
iou_next = result_iou[i + 1]
if abs(iou - iou_next) > 0.2:
result_iou[i] = (iou + iou_next) / 2
fig = plt.figure(2, figsize=(6, 4))
ax = fig.add_subplot(1, 1, 1)
ax.plot(result_iou, label="Region Avg IOU", color="#ff7043")
ax.legend(loc="best")
ax.set_title("Avg IOU Curve")
ax.set_xlabel("Batches")
ax.set_ylabel("Avg IOU")
if name == “main”:
loss_log_path = “train_log_loss.txt”
iou_log_path = “train_log_iou.txt”
if os.path.exists(g_log_path) is False:
exit(-1)
if os.path.exists(loss_log_path) is False:
extract_log(g_log_path, loss_log_path, “images”)
if os.path.exists(iou_log_path) is False:
extract_log(g_log_path, iou_log_path, “IOU”)
drawAvgLoss(loss_log_path)
drawIOU(iou_log_path)
plt.show()
————————————————
Drawn by the time of their training model trained log graph and IOU loss graph: