一:darknet下载与安装 (https://pjreddie.com/darknet/yolo/)
1.源码下载并编译,终端输入:
git clone https://github.com/pjreddie/darknet
cd darknet
make
wget https://pjreddie.com/media/files/yolo.weights
wget http://pjreddie.com/media/files/darknet19_448.conv.23
将下载的模型darknet19_448.conv.23(yolov2)放在darknet文件夹目录下
二:制作数据集的标签生成xml文件
数据集的介绍(YOLOV2训练一类person)
数据集下载:https://pjreddie.com/projects/pascal-voc-dataset-mirror/
还包含一些工具包和文档说明。
1.VOC2007中包含9963张标注过的图片, 由train/val/test三部分组成, 共标注出24,640个物体。 VOC2007的test数据label已经公布,不多说了,看懂VOC2012,VOC2007也就ok!
2.VOC2012是VOC2007的升级,对于检测任务,VOC2012的trainval/test包含08-11年的所有对应图片。 trainval有11540张图片共27450个物体。 对于分割任务, VOC2012的trainval包含07-11年的所有对应图片, test只包含08-11。trainval有 2913张图片共6929个物体。
一共20个类,如下:
• person
• bird, cat, cow, dog, horse, sheep
• aeroplane, bicycle, boat, bus, car, motorbike, train
• bottle, chair, dining table, potted plant, sofa, tv/monitor
文件结构如下:
–Annotations(存放数据标注的XML文件)
–ImageSets(存放TXT文件)
-----Action存放的是人的动作(例如running、jumping等等)
-----Layout存放的是具有人体部位的数据(人的head、hand、feet等等)
-----Main保存了具体数据集的索引,{class}_trainval.txt {class}_val.txt 的格式命名。 train.txt val.txt 例外
-----Segmentation存放的是可用于分割的数据
–JPEGImages(存放源图片)
–labels(存放标注的xml文件生成的txt文件)
–SegmentationClass标注出每一个像素的类别
–SegmentationObject标注出每一个像素属于哪一个物体
对train文件的说明:
train: Training data
val: Validation data (suggested). The validation data may be used as addi-
tional training data (see below).
trainval: The union of train and val.
test: Test data. The test set is not provided in the development kit. It will be
released in good time before the deadline for submission of results.
其中,2012_train.txt + 2012_val.txt = train.txt(代指文件中的路径数量)
{class}_train.txt 保存类别为 class 的训练集的所有索引,每一个 class 的 train 数据都有 5717 个。
{class}_val.txt 保存类别为 class 的验证集的所有索引,每一个 class 的val数据都有 5823 个
{class}_trainval.txt 保存类别为 class 的训练验证集的所有索引,每一个 class 的val数据都有11540 个
2011_003194 -1
2011_003216 -1
2011_003223 -1
2011_003230 1
2011_003236 1
2011_003238 1
2011_003246 1
2011_003247 0
2011_003253 -1
2011_003255 1
2011_003259 1
2011_003274 -1
2011_003276 -1
注:1代表正样本,-1代表负样本。
官方给的解释:
-1: Negative: The image contains no objects of the class of interest. A classi-
fier should give a ‘negative’ output.
1: Positive: The image contains at least one object of the class of interest.
A classifier should give a ‘positive’ output.
0: “Difficult”: The image contains only objects of the class of interest marked
as ‘difficult’.
额外的补充:C++中return 0,-1,1
一个有返回值的函数,如果函数执行成功返回0,不成功返回非0,一般情况下非0值常用-1来表示。
参考:https://blog.csdn.net/wenxueliu/article/details/80327316 找了好久的博客,良莠不齐真的是烦。
制作数据集步骤
1.对原始数据进行筛选,并对其排序(000001…),改后缀名为jpg;
2.具体代码下次再贴;
3.VOC的结构如下:
这里面用到的文件夹是Annotation、ImageSets和JPEGImages。其中文件夹Annotation中主要存放xml文件,每一个xml对应一张图像,并且每个xml中存放的是标记的各个目标的位置和类别信息,命名通常与对应的原始图像一样;而ImageSets我们只需要用到Main文件夹,这里面存放的是一些文本文件,通常为train.txt、test.txt等,该文本文件里面的内容是需要用来训练或测试的图像的名字(无后缀无路径);JPEGImages文件夹中放我们已按统一规则命名好的原始图像。
因此,首先:
1).新建文件夹(通常命名为VOC+年份)VOC2007
2).在VOC2007文件夹下新建三个文件夹Annotation、ImageSets和JPEGImages,并将准备好的自己的数据集放在JPEGImages文件夹下
3).在ImageSets文件夹中,新建三个空文件夹Layout、Main、Segmentation
4).生成xml文件
对1中得到的数据集进行手动标注,并生成VOC格式数据集的xml文件,保存于2中VOC2007/Annotations/(使用labelImg软件,安装与使用教程:https://blog.csdn.net/jesse_mx/article/details/53606897)
使用此方法标注时,filename中文件的文件名名没有后缀,因此需要统一加上后缀。只需一段命令即可:在Annotations文件夹下运行:find -name '*.xml' |xargs perl -pi -e 's||.jpg|g'
三.生成txt与labels文件
1.利用脚本voc_label.py,在VOC2007/ImageSets/main/下生成train.txt与val.txt
2.对scripts/的脚本voc_label.py进行改动,生成一系列训练文件的txt文件(主要存放训练或验证集的绝对路径)和labels(主要存放训练或验证集的类别,坐标信息)。
3.修改后在scripts/运行命令:python voc_label.py,之后则在文件夹scripts\VOCdevkit\VOC2007下生成了tain.txt与val.txt以及文件夹lables,如下所示:
四:修改配置文件
做好了上述准备,就可以根据不同的网络设置(cfg文件)来训练了。在文件夹cfg中有很多cfg文件,这里选用的是:yolo-voc.2.0.cfg
1.先是在data文件夹下创建一个voc.names(存放类别)文件,内容只有person。
2.cfg/voc.data中
classes= 1
train = /home/aibc/Wen/darknet/scripts/train.all.txt #上一步生成的train.txt的绝对路径
valid = /home/aibc/Wen/darknet/scripts/2007_val.txt
names = data/voc.names
backup = /home/aibc/Wen/darknet/backup #backup的绝对路径,用于保存训练中的权重文件
3.cfg/yolov2.cfg)中
【region】层classes改为分类的个数1
【region】层上一个【convolution】层中filters改为(classes+ coords+ 1)* (NUM)=(1+4+1)×5=30
by the way,只要修改好了voc.data和yolo网络参数文件和voc.names,不用修改源码,因为读取配置文件时,已将配置读取完成。
4.examples/yolo.c
改类别:char *voc_names={“fire”}
修改draw_detection这个函数最后一个参数:20改成1。
在demo函数中,倒数第三个参数把20改成了1。
开头的train_yolo函数中,修改
train_images=”/home/darknet/scripts/train.txt” ——即你自己存放的train.txt所在目录
backup_directory = “/home/darknet/backup”——训练完成存放模型的目录
5.examples/detector.c
开头的train_yolo函数中,修改
train_images=”/home/darknet/scripts/train.txt” ——即你自己存放的train.txt所在目录
最后的classes修改为自己的值1。
6.在修改好所有文件后,在/darknet 终端输入:
make clean
make
五.训练
1.下载预训练模型darknet19_448.conv.23放在darknet目录下
2.运行./darknet detector train cfg/voc.data cfg/yolov2.cfg darknet19_448.conv.23
开始训练
3.最大迭代次数在yolov2.cfg中max_batches修改
4.detector.c中validate_detector_recall函数中修改阈值thresh
5.保存日志文件(方便可视化,这个地方没太明白)
(1).在训练前,darknet目录下终端输入:script -a log.txt
;darknet目录下终端输入:./darknet detector train cfg/voc.data cfg/yolov2.cfg darknet19_448.conv.23
;训练完成后记得使用ctrl+D或者输入exit结束屏幕录像。
(2).在./darknet detector train cfg/voc.data cfg/yolov2.cfg darknet19_448.conv.23 | tee log.txt
特别卡,不推荐使用。
六.测试
在darknet下运行:
测试图片:
./darknet detector test cfg/voc.data cfg/yolov2.cfg backup/yolov2_6000.weights data/test.jpg
测试视频:
./darknet detector demo cfg/voc.data cfg/yolov2.cfg yolov2_39000.weights data/person.avi
测试Map,recall:
https://blog.csdn.net/lucky__ing/article/details/78310510?utm_source=debugrun&utm_medium=referral
测试map:
1.使用的yolo网络自带的valid函数接口来测试大量的图片,读取每张被测试的图片的置信度及bbox像素坐标,然后保存在results 下的321smoke.txt文件里,也可以是其他的文件,名字,位置自己决定。(是否可提取出代码,提取任意被测图片的坐标及xml文件???)
./darknet detector valid cfg/voc.data cfg/yolov2.cfg yolov2_38400.weights -out 321 -thresh 0.5
2.首先cfg/voc.data里面是一些路径的描述,具体内容为
classes= 1
train = /hom……….../train.txt
valid = /home……….../valid.txt
names = data/voc.names
backup = backup
3.将原图与xml文件放在同一个文件夹下,再将将计算的源码(https://github.com/lucky-ing/voc_eval)下载到本地,很小的文件,进入下载解压后的文件夹,终端输入:
python 123.py /home/aibc/Wen/darknet/results/321person.txt /home/aibc/Wen/darknet/VOCdevkit/VOC2007/2007_val.txt person
不同的class有不同的valid文件,所以不同的分类需要一个一个测试。
七.YOLO模型训练可视化训练过程中的中间参数
一:使用python语言
1.可视化中间参数需要用到训练时保存的log文件:在darknet下运行:./darknet detector train cfg/voc.data cfg/yolo-voc.2.0.cfg darknet19_448.conv.23 | tee smoke_train_log.txt
保存log时会在darknet下生成两个文件,“文件1”里保存的是网络加载信息和checkout点保存信息,“fire_train_log.txt”中保存的是训练信息。
2.在使用脚本绘制变化曲线之前,需要先使用extract_log.py脚本,格式化log,用生成的新的log文件供可视化工具绘图,格式化log的extract_log.py脚本如下:
3.使用train_loss_visualization.py脚本可以绘制loss变化曲线
train_loss_visualization.py脚本如下:
修改train_loss_visualization.py中lines为log行数,并根据需要修改要跳过的行数:
运行train_loss_visualization.py会在脚本所在路径生成avg_loss.png。
可以通过分析损失变化曲线(The loss curves),修改cfg中的学习率变化策略,比如上图:模型在100000万次迭代后损失下降速度非常慢,几乎没有下降。结合log和cfg文件发现,自定义的学习率变化策略在十万次迭代时会减小十倍,十万次迭代后学习率下降到非常小的程度,导致损失下降速度降低。修改cfg中的学习率变化策略,10万次迭代时不改变学习率,30万次时再降低。
4.除了可视化loss,还可以可视化Avg IOU,Avg Recall等参数可视化’Region Avg IOU’, ‘Class’, ‘Obj’, ‘No Obj’, ‘Avg Recall’,’count’这些参数可以使用脚本train_iou_visualization.py,使用方式和train_loss_visualization.py相同,train_iou_visualization.py脚本如下:
运行train_iou_visualization.py会在脚本所在路径生成相应的曲线图。
-----------------------------------------------分割线---------------------------------------------------
先写这么多,在更新吧!