Simple convolution function in Pytorch

Mirror_Neuron: <p>A simple 6x6 matrix<br>
mg_data = [[10, 10, 10, 0, 0, 0],</p>
<pre><code>        [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]]
</code></pre>
<p>And a 3x3 kernel or filter<br>
f_data = [[1,0,-1],</p>
<pre><code>      [1,0,-1],

      [1,0,-1]]
</code></pre>
<p>How do I do a simple convolution operation using Stride = 1 and padding = 0 in Pytorch.</p>
<p>The output should look like this:</p>
<p>[[0, 30, 30, 0],<br>
[0, 30, 30, 0],<br>
[0, 30, 30, 0],<br>
[0, 30, 30, 0]]</p>

KFrank: <p>Hello Mirror!</p>
<aside class="quote no-group" data-username="Mirror_Neuron" data-post="1" data-topic="94503" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/mirror_neuron/48/28264_2.png" class="avatar"> Mirror_Neuron:</div>
<blockquote>
<p>How do I do a simple convolution operation using Stride = 1 and padding = 0 in Pytorch.</p>
</blockquote>
</aside>
<p>Note, I am using an older version of pytorch, 0.3.0.</p>
<p>The only way I know to perform a convolution in pytorch (without<br>
writing your own convolution logic) is to create an appropriate<br>
<a href="https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html#torch.nn.Conv2d" rel="noopener nofollow ugc">torch.nn.Conv2d</a> and apply it to your appropriately-reshaped data.</p>
<p>(Newer versions of pytorch may offer greater flexibility.)</p>
<p>Here is a hopefully self-explanatory script:</p>
<pre data-code-wrap="python"><code class="lang-python">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
</code></pre>
<p>Here is the output:</p>
<pre><code class="lang-plaintext">&gt;&gt;&gt; import torch
&gt;&gt;&gt; torch.__version__
'0.3.0b0+591e73e'
&gt;&gt;&gt;
&gt;&gt;&gt; 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]
... ]
&gt;&gt;&gt;
&gt;&gt;&gt; f_data = [
...     [1, 0, -1],
...     [1, 0, -1],
...     [1, 0, -1]
... ]
&gt;&gt;&gt;
&gt;&gt;&gt; mg_data = torch.autograd.Variable (torch.FloatTensor (mg_data))
&gt;&gt;&gt; f_data = torch.FloatTensor (f_data)
&gt;&gt;&gt;
&gt;&gt;&gt; # create convolution -- stride and padding are 1 and 0 by default
... cnv = torch.nn.Conv2d (1, 1, 3)   # randomly initialized convolution layer
&gt;&gt;&gt; # set kernel to f_data and bias to 0
... cnv.weight.data = f_data.unsqueeze (0).unsqueeze (0)  # add singleton channels dimensions
&gt;&gt;&gt; cnv.bias.data.zero_()

 0
[torch.FloatTensor of size 1]

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

&gt;&gt;&gt; cnv.bias
Parameter containing:
 0
[torch.FloatTensor of size 1]

&gt;&gt;&gt;
&gt;&gt;&gt; # apply convolution to mg_data
... output = cnv (mg_data.unsqueeze (0).unsqueeze (0))  # add singleton batch and channel dimensions
&gt;&gt;&gt; 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]

&gt;&gt;&gt; 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]]
</code></pre>
<p>Best.</p>
<p>K. Frank</p>

Mirror_Neuron: <p>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.</p>