Batch size mismatch

MA_CASANDRA_QUILANG: <p>Hi. I am really new to deep learning and I am trying to create a school project using ESNet architecture. But this time I just want to test with a sample dataset (Cats VS Dogs) but I keep on getting the error:</p>
<p>Expected input batch_size (4) to match target batch_size (1).</p>

MA_CASANDRA_QUILANG: <p>THIS IS THE ARCHITECTURE THAT I USED</p>
<p><span class="hashtag">#ESNet:</span> An Efficient Symmetric Network for Real-time Semantic Segmentation</p>
<p><span class="hashtag">#Paper-Link:</span> <a href="https://arxiv.org/pdf/1906.09826.pdf" rel="noopener nofollow ugc">https://arxiv.org/pdf/1906.09826.pdf</a></p>
<p>###################################################################################################</p>
<p>import torch</p>
<p>import torch.nn as nn</p>
<p>import torch.nn.init as init</p>
<p>import torch.nn.functional as F</p>
<p>from torchsummary import summary</p>
<p>class DownsamplerBlock(nn.Module):</p>
<pre><code>def __init__(self, ninput, noutput):

    super().__init__()

    self.conv = nn.Conv2d(ninput, noutput-ninput, (3, 3), stride=2, padding=1, bias=True)

    self.pool = nn.MaxPool2d(2, stride=2)

    self.bn = nn.BatchNorm2d(noutput, eps=1e-3)

    self.relu = nn.ReLU(inplace=True)

def forward(self, input):

    x1 = self.pool(input)

    x2 = self.conv(input)

  

    diffY = x2.size()[2] - x1.size()[2]

    diffX = x2.size()[3] - x1.size()[3]

    x1 = F.pad(x1, [diffX // 2, diffX - diffX // 2,

                    diffY // 2, diffY - diffY // 2])

    print(x1.shape)

    output = torch.cat([x2, x1], 1)

    output = self.bn(output)

    output = self.relu(output)

    return output
</code></pre>
<p>class UpsamplerBlock (nn.Module):</p>
<pre><code>def __init__(self, ninput, noutput):

    super().__init__()

    self.conv = nn.ConvTranspose2d(ninput, noutput, 3, stride=2, padding=1, output_padding=1, bias=True)

    self.bn = nn.BatchNorm2d(noutput, eps=1e-3)

def forward(self, input):

    output = self.conv(input)

    output = self.bn(output)

    return F.relu(output)
</code></pre>
<p>class FCU(nn.Module):</p>
<pre><code>def __init__(self, chann, kernel_size,dropprob, dilated): 

    """

    Factorized Convolution Unit

    """     

    super(FCU,self).__init__()

    padding = int((kernel_size-1)//2) * dilated

    self.conv3x1_1 = nn.Conv2d(chann, chann, (kernel_size,1), stride=1, padding=(int((kernel_size-1)//2)*1,0), bias=True)

    self.conv1x3_1 = nn.Conv2d(chann, chann, (1,kernel_size), stride=1, padding=(0,int((kernel_size-1)//2)*1), bias=True)

    self.bn1 = nn.BatchNorm2d(chann, eps=1e-03)

    self.conv3x1_2 = nn.Conv2d(chann, chann, (kernel_size,1), stride=1, padding=(padding,0), bias=True, dilation = (dilated,1))

    self.conv1x3_2 = nn.Conv2d(chann, chann, (1,kernel_size), stride=1, padding=(0,padding), bias=True, dilation = (1, dilated))

    self.bn2 = nn.BatchNorm2d(chann, eps=1e-03)

    

    self.relu = nn.ReLU(inplace = True)

    self.dropout = nn.Dropout2d(dropprob)

    

def forward(self, input):

    residual = input

    output = self.conv3x1_1(input)

    output = self.relu(output)

    output = self.conv1x3_1(output)

    output = self.bn1(output)

    output = self.relu(output)

    output = self.conv3x1_2(output)

    output = self.relu(output)

    output = self.conv1x3_2(output)

    output = self.bn2(output)   

    if (self.dropout.p != 0):

        output = self.dropout(output)

    

    return F.relu(residual+output,inplace=True) 
</code></pre>
<p>class PFCU(nn.Module):</p>
<pre><code>def __init__(self,chann):

    """

    Parallel Factorized Convolution Unit

    """         



    super(PFCU,self).__init__()

    

    self.conv3x1_1 = nn.Conv2d(chann, chann, (3,1), stride=1, padding=(1,0), bias=True)

    self.conv1x3_1 = nn.Conv2d(chann, chann, (1,3), stride=1, padding=(0,1), bias=True)

    self.bn1 = nn.BatchNorm2d(chann, eps=1e-03)

    self.conv3x1_22 = nn.Conv2d(chann, chann, (3,1), stride=1, padding=(2,0), bias=True, dilation = (2,1))

    self.conv1x3_22 = nn.Conv2d(chann, chann, (1,3), stride=1, padding=(0,2), bias=True, dilation = (1,2))

    self.conv3x1_25 = nn.Conv2d(chann, chann, (3,1), stride=1, padding=(5,0), bias=True, dilation = (5,1))

    self.conv1x3_25 = nn.Conv2d(chann, chann, (1,3), stride=1, padding=(0,5), bias=True, dilation = (1,5))

    self.conv3x1_29 = nn.Conv2d(chann, chann, (3,1), stride=1, padding=(9,0), bias=True, dilation = (9,1))

    self.conv1x3_29 = nn.Conv2d(chann, chann, (1,3), stride=1, padding=(0,9), bias=True, dilation = (1,9))

    self.bn2 = nn.BatchNorm2d(chann, eps=1e-03)

    self.dropout = nn.Dropout2d(0.3)

def forward(self, input):

    residual = input

    output = self.conv3x1_1(input)

    output = F.relu(output)

    output = self.conv1x3_1(output)

    output = self.bn1(output)

    output = F.relu(output)

    output2 = self.conv3x1_22(output)

    output2 = F.relu(output2)

    output2 = self.conv1x3_22(output2)

    output2 = self.bn2(output2)

    if (self.dropout.p != 0):

        output2 = self.dropout(output2)

    output5 = self.conv3x1_25(output)

    output5 = F.relu(output5)

    output5 = self.conv1x3_25(output5)

    output5 = self.bn2(output5)

    if (self.dropout.p != 0):

        output5 = self.dropout(output5)

    output9 = self.conv3x1_29(output)

    output9 = F.relu(output9)

    output9 = self.conv1x3_29(output9)

    output9 = self.bn2(output9)

    if (self.dropout.p != 0):

        output9 = self.dropout(output9)

    return F.relu(residual+output2+output5+output9,inplace=True)
</code></pre>
<p>class ESNet(nn.Module):</p>
<pre><code>def __init__(self, classes):

    super().__init__()

    #-----ESNET---------#

    self.initial_block = DownsamplerBlock(1, 16)

    self.layers = nn.ModuleList()

    

    for x in range(0, 3):

       self.layers.append(FCU(16, 3, 0.03, 1))  

    

    self.layers.append(DownsamplerBlock(16,64))

    for x in range(0, 2):

       self.layers.append(FCU(64, 5, 0.03, 1))  

    self.layers.append(DownsamplerBlock(64,128))

    for x in range(0, 3):   

        self.layers.append(PFCU(chann=128)) 

    self.layers.append(UpsamplerBlock(128,64))

    self.layers.append(FCU(64, 5, 0, 1))

    self.layers.append(FCU(64, 5, 0, 1))

    self.layers.append(UpsamplerBlock(64,16))

    self.layers.append(FCU(16, 3, 0, 1))

    self.layers.append(FCU(16, 3, 0, 1))

    self.output_conv = nn.ConvTranspose2d( 16, classes, 2, stride=2, padding=0, output_padding=0, bias=True)

def forward(self, input):

    output = self.initial_block(input)

    for layer in self.layers:

        output = layer(output)

    output = self.output_conv(output)

  

    return output
</code></pre>
<p>“”“print layers and params of network”""</p>
<p>if <strong>name</strong> == ‘<strong>main</strong>’:</p>
<pre><code>device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

model = ESNet(classes=2).to(device)

summary(model,(1,100,100))</code></pre>

MA_CASANDRA_QUILANG: <p>and this is the rest of my code:</p>
<p>import numpy as np</p>
<p>from tqdm import tqdm</p>
<p>import torch.optim as optim</p>
<p>training_data = np.load("/content/thirdy/training_data_grayscale.npy", allow_pickle = True)</p>
<p>x = torch.Tensor([i[0] for i in training_data]).view(-1, 100, 100)</p>
<p>y = torch.Tensor([i[1] for i in training_data])</p>
<p>VAL_PCT = 0.1</p>
<p>val_size = int(len(x)*VAL_PCT)</p>
<p>print(val_size)</p>
<p>train_x = x[:-val_size]</p>
<p>train_y = y[:-val_size]</p>
<p>test_x = x[-val_size:]</p>
<p>test_y = y[-val_size:]</p>
<p>import torch.optim as optim</p>
<p>optimizer = optim.Adam(model.parameters(), lr = 0.001)</p>
<p>loss_function = nn.CrossEntropyLoss()</p>
<p>BATCH_SIZE = 1</p>
<p>EPOCHS = 1</p>
<p>for epoch in range(EPOCHS):</p>
<pre><code>for i in tqdm(range(0, len(train_x), BATCH_SIZE)): 

    batch_x = train_x[i:i+BATCH_SIZE].view(-1, 1, 50, 50)

    print(batch_x.shape)

    batch_y = train_y[i:i+BATCH_SIZE]

    print(batch_y.shape)

    model.zero_grad()

    outputs = model(batch_x)

    loss = loss_function(outputs, batch_y)

    loss.backward()

    optimizer.step()    # Does the update

print(f"Epoch: {epoch}. Loss: {loss}")</code></pre>

MA_CASANDRA_QUILANG: <p>and this is the error I always get no matter how i try to apply the suggestions i found online:</p>
<p>0%|          | 0/22452 [00:00&lt;?, ?it/s]torch.Size([4, 1, 50, 50])<br>
torch.Size([1, 2])<br>
torch.Size([4, 2, 56, 56])</p>
<hr>
<p>ValueError                                Traceback (most recent call last)<br>
 in ()<br>
13         outputs = model(batch_x)<br>
14         outputs = outputs.squeeze(0)<br>
—&gt; 15         loss = loss_function(outputs, batch_y)<br>
16         loss.backward()<br>
17         optimizer.step()    # Does the update</p>
<p>3 frames<br>
/usr/local/lib/python3.6/dist-packages/torch/nn/functional.py in nll_loss(input, target, weight, size_average, ignore_index, reduce, reduction)<br>
2214     if input.size(0) != target.size(0):<br>
2215         raise ValueError(‘Expected input batch_size ({}) to match target batch_size ({}).’<br>
-&gt; 2216                          .format(input.size(0), target.size(0)))<br>
2217     if dim == 2:<br>
2218         ret = torch._C._nn.nll_loss(input, target, weight, _Reduction.get_enum(reduction), ignore_index)</p>
<p>ValueError: Expected input batch_size (4) to match target batch_size (1).</p>

ptrblck: <p>I guess you are reshaping the intermediate tensors somewhere in your model and are reducing the batch size to 1.</p>
<p>Your current code is not easily readable, so please feel free to post an executable code snippet to reproduce this error by wrapping it into three backticks ``` <img src="https://discuss.pytorch.org/images/emoji/apple/wink.png?v=9" title=":wink:" class="emoji" alt=":wink:"></p>

MA_CASANDRA_QUILANG: <p>I am really new to this sir and is still trying to understand how networks work and I really find it tricky to do so, that’s why any helpful comments will do! By the way this is my complete code and the error was different this time and I have no idea why!</p>
<pre><code class="lang-auto">
###################################################################################################
#ESNet: An Efficient Symmetric Network for Real-time Semantic Segmentation
#Paper-Link: https://arxiv.org/pdf/1906.09826.pdf
###################################################################################################

import torch
import torch.nn as nn
import torch.nn.init as init
import torch.nn.functional as F
from torchsummary import summary

class DownsamplerBlock(nn.Module):
    def __init__(self, ninput, noutput):
        super().__init__()

        self.conv = nn.Conv2d(ninput, noutput-ninput, (3, 3), stride=2, padding=1, bias=True)
        self.pool = nn.MaxPool2d(2, stride=2)
        self.bn = nn.BatchNorm2d(noutput, eps=1e-3)
        self.relu = nn.ReLU(inplace=True)

    def forward(self, input):
        x1 = self.pool(input)
        x2 = self.conv(input)

        diffY = x2.size()[2] - x1.size()[2]
        diffX = x2.size()[3] - x1.size()[3]

       

        x1 = F.pad(x1, [diffX // 2, diffX - diffX // 2,
                        diffY // 2, diffY - diffY // 2])


        output = torch.cat([x2, x1], 1)
        output = self.bn(output)
        output = self.relu(output)

        return output



class UpsamplerBlock (nn.Module):
    def __init__(self, ninput, noutput):
        super().__init__()

        self.conv = nn.ConvTranspose2d(ninput, noutput, 3, stride=2, padding=1, output_padding=1, bias=True)
        self.bn = nn.BatchNorm2d(noutput, eps=1e-3)

    def forward(self, input):

        output = self.conv(input)
        output = self.bn(output)

        return F.relu(output)
		
class FCU(nn.Module):
    def __init__(self, chann, kernel_size,dropprob, dilated): 
        """
        Factorized Convolution Unit
        """     
        super(FCU,self).__init__()

        padding = int((kernel_size-1)//2) * dilated

        self.conv3x1_1 = nn.Conv2d(chann, chann, (kernel_size,1), stride=1, padding=(int((kernel_size-1)//2)*1,0), bias=True)

        self.conv1x3_1 = nn.Conv2d(chann, chann, (1,kernel_size), stride=1, padding=(0,int((kernel_size-1)//2)*1), bias=True)

        self.bn1 = nn.BatchNorm2d(chann, eps=1e-03)

        self.conv3x1_2 = nn.Conv2d(chann, chann, (kernel_size,1), stride=1, padding=(padding,0), bias=True, dilation = (dilated,1))

        self.conv1x3_2 = nn.Conv2d(chann, chann, (1,kernel_size), stride=1, padding=(0,padding), bias=True, dilation = (1, dilated))

        self.bn2 = nn.BatchNorm2d(chann, eps=1e-03)
        
        self.relu = nn.ReLU(inplace = True)
        self.dropout = nn.Dropout2d(dropprob)
        
    def forward(self, input):
        residual = input
        output = self.conv3x1_1(input)
        output = self.relu(output)
        output = self.conv1x3_1(output)
        output = self.bn1(output)
        output = self.relu(output)

        output = self.conv3x1_2(output)
        output = self.relu(output)
        output = self.conv1x3_2(output)
        output = self.bn2(output)   

        if (self.dropout.p != 0):
            output = self.dropout(output)
        
        return F.relu(residual+output,inplace=True) 


class PFCU(nn.Module):
    def __init__(self,chann):
        """
        Parallel Factorized Convolution Unit
        """         
    
        super(PFCU,self).__init__()
        
        self.conv3x1_1 = nn.Conv2d(chann, chann, (3,1), stride=1, padding=(1,0), bias=True)

        self.conv1x3_1 = nn.Conv2d(chann, chann, (1,3), stride=1, padding=(0,1), bias=True)

        self.bn1 = nn.BatchNorm2d(chann, eps=1e-03)

        self.conv3x1_22 = nn.Conv2d(chann, chann, (3,1), stride=1, padding=(2,0), bias=True, dilation = (2,1))
        self.conv1x3_22 = nn.Conv2d(chann, chann, (1,3), stride=1, padding=(0,2), bias=True, dilation = (1,2))

        self.conv3x1_25 = nn.Conv2d(chann, chann, (3,1), stride=1, padding=(5,0), bias=True, dilation = (5,1))
        self.conv1x3_25 = nn.Conv2d(chann, chann, (1,3), stride=1, padding=(0,5), bias=True, dilation = (1,5))

        self.conv3x1_29 = nn.Conv2d(chann, chann, (3,1), stride=1, padding=(9,0), bias=True, dilation = (9,1))
        self.conv1x3_29 = nn.Conv2d(chann, chann, (1,3), stride=1, padding=(0,9), bias=True, dilation = (1,9))

        self.bn2 = nn.BatchNorm2d(chann, eps=1e-03)

        self.dropout = nn.Dropout2d(0.3)

    def forward(self, input):
        residual = input
        output = self.conv3x1_1(input)
        output = F.relu(output)
        output = self.conv1x3_1(output)
        output = self.bn1(output)
        output = F.relu(output)

        output2 = self.conv3x1_22(output)
        output2 = F.relu(output2)
        output2 = self.conv1x3_22(output2)
        output2 = self.bn2(output2)
        if (self.dropout.p != 0):
            output2 = self.dropout(output2)

        output5 = self.conv3x1_25(output)
        output5 = F.relu(output5)
        output5 = self.conv1x3_25(output5)
        output5 = self.bn2(output5)
        if (self.dropout.p != 0):
            output5 = self.dropout(output5)

        output9 = self.conv3x1_29(output)
        output9 = F.relu(output9)
        output9 = self.conv1x3_29(output9)
        output9 = self.bn2(output9)
        if (self.dropout.p != 0):
            output9 = self.dropout(output9)

        return F.relu(residual+output2+output5+output9,inplace=True)

		
class ESNet(nn.Module):
    def __init__(self, classes):
        super().__init__()
        #-----ESNET---------#
        self.initial_block = DownsamplerBlock(3, 16)

        self.layers = nn.ModuleList()
        
        for x in range(0, 3):
           self.layers.append(FCU(16, 3, 0.03, 1))  
        
        self.layers.append(DownsamplerBlock(16,64))

        for x in range(0, 2):
           self.layers.append(FCU(64, 5, 0.03, 1))  

        self.layers.append(DownsamplerBlock(64,128))

        for x in range(0, 3):   
            self.layers.append(PFCU(chann=128)) 

        self.layers.append(UpsamplerBlock(128,64))
        self.layers.append(FCU(64, 5, 0, 1))
        self.layers.append(FCU(64, 5, 0, 1))

        self.layers.append(UpsamplerBlock(64,16))
        self.layers.append(FCU(16, 3, 0, 1))
        self.layers.append(FCU(16, 3, 0, 1))

        self.output_conv = nn.ConvTranspose2d( 16, classes, 2, stride=2, padding=0, output_padding=0, bias=True)

    def forward(self, input):
        output = self.initial_block(input)

        for layer in self.layers:
            output = layer(output)

        output = self.output_conv(output)
        return output


"""print layers and params of network"""
if __name__ == '__main__':
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    model = ESNet(classes=2).to(device)
    summary(model,(3,100,100))

import numpy as np
from tqdm import tqdm
import torch.optim as optim

training_data = np.load("/content/thirdy/training_data.npy", allow_pickle = True)

x = torch.Tensor([i[0] for i in training_data]).view(-1, 3, 100, 100)


print(x.shape)

y = torch.Tensor([i[1] for i in training_data])

print(y.shape)

VAL_PCT = 0.1
val_size = int(len(x)*VAL_PCT)
print(val_size)

train_x = x[:-val_size]
train_y = y[:-val_size]

test_x = x[-val_size:]
test_y = y[-val_size:]

print(len(train_x))
print(len(test_x))

import torch.optim as optim
optimizer = optim.Adam(model.parameters(), lr = 0.001)
loss_function = nn.CrossEntropyLoss()

BATCH_SIZE = 10
EPOCHS = 1

for epoch in range(EPOCHS):
    for i in tqdm(range(0, len(train_x), BATCH_SIZE)): 
        batch_x = train_x[i:i+BATCH_SIZE].view(-1, 3, 100, 100)
        print(batch_x.shape)
        batch_y = train_y[i:i+BATCH_SIZE].squeeze(1)
        print(batch_y.shape)

        model.zero_grad()

        outputs = model(batch_x)
        loss = loss_function(outputs, batch_y)
        loss.backward()
        optimizer.step()    # Does the update

    print(f"Epoch: {epoch}. Loss: {loss}")```</code></pre>

ptrblck: <p>Thanks for the code. Unfortunately it’s not executable, but based on the <code>view</code> operation I assume your input has the shape <code>[batch_size, 3, 100, 100]</code>.<br>
Based on this shape the output would have the shape <code>[batch_size, 2, 104, 104]</code> and thus the target should have the shape <code>[batch_size, 104, 104]</code> and contain values in <code>[0, 1]</code>.<br>
Using these shapes, the script works fine so you could check the shapes of your inputs, outputs, and targets and make sure they have the mentioned shapes.</p>

MA_CASANDRA_QUILANG: <p>Thank you so much sir for your response. But as a newbie I don’t understand why my model should have the shapes you have stated above, specifically the output’s shape and the target shape. Lastly, I still don’t fully understand what target really is. Can you please give an explanation? Thanks!</p>

MA_CASANDRA_QUILANG: <p>by the way sir, this is my complete code (I forgot to include my repo where i store my custom dataset in the previous code I provided):</p>
<pre><code class="lang-auto">!git clone https://gitlab.com/mariacassie/thirdy.git

###################################################################################################
#ESNet: An Efficient Symmetric Network for Real-time Semantic Segmentation
#Paper-Link: https://arxiv.org/pdf/1906.09826.pdf
###################################################################################################

import torch
import torch.nn as nn
import torch.nn.init as init
import torch.nn.functional as F
from torchsummary import summary

class DownsamplerBlock(nn.Module):
    def __init__(self, ninput, noutput):
        super().__init__()

        self.conv = nn.Conv2d(ninput, noutput-ninput, (3, 3), stride=2, padding=1, bias=True)
        self.pool = nn.MaxPool2d(2, stride=2)
        self.bn = nn.BatchNorm2d(noutput, eps=1e-3)
        self.relu = nn.ReLU(inplace=True)

    def forward(self, input):
        x1 = self.pool(input)
        x2 = self.conv(input)

        diffY = x2.size()[2] - x1.size()[2]
        diffX = x2.size()[3] - x1.size()[3]

       

        x1 = F.pad(x1, [diffX // 2, diffX - diffX // 2,
                        diffY // 2, diffY - diffY // 2])


        output = torch.cat([x2, x1], 1)
        output = self.bn(output)
        output = self.relu(output)

        return output



class UpsamplerBlock (nn.Module):
    def __init__(self, ninput, noutput):
        super().__init__()

        self.conv = nn.ConvTranspose2d(ninput, noutput, 3, stride=2, padding=1, output_padding=1, bias=True)
        self.bn = nn.BatchNorm2d(noutput, eps=1e-3)

    def forward(self, input):

        output = self.conv(input)
        output = self.bn(output)

        return F.relu(output)
		
class FCU(nn.Module):
    def __init__(self, chann, kernel_size,dropprob, dilated): 
        """
        Factorized Convolution Unit
        """     
        super(FCU,self).__init__()

        padding = int((kernel_size-1)//2) * dilated

        self.conv3x1_1 = nn.Conv2d(chann, chann, (kernel_size,1), stride=1, padding=(int((kernel_size-1)//2)*1,0), bias=True)

        self.conv1x3_1 = nn.Conv2d(chann, chann, (1,kernel_size), stride=1, padding=(0,int((kernel_size-1)//2)*1), bias=True)

        self.bn1 = nn.BatchNorm2d(chann, eps=1e-03)

        self.conv3x1_2 = nn.Conv2d(chann, chann, (kernel_size,1), stride=1, padding=(padding,0), bias=True, dilation = (dilated,1))

        self.conv1x3_2 = nn.Conv2d(chann, chann, (1,kernel_size), stride=1, padding=(0,padding), bias=True, dilation = (1, dilated))

        self.bn2 = nn.BatchNorm2d(chann, eps=1e-03)
        
        self.relu = nn.ReLU(inplace = True)
        self.dropout = nn.Dropout2d(dropprob)
        
    def forward(self, input):
        residual = input
        output = self.conv3x1_1(input)
        output = self.relu(output)
        output = self.conv1x3_1(output)
        output = self.bn1(output)
        output = self.relu(output)

        output = self.conv3x1_2(output)
        output = self.relu(output)
        output = self.conv1x3_2(output)
        output = self.bn2(output)   

        if (self.dropout.p != 0):
            output = self.dropout(output)
        
        return F.relu(residual+output,inplace=True) 


class PFCU(nn.Module):
    def __init__(self,chann):
        """
        Parallel Factorized Convolution Unit
        """         
    
        super(PFCU,self).__init__()
        
        self.conv3x1_1 = nn.Conv2d(chann, chann, (3,1), stride=1, padding=(1,0), bias=True)

        self.conv1x3_1 = nn.Conv2d(chann, chann, (1,3), stride=1, padding=(0,1), bias=True)

        self.bn1 = nn.BatchNorm2d(chann, eps=1e-03)

        self.conv3x1_22 = nn.Conv2d(chann, chann, (3,1), stride=1, padding=(2,0), bias=True, dilation = (2,1))
        self.conv1x3_22 = nn.Conv2d(chann, chann, (1,3), stride=1, padding=(0,2), bias=True, dilation = (1,2))

        self.conv3x1_25 = nn.Conv2d(chann, chann, (3,1), stride=1, padding=(5,0), bias=True, dilation = (5,1))
        self.conv1x3_25 = nn.Conv2d(chann, chann, (1,3), stride=1, padding=(0,5), bias=True, dilation = (1,5))

        self.conv3x1_29 = nn.Conv2d(chann, chann, (3,1), stride=1, padding=(9,0), bias=True, dilation = (9,1))
        self.conv1x3_29 = nn.Conv2d(chann, chann, (1,3), stride=1, padding=(0,9), bias=True, dilation = (1,9))

        self.bn2 = nn.BatchNorm2d(chann, eps=1e-03)

        self.dropout = nn.Dropout2d(0.3)

    def forward(self, input):
        residual = input
        output = self.conv3x1_1(input)
        output = F.relu(output)
        output = self.conv1x3_1(output)
        output = self.bn1(output)
        output = F.relu(output)

        output2 = self.conv3x1_22(output)
        output2 = F.relu(output2)
        output2 = self.conv1x3_22(output2)
        output2 = self.bn2(output2)
        if (self.dropout.p != 0):
            output2 = self.dropout(output2)

        output5 = self.conv3x1_25(output)
        output5 = F.relu(output5)
        output5 = self.conv1x3_25(output5)
        output5 = self.bn2(output5)
        if (self.dropout.p != 0):
            output5 = self.dropout(output5)

        output9 = self.conv3x1_29(output)
        output9 = F.relu(output9)
        output9 = self.conv1x3_29(output9)
        output9 = self.bn2(output9)
        if (self.dropout.p != 0):
            output9 = self.dropout(output9)

        return F.relu(residual+output2+output5+output9,inplace=True)

		
class ESNet(nn.Module):
    def __init__(self, classes):
        super().__init__()
        #-----ESNET---------#
        self.initial_block = DownsamplerBlock(3, 16)

        self.layers = nn.ModuleList()
        
        for x in range(0, 3):
           self.layers.append(FCU(16, 3, 0.03, 1))  
        
        self.layers.append(DownsamplerBlock(16,64))

        for x in range(0, 2):
           self.layers.append(FCU(64, 5, 0.03, 1))  

        self.layers.append(DownsamplerBlock(64,128))

        for x in range(0, 3):   
            self.layers.append(PFCU(chann=128)) 

        self.layers.append(UpsamplerBlock(128,64))
        self.layers.append(FCU(64, 5, 0, 1))
        self.layers.append(FCU(64, 5, 0, 1))

        self.layers.append(UpsamplerBlock(64,16))
        self.layers.append(FCU(16, 3, 0, 1))
        self.layers.append(FCU(16, 3, 0, 1))

        self.output_conv = nn.ConvTranspose2d( 16, classes, 2, stride=2, padding=0, output_padding=0, bias=True)

    def forward(self, input):
        output = self.initial_block(input)

        for layer in self.layers:
            output = layer(output)

        output = self.output_conv(output)
        return output


"""print layers and params of network"""
if __name__ == '__main__':
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    model = ESNet(classes=2).to(device)
    summary(model,(3,100,100))

import numpy as np
from tqdm import tqdm
import torch.optim as optim

training_data = np.load("/content/thirdy/training_data.npy", allow_pickle = True)

x = torch.Tensor([i[0] for i in training_data]).view(-1, 3, 100, 100)


print(x.shape)

y = torch.Tensor([i[1] for i in training_data])

print(y.shape)

VAL_PCT = 0.1
val_size = int(len(x)*VAL_PCT)
print(val_size)

train_x = x[:-val_size]
train_y = y[:-val_size]

test_x = x[-val_size:]
test_y = y[-val_size:]

print(len(train_x))
print(len(test_x))

import torch.optim as optim
optimizer = optim.Adam(model.parameters(), lr = 0.001)
loss_function = nn.CrossEntropyLoss()

BATCH_SIZE = 100
EPOCHS = 1

for epoch in range(EPOCHS):
    for i in tqdm(range(0, len(train_x), BATCH_SIZE)): 
        batch_x = train_x[i:i+BATCH_SIZE].view(-1, 3, 100, 100)
        batch_y = train_y[i:i+BATCH_SIZE]
      

        model.zero_grad()

        outputs = model(batch_x)
        print(outputs.shape)
        loss = loss_function(outputs, batch_y)
        loss.backward()
        optimizer.step()    # Does the update

    print(f"Epoch: {epoch}. Loss: {loss}")</code></pre>

ptrblck: <aside class="quote no-group" data-username="MA_CASANDRA_QUILANG" data-post="9" data-topic="98354">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ma_casandra_quilang/48/13913_2.png" class="avatar"> MA_CASANDRA_QUILANG:</div>
<blockquote>
<p>But as a newbie I don’t understand why my model should have the shapes you have stated above, specifically the output’s shape and the target shape.</p>
</blockquote>
</aside>
<p>For the input shape I used the shaped defined in your script:</p>
<pre data-code-wrap="python"><code class="lang-python">batch_x = train_x[i:i+BATCH_SIZE].view(-1, 3, 100, 100)
</code></pre>
<p>Using a random input in this shape, the model creates an output in the shape <code>[batch_size, 2, 104, 104]</code>.</p>
<aside class="quote no-group" data-username="MA_CASANDRA_QUILANG" data-post="9" data-topic="98354">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ma_casandra_quilang/48/13913_2.png" class="avatar"> MA_CASANDRA_QUILANG:</div>
<blockquote>
<p>Lastly, I still don’t fully understand what target really is.</p>
</blockquote>
</aside>
<p>The target is the ground truth label of the sample. During the training of your model you are trying to get the model predictions as close to the target (label) as possible.</p>

MA_CASANDRA_QUILANG: <p>Sir, I checked the shape of my output and target and I found that my output has the shape [100, 3, 104, 104] and my target shape is [100, 2]. Now, I find it difficult to adjust my target shape. Can you please give any suggestion where should I adjust it? in your previous answers you stated that my target should have the shape [batch_size, 104, 104] but it doesn’t coincide to what I got thus getting the error: RuntimeError: only batches of spatial targets supported (3D tensors) but got targets of dimension: 2</p>

ptrblck: <p>Could you explain what the target contains and what <code>dim1</code> is used for in <code>[100, 2]</code>?<br>
Based on the shape it should be a multi-class classification target for a sequence length of 2, but I guess you might be using a one-hot encoded target for a binary classifiaction?<br>
If that’s the case, you would have to create a target in the shape <code>[batch_size=100]</code>, which contains the class indices in <code>[0, 1]</code> (or use alternatively <code>nn.BCEWithLogitsLoss</code>).<br>
Since your current model outputs a 4-dimensional tensor, you could flatten the activation and add linear layers to the model to get the desired output shape.</p>
<p>Have a look at <a href="https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html">this tutorial</a> for a simple CNN.</p>

MA_CASANDRA_QUILANG: <p>My target contains my labels sir and thank you for the linked tutorial I will check it out.</p>

MA_CASANDRA_QUILANG: <p>Sir, I decided to just flatten my output shape because I see it as the best answer to my problem. But I actually don’t know how</p>

ptrblck: <p>You can flatten the activations via <code>x = x.view(x.size(0), -1)</code> or by using <code>nn.Flatten</code>.<br>
However, I don’t think flattening the activations alone will solve the issue, since the model output should have the shape <code>[batch_size, nb_classes]</code> for a multi-class classification as shown in the tutorial.<br>
Thus I would still recommend to use e.g. an <code>nn.Linear</code> module to create the desired outputs.</p>

MA_CASANDRA_QUILANG: <p>Hi! I tried using nn.Linear module and tried to flatten the last layer of my network too. My code finally has no error but still I am not 100% sure if I did it correctly, any comments on this sir? :</p>
<pre><code class="lang-auto">class ESNet(nn.Module):
    def __init__(self, classes):
        super().__init__()
        #-----ESNET---------#
        self.initial_block = DownsamplerBlock(3, 16)

        self.layers = nn.ModuleList()
        
        for x in range(0, 3):
           self.layers.append(FCU(16, 3, 0.03, 1))  
        
        self.layers.append(DownsamplerBlock(16,64))

        for x in range(0, 2):
           self.layers.append(FCU(64, 5, 0.03, 1))  

        self.layers.append(DownsamplerBlock(64,128))

        for x in range(0, 3):   
            self.layers.append(PFCU(chann=128)) 

        self.layers.append(UpsamplerBlock(128,64))
        self.layers.append(FCU(64, 5, 0, 1))
        self.layers.append(FCU(64, 5, 0, 1))

        self.layers.append(UpsamplerBlock(64,16))
        self.layers.append(FCU(16, 3, 0, 1))
        self.layers.append(FCU(16, 3, 0, 1))

        self.output_conv = nn.ConvTranspose2d( 16, classes, 2, stride=2, padding=0, output_padding=0, bias=True)
        self.hidden = nn.Linear(2*104*104, 208)
        self.out = nn.Linear(208, 2)
        self.act = nn.ReLU()

    def forward(self, input):
        output = self.initial_block(input)
        print(input.shape)
        

        for layer in self.layers:
            output = layer(output)
           

        output = self.output_conv(output)
        output = output.view(output.size(0), -1)
        output = self.act(self.hidden(output))
        output = self.out(output)
        print(output.shape)
       
        return output</code></pre>

ptrblck: <p>The implementation looks alright for a 2-class classification.<br>
As said before, you could also use a single output unit and then <code>nn.BCEWithLogitsLoss</code> for a binary classification, but your approach should also work.</p>