最近在学习使用yolov3训练自己的数据,百度上找到了很多使用yolov3训练自己的数据的教程,自己也是踩了很多坑最后才顺利训练了自己的数据,下面记录下自己训练自己数据的过程。
总结来说,快速训练自己的数据需要建立自己的数据集(或者使用自己感兴趣的公开数据集)、将数据集的文件格式改成和要求所需一样的格式、将数据集的格式转换为tfrecorde格式的数据集、使用k-means聚类算法得到自己数据集的anchors、训练、将训练得到的权重文件转换成pb格式的文件进行图片或者视频的预测。
第一步:下载github上大佬写的tensorflow版的yolov3,https://github.com/YunYang1994/tensorflow-yolov3,yolo系列的原理网上有很多人的解读,介绍的很详细,我是看博客专家木盏大神的解读,他对yolo所有版本的解读都很详细,https://blog.youkuaiyun.com/lev iopk u/article/details/82660381。
第二步,也是需要自己动手最多的一步,数据集的准备,如果用自己标注的数据集进行训练的话,需要使用标注工具对数据集进行标注,大家使用最多的标注工具是LabelImg,使用教程参考 https://blog.youkuaiyun.com/u012746060/article/details/81016993。此版本的yolov3的代码提供者要求数据的格式为:图片数据的路径 groundtruth的坐标 类别标签,中间使用空格分开,如下图所示。
image_path x_min y_min x_max y_max class_id x_min y_min ... class_id
也就是说,不管你是自己制作的数据集还是使用公开的数据集,在这一步都要将格式转换成这样。我这里是进行交通标志的识别,使用的是公开数据集GTSDB。如果是使用LabelImg制作的数据集,其生成的文件是XML格式的数据,如下图,我自己建立了两类的数据集:
对于XML文件的解析,https://blog.youkuaiyun.com/weixin_39274753/article/details/82221859总结的很详细,我使用的方法是ElementTree,这个不难,简述下思路,导入xml.etree.ElementTree模块,使用ElementTree.parse()函数来获取树,使用ElementTree.parse().getroot()来获取根节点,可以使用ElementTree.parse().getroot().tag获取标签名,使用ElementTree.parse().getroot().attrib获取属性(返回的是字典)。Element对象有一个iter方法,可以对某个元素对象之下所有的子元素进行深度优先遍历(DFS)。ElementTree对象同样也有这个方法。针对上面的XML文件,使用这个方法对XML文件中的所有object进行遍历,然后使用find('name').text和find('bndbox').find('xmin').text.....获取标签和groundtruth的坐标,path是图片的路径,最后将获取的这些按照上面yolov3需要的格式写入txt文件中,数据集便制作完成了。、
第二步:修改convert_tfrecord.py文件中的数据集路径对应自己建立的数据集,然后运行,将数据集转换成tfrecorde格式的数据,同样修改k-means.py文件中的数据集路径,获得对应自己数据集的anchors,注意,代码的作者在这里将anchors的尺寸进行了归一化。所以刚开始看到生成的anchors尺寸很小也不要惊讶,这是正确的结果。
第三步:下载预训练权重yolov3.weights,运行convert_weights.py将权重转换
第四步:修改文件quick_train.py中的文件路径,anchors等,进行训练
第五步:运行quick_test.py进行图片测试,video_demo.py进行视频测试,效果图图下所示: