CNN loss isn't reducing, and the model misclassifies half of the cats and dogs dataset

gerardbarbalich: <p>Hello.</p>
<p>Here is my model:</p>
<pre><code class="lang-auto">class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(in_channels=3, out_channels=6, kernel_size=5)
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
        self.conv2 = nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5)
        
        self.fc1 = nn.Linear(in_features=16 * 61 * 61, out_features=120)
        self.fc2 = nn.Linear(in_features=120, out_features=84)
        self.out = nn.Linear(in_features=84, out_features=NUM_CLASSES)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 16 * 61 * 61)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.out(x)
        return x
</code></pre>
<p>… and its use:</p>
<pre><code class="lang-auto">    model = Net().to(device)
    criterion = nn.CrossEntropyLoss()
    optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

    model.train()
    running_loss = 0.0

    # define training loop
    n_total_steps = len(train_loader)
    for epoch in range(num_epochs): # loop over the number of epochs
        for i, (images, labels) in enumerate(train_loader): # loop over the training loaders
            images = images.to(device) # push images and labels to device to get CPU support
            labels = labels.to(device)

            # Forward pass
            optimizer.zero_grad()
            outputs = model(images)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()
                        
            running_loss += loss.item()

            if (i+1) % 20 == 0:
                print (f"Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{n_total_steps}], Running Loss: {running_loss:.4f}")
                running_loss = 0.0
</code></pre>
<p>These are the results:</p>
<p>Epochs: 5, Learning rate: 0.001</p>
<p>Epoch [1/5], Step [20/40], Running Loss: 13.9385<br>
Epoch [1/5], Step [40/40], Running Loss: 13.9349<br>
Epoch 1 of 5 completed…<br>
Epoch [2/5], Step [20/40], Running Loss: 13.8513<br>
Epoch [2/5], Step [40/40], Running Loss: 13.9098<br>
Epoch 2 of 5 completed…<br>
Epoch [3/5], Step [20/40], Running Loss: 13.8609<br>
Epoch [3/5], Step [40/40], Running Loss: 13.8211<br>
Epoch 3 of 5 completed…<br>
Epoch [4/5], Step [20/40], Running Loss: 13.7967<br>
Epoch [4/5], Step [40/40], Running Loss: 13.8098<br>
Epoch 4 of 5 completed…<br>
Epoch [5/5], Step [20/40], Running Loss: 13.7332<br>
Epoch [5/5], Step [40/40], Running Loss: 13.7854<br>
Epoch 5 of 5 completed…<br>
Finished Training<br>
Total training time: 3.3 minutes<br>
train samples: 800, test samples :800</p>
<p>Accuracy of CAT: 95.7%, of 390 cases<br>
Accuracy of DOG: 3.7%, of 410 cases<br>
Classification report:<br>
precision    recall  f1-score   support</p>
<pre><code>     CAT       0.47      0.88      0.62       390
     DOG       0.39      0.07      0.12       410

accuracy                           0.47       800
</code></pre>
<p>macro avg       0.43      0.48      0.37       800<br>
weighted avg       0.43      0.47      0.36       800</p>
<p>Confusion matrix:<br>
[[344  46]<br>
[381  29]]</p>
<p>So running the model does not show a reduction in loss, and results in a poorly preforming model. Any suggestions welcome…</p>

ptrblck: <p>The code looks generally alright, so try to play around with some hyperparameters such as the learning rate.<br>
If you get stuck, scale down the problem a bit and try to overfit a small dataset (e.g. just 10 samples) first to make sure there are no hidden bugs in the rest of the code.</p>