Hi guys.
I’m training a convNet on gray-scale 224*224 images with 2 classes.
This is my convNet:
class Frequentist_CNN(ModuleWrapper):
    def __init__(self, outputs, inputs):
        super(Frequentist_CNN, self).__init__()

        self.num_classes = outputs
        self.num_channels = inputs

        self.layer1 = nn.Sequential(
            nn.Conv2d(inputs, 6, kernel_size=5, stride=1, padding=2),
            nn.Softplus(),
            nn.MaxPool2d(kernel_size=2, stride=2))
        self.layer2 = nn.Sequential(
            nn.Conv2d(6, 16, kernel_size=5, stride=1, padding=0),
            nn.Softplus(),
            nn.MaxPool2d(kernel_size=2, stride=2))
        self.layer3 = nn.Sequential(
            nn.Conv2d(16, 16, kernel_size=5, stride=1, padding=1),
            nn.Softplus(),
            nn.MaxPool2d(kernel_size=3, stride=2))
        
        self.flatten = FlattenLayer(25)
        self.fc1 = nn.Linear(25, 1000)
        self.act1 = nn.Softplus()
        self.fc2 = nn.Linear(1000, 500)
        self.act2 = nn.Softplus()
        self.fc3 = nn.Linear(500, outputs)

    def forward(self, x):
        out = self.layer1(x)
        out = self.layer2(out)
        out = self.layer3(out)
        # out = out.view(1, -1)
        out = self.fc1(out)
        #out = nn.Softplus(self.fc2(out))
        #out = nn.Softplus(self.fc3(out))
        out = self.fc2(out)
        out = self.fc3(out)
        return out

And I’m running the training loop:
# Train the model

freq_net = Frequentist_CNN(num_classes, num_channels)#.to(device)

# Loss and optimizer
criterion = nn.BCELoss()
optimizer = torch.optim.Adam(freq_net.parameters(), lr=0.01)

total_step = len(train_loader)
loss_list = []
acc_list = []
for epoch in range(n_epochs):
    for i, (images, labels) in enumerate(train_loader):
        # Run the forward pass
        print("Images have shape: {}".format(images.shape))
        # images, labels = images.to(device), labels.to(device)
        #labels = labels.unsqueeze(1)
        outputs = freq_net(images)
        #outputs = outputs.argmax(dim=1, keepdim=True)
        print("Outputs have shape: {}".format(outputs.shape))
        print("Labels have shape: {}".format(labels.shape))

        loss = criterion(outputs, labels)
        loss_list.append(loss.item())

        # Backprop and perform Adam optimisation
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        # Track the accuracy
        total = labels.size(0)
        _, predicted = torch.max(outputs.data, 1)
        correct = (predicted == labels).sum().item()
        acc_list.append(correct / total)

        if (i + 1) % 100 == 0:
            print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}, Accuracy: {:.2f}%'
                  .format(epoch + 1, num_epochs, i + 1, total_step, loss.item(),
                          (correct / total) * 100))

Giving me the output AND error:
(Notice the shapes)
Images have shape: torch.Size([32, 1, 224, 224])
Outputs have shape: torch.Size([32, 16, 25, 2])
Labels have shape: torch.Size([32])


/usr/local/lib/python3.6/dist-packages/torch/nn/modules/loss.py:516: UserWarning: Using a target size (torch.Size([32])) that is different to the input size (torch.Size([32, 16, 25, 2])) is deprecated. Please ensure they have the same size.
  return F.binary_cross_entropy(input, target, weight=self.weight, reduction=self.reduction)

...

ValueError: Target and input must have the same number of elements. target nelement (32) != input nelement (25600)

As you can see, I’ve tried unsqueezing labels, training on the GPU… I’ve also tried CrossEntropyLoss(). That didn’t work either.
Does anybody have any idea why this may be happening?
Thanks so much! 
John