Extract all nxm blocks

username: vainaijr
cooked: <p>If I have a 5x5 tensor, then, how do I get all 9 3x3 blocks from it, so that resulting tensor is of shape [9, 3, 3] or if these 3x3 blocks are flattened then [9, 9] shape. for example,</p>
<pre><code class="lang-auto">x = torch.randn(5, 5)
</code></pre>
<p>suppose x is</p>
<pre><code class="lang-auto">tensor([[ 0.5756,  0.2463,  1.3940,  0.8473, -0.8371],
        [ 0.9690,  1.4913, -0.2129,  0.8331, -0.6322],
        [-0.0348, -1.6920, -0.0157,  0.6159,  0.1038],
        [-1.0790,  1.4303,  0.3861,  0.1293,  0.4582],
        [ 0.2815, -1.1944, -0.7612,  0.6595,  1.4611]])
</code></pre>
<p>then resulting tensor should be like,</p>
<pre><code class="lang-auto">tensor([[0.5756,  0.2463,  1.3940, 0.9690,  1.4913, -0.2129, -0.0348, -1.6920, -0.0157],
 [0.2463, 1.3940,  0.8473, 1.4913, -0.2129,  0.8331, -1.6920, -0.0157,  0.6159],
...
[-0.0157,  0.6159,  0.1038, 0.3861,  0.1293,  0.4582, -0.7612,  0.6595,  1.4611]])
</code></pre>
<p>without using for loop</p>

username: vainaijr
cooked: <p>is unfold a way to do this, but I get a bit different result when I use unfold</p>
<p>for example if I want all (2x3) blocks</p>
<pre><code class="lang-auto">import torch.nn as nn
x = torch.randn(1, 1, 5, 5)
x
</code></pre>
<pre><code class="lang-auto">tensor([[[[-0.0197,  1.0647, -0.2223,  0.6515,  0.4126],
          [ 0.2328,  0.3959, -0.2910, -0.3321, -0.7934],
          [-0.5428, -0.8354, -0.4103, -0.8781,  0.6794],
          [ 0.0659, -1.7829,  0.0720, -0.3183,  2.2014],
          [-0.8724, -0.1767, -1.3356,  1.0183, -0.0641]]]])
</code></pre>
<pre><code class="lang-auto">a = nn.Unfold((2, 3))
a(x)
</code></pre>
<p>it give me something like this,</p>
<pre><code class="lang-auto">tensor([[[-0.0197,  1.0647, -0.2223,  0.2328,  0.3959, -0.2910, -0.5428,
          -0.8354, -0.4103,  0.0659, -1.7829,  0.0720],
         [ 1.0647, -0.2223,  0.6515,  0.3959, -0.2910, -0.3321, -0.8354,
          -0.4103, -0.8781, -1.7829,  0.0720, -0.3183],
         [-0.2223,  0.6515,  0.4126, -0.2910, -0.3321, -0.7934, -0.4103,
          -0.8781,  0.6794,  0.0720, -0.3183,  2.2014],
         [ 0.2328,  0.3959, -0.2910, -0.5428, -0.8354, -0.4103,  0.0659,
          -1.7829,  0.0720, -0.8724, -0.1767, -1.3356],
         [ 0.3959, -0.2910, -0.3321, -0.8354, -0.4103, -0.8781, -1.7829,
           0.0720, -0.3183, -0.1767, -1.3356,  1.0183],
         [-0.2910, -0.3321, -0.7934, -0.4103, -0.8781,  0.6794,  0.0720,
          -0.3183,  2.2014, -1.3356,  1.0183, -0.0641]]])
</code></pre>
<p>but this is not what I want,<br>
how should I change this, to get 2x3 size blocks from input?</p>
<p>one way that I found, is to reshape this tensor,</p>
<pre><code class="lang-auto">a(x).reshape(1, 12, 6)
</code></pre>
<p>which gives</p>
<pre><code class="lang-auto">tensor([[[-0.0197,  1.0647, -0.2223,  0.2328,  0.3959, -0.2910],
         [-0.5428, -0.8354, -0.4103,  0.0659, -1.7829,  0.0720],
         [ 1.0647, -0.2223,  0.6515,  0.3959, -0.2910, -0.3321],
         [-0.8354, -0.4103, -0.8781, -1.7829,  0.0720, -0.3183],
         [-0.2223,  0.6515,  0.4126, -0.2910, -0.3321, -0.7934],
         [-0.4103, -0.8781,  0.6794,  0.0720, -0.3183,  2.2014],
         [ 0.2328,  0.3959, -0.2910, -0.5428, -0.8354, -0.4103],
         [ 0.0659, -1.7829,  0.0720, -0.8724, -0.1767, -1.3356],
         [ 0.3959, -0.2910, -0.3321, -0.8354, -0.4103, -0.8781],
         [-1.7829,  0.0720, -0.3183, -0.1767, -1.3356,  1.0183],
         [-0.2910, -0.3321, -0.7934, -0.4103, -0.8781,  0.6794],
         [ 0.0720, -0.3183,  2.2014, -1.3356,  1.0183, -0.0641]]])
</code></pre>
<p>I think so this works, but when I add channel to input, then this fails.</p>
<p>edit:<br>
I found one way,</p>
<pre><code class="lang-auto">x.unfold(2, 2, 1).unfold(3, 3, 1)
</code></pre>
<p>2 sized slices for each row, and 3 sized slices for each column<br>
if I wanted (4, 4) slices<br>
then,</p>
<pre><code class="lang-auto">x.unfold(2, 4, 1).unfold(3, 4, 1)
</code></pre>