RuntimeError: mat1 and mat2 shapes cannot be multiplied (8192x1 and 2048x1000)

jjoon0928: <p>I want to train Cars-196 dataset in Pytorch</p>
<pre><code class="lang-auto">import torchvision.transforms as transforms
transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
batch_size=4

# Load the Cars-196 train and test dataset
"""https://pytorch.org/vision/main/generated/torchvision.datasets.StanfordCars.html"""

trainset = torchvision.datasets.StanfordCars(root='./data', split='train',
                                                 download=True, transform=transform)
trainloader = DataLoader(trainset, batch_size=batch_size,
                                          shuffle=True, num_workers=4)
testset = torchvision.datasets.StanfordCars(root='./data', split='test',
                                       download=True, transform=transform)
testloader = DataLoader(testset, batch_size=batch_size,
                                         shuffle=False, num_workers=4)
</code></pre>
<p>I just put ResNet-50 in class and there is no modification.</p>
<pre><code class="lang-auto">class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        resnet = models.resnet50(pretrained=True)
        self.features=nn.Sequential(*list(resnet.children()))
    def forward(self, x):
        x=self.features(x)
        return x
</code></pre>
<pre><code class="lang-auto">model=Model()
model=model.to(device)

import torch.optim as optim

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.001)

for epoch in range(10):   # Iterate data 
    model.train()
    train_loss  = 0.0
    for i, data in tqdm(enumerate(trainloader), total=len(trainloader)):
        image, labels= data
        image = image.to(device)
        labels = labels.to(device)
        # Make Gradient parameter 0...
        optimizer.zero_grad()
        
        # propagation + backpropagation + optimisation...
        outputs = model(image)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # outputs statistics
        train_loss += loss.item()
    train_loss = train_loss / len(trainset)

print('Finished Training')

</code></pre>
<p>But, RuntimeError: mat1 and mat2 shapes cannot be multiplied (8192x1 and 2048x1000) has been occurred.</p>
<p>What is the difference between training resnet-50 without class and training it using Sequential()? and how can I resolve this problem?</p>

ptrblck: <p>Wrapping the resnet modules into an <code>nn.Sequential</code> container will drop all functional API calls used in the original <code>forward</code> method such as <a href="https://github.com/pytorch/vision/blob/5850f370c03d941f97c7bd53f99a83abb0b9dd01/torchvision/models/resnet.py#L279">this <code>torch.flatten</code> operation</a> and will thus create this shape mismatch.<br>
Since you are wrapping all children into <code>nn.Sequential</code> you could also directly use the <code>resnet50</code>.</p>

jjoon0928: <p>Hello, thank you for your help. But, I want to modify ResNet-50 such as removing some conv layer and skip connection. In this case, should I type all the layers of ResNet in class?</p>

jjoon0928: <p>Hi, when I declare self.model = models.resnet50(pretrained=True) not using nn.Sequential() it works! Thanks!</p>

ptrblck: <p>If you want to replace specific layers you could replace the internal attribute directly e.g. via:</p>
<pre><code class="lang-python">model.fc = nn.Linear(...)
</code></pre>
<p>which would replace the internal <code>.fc</code> layer with a new <code>nn.Linear</code> layer while still reusing the same <code>forward</code> method.<br>
For more complicated use cases you might want to create a custom <code>nn.Module</code> and override the <code>forward</code> with your custom implementation.</p>

jjoon0928: <p>Hi, layer4 of ResNet-50 is consist of 3 Bottleneck containers in Sequential.<br>
If I want to modify layer in Bottleneck container, should I make Bottleneck class separately?</p>

ptrblck: <p>It depends as mentioned in my previous post.<br>
If you want to replace a single layer it might be easier to directly use the internal attribute and replace it. If you want to change the actual forward pass you might want to create a custom module.</p>