RuntimeError: Sizes of tensors must match except in dimension 1. Expected size 1180 but got size 1178 for tensor number 1 in the list

Hello got a really weird issue my code is going trough but l don´t know why l am losing 2 size of width between 2 steps . Really weird do you know why ? Thanks a lot !
torch.Size([2, 512, 145, 145])
torch.Size([2, 256, 293, 293])
torch.Size([2, 128, 590, 588])


RuntimeError Traceback (most recent call last)
Cell In[18], line 3
1 epochs=10
2 for epoch in range(1,epochs+1):
----> 3 training(epoch)

Cell In[17], line 66, in training(epochs)
56 #label = label.to(device)
57
58
(…)
62
63 #Clear the gradients
64 optimizer.zero_grad()
—> 66 output = Model(x_pre,x_post)
67 #loss = sum(loss1,loss2,loss3)
69 loss1 = diceLoss (output,label)

File ~/miniconda3/lib/python3.10/site-packages/torch/nn/modules/module.py:1501, in Module._call_impl(self, *args, **kwargs)
1496 # If we don’t have any hooks, we want to skip the rest of the logic in
1497 # this function, and just call forward.
1498 if not (self._backward_hooks or self._backward_pre_hooks or self._forward_hooks or self._forward_pre_hooks
1499 or _global_backward_pre_hooks or _global_backward_hooks
1500 or _global_forward_hooks or _global_forward_pre_hooks):
→ 1501 return forward_call(*args, **kwargs)
1502 # Do not call functions when jit is used
1503 full_backward_hooks, non_full_backward_hooks = [], []

File ~/codes/Buldings_damage_assessment/models/testUNet_Assement.py:155, in Siamese_UNet_Assement.forward(self, input1, input2)
153 dec2_1= self.up_conv2(dec3_1, skip2_out1)
154 print(dec2_1.size())
→ 155 dec1_1 = self.up_conv1(dec2_1, skip1_out1)
156 print(dec1_1.size())
157 dec1_1 = self.conv_last(dec1_1)

File ~/miniconda3/lib/python3.10/site-packages/torch/nn/modules/module.py:1501, in Module._call_impl(self, *args, **kwargs)
1496 # If we don’t have any hooks, we want to skip the rest of the logic in
1497 # this function, and just call forward.
1498 if not (self._backward_hooks or self._backward_pre_hooks or self._forward_hooks or self._forward_pre_hooks
1499 or _global_backward_pre_hooks or _global_backward_hooks
1500 or _global_forward_hooks or _global_forward_pre_hooks):
→ 1501 return forward_call(*args, **kwargs)
1502 # Do not call functions when jit is used
1503 full_backward_hooks, non_full_backward_hooks = [], []

File ~/codes/Buldings_damage_assessment/models/testUNet_Assement.py:106, in UpBlock.forward(self, down_input, skip_input)
101 diffY2 = skip_input.size()[3] - down_input.size()[3]
103 down_input = F.pad(down_input, [diffX2 // 2, diffX2 - diffX2 // 2, diffY2 // 2, diffY2 - diffY2 // 2])
→ 106 x = torch.cat([down_input, skip_input], dim=1)
108 return self.double_conv(x)

RuntimeError: Sizes of tensors must match except in dimension 1. Expected size 1180 but got size 1178 for tensor number 1 in the list.

my code :

import glob
import os
import pickle
import sys
from pathlib import Path
import random
from tqdm import tqdm

import torchvision.models as models
from torch.nn import Module, Dropout
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import copy
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, Dataset
from torch.utils.data import Dataset, DataLoader,TensorDataset,random_split,SubsetRandomSampler, ConcatDataset
import torchvision
from torchvision import transforms, datasets
import segmentation_models_pytorch as smp
from segmentation_models_pytorch import utils
from torch.utils.data import Dataset, DataLoader
import torchvision.transforms.functional as F

In[4]:

class DoubleConv(nn.Module):

def __init__(self, in_channels, out_channels):
    
    super(DoubleConv, self).__init__()
    
    self.double_conv = nn.Sequential(
        nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=2),
        nn.BatchNorm2d(out_channels),
        nn.ReLU(inplace=True),
        nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=2),
        nn.BatchNorm2d(out_channels),
        nn.ReLU(inplace=True),
    )

def forward(self, out):
    
    x=self.double_conv(out)
    
    
    return x

In[5]:

class DownBlock(nn.Module):
def init(self, in_channels, out_channels):

    super(DownBlock, self).__init__()
    
    self.double_conv = DoubleConv(in_channels, out_channels)
    self.down_sample = nn.MaxPool2d(2)

def forward(self, x):
    skip_out = self.double_conv(x)
    down_out = self.down_sample(skip_out)
    return (down_out, skip_out)

In[6]:

class UpBlock (nn.Module):
“”“Upscaling then double conv”“”

def __init__(self, in_channels, out_channels, up_sample_mode):
    super(UpBlock, self).__init__()
    if up_sample_mode == 'conv_transpose':
        self.up_sample = nn.ConvTranspose2d(in_channels-out_channels, in_channels-out_channels, kernel_size=2, stride=2,  padding=1, output_padding=1)        
    elif up_sample_mode == 'bilinear':
        self.up_sample = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)
    else:
        raise ValueError("Unsupported `up_sample_mode` (can take one of `conv_transpose` or `bilinear`)")
    self.double_conv = DoubleConv(in_channels, out_channels)

def forward(self, down_input, skip_input):
    down_input = self.up_sample(down_input)
    
    diffX1 = down_input.size()[2] - skip_input.size()[2]
    diffY1 = down_input.size()[3] - skip_input.size()[3]

    skip_input = F.pad(skip_input, [diffX1 // 2, diffX1 - diffX1 // 2, diffY1 // 2, diffY1 - diffY1 // 2])
    
    diffX2 = skip_input.size()[2] - down_input.size()[2]
    diffY2 = skip_input.size()[3] - down_input.size()[3]

    down_input = F.pad(down_input, [diffX2 // 2, diffX2 - diffX2 // 2, diffY2 // 2, diffY2 - diffY2 // 2])
    
    
    x = torch.cat([down_input, skip_input], dim=1)
    
    return self.double_conv(x)

In[9]:

class Siamese_UNet_Assement(nn.Module):
def init(self, out_classes, up_sample_mode=‘conv_transpose’):

    super(Siamese_UNet_Assement, self).__init__()
    
    self.up_sample_mode = up_sample_mode
    # Downsampling Path
    self.down_conv1 = DownBlock(3, 64)
    self.down_conv2 = DownBlock(64, 128)
    self.down_conv3 = DownBlock(128, 256)
    self.down_conv4 = DownBlock(256, 512)
    # Bottleneck
    self.double_conv = DoubleConv(512, 1024)
    # Upsampling Path
    self.up_conv4 = UpBlock(512 + 1024, 512, self.up_sample_mode)
    self.up_conv3 = UpBlock(256 + 512, 256,self.up_sample_mode)
    self.up_conv2 = UpBlock(128 + 256,128,self.up_sample_mode)
    self.up_conv1 = UpBlock(64+128 , 64, self.up_sample_mode)
    # Final Convolution
    self.conv_last = nn.Conv2d(64, out_classes, kernel_size=1)

def forward(self, input1,input2):
    
    # Unet1
    
    # Encoder
    enc1_1, skip1_out1 = self.down_conv1(input1)
    enc1_2, skip2_out1 = self.down_conv2(enc1_1)
    enc1_3, skip3_out1 = self.down_conv3(enc1_2)
    enc1_4, skip4_out1 = self.down_conv4(enc1_3)
    bottleneck_1  = self.double_conv(enc1_4)


    #Decoder
    dec4_1= self.up_conv4(bottleneck_1, skip4_out1)
    print(dec4_1.size())
    dec3_1= self.up_conv3(dec4_1, skip3_out1)
    print(dec3_1.size())
    dec2_1= self.up_conv2(dec3_1, skip2_out1)
    print(dec2_1.size())
    dec1_1 = self.up_conv1(dec2_1, skip1_out1)
    print(dec1_1.size())
    dec1_1 = self.conv_last(dec1_1)
    print(dec1_1.size())
    # Unet2
    
    # Encoder
    enc2_1, skip1_out2 = self.down_conv1(input2)
    enc2_2, skip2_out2 = self.down_conv2(enc2_1)
    enc2_3, skip3_out2 = self.down_conv3(enc2_2)
    enc2_4, skip4_out2 = self.down_conv4(enc2_3)
    bottleneck_2  = self.double_conv(enc2_4)
    
    #Decoder
    dec4_2= self.up_conv4(bottleneck_2 , skip4_out2)
    dec3_2_= self.up_conv3(dec4_2, skip3_out2)
    dec2_2= self.up_conv2(dec3_2_, skip2_out2)
    dec1_2 = self.up_conv1(dec2_2, skip1_out2)
    dec1_2 = self.conv_last(dec1_2)
    
    
    
    # Siamese
    output = torch.cat((dec1_1,dec1_2), 1)
    
    
    
    return output