【发布时间】:2021-08-20 02:54:38
【问题描述】:
我有一个CNN,其基本结构如下,
卷积层 -> 全局平均池化 -> 扁平化 -> 密集 -> 输出
我拥有的网络与输入大小无关,因此我可以在不同大小的输入上使用它。但是,全局平均池化操作使用输入大小来平均通道中的所有值。例如,如果我对图像进行零填充以更改其输入大小,则在全局平均池化之后我会得到一个不同的向量。因此,我正在考虑使用 sum pooling 代替,因为它与输入大小无关(我也不确定使用 sum pooling 是否可行)。由于 PyTorch 中没有内置的 sum pooling(据我所知),因此我将其实现如下,
def forward(self, x):
features = self.features(x)
out = F.relu(features, inplace=True)
fshape = float(out.shape[-1])
fshape3 = np.power(fshape, 3)
out = F.adaptive_avg_pool3d(out, (1, 1, 1))
out = torch.flatten(out, 1)
out = torch.mul(out, fshape3)
out = self.classifier(out)
return out
不幸的是,在用总和池替换平均池后,我得到了nan 作为损失,这可能是因为在我将层与大量相乘后梯度爆炸了。所以,为了解决这个问题,我在乘法层之后应用了一个批量标准化层。这解决了nan 丢失问题;然而,学习(或优化)变得非常缓慢。我或许可以尝试提高学习率,看看是否能解决问题。
但是,我想了解为什么总和池会提供不稳定的结果,而从技术上讲,我只是将层乘以(或缩放)一个常数?如果有人能对此有所了解,我将不胜感激。如果其他人在实施 sum pooling 时遇到任何问题,我也想了解更多关于他们的经验。
【问题讨论】:
-
为什么要在输入图像上启用/禁用零填充?您在 CNN 部分中使用的第一个卷积层是什么?
-
@Ivan 我当然可以使用零填充来使所有输入的大小相同,但目前,我正试图避免它。此外,我用较小的输入尺寸(比如 20x20)训练了某些模型,但现在,我想在更大的输入(比如 24x24)上使用该训练模型。我不能真正使用我正在处理的数据类型进行裁剪和重新缩放。第一个 conv 层的 kernel size=3、stride=1 和 out_channels=64,尽管我认为我使用什么类型的 conv 层并不重要。
标签: python pytorch conv-neural-network batch-normalization