使用Darknet网络框架

【训练分类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值。

你可能感兴趣的:(darknet)