Using a target size (torch.Size([3])) that is different to the input size (torch.Size([3, 2]))

I have a 2-class classification problem that implemented with Pytorch, in this model I used the nn.BCELoss () loss function, but when training the model I encounter the following error:

outputs torch.Size([3, 2])
labels torch.Size([3])
/usr/local/lib/python3.7/dist-packages/torch/nn/functional.py:1698: UserWarning: nn.functional.tanh is deprecated. Use torch.tanh instead.
warnings.warn(“nn.functional.tanh is deprecated. Use torch.tanh instead.”)

ValueError Traceback (most recent call last)
in ()
43 print(‘outputs’,outputs.shape)
44 print(‘labels’,labels.shape)
—> 45 loss = criterion(outputs, labels)
46
47 #backward pass

2 frames
/usr/local/lib/python3.7/dist-packages/torch/nn/functional.py in binary_cross_entropy(input, target, weight, size_average, reduce, reduction)
2753 raise ValueError(
2754 "Using a target size ({}) that is different to the input size ({}) is deprecated. "
→ 2755 “Please ensure they have the same size.”.format(target.size(), input.size())
2756 )
2757

ValueError: Using a target size (torch.Size([3])) that is different to the input size (torch.Size([3, 2])) is deprecated. Please ensure they have the same size.

Can anyone guide me to fix this error?

The error points to the shape mismatch in the model output and the target.
Based on your model output shape I assume you are working on a multi-label classification, where each sample can belong to zero, one, or multiple classes (2 in your case based on the shape).
If that’s the case, you would have to make sure that the target has also the same shape.

However, if you are working on a multi-class classification, where each sample belongs to a single class only, you would use e.g. nn.CrossEntropyLoss as the criterion. For this make sure to remove any activation function applied on the output of the model and pass the raw logits to the criterion.

1 Like

Hi, dear ptrblck

can you help me?
I want to use vgg16 pretrained in my model.
I want to give images to the pretrained vgg16 model and give the output of it again to several convolution layers.
But in the forward function, I do not know how to give the image to the pretrained vgg16 .

class attention_block(nn.Module):

def init(self):

super(attention_block, self).__init__()

vgg16 = models.vgg16(pretrained=True)
vgg16.to(device)
for param in vgg16.features.parameters():
param.requires_grad = False

self.Global_1 = nn.Conv2d(512,128,kernel_size=3, padding=1)

self.conv2_bn6= nn.BatchNorm2d(128)

self.Global_2 = nn.Conv2d(128,128,kernel_size=3, padding=1)

self.conv2_bn7= nn.BatchNorm2d(128)

self.Global_features = nn.Conv2d(128,128,kernel_size=1, padding=1)

self.Global_Score = nn.Conv2d(128,2,kernel_size=1, padding=1)

########################################################################
#fully connected

self.fc1 = nn.Linear(10*10* 208, 64)

self.fc2 = nn.Linear(64,32)

self.fc3 = nn.Linear(32,2)

##############################################################################

def forward(self, x):

out = vgg16(x)

Global_Score = self.Global_Score(self.Global_features(F.relu(self.conv2_bn7(self.Global_2(F.relu(self.conv2_bn6(self.Global_1(out))))))))



 # inception module############################################################################################# 

final_out= torch.sigmoid(F.dropout(self.fc3(torch.sigmoid(F.dropout(self.fc2(torch.sigmoid(F.dropout(self.fc1(Global_Score .view(Global_Score .size(0),-1))))))))))



return final_out

In your __init__ method you are not assigning models.vgg16() to a class attribute, but to a local variable vgg16, which would thus not be available in the forward method.
Use self.vgg16 = models.vgg16(pretrained=True) and self.vgg16 in all following operations and it should work.

PS: you can post code snippets by wrapping them into three backticks ```, which makes debugging easier.

thanks ,it works for me.
but I have another problem, I want to delete the linear layers in vgg16 pretrained and use the output tensor of the latest layer of vgg16 pretrained before fc layers, as input of the self.Global_1.
but I got the error :

AttributeError: ‘Sequential’ object has no attribute ‘features’

class attention_block(nn.Module):

def init(self):

super(attention_block, self).init()

self.vgg16 = models.vgg16(pretrained=True) 
self.vgg16 =list(self.vgg16 .children())[0][:-1]

print(self.vgg16)

self.vgg16.to(device)
for param in self.vgg16.features.parameters():
  param.requires_grad = False

self.Global_1 = nn.Conv2d(512,128,kernel_size=3, padding=1)
self.conv2_bn6= nn.BatchNorm2d(128)
self.Global_2 = nn.Conv2d(128,128,kernel_size=3, padding=1)
self.conv2_bn7= nn.BatchNorm2d(128)
self.Global_features = nn.Conv2d(128,128,kernel_size=1, padding=1)
self.Global_Score = nn.Conv2d(128,2,kernel_size=1, padding=1)


############################################################################
#fully connected
self.fc1 = nn.Linear(10*10* 208, 64)
self.fc2 = nn.Linear(64,32)
self.fc3 = nn.Linear(32,2)
##############################################################################

def forward(self, x):
out = self.vgg16(x)
print(out.shape)

Global_Score = self.Global_Score(self.Global_features(F.relu(self.conv2_bn7(self.Global_2(F.relu(self.conv2_bn6(self.Global_1(out))))))))
Global_Score = Global_Score.repeat(1, 64, 1, 1)



final_out= torch.sigmoid(F.dropout(self.fc3(torch.sigmoid(F.dropout(self.fc2(torch.sigmoid(F.dropout(self.fc1(Global_Score .view(Global_Score .size(0),-1))))))))))

return final_out

You are removing all internal attributes by assigning (some) child modules to a list:

self.vgg16 =list(self.vgg16 .children())[0][:-1]

and thus cannot use the .features attribute anymore.
If you want to remove the last linear layer, you could replace it with an nn.Identity module.

Also note, that you should use an nn.ModuleList instead of a list so that all parameters will be registered.

Hi, Thanks
I’m confused and do not know how to correct the code. I do not have much experience in deep. Can you please help me?

class attention_block(nn.Module):

def init(self):

super(attention_block, self).__init__()
self.vgg16 = models.vgg16(pretrained=True) 
self.vgg16.fc = Identity()
print(self.vgg16)

self.vgg16.to(device)
for param in self.vgg16.features.parameters():
  param.requires_grad = False

self.Global_1 = nn.Conv2d(512,128,kernel_size=3, padding=1)
self.conv2_bn6= nn.BatchNorm2d(128)
self.Global_2 = nn.Conv2d(128,128,kernel_size=3, padding=1)
self.conv2_bn7= nn.BatchNorm2d(128)
self.Global_features = nn.Conv2d(128,128,kernel_size=1, padding=1)
self.Global_Score = nn.Conv2d(128,2,kernel_size=1, padding=1)

#######################################################################
#fully connected

self.fc1 = nn.Linear(10*10* 208, 64)

self.fc2 = nn.Linear(64,32)

self.fc3 = nn.Linear(32,2)

########################################################################

def forward(self, x):

out = self.vgg16(x)
print(out.shape)
Global_Score = self.Global_Score(self.Global_features(F.relu(self.Global_2(F.relu(self.Global_1(out))))))
Global_Score = Global_Score.repeat(1, 64, 1, 1)

final_out= torch.sigmoid(F.dropout(self.fc3(torch.sigmoid(F.dropout(self.fc2(torch.sigmoid(F.dropout(self.fc1(Global_Score .view(Global_Score .size(0),-1))))))))))

return final_out

I changed the code as follows:
Now I want to give the output to the self.Global_1 convolution layer, but the output size of vgg is [3,100] but the input for self.Global_2 is [128, 512, 3, 3].How can I fix it?

errpr:
RuntimeError: Expected 4-dimensional input for 4-dimensional weight [128, 512, 3, 3], but got 2-dimensional input of size [3, 1000] instead

class Identity(nn.Module):

def __init__(self):

    super(Identity, self).__init__()     

def forward(self, x):

    return x

vgg16 = models.vgg16(pretrained=True)
vgg16.fc = Identity()
vgg16.to(device)
for param in vgg16.features.parameters():
param.requires_grad = False
print(vgg16)

class attention_block(nn.Module):
def init(self):
super(attention_block, self).init()

self.Global_1 = nn.Conv2d(512,128,kernel_size=3, padding=1)
self.conv2_bn6= nn.BatchNorm2d(128)
self.Global_2 = nn.Conv2d(128,128,kernel_size=3, padding=1)
self.conv2_bn7= nn.BatchNorm2d(128)
self.Global_features = nn.Conv2d(128,128,kernel_size=1, padding=1)
self.Global_Score = nn.Conv2d(128,2,kernel_size=1, padding=1)


#fully connected

self.fc1 = nn.Linear(10*10* 208, 64)
self.fc2 = nn.Linear(64,32)
self.fc3 = nn.Linear(32,2)
########################################################################

def forward(self, x):
out = vgg16(x)
print(out.shape)
Global_Score = self.Global_Score(self.Global_features(F.relu(self.Global_2(F.relu(self.Glo bal_1(out))))))

Global_Score = Global_Score.repeat(1, 64, 1, 1)

final_out= torch.sigmoid(F.dropout(self.fc3(torch.sigmoid(F.dropout(self.fc2(torch.sigmoid(F.dropout(self.fc1(Global_Score .view(Global_Score .size(0),-1))))))))))



return final_out