yolov3训练讯飞安检图像数据集记录
前言
最近在做安检图像特定目标检测方面的工作,由于相关的数据还没有到位,前期尝试使用yolov3算法检测讯飞安检图像数据中的危险物品练练手,以下是本次工作的实录,做回顾之用。
前置工作
数据集
使用讯飞初赛提供的安检图像数据,以下摘录数据集标签的详细解释:
yolov3配置
下载yolov3项目代码
git clone https://github.com/pjreddie/darknet
cd darknet
修改Makefile文件并编译
vim Makefile # 文件地址:darknet/Makefile
GPU=1 # 使用GPU训练
CUDNN=0
OPENCV=0
OPENMP=0
DEBUG=0
CC=gcc
CPP=g++
NVCC=/usr/local/cuda-9.0/bin/nvcc # 配置本地CUDA路径
AR=ar
make
实验
准备数据集
将手边的数据集转换为PASCAL VOC的格式。首先在darknet/scripts目录下创建如下形式的文件目录:
VOCdevkit
--VOC2020
----Annotations # 放入所有的xml文件(labels)
----ImageSets
------Main # 放入train.txt, val.txt文件
----JPEGImages # 放入所有的图片文件(data)
ps:在Main文件夹中,train.txt是训练集,val.txt是验证集,test.txt是测试集,trainval.txt是训练和验证集,本次实验只准备了训练集和验证集文本
Main文件夹中txt文件只写文件名,例如
# 图像路径
darkent/scripts/VOCdevkit/VOC2020/JPEGImages/100001.jpg
# train.txt中对应条目
100001 # 对应100001.jpg图像
100002
修改darknet/scripts/voc_label.py。作用:根据Main中txt里的文件名生成相应的txt。
sets = [('2020', 'train'), ('2020', 'val')] #同Main中txt文件一致
classes = ["knife", "scissors", "lighter", "zippooil", "pressure", "slingshot", "handcuffs", "nailpolish", "powerbank", "firecrackers"] # 标签类别
os.system("cat 2020_train.txt 2020_val.txt > train.txt") # 将生成的文件合并
python voc_label.py # 保存后运行
运行后会生成2020_train.txt, 2020_val.txt, train.txt,如图:
下载Imagenet上预先训练的权重
wget https://pjreddie.com/media/files/darknet53.conv.74
修改darknet/cfg/voc.data
classes=10 # 训练样本集的类别总数
train=scripts/2020_train.txt # 训练样本集所在路径
valid=scripts/2020_val.txt # 验证样本集所在路径
names=data/voc.names
backup=backup # 权重文件备份
修改darknet/data/voc.name
knife
scissors
lighter
zippooil
pressure
slingshot
handcuffs
nailpolish
powerbank
firecrackers
修改darknet/cfg/yolov3-voc.cfg
[net]
# Testing
# batch=1
# subdivisions=1
# Training
batch=64
subdivisions=16
首先在普通模式下使用vim命令:/yolo 检索关键词,n 切换下一个匹配
[convolutional]
size=1
stride=1
pad=1
filters=45 # 修改为3*(classes+5)即3*(10+5)= 45
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=10 # 修改为标签类别个数,10类
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=1 # 如果显存很小,将random设置为0,关闭多尺度训练
[convolutional]
size=1
stride=1
pad=1
filters=45 # 修改为3*(classes+5)即3*(10+5)= 45
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=10 # 修改为标签类别个数,10类
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=1 # 如果显存很小,将random设置为0,关闭多尺度训练
[convolutional]
size=1
stride=1
pad=1
filters=45 # 修改为3*(classes+5)即3*(10+5)= 45
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=10 # 修改为标签类别个数,10类
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=1 # 如果显存很小,将random设置为0,关闭多尺度训练
开始训练
在目录darknet/下执行命令,注意各参数文件的目录是否正确。
./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg scripts/darknet53.conv.74
测试识别
训练后使用darknet/backup目录下的权重文件进行测试识别
./darknet detector test cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_20000.weights data/100010.jpg
测试图片:
测试结果:
yolov3训练过程中输出参数详解
- Region XX 表示不同尺度上检测的结果。在darknet中,所有训练图片中的一个batch又被分成subdivision份来进行计算。
- Region XX Avg IOU: 表示在当前subdivision内的图片的平均IOU(预测矩形框同真值矩形框的交集与并集之比)。越大越好,最大为1。
- Class: 标注物体分类的正确率。越大越好,最大为1。
- Obj:越接近1越好。
- No Obj:期望该值越小越好,但不为零。
- .5R:同ground true的IOU值大于0.5为正样本时的recall/count,是当前模型在所有subdivision图片中检测出的正样本与实际的样本的比值。全部正样本被正确的检测到时为1。
- .75R:同ground true的IOU值大于0.75为正样本时的recall/count。count:所有当前subdivision图片中包含正样本的图片的数量。
- 当前训练的迭代次数
- 总体的Loss
- 平均Loss(此数值低于0.060730 avg即可终止训练)
- 当前的学习率
- 当前batch训练花费的总时间
- 到目前为止参与训练的图片的总量==迭代次数 * batch
后续工作
使用yolo算法对安检图像中的目标进行识别的准确率不高,由于许多目标非专业人士一般都识别不出来(我真看不出来打火机之类的),后续尝试在这方面继续研究,提升安检图像识别的准确率。
引用
[1] https://blog.csdn.net/weixin_42731241/article/details/81352013
[2] https://blog.csdn.net/tintinetmilou/article/details/88877039