Problems using torch.nn.functional.pad(...)

username: pyto
cooked: <p>Hey,</p>
<p>So I was wondering about the padding function of nn.functional:</p>
<p>I am working with 3d images which, outside of the net need padding for some processing.<br>
pad() works fine when just leaving the mode at its default. But trying to use mode=‘reflect’ or mode=‘replicate’ doesn’t work for 3d images it seems.</p>
<p>I can’t access my code right now, but I think I tried to programm it manually like this with a,b,c being the count of lines to be padded on:</p>
<hr>
<p>shape = img.shape<br>
img_padded = F.pad(img, (0, a, 0, b, 0, c))</p>
<p><span class="hashtag">#1</span>) replication on first dimension seems to work fine like this<br>
img_padded[shape[0]:, :shape[1], :shape[2]] = img_padded[shape[0]-1, :shape[1], :shape[2]]</p>
<p><span class="hashtag">#2</span>) this doesn’t work anymore though<br>
img_padded[:, shape[1]:, :shape[2]] = img_padded[:, shape[1]-1, :shape[2]]<br>
img_padded[:, :, shape[2]:] = img_padded[:, :, shape[2]-1]</p>
<hr>
<p>What I really don’t get is why it works for 1) and not for 2). I could understand why it would not work like this at all though.<br>
Anyway, is there any nice solution to do replication or reflection padding in 3 dimensional images?</p>

username: ptrblck
cooked: <p>I’m not completely sure about the shapes you are using, but “3d images” should have 5 dimensions as <code>[batch_size, channels, depth, height, width]</code>.<br>
Your current padding call would pad the depth, height, and width dimension. Not the batch and channels dimensions. In the code snippet to compare some outputs, it seems you are trying to index the batch, channel, and depth dimensions, which seems to be wrong.</p>
<p>Could you check the shape before and after padding and rerun the comparison?</p>

username: pyto
cooked: <p>Hm ok… I actually used only 3 dimensions. Since it is outside the neural net and only one channel image anyway, batch and channel don’t play a role here. I really just want to change the shape of the image itself. That works great so far. But only with the default padding mode.</p>
<p>So for example if I want multiples of 128:</p>
<p>img.shape:<br>
(279, 510, 510)</p>
<p>padded_img.shape:<br>
(384, 512, 512)</p>
<p>So I am actually trying to index the depth, height and width and there is no batch and channels.</p>

username: ptrblck
cooked: <p>From the docs:</p>
<blockquote>
<p>Constant padding is implemented for arbitrary dimensions.<br>
Replicate padding is implemented for padding the last 3 dimensions of 5D input<br>
tensor, or the last 2 dimensions of 4D input tensor, or the last dimension of<br>
3D input tensor. Reflect padding is only implemented for padding the last 2<br>
dimensions of 4D input tensor, or the last dimension of 3D input tensor.</p>
</blockquote>
<p>Your batch and channel dimensions should be 1 in this case.<br>
Try to add them via:</p>
<pre data-code-wrap="python"><code class="lang-python">input = input.unsqueeze(0).unsqueeze(1)
</code></pre>
<p>and rerun your code.</p>

username: pyto
cooked: <p>Thank you! I will try right away <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=9" title=":slight_smile:" class="emoji" alt=":slight_smile:"></p>