Convolution outputs from Scipy and PyTorch

Hi,

Trying to convert my standalone numpy/Scipy code to Pytorch code. But for convolution operation I get different ouput. New to PyTorch Could not figure what is the problem. Your inputs will be really helpful.

Code:import matplotlib.pyplot as plt

import numpy as np
import matplotlib.image as mpimg
import os
import scipy.misc as sm
import skimage
from scipy import ndimage

import torch
import torch.nn.functional as F
from torch.autograd import Variable
import matplotlib.image as mpimg
import numpy as np
from math import exp
import torch.utils.data as _trchData
import torchvision
import torchvision.transforms as _trchTransforms
from PIL import Image
from torchvision.utils import save_image

Kx1 = np.array([[[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]],
               [[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]],
               [[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]],np.float32)

Ky1 = np.array([[[1, 2, 1], [0, 0, 0], [-1, -2, -1]],
               [[1, 2, 1], [0, 0, 0], [-1, -2, -1]],
               [[1, 2, 1], [0, 0, 0], [-1, -2, -1]]],np.float32)

input = np.random.rand(3,5,5)
input = input.astype( float)
input_tensor = torch.tensor(input,dtype=torch.float32)
input_tensor = input_tensor.unsqueeze(0) #adding the batch dimention

print(input)
print(input_tensor)


print('After Convolution')
Ix = ndimage.filters.convolve(input, Kx1)
print('Numpy')
print(Ix)
print('PyTorch')
Kx1 = torch.tensor(Kx1,dtype=torch.float32)
Kx1 = Kx1.unsqueeze(1) #weight – filters of shape (out_channels,in_channels/groups,kH,kW)
eV = F.conv2d(input_tensor, Kx1,groups=3,padding=1) #Need same output resolution as input
print(eV)

OutPut:

[[[0.42746186 0.80223515 0.08455418 0.95034426 0.73531461]
  [0.88848631 0.23339465 0.64763112 0.923042   0.98131799]
  [0.93706951 0.62827498 0.38796258 0.97992936 0.56311864]
  [0.71325612 0.211876   0.22662245 0.32865804 0.32806802]
  [0.91231137 0.3576359  0.24281409 0.82060259 0.47134624]]

 [[0.52197234 0.44303742 0.66290849 0.4663358  0.696525  ]
  [0.19334521 0.07296327 0.71405365 0.06187589 0.67431166]
  [0.82079495 0.3291177  0.37872362 0.38076496 0.2965895 ]
  [0.43784337 0.41070259 0.53129402 0.2847321  0.07362187]
  [0.47097682 0.13860599 0.71614126 0.5341319  0.70412184]]

 [[0.71533471 0.46008727 0.47486876 0.62407546 0.90584169]
  [0.66023983 0.40662516 0.09218006 0.88070502 0.02542857]
  [0.89013672 0.79380483 0.55417365 0.15604435 0.50410485]
  [0.30040657 0.12149912 0.01704382 0.20500113 0.89581468]
  [0.19484541 0.62343986 0.44213969 0.25765058 0.16109561]]]
tensor([[[[0.4275, 0.8022, 0.0846, 0.9503, 0.7353],
          [0.8885, 0.2334, 0.6476, 0.9230, 0.9813],
          [0.9371, 0.6283, 0.3880, 0.9799, 0.5631],
          [0.7133, 0.2119, 0.2266, 0.3287, 0.3281],
          [0.9123, 0.3576, 0.2428, 0.8206, 0.4713]],

         [[0.5220, 0.4430, 0.6629, 0.4663, 0.6965],
          [0.1933, 0.0730, 0.7141, 0.0619, 0.6743],
          [0.8208, 0.3291, 0.3787, 0.3808, 0.2966],
          [0.4378, 0.4107, 0.5313, 0.2847, 0.0736],
          [0.4710, 0.1386, 0.7161, 0.5341, 0.7041]],

         [[0.7153, 0.4601, 0.4749, 0.6241, 0.9058],
          [0.6602, 0.4066, 0.0922, 0.8807, 0.0254],
          [0.8901, 0.7938, 0.5542, 0.1560, 0.5041],
          [0.3004, 0.1215, 0.0170, 0.2050, 0.8958],
          [0.1948, 0.6234, 0.4421, 0.2577, 0.1611]]]])
After Convolution
Numpy
[[[-0.58126966  1.59563963 -2.32675714 -4.6330439  -0.12937747]
  [ 3.29978519  2.00716829 -3.81088727 -2.85857889 -0.34030851]
  [ 4.67899888  3.92138897 -2.98571297 -0.90920672  1.31889634]
  [ 4.6107901   4.39374866 -2.29160252 -0.20366083  1.87090024]
  [ 5.35506635  4.16130708 -4.07197147 -1.08035363  1.79785857]]

 [[ 0.90731552  1.61551902 -2.15882686 -3.57324304 -0.70621267]
  [ 2.9143893   2.34599187 -2.40621649 -1.61268981  0.22512925]
  [ 3.53012395  3.61903493 -0.75803571 -0.83564394  0.01130275]
  [ 2.77011221  2.85727141 -0.40687161 -1.02351033 -0.52947951]
  [ 2.0827839   1.20766146 -1.55242352 -0.32895022  0.34835086]]

 [[ 2.3959007   1.63539841 -1.99089658 -2.51344217 -1.28304788]
  [ 2.52899341  2.68481544 -1.00154571 -0.36680073  0.79056701]
  [ 2.38124902  3.31668089  1.46964155 -0.76208117 -1.29629085]
  [ 0.92943431  1.32079416  1.4778593  -1.84335982 -2.92985927]
  [-1.18949855 -1.74598417  0.96712443  0.42245318 -1.10115685]]]
PyTorch
tensor([[[[ 1.8379, -0.9267,  0.9859,  1.6352, -2.8237],
          [ 1.8973, -1.3737,  1.8791,  1.4933, -3.7764],
          [ 1.7018, -1.8257,  1.5097,  0.7854, -3.2116],
          [ 1.4097, -2.1919,  1.0482,  0.6066, -2.4578],
          [ 0.9271, -1.8256,  1.0427,  0.5585, -1.9699]],

         [[ 0.9590,  0.8026,  0.0355,  0.0275, -0.9945],
          [ 0.9181,  0.7403,  0.0528, -0.1280, -0.9709],
          [ 1.1419, -0.2700, -0.0338, -0.6617, -1.1081],
          [ 1.2891, -0.0100,  0.1952, -1.0095, -1.4844],
          [ 0.6879,  0.5838,  0.6651, -0.4817, -1.3530]],

         [[ 1.3268, -1.0490,  0.8021,  0.7952, -2.1289],
          [ 2.0671, -1.7125,  0.4744,  0.2474, -2.5415],
          [ 2.1157, -1.5233, -0.7179,  0.7119, -1.3978],
          [ 1.6602, -0.6554, -0.8365,  1.4264, -0.8237],
          [ 1.3684,  0.2112, -0.6481,  0.3167, -0.7203]]]])

Pytorch does correlation, not convolution. It is explicitly said in docs. https://pytorch.org/docs/stable/nn.html#torch.nn.Conv2d