广告位联系
返回顶部
分享到

darknet框架中YOLOv3对数据集进行训练和预测介绍

python 来源:互联网 作者:佚名 发布时间:2022-11-27 15:39:47 人浏览
摘要

1. 下载darknet源码 在命令窗口(terminal)中进入你想存放darknet源码的路径,然后在该路径下输入依次输入以下命令: git clone https://github.com/pjreddie/darknet cd darknet 上述命令首先从darknet的源

1. 下载darknet源码

在命令窗口(terminal)中进入你想存放darknet源码的路径,然后在该路径下输入依次输入以下命令:

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

cd darknet

上述命令首先从darknet的源码地址复制一份源码到本地,下载下来的是一个名为darknet的文件。然后进入这个名为darknet的文件夹。

2. 修改darknet的Makefile文件

Note:如果不需要darknet在GPU上运行,则略过此步骤,只需执行make命令。 在命令窗口输入以下命令打开Makefile文件:

1

vi Makefile

将Makefile文件开头的GPU=0改为GPU=1,如下所示:

1

2

3

4

5

GPU=1

CUDNN=0

OPENCV=0

OPENMP=0

DEBUG=0

修改完之后,需要执行make命令才可以生效。

1

make

3. 准备数据集

在./darknet/scripts文件夹下创建文件夹,命名为VOCdevkit,然后再在VOCdevkit文件夹下创建一系列文件夹,整个目录结构如下所示:

1

2

3

4

5

6

7

8

VOCdevkit

-VOC2019 # 这个文件夹的年份可以自己取

--Annotations # 在这个文件夹下存放所有的xml文件

--ImageSets

---Main # 在这个文件夹下新建两个TXT文件

----train.txt

----val.txt

--JPEGImages # 在这个文件夹下存放所有的图片文件

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

上述文件及文件夹创建好之后,下面来对我们的数据集生成train.txt和val.txt,这两个文件中存放训练图像和测试图像的文件名(不含.jpg后缀)。 新建一个creat_train_val_txt.py文件(名字可以自己随便取),然后将以下代码复制进去(注意相应路径的修改)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

#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文件后,在命令行执行该文件:

1

python creat_train_val_txt.py

执行完毕之后可以看到刚刚我们新建的train.txt和val.txt文件中被写进了我们的数据集图片的文件名。

在这里插入图片描述

4. 修改voc_label.py

打开scripts文件夹下的 voc_label.py 文件,修改信息:#要修改的地方 共三处

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

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(...)语句。

保存修改后,运行该文件:

1

python voc_label.py

执行完毕之后,会生成2018_train.txt、2018_val.txt、train.txt 三个文件,如下图:

在这里插入图片描述

在labels文件夹下会生成图片对应的txt形式的图片标注信息

在这里插入图片描述

5. 下载预训练模型

为了加速训练过程,可以在darknet官网上下载预训练模型,在该预训练模型上再进行训练。 在命令窗口输入以下命令:

1

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

文件保存在script文件夹下即可

6. 修改./darknet/cfg/voc.data文件

1

2

3

4

5

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文件做如下修改:

1

2

car

people

内容为你的数据集的类别名称,注意和xml文件中的类别名称一致。

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

该文件为网络结构文件。 首先修改开头处如下:

1

2

3

4

5

6

7

[net]

# Testing

# batch=1

# subdivisions=1

# Training

batch=64

subdivisions=16

即,将训练模式打开,将测试模式的语句注释掉。

其中subdivisions为将一个batch(此处为64)分成多大的小batch。如果训练时提示超出内存,则可以相应的改小这两个参数的值。

接着视情况修改开头处的超参数(学习率,迭代次数等):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

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

然后再该文件的底部部分,找到如下语句进行如下修改:

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

......

[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

1

./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg scripts/darknet53.conv.74 -gpus 0,1

10.训练终止后继续训练方法

假如训练由于意外情况,如显存不够终止了,可以通过加载中间权重文件,进而继续训练 中间权重文件在backup文件夹中

在这里插入图片描述

把9步权重文件的路径换为backup中文件即可

1

./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文件。注意此文件不能作为检查模型使用。


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://juejin.cn/post/7168455293167697957
相关文章
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计