YOLOv3训练自己的数据、批量测试、测试召回率步骤总结--转载

转载来源:https://blog.csdn.net/qq_43211132/article/details/90640540







系统:ubuntu16.04.5查看命令:cat /etc/issue
GPU:RTX 2070查看命令:nvidia-smi
python:2.7.15查看命令:python
opencv:3.4.0查看命令:pkg-config --modversion opencv
CUDA Version:8.0.61查看命令:cat /usr/local/cuda/version.txt
CUDNN:6.0.21查看命令:cat /usr/local/cuda/include/cudnn.h

训练过程

1.标注数据,用到的是原图和标注数据(XML)
可以用LabelImg工具标注。
链接:https://pan.baidu.com/s/11zsNoah9nIRDjqgPPQ-xxA 提取码:874q

2.下载yolov3项目工程

git clone https://github.com/pjreddie/darknet
cd darknet
make

 
 
  • 1
  • 2
  • 3

3.修改Makefile文件

GPU=1
CUDNN=1
OPENCV=1

-gencode arch=compute_61,code=[sm_61,compute_61] 根据GPU版本修改

NVCC=/usr/local/cuda-8.0/bin/nvcc

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

4.准备所需的数据集格式

1)建立VOCdevkit文件夹,里面为名为VOC2018的文件夹,在里面是4个文件夹,Annotations、 ImageSets、JPEGImages、labels
在这里插入图片描述
2)Annotations是存放标注的XML文件
ImageSets里面有个main文件夹,里面装着train.txt和val.txt,里面装的是图片名称的前缀儿
JPEGImages用于存放原图
labels用于存放每个图片目标数据的txt文件(纯数据)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3)执行getTxtOfTandV.py文件,提取文件名的前缀,并按1:9的比例分训练集和测试集(网上有)

#coding:utf-8
import os
import random

trainval_percent = 1 #训练验证数据集的百分比
train_percent = 0.9 #训练集的百分比
xmlfilepath = ‘/home/…/darknet/VOCdevkit/VOC2018/Annotations’ #xml文件的路径
txtsavepath = ‘/home/…/darknet/VOCdevkit/VOC2018/ImageSets/Main’ #txt文件的保存路径 # os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表。这个列表以字母顺序。
total_xml = os.listdir(xmlfilepath)
num=len(total_xml) #列表的长度
list=range(num)
tv=int(numtrainval_percent) #训练验证集的图片个数
tr=int(tv
train_percent) #训练集的图片个数 # sample(seq, n) 从序列seq中选择n个随机且独立的元素;
trainval= random.sample(list,tv)
train=random.sample(trainval,tr)
#创建文件trainval.txt,test.txt,train.txt,val.txt
ftrain = open(’/home/sys507/darknet/VOCdevkit/VOC2018/ImageSets/Main/train.txt’, ‘w’)
fval = open(’/home/sys507/darknet/VOCdevkit/VOC2018/ImageSets/Main/val.txt’, ‘w’)
for i in list:
name=total_xml[i][:-4]+’\n’
if i in train:
ftrain.write(name)
else:
fval.write(name)
#ftrainval.close()
ftrain.close()
fval.close()
#ftest .close()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

4)执行voc_label.py文件, 通过前缀来获取路径提取txt数据再生成两个名为train.txt和val.txt用于
存放图片路径的文件
带注解版:链接:https://pan.baidu.com/s/1hJ6bor2ZThFboZjQQODMzw 提取码:gd86

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join

sets=[(‘2018’, ‘train’), (‘2018’, ‘val’)]

classes = [“foreignbody”]

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 = xdw
w = w
dw
y = ydh
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’)
tree=ET.parse(in_file)
root = tree.getroot()
size = root.find(‘size’)
w = int(float(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))
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’)
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()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

5.下载预训练权重

wget https://pjreddie.com/media/files/darknet53.conv.74 

 
 
  • 1

6.修改cfg/voc.data文件

classes= 1
train  = /home/.../darknet/2018_train.txt
valid  = /home/.../darknet/2018_val.txt
names = data/voc.names
backup = backup

 
 
  • 1
  • 2
  • 3
  • 4
  • 5

7.修改data/voc.names文件
类别名

8.修改cfg/yolov3-voc.cfg文件

# Training
batch=64
subdivisions=16

filters=18
classes=1 3处

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

9.训练

./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg  darknet53.conv.74

 
 
  • 1

10.批量测试
1)将.cfg文件修改为测试模式(注解去掉)
2)添加头文件:

    #include <sys/stat.h>
	#include<stdio.h>
	#include<time.h>
	#include<sys/types.h>

 
 
  • 1
  • 2
  • 3
  • 4

3)在开头加入

char *GetFilename(char *p)
{
    static char name[20]={""};
    char *q = strrchr(p,'/') + 1;
    strncpy(name,q,6);//注意后面的6,如果你的测试集的图片的名字字符(不包括后缀)是其他长度,请改为你需要的长度(官方的默认的长度是6)
    return name;
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

4)将以下代码替换examples/detector.c中的test_detector函数,修改自己的路径

void test_detector(char *datacfg, char *cfgfile, char *weightfile, char *filename, float thresh, float hier_thresh, char *outfile, int fullscreen)
{
list *options = read_data_cfg(datacfg);
char *name_list = option_find_str(options, "names", "data/names.list");
char **names = get_labels(name_list);

image **alphabet = load_alphabet();
network *net = load_network(cfgfile, weightfile, 0);
set_batch_network(net, 1);
srand(2222222);
double time;
double start;
double endTime ;
double totalTime = 0.0;
char buff[256];
char *input = buff;
float nms=.45;
int i=0;
int number = 0;
while(1){
    if(filename){
        strncpy(input, filename, 256);
        image im = load_image_color(input,0,0);
        image sized = letterbox_image(im, net-&gt;w, net-&gt;h);
    //image sized = resize_image(im, net-&gt;w, net-&gt;h);
    //image sized2 = resize_max(im, net-&gt;w);
    //image sized = crop_image(sized2, -((net-&gt;w - sized2.w)/2), -((net-&gt;h - sized2.h)/2), net-&gt;w, net-&gt;h);
    //resize_network(net, sized.w, sized.h);
        layer l = net-&gt;layers[net-&gt;n-1];


        float *X = sized.data;
        time=what_time_is_it_now();
        network_predict(net, X);
        printf("%s: Predicted in %f seconds.\n", input, what_time_is_it_now()-time);

        int nboxes = 0;
        detection *dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, 0, 1, &amp;nboxes);
        //printf("%d\n", nboxes);
        //if (nms) do_nms_obj(boxes, probs, l.w*l.h*l.n, l.classes, nms);
        if (nms) do_nms_sort(dets, nboxes, l.classes, nms);
            draw_detections(im, dets, nboxes, thresh, names, alphabet, l.classes);
            free_detections(dets, nboxes);
        if(outfile)
         {
            save_image(im, outfile);
         }
        else{
            save_image(im, "predictions");

/*
#ifdef OPENCV
cvNamedWindow(“predictions”, CV_WINDOW_NORMAL);
if(fullscreen){
cvSetWindowProperty(“predictions”, CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
}
show_image(im, “predictions”);
cvWaitKey(0);
cvDestroyAllWindows();
#endif*/
}
free_image(im);
free_image(sized);
if (filename) break;
}
else {
printf("Enter Image Path: ");
fflush(stdout);
input = fgets(input, 256, stdin);
if(!input) return;
strtok(input, “\n”);

        list *plist = get_paths(input);
        char **paths = (char **)list_to_array(plist);
         printf("Start Testing!\n");
        int m = plist-&gt;size;
        if(access("/home/sys507/darknet2/data/out",0)==-1)//"/home/FENGsl/darknet/data"修改成自己的路径
        {
          if (mkdir("/home/sys507/darknet2/data/out",0777))//"/home/FENGsl/darknet/data"修改成自己的路径
           {
             printf("creat file bag failed!!!");
           }
        }

        start=what_time_is_it_now();
        for(i = 0; i &lt; m; ++i){
         char *path = paths[i];
         image im = load_image_color(path,0,0);
         image sized = letterbox_image(im, net-&gt;w, net-&gt;h);
    //image sized = resize_image(im, net-&gt;w, net-&gt;h);
    //image sized2 = resize_max(im, net-&gt;w);
    //image sized = crop_image(sized2, -((net-&gt;w - sized2.w)/2), -((net-&gt;h - sized2.h)/2), net-&gt;w, net-&gt;h);
    //resize_network(net, sized.w, sized.h);
    layer l = net-&gt;layers[net-&gt;n-1];


    float *X = sized.data;


    time=what_time_is_it_now();
    network_predict(net, X);
    endTime =  what_time_is_it_now()-time;
    printf("Try Very Hard:");
    printf("%s: Predicted in %f seconds.\n", path, endTime);
    totalTime = totalTime + endTime;
    number ++;
    int nboxes = 0;
    detection *dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, 0, 1, &amp;nboxes);
    //printf("%d\n", nboxes);
    //if (nms) do_nms_obj(boxes, probs, l.w*l.h*l.n, l.classes, nms);
    if (nms) do_nms_sort(dets, nboxes, l.classes, nms);
    draw_detections(im, dets, nboxes, thresh, names, alphabet, l.classes);
    free_detections(dets, nboxes);
    if(outfile){
        save_image(im, outfile);
    }
    else{

         char b[2048];
        sprintf(b,"/home/sys507/darknet2/data/out/%s",GetFilename(path));//"/home/FENGsl/darknet/data"修改成自己的路径

        save_image(im, b);
        printf("save %s successfully!\n",GetFilename(path));

/*
#ifdef OPENCV
cvNamedWindow(“predictions”, CV_WINDOW_NORMAL);
if(fullscreen){
cvSetWindowProperty(“predictions”, CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
}
show_image(im, “predictions”);
cvWaitKey(0);
cvDestroyAllWindows();

#endif
*/
}

    free_image(im);
    free_image(sized);
    if (filename) break;
    }
    printf("number: There are %d  pictures.\n",number);
    printf("time: it costs %f seconds.\n",totalTime);
    printf("speed: Predicted %f in 1 seconds.\n",number/totalTime);
  }

}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150

5)修改完要make编译
6)然后输入测试指令:

./darknet detector test cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_final.weights 

 
 
  • 1

10.测试召回率
1)修改detector.c文件中validate_detector_recall函数
list *plist = get_paths("data/coco_val_5k.list");
换成

list *plist=get_paths("/home/.../darknet/2018_train.txt");

 
 
  • 1

2)for(k = 0; k < l.w*l.h*l.n; ++k){
换成

for(k = 0; k < nboxes; ++k){

 
 
  • 1

3)执行指令

./darknet detector recall cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_final.weights

 
 
  • 1
## YOLOv3训练自己的数据、批量测试、测试召回率步骤总结--转载
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值