python - 训练对象检测模型过长导致模型破裂
问题描述
我正在使用来自 tensorflow 的对象检测。
关于我面临挑战的问题的一些背景信息,
因为我有兴趣训练一个模型,该模型除其他外还能检测武器。我的常规观点来自无人机,但从这个观点来看,我找不到任何包含武器的公开数据集。所以,我收集了带有武器的图像,并试图尽可能多地模仿无人机的观点。
- 我的第一个想法是填充我的图像(相对于图像本身,使我在其中的实际边界框更小)。
- 第二个也是旋转我的图像。由于 tensorflow 尚未实现此功能,我编写了一个简单的代码来创建预旋转图像。这有局限性,但无论如何我试了一下。
我用海滩上的人的图像进行了实验,并试图模仿实际的问题:
- 我正在使用海滩上人的相对近距离图像进行训练
- 同时使用海滩上相对较远的人的图像进行测试。
实际问题
在我的一个实验中,我训练模型的时间比平时更长,并注意到它确实搞砸了。更具体:
我有一个初始的 140 个“近帧”图像用于训练。
从他们那里我创建了
4x140=560
带有小填充的图像(结果图像在最大版本中是原始图像的 1.6 倍)和旋转(最多 5 度旋转)调整大小的版本。我使用这个包含 560 张图像的数据集来训练我的模型,使用 Faster R-CNN 模型进行近 80 万次迭代。
我在各种迭代中导出了模型:150k、300k、500k、700k,并用于在我的测试图像上对其进行测试。
我还用于比较模型,这些模型是用原始调整大小的图像训练的,以检查差异。
出乎意料的结果
- 第一个特殊的观察是我的模型在 500k 及以上时根本没有检测到任何人。(首先想到的是过度训练)
- 我在实际的训练图像上进行了尝试以检查这一点,这里也没有在我的测试图像中检测到任何东西。
- 此外,我希望我的“增强”数据集比简单调整大小的数据集表现更好,但这似乎也并非如此。(虽然这是一个看起来科学合理的小问题)。
所以,我的问题是这怎么可能?训练时间过长也会导致无法检测到训练样本?对此有什么理论上的解释吗?(除了我认为不太可能但在任何情况下都不能排除的实施错误等)。
PS1
我调整大小的图像版本遵循与 Faster R-CNN 相同的调整大小条件,最小。暗淡。是 600 像素和最大。一个 1024 像素。所以,这不应该是任何调整大小的问题。
PS2
我正在使用 tensorflow,但我认为这不是 tensorflow 特有的问题。所以,我没有将它包含在标签中。
解决方案
经过一些研究(和大量实验),我得出了一些结论,这些结论可能会帮助其他面临同样问题的人。
- 未能检测到任何对象可能意味着模型在训练的某些部分已经崩溃。在我的例子中,一个可能的迹象是训练时损失值的值非常高。虽然我有模型发生了这种情况,并且似乎并没有对模型产生太大影响(至少不会太多以使其无用),但这些值的增加数量是一个好兆头,表明某些事情是致命的错误。请注意,这些值的出现频率不一定一直在增加。
- 课程越多越好:在第一节课之后,我只用了一节课进行实验。虽然这是合法的,并且(据我所知)没有提到避免它(我什至阅读了使用 1 类对象检测的教程),但这也加剧了破解率。使用 2 个类似乎可以部分缓解这个问题。当我用 11 个类训练我的模型时,问题似乎消失了。
- bbox 大小的微小变化有帮助: 对大小变化很大的边界框进行实验我得出的结论是,bbox 的大小基本一致也有助于缓解这个问题。
- 更多类可能会提高性能:我还注意到,由于训练具有 1 类性能的模型的限制,11 类问题似乎比 1 类任务更重,但在前一种情况下,某些情况下更高。
我的最终结论是,由于某种原因,我的模型在某些时候遇到了一些权重溢出,导致它无法再次恢复正常。我已经扩充了我的数据这一事实(例如,类似的图像可能一个接一个地输入并增强了某些权重)可能会增加问题发生的频率,但问题仍然存在于非增强数据集中。
推荐阅读
- pandas - 尝试根据其值对特定行进行分组
- npm - package.json 中的双重命令不起作用
- spring-boot - spring 可以像 grails 一样自动重新加载更改吗?
- javascript - 如何使用 javascript 缓存背景图像?
- python - 如何逐行应用函数,并在每一步保存csv(追加)?
- javascript - Context Provider 内部的 React Router Switch 导致不断闪烁(重新渲染)
- django - 如何在 django 验证错误中更改日期格式
- react-apollo - 使用 useMutation 可能出现未处理的承诺拒绝警告
- html - 调整窗口大小时如何使图像响应?CSS & HTML5
- javascript - 升级 npm 包后功能变慢