Since I am going to ask about the same model I will continue with this thread. Below, you can see the way I have fixed the “Residual” layer. (I only have provided the part that I have changed in my code.) However, I still have doubts if all parameters in the “Residual” layers are actually being trained properly! You can see more details below.
This is my fixed code (note that I commented out the “Residual” class completely so I am not showing it here).

class Encoding(nn.Module):
    def __init__(self, channel = [64, 128, 192, 256, 320, 384, 448], s\
                 tride = [(2, 1), (1, 3), (2, 1), (3, 3), (2, 2), (2, 2)], \
                 sameChannel_In = [128, 192, 256, 320, 384, 448]):

        super().__init__()
        self.channel    = channel
        self.enConvList = nn.ModuleList([nn.Conv2d(channel[i], channel[i + 1], 3, stride = stride[i], \
                          padding = 1) for i in range(len(channel) - 1)])
        self.batchList  = nn.ModuleList([nn.BatchNorm2d(channel[j  + 1]) for j in range(len(channel) - 1)])
        self.active     = nn.LeakyReLU()
        
        ### Residual layers
        self.residualEncoding = nn.ModuleList([nn.Conv2d(sameChannel_In[i], sameChannel_In[i], 
                                kernel_size = 3, stride = 1, padding = 1) 
                                for i in range(len(sameChannel_In))])
        self.residualBatch    = nn.ModuleList([nn.BatchNorm2d(sameChannel_In[i]) \
                                for i in range(len(sameChannel_In))]) 
    def forward(self, out):
        concatList = []
        for i in range(len(self.channel) - 1):
            concatList.append(out)
            ### strided convolution block
            out      = self.enConvList[i](out)
            ### batch normalization block
            out      = self.batchList[i](out)
            ### activation block
            out      = self.active(out)
            ### Residual layers
            inputToResidual = out
            ## first layer
            out  = self.residualEncoding[i](out)
            out  = self.residualBatch[i](out)
            out  = self.active(out)
            ## second layer
            out  = self.residualEncoding[i](out)
            out  = self.residualBatch[i](out)
            out  = self.active(out)
            ## third layer
            out  = self.residualEncoding[i](out)
            out  = self.residualBatch[i](out)
            out  = self.active(out)
            ## Addition of the input of the residual block to the output of the residual block!
            out  = inputToResidual + out
        return out, concatList


class Decoding(nn.Module):
    def __init__(self, upChannel_in  = [448, 384, 320, 256, 192, 128],\
                 upChannel_out       = [384, 320, 256, 192, 128, 64] ,\
                 deconvChannel2_in   = [768, 640, 512, 384, 256, 128],\
                 deconvChannel2_out  = [384, 320, 256, 192, 128, 64] ,\
                 upKernel  = [(3, 3), (3, 3), (3, 3), (3, 3), (3, 5), (3, 3)], \
                 upPadding = [1, 1, 1, 1, (1, 2), 1], finalIn = 64, finalOut = 2,\
                 sameChannel_Out= [384, 320, 256, 192, 128, 64]):
        
        super().__init__()
        self.channelLength = upChannel_in
        self.deConvList = nn.ModuleList([nn.Conv2d(deconvChannel2_in[i], \
        deconvChannel2_out[i], 3, padding = 1) \
        for i in range(len(upChannel_in))])
        self.batch      = nn.ModuleList([nn.BatchNorm2d(deconvChannel2_out[k]) \
        for k in range(len(deconvChannel2_out))])
        self.active     = nn.LeakyReLU()
    
        ### Upsampling block preparation ###
        self.upConv     = nn.ModuleList([nn.Conv2d(upChannel_in[i], \
        upChannel_out[i], kernel_size = upKernel[i], padding = upPadding[i], \
        padding_mode = "replicate") for i in range(len(upChannel_out))])
        self.upBatch    = nn.ModuleList([nn.BatchNorm2d(upChannel_out[j]) \
        for j in range(len(upChannel_out))])

        self.upActive   = nn.LeakyReLU()
        
        ### Last deconvolution layer ###
        self.lastConv    = nn.Conv2d(finalIn, finalOut, 3, padding = 1, padding_mode = "replicate")
    
       ### Residual layers
        self.residualDecoding = nn.ModuleList([nn.Conv2d(sameChannel_Out[i], \
        sameChannel_Out[i], kernel_size = 3, stride = 1, padding = 1) \
        for i in range(len(sameChannel_Out))])
        self.residualBatch    = nn.ModuleList([nn.BatchNorm2d(sameChannel_Out[i]) \
        for i in range(len(sameChannel_Out))])

    def interpolation(self, inputT, targetT):
        """This function upsamples an input tensor to the spatial dimensions of the target tensor using a 
        combination of bilinear interpolation and convolution."""
        inputT_ch = inputT.shape[1]
        inputT_H  = inputT.shape[2]
        inputT_W  = inputT.shape[3]
        
        targetT_ch= targetT.shape[1]
        targetT_H = targetT.shape[2]
        targetT_W = targetT.shape[3]
             
        interpol  = nn.functional.interpolate(inputT, size = (targetT_H, targetT_W), mode = "bilinear")
        return interpol
    
    def forward(self, out, enList):
        enList     = enList[: : -1] # reversing the order of elements inside the list.
        
        for l in range(len(self.channelLength)):
            
            ### Upscaling = interpolation + convolution ###
            out    = self.interpolation(out, enList[l])
            out    = self.upConv[l](out)
            out    = self.upBatch[l](out)
            out    = self.upActive(out)
            ### Concatenation ###
            out    = torch.cat([out, enList[l]], 1) # concatenation on channel number!
            ### Decoding ###
            out    = self.deConvList[l](out)
            out    = self.batch[l](out)
            out    = self.active(out)
            ### Residual layers
            inputToResidual = out
            ## first layer
            out  = self.residualDecoding[l](out)
            out  = self.residualBatch[l](out)
            out  = self.active(out)
            ## second layer
            out  = self.residualDecoding[l](out)
            out  = self.residualBatch[l](out)
            out  = self.active(out)
            ## third layer
            out  = self.residualDecoding[l](out)
            out  = self.residualBatch[l](out)
            out  = self.active(out)
            ## Addition of the input of the residual block to the output of the residual block!
            out  = inputToResidual + out
            
        ### This is the last convolution layer!
        out      = self.lastConv(out)
        return out

This time, as you can see, I initialise the Residual layer in the ___init___ section. The point I would like to raise is that I am initialising a list of six different residual layers in the Encoding and Decoding blocks BUT, in the forward methods, I am using each member of the Residual list THREE times before I add the input of the Residual layer to the output of the Residual layer. The question is when I want to use a layer three times (such as the case above) can I initialise it as one layer and repeat it in the forward method several times (here three) or do I have to initialise a layer as many times as I want to use that layer. In other words, should I have created three identical lists of the Residual layers under different names each with six identical layers and should have used, for instance, each list in place of each of the Residual layers above? Something similar to the following code snippet? (Please note the change of names of the lists.)

### Residual layers
inputToResidual = out
 ## first layer
out  = self.residualDecodingOne[l](out)
out  = self.residualBatchOne[l](out)
out  = self.active(out)
## second layer
out  = self.residualDecodingTwo[l](out)
out  = self.residualBatchTwo[l](out)
out  = self.active(out)
## third layer
out  = self.residualDecodingThree[l](out)
out  = self.residualBatchThree[l](out)
out  = self.active(out)
## Addition of the input of the residual block to the output of the residual block!
out  = inputToResidual + out

This question occurred to me as a result of printing out the number and name of the trainable parameters of the model (see below). (Here only the trainable parameters of the Residual layers of the Decoding block are shown where the first column shows the number of parameters and the second column shows the name of the layer).
1327104 decoder.residualDecoding.0.weight
384  decoder.residualDecoding.0.bias
921600 decoder.residualDecoding.1.weight
320 decoder.residualDecoding.1.bias
589824 decoder.residualDecoding.2.weight
256 decoder.residualDecoding.2.bias
331776 decoder.residualDecoding.3.weight
192 decoder.residualDecoding.3.bias
147456 decoder.residualDecoding.4.weight
128 decoder.residualDecoding.4.bias
36864 decoder.residualDecoding.5.weight
64 decoder.residualDecoding.5.bias
384 decoder.residualBatch.0.weight
384 decoder.residualBatch.0.bias
320 decoder.residualBatch.1.weight
320 decoder.residualBatch.1.bias
256 decoder.residualBatch.2.weight
256 decoder.residualBatch.2.bias
192 decoder.residualBatch.3.weight
192 decoder.residualBatch.3.bias
128 decoder.residualBatch.4.weight
128 decoder.residualBatch.4.bias
64 decoder.residualBatch.5.weight
64 decoder.residualBatch.5.bias
While I am not surprised that the model prints out  six layers of weights and biases because I have declared a Residual list with six layers but I am confused as to what happens to the weights and biases of the repeated layers in the forward function. Assuming the model actually sees them as trainable parameters and trains them, then why did they not appear as trainable parameters when I printed the list of trainable parameters above? The same questions holds true for the BatchNorm2d layers too!