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

username: nafise
cooked: <p>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:</p>
<h2>
<a name="outputs-torchsize3-2-labels-torchsize3-usrlocallibpython37dist-packagestorchnnfunctionalpy1698-userwarning-nnfunctionaltanh-is-deprecated-use-torchtanh-instead-warningswarnnnfunctionaltanh-is-deprecated-use-torchtanh-instead" class="anchor" href="#outputs-torchsize3-2-labels-torchsize3-usrlocallibpython37dist-packagestorchnnfunctionalpy1698-userwarning-nnfunctionaltanh-is-deprecated-use-torchtanh-instead-warningswarnnnfunctionaltanh-is-deprecated-use-torchtanh-instead"></a>outputs torch.Size([3, 2])<br>
labels torch.Size([3])<br>
/usr/local/lib/python3.7/dist-packages/torch/nn/functional.py:1698: UserWarning: nn.functional.tanh is deprecated. Use torch.tanh instead.<br>
warnings.warn(“nn.functional.tanh is deprecated. Use torch.tanh instead.”)</h2>
<p>ValueError                                Traceback (most recent call last)<br>
 in ()<br>
43         print(‘outputs’,outputs.shape)<br>
44         print(‘labels’,labels.shape)<br>
—&gt; 45         loss = criterion(outputs, labels)<br>
46<br>
47         <span class="hashtag">#backward</span> pass</p>
<p>2 frames<br>
/usr/local/lib/python3.7/dist-packages/torch/nn/functional.py in binary_cross_entropy(input, target, weight, size_average, reduce, reduction)<br>
2753         raise ValueError(<br>
2754             "Using a target size ({}) that is different to the input size ({}) is deprecated. "<br>
 → 2755             “Please ensure they have the same size.”.format(target.size(), input.size())<br>
2756         )<br>
2757</p>
<p>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.</p>
<p>Can anyone guide me to fix this error?</p>

username: ptrblck
cooked: <p>The error points to the shape mismatch in the model output and the target.<br>
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).<br>
If that’s the case, you would have to make sure that the target has also the same shape.</p>
<p>However, if you are working on a multi-class classification, where each sample belongs to a single class only, you would use e.g. <code>nn.CrossEntropyLoss</code> 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.</p>

username: nafise
cooked: <p>Hi, dear ptrblck</p>
<p>can you help me?<br>
I want to use vgg16 pretrained  in my model.<br>
I want to give  images to the pretrained vgg16 model and give the output of it again to several convolution layers.<br>
But in the forward function, I do not know how to give the image to the pretrained vgg16 .</p>
<p>class attention_block(nn.Module):</p>
<p>def <strong>init</strong>(self):</p>
<pre><code>super(attention_block, self).__init__()
</code></pre>
<p>vgg16 = models.vgg16(pretrained=True)<br>
vgg16.to(device)<br>
for param in vgg16.features.parameters():<br>
param.requires_grad = False</p>
<pre><code>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)

##############################################################################
</code></pre>
<p>def forward(self, x):</p>
<pre><code>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</code></pre>

username: ptrblck
cooked: <p>In your <code>__init__</code> method you are not assigning <code>models.vgg16()</code> to a class attribute, but to a local variable <code>vgg16</code>, which would thus not be available in the <code>forward</code> method.<br>
Use <code>self.vgg16 = models.vgg16(pretrained=True)</code> and <code>self.vgg16</code> in all following operations and it should work.</p>
<p>PS: you can post code snippets by wrapping them into three backticks ```, which makes debugging easier.</p>

username: nafise
cooked: <p>thanks ,it works for me.<br>
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.<br>
but I got the error :</p>
<p>AttributeError: ‘Sequential’ object has no attribute ‘features’</p>
<p>class attention_block(nn.Module):</p>
<p>def <strong>init</strong>(self):</p>
<p>super(attention_block, self).<strong>init</strong>()</p>
<pre><code>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)
##############################################################################
</code></pre>
<p>def forward(self, x):<br>
out = self.vgg16(x)<br>
print(out.shape)</p>
<pre><code>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</code></pre>

username: ptrblck
cooked: <p>You are removing all internal attributes by assigning (some) child modules to a <code>list</code>:</p>
<pre><code class="lang-python">self.vgg16 =list(self.vgg16 .children())[0][:-1]
</code></pre>
<p>and thus cannot use the <code>.features</code> attribute anymore.<br>
If you want to remove the last linear layer, you could replace it with an <code>nn.Identity</code> module.</p>
<p>Also note, that you should use an <code>nn.ModuleList</code> instead of a <code>list</code> so that all parameters will be registered.</p>

username: nafise
cooked: <p>Hi, Thanks<br>
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?</p>
<p>class attention_block(nn.Module):</p>
<p>def <strong>init</strong>(self):</p>
<pre><code>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)

########################################################################
</code></pre>
<p>def forward(self, x):</p>
<pre><code>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</code></pre>

username: nafise
cooked: <p>I changed the code as follows:<br>
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?</p>
<p>errpr:<br>
RuntimeError: Expected 4-dimensional input for 4-dimensional weight [128, 512, 3, 3], but got 2-dimensional input of size [3, 1000] instead</p>
<p>class Identity(nn.Module):</p>
<pre><code>def __init__(self):

    super(Identity, self).__init__()     

def forward(self, x):

    return x
</code></pre>
<p>vgg16 = models.vgg16(pretrained=True)<br>
vgg16.fc = Identity()<br>
vgg16.to(device)<br>
for param in vgg16.features.parameters():<br>
param.requires_grad = False<br>
print(vgg16)</p>
<p>class attention_block(nn.Module):<br>
def <strong>init</strong>(self):<br>
super(attention_block, self).<strong>init</strong>()</p>
<pre><code>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)
########################################################################
</code></pre>
<p>def forward(self, x):<br>
out = vgg16(x)<br>
print(out.shape)<br>
Global_Score = self.Global_Score(self.Global_features(F.relu(self.Global_2(F.relu(self.Glo bal_1(out))))))</p>
<pre><code>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</code></pre>