Image processing 为什么翻转图像会改变CNN池输出

Image processing 为什么翻转图像会改变CNN池输出,image-processing,deep-learning,conv-neural-network,data-augmentation,Image Processing,Deep Learning,Conv Neural Network,Data Augmentation,我正在研究图像嵌入,想知道为什么翻转图像会改变输出。考虑RESNET18,删除头部,例如: 导入火炬 导入torch.nn作为nn 将torchvision.models导入为模型 设备=torch.device(“cuda”)如果torch.cuda.可用()否则torch.device(“cpu”) model=models.resnet18(预训练=True) model.fc=nn.Identity() 模型=模型到(设备) model.eval() x=火炬.randn(20,3,12

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

导入火炬
导入torch.nn作为nn
将torchvision.models导入为模型
设备=torch.device(“cuda”)如果torch.cuda.可用()否则torch.device(“cpu”)
model=models.resnet18(预训练=True)
model.fc=nn.Identity()
模型=模型到(设备)
model.eval()
x=火炬.randn(20,3,128,128).to(设备)
使用手电筒。无梯度()
y1=型号(x)
y2=型号(x.1)
y3=型号(x.2))
最后一层看起来像这样,最重要的是有一个
AdaptiveAveragePooling
作为最后一层,其中像素/特征被汇集到1个像素上:

根据我的想法,因为我们只是在卷积的基础上进行卷积,在合并之前,将发生的只是特征映射将根据图像的翻转方式进行翻转。平均池只是对最后一个特征贴图(沿每个通道)进行平均,并对其方向保持不变
AdaptiveMaxPool
应该是相同的

“正常”convnet之间的关键区别在于,我们将池化/平均化为一个像素宽度


但是,当我查看
y1-y2
y1-y3
y2-y3
时,值与零显著不同。我想错了什么?

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

简短回答:翻转输入,但不翻转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),我们在卷积层后得到的输出将不同,在合并后的最终输出将产生不同/意外的结果

因此,要在这里获得所需的输出,还需要翻转内核