Neural network 在Pytork中执行卷积(非互相关)

Neural network 在Pytork中执行卷积(非互相关),neural-network,conv-neural-network,pytorch,convolution,torch,Neural Network,Conv Neural Network,Pytorch,Convolution,Torch,我知道我正试图在pytorch中实现,但我似乎不知道如何实现“纯”卷积。在tensorflow中,可以这样完成: def conv2d_flipkernel(x, k, name=None): return tf.nn.conv2d(x, flipkernel(k), name=name, strides=(1, 1, 1, 1), padding='SAME') flipkernel函数为: def flipkernel(kern):

我知道我正试图在pytorch中实现,但我似乎不知道如何实现“纯”卷积。在tensorflow中,可以这样完成:

def conv2d_flipkernel(x, k, name=None):
    return tf.nn.conv2d(x, flipkernel(k), name=name,
                        strides=(1, 1, 1, 1), padding='SAME')
flipkernel
函数为:

def flipkernel(kern):
      return kern[(slice(None, None, -1),) * 2 + (slice(None), slice(None))]

如何在Pytork中完成类似的操作?

TLDR使用功能工具箱中的卷积,而不是,并围绕垂直轴和水平轴翻转过滤器


Conv2d是网络的卷积层。因为权重是学习的,所以它是否使用互相关实现并不重要,因为网络将只学习内核的镜像版本(感谢@etarion的澄清)

torch.nn.fuctional.conv2d
使用作为参数提供的输入和权重执行卷积,类似于示例中的tensorflow函数。我写了一个简单的测试来确定它是否像tensorflow函数一样,实际执行了互相关,并且有必要翻转滤波器以获得正确的卷积结果

导入火炬
导入torch.nn.功能为F
导入torch.autograd作为autograd
将numpy作为np导入
#垂直边缘检测滤波器。
#因为这个滤波器不是对称的,为了得到正确的卷积,必须在元素相乘之前翻转滤波器
filters=autograd.Variable(torch.FloatTensor([-1,1]]]))
#正方形的测试图像
输入=自动加载变量(火炬浮动张量([[0,0,0,0,0,0,0,0],[0,0,1,1,1,0,0],
[0, 0, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 0, 0],
[0,0,0,0,0,0,0]]]]))
打印(F.conv2d(输入、过滤器))
这个输出

变量包含:
(0 ,0 ,.,.) = 
0  0  0  0  0  0
0  1  0  0 -1  0
0  1  0  0 -1  0
0  1  0  0 -1  0
0  0  0  0  0  0
[torch.FLOTTENSOR,尺寸1x1x5x6]
此输出是互相关的结果。因此,我们需要翻转过滤器

def翻转张量(t):
翻转=t.numpy().copy()
对于范围内的i(len(filters.size()):
翻转=np.翻转(翻转,i)#反转维度i上的给定张量
从\u numpy返回火炬(翻转的.copy())
打印(F.conv2d(输入,自动加载变量(翻转张量(过滤器.数据)))
新输出是卷积的正确结果

变量包含:
(0 ,0 ,.,.) = 
0  0  0  0  0  0
0 -1  0  0  1  0
0 -1  0  0  1  0
0 -1  0  0  1  0
0  0  0  0  0  0
[torch.FLOTTENSOR,尺寸1x1x5x6]

与上面的答案没有太大的不同,但是
火炬
可以做
翻转(i)
(我猜你只想
翻转(2)
翻转(3)
):


OP要求卷积而不是互相关。我确信,他们知道,学习权重将导致相同的结果。然而,如果你想通过从另一种语言移植复制一个网络,并使用固定权重检查等效性,那么你可能会发现自己处于OPs的情况下,有一个确切的问题——特别是考虑到pytorch没有实现
[::-1]
还没有。
torch.nn.conv2d
现在在CamelCase中是
torch.nn.conv2d
,表示一个类。
def convolution(A, B):
  return F.conv2d(A, B.flip(2).flip(3), padding=padding)