【训练分类weight文件】
》命令:
./darknet classifier train cfg/mydata.data cfg/mydata.cfg
》若中途终端,基于已有的训练模型接着训练执行如下命令:
./darknet classifier train cfg/mydata.data cfg/mydata.cfg /home/page/Pictures/ImageSet/backup/mydata_44.weights
》评估训练weight文件的正确率:
./darknet classifier valid cfg/mydata.data cfg/mydata.cfg /home/page/Pictures/ImageSet/backup/mydata_44.weights
》制作train.list,val.list,lables.list
train文件夹中的每张图片的名字,需要包含label中的标签,比如有张图片属于类别”dog”,则这张图片名字可以命名为“dog_XXXXX”,其中XXXXX 为任意字符,但不能包含标签中其他类别的字符,否则程序就会当作该图片属于多个类。
train.list文件,这个文件里列出了train文件夹里所有的图片,每一行为一张图片的绝对路径。
val.list文件,这个文件里列出了val文件夹里所有的图片,每一行为一张图片的绝对路径。
注意:绝对路径里不能包含类别名字。
运行命令:python creat_list.py
import os
from os import listdir, getcwd
from os.path import join
if __name__ == '__main__':
source_folder='/home/page/Pictures/ImageSet/set/'#地址是所有图片的保存地点!!!!
dest='/home/page/Pictures/ImageSet/train.list' #保存train.txt的地址!!!!
dest2='/home/page/Pictures/ImageSet/val.list' #保存val.txt的地址!!!!
file_list=os.listdir(source_folder) #赋值图片所在文件夹的文件列表
train_file=open(dest,'a') #打开文件
val_file=open(dest2,'a') #打开文件
file_num = 0
for file_obj in file_list: #访问文件列表中的每一个文件
file_path=os.path.join(source_folder,file_obj)
#file_path保存每一个文件的完整路径
file_name,file_extend=os.path.splitext(file_obj)
#file_name 保存文件的名字,file_extend保存文件扩展名
#file_num=int(file_name)
#把每一个文件命str转换为 数字 int型 每一文件名字都是由四位数字组成的 如 0201 代表 201 高位补零
file_num = file_num + 1
if(file_num<9001): #前9000个文件用于训练!!!!!!!!
#print file_num
train_file.write('/home/page/Pictures/ImageSet/set/'+file_name+'.jpg'+'\n') #用于训练前9000个的图片路径保存在train.list里面,结尾加回车换行
elif(file_num<10001) :
val_file.write('/home/page/Pictures/ImageSet/set/'+file_name+'.jpg'+'\n') #其余的文件保存在val.txt里面
elif(file_num<19001) :
train_file.write('/home/page/Pictures/ImageSet/set/'+file_name+'.jpg'+'\n')
else :
val_file.write('/home/page/Pictures/ImageSet/set/'+file_name+'.jpg'+'\n')
train_file.close()#关闭文件
val_file.close()
》进入darknet/cfg文件夹,修改imagenet1k.data文件,并保存为mydata.data:
classes=2 //类别数
train = data/train.list //训练集列表路径
valid = data/valid.list //验证集列表路径
backup = /home/yrs/backup/ //用来保存训练结果的路径
labels = data/labels.list //标签路径
names = data/shortnames.list //训练阶段不使用
top=1 //top1准确率
》还是上一步的文件夹,打开darknet19.cfg,这里列出了主要需要修改的项,并保存为mydata.cfg:
也可以选择除了darknet19.cfg网络外的其他网络。
/# Testing
batch=32 //修改训练时候的同时输入网络的图片基数,大小取决于显卡内存,太大训练会直接报错,可以改小
subdivisions=1
height=256 //图片进入网络后被resize的大小
width=256
min_crop=128
max_crop=448
channels=3
momentum=0.9
decay=0.0005
burn_in=1000
learning_rate=0.01 //学习率小一点好些
policy=poly
power=4
max_batches=800000
......
[convolutional]
filters=2 //最后一层的层数要等于类别数
size=1
stride=1
pad=1
activation=linear
[avgpool]
[softmax]
groups=1
下面的是用yolo训练检测识别的weight文件,需要xml文件
在darknet-voc中运行
【报错:无法找到libcudart.so.7.5】
export LD_LIBRARY_PATH=/usr/local/cuda-7.5/lib64:$LD_LIBRARY_PATH
./darknet detect cfg/yolo.cfg yolo.weights /home/page/data/yolo_DATA/picture/horses.jpg
【测试文件】
》图片:
./darknet detector test cfg/voc.data cfg/yolo-voc.cfg backup/yolo-voc_final.weights /home/page/data/yolo_DATA/yolo-alldata/first-hand-data/mark2.1/00148.jpg
》视频:
./darknet detector demo cfg/coco.data cfg/yolo.cfg yolo.weights
./darknet detector demo cfg/voc.data cfg/yolo-voc.cfg backup/yolo-voc_final.weights /home/page/data/yolo_DATA/vedio/mark1.mov
》摄像头:
./darknet detector demo cfg/coco.data cfg/yolo.cfg yolo.weights
》修改阈值:(默认阈值为0.001,不要大于1)
./darknet detect cfg/yolo.cfg yolo.weights data/dog.jpg -thresh 0
【制作自己的数据集】
》初始图片.jpg统一放在:/home/page/data/yolo_DATA/yolo_test/voc-mydata/image/文件夹下
labelImg生成的.xml文件统一放在:/home/page/data/yolo_DATA/yolo_test/voc-mydata/xml/文件夹下
》生成.txt文件的python代码:
运行命令:
python creat_list.py
python voc_label_train.py
python voc_label_val.py
/home/page/data/yolo_DATA/yolo_test/voc-py/文件夹下:
》creat_list.py:
用于生成:(1)训练图片名称目录train.txt (2)验证图片名称目录val.txt (不包含后缀)
!!! 需要修改 if(file_num<81): 语句中的数字,数字表示前80张图片为训练数据,后面的图片为测试数据
# -*- coding: utf-8 -*-
#这个小脚本是用来打开图片文件所在文件夹,把前180个用于训练的图片的名称保存在tain.txt,后71个用于验证的图片保存在val.txt
import os
from os import listdir, getcwd
from os.path import join
if __name__ == '__main__':
source_folder='/home/page/data/yolo_DATA/yolo_test/voc-mydata/image/'#地址是所有图片的保存地点!!!!
dest='/home/page/data/yolo_DATA/yolo_test/voc-mydata/train.txt' #保存train.txt的地址!!!!
dest2='/home/page/data/yolo_DATA/yolo_test/voc-mydata/val.txt' #保存val.txt的地址!!!!
file_list=os.listdir(source_folder) #赋值图片所在文件夹的文件列表
train_file=open(dest,'a') #打开文件
val_file=open(dest2,'a') #打开文件
for file_obj in file_list: #访问文件列表中的每一个文件
file_path=os.path.join(source_folder,file_obj)
#file_path保存每一个文件的完整路径
file_name,file_extend=os.path.splitext(file_obj)
#file_name 保存文件的名字,file_extend保存文件扩展名
file_num=int(file_name)
#把每一个文件命str转换为 数字 int型 每一文件名字都是由四位数字组成的 如 0201 代表 201 高位补零
if(file_num<146): #前180个文件用于训练!!!!!!!!
#print file_num
train_file.write(file_name+'\n') #用于训练前180个的图片路径保存在train.txt里面,结尾加回车换行
else :
val_file.write(file_name+'\n') #其余的文件保存在val.txt里面
train_file.close()#关闭文件
val_file.close()
》voc_label_train.py:
用于生成:(1)训练图片的完整路径目录infrared_train.txt (2)对应每一个.xml文件的.txt文件存储文件夹labels。
# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
sets=[('2012', 'train'), ('2012', 'val'), ('2007', 'train'), ('2007', 'val'), ('2007', 'test')]
classes = ["mark"]
def convert(size, box):
dw = 1./(size[0])
dh = 1./(size[1])
x = (box[0] + box[1])/2.0 - 1
y = (box[2] + box[3])/2.0 - 1
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('VOCdevkit/VOC%s/Annotations/%s.xml'%(year, image_id))
in_file = open('/home/page/data/yolo_DATA/yolo_test/voc-mydata/xml/%s.xml'%(image_id))
#out_file = open('VOCdevkit/VOC%s/labels/%s.txt'%(year, image_id), 'w')
out_file = open('/home/page/data/yolo_DATA/yolo_test/voc-mydata/labels/%s.txt'%(image_id), 'w')
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'):
#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')
image_ids = open('/home/page/data/yolo_DATA/yolo_test/voc-mydata/train.txt').read().strip().split() #如果是训练集数据打开这一行,注释下一行
#image_ids = open('/home/page/data/yolo_DATA/yolo_test/voc-mydata/val.txt').read().strip().split() #如果是验证数据集数据打开这一行,注释上一行
list_file = open('/home/page/data/yolo_DATA/yolo_test/voc-mydata/infrared_train.txt', 'w')
#把结果写入到indrared_train.txt文件中,如果是训练集数据打开这一行,注释下一行
#list_file = open('/home/page/data/yolo_DATA/yolo_test/voc-mydata/infrared_val.txt', 'w')
#把结果写入到indrared_val.txt文件中,如果是验证数据集数据打开这一行,注释上一行
for image_id in image_ids:
list_file.write('/home/page/data/yolo_DATA/yolo_test/voc-mydata/image/%s.jpg\n'%(image_id))
#把每一用于训练或验证的图片的完整的路径写入到infrared_train.txt中 这个文件会被voc.data yolo.c调用
convert_annotation(image_id)
list_file.close()
#os.system("cat 2007_train.txt 2007_val.txt 2012_train.txt 2012_val.txt > train.txt")
#os.system("cat 2007_train.txt 2007_val.txt 2007_test.txt 2012_train.txt 2012_val.txt > train.all.txt")
》 voc_label_val.py:
用于生成:(1)验证图片的完整路径目录infrared_val.txt (2)对应每一个.xml文件的.txt文件存储文件夹labels
# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
sets=[('2012', 'train'), ('2012', 'val'), ('2007', 'train'), ('2007', 'val'), ('2007', 'test')]
classes = ["mark"]
def convert(size, box):
dw = 1./(size[0])
dh = 1./(size[1])
x = (box[0] + box[1])/2.0 - 1
y = (box[2] + box[3])/2.0 - 1
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('VOCdevkit/VOC%s/Annotations/%s.xml'%(year, image_id))
in_file = open('/home/page/data/yolo_DATA/yolo_test/voc-mydata/xml/%s.xml'%(image_id))
#out_file = open('VOCdevkit/VOC%s/labels/%s.txt'%(year, image_id), 'w')
out_file = open('/home/page/data/yolo_DATA/yolo_test/voc-mydata/labels/%s.txt'%(image_id), 'w')
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'):
#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')
#image_ids = open('/home/page/data/yolo_DATA/yolo_test/voc-mydata/train.txt').read().strip().split() #如果是训练集数据打开这一行,注释下一行
image_ids = open('/home/page/data/yolo_DATA/yolo_test/voc-mydata/val.txt').read().strip().split() #如果是验证数据集数据打开这一行,注释上一行
#list_file = open('/home/page/data/yolo_DATA/yolo_test/voc-mydata/infrared_train.txt', 'w')
#把结果写入到indrared_train.txt文件中,如果是训练集数据打开这一行,注释下一行
list_file = open('/home/page/data/yolo_DATA/yolo_test/voc-mydata/infrared_val.txt', 'w')
#把结果写入到indrared_val.txt文件中,如果是验证数据集数据打开这一行,注释上一行
for image_id in image_ids:
list_file.write('/home/page/data/yolo_DATA/yolo_test/voc-mydata/image/%s.jpg\n'%(image_id))
#把每一用于训练或验证的图片的完整的路径写入到infrared_train.txt中 这个文件会被voc.data yolo.c调用
convert_annotation(image_id)
list_file.close()
#os.system("cat 2007_train.txt 2007_val.txt 2012_train.txt 2012_val.txt > train.txt")
#os.system("cat 2007_train.txt 2007_val.txt 2007_test.txt 2012_train.txt 2012_val.txt > train.all.txt")
》将labels与xml文件夹下所有文件拷贝至image中!
【修改路径】
》cfg/voc.data:
class为训练的类别数
train为训练集train.txt
valid为验证集val.txt
names为voc.names,里面为自己训练的目标名称
backup为weights的存储位置
》cfg/yolo-voc.cfg
244行:region的classes
237行:filters=num×(classes + coords + 1)=5*(1+4+1)=30,这里只有1个类别时。
【训练检测weight文件】
》命令:
./darknet detector train cfg/voc.data cfg/yolo-voc.cfg darknet19_448.conv.23
》修改迭代次数:(正常12000即可)
cfg/yolo-voc.cfg,修改max_batches值。