CNN matrix shape issue when adding new convolutional layer

DrBwts: <p>I have been adding more &amp; more convolutional layers to my model to see how they effect model size &amp; accuracy. It was all going fine until I added my 6th convolutional layer.</p>
<pre><code>class MyCNN(nn.Module):

    def __init__(self):
        super().__init__()

        # convolution layers
        self._body = nn.Sequential(
            
            # Conv - 1
            nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3),
            nn.ReLU(inplace=True),
            nn.BatchNorm2d(64, momentum=0.3),
            nn.MaxPool2d(kernel_size=2),

            # Conv - 2
            nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3),
            nn.ReLU(inplace=True),
            nn.BatchNorm2d(128, momentum=0.3),
            nn.MaxPool2d(kernel_size=2),

            # Conv - 3
            nn.Conv2d(in_channels=128, out_channels=256, kernel_size=3),
            nn.ReLU(inplace=True),
            nn.BatchNorm2d(256, momentum=0.3),
            nn.MaxPool2d(kernel_size=2),

            # Conv - 4
            nn.Conv2d(in_channels=256, out_channels=512, kernel_size=3),
            nn.ReLU(inplace=True),
            nn.BatchNorm2d(512, momentum=0.3),
            nn.MaxPool2d(kernel_size=2),

            # Conv - 5
            nn.Conv2d(in_channels=512, out_channels=1024, kernel_size=3),
            nn.ReLU(inplace=True),
            nn.BatchNorm2d(1024, momentum=0.3),
            nn.MaxPool2d(kernel_size=2),

            # Conv - 6                
            nn.Conv2d(in_channels=1024, out_channels=2048, kernel_size=3),
            nn.ReLU(inplace=True),
            nn.BatchNorm2d(2048, momentum=0.3),
            nn.MaxPool2d(kernel_size=2),

        )

        # Fully connected layers 
        self._head = nn.Sequential(

            # nn.Linear(in_features=128*54*54, out_features=512),
            # nn.Linear(in_features=512*12*12, out_features=512),
            # nn.Linear(in_features=1024*5*5, out_features=512),
            nn.Linear(in_features=2048*2*2, out_features=512),
            nn.ReLU(inplace=True),
            nn.Linear(in_features=512, out_features=7)

        )

    def forward(self, x):

        x = self._body(x)
        x = x.view(x.size()[0], -1)
        x = self._head(x)
        
        return x
</code></pre>
<p>As can be seen in the code above I have been adding a conv-layer then recalculating the length of the vector to put into the fully connected layers. For each successive addition the calculations have been right &amp; the model trains. But now I’ve added the 6th layer I get the following error,</p>
<pre><code>RuntimeError: mat1 and mat2 shapes cannot be multiplied (32x2048 and 8192x512)
</code></pre>
<p>Why has it decided that my input feature vector is <code>32*2048</code> and not <code>2048*2*2</code> that I have coded?</p>

KFrank: <p>Hi Dr!</p>
<aside class="quote no-group quote-modified" data-username="DrBwts" data-post="1" data-topic="198275" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/drbwts/48/62559_2.png" class="avatar"> DrBwts:</div>
<blockquote>
<pre><code>class MyCNN(nn.Module):

    def __init__(self):
        super().__init__()

        # convolution layers
        self._body = nn.Sequential(
            
            # Conv - 1
            nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3),
            nn.ReLU(inplace=True),
            nn.BatchNorm2d(64, momentum=0.3),
            nn.MaxPool2d(kernel_size=2),

            # Conv - 2
            nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3),
            nn.ReLU(inplace=True),
            nn.BatchNorm2d(128, momentum=0.3),
            nn.MaxPool2d(kernel_size=2),

            # Conv - 3
            nn.Conv2d(in_channels=128, out_channels=256, kernel_size=3),
            nn.ReLU(inplace=True),
            nn.BatchNorm2d(256, momentum=0.3),
            nn.MaxPool2d(kernel_size=2),

            # Conv - 4
            nn.Conv2d(in_channels=256, out_channels=512, kernel_size=3),
            nn.ReLU(inplace=True),
            nn.BatchNorm2d(512, momentum=0.3),
            nn.MaxPool2d(kernel_size=2),

            # Conv - 5
            nn.Conv2d(in_channels=512, out_channels=1024, kernel_size=3),
            nn.ReLU(inplace=True),
            nn.BatchNorm2d(1024, momentum=0.3),
            nn.MaxPool2d(kernel_size=2),

            # Conv - 6                
            nn.Conv2d(in_channels=1024, out_channels=2048, kernel_size=3),
            nn.ReLU(inplace=True),
            nn.BatchNorm2d(2048, momentum=0.3),
            nn.MaxPool2d(kernel_size=2),

        )

        # Fully connected layers 
        self._head = nn.Sequential(

            # nn.Linear(in_features=128*54*54, out_features=512),
            # nn.Linear(in_features=512*12*12, out_features=512),
            # nn.Linear(in_features=1024*5*5, out_features=512),
            nn.Linear(in_features=2048*2*2, out_features=512),
            nn.ReLU(inplace=True),
            nn.Linear(in_features=512, out_features=7)

        )

    def forward(self, x):

        x = self._body(x)
        x = x.view(x.size()[0], -1)
        x = self._head(x)
        
        return x
</code></pre>
<p>…</p>
<pre><code>RuntimeError: mat1 and mat2 shapes cannot be multiplied (32x2048 and 8192x512)
</code></pre>
</blockquote>
</aside>
<p>It works for me.  Maybe check the code you actually ran for typos.</p>
<p>Here’s a test script that incorporates your code:</p>
<pre data-code-wrap="python"><code class="lang-python">import torch
print (torch.__version__)

import torch.nn as nn

_ = torch.manual_seed (2024)

class MyCNN(nn.Module):
    
    def __init__ (self):
        super().__init__()
        
        # convolution layers
        self._body = nn.Sequential(
            
            # Conv - 1
            nn.Conv2d (in_channels = 3, out_channels = 64, kernel_size = 3),
            nn.ReLU (inplace = True),
            nn.BatchNorm2d (64, momentum = 0.3),
            nn.MaxPool2d (kernel_size = 2),
            
            # Conv - 2
            nn.Conv2d (in_channels = 64, out_channels = 128, kernel_size = 3),
            nn.ReLU (inplace = True),
            nn.BatchNorm2d (128, momentum = 0.3),
            nn.MaxPool2d (kernel_size = 2),
            
            # Conv - 3
            nn.Conv2d (in_channels = 128, out_channels = 256, kernel_size = 3),
            nn.ReLU (inplace = True),
            nn.BatchNorm2d (256, momentum = 0.3),
            nn.MaxPool2d (kernel_size = 2),
            
            # Conv - 4
            nn.Conv2d (in_channels = 256, out_channels = 512, kernel_size = 3),
            nn.ReLU (inplace = True),
            nn.BatchNorm2d (512, momentum = 0.3),
            nn.MaxPool2d (kernel_size = 2),
            
            # Conv - 5
            nn.Conv2d (in_channels = 512, out_channels = 1024, kernel_size = 3),
            nn.ReLU (inplace = True),
            nn.BatchNorm2d (1024, momentum = 0.3),
            nn.MaxPool2d (kernel_size = 2),
            
            # Conv - 6                
            nn.Conv2d (in_channels = 1024, out_channels = 2048, kernel_size = 3),
            nn.ReLU (inplace = True),
            nn.BatchNorm2d (2048, momentum = 0.3),
            nn.MaxPool2d (kernel_size = 2),
            
        )
        
        # Fully connected layers 
        self._head = nn.Sequential(
            
            # nn.Linear (in_features = 128*54*54, out_features = 512),
            # nn.Linear (in_features = 512*12*12, out_features = 512),
            # nn.Linear (in_features = 1024*5*5, out_features = 512),
            nn.Linear (in_features = 2048*2*2, out_features = 512),
            nn.ReLU (inplace = True),
            nn.Linear (in_features = 512, out_features = 7)
            
        )
    
    def forward (self, x):
        
        x = self._body (x)
        x = x.view (x.size()[0], -1)
        x = self._head (x)
        
        return x


myCNN = MyCNN()

t = torch.randn (32, 3, 256, 256)
print ('t.shape =', t.shape)

u = myCNN (t)
print ('u.shape =', u.shape)
</code></pre>
<p>And here is its output:</p>
<pre><code class="lang-plaintext">2.2.1
t.shape = torch.Size([32, 3, 256, 256])
u.shape = torch.Size([32, 7])
</code></pre>
<p>Best.</p>
<p>K. Frank</p>

DrBwts: <p>hmmmm… how odd. I’ll check it over again when I’m back in tomorrow</p>

DrBwts: <p>Nope its not having it.</p>
<p>Rewrote the model to eliminate typos but it keeps insisting that I’m trying to use a <code>32 x 2048</code> and not a <code>2 x 2 x 2048</code></p>

DrBwts: <p>I go the dimensions of the last conv layer wrong, I was expecting <code>2048 x 2 x 2</code> but the Max Pooling is spitting out <code>2048 x 1 x 1</code></p>