Error with CNN, mismatch between target and input size

username: Surpuissant
cooked: <p>Hi there,</p>
<p>I am trying to implement my first CNN to classify pathological and healthy images.<br>
During the training, I have an error that I can’t correct.<br>
Despite searching on google I can’t find a solution.<br>
Is there a kind soul who could help me? <img src="https://discuss.pytorch.org/images/emoji/apple/innocent.png?v=12" title=":innocent:" class="emoji" alt=":innocent:" loading="lazy" width="20" height="20"> <img src="https://discuss.pytorch.org/images/emoji/apple/pray.png?v=12" title=":pray:" class="emoji" alt=":pray:" loading="lazy" width="20" height="20"></p>
<p>The code is as follows:</p>
<blockquote>
<p><span class="hashtag-raw">#def</span> train_net(n_epoch): # Training our network<br>
losses = <span class="chcklst-box fa fa-square-o fa-fw"></span><br>
for epoch in range(n_epoch):  # loop over the dataset multiple times<br>
running_loss = 0.0<br>
for i, data in enumerate(train, 0):<br>
# get the inputs; data is a list of [inputs, labels]<br>
inputs, labels = data</p>
</blockquote>
<pre><code>    # zero the parameter gradients
    optimizer.zero_grad()

    # forward + backward + optimize
    
    outputs = model(inputs)
    loss = criterion(outputs, labels)
    loss.backward()
    optimizer.step()

    # print statistics
    losses.append(loss)
    running_loss += loss.item()
    if i % 100 == 99:  # print every 2000 mini-batches
        print('[%d, %5d] loss: %.10f' %
              (epoch + 1, i + 1, running_loss / 2000))
        running_loss = 0.0
</code></pre>
<blockquote>
<p>plt.plot(losses, label=‘Training loss’)<br>
plt.show()</p>
</blockquote>
<blockquote>
<p>ValueError                                Traceback (most recent call last)<br>
/var/folders/7x/f_g9k1797vn0y8xdfwzz10gc0000gn/T/ipykernel_71356/646090411.py in <br>
13<br>
14         outputs = model(inputs)<br>
—&gt; 15         loss = criterion(outputs, labels)<br>
16         loss.backward()<br>
17         optimizer.step()</p>
</blockquote>
<blockquote>
<p>~/opt/anaconda3/lib/python3.9/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)<br>
1108         if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks<br>
1109                 or _global_forward_hooks or _global_forward_pre_hooks):<br>
 → 1110             return forward_call(*input, **kwargs)<br>
1111         # Do not call functions when jit is used<br>
1112         full_backward_hooks, non_full_backward_hooks = <span class="chcklst-box fa fa-square-o fa-fw"></span>, <span class="chcklst-box fa fa-square-o fa-fw"></span></p>
</blockquote>
<blockquote>
<p>~/opt/anaconda3/lib/python3.9/site-packages/torch/nn/modules/loss.py in forward(self, input, target)<br>
610<br>
611     def forward(self, input: Tensor, target: Tensor) → Tensor:<br>
 → 612         return F.binary_cross_entropy(input, target, weight=self.weight, reduction=self.reduction)<br>
613<br>
614</p>
</blockquote>
<blockquote>
<p>~/opt/anaconda3/lib/python3.9/site-packages/torch/nn/functional.py in binary_cross_entropy(input, target, weight, size_average, reduce, reduction)<br>
3054         reduction_enum = _Reduction.get_enum(reduction)<br>
3055     if target.size() != input.size():<br>
 → 3056         raise ValueError(<br>
3057             "Using a target size ({}) that is different to the input size ({}) is deprecated. "<br>
3058             “Please ensure they have the same size.”.format(target.size(), input.size())</p>
</blockquote>
<blockquote>
<p>ValueError: Using a target size (torch.Size([32])) that is different to the input size (torch.Size([32, 1, 128, 2])) is deprecated. Please ensure they have the same size.</p>
</blockquote>

username: ptrblck
cooked: <p>Based on the error message it seems your model is returning a 4-dimensional output in the shape <code>[32, 1, 128, 2]</code> while the target has the shape <code>[32]</code>. If you are working on a binary classification use case using <code>nn.BCEWithLogitsLoss</code>, make sure both outputs have the shape <code>[batch_size, 1]</code>. If not, could you explain your use case a bit more and what the shapes represent, please?</p>

username: Surpuissant
cooked: <p>Thank you very much for your answer.<br>
I am trying  to make a CNN that classifies images as pathological or healthy.<br>
If the network works I would like to use “class activation map” that requires the last convolutional layer to have average pooling before the fully connected layer.</p>
<p>Here is the dataloader code</p>
<blockquote>
<p>transform = transforms.Compose([<br>
transforms.RandomRotation(10),<br>
transforms.RandomResizedCrop(128),<br>
transforms.RandomHorizontalFlip(),<br>
transforms.Grayscale(),<br>
transforms.ToTensor()])</p>
</blockquote>
<blockquote>
<p>train_set = datasets.ImageFolder(data_dir + ‘/train’, transform = transform)<br>
test_set = datasets.ImageFolder(data_dir + ‘/test’, transform = transform)</p>
</blockquote>
<blockquote>
<p>train = DataLoader(train_set ,batch_size = 32, shuffle = True)<br>
test = DataLoader(test_set ,batch_size = 32, shuffle = True)</p>
</blockquote>
<p>and the neural network code :</p>
<blockquote>
<p>class Net(nn.Module):</p>
</blockquote>
<blockquote>
<p>def <strong>init</strong>(self):<br>
super(Net, self).<strong>init</strong>()<br>
self.conv1 = nn.Conv2d(1, 32, 5)<br>
self.pool = nn.MaxPool2d(kernel_size= 2, stride= 2)<br>
self.AvPool = nn.AvgPool2d(kernel_size= 2, stride= 2)<br>
self.conv2 = nn.Conv2d(32, 64, 5)<br>
self.fc1 = nn.Linear(64<em>29</em>29, 100)<br>
self.fc2 = nn.Linear(100, 50)<br>
self.fc3 = nn.Linear(50, 2)</p>
</blockquote>
<pre><code>def forward(self, x):
    print(x.shape) #torch.Size([32, 1, 128, 128])
    x = self.pool(F.mish(self.conv1(x)))
    print(x.shape) #torch.Size([32, 32, 62, 62])
    x = self.AvPool(F.mish(self.conv2(x)))
    print(x.shape) #torch.Size([32, 64, 29, 29])
    x = x.view(-1, 64*29*29)
    print(x.shape) #torch.Size([107648, 16])
    x = F.mish(self.fc1(x))
    print(x.shape)
    x = F.mish(self.fc2(x))
    x = self.fc3(x)
    return x
</code></pre>
<p>Thanks again for your help</p>

username: ptrblck
cooked: <p>The model architecture looks generally alright and should return a 2-dimensional output which doesn’t match your error message, so double check your code.</p>
<p>A minor issue: your flattening seems to be wrong:</p>
<pre><code class="lang-python">    print(x.shape) #torch.Size([32, 64, 29, 29])
    x = x.view(-1, 64*29*29)
    print(x.shape) #torch.Size([107648, 16])
</code></pre>
<p>since you are changing the batch size.<br>
Use <code>x = x.view(x.size(0), -1)</code> to flatten the activation and to keep the batch size equal.</p>

username: Surpuissant
cooked: <p>Thanks again.<br>
I still have this error…</p>
<p>Here is the entiere code :</p>
<blockquote>
<p>import matplotlib.pyplot as plt<br>
from torchvision import datasets, transforms<br>
from torch.utils.data import DataLoader<br>
import torch.nn as nn<br>
import torch.nn.functional as F<br>
import torch.optim as optim<br>
import torch<br>
import pandas as pd</p>
</blockquote>
<blockquote>
<p><span class="hashtag-raw">#def</span> get_data():<br>
data_dir = ‘/Users/kevin/Downloads/OCT2022_ter’</p>
</blockquote>
<blockquote>
<p>transform = transforms.Compose([<br>
transforms.RandomRotation(10),<br>
transforms.RandomResizedCrop(128),<br>
transforms.RandomHorizontalFlip(),<br>
transforms.Grayscale(),<br>
transforms.ToTensor()])</p>
</blockquote>
<p>train_set = datasets.ImageFolder(data_dir + ‘/train’, transform = transform)<br>
test_set = datasets.ImageFolder(data_dir + ‘/test’, transform = transform)</p>
<blockquote>
<p>train = DataLoader(train_set ,batch_size = 32, shuffle = True)<br>
test = DataLoader(test_set ,batch_size = 32, shuffle = True)</p>
</blockquote>
<blockquote>
<p><span class="hashtag-raw">#return</span> train, test</p>
</blockquote>
<blockquote>
<p>classes = (‘Control’, ‘Pathos’) # Defining the classes we have<br>
dataiter = iter(train)<br>
images, labels = dataiter.next()<br>
fig, axes = plt.subplots(figsize=(10, 4), ncols=5)<br>
for i in range(5):<br>
ax = axes[i]<br>
ax.imshow(images[i].permute(1, 2, 0))<br>
ax.title.set_text(’ ‘.join(’%5s’ % classes[labels[i]]))<br>
plt.show()</p>
</blockquote>
<blockquote>
<p>class Net(nn.Module):</p>
</blockquote>
<blockquote>
<p>def <strong>init</strong>(self):<br>
super(Net, self).<strong>init</strong>()<br>
self.conv1 = nn.Conv2d(1, 32, 5)<br>
self.pool = nn.MaxPool2d(kernel_size= 2, stride= 2)<br>
self.AvPool = nn.AvgPool2d(kernel_size= 2, stride= 2)<br>
self.conv2 = nn.Conv2d(32, 64, 5)<br>
self.fc1 = nn.Linear(64<em>29</em>29, 100)<br>
self.fc2 = nn.Linear(100, 50)<br>
self.fc3 = nn.Linear(50, 2)</p>
</blockquote>
<blockquote>
<p>def forward(self, x):<br>
print(x.shape) <span class="hashtag-raw">#torch</span>.Size([32, 1, 128, 128])<br>
x = self.pool(F.mish(self.conv1(x)))<br>
print(x.shape) <span class="hashtag-raw">#torch</span>.Size([32, 32, 62, 62])<br>
x = self.AvPool(F.mish(self.conv2(x)))<br>
print(x.shape) <span class="hashtag-raw">#torch</span>.Size([32, 64, 29, 29])<br>
x = x.view(x.size(0), -1)<br>
print(x.shape) <span class="hashtag-raw">#torch</span>.Size([107648, 16])<br>
x = F.mish(self.fc1(x))<br>
print(x.shape)<br>
x = F.mish(self.fc2(x))<br>
x = self.fc3(x)<br>
return x</p>
</blockquote>
<blockquote>
<p>model = Net()<br>
learning_rate = 0.01<br>
criterion = nn.BCELoss()<br>
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)<br>
n_epoch = 100</p>
</blockquote>
<blockquote>
<p><span class="hashtag-raw">#def</span> train_net(n_epoch): # Training our network<br>
losses = <span class="chcklst-box fa fa-square-o fa-fw"></span><br>
for epoch in range(n_epoch):  # loop over the dataset multiple times<br>
running_loss = 0.0<br>
for i, data in enumerate(train, 0):<br>
# get the inputs; data is a list of [inputs, labels]<br>
inputs, labels = data</p>
</blockquote>
<pre><code>    # zero the parameter gradients
    optimizer.zero_grad()

    # forward + backward + optimize
    
    outputs = model(inputs)
    loss = criterion(outputs, labels)
    loss.backward()
    optimizer.step()

    # print statistics
    losses.append(loss)
    running_loss += loss.item()
    if i % 100 == 99:  # print every 2000 mini-batches
        print('[%d, %5d] loss: %.10f' %
              (epoch + 1, i + 1, running_loss / 2000))
        running_loss = 0.0
</code></pre>
<blockquote>
<p>plt.plot(losses, label=‘Training loss’)<br>
plt.show()<br>
print(‘Finished Training’)</p>
</blockquote>
<blockquote>
<hr>
<p>ValueError                                Traceback (most recent call last)<br>
/var/folders/7x/f_g9k1797vn0y8xdfwzz10gc0000gn/T/ipykernel_71356/646090411.py in <br>
13<br>
14         outputs = model(inputs)<br>
—&gt; 15         loss = criterion(outputs, labels)<br>
16         loss.backward()<br>
17         optimizer.step()</p>
</blockquote>
<blockquote>
<p>~/opt/anaconda3/lib/python3.9/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)<br>
1108         if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks<br>
1109                 or _global_forward_hooks or _global_forward_pre_hooks):<br>
 → 1110             return forward_call(*input, **kwargs)<br>
1111         # Do not call functions when jit is used<br>
1112         full_backward_hooks, non_full_backward_hooks = <span class="chcklst-box fa fa-square-o fa-fw"></span>, <span class="chcklst-box fa fa-square-o fa-fw"></span></p>
</blockquote>
<blockquote>
<p>~/opt/anaconda3/lib/python3.9/site-packages/torch/nn/modules/loss.py in forward(self, input, target)<br>
610<br>
611     def forward(self, input: Tensor, target: Tensor) → Tensor:<br>
 → 612         return F.binary_cross_entropy(input, target, weight=self.weight, reduction=self.reduction)<br>
613<br>
614</p>
</blockquote>
<blockquote>
<p>~/opt/anaconda3/lib/python3.9/site-packages/torch/nn/functional.py in binary_cross_entropy(input, target, weight, size_average, reduce, reduction)<br>
3054         reduction_enum = _Reduction.get_enum(reduction)<br>
3055     if target.size() != input.size():<br>
 → 3056         raise ValueError(<br>
3057             "Using a target size ({}) that is different to the input size ({}) is deprecated. "<br>
3058             “Please ensure they have the same size.”.format(target.size(), input.size())</p>
</blockquote>
<blockquote>
<p>ValueError: Using a target size (torch.Size([32])) that is different to the input size (torch.Size([32, 2])) is deprecated. Please ensure they have the same size.</p>
</blockquote>
<p>Maybe the problem is with Dataloader or my images ? I dont’ understand…</p>

username: ptrblck
cooked: <p>An output size of <code>[batch_size, 2]</code> can be used for a 2-class mutli-class classification with <code>nn.CrossEntropyLoss</code> which would then expect a target in the shape <code>[batch_size]</code> containing class indices in <code>[0, 1]</code>. If you want to use <code>nn.BCEWithLogitsLoss</code> for a binary classification, make sure your model outputs a single logit in <code>[batch_size, 1]</code> and also make sure the target has the same shape.</p>

username: Surpuissant
cooked: <p>It seems to work with CrossEntropyLoss<br>
Thank you very much !</p>