在pytorch中执行卷积(不互相关) [英] Performing Convolution (NOT cross-correlation) in pytorch

查看:429
本文介绍了在pytorch中执行卷积(不互相关)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个网络( https://github.com/TheAbhiKumar/tensorflow-value -iteration-networks )(我尝试在pytorch中实现)(我对pytorch还是很陌生,但对于机器学习而言却不是新手).

I have a network (https://github.com/TheAbhiKumar/tensorflow-value-iteration-networks) that I am trying to implement in pytorch (I'm very new to pytorch, however, not at all new to machine learning).

简而言之,我似乎无法弄清楚如何在pytorch中实现纯"卷积.在tensorflow中,可以这样实现:

In short, I cannot seem to figure out how to implement "pure" convolution in pytorch. In tensorflow it could be accomplished like this:

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

flipkernel功能为:

With the flipkernel function being:

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

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

How could something similar be done in pytorch?

推荐答案

TLDR 使用功能工具箱中的卷积 torch.nn.conv2d ,然后围绕垂直和水平轴翻转滤镜.

TLDR Use the convolution from the functional toolbox, torch.nn.fuctional.conv2d, not torch.nn.conv2d, and flip your filter around the vertical and horizontal axis.

torch.nn.conv2d是网络的卷积层.因为权重是可以学习的,所以它是否可以使用互相关来实现都没有关系,因为网络将仅学习内核的镜像版本(感谢@etarion进行澄清).

torch.nn.conv2d is a convolutional layer for a network. Because weights are learned, it does not matter if it is implemented using cross-correlation, because the network will simply learn a mirrored version of the kernel (Thanks @etarion for this clarification).

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

torch.nn.fuctional.conv2d performs convolution with the inputs and weights provided as arguments, similar to the tensorflow function in your example. I wrote a simple test to determine whether, like the tensorflow function, it is actually performing cross-correlation and it is necessary to flip the filter for correct convolutional results.

import torch
import torch.nn.functional as F
import torch.autograd as autograd
import numpy as np

#A vertical edge detection filter. 
#Because this filter is not symmetric, for correct convolution the filter must be flipped before element-wise multiplication
filters = autograd.Variable(torch.FloatTensor([[[[-1, 1]]]]))

#A test image of a square
inputs = autograd.Variable(torch.FloatTensor([[[[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]]]]))
print(F.conv2d(inputs, filters))

这将输出

Variable containing:
(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.FloatTensor of size 1x1x5x6]

此输出是互相关的结果.因此,我们需要翻转过滤器

This output is the result for cross-correlation. Therefore, we need to flip the filter

def flip_tensor(t):
    flipped = t.numpy().copy()

    for i in range(len(filters.size())):
        flipped = np.flip(flipped,i) #Reverse given tensor on dimention i
    return torch.from_numpy(flipped.copy())

print(F.conv2d(inputs, autograd.Variable(flip_tensor(filters.data))))

新的输出是卷积的正确结果.

The new output is the correct result for convolution.

Variable containing:
(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.FloatTensor of size 1x1x5x6] 

这篇关于在pytorch中执行卷积(不互相关)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆