Tensorflow 高误报率和非最大抑制问题
Tensorflow high false-positive rate and non-max-suppression issue
我正在 Windows 10 上训练 Tensorflow 对象检测,使用 faster_rcnn_inception_v2_coco 作为预训练模型。我在 Windows 10,在 NVIDIA GeForce GTX 1080、CUDA 9.0 和 CUDNN 7.0 上使用 tensorflow-gpu 1.6。
我的数据集只包含一个对象,"Pistol",和 3000 张图像(2700 个训练集,300 个测试集)。图片的大小从 ~100x200 到 ~800x600。
我对这个模型进行了 55k 次迭代训练,其中 mAP was ~0.8 and the TotalLoss seems converged to 0.001. But however, seeing the evaluation, that there are a lot of multiple bounding boxes on the same detected object (e.g. this and this), and lot of false positives (house detected as a pistol). For example, in this photo 是我拍摄的(后来应用了模糊滤镜),模型将人和车检测为手枪,并且检测正确。
数据集已上传 here,连同 tfrecords 和标签图。
我使用 this config file,我唯一改变的是:num_classes 到 1,fine_tune_checkpoint、input_path 和 label_map_path 用于训练和评估,以及 num_examples。
因为我认为多个框是一个非最大抑制问题,所以我将 score_threshold(第 73 行)从 0 更改为 0.01,并将 iou_threshold(第 74 行)从 1 到 0.6。使用标准值,结果比这更糟糕。
我该怎么做才能有好的检测?我应该改变什么?也许我错过了一些关于参数调整的东西......
谢谢
我认为在深入研究参数调整(即提到的 score_threshold
)之前,您必须检查您的数据集。
我没有检查您共享的整个数据集,但从高层次的角度来看,我发现的主要问题是 大多数 图像非常小并且变化很大宽高比。
我认为这与您的配置文件的这一部分冲突:
image_resizer {
keep_aspect_ratio_resizer {
min_dimension: 600
max_dimension: 1024
}
}
如果获取数据集的其中一张图像并手动应用该转换,您会发现结果对于小图像来说非常嘈杂,对于许多具有不同纵横比的图像来说非常变形。
我强烈建议您 re-build 您的数据集包含更清晰的图像,并可能尝试使用填充、裁剪或其他策略对具有不寻常纵横比的图像进行预处理。
如果您想坚持使用小图像,您至少必须更改 image_resizer
的最小和最大尺寸,但根据我的经验,这里最大的问题是数据集,我会花时间尝试解决这个问题。
PD.
如果我们认为房子误报来自数据集的一个完全不同的域,那么我不认为它是一个大问题。
您可以调整最小置信度以将检测视为真阳性并将其删除。
如果您将当前的 COCO 获胜者输入卡通中的奇怪图像,您会发现它会产生很多误报。
所以这更像是当前对象检测方法的问题,它对域变化不稳健。
我在网上看到的很多人都运行使用 Tensorflow API 遇到同样的问题。我认为 idea/process 在家中使用带有自定义分类器的预训练模型存在一些固有问题。例如,人们想使用 SSD Mobile 或 Faster RCNN Inception 来检测 "Person w/ helmet," "pistol," 或 "tool box," 等对象。一般过程是输入该对象的图像,但大多数时间,无论有多少图像...200 到 2000,当您实际 运行 在办公桌前时,您仍然会以误报告终。
当您将对象显示在其自身的上下文中时,对象分类器工作得很好,但您最终会在每天的物品上获得 99% 的匹配度,例如您的卧室 window、您的办公桌、您的电脑显示器、键盘等。人们提到了引入负面图像或软图像的策略。我认为问题与大多数人使用的图像中的有限上下文有关。预训练模型在多种环境中使用十几个分类器进行训练,例如在一个例子中可能是街上的一辆汽车。 CNN 看到了汽车,然后图像中所有不是汽车的东西都是负面图像,包括街道、建筑物、天空等。在另一幅图像中,它可以看到瓶子和图像中的所有东西,包括桌子,表、windows 等。我认为训练自定义分类器的问题在于它是一个负面形象问题。即使您有足够多的对象本身的图像,在不同的上下文和背景下也没有足够的同一对象的数据。所以从某种意义上说,即使在概念上你不应该需要负面图像,也没有足够的负面图像。当您 运行 在家里使用该算法时,您会在整个地方识别出您房间周围的物体时出现误报。我认为以这种方式进行迁移学习的想法是有缺陷的。我们最终在网上看到了很多关于人们识别扑克牌、千年隼等的很棒的教程,但是 none 这些模型在现实世界中是可以部署的,因为它们都会在它出现时产生一堆误报看到其图像池之外的任何东西。最好的策略是使用多个分类器从头开始重新训练 CNN,并在其中添加所需的分类器。我建议使用 10-20 个预先存在的分类器重新引入来自 ImageNet 或 Pascal 的先前数据集,并添加您自己的分类器并重新训练它。
我正在 Windows 10 上训练 Tensorflow 对象检测,使用 faster_rcnn_inception_v2_coco 作为预训练模型。我在 Windows 10,在 NVIDIA GeForce GTX 1080、CUDA 9.0 和 CUDNN 7.0 上使用 tensorflow-gpu 1.6。
我的数据集只包含一个对象,"Pistol",和 3000 张图像(2700 个训练集,300 个测试集)。图片的大小从 ~100x200 到 ~800x600。
我对这个模型进行了 55k 次迭代训练,其中 mAP was ~0.8 and the TotalLoss seems converged to 0.001. But however, seeing the evaluation, that there are a lot of multiple bounding boxes on the same detected object (e.g. this and this), and lot of false positives (house detected as a pistol). For example, in this photo 是我拍摄的(后来应用了模糊滤镜),模型将人和车检测为手枪,并且检测正确。
数据集已上传 here,连同 tfrecords 和标签图。 我使用 this config file,我唯一改变的是:num_classes 到 1,fine_tune_checkpoint、input_path 和 label_map_path 用于训练和评估,以及 num_examples。 因为我认为多个框是一个非最大抑制问题,所以我将 score_threshold(第 73 行)从 0 更改为 0.01,并将 iou_threshold(第 74 行)从 1 到 0.6。使用标准值,结果比这更糟糕。
我该怎么做才能有好的检测?我应该改变什么?也许我错过了一些关于参数调整的东西......
谢谢
我认为在深入研究参数调整(即提到的 score_threshold
)之前,您必须检查您的数据集。
我没有检查您共享的整个数据集,但从高层次的角度来看,我发现的主要问题是 大多数 图像非常小并且变化很大宽高比。
我认为这与您的配置文件的这一部分冲突:
image_resizer {
keep_aspect_ratio_resizer {
min_dimension: 600
max_dimension: 1024
}
}
如果获取数据集的其中一张图像并手动应用该转换,您会发现结果对于小图像来说非常嘈杂,对于许多具有不同纵横比的图像来说非常变形。
我强烈建议您 re-build 您的数据集包含更清晰的图像,并可能尝试使用填充、裁剪或其他策略对具有不寻常纵横比的图像进行预处理。
如果您想坚持使用小图像,您至少必须更改 image_resizer
的最小和最大尺寸,但根据我的经验,这里最大的问题是数据集,我会花时间尝试解决这个问题。
PD.
如果我们认为房子误报来自数据集的一个完全不同的域,那么我不认为它是一个大问题。
您可以调整最小置信度以将检测视为真阳性并将其删除。
如果您将当前的 COCO 获胜者输入卡通中的奇怪图像,您会发现它会产生很多误报。
所以这更像是当前对象检测方法的问题,它对域变化不稳健。
我在网上看到的很多人都运行使用 Tensorflow API 遇到同样的问题。我认为 idea/process 在家中使用带有自定义分类器的预训练模型存在一些固有问题。例如,人们想使用 SSD Mobile 或 Faster RCNN Inception 来检测 "Person w/ helmet," "pistol," 或 "tool box," 等对象。一般过程是输入该对象的图像,但大多数时间,无论有多少图像...200 到 2000,当您实际 运行 在办公桌前时,您仍然会以误报告终。
当您将对象显示在其自身的上下文中时,对象分类器工作得很好,但您最终会在每天的物品上获得 99% 的匹配度,例如您的卧室 window、您的办公桌、您的电脑显示器、键盘等。人们提到了引入负面图像或软图像的策略。我认为问题与大多数人使用的图像中的有限上下文有关。预训练模型在多种环境中使用十几个分类器进行训练,例如在一个例子中可能是街上的一辆汽车。 CNN 看到了汽车,然后图像中所有不是汽车的东西都是负面图像,包括街道、建筑物、天空等。在另一幅图像中,它可以看到瓶子和图像中的所有东西,包括桌子,表、windows 等。我认为训练自定义分类器的问题在于它是一个负面形象问题。即使您有足够多的对象本身的图像,在不同的上下文和背景下也没有足够的同一对象的数据。所以从某种意义上说,即使在概念上你不应该需要负面图像,也没有足够的负面图像。当您 运行 在家里使用该算法时,您会在整个地方识别出您房间周围的物体时出现误报。我认为以这种方式进行迁移学习的想法是有缺陷的。我们最终在网上看到了很多关于人们识别扑克牌、千年隼等的很棒的教程,但是 none 这些模型在现实世界中是可以部署的,因为它们都会在它出现时产生一堆误报看到其图像池之外的任何东西。最好的策略是使用多个分类器从头开始重新训练 CNN,并在其中添加所需的分类器。我建议使用 10-20 个预先存在的分类器重新引入来自 ImageNet 或 Pascal 的先前数据集,并添加您自己的分类器并重新训练它。