I am trying to create a Binary Classifier for dogs and cats. Here is the model of the network:
ConvNet(
(conv1): Conv2d(3, 32, kernel_size=(7, 7), stride=(1, 1))
(max_pool): MaxPool2d(kernel_size=3, stride=3, padding=0, dilation=1, ceil_mode=False)
(conv2): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1))
(avg_pool): AvgPool2d(kernel_size=2, stride=2, padding=0)
(fc1): Linear(in_features=131072, out_features=100, bias=True)
(fc2): Linear(in_features=100, out_features=1, bias=True)
)
This is the code I use to train the network:
loss = nn.BCELoss()
optimizer = optim.RMSprop(net.parameters(), lr=0.001)
for epoch in range(2):
running_loss = 0.0
correct = 0
net.train()
for data, target in training_set:
target = target.float()
optimizer.zero_grad()
output = net(data)
loss = loss(output, target)
loss.backward()
optimizer.step()
running_loss += loss.item()
I am getting this error when calling the line > loss = loss(output, target)
... in binary_cross_entropy
raise ValueError("Target and input must have the same number of elements. target nelement ({}) "
ValueError: Target and input must have the same number of elements. target nelement (32) != input nelement (1)
From what I understand the output of my network is 1 but the labels of the dataset are 32 because of the batch size.
What are the shapes of target
, data
and output
?
target: torch.Size([32])
, data: torch.Size([32, 3, 64, 64])
, and output: torch.Size([1, 1])
I think there’s something wrong happening in your model because your 32 examples that should be ran in parallel disappears into a single example as the output. The output should be torch.size([32, 1])
. Could you show how net
looks like?
That’s also what I suspect but I don’t know how to fix it. Here is the model if you want to see:
class ConvNet(nn.Module):
def __init__(self):
super(ConvNet, self).__init__()
self.conv1 = nn.Conv2d(3, 32, 7)
self.max_pool = nn.MaxPool2d(3)
self.conv2 = nn.Conv2d(32, 64, 3)
self.avg_pool = nn.AvgPool2d(2)
self.fc1 = nn.Linear(64 * 64 * 32, 100) # height * width * batch_size
self.fc2 = nn.Linear(100, 1)
def forward(self, x):
x = self.max_pool(f.relu(self.conv1(x)))
x = self.avg_pool(f.relu(self.conv2(x)))
x = x.view(-1, 64 * 64 * 32)
x = f.relu(self.fc1(x))
x = f.relu(self.fc2(x))
x = f.sigmoid(x)
return x
After the two conv layers the shape is [32, 64, 8, 8]
so when you’re doing .view
the shapes get screwed up. I modified your net to
class ConvNet(nn.Module):
def __init__(self):
super(ConvNet, self).__init__()
self.conv1 = nn.Conv2d(3, 32, 7)
self.max_pool = nn.MaxPool2d(3)
self.conv2 = nn.Conv2d(32, 64, 3)
self.avg_pool = nn.AvgPool2d(2)
self.fc1 = nn.Linear(64*8*8, 100) # height * width * batch_size
self.fc2 = nn.Linear(100, 1)
def forward(self, x):
x = self.max_pool(f.relu(self.conv1(x)))
x = self.avg_pool(f.relu(self.conv2(x)))
x = x.view(-1, 64 * 8 * 8)
x = f.relu(self.fc1(x))
x = f.relu(self.fc2(x))
x = f.sigmoid(x)
return x
1 Like
Wow! Thanks! It works now. 
May I ask how did you get the shape of the conv layers?