model.py
def ic_algo(self, g0, p0, p1, maxiter, xtol, is_test=False):
        """
        use IC algorithm to estimate the increment of transformation parameters
        :param g0: initial transformation
        :param p0: point cloud
        :param p1: point cloud
        :param maxiter: maxmimum iteration
        :param xtol: a threashold to check increment of transformation  for early stop
        :return: feature-metric projection error (r), updated transformation (g), encoder-decoder loss
        """
        training = self.encoder.training
        # training = self.decoder.training
        batch_size = p0.size(0)

        self.last_err = None
        g = g0
        self.g_series = torch.zeros(maxiter + 1, *g0.size(), dtype=g0.dtype)
        self.g_series[0] = g0.clone()

        # generate the features
        f0 = self.encoder(p0)
        f1 = self.encoder(p1)

        # task 1
        loss_enco_deco = 0.0
        if not is_test:
            decoder_out_f0 = self.decoder(f0)
            decoder_out_f1 = self.decoder(f1)

            p0_dist1, p0_dist2 = self.chamfer_loss(p0.contiguous(), decoder_out_f0)  # loss function
            loss_net0 = (torch.mean(p0_dist1)) + (torch.mean(p0_dist2))
            p1_dist1, p1_dist2 = self.chamfer_loss(p1.contiguous(), decoder_out_f1)  # loss function
            loss_net1 = (torch.mean(p1_dist1)) + (torch.mean(p1_dist2))
            loss_enco_deco = loss_net0 + loss_net1

        self.encoder.eval()  # and fix them.

        # task 2
        f0 = self.encoder(p0)  # [B, N, 3] -> [B, K]
        # approx. J by finite difference
        dt = self.dt.to(p0).expand(batch_size, 6)  # convert to the type of p0. [B, 6]
        J = self.approx_Jac(p0, f0, dt)
        # compute pinv(J) to solve J*x = -r
        try:
            Jt = J.transpose(1, 2)  # [B, 6, K]
            H = Jt.bmm(J)  # [B, 6, 6]
            # H = H + u_lamda * iDentity
            B = self.inverse(H)
            pinv = B.bmm(Jt)  # [B, 6, K]
        except RuntimeError as err:
            # singular...?
            self.last_err = err
            print(err)
            f1 = self.encoder(p1)  # [B, N, 3] -> [B, K]
            r = f1 - f0
            self.ptnet.train(training)
            return r, g, -1

        itr = 0
        r = None
        for itr in range(maxiter):
            p = self.transform(g.unsqueeze(1), p1)  # [B, 1, 4, 4] x [B, N, 3] -> [B, N, 3]
            f1 = self.encoder(p)  # [B, N, 3] -> [B, K]
            r = f1 - f0  # [B,K]
            dx = -pinv.bmm(r.unsqueeze(-1)).view(batch_size, 6)

            check = dx.norm(p=2, dim=1, keepdim=True).max()
            if float(check) < xtol:
                if itr == 0:
                    self.last_err = 0  # no update.
                break

            g = self.update(g, dx)
            self.g_series[itr + 1] = g.clone()
            self.prev_r = r

        self.encoder.train(training)
        return r, g, loss_enco_deco

        use IC algorithm to estimate the increment of transformation parameters
        :param g0: initial transformation
        :param p0: point cloud
        :param p1: point cloud
        :param maxiter: maxmimum iteration
        :param xtol: a threashold to check increment of transformation  for early stop
        :return: feature-metric projection error (r), updated transformation (g), encoder-decoder loss
        
use IC algorithm to estimate the increment of transformation parameters
use IC algorithm to estimate the increment of transformation parameters
def ic_algo(self, g0, p0, p1, maxiter, xtol, is_test=False):
        training = self.encoder.training
        batch_size = p0.size(0)
        self.last_err = None
        g = g0
        self.g_series = torch.zeros(maxiter + 1, *g0.size(), dtype=g0.dtype)
        self.g_series[0] = g0.clone()
        f0 = self.encoder(p0)
        f1 = self.encoder(p1)
        loss_enco_deco = 0.0
        if not is_test:
            decoder_out_f0 = self.decoder(f0)
            decoder_out_f1 = self.decoder(f1)
            p0_dist1, p0_dist2 = self.chamfer_loss(p0.contiguous(), decoder_out_f0)  
            loss_net0 = (torch.mean(p0_dist1)) + (torch.mean(p0_dist2))
            p1_dist1, p1_dist2 = self.chamfer_loss(p1.contiguous(), decoder_out_f1)  
            loss_net1 = (torch.mean(p1_dist1)) + (torch.mean(p1_dist2))
            loss_enco_deco = loss_net0 + loss_net1
        self.encoder.eval()  
        f0 = self.encoder(p0)  
        dt = self.dt.to(p0).expand(batch_size, 6)  
        J = self.approx_Jac(p0, f0, dt)
        try:
            Jt = J.transpose(1, 2)  
            H = Jt.bmm(J)  
            B = self.inverse(H)
            pinv = B.bmm(Jt)  
        except RuntimeError as err:
            self.last_err = err
            print(err)
            f1 = self.encoder(p1)  
            r = f1 - f0
            self.ptnet.train(training)
            return r, g, -1
        itr = 0
        r = None
        for itr in range(maxiter):
            p = self.transform(g.unsqueeze(1), p1)  
            f1 = self.encoder(p)  
            r = f1 - f0  
            dx = -pinv.bmm(r.unsqueeze(-1)).view(batch_size, 6)
            check = dx.norm(p=2, dim=1, keepdim=True).max()
            if float(check) < xtol:
                if itr == 0:
                    self.last_err = 0  
                break
            g = self.update(g, dx)
            self.g_series[itr + 1] = g.clone()
            self.prev_r = r
        self.encoder.train(training)
        return r, g, loss_enco_deco
def ic_algo ( self , g0 , p0 , p1 , maxiter , xtol , is_test = False ) : training = self . encoder . training batch_size = p0 . size ( 0 ) self . last_err = None g = g0 self . g_series = torch . zeros ( maxiter + 1 , * g0 . size ( ) , dtype = g0 . dtype ) self . g_series [ 0 ] = g0 . clone ( ) f0 = self . encoder ( p0 ) f1 = self . encoder ( p1 ) loss_enco_deco = 0.0 if not is_test : decoder_out_f0 = self . decoder ( f0 ) decoder_out_f1 = self . decoder ( f1 ) p0_dist1 , p0_dist2 = self . chamfer_loss ( p0 . contiguous ( ) , decoder_out_f0 ) loss_net0 = ( torch . mean ( p0_dist1 ) ) + ( torch . mean ( p0_dist2 ) ) p1_dist1 , p1_dist2 = self . chamfer_loss ( p1 . contiguous ( ) , decoder_out_f1 ) loss_net1 = ( torch . mean ( p1_dist1 ) ) + ( torch . mean ( p1_dist2 ) ) loss_enco_deco = loss_net0 + loss_net1 self . encoder . eval ( ) f0 = self . encoder ( p0 ) dt = self . dt . to ( p0 ) . expand ( batch_size , 6 ) J = self . approx_Jac ( p0 , f0 , dt ) try : Jt = J . transpose ( 1 , 2 ) H = Jt . bmm ( J ) B = self . inverse ( H ) pinv = B . bmm ( Jt ) except RuntimeError as err : self . last_err = err print ( err ) f1 = self . encoder ( p1 ) r = f1 - f0 self . ptnet . train ( training ) return r , g , - 1 itr = 0 r = None for itr in range ( maxiter ) : p = self . transform ( g . unsqueeze ( 1 ) , p1 ) f1 = self . encoder ( p ) r = f1 - f0 dx = - pinv . bmm ( r . unsqueeze ( - 1 ) ) . view ( batch_size , 6 ) check = dx . norm ( p = 2 , dim = 1 , keepdim = True ) . max ( ) if float ( check ) < xtol : if itr == 0 : self . last_err = 0 break g = self . update ( g , dx ) self . g_series [ itr + 1 ] = g . clone ( ) self . prev_r = r self . encoder . train ( training ) return r , g , loss_enco_deco
use IC algorithm to estimate the increment of transformation parameters
use IC algorithm to estimate the increment of transformation parameters
"""
        use IC algorithm to estimate the increment of transformation parameters
        :param g0: initial transformation
        :param p0: point cloud
        :param p1: point cloud
        :param maxiter: maxmimum iteration
        :param xtol: a threashold to check increment of transformation  for early stop
        :return: feature-metric projection error (r), updated transformation (g), encoder-decoder loss
        """ # training = self.decoder.training # generate the features # task 1 # loss function # loss function # and fix them. # task 2 # [B, N, 3] -> [B, K] # approx. J by finite difference # convert to the type of p0. [B, 6] # compute pinv(J) to solve J*x = -r # [B, 6, K] # [B, 6, 6] # H = H + u_lamda * iDentity # [B, 6, K] # singular...? # [B, N, 3] -> [B, K] # [B, 1, 4, 4] x [B, N, 3] -> [B, N, 3] # [B, N, 3] -> [B, K] # [B,K] # no update.
feature-metric projection error (r), updated transformation (g), encoder-decoder loss
feature - metric projection error ( r ) updated transformation ( g ) encoder - decoder loss
self
g0
None
p0
None
p1
None
maxiter
None
xtol
a threashold to check increment of transformation  for early stop
a threashold to check increment of transformation for early stop
is_test