ConvTranspose2d output_padding position

sharvil: <p>I have a convolution transpose that’s defined like this:</p>
<pre><code class="lang-python">nn.ConvTranspose2d(1, 1, [1, 30], stride=[1, 15], padding=[1, 8], output_padding=[0, 1])
</code></pre>
<p>This describes the inverse operation for a convolution that is padded by 8 pixels on the left, and 7 pixels on the right with a stride of 15 pixels.</p>
<p>Is there a way for me to specify that I want this transposed convolution to be the inverse for a convolution that’s padded by 7 pixels on the left and 8 pixels on the right instead? In other words, I want <code>output_padding</code> to remove 1 pixel of padding from the left side instead of the right side.</p>

ptrblck: <p>If I’m not mistaken, <code>output_padding</code> just adds the padding after the transposed convolution was applied.<br>
If that’s the case, you could remove the output padding and instead slice and pad the output manually via <code>F.pad</code>.</p>

sharvil: <p>I don’t think that’s what <code>output_padding</code> does. It prevents some number of elements from being treated as padding (and thus removed from the output).</p>
<p>Consider this transpose operation:</p>
<pre><code class="lang-python">torch.nn.Conv1d(1, 1, kernel_size=30, stride=15, padding=8, output_padding=1)
</code></pre>
<p>The equivalent of the above operation without specifying <code>padding</code> or <code>output_padding</code> is:</p>
<pre><code class="lang-python">padding = 8
output_padding = 1
y = torch.nn.Conv1d(1, 1, kernel_size=30, stride=15)(x)
y[:, :, padding:-(padding - output_padding)]
</code></pre>
<p>The issue is that <code>output_padding</code> is applied to the right side, and I can’t find a way to apply it on the left instead. A natural solution would be to accept a tuple for <code>padding</code>, just like <code>np.pad</code> or any of the other PyTorch padding ops that take separate left and right padding values. That approach would be more consistent, more flexible, and eliminate <code>output_padding</code> entirely.</p>
<p>Admittedly, I could just manually extract the parts of the tensor I need and ignore <code>padding</code> / <code>output_padding</code> entirely, but I’m hoping that I just missed something and that there’s a better way to get the result I’m looking for.</p>
<p>(BTW, this post was motivated by the fact that TensorFlow applies the equivalent of <code>output_padding</code> on the left whereas PyTorch applies it on the right. This difference prevents model conversion between TF and PyTorch.)</p>

ptrblck: <p>I see, thanks for the code snippet (I assume the conv layer should be <code>nn.ConvTranspose1d</code>).</p>
<p>I don’t think you can easily change it, but might instead have to slip the inputs and kernel if you compare the TF and PyTorch implementations.<br>
I’m not sure, if TF flips the kernel anyway, but I think Theano flipped it internally to use a convolution instead of a cross-correlation.</p>

sharvil: <p>Thanks for the response. Yes, you’re right – those should’ve been <code>nn.ConvTranspose1d</code>.</p>
<p>TF does cross-correlation, same as PyTorch. I’ve confirmed by writing some framework-independent C++ code that the only delta between the two is their preference on which side to remove more elements from.</p>