//  [python]
def forward(self, input):   
        # print("original input", input.size())
        input = torch.nn.functional.upsample_bilinear(input, size=[512, 640]) 
        # print("original input", input.size())
        input_small = self.downsample(input)
    
        e1 = self.conv1_1(input_small)
        e1 = self.relu1_1(e1)
        e1 = self.conv1_2(e1)
        e1 = self.norm1(e1)
        e1 = self.relu1_2(e1)
        e1 = self.max1(e1)
        # print("e1 size is :", e1.size())
        
        e2 = self.conv2_1(e1)
        e2 = self.relu2_1(e2)
        e2 = self.conv2_2(e2)
        e2 = self.norm2(e2)
        e2 = self.relu2_2(e2)
        e2 = self.max2(e2)
        # print("e2 size is :", e2.size())
        
        e3 = self.conv3_1(e2)
        e3 = self.relu3_1(e3)
        e3 = self.conv3_2(e3)
        e3 = self.relu3_2(e3)
        e3 = self.conv3_3(e3)
        e3 = self.norm3(e3)
        e3 = self.relu3_3(e3)
        e3 = self.max3(e3)
        # print("e3 size is :", e3.size())
        
        e4 = self.conv4_1(e3)
        e4 = self.relu4_1(e4)
        e4 = self.conv4_2(e4)
        e4 = self.relu4_2(e4)
        e4 = self.conv4_3(e4)
        e4 = self.norm4(e4)
        e4 = self.relu4_3(e4)
        e4 = self.max4(e4)
        # print("e4 size is :", e4.size())
        
        e5 = self.conv5_1(e4)
        e5 = self.relu5_1(e5)
        e5 = self.conv5_2(e5)
        e5 = self.relu5_2(e5)
        e5 = self.conv5_3(e5)
        e5 = self.norm5(e5)
        e5 = self.relu5_3(e5)
        e5 = self.max5(e5)
        # print("e5 size is :", e5.size())

        res1 = self.res_1(e5)
        res2 = self.res_2(res1)
        res3 = self.res_1(res2)
        res4 = self.res_2(res3)

        e5_upsp = self.conv6_1(res4)
        e5_upsp = self.norm6(e5_upsp)
        e5_upsp = self.relu6_1(e5_upsp)
        # e5_upsp = self.upsp(e5)
        # print("e5_upsp size is :", e5_upsp.size())
  
        e1_h = self.conv1_1_h(input)
        # e1_h = self.relu1_1_h(e1_h)
        # e1_h = self.conv1_2_h(e1_h)
        e1_h = self.norm1_h(e1_h)
        e1_h = self.relu1_2_h(e1_h)
        e1_h = self.max1_h(e1_h)
        # print("e1_h size is :", e1_h.size())
        
        e2_h = self.conv2_1_h(e1_h)
        # e2_h = self.relu2_1_h(e2_h)
        # e2_h = self.conv2_2_h(e2_h)
        e2_h = self.norm2_h(e2_h)
        e2_h = self.relu2_2_h(e2_h)
        e2_h = self.max2_h(e2_h)
        # print("e2_h size is :", e2_h.size())
        
        e3_h = self.conv3_1_h(e2_h)
        # e3_h = self.relu3_1_h(e3_h)
        # e3_h = self.conv3_2_h(e3_h)
        # e3_h = self.relu3_2_h(e3_h)
        # e3_h = self.conv3_3_h(e3_h)
        e3_h = self.norm3_h(e3_h)
        e3_h = self.relu3_3_h(e3_h)
        e3_h = self.max3_h(e3_h)
        # print("e3_h size is :", e3_h.size())

        ird_1_A = self.onemulone_ird_1_A(e3_h)
        ird_1_B = self.onemulone_ird_1_B(e3_h)
        ird_1_B = self.dcn_ird_1_B(ird_1_B)
        ird_1_C = self.onemulone_ird_1_C(e3_h)
        ird_1_C = self.dcn_ird_1_C(ird_1_C)
        ird_1_C = self.dcn_ird_1_C(ird_1_C)
        ird_1_concat_ori = torch.cat([ird_1_A, ird_1_B, ird_1_C], dim=1)
        # print("size ofird_1_concat_ori is:", ird_1_concat_ori.size())
        ird_1_concat_se = self.se_1(ird_1_concat_ori)
        # print("size ofird_1_concat_se is:", ird_1_concat_se.size())
        ird_1_concat_residual = self.onemulone_ird_1_D(ird_1_concat_se)
        # ird_1_concat_residual = self.norm_ird_1(ird_1_concat_residual)
        # ird_1_concat_residual = self.relu_ird_1(ird_1_concat_residual)
        ird_1 = e3_h + ird_1_concat_residual
        # print("ird_1 size is:", ird_1.size())
        ird_1 = self.relu(ird_1)

        ird_2_A = self.onemulone_ird_2_A(ird_1)
        ird_2_B = self.onemulone_ird_2_B(ird_1)
        ird_2_B = self.dcn_ird_2_B(ird_2_B)
        ird_2_C = self.onemulone_ird_2_C(ird_1)
        ird_2_C = self.dcn_ird_2_C(ird_2_C) # two 3X3 equals one 5X5 deformable conv
        ird_2_C = self.dcn_ird_2_C(ird_2_C)
        ird_2_concat_ori = torch.cat([ird_2_A, ird_2_B, ird_2_C], dim=1)
        # print("size ofird_2_concat_ori is:", ird_2_concat_ori.size())
        ird_2_concat_se = self.se_2(ird_2_concat_ori)
        # print("size ofird_2_concat_se is:", ird_2_concat_se.size())
        ird_2_concat_residual = self.onemulone_ird_2_D(ird_2_concat_se)
        # ird_2_concat_residual = self.norm_ird_2(ird_2_concat_residual)
        # ird_2_concat_residual = self.relu_ird_2(ird_2_concat_residual)
        ird_2 = ird_1 + ird_2_concat_residual
        # print("ird_2 size is:", ird_2.size()) 
        ird_2 = self.relu(ird_2)      

        ird_3_A = self.onemulone_ird_3_A(ird_2)
        ird_3_B = self.onemulone_ird_3_B(ird_2)
        ird_3_B = self.dcn_ird_3_B(ird_3_B)
        ird_3_C = self.onemulone_ird_3_C(ird_2)
        ird_3_C = self.dcn_ird_3_C(ird_3_C) # two 3X3 equals one 5X5 deformable conv
        ird_3_C = self.dcn_ird_3_C(ird_3_C)
        ird_3_concat_ori = torch.cat([ird_3_A, ird_3_B, ird_3_C], dim=1)
        # print("size ofird_3_concat_ori is:", ird_3_concat_ori.size())
        ird_3_concat_se = self.se_3(ird_3_concat_ori)
        # print("size ofird_3_concat_se is:", ird_3_concat_se.size())
        ird_3_concat_residual = self.onemulone_ird_3_D(ird_3_concat_se)
        # ird_3_concat_residual = self.norm_ird_3(ird_3_concat_residual)
        # ird_3_concat_residual = self.relu_ird_3(ird_3_concat_residual)
        ird_3 = ird_2 + ird_3_concat_residual
        # print("ird_3 size is:", ird_3.size())
        ird_3 = self.relu(ird_3)

        ird_4_A = self.onemulone_ird_4_A(ird_3)
        ird_4_B = self.onemulone_ird_4_B(ird_3)
        ird_4_B = self.dcn_ird_4_B(ird_4_B)
        ird_4_C = self.onemulone_ird_4_C(ird_3)
        ird_4_C = self.dcn_ird_4_C(ird_4_C) # two 3X3 equals one 5X5 deformable conv
        ird_4_C = self.dcn_ird_4_C(ird_4_C)
        ird_4_concat_ori = torch.cat([ird_4_A, ird_4_B, ird_4_C], dim=1)
        # print("size ofird_4_concat_ori is:", ird_4_concat_ori.size())
        ird_4_concat_se = self.se_4(ird_4_concat_ori)
        # print("size ofird_4_concat_se is:", ird_4_concat_se.size())
        ird_4_concat_residual = self.onemulone_ird_4_D(ird_4_concat_se)
        # ird_4_concat_residual = self.norm_ird_4(ird_4_concat_residual)
        # ird_4_concat_residual = self.relu_ird_4(ird_4_concat_residual)
        ird_4 = ird_3 + ird_4_concat_residual
        # print("ird_4 size is:", ird_4.size())
        ird_4 = self.relu(ird_4)

        e4_h = self.conv4_1_h(ird_4)
        # e4_h = self.relu4_1_h(e4_h)
        # e4_h = self.conv4_2_h(e4_h)
        # e4_h = self.relu4_2_h(e4_h)
        # e4_h = self.conv4_3_h(e4_h)
        e4_h = self.norm4_h(e4_h)
        e4_h = self.relu4_3_h(e4_h)
        e4_h = self.max4_h(e4_h)
        # print("e4_h size is :", e4_h.size())

        ird_5_A = self.onemulone_ird_5_A(e4_h)
        ird_5_B = self.onemulone_ird_5_B(e4_h)
        ird_5_B = self.dcn_ird_5_B(ird_5_B)
        ird_5_C = self.onemulone_ird_5_C(e4_h)
        ird_5_C = self.dcn_ird_5_C(ird_5_C) # two 3X3 equals one 5X5 deformable conv
        ird_5_C = self.dcn_ird_5_C(ird_5_C)
        ird_5_concat_ori = torch.cat([ird_5_A, ird_5_B, ird_5_C], dim=1)
        # print("size ofird_5_concat_ori is:", ird_5_concat_ori.size())
        ird_5_concat_se = self.se_5(ird_5_concat_ori)
        # print("size ofird_5_concat_se is:", ird_5_concat_se.size())
        ird_5_concat_residual = self.onemulone_ird_5_D(ird_5_concat_se)
        # ird_5_concat_residual = self.norm_ird_5(ird_5_concat_residual)
        # ird_5_concat_residual = self.relu_ird_5(ird_5_concat_residual)
        ird_5 = e4_h + ird_5_concat_residual
        # print("ird_5 size is:", ird_5.size())
        ird_5 = self.relu(ird_5)

        ird_6_A = self.onemulone_ird_6_A(ird_5)
        ird_6_B = self.onemulone_ird_6_B(ird_5)
        ird_6_B = self.dcn_ird_6_B(ird_6_B)
        ird_6_C = self.onemulone_ird_6_C(ird_5)
        ird_6_C = self.dcn_ird_6_C(ird_6_C) # two 3X3 equals one 5X5 deformable conv
        ird_6_C = self.dcn_ird_6_C(ird_6_C)
        ird_6_concat_ori = torch.cat([ird_6_A, ird_6_B, ird_6_C], dim=1)
        # print("size ofird_6_concat_ori is:", ird_6_concat_ori.size())
        ird_6_concat_se = self.se_6(ird_6_concat_ori)
        # print("size ofird_6_concat_se is:", ird_6_concat_se.size())
        ird_6_concat_residual = self.onemulone_ird_6_D(ird_6_concat_se)
        # ird_6_concat_residual = self.norm_ird_6(ird_6_concat_residual)
        # ird_6_concat_residual = self.relu_ird_6(ird_6_concat_residual)
        ird_6 = ird_5 + ird_6_concat_residual
        # print("ird_6 size is:", ird_6.size())
        ird_6 = self.relu(ird_6)

        ird_7_A = self.onemulone_ird_7_A(ird_6)
        ird_7_B = self.onemulone_ird_7_B(ird_6)
        ird_7_B = self.dcn_ird_7_B(ird_7_B)
        ird_7_C = self.onemulone_ird_7_C(ird_6)
        ird_7_C = self.dcn_ird_7_C(ird_7_C) # two 3X3 equals one 5X5 deformable conv
        ird_7_C = self.dcn_ird_7_C(ird_7_C)
        ird_7_concat_ori = torch.cat([ird_7_A, ird_7_B, ird_7_C], dim=1)
        # print("size ofird_7_concat_ori is:", ird_7_concat_ori.size())
        ird_7_concat_se = self.se_7(ird_7_concat_ori)
        # print("size ofird_7_concat_se is:", ird_7_concat_se.size())
        ird_7_concat_residual = self.onemulone_ird_7_D(ird_7_concat_se)
        # ird_7_concat_residual = self.norm_ird_7(ird_7_concat_residual)
        # ird_7_concat_residual = self.relu_ird_7(ird_7_concat_residual)
        ird_7 = ird_6 + ird_7_concat_residual
        # print("ird_7 size is:", ird_7.size())
        ird_7 = self.relu(ird_7)

        ird_8_A = self.onemulone_ird_8_A(ird_7)
        ird_8_B = self.onemulone_ird_8_B(ird_7)
        ird_8_B = self.dcn_ird_8_B(ird_8_B)
        ird_8_C = self.onemulone_ird_8_C(ird_7)
        ird_8_C = self.dcn_ird_8_C(ird_8_C) # two 3X3 equals one 5X5 deformable conv
        ird_8_C = self.dcn_ird_8_C(ird_8_C)
        ird_8_concat_ori = torch.cat([ird_8_A, ird_8_B, ird_8_C], dim=1)
        # print("size ofird_8_concat_ori is:", ird_8_concat_ori.size())
        ird_8_concat_se = self.se_8(ird_8_concat_ori)
        # print("size ofird_8_concat_se is:", ird_8_concat_se.size())
        ird_8_concat_residual = self.onemulone_ird_8_D(ird_8_concat_se)
        # ird_8_concat_residual = self.norm_ird_8(ird_8_concat_residual)
        # ird_8_concat_residual = self.relu_ird_8(ird_8_concat_residual)
        ird_8 = ird_7 + ird_8_concat_residual
        # print("ird_8 size is:", ird_8.size())
        ird_8 = self.relu(ird_8)

        e5_h = self.conv5_1_h(ird_8)
        # e5_h = self.relu5_1_h(e5_h)
        # e5_h = self.conv5_2_h(e5_h)
        # e5_h = self.relu5_2_h(e5_h)
        # e5_h = self.conv5_3_h(e5_h)
        e5_h = self.norm5_h(e5_h)
        e5_h = self.relu5_3_h(e5_h)
        e5_h = self.max5_h(e5_h)
        # print("e5_h size is :", e5_h.size())

        e5_h_concat = torch.cat([e5_upsp, e5_h], dim=1)
        # print("shape of e5_h_concat:", e5_h_concat.size())

        # e5_sd = torch.cat([e5_s, e5_d], dim=1)
        e5_sd = self.channel_spatial_gate_1(e5_h_concat)
        # print("e5_sd size is :", e5_sd.size())

        # d1_h = self.conv6_1_h(e5_h)
        d1_h = self.conv6_1_h(e5_sd)
        # d1_h = self.conv6_1_h(e5_h_concat)
        # d1_h = self.conv6_1_h(e5_h_concat_refine)
        d1_h = self.norm6_h(d1_h)
        d1_h = self.relu6_1_h(d1_h)
        # print("d1_h size is :", d1_h.size())
        
        d2_h = self.conv7_1_h(d1_h)
        # d2 = self.norm7(d2)
        d2_h = self.relu7_1_h(d2_h)
        # print("d2_h size is :", d2_h.size())

        d2_h_sequence_unit = torch.unsqueeze(d2_h, dim=1)
        # print("shape of d2_h_sequence_unit:", d2_h_sequence_unit.size())

        # e5_h_sequence_1 = []
        d2_h_sequence_2 = d2_h_sequence_unit

        for n_sequence in range(4):
            # e5_h_sequence_1.append(e5_h_sequence_unit)
            d2_h_sequence_2 = torch.cat([d2_h_sequence_2, d2_h_sequence_unit], dim=1)


        # print("shape of e5_h_sequence_1:", e5_h_sequence_1.size())
        # print("shape of d2_h_sequence_2:", d2_h_sequence_2.size())

        layer_output_list, last_state_list = self.ConvLSTM_layer_1(d2_h_sequence_2)
        # print("layer_output_list is:", layer_output_list)
        d2_h_refine = layer_output_list[0]
        d2_h_refine = d2_h_refine[:, -1, :, :, :]
        # print("shape of d2_h_refine:", d2_h_refine.size())


        
        # d3_h = self.conv8_1_h(d2_h)
        d3_h = self.conv8_1_h(d2_h_refine)
        # d2 = self.norm7(d2)
        d3_h = self.relu8_1_h(d3_h)
        # print("d3_h size is :", d3_h.size())
        
        d4_h = self.conv9_1_h(d3_h)
        d4_h = self.tanh9_1_h(d4_h)
        # print("d4_h size is :", d4_h.size())

        d4_out = torch.nn.functional.upsample_bilinear(d4_h, size=[120, 160])
        
        d4_h_upsp = self.upsp_output(d4_out)
        # print("d4_h_upsp size is :", d4_h_upsp.size())
        # d4_h_upsp = torch.nn.functional.upsample_bilinear(d4_h_upsp, size=[480, 640])

        return d4_h_upsp, d1_h, d3_h