Yolov--3--TensorRT中yolov3性能优化加速(基于caffe)
yolov-5-目标检测:YOLOv2算法原理详解
yolov--8--Tensorflow实现YOLO v3
yolov--9--YOLO v3的剪枝优化
yolov--10--目标检测模型的参数评估指标详解、概念解析
yolov--12--YOLOv3的原理深度剖析和关键点讲解
TX2上用YOLOv3训练自己数据集的流程(VOC2007数据集-TX2-GPU版本)
平台:英伟达NVIDIA TX2开发板 环境:python2.7,cuda8.0,cudnn6.0.2,opencv2.4.13.1
以下2007都改为2009,文件夹修改的原因
以防8G的内存不够用,另外开辟4-8G的虚拟内存:
1. 创建8G大小的swapfile
fallocate -l 8G swapfile
2. 更改swapfile的权限
chmod 600 swapfile
3. 创建swap区
mkswap swapfile
4. 激活swap区
sudo swapon swapfile
5. 确认swap区在用
swapon -s
6、关闭swap区
sudo swapoff -a
运行过程中如果遇到内存占用较多,执行以下语句清除部分内存的占用:
sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'
查看TX2上的CPU情况
$cat /proc/cpuinfo
or
$lscpu
TX2上电的时候,默认最低功耗模式1,即只有4个CPU核心开启,风扇不转;
1、直接运行home下的jetson_clocks.sh,开启最大频率
sudo ~/jetson_clocks.sh
然后小风扇就呼啦啦转起来啦。。
在Jetson Xavier上,jetson_clock.sh为当前的nvpmodel模式提供了最佳的性能。nvpmodel配置为任何给定模式定义了最大和最小时钟值。jetson_clocks.sh将时钟值调整到最大值。哦,当你决定全速跑的时候,有时会调整风扇的数值。
jetson_clocks.sh还可以显示CPU、GPU和EMC的当前设置。
$sudo ./jetson_clock.sh --show
2、查询当前工作模式,输入
sudo nvpmodel -q verbose
此时显示的是
NV Power Mode: MAX-P ARM
3
3、修改工作模式为0,输入:
sudo nvpmodel -m 0
再次查询,
$sudo nvpmodel -q verbose
NV Power Mode: MAXN
0
模式0下TX2的6个CPU核心全部开启,即火力全开模式,这样工作模式修改成功。火力全开模式可以有效提高速度!
注意nvpmodel设置更改后,重启后数值会保持。
1.1 数据集制作:
A.制作VOC格式的xml文件工具:LabelImg
将xml文件存放在/darknet/scripts/VOCdevkit/VOC2009/Annotations
B.将VOC格式的xml文件转换成YOLO格式的txt文件
用到的脚本:voc_label.py
执行:cd darknet
python voc_label.py
生成:
1、/darknet/scripts/VOCdevkit/VOC2009/labels
2、/darknet/scripts/2009_train.txt
.txt里的数据格式是这样的:
具体的每一个值的计算方式是这样的:假设一个标注的boundingbox的左下角和右上角坐标分别为(x1,y1)(x2,y2),图像的宽和高分别为w,h
归一化的中心点x坐标计算公式:((x2+x1) / 2.0)/ w
归一化的中心点y坐标计算公式:((y2+y1) / 2.0)/ h
归一化的目标框宽度的计算公式: (x2-x1) / w
归一化的目标框高度计算公式:((y2-y1)/ h
1.2 文件修改
准备好了自己的图像后,需要按VOC数据集的结构放置图像文件。VOC的结构如下
--VOC2009
--Annotations ---主要存放xml文件
--ImageSets
--Main -----为train.txt等(需要自己用软件生成)
作用:
--Layout
--Segmentation
--JPEGImages ---放我们已按统一规则命名好的原始图像
--SegmentationClass
--SegmentationObject
这里面用到的文件夹是Annotation、ImageSets和JPEGImages。
其中文件夹Annotation中主要存放xml文件,每一个xml对应一张图像,并且每个xml中存放的是标记的各个目标的位置和类别信息,命名通常与对应的原始图像一样;而ImageSets我们只需要用到Main文件夹,这里面存放的是一些文本文件,通常为train.txt等,该文本文件里面的内容是需要用来训练或测试的图像的名字(无后缀无路径);JPEGImages文件夹中放我们已按统一规则命名好的原始图像。
因此,首先
1.新建文件夹VOC2009(通常命名为这个,也可以用其他命名,但一定是名字+年份,例如MYDATA2016,无论叫什么后面都需要改相关代码匹配这里,本例中以VOC2007为例)
2.在VOC2009文件夹下新建三个文件夹Annotation、ImageSets和JPEGImages,并把准备好的自己的原始图像放在JPEGImages文件夹下
3.在ImageSets文件夹中,新建三个空文件夹Layout、Main、Segmentation,然后把写了训练或测试的图像的名字的文本拷到Main文件夹下,按目的命名,我这里所有图像用来训练,故而Main文件夹下只有train.txt文件。
1.3 编译工程
改配置文件:
我想要GPU支持的版本,所以在编译工程前需要先修改Makefile文件,根据自己需求改,GPU版本的将GPU=1,CUDNN = 1, OPENCV=1,
执行:
cd darknet
make
如果遇到缺失包报错,将缺失的包装上去以后重新编译,重复下列两个操作,直到所有包都装好,
make clean
make
1.4 配置文件参数修改
(A) 修改darknet/cfg/voc-1.data
classes= 80 类别数
train = /home/nvidia/darknet/scripts/2009_train.txt 训练数据2009_train.txt的路径
//valid = /home/pjreddie/data/voc/2009_test.txt 验证数据2009_test.txt的路径
names = data/2-voc-1.names 存放类别名
backup = /home/nvidia/darknet/backup 生成的权重文件存放的路径
(B)关于cfg修改,以6类目标检测为例,主要有以下几处调整(蓝色标出),也可参考我上传的文件,里面对应的是4类。#表示注释,根据训练和测试,自行修改。
例如:cfg/yolov3-1.cfg
[net]
# Testing
# batch=1
# subdivisions=1
# Training
batch=1
subdivisions=1
# 一批训练样本的样本数量,每batch个样本更新一次参数
# batch/subdivisions作为一次性送入训练器的样本数量
# 如果内存不够大,将batch分割为subdivisions个子batch
# 上面这两个参数如果电脑内存小,则把batch改小一点,batch越大,训练效果越好
# subdivisions越大,可以减轻显卡压力
learning_rate:学习率,训练发散的话可以降低学习率。学习遇到瓶颈,loss不变的话也减低学习率。
max_batches: 最大迭代次数。
policy:学习策略,一般都是step这种步进式。
step,scales:这两个是组合一起的,举个例子:learn_rate: 0.001, step:100,25000,35000 scales: 10, .1, .1 这组数据的意思就是在0-100次iteration期间learning rate为原始0.001,在100-25000次iteration期间learning rate为原始的10倍0.01,在25000-35000次iteration期间learning rate为当前值的0.1倍,就是0.001, 在35000到最大iteration期间使用learning rate为当前值的0.1倍,就是0.0001。随着iteration增加,降低学习率可以是模型更有效的学习,也就是更好的降低train loss。
最后一层卷积层中filters数值是 5×(类别数 + 5)。
region里需要把classes改成你的类别数。
最后一行的random,是一个开关。如果设置为1的话,就是在训练的时候每一batch图片会随便改成320-640(32整倍数)大小的图片。目的和上面的色度,曝光度等一样。如果设置为0的话,所有图片就只修改成默认的大小 416*416。
1.5 跑模型
I.5.1 训练
上面完成了就可以命令训练了,可以在官网上找到一些预训练的模型作为参数初始值,也可以直接训练,训练命令为
$./darknet detector train ./cfg/voc-1.data cfg/yolov3-1.cfg
将权重文件保存在/darknet/backup下
训练过程中会根据迭代次数保存训练的权重模型,然后就可以拿来测试了。
Avg IOU: 当前迭代中,预测的box与标注的box的平均交并比,越大越好,期望数值为1;
Class: 标注物体的分类准确率,越大越好,期望数值为1;
obj: 越大越好,期望数值为1;
No obj: 越小越好;
.5R: 以IOU=0.5为阈值时候的recall; recall = 检出的正样本/实际的正样本
0.75R: 以IOU=0.75为阈值时候的recall;
count: 正样本数目。
I.5.2 测试
(1)一张图片
./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg
原始图片
生成的图片保存在darknet下
(2)一个视频
./darknet detector demo cfg/voc-1.data cfg/yolov3-1.cfg yolov3.weights data/test1.flv
(3)批量图片
./darknet detector test cfg/voc-2.data cfg/yolov3-1.cfg yolov3.weights
Enter Image Path:后面输入你的txt文件路径(你准备好的所有测试图片的路径全部存放在一个txt文件里)
这里可以输入:/home/nvidia/darknet/scripts/2009_train.txt
输出带标记的图片保存在:/darknet /data/out
(4)验证批量图片,返回评估值
将要验证的每张图片的路径保存在scripts/2009_valid-1.txt 下
./darknet detector valid cfg/voc-valid-1.data cfg/yolov3-1.cfg yolov3.weights
/*只在./results/det_valid_[类名].txt里保存测试结果,如下:*/
文件名;每个框中存在该分类物体的概率;框框坐标 xmin;框框坐标 ymin;框框坐标 xmax;框框坐标 ymax
其中(左,上) - (右,下)定义检测对象的边界框。 图像中左上角的像素具有坐标(1,1)。 更高的置信度值意味着检测结果的正确性。 下面显示了一个示例文件摘录。 请注意,对于图像000006,检测到多个对象:
复制代码
//comp3_det_test_car.txt:
000004 0.702732 89 112 516 466
000006 0.870849 373 168 488 229
000006 0.852346 407 157 500 213
(5)查看训练网络的召回率
https://www.jianshu.com/p/7ae10c8f7d77/
https://blog.csdn.net/hysteric314/article/details/54093734
./darknet detector recall cfg/voc-valid-1.data cfg/yolov3-1.cfg yolov3.weights (这个命令需修改dectector.c文件)
大雁与飞机
假设现在有这样一个测试集,测试集中的图片只由大雁和飞机两种图片组成,如下图所示:
假设你的分类系统最终的目的是:能取出测试集中所有飞机的图片,而不是大雁的图片。
现在做如下的定义:
True positives : 飞机的图片被正确的识别成了飞机。
True negatives: 大雁的图片没有被识别出来,系统正确地认为它们是大雁。
False positives: 大雁的图片被错误地识别成了飞机。
False negatives: 飞机的图片没有被识别出来,系统错误地认为它们是大雁。
假设你的分类系统使用了上述假设识别出了四个结果,如下图所示:
那么在识别出来的这四张照片中:
True positives : 有三个,画绿色框的飞机。
False positives: 有一个,画红色框的大雁。
没被识别出来的六张图片中:
True negatives : 有四个,这四个大雁的图片,系统正确地没有把它们识别成飞机。
False negatives: 有两个,两个飞机没有被识别出来,系统错误地认为它们是大雁。
Precision 与 Recall
Precision其实就是在识别出来的图片中,True positives所占的比率:
(识别出的飞机数 / 所有识别出来的图片)
其中的n代表的是(True positives + False positives),也就是系统一共识别出来多少照片 。
在这一例子中,True positives为3,False positives为1,所以Precision值是 3/(3+1)=0.75。
意味着在识别出的结果中,飞机的图片占75%。
Recall 是被正确识别出来的飞机个数与测试集中所有飞机的个数的比值:
(识别出的飞机数 / 所有飞机图片数)
Recall的分母是(True positives + False negatives),这两个值的和,可以理解为一共有多少张飞机的照片。
在这一例子中,True positives为3,False negatives为2,那么Recall值是 3/(3+2)=0.6。
意味着在所有的飞机图片中,60%的飞机被正确的识别成飞机.。
准确率就是找得对,召回率就是找得全。
I.5.3 注意
1、测试输出的图片与原图片像素相同,
2、用yolov3-tiny-1.cfg(288*288), 跑test1.flv,大概30帧左右
用yolov3-tiny-1.cfg(输入网络图片像素为416*416), 跑test1.flv,大概20帧左右
用yolov3-tiny-1.cfg(608*608), 跑text1.flv,大概10帧左右
用yolov3-1.cfg(288*288), 跑test1.flv,大概5帧左右
用yolov3-1.cfg(416*416), 跑test1.flv,大概3帧左右
用yolov3-1.cfg(608*608), 跑test1.flv,大概2帧左右
参考文献
[1] https://blog.csdn.net/u012135425/article/details/80294884
[2] https://blog.csdn.net/lilai619/article/details/79695109
[3] https://www.cnblogs.com/antflow/p/7350274.html
[4]https://blog.csdn.net/mieleizhi0522/article/details/79989754
https://www.cnblogs.com/happyamyhope/p/9110899.html