Simple convolution function in Pytorch

A simple 6x6 matrix
mg_data = [[10, 10, 10, 0, 0, 0],

        [10,10,10, 0, 0, 0],

        [10,10,10, 0, 0,0],

        [10,10,10, 0, 0,0],

        [10,10,10, 0, 0,0],

        [10,10,10, 0, 0,0]]

And a 3x3 kernel or filter
f_data = [[1,0,-1],

      [1,0,-1],

      [1,0,-1]]

How do I do a simple convolution operation using Stride = 1 and padding = 0 in Pytorch.

The output should look like this:

[[0, 30, 30, 0],
[0, 30, 30, 0],
[0, 30, 30, 0],
[0, 30, 30, 0]]

1 Like

Hello Mirror!

Note, I am using an older version of pytorch, 0.3.0.

The only way I know to perform a convolution in pytorch (without
writing your own convolution logic) is to create an appropriate
torch.nn.Conv2d and apply it to your appropriately-reshaped data.

(Newer versions of pytorch may offer greater flexibility.)

Here is a hopefully self-explanatory script:

import torch
torch.__version__

mg_data = [
    [10, 10, 10, 0, 0, 0],
    [10, 10, 10, 0, 0, 0],
    [10, 10, 10, 0, 0, 0],
    [10, 10, 10, 0, 0, 0],
    [10, 10, 10, 0, 0, 0],
    [10, 10, 10, 0, 0, 0]
]

f_data = [
    [1, 0, -1],
    [1, 0, -1],
    [1, 0, -1]
]

mg_data = torch.autograd.Variable (torch.FloatTensor (mg_data))
f_data = torch.FloatTensor (f_data)

# create convolution -- stride and padding are 1 and 0 by default
cnv = torch.nn.Conv2d (1, 1, 3)   # randomly initialized convolution layer
# set kernel to f_data and bias to 0
cnv.weight.data = f_data.unsqueeze (0).unsqueeze (0)  # add singleton channels dimensions
cnv.bias.data.zero_()
# check convolution
cnv.weight
cnv.bias

# apply convolution to mg_data
output = cnv (mg_data.unsqueeze (0).unsqueeze (0))  # add singleton batch and channel dimensions
output   # output is a Variable with some singleton dimensions
output.squeeze().data.tolist()   # remove singleton dimensions and convert to python list

Here is the output:

>>> import torch
>>> torch.__version__
'0.3.0b0+591e73e'
>>>
>>> mg_data = [
...     [10, 10, 10, 0, 0, 0],
...     [10, 10, 10, 0, 0, 0],
...     [10, 10, 10, 0, 0, 0],
...     [10, 10, 10, 0, 0, 0],
...     [10, 10, 10, 0, 0, 0],
...     [10, 10, 10, 0, 0, 0]
... ]
>>>
>>> f_data = [
...     [1, 0, -1],
...     [1, 0, -1],
...     [1, 0, -1]
... ]
>>>
>>> mg_data = torch.autograd.Variable (torch.FloatTensor (mg_data))
>>> f_data = torch.FloatTensor (f_data)
>>>
>>> # create convolution -- stride and padding are 1 and 0 by default
... cnv = torch.nn.Conv2d (1, 1, 3)   # randomly initialized convolution layer
>>> # set kernel to f_data and bias to 0
... cnv.weight.data = f_data.unsqueeze (0).unsqueeze (0)  # add singleton channels dimensions
>>> cnv.bias.data.zero_()

 0
[torch.FloatTensor of size 1]

>>> # check convolution
... cnv.weight
Parameter containing:
(0 ,0 ,.,.) =
  1  0 -1
  1  0 -1
  1  0 -1
[torch.FloatTensor of size 1x1x3x3]

>>> cnv.bias
Parameter containing:
 0
[torch.FloatTensor of size 1]

>>>
>>> # apply convolution to mg_data
... output = cnv (mg_data.unsqueeze (0).unsqueeze (0))  # add singleton batch and channel dimensions
>>> output   # output is a Variable with some singleton dimensions
Variable containing:
(0 ,0 ,.,.) =
   0  30  30   0
   0  30  30   0
   0  30  30   0
   0  30  30   0
[torch.FloatTensor of size 1x1x4x4]

>>> output.squeeze().data.tolist()   # remove singleton dimensions and convert to python list
[[0.0, 30.0, 30.0, 0.0], [0.0, 30.0, 30.0, 0.0], [0.0, 30.0, 30.0, 0.0], [0.0, 30.0, 30.0, 0.0]]

Best.

K. Frank

1 Like

Thank you so much Frank. Really appreciate the answer you have shared. I believe this is the only solution ever available on the internet for the above question. And now I see why Pytorch is a nightmare for beginners to use it. May be it’s built for top coders and super experienced folks. But definitely not for weakhearted.