自定义卷积与pytorch conv2d结果之间的差异?

时间:2018-07-21 20:48:39

标签: python-3.x conv-neural-network pytorch

我正在尝试使用pytorch unfold function

中所示的方法来构建自定义卷积

自定义卷积函数如下:

import torch
from torch import nn
import torch.nn.functional as F
from torch.nn.parameter import Parameter
import math
from torch.nn.modules.utils import _pair


class customConv(nn.Module):
    def __init__(self, n_channels, out_channels, kernel_size, dilation=1, padding=0, stride=1, bias=True):
        super(customConv, self).__init__()

        self.kernel_size = _pair(kernel_size)
        self.out_channels = out_channels
        self.dilation = _pair(dilation)
        self.padding = _pair(padding)
        self.stride = _pair(stride)
        self.n_channels = n_channels
        self.weight = Parameter(torch.Tensor(self.out_channels, self.n_channels, self.kernel_size[0], self.kernel_size[1]))
        if bias:
            self.bias = Parameter(torch.Tensor(out_channels))
        else:
            self.register_parameter('bias', None)
        self.reset_parameters()

    def reset_parameters(self):
        n = self.n_channels
        for k in self.kernel_size:
            n *= k
        stdv = 1. / math.sqrt(n)
        self.weight.data.uniform_(-stdv, stdv)
        if self.bias is not None:
            self.bias.data.uniform_(-stdv, stdv)

    def forward(self, input_):

        hout = ((input_.shape[2] + 2 * self.padding[0] - self.dilation[0] * (self.kernel_size[0]-1)-1)//self.stride[0])+1
        wout = ((input_.shape[3] + 2 * self.padding[1] - self.dilation[1] * (self.kernel_size[1]-1)-1)//self.stride[1])+1

        inputUnfolded = F.unfold(input_, kernel_size=self.kernel_size, padding=self.padding, dilation=self.dilation, stride=self.stride)
        if self.bias:
            convolvedOutput = (inputUnfolded.transpose(1, 2).matmul(
            self.weight.view(self.weight.size(0), -1).t()).transpose(1, 2)) + self.bias.view(-1, 1)
        else:
            convolvedOutput = (inputUnfolded.transpose(1, 2).matmul(self.weight.view(self.weight.size(0), -1).t()).transpose(1, 2))
        convolutionReconstruction = convolvedOutput.view(input_.shape[0], self.out_channels, hout, wout)
        return convolutionReconstruction

但是当我尝试将其与pytorch实现进行比较时,我没有得到确切的值。下面提供了用于检查差异的代码

import torch
from torch import nn
from customConvolve import customConv   
torch.manual_seed(1)

input = torch.randn (10,3,64,64)

conv1 = nn.Conv2d(input.shape[1],5, kernel_size=3, dilation=1, padding=1, stride=1 ,bias = False)
conv1_output = conv1(input)

conv2 = customConv(n_channels=input.shape[1], out_channels=5, kernel_size=3,  dilation=1, stride =1, padding = 1, bias = False)
conv2_output = conv2(input)

print(torch.equal(conv1.weight.data, conv2.weight.data))

print(torch.equal(conv1_output, conv2_output))

我想知道为什么存在这种差异以及如何解决呢? 谢谢。

0 个答案:

没有答案