How do I get the correct Tensor dimensions after Conv2d Layer? (keras to PyTorch)

robinbaudisch: <p>I am trying to recreate a keras model in PyTorch. My input tensor has the shape (2, 10, 25). In keras, I apply the following Conv2d layer to my input tensor:</p>
<pre><code class="lang-auto">import tensorflow as tf

batch_size = 1
x = tf.random.normal( (batch_size, 2, 10, 25) )
y = tf.keras.layers.Conv2D(filters=34, 
                           kernel_size=(1,10),
                           padding='valid',
                           input_shape=input_shape[2:])(x)
print(y.shape)

# (1, 2, 1, 34)
</code></pre>
<p>When trying to recreate this layer in PyTorch, I am not quite grasping the dimensionalities to use, since the Conv2d layer in PyTorch has no filters parameter. This is how far I’ve gotten on my own:</p>
<pre><code class="lang-auto">import torch
import torch.nn as nn

batch_size = 1
x = torch.randn(batch_size, 2, 10, 25)
conv = nn.Conv2d(in_channels=2, out_channels=2, kernel_size=(10,1), bias=True)

y = conv(input_data)
print(y.shape)

# torch.Size([1, 2, 1, 25])
</code></pre>
<p>Now, all dimensions except for the last one are identical to the keras implementation. I suspect my understanding of the out_channels parameter is not correct but I am not sure how to proceed from here.</p>
<p>Any help is hugely appreciated!</p>

gphilip: <p>The <a href="https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html" rel="noopener nofollow ugc">documentation for Conv2d</a> gives the formulas for computing the output shape; search for the string “Shape:” to find these in that page.</p>

robinbaudisch: <p>Thanks for the input, however, when keeping all common parameters the same when porting from keras to PyTorch (padding=‘valid’ → no padding, stride=(1,1), dilation=(1,1), groups=1), the dimensionalities don’t add up. That’s what’s confusing me.</p>
<p>I know I can achieve the right dimensions when I add padding=(0,5) and kernel_size=(10,2), but that does not seem to result in the same output. The number of parameters for the keras implementation are:</p>
<pre><code class="lang-auto">model.summary()

Model: "model_1"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            [(None, 2, 10, 25)]  0                                            
__________________________________________________________________________________________________
conv2d_5 (Conv2D)               (None, 2, 1, 34)     8534        input_1[0][0]                 
</code></pre>
<p>whereas for the PyTorch implementation with padding=(0,5) and kernel_size=(10,2):</p>
<pre><code class="lang-auto">device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model = SoccerModel().to(device)
summary(model, [(2, 10, 25), (2, 1, 11)])

----------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Conv2d-1             [-1, 2, 1, 34]              82
</code></pre>

gphilip: <p>You use the variable <code>input_shape</code> in your keras code, but you don’t show how you initialize this variable. Could you show the value of <code>input_shape</code>?</p>

ptrblck: <aside class="quote no-group" data-username="robinbaudisch" data-post="3" data-topic="131925">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/r/9fc29f/48.png" class="avatar"> robinbaudisch:</div>
<blockquote>
<p>The number of parameters for the keras implementation are:</p>
</blockquote>
</aside>
<p>TF/Keras use the channels-last memory layout so your input has the shape <code>[batch_size, height=2, width=10, channels=25]</code>, while PyTorch uses channels-first.<br>
The <code>nn.Conv2d</code> layer is currently using <code>in_channels=2</code> in PyTorch, which is wrong, so you should change it to <code>in_channels=25</code> and <code>permute</code> the input to <code>[batch_size, 25, 2, 10]</code>.</p>