How to keep the shape of input and output same when dilation conv?

micklexqg: <p>in keras, if the padding is set “same”, then the the shape of input and output will be same.<br>
for example, in keras, if the input is 32<br>
model.add(Conv2D(256, kernel_size=3, strides=1,<br>
padding=‘same’, dilation_rate=(2, 2)))<br>
the output shape will not change.<br>
but in pytorch,<br>
nn.Conv2d(256,256,3,1,1, dilation=2,bias=False),<br>
the output shape will become 30.<br>
so how to keep the shape of input and output same when dilation conv?</p>

ptrblck: <p>You could visualize it with some tools like <a href="https://ezyang.github.io/convolution-visualizer/index.html" rel="nofollow noopener">ezyang’s convolution visualizer</a> or calculate it with this formula:</p>
<ul>
<li><code>o = output</code></li>
<li><code>p = padding</code></li>
<li><code>k = kernel_size</code></li>
<li><code>s = stride</code></li>
<li><code>d = dilation</code></li>
</ul>
<pre><code class="lang-auto">o = [i + 2*p - k - (k-1)*(d-1)]/s + 1
</code></pre>
<p>In your case this gives <code>o = [32 + 2 - 3 - 2*1]/1 +1 = [29] + 1 = 30</code>.<br>
Now, you could set all your parameters and “solve” the equation for <code>p</code>.<br>
You will see, that <code>p=2</code> will give you an output size of <code>32</code>.</p>

micklexqg: <p>thank you, i have just tried and solved my problem in terms of your answer.<br>
another question, what is the similar formula for ConvTranspose2d?</p>

ptrblck: <p>The output size of a transposed convolution is given by:</p>
<pre><code class="lang-auto">o = (i -1)*s - 2*p + k + output_padding 
</code></pre>
<p>Note that  <code>ConvTranspose</code> layers come with an <code>output_padding</code> parameter, which defaults to <code>0</code>.<br>
The formulas are also shown in the <a href="http://pytorch.org/docs/master/nn.html#torch.nn.ConvTranspose2d" rel="nofollow noopener">documentation</a> of PyTorch’s convolution layers.<br>
(I used a slightly different notation for the <code>Conv</code> layer output. My formula can be simplified to the one shown in the docu though.)</p>

micklexqg: <p>nice, thank you very much! <img src="https://discuss.pytorch.org/images/emoji/apple/hugs.png?v=5" title=":hugs:" class="emoji" alt=":hugs:"></p>

Shivam_Saboo: <p>Might be a silly question, but I am finding it hard to visualize the above formula for 3d images.<br>
I am working on 3d U-Net model for passing oct scans in the model and want to keep the volume same after applying 3d Conv. What modification should I make to the above formula?</p>
<p>If my kernel size is not square i.e suppose I use 3x3x1 and then 1x1x3 conv3D on my scans, how will I calculate padding separately for all three dimensions?</p>

Time0o: <p>Sorry for digging this up again, but as the formula depends on the input size of the convolution layer I’m not sure how to create a dilated convolution layer that will preserve arbitrary input dimensions. Is that even possible? (It seems to be in Keras).</p>

SumanthMeenan: <p><a class="mention" href="/u/time0o">@Time0o</a> Yes, its definitely possible with the help of padding.<br>
To preserve input dimension we obviously need to use stride = 1<br>
bcz if we use stride &gt; 1, input image size will be almost half.</p>
<p>Next, in the above case lets say i am using dilation = 2, kernel size 3, padding = 2<br>
0 = [256 + 4 - 3 - 2]/1  +  1    =   256<br>
We are able to preserve the input dimension even after dilated convolution</p>

metatl: <p>A somewhat related, but different question:<br>
In a u-net architecture, I am using conv2d and convtransposed2d for the down and up path. I wish to build a class that can take in arbitrary input image size. However, for many input image sizes the layers at the same depth of the down and up paths can have slightly different image size due to the way the implementations of conv2d and convtransposed2d are made. Is there a way to dynamically calculate the padding needed to make the down and up paths at the same depth have the same image size?</p>

SumanthMeenan: <p>Your stride is 2 or changing during upsampling and downsampling?</p>

LazySleeper: <p>what if the input has non-equal height and width.</p>

road: <p>You apply the formula separately on the height and the width.</p>

Marcus_Brown: <p><a class="mention" href="/u/ptrblck">@ptrblck</a> Hello, how do I keep the same size in either the height or width after a transpose convolution?</p>

ptrblck: <p>You could set the kernel size and stride for this spatial dimension to <code>1</code> as seen here:</p>
<pre><code class="lang-python">x = torch.randn(1, 1, 24, 24)
conv = nn.ConvTranspose2d(1, 1, (2, 1), (2, 1))
out = conv(x)
print(out.shape)
&gt; torch.Size([1, 1, 48, 24])
</code></pre>

Kirti_Pandya: <p>In my case it is not working.<br>
input shape : 1x28x28<br>
nn.Conv2d(in_channels=1, out_channels=32, kernel_size=5, stride=2, dilation=1, padding=0)<br>
Output shape : 32x12x12<br>
According to your equation it should be [28 + 0 - 5 - 0] / 2 + 1= 12.5 which is not possible.</p>
<p>Could you please help.</p>

ptrblck: <p>The formula in the docs uses the floor operation, which would thus yield a spatial output shape of 12.</p>

Kirti_Pandya: <p>Thank you very for the help.</p>
<p><a href="https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html" class="inline-onebox" rel="noopener nofollow ugc">Conv2d — PyTorch 1.7.0 documentation</a> &lt;-- Here I can not find any float equation. Could you please provide link if possible. I have watched CS231n Stanford lectures but could not find any float equation.</p>
<p>Thanking you.</p>

ptrblck: <p>I’m not sure what “float equation” means in this context, but the formula can be found in the <a href="https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html#torch.nn.Conv2d">Conv2d docs</a>.<br>
Specifically the <a href="https://en.wikipedia.org/wiki/Floor_and_ceiling_functions">Floor operation</a> is used to calculate the output shapes (looks like an uppercase L on the left and flipped on the right hand side of the calculation).</p>

neel_g: <p>For anyone looking for the transposed Convolution formula <strong>w/ Dilation</strong> to copy/paste:-</p>
<pre data-code-wrap="py"><code class="lang-nohighlight">p = o - 1 - d*(k-1) + 2*p - [(o - 1)*s]
</code></pre>
<p>if they want to preserve the shape of input and output (i.e <code>H_out, W_out = H_in, W_in</code>)</p>
<p>This yields the padding with var names as pasted above - so one could just modify padding alone to achieve same sizes.</p>

Ywandung-Lyou: <p>Why there is ‘p’ in both sides of the equation?<br>
<a class="mention" href="/u/neel_g">@neel_g</a></p>