Beispiel #1
0
def tps_nr_fit_enhanced(x_na, y_ng, bend_coef, nr_ma, nr_coef):

    N, D = x_na.shape
    M = nr_ma.shape[0]
    E = N + 4 * M
    F = E - M
    Q = N + 3 * M - 4

    s = .1  # tetrahedron sidelength (meters)
    u = 1 / (2 * np.sqrt(2))

    tetra_pts = []
    for pt in nr_ma:
        tetra_pts.append(s * np.r_[-.5, 0, -u] + pt)
        tetra_pts.append(s * np.r_[+.5, 0, -u] + pt)
        tetra_pts.append(s * np.r_[0, -.5, +u] + pt)
        tetra_pts.append(s * np.r_[0, +.5, +u] + pt)

    x_ea = np.r_[x_na, tetra_pts]

    badsub_ex = np.c_[x_ea,
                      np.ones((E, 1)), np.r_[np.zeros((N, M)),
                                             np.repeat(np.eye(M), 4, axis=0)]]
    lin_ag, trans_g, w_ng = tps_fit2(x_na, y_ng, bend_coef, 1e-3)
    w_eg = np.r_[w_ng, np.zeros((4 * M, D))]

    assert badsub_ex.shape[0] >= badsub_ex.shape[1]
    _u, _s, _vh = np.linalg.svd(badsub_ex, full_matrices=True)
    assert badsub_ex.shape[1] == _s.size
    N_eq = _u[:, badsub_ex.shape[1]:]  # null of data

    assert N_eq.shape == (E, Q)

    assert E == N + 4 * M
    assert F == Q + 4
    # e is number of kernels
    # q is number of nonrigid dofs
    # f is total number of dofs
    K_ee = tps_kernel_matrix(x_ea)
    K_ne = K_ee[:N, :]
    Q_nf = np.c_[x_na, np.ones((N, 1)), K_ne.dot(N_eq)]
    QQ_ff = np.dot(Q_nf.T, Q_nf)
    Bend_ff = np.zeros((F, F))
    Bend_ff[4:, 4:] = -N_eq.T.dot(K_ee.dot(N_eq))  # K_qq

    assert Q_nf.shape == (N, F)
    assert w_eg.shape == (E, D)

    n_iter = 40
    for i in xrange(n_iter):

        # if plotting and i%plotting==0:
        # import lfd.registration as lr
        # lr.Globals.setup()
        # def eval_partial(x_ma):
        #     return tps_eval(x_ma, lin_ag, trans_g, w_eg, x_ea)
        # lr.plot_orig_and_warped_clouds(eval_partial, x_na, y_ng, res=.008)

        X_fg = np.r_[lin_ag, trans_g[None, :], N_eq.T.dot(w_eg)]

        res_cost, bend_cost, nr_cost, fval = tps_nr_cost_eval_general(
            lin_ag,
            trans_g,
            w_eg,
            x_ea,
            y_ng,
            nr_ma,
            bend_coef,
            nr_coef,
            return_tuple=True)
        if VERBOSE:
            print colorize("iteration %i, cost %.3e" % (i, fval), 'red'),
        if VERBOSE:
            print "= %.3e (res) + %.3e (bend) + %.3e (nr)" % (
                res_cost, bend_cost, nr_cost)

        Jl_zcg, Jt_zg, Jw_zeg = tps_nr_grad(nr_ma,
                                            lin_ag,
                                            trans_g,
                                            w_eg,
                                            x_ea,
                                            return_tuple=True)
        nrerr_z = tps_nr_err(nr_ma, lin_ag, trans_g, w_eg, x_ea)

        fullstep_fg = np.empty((F, D))
        for g in xrange(D):
            J_zf = np.c_[Jl_zcg[:, g::D], Jt_zg[:, g::D],
                         Jw_zeg[:, g::D].dot(N_eq)]
            JJ_ff = np.dot(J_zf.T, J_zf)
            A_ff = nr_coef * JJ_ff + QQ_ff + bend_coef * Bend_ff
            X0 = X_fg[:, g]
            B_f = nr_coef * np.dot(J_zf.T,
                                   np.dot(J_zf, X0) - nrerr_z) + Q_nf.T.dot(
                                       y_ng[:, g])
            fullstep_fg[:, g] = np.linalg.solve(A_ff, B_f) - X_fg[:, g]

        cost_improved = False
        for stepsize in 3.**np.arange(0, -10, -1):
            cand_X_fg = X_fg + fullstep_fg * stepsize
            cand_lin_ag, cand_trans_g, cand_w_eg = cand_X_fg[:D], cand_X_fg[
                D], N_eq.dot(cand_X_fg[D + 1:])
            fval_cand = tps_nr_cost_eval_general(cand_lin_ag,
                                                 cand_trans_g,
                                                 cand_w_eg,
                                                 x_ea,
                                                 y_ng,
                                                 nr_ma,
                                                 bend_coef,
                                                 nr_coef,
                                                 return_tuple=False)
            if VERBOSE:
                print "stepsize: %.1g, fval: %.3e" % (stepsize, fval_cand)
            if fval_cand < fval:
                cost_improved = True
                break
        if not cost_improved:
            if VERBOSE: print "couldn't improve objective"
            break

        lin_ag = cand_lin_ag
        trans_g = cand_trans_g
        w_eg = cand_w_eg
    return lin_ag, trans_g, w_eg, x_ea
Beispiel #2
0
Datei: tps.py Projekt: amoliu/lfd
def tps_nr_fit_enhanced(x_na, y_ng, bend_coef, nr_ma, nr_coef):
    
    N,D = x_na.shape
    M = nr_ma.shape[0]
    E = N + 4*M
    F = E - M
    Q = N + 3*M - 4
    
    s = .1 # tetrahedron sidelength (meters)
    u = 1/(2*np.sqrt(2))
    
    tetra_pts = []
    for pt in nr_ma:
        tetra_pts.append(s*np.r_[-.5, 0, -u]+pt)
        tetra_pts.append(s*np.r_[+.5, 0, -u]+pt)
        tetra_pts.append(s*np.r_[0, -.5, +u]+pt)
        tetra_pts.append(s*np.r_[0, +.5, +u]+pt)
    
    x_ea = np.r_[x_na, tetra_pts]

    badsub_ex = np.c_[x_ea, np.ones((E,1)), np.r_[np.zeros((N,M)), np.repeat(np.eye(M), 4, axis=0)]]    
    lin_ag, trans_g, w_ng = tps_fit2(x_na, y_ng,  bend_coef, 1e-3)
    w_eg = np.r_[w_ng, np.zeros((4*M, D))]

    assert badsub_ex.shape[0] >= badsub_ex.shape[1]
    _u,_s,_vh = np.linalg.svd(badsub_ex, full_matrices=True)
    assert badsub_ex.shape[1] == _s.size
    N_eq = _u[:,badsub_ex.shape[1]:] # null of data
        
    assert N_eq.shape == (E,Q)

    assert E == N + 4*M
    assert F == Q + 4
    # e is number of kernels
    # q is number of nonrigid dofs
    # f is total number of dofs
    K_ee = tps_kernel_matrix(x_ea)
    K_ne = K_ee[:N, :]
    Q_nf = np.c_[x_na, np.ones((N,1)),K_ne.dot(N_eq)]
    QQ_ff = np.dot(Q_nf.T, Q_nf)
    Bend_ff = np.zeros((F,F))
    Bend_ff[4:, 4:] = - N_eq.T.dot(K_ee.dot(N_eq)) # K_qq
    
    assert Q_nf.shape == (N, F)
    assert w_eg.shape == (E, D)
    
    n_iter=40
    for i in xrange(n_iter):
        
        
        # if plotting and i%plotting==0:
            # import lfd.registration as lr
            # lr.Globals.setup()
            # def eval_partial(x_ma):
            #     return tps_eval(x_ma, lin_ag, trans_g, w_eg, x_ea) 
            # lr.plot_orig_and_warped_clouds(eval_partial, x_na, y_ng, res=.008)            
        
        X_fg = np.r_[lin_ag, 
                    trans_g[None,:], 
                    N_eq.T.dot(w_eg)]

        res_cost, bend_cost, nr_cost, fval = tps_nr_cost_eval_general(lin_ag, trans_g, w_eg, x_ea, y_ng, nr_ma, bend_coef, nr_coef, return_tuple=True)
        if VERBOSE: print colorize("iteration %i, cost %.3e"%(i, fval), 'red'),
        if VERBOSE: print "= %.3e (res) + %.3e (bend) + %.3e (nr)"%(res_cost, bend_cost, nr_cost)
                
        
        Jl_zcg, Jt_zg, Jw_zeg = tps_nr_grad(nr_ma, lin_ag, trans_g, w_eg, x_ea, return_tuple=True)
        nrerr_z = tps_nr_err(nr_ma, lin_ag, trans_g, w_eg, x_ea)        
        
        fullstep_fg = np.empty((F,D))
        for g in xrange(D):
            J_zf = np.c_[Jl_zcg[:,g::D], Jt_zg[:,g::D], Jw_zeg[:,g::D].dot(N_eq)]
            JJ_ff = np.dot(J_zf.T, J_zf)
            A_ff = nr_coef*JJ_ff + QQ_ff + bend_coef*Bend_ff
            X0 = X_fg[:,g]
            B_f = nr_coef*np.dot(J_zf.T, np.dot(J_zf, X0) - nrerr_z) + Q_nf.T.dot(y_ng[:,g])
            fullstep_fg[:,g] = np.linalg.solve(A_ff,B_f) - X_fg[:,g]

        cost_improved = False
        for stepsize in 3.**np.arange(0,-10,-1):
            cand_X_fg = X_fg + fullstep_fg*stepsize
            cand_lin_ag, cand_trans_g, cand_w_eg = cand_X_fg[:D], cand_X_fg[D], N_eq.dot(cand_X_fg[D+1:])
            fval_cand = tps_nr_cost_eval_general(cand_lin_ag, cand_trans_g, cand_w_eg, x_ea, y_ng, nr_ma, bend_coef, nr_coef, return_tuple=False)
            if VERBOSE: print "stepsize: %.1g, fval: %.3e"%(stepsize, fval_cand)
            if fval_cand < fval:
                cost_improved = True
                break
        if not cost_improved:
            if VERBOSE: print "couldn't improve objective"
            break

            
        lin_ag = cand_lin_ag
        trans_g = cand_trans_g
        w_eg = cand_w_eg
    return lin_ag, trans_g, w_eg, x_ea
Beispiel #3
0
def tps_nr_fit(x_na, y_ng, bend_coef, nr_ma, nr_coef, method="newton"):
    N, D = x_na.shape
    lin_ag, trans_g, w_ng = tps_fit2(x_na, y_ng, bend_coef, 1e-3)
    #return lin_ag, trans_g, w_ng

    ##for testing that it takes one step when nonrigidity cost is zero:
    #lin_ag, trans_g, w_ng = tps_fit(x_na, y_ng, bend_coef, 0)
    #res_cost, bend_cost, nr_cost, fval = tps_nr_cost_eval(lin_ag, trans_g, w_ng, x_na, nr_ma, bend_coef, nr_coef, return_tuple=True)
    #print "CORRECT COST, res,bend,nr,total = %.3e, %.3e, %.3e, %.3e"%(res_cost, bend_cost, nr_cost, fval)
    #lin_ag += np.random.randn(*lin_ag.shape)*5
    #res_cost, bend_cost, nr_cost, fval = tps_nr_cost_eval(lin_ag, trans_g, w_ng, x_na, nr_ma, bend_coef, nr_coef, return_tuple=True)
    #print "NOISE ADDED COST, res,bend,nr,total = %.ef, %.3e, %.3e, %.3e"%(res_cost, bend_cost, nr_cost, fval)

    _u, _s, _vh = np.linalg.svd(np.c_[x_na, np.ones((N, 1))],
                                full_matrices=True)
    N_nq = _u[:, 4:]  # null of data
    #w_ng = N_nq.dot(N_nq.T.dot(w_ng))

    K_nn = tps_kernel_matrix(x_na)
    Q_nn = np.c_[x_na, np.ones((N, 1)), K_nn.dot(N_nq)]
    QQ_nn = np.dot(Q_nn.T, Q_nn)
    Bend_nn = np.zeros((N, N))
    Bend_nn[4:, 4:] = -N_nq.T.dot(K_nn.dot(N_nq))

    n_iter = 60
    for i in xrange(n_iter):
        X_ng = np.r_[lin_ag, trans_g[None, :], N_nq.T.dot(w_ng)]

        res_cost, bend_cost, nr_cost, fval = tps_nr_cost_eval(
            lin_ag,
            trans_g,
            w_ng,
            x_na,
            y_ng,
            nr_ma,
            bend_coef,
            nr_coef,
            return_tuple=True)
        if VERBOSE:
            print colorize("iteration %i, cost %.3e" % (i, fval), 'red'),
        if VERBOSE:
            print "= %.3e (res) + %.3e (bend) + %.3e (nr)" % (
                res_cost, bend_cost, nr_cost)

        Jl_zcg, Jt_zg, Jw_zng = tps_nr_grad(nr_ma,
                                            lin_ag,
                                            trans_g,
                                            w_ng,
                                            x_na,
                                            return_tuple=True)
        nrerr_z = tps_nr_err(nr_ma, lin_ag, trans_g, w_ng, x_na)

        if method == "newton":
            fullstep_ng = np.empty((N, D))
            for g in xrange(D):
                J_zn = np.c_[Jl_zcg[:, g::D], Jt_zg[:, g::D],
                             Jw_zng[:, g::D].dot(N_nq)]
                JJ_nn = np.dot(J_zn.T, J_zn)
                A = nr_coef * JJ_nn + QQ_nn + bend_coef * Bend_nn
                X0 = X_ng[:, g]
                B = nr_coef * np.dot(J_zn.T,
                                     np.dot(J_zn, X0) - nrerr_z) + Q_nn.T.dot(
                                         y_ng[:, g])
                fullstep_ng[:, g] = np.linalg.solve(A, B) - X_ng[:, g]

        elif method == "gradient":
            # def eval_partial(cand_X_ng):
            #     cand_X_ng = cand_X_ng.reshape(-1,3)
            #     cand_lin_ag, cand_trans_g, cand_w_ng = cand_X_ng[:D], cand_X_ng[D], N_nq.dot(cand_X_ng[D+1:])
            #     fval_cand = tps_nr_cost_eval(cand_lin_ag, cand_trans_g, cand_w_ng, x_na, y_ng, nr_ma, bend_coef, nr_coef)
            #     return fval_cand
            # def eval_partial2(cand_X_ng):
            #     return ((Q_nn.dot(X_ng) - y_ng)**2).sum()
            # def eval_partial3(cand_X_ng):
            #     cand_X_ng = cand_X_ng.reshape(-1,3)
            #     cand_lin_ag, cand_trans_g, cand_w_ng = cand_X_ng[:D], cand_X_ng[D], N_nq.dot(cand_X_ng[D+1:])
            #     return ((y_ng - tps_eval(x_na, cand_lin_ag, cand_trans_g, cand_w_ng, x_na))**2).sum()

            grad_ng = np.empty((N, D))
            for g in xrange(D - 1, -1, -1):
                Jnr_zn = np.c_[Jl_zcg[:, g::D], Jt_zg[:, g::D],
                               Jw_zng[:, g::D].dot(N_nq)]
                grad_ng[:,g] = 2 * nr_coef * nrerr_z.dot(Jnr_zn) \
                    + 2 * Q_nn.T.dot(Q_nn.dot(X_ng[:,g]) - y_ng[:,g]) \
                    + 2 * bend_coef * Bend_nn.dot(X_ng[:,g])

            #assert np.allclose(eval_partial2(X_ng), eval_partial3(X_ng))
            #assert np.allclose(eval_partial(X_ng), eval_partial2(X_ng))
            #grad0_ng = ndt.Gradient(eval_partial)(X_ng.flatten()).reshape(-1,3)
            fullstep_ng = -grad_ng
            #assert np.allclose(grad0_ng, grad_ng)

        cost_improved = False
        for stepsize in 3.**np.arange(0, -10, -1):
            cand_X_ng = X_ng + fullstep_ng * stepsize
            cand_lin_ag, cand_trans_g, cand_w_ng = cand_X_ng[:D], cand_X_ng[
                D], N_nq.dot(cand_X_ng[D + 1:])
            fval_cand = tps_nr_cost_eval(cand_lin_ag, cand_trans_g, cand_w_ng,
                                         x_na, y_ng, nr_ma, bend_coef, nr_coef)
            if VERBOSE:
                print "stepsize: %.1g, fval: %.3e" % (stepsize, fval_cand)
            if fval_cand < fval:
                cost_improved = True
                break
        if not cost_improved:
            if VERBOSE: print "couldn't improve objective"
            break

        lin_ag = cand_lin_ag
        trans_g = cand_trans_g
        w_ng = cand_w_ng
    return lin_ag, trans_g, w_ng
Beispiel #4
0
Datei: tps.py Projekt: amoliu/lfd
def tps_nr_fit(x_na, y_ng, bend_coef, nr_ma, nr_coef, method="newton"):
    N,D = x_na.shape
    lin_ag, trans_g, w_ng = tps_fit2(x_na, y_ng, bend_coef, 1e-3)
    #return lin_ag, trans_g, w_ng

    ##for testing that it takes one step when nonrigidity cost is zero:
    #lin_ag, trans_g, w_ng = tps_fit(x_na, y_ng, bend_coef, 0)
    #res_cost, bend_cost, nr_cost, fval = tps_nr_cost_eval(lin_ag, trans_g, w_ng, x_na, nr_ma, bend_coef, nr_coef, return_tuple=True)
    #print "CORRECT COST, res,bend,nr,total = %.3e, %.3e, %.3e, %.3e"%(res_cost, bend_cost, nr_cost, fval)
    #lin_ag += np.random.randn(*lin_ag.shape)*5
    #res_cost, bend_cost, nr_cost, fval = tps_nr_cost_eval(lin_ag, trans_g, w_ng, x_na, nr_ma, bend_coef, nr_coef, return_tuple=True)
    #print "NOISE ADDED COST, res,bend,nr,total = %.ef, %.3e, %.3e, %.3e"%(res_cost, bend_cost, nr_cost, fval)
    
    _u,_s,_vh = np.linalg.svd(np.c_[x_na, np.ones((N,1))], full_matrices=True)
    N_nq = _u[:,4:] # null of data
    #w_ng = N_nq.dot(N_nq.T.dot(w_ng))
        
    K_nn = tps_kernel_matrix(x_na)
    Q_nn = np.c_[x_na, np.ones((N,1)),K_nn.dot(N_nq)]
    QQ_nn = np.dot(Q_nn.T, Q_nn)
    Bend_nn = np.zeros((N,N))
    Bend_nn[4:, 4:] = - N_nq.T.dot(K_nn.dot(N_nq))
    
    n_iter=60
    for i in xrange(n_iter):
        X_ng = np.r_[lin_ag, trans_g[None,:], N_nq.T.dot(w_ng)]

        res_cost, bend_cost, nr_cost, fval = tps_nr_cost_eval(lin_ag, trans_g, w_ng, x_na, y_ng, nr_ma, bend_coef, nr_coef, return_tuple=True)
        if VERBOSE: print colorize("iteration %i, cost %.3e"%(i, fval), 'red'),
        if VERBOSE: print "= %.3e (res) + %.3e (bend) + %.3e (nr)"%(res_cost, bend_cost, nr_cost)
                
        
        Jl_zcg, Jt_zg, Jw_zng = tps_nr_grad(nr_ma, lin_ag, trans_g, w_ng, x_na, return_tuple=True)
        nrerr_z = tps_nr_err(nr_ma, lin_ag, trans_g, w_ng, x_na)
        
        
        if method == "newton":
            fullstep_ng = np.empty((N,D))
            for g in xrange(D):
                J_zn = np.c_[Jl_zcg[:,g::D], Jt_zg[:,g::D], Jw_zng[:,g::D].dot(N_nq)]
                JJ_nn = np.dot(J_zn.T, J_zn)
                A = nr_coef*JJ_nn + QQ_nn + bend_coef*Bend_nn
                X0 = X_ng[:,g]
                B = nr_coef*np.dot(J_zn.T, np.dot(J_zn, X0) - nrerr_z) + Q_nn.T.dot(y_ng[:,g])
                fullstep_ng[:,g] = np.linalg.solve(A,B) - X_ng[:,g]

        elif method == "gradient":
            # def eval_partial(cand_X_ng):
            #     cand_X_ng = cand_X_ng.reshape(-1,3)
            #     cand_lin_ag, cand_trans_g, cand_w_ng = cand_X_ng[:D], cand_X_ng[D], N_nq.dot(cand_X_ng[D+1:])
            #     fval_cand = tps_nr_cost_eval(cand_lin_ag, cand_trans_g, cand_w_ng, x_na, y_ng, nr_ma, bend_coef, nr_coef)
            #     return fval_cand
            # def eval_partial2(cand_X_ng):
            #     return ((Q_nn.dot(X_ng) - y_ng)**2).sum()
            # def eval_partial3(cand_X_ng):
            #     cand_X_ng = cand_X_ng.reshape(-1,3)
            #     cand_lin_ag, cand_trans_g, cand_w_ng = cand_X_ng[:D], cand_X_ng[D], N_nq.dot(cand_X_ng[D+1:])
            #     return ((y_ng - tps_eval(x_na, cand_lin_ag, cand_trans_g, cand_w_ng, x_na))**2).sum()
            
            
            grad_ng = np.empty((N,D))
            for g in xrange(D-1,-1,-1):
                Jnr_zn = np.c_[Jl_zcg[:,g::D], Jt_zg[:,g::D], Jw_zng[:,g::D].dot(N_nq)]
                grad_ng[:,g] = 2 * nr_coef * nrerr_z.dot(Jnr_zn) \
                    + 2 * Q_nn.T.dot(Q_nn.dot(X_ng[:,g]) - y_ng[:,g]) \
                    + 2 * bend_coef * Bend_nn.dot(X_ng[:,g])

            #assert np.allclose(eval_partial2(X_ng), eval_partial3(X_ng))
            #assert np.allclose(eval_partial(X_ng), eval_partial2(X_ng))
            #grad0_ng = ndt.Gradient(eval_partial)(X_ng.flatten()).reshape(-1,3)
            fullstep_ng = -grad_ng
            #assert np.allclose(grad0_ng, grad_ng)
            
            
            

        cost_improved = False
        for stepsize in 3.**np.arange(0,-10,-1):
            cand_X_ng = X_ng + fullstep_ng*stepsize
            cand_lin_ag, cand_trans_g, cand_w_ng = cand_X_ng[:D], cand_X_ng[D], N_nq.dot(cand_X_ng[D+1:])
            fval_cand = tps_nr_cost_eval(cand_lin_ag, cand_trans_g, cand_w_ng, x_na, y_ng, nr_ma, bend_coef, nr_coef)
            if VERBOSE: print "stepsize: %.1g, fval: %.3e"%(stepsize, fval_cand)
            if fval_cand < fval:
                cost_improved = True
                break
        if not cost_improved:
            if VERBOSE: print "couldn't improve objective"
            break

            
        lin_ag = cand_lin_ag
        trans_g = cand_trans_g
        w_ng = cand_w_ng
    return lin_ag, trans_g, w_ng