在自己的数据集上训练 TensorFlow 对象检测
Posted
技术标签:
【中文标题】在自己的数据集上训练 TensorFlow 对象检测【英文标题】:Train Tensorflow Object Detection on own dataset 【发布时间】:2017-12-11 21:27:26 【问题描述】:在花了几天时间尝试完成这项任务后,我想分享一下我如何回答这个问题的经验:
如何使用TS Object Detection 来使用我自己的数据集进行训练?
【问题讨论】:
你是老板,谢谢! 【参考方案1】:这假定模块已经安装。如果没有请参考他们的documentation。
免责声明
这个答案并不意味着是训练对象检测模块的正确或唯一方式。这只是我分享我的经验以及对我有用的方法。我愿意接受建议并了解更多关于这方面的信息,因为我对 ML 还是新手。
TL;DR
-
创建您自己的 PASCAL VOC 格式数据集
从中生成 TFRecords
配置管道
可视化
此答案的每个部分都包含相应的编辑(见下文)。阅读每个部分后,请同时阅读其编辑以进行澄清。每个部分都添加了更正和提示。
使用的工具
LabelImg:创建PASCAL VOC格式注释的工具。
1.创建您自己的 PASCAL VOC 数据集
PS: 为简单起见,我的答案的文件夹命名约定遵循 Pascal VOC 2012
查看May 2012 dataset,您会注意到该文件夹具有以下结构
+VOCdevkit
+VOC2012
+Annotations
+ImageSets
+Action
+Layout
+Main
+Segmentation
+JPEGImages
+SegmentationClass
+SegmentationObject
暂时对以下文件夹进行了修改:
注解:这是所有图像对应的 XML 文件将被放入其中。使用上面建议的工具来创建注解。不要担心<truncated>
和<difficulty>
标签,因为它们会被训练和评估二进制文件忽略。
JPEGImages:实际图像的位置。确保它们是 JPEG 类型,因为这是当前支持使用它们提供的脚本创建 TFRecords 的类型。
ImageSets->Main:这只是由文本文件组成。对于每个类,都有一个对应的train.txt、trainval.txt和val.txt。下面是 VOC 2012 文件夹中 aeroplane_train.txt 的内容示例
2008_000008 -1
2008_000015 -1
2008_000019 -1
2008_000023 -1
2008_000028 -1
2008_000033 1
该结构基本上是图像名称,后跟一个布尔值,表示相应对象是否存在于该图像中。例如图像 2008_000008 不包含飞机,因此标记为 -1 但图像 2008_000033 包含。
我编写了一个小的 Python 脚本来生成这些文本文件。只需遍历图像名称并在它们旁边分配一个 1 或 -1 以表示对象存在。我通过改组图像名称在我的文本文件中添加了一些随机性。
classname_val.txt 文件由 testing 验证数据集组成。将此视为训练期间的测试数据。您希望将数据集划分为训练和验证。更多信息可以找到here。这些文件的格式与训练类似。
此时,你的文件夹结构应该是
+VOCdevkit
+VOC2012
+Annotations
--(for each image, generated annotation)
+ImageSets
+Main
--(for each class, generated *classname*_train.txt and *classname*_val.txt)
+JPEGImages
--(a bunch of JPEG images)
1.1 生成标签图
准备好数据集后,我们需要创建相应的标签图。 导航到 models/object_detection/data 并打开 pascal_label_map.pbtxt。
此文件由一个 JSON 组成,该 JSON 为每个项目分配一个 ID 和名称。修改此文件以反映您想要的对象。
2。生成 TFRecords
如果您查看他们的代码,尤其是 line,他们会明确地仅获取 aeroplane_train.txt。对于好奇的头脑,here's why。将此文件名更改为您的任何班级培训文本文件。
确保 VOCdevkit 在 models/object_detection 中,然后您可以继续使用 generate the TFRecords。
如果您遇到任何问题,请先查看他们的代码。它是不言自明的并且有据可查。
3.管道配置
instructions 应该是不言自明的以涵盖此部分。示例配置可以在object_detection/samples/configs 中找到。
对于那些像我一样希望从头开始训练的人,只需确保删除 fine_tune_checkpoint
和 from_detection_checkpoint
节点即可。 Here's 我的配置文件是什么样的供参考。
从这里开始,您可以继续使用tutorial 并运行培训过程。
4.可视化
确保在训练的同时运行评估,以便能够可视化学习过程。引用Jonathan Huang
最好的方法是只运行 eval.py 二进制文件。我们通常运行这个 与训练并行的二进制文件,将其指向保存的目录 正在训练的检查点。 eval.py 二进制文件将写入 记录到您指定的
eval_dir
,然后您可以指向该eval_dir
使用 Tensorboard。您希望看到 mAP 在最初的几个小时内“起飞”, 然后你想看看它什么时候收敛。没有就很难说 看看这些图,你需要多少步。
第一版(2017 年 7 月 28 日):
我没想到我的回复会引起这么多关注,所以我决定回来看看。
工具
对于我的 Apple 用户,您实际上可以使用 RectLabel 进行注释。
帕斯卡 VOC
翻来覆去,我终于意识到trainval.txt实际上是训练和验证数据集的联合。
请查看他们的official development kit 以更好地理解格式。
标签图生成
在我撰写本文时,ID 0 代表none_of_the_above
。建议您的 ID 从 1 开始。
可视化
在运行评估并将 tensorboard 定向到您的 Eval 目录后,它会向您显示每个类别的 mAP 以及每个类别的性能。这很好,但我也喜欢与 Eval 并行查看我的训练数据。
为此,请在不同的端口上运行 tensorboard 并将其指向您的 train 目录
tensorboard --logdir=$PATH_TO_TRAIN --port=$DESIRED_NUMBER
【讨论】:
谢谢。我最终也换到了 2.7,情况变得更好了。 2880X1800 肯定太大了。如果您查看image_resizer
下的配置文件,对象检测器最终会将每个图像的大小调整为 300X300。我给它提供了 618X816 的图像,它仍然可以很好地检测我想要的类。我建议在运行检测之前先调整图像的大小,以查看哪些比例仍然可以保持对象的良好视觉效果(这也是我所做的)。您还可以调整 image_resizer
的参数,运行检测器并比较结果。
@eshirima 谢谢,所以调整器也很聪明,可以调整为原始图像绘制的注释和边界?
我无法给出具体的答案,但在核心中,边界框是对包含大部分对象的像素位置的估计属性/特征。您看到的最后一个盒子实际上是多个紧密包装的盒子组合在一起的结果。馈送整个 2880X1800 的问题在于,您最终会拥有太多无法将它们保存在内存中的特征,并且在计算上会受到惩罚,从而导致单层计算需要很长时间。
调整大小背后的想法是找到足够的特征,以便它们可以保存在内存中,但不会在计算上受到惩罚。理论上,一旦它学会了所有这些特征,它应该能够找到它们以及更大的图像。但是处理大帧仍然是计算机视觉中一个持续存在的问题。【参考方案2】:
我在 Medium 上写了一个blog post,讲述了我的经验以及我如何在自己的数据集上使用 Tensorflow 训练对象检测器(特别是 Raccoon 检测器)。这对其他人也可能有用,并且是对 eshirima 的回答的补充。
【讨论】:
我实际上也查看了@你的实时帖子,并从中学到了很多东西。几个问题/建议。 1:在配置文件中,你知道num_hard_examples
和num_examples
代表什么吗? 2:对于 Mac 上的图像注释,您可以使用 RectLabel。 3:我实际上是要探索在自己的不是 Pascal Voc 格式的数据集上进行训练。你打败了我 :)
嘿,感谢您的建议:) 我查看了 RectLabel。看起来还不错。我会试一试。关于您的第一个问题,num_hard_examples
与困难示例矿工有关。看看这个paper 来理解这一点。 num_examples
与评估有关。在评估期间,它会获取图像,您需要指定您拥有多少。他们还使用max_eval
来限制评估过程。对于第 3 名:) 是的没关系哈哈这不是谁先来,而是互相学习。
@Yirga 当然,但这可能需要一段时间。
@rambossa 如果你关心那些矩形的稳定性,你应该看看ROLO。
@ShamaneSiriwardhana 我在训练后遇到了一些误报检测。这很容易发生,因为模型不能保证始终 100% 正确,因为 mAP 永远不会完全收敛到 0。关于数据集,我使用 PASCAL,因为它是 @987654325 之前的行业标准@因此是一个更大的社区。span>
以上是关于在自己的数据集上训练 TensorFlow 对象检测的主要内容,如果未能解决你的问题,请参考以下文章
为啥在同一数据集上使用 tensorflow 和 keras 重新训练的 Inception V3 显示出不同的准确性?
在自定义数据集上训练 tensorflow attention-ocr 的管道是啥?
TensorFlow Object Detection API 只训练一个类