keras-yolov3训练自己的数据
keras-yolov3基本使用
keras-yolov3是yolov3算法的keras实现,之所以找keras实现是因为tensorflow-gpu经过个人测试是相对比较完整的支持cuda的。opencv 4.1.1 如今的dnn模块还不能通过cuda进行加速,opencv官方现在仍在努力。基本使用方法这边不再表述,项目的README.md文件中已经描述的很清楚了。使用过程中碰到的一个要注意的地方就是不要安装当前最新的tensorflow-gpu 2.0,实测1.15rc3是正常的,主要原因是2.0里没有了get_session方法,运行会报错。用gtx1050时的推理速度是6~7fps,比用cpu的0.5fps快很多了。接下来开始训练自己的检测分类和数据。自己训练的原因是yolo默认训练用的数据集中没有我要的分类。要想检测自己的分类就要用自己的数据做标记,然后丢进去训练。
准备数据
视频截图
数据源是一堆视频,但是我们需要截成jpg图片才能使用。发现yolo_mark工具除了可以标记数据,也可以从视频中批量截取jpg照片。通过yolo mark这个工具标记的数据格式跟keras-yolov3所需的数据格式不同,但是yolo_mark将视频自动截图的功能挺好用的。yolo mark项目依赖opencv2 或 opencv3,使用过程中实测确实不能用opencv 4。
准备VOC文件夹框架
想要训练自己的数据,keras-yolov3作者建议用voc_annotation.py这个工具来标记数据,那要用到这个工具的话那我们就需要把数据整理成VOC数据集的样式(VOC数据格式也是ImageNet使用的格式)。先在keras-yolov3根目录下新建一个VOC数据集的文件夹框架(里面不能有其他文件,只有文件夹),文件夹组织如下:1
2
3
4
5
6
7
8
9VOCdevkit
└VOC2007
├Annotations
├ImageSets
│ ├Layout
│ ├Main
│ └Segmentation
├JPEGImages
└labels
使用labelImg标记数据
使用labelImg工具进行数据标记,使用方法项目readme文件有说明。可以把图片数据放在lanbelImg/data/img目录下,想要预先分拣出的分类写到labelImg/data/predefined_classes.txt文件中。使用如下指令运行1
python labelImg.py data/img data/predefined_classes.txt
标记完成的jpg放到VOC的JPEGImages文件夹里,data/annotation下的xml文件放到VOC的Annotations文件夹里。
返回到keras-yolov3的目录下,切到VOC2007目录下新建一个python脚本文件,用以生成VOC2007/ImageSets/Main目录下的四个txt文件:train.txt, val.txt, trainval.txt, test.txt,脚本内容如下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
import os
import random
trainval_percent = 0.1
train_percent = 0.9
xmlfilepath = 'Annotations'
txtsavepath = 'ImageSets/Main'
total_xml = os.listdir(xmlfilepath)
num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
train = random.sample(trainval, tr)
if not os.path.exists(txtsavepath):
print('not exist...{}'.format(txtsavepath))
os.makedirs(txtsavepath)
ftrainval = open('ImageSets/Main/trainval.txt', 'w')
ftest = open('ImageSets/Main/test.txt', 'w')
ftrain = open('ImageSets/Main/train.txt', 'w')
fval = open('ImageSets/Main/val.txt', 'w')
for i in list:
name = total_xml[i][:-4] + '\n'
if i in trainval:
ftrainval.write(name)
if i in train:
ftest.write(name)
else:
fval.write(name)
else:
ftrain.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest.close()
保存后运行。接着修改keras-yolov3目录下的voc_annotation.py中的classes,设定为自己所需的分类后,保存,运行。会发现主目录下多了3个文件:2007_text.txt,2007_train.txt,2007_val.txt。
准备预训练模型
下载darknet的预训练模型并且重命名为darknet53.weights。通过以下指令将其转换成keras需要的h5格式1
python convert.py -w darknet53.cfg darknet53.weights model_data/yolo_weights.h5
运行中如果出现requires 某个库的错误那就安装一下然后重新运行。检查yolo_weights.h5文件是否有生成。
修改classes文件
修改model_data/voc_classes.txt,将内容改成自己所需要的类别
修改anchor文件
anchor设置好坏影响训练和推理的结果,通过kmeans.py脚本可以得到我们训练集所对应的anchor。将得到的anchors值填入model_data/yolo_anchors.txt中。
修改yolov3.cfg文件
参照这篇文章进行修改 yolo3 配置文件yolo3_voc.cfg参数学习。
- 首先前面几行将testing相关的设置注释掉,将training相关的设置取消注释。
- 查找yolo,总共会发现3个地方。每个地方都有4个变量要修改:filters,classes和random。
- classes就是我们需要推理的分类数量,我这里是2
- filters = 3 * (5 + len(classes)),我这里就是21
- 如果显存比较小random要从1改为0
则需要卸载掉当前版本的keras,然后安装keras 2.1.5。1
2pip uninstall keras
pip install keras==2.1.5
如果提示错误是下面这个样子的,这个一般在运行中途时候出现:1
Hint: If you want to see a list of allocated tensors when OOM happens, add report_tensor_allocations_upon_oom to RunOptions for current allocation info.
或者什么类似于资源一类的字眼出现,那一般是gpu的显存不足,在train.py中将batch_size修改小,默认是32,可以改成16或者8或者4,但是改小会导致模型精度下降。GTX1050改到2了才没有报错,可能后期会将训练转移动云服务器上进行。
训练完成
寻找一个trained_weights_final.h5文件,将该文件拷贝到model_data目录下,并且改名为yolo.h5,(原来的yolo.h5需要做好备份)。
进行推理
model_data/voc_classes.txt里改为自己的分类,另外yolov3.cfg文件前面的training要换回testing。yolo.py第26行的score可以改低点,如果没改低可能很难检测出来。
然后运行如下指令进行推理1
python yolo_video.py --input ../keras/mp4/test.mp4 --classes=model_data/voc_classes.txt
后续
代码分析什么的……emmmm