god*_*dot 4 python convolution pytorch
我正在尝试使用Pytorch的函数torch.conv2d但无法得到我理解的结果......
这是一个简单的示例,其中内核 ( filt
) 与输入 ( im
) 的大小相同,以解释我正在寻找的内容。
import pytorch
filt = torch.rand(3, 3)
im = torch.rand(3, 3)
Run Code Online (Sandbox Code Playgroud)
我想计算一个没有 padding 的简单卷积,所以结果应该是一个标量(即 1x1 张量)。
我试过这个conv2d
:
# I have to convert image and kernel to 4 dimensions tensors to use conv2d
im_torch = im.reshape((im_height, filt_height, 1, 1))
filt_torch = filt.reshape((filt_height, im_height, 1, 1))
out = torch.nn.functional.conv2d(im_torch, filt_torch, stride=1, padding=0)
print(out)
Run Code Online (Sandbox Code Playgroud)
但结果并不是我所期望的:
tensor([[[[0.6067]], [[0.3564]], [[0.5397]]],
[[[0.2557]], [[0.0493]], [[0.2562]]],
[[[0.6067]], [[0.3564]], [[0.5397]]]])
Run Code Online (Sandbox Code Playgroud)
为了了解我想要什么,我想重现 scipyconvolve2d
行为:
import scipy.signal
out_scipy = scipy.signal.convolve2d(im.detach().numpy(), filt.detach().numpy(), 'valid')
print(out_scipy)
Run Code Online (Sandbox Code Playgroud)
打印:
array([[1.195723]], dtype=float32)
Run Code Online (Sandbox Code Playgroud)
输入和过滤器的张量形状应该是:
(batch, dim_ch, width, height)
并不是:
(width, height, 1, 1)
例如
import torch
import torch.nn.functional as F
x = torch.randn(1,1,4,4);
y = torch.randn(1,1,4,4);
z = F.conv2d(x,y);
Run Code Online (Sandbox Code Playgroud)
的输出形状z
:
torch.Size([1,1,1,1])
Run Code Online (Sandbox Code Playgroud)
好吧,我没有找到我的问题的确切答案(即如何使用 conv2d),但我找到了另一种方法来做到这一点。
首先,我了解到我正在寻找的称为有效互相关,它实际上是该类实现的操作[Conv2d][1]
。
因此我的解决方案使用Conv2d
类而不是conv2d
函数。
import pytorch
img = torch.rand(3, 3)
model = torch.nn.Conv2d(in_channels=1, out_channels=1, kernel_size=(3, 3), stride=1, padding=0, bias=False)
res = conv_mdl(img)
print(res.shape)
Run Code Online (Sandbox Code Playgroud)
它打印我想要的标量:
torch.Size([1, 1, 1, 1])
Run Code Online (Sandbox Code Playgroud)
PS:我还检查了结果是否正确,而不仅仅是尺寸。