"RuntimeError: mat1 dim 1 must match mat2 dim 0" only at eval

File “classifier.py”, line 144, in
test_loss, test_accuracy = evaluate(model, dataloaders[“val”])
File “classifier.py”, line 115, in evaluate
output = model(image)
File “/home/bak/anaconda3/envs/GNN/lib/python3.7/site-packages/torch/nn/modules/module.py”, line 889, in _call_impl
result = self.forward(*input, **kwargs)
File “/home/bak/anaconda3/envs/GNN/lib/python3.7/site-packages/torchvision/models/resnet.py”, line 151, in forward
x = self.fc(x)
File “/home/bak/anaconda3/envs/GNN/lib/python3.7/site-packages/torch/nn/modules/module.py”, line 889, in _call_impl
result = self.forward(*input, **kwargs)
File “/home/bak/anaconda3/envs/GNN/lib/python3.7/site-packages/torch/nn/modules/linear.py”, line 94, in forward
return F.linear(input, self.weight, self.bias)
File “/home/bak/anaconda3/envs/GNN/lib/python3.7/site-packages/torch/nn/functional.py”, line 1753, in linear
return torch._C._nn.linear(input, weight, bias)
RuntimeError: mat1 dim 1 must match mat2 dim 0


import numpy as np
import matplotlib.pyplot as plt

import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision import transforms, datasets, models, utils

if torch.cuda.is_available():
DEVICE = torch.device(‘cuda’)
else:
DEVICE = torch.device(‘cpu’)

BATCH_SIZE = 8
EPOCHS = 50

data_transforms = {
‘train’: transforms.Compose([
transforms.RandomResizedCrop(224),
# transforms.Resize(256),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
]),
‘val’: transforms.Compose([
transforms.CenterCrop(224),
transforms.Resize(256),
transforms.ToTensor(),
transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
]),
}

image_datasets = {x: datasets.ImageFolder("/home/bak/Dataset/hymenoptera_data/hymenoptera_data", data_transforms[x]) for x in [‘train’, ‘val’]}
dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size = BATCH_SIZE, num_workers = 0, shuffle = True) for x in [‘train’, ‘val’]}
dataset_sizes = {x: len(image_datasets[x]) for x in [‘train’, ‘val’]}
class_names = image_datasets[‘train’].classes

def train(model, train_loader, optimizer, log_interval):
model.train()
for batch_idx, (image, label) in enumerate(train_loader):
image = image.to(DEVICE)
label = label.to(DEVICE)
optimizer.zero_grad()
output = model(image)
loss = criterion(output, label)
loss.backward()
optimizer.step()

    if batch_idx % log_interval == 0:
        print("Train Epoch: {} [{}/{} ({:.0f}%)]\tTrain Loss: {:.6f}".format(
            epoch, batch_idx * len(image),
            len(train_loader.dataset), 100. * batch_idx / len(train_loader),
            loss.item()))

def evaluate(model, test_loader):
model.eval()
test_loss = 0
correct = 0

with torch.no_grad():
    for image, label in test_loader:
        image = image.to(DEVICE)
        label = label.to(DEVICE)
        output = model(image)
        test_loss += criterion(output, label).item()
        prediction = output.max(1, keepdim = True)[1]
        correct += prediction.eq(label.view_as(prediction)).sum().item()

test_loss /= (len(test_loader.dataset) / BATCH_SIZE)
test_accuracy = 100. * correct / len(test_loader.dataset)
return test_loss, test_accuracy

model = models.resnet18(pretrained = False)
num_ftrs = model.fc.in_features
model.fc = nn.Linear(num_ftrs, 2)
model = model.to(DEVICE)

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

for epoch in range(1, EPOCHS + 1):
train(model, dataloaders[“train”], optimizer, log_interval = 5)
test_loss, test_accuracy = evaluate(model, dataloaders[“val”])
print("\n[EPOCH: {}], \tTest Loss: {:.4f}, \tTest Accuracy: {:.2f} % \n".format(
epoch, test_loss, test_accuracy))


Train works well until the end of the first epoch. However, Runtimeerror appears at evaluation. I saw the linear dimension was different from the train.

I still don’t understand why these changes appear…

Have you checked whether the shapes are what you expect at each stage in the model?

Even if the image resolution is different at validation time it shouldn’t affect the input dimension to the linear layer as there is an average pooling step after the last conv layer in ResNet-18.

Finally, I found the reason! Due to the limitation of the input size of ResNet, there was a miss-match between CNN layer and FC layer. When I change the resize value of transforms, it works well.

Thank you.