您如何在小于目标大小的区域上进行 ROI-Pooling?
Posted
技术标签:
【中文标题】您如何在小于目标大小的区域上进行 ROI-Pooling?【英文标题】:How do you do ROI-Pooling on Areas smaller than the target size? 【发布时间】:2018-06-18 05:43:29 【问题描述】:我目前正在尝试从here 获取 Faster R-CNN 网络,以便在带有 tensorflow 的 Windows 中工作。为此,我想重新实现 ROI-Pooling 层,因为它不能在 Windows 中工作(至少对我来说不是。如果你有任何关于使用 tensorflow 移植到 Windows 的提示,我将非常感谢你的 cmets!)。根据this 网站,您所做的是,您从特征图中获取建议的 roi,并将其内容最大池化为固定的输出大小。以下全连接层需要此固定输出,因为它们只接受固定大小的输入。
现在的问题是:
在 conv5_3 之后,即 roi 池化之前的最后一个卷积层,区域提议网络产生的框的大小大多为 5x5 像素。这完全没问题,因为我要检测的对象通常在原始图像中具有 80x80 像素的尺寸(由于池化而导致的下采样因子为 16)。但是,我现在必须最大池化 5x5 像素的区域并将其放大到 7x7,即 ROI-Pooling 的目标大小。我的第一次尝试只是简单地进行插值并没有奏效。此外,用零填充也不起作用。我的课似乎总是得到相同的分数。
我做错了什么吗?我不想更改任何层的尺寸,而且我知道我训练有素的网络通常可以正常工作,因为我的数据集上有在 Linux 中运行的参考实现。
非常感谢您的时间和精力:)
【问题讨论】:
【参考方案1】:现在有一个 Faster-RCNN 和其他对象检测算法的官方 TF 实现,在他们的Object Detection API 中,您可能应该检查一下。
如果您仍想自己编写代码,我想知道的事情与您完全相同,但找不到有关您应该如何做的答案。我的三个猜测是:
插值,但是它改变了特征值,所以它破坏了一些信息......
只需将每个单元复制 7 次,然后将最大池化回 7x7,即可将大小调整为 35x35(您不必实际调整大小,然后再进行池化,例如在 1D 中,它基本上会将自身缩减为 @ 987654326@,在 2D 中最多有 4 个元素 - 小心,我可能忘记了一些 +1/-1 或其他东西 -)。我至少看到两个问题:一些值被过度代表,被复制的比其他值更多;但更糟糕的是,一些(小)值甚至根本不会被复制到输出中! (你应该避免,因为你可以在输出中存储比在输入中更多的信息)
确保所有输入特征值至少在输出中精确复制一次,在最佳位置(基本上将input[i]
复制到output[j]
和j=floor((i+1)*7/5)-1)
)。对于剩余的点,要么留下 0,要么进行插值。我认为这个解决方案是最好的,也许有插值,但我真的不确定。
看起来smallcorgi's implementation 使用了我的第二个解决方案(没有实际调整大小,只使用最大池化),因为它与输入大于输出的情况相同。
【讨论】:
感谢您的回答!我查看了 Faster-RCNN 的官方 TF 实现,但是我目前正在将它与我没有在那里找到的 VGG 网络一起使用。我已经尝试了你的一些猜测,尤其是插值(使用双三次插值进行简单的调整大小)和用零填充,它在一定程度上起作用。它并不完美,但非常接近。对于插值情况,您有很大的变化,因为让我们说被零包围的 1.0 的值(由于 ReLus 这很常见)被冲掉,导致类似于 0.4、0.4 等。填充零最适合 atm VGG16 确实不存在。不过有一个procedure to use another feature extractor,它可能比重写 ROI-pooling 层更快,并且您可以轻松地与其他特征提取器进行比较。此外,您可能需要重新考虑选择 VGG,因为 ResNet34 for instance seems to outperform it both in accuracy and speed 在某些任务上。 我的第三个解决方案将避免这种“洗出”;填充的效率可能取决于您要填充的位置(即,按照我的建议,这样做可能比将 5x5 输入复制到输出的左上角并将底部和右侧保留为 0 更好,因为我的方法尊重原拓扑更好) VGG 目前很好,现在我只希望我的设置能够运行,性能要晚得多。我的设置现在运行,比参考 Linux 版本差一点,但在给定的限制范围内。然而,基本问题仍然存在...... roi_pooling 对小于目标大小的补丁做了什么......因此我不能将您的答案标记为“答案”,我希望您理解:/ 是的,别担心!但是在第二次查看the implementation of the linux version you're using(特别是第 123 到 182 行)之后,它们看起来就像我的第二种方法一样(实际上与大于目标大小的 ROI 的代码相同)【参考方案2】:我知道已经很晚了,但我发布了这个答案,因为它可能对其他人有所帮助。我编写了一个代码来解释 roi 池如何在池和区域的不同高度和宽度条件下工作。 你可以在github中看到代码的链接: https://github.com/Parsa33033/RoiPooling
【讨论】:
以上是关于您如何在小于目标大小的区域上进行 ROI-Pooling?的主要内容,如果未能解决你的问题,请参考以下文章