//  [python]
def forward(self, x):
        residual = x
        h = x.size(2)
        w = x.size(3)

        out = self.DCR_block11(x)
        conc1= self.DCR_block12(out)
        out = self.down1(conc1)
        
        out = self.DCR_block21(out)
        conc2= self.DCR_block22(out)
        out = self.down2(conc2)

        out = self.DCR_block31(out)
        conc3= self.DCR_block32(out)
        out = self.down3(conc3)

        out = self.DCR_block41(out)
        conc4= self.DCR_block42(out)
        out = self.down4(conc4)
        
        # bridge part
        conc5 = self.uspp(out)

        out = self.up4(conc5)
        out = torch.cat([conc4, out], 1)
        out = self.DCR_block43(out)
        out = self.DCR_block44(out)
        
        out = self.up3(out)
        out = torch.cat([conc3, out], 1)
        out = self.DCR_block33(out)
        out = self.DCR_block34(out)

        out = self.up2(out)
        out = torch.cat([conc2, out], 1)
        out = self.DCR_block23(out)
        out = self.DCR_block24(out)

        out = self.up1(out)
        out = torch.cat([conc1, out], 1)
        out = self.DCR_block13(out)
        out = self.DCR_block14(out)
        
        d1 = self.dsn1(conc1)
        d2 = F.upsample_bilinear(self.dsn2(conc2), size=(h,w))
        d3 = F.upsample_bilinear(self.dsn3(conc3), size=(h,w))
        d4 = F.upsample_bilinear(self.dsn4(conc4), size=(h,w))
        d5 = F.upsample_bilinear(self.dsn5(conc5), size=(h,w))
        d1_out = F.sigmoid(d1)
        d2_out = F.sigmoid(d2)
        d3_out = F.sigmoid(d3)
        d4_out = F.sigmoid(d4)
        d5_out = F.sigmoid(d5)
        concat = torch.cat((d1_out, d2_out, d3_out, d4_out, d5_out), 1)
        
        fuse_box = self.fuse(concat)
        GAP = F.adaptive_avg_pool2d(fuse_box,(1,1))
        GAP = GAP.view(-1, 64)        
        se_like = self.SE_mimic(GAP)        
        se_like = torch.unsqueeze(se_like, 2)
        se_like = torch.unsqueeze(se_like, 3)

        feat_se = concat * se_like.expand_as(concat)
        boundary = self.final_boundary(feat_se)
        boundary_out = torch.unsqueeze(boundary[:,1,:,:],1)        
        bd_sftmax = F.softmax(boundary, dim=1)
        boundary_scale = torch.unsqueeze(bd_sftmax[:,1,:,:],1)        
        
        feat_concat = torch.cat( [out, fuse_box], 1)
        feat_concat_conv = self.final_conv(feat_concat)
        mask = self.final_mask(feat_concat_conv)
        mask_sftmax = F.softmax(mask,dim=1)        
        mask_scale = torch.unsqueeze(mask_sftmax[:,1,:,:],1)

        if self.mode == 'Train':
            scalefactor = torch.clamp(mask_scale+boundary_scale,0,1)            
        elif self.mode == 'Infer':
            scalefactor = torch.clamp(mask_scale+5*boundary_scale,0,1)
        
        
        mask_out = torch.unsqueeze(mask[:,1,:,:],1)
        relu = self.relu(mask_out)        
        scalar = relu.cpu().detach().numpy()
        if np.sum(scalar) == 0:
            average = 0
        else : 
            average = scalar[np.nonzero(scalar)].mean()
        mask_out = mask_out-relu + (average*scalefactor)
        
        if self.mode == 'Train':
            mask_out = F.sigmoid(mask_out)
            boundary_out = F.sigmoid(boundary_out)

            return d1_out, d2_out, d3_out, d4_out, d5_out, boundary_out, mask_out
        elif self.mode =='Infer':
            return mask_out