【问题标题】:Why do flipping images change CNN pooling output为什么翻转图像会改变 CNN 池化输出
【发布时间】:2021-01-24 02:25:52
【问题描述】:

我正在研究图像嵌入,想知道为什么翻转图像会改变输出。考虑去掉头部的 resnet18,例如:

import torch
import torch.nn as nn
import torchvision.models as models
device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")

model = models.resnet18(pretrained=True)
model.fc = nn.Identity()
model = model.to(device)
model.eval()

x = torch.randn(20, 3, 128, 128).to(device)
with torch.no_grad():
    y1 = model(x)
    y2 = model(x.flip(-1))
    y3 = model(x.flip(-2))

最后一层看起来像这样,最重要的是有一个AdaptiveAveragePooling 作为最后一层像素/特征被汇集到 1 个像素

根据我的想法,由于我们只是在卷积之上进行卷积,因此在池化之前,所发生的只是特征图将根据图像的翻转方式进行翻转。平均池化只是对最后一个特征图(沿每个通道)进行平均,并且不受其方向的影响。 AdaptiveMaxPool 应该是一样的。

“普通”卷积网络之间的主要区别在于我们将池化/平均到一个像素宽度。

但是,当我查看y1-y2y1-y3y2-y3 时,这些值与零明显不同。我在想什么?

【问题讨论】:

    标签: image-processing deep-learning conv-neural-network data-augmentation


    【解决方案1】:

    我认为池化输出发生了变化,因为池化层的输入没有像我们预期的那样传递。

    简短回答: 输入被翻转,但 Conv2d 层的权重没有翻转。这些核权重也需要根据输入翻转来翻转,才能得到预期的输出。

    长答案:这里,根据模型的尾部,Conv2d 的输出被传递给AdaptiveAveragePooling。为了便于理解,我们暂时忽略BatchNorm

    为简单起见,我们将输入张量视为x = [1, 3, 5, 4, 7],而内核为k =[0.3, 0.5, 0.8]。当它翻转输入时,位置 [0,0] 的输出将为 [0.3*1+0.5*3+0.8*5] = 6.8 并且 [0,2] 将为 [0.3 *5+0.5*4+0.8*7]=9.3 考虑到stride=1

    现在如果输入翻转,x_flip = [7, 4, 5, 3, 1],位置 [0,0] 的输出将是 [0.3*7+0.5*4+0.8*5] = 8.1 和 [0 ,2] 将是 [0.3*5+0.5*3+0.8*1] = 3.8

    由于两种情况下输出的头部和尾部不同(8.1 != 9.36.8 != 3.8),我们在卷积层之后得到的输出将是不同,在池化后给出不同/意外的结果作为最终输出。

    因此,要在此处获得所需的输出,您还需要翻转内核。

    【讨论】:

      猜你喜欢
      • 2018-06-17
      • 2017-07-16
      • 2023-03-23
      • 1970-01-01
      • 2013-03-17
      • 2013-12-28
      • 2018-05-19
      • 2020-07-24
      • 2015-08-31
      相关资源
      最近更新 更多