MiniDPVO / mini_dpvo /lietorch /run_tests.py
pablovela5620's picture
initial commit with working dpvo
899c526
raw
history blame contribute delete
No virus
9.56 kB
import torch
import lietorch
from lietorch import SO3, RxSO3, SE3, Sim3
from gradcheck import gradcheck, get_analytical_jacobian
### forward tests ###
def make_homogeneous(p):
return torch.cat([p, torch.ones_like(p[...,:1])], dim=-1)
def matv(A, b):
return torch.matmul(A, b[...,None])[..., 0]
def test_exp_log(Group, device='cuda'):
""" check Log(Exp(x)) == x """
a = .2*torch.randn(2,3,4,5,6,7,Group.manifold_dim, device=device).double()
b = Group.exp(a).log()
assert torch.allclose(a,b,atol=1e-8), "should be identity"
print("\t-", Group, "Passed exp-log test")
def test_inv(Group, device='cuda'):
""" check X * X^{-1} == 0 """
X = Group.exp(.1*torch.randn(2,3,4,5,Group.manifold_dim, device=device).double())
a = (X * X.inv()).log()
assert torch.allclose(a, torch.zeros_like(a), atol=1e-8), "should be 0"
print("\t-", Group, "Passed inv test")
def test_adj(Group, device='cuda'):
""" check X * Exp(a) == Exp(Adj(X,a)) * X 0 """
X = Group.exp(torch.randn(2,3,4,5, Group.manifold_dim, device=device).double())
a = torch.randn(2,3,4,5, Group.manifold_dim, device=device).double()
b = X.adj(a)
Y1 = X * Group.exp(a)
Y2 = Group.exp(b) * X
c = (Y1 * Y2.inv()).log()
assert torch.allclose(c, torch.zeros_like(c), atol=1e-8), "should be 0"
print("\t-", Group, "Passed adj test")
def test_act(Group, device='cuda'):
X = Group.exp(torch.randn(1, Group.manifold_dim, device=device).double())
p = torch.randn(1,3,device=device).double()
p1 = X.act(p)
p2 = matv(X.matrix(), make_homogeneous(p))
assert torch.allclose(p1, p2[...,:3], atol=1e-8), "should be 0"
print("\t-", Group, "Passed act test")
### backward tests ###
def test_exp_log_grad(Group, device='cuda', tol=1e-8):
D = Group.manifold_dim
def fn(a):
return Group.exp(a).log()
a = torch.zeros(1, Group.manifold_dim, requires_grad=True, device=device).double()
analytical, reentrant, correct_grad_sizes, correct_grad_types = \
get_analytical_jacobian((a,), fn(a))
assert torch.allclose(analytical[0], torch.eye(D, device=device).double(), atol=tol)
a = .2 * torch.randn(1, Group.manifold_dim, requires_grad=True, device=device).double()
analytical, reentrant, correct_grad_sizes, correct_grad_types = \
get_analytical_jacobian((a,), fn(a))
assert torch.allclose(analytical[0], torch.eye(D, device=device).double(), atol=tol)
print("\t-", Group, "Passed eye-grad test")
def test_inv_log_grad(Group, device='cuda', tol=1e-8):
D = Group.manifold_dim
X = Group.exp(.2*torch.randn(1,D,device=device).double())
def fn(a):
return (Group.exp(a) * X).inv().log()
a = torch.zeros(1, D, requires_grad=True, device=device).double()
analytical, numerical = gradcheck(fn, [a], eps=1e-4)
# assert torch.allclose(analytical[0], numerical[0], atol=tol)
if not torch.allclose(analytical[0], numerical[0], atol=tol):
print(analytical[0])
print(numerical[0])
print("\t-", Group, "Passed inv-grad test")
def test_adj_grad(Group, device='cuda'):
D = Group.manifold_dim
X = Group.exp(.5*torch.randn(1,Group.manifold_dim, device=device).double())
def fn(a, b):
return (Group.exp(a) * X).adj(b)
a = torch.zeros(1, D, requires_grad=True, device=device).double()
b = torch.randn(1, D, requires_grad=True, device=device).double()
analytical, numerical = gradcheck(fn, [a, b], eps=1e-4)
assert torch.allclose(analytical[0], numerical[0], atol=1e-8)
assert torch.allclose(analytical[1], numerical[1], atol=1e-8)
print("\t-", Group, "Passed adj-grad test")
def test_adjT_grad(Group, device='cuda'):
D = Group.manifold_dim
X = Group.exp(.5*torch.randn(1,Group.manifold_dim, device=device).double())
def fn(a, b):
return (Group.exp(a) * X).adjT(b)
a = torch.zeros(1, D, requires_grad=True, device=device).double()
b = torch.randn(1, D, requires_grad=True, device=device).double()
analytical, numerical = gradcheck(fn, [a, b], eps=1e-4)
assert torch.allclose(analytical[0], numerical[0], atol=1e-8)
assert torch.allclose(analytical[1], numerical[1], atol=1e-8)
print("\t-", Group, "Passed adjT-grad test")
def test_act_grad(Group, device='cuda'):
D = Group.manifold_dim
X = Group.exp(5*torch.randn(1,D, device=device).double())
def fn(a, b):
return (X*Group.exp(a)).act(b)
a = torch.zeros(1, D, requires_grad=True, device=device).double()
b = torch.randn(1, 3, requires_grad=True, device=device).double()
analytical, numerical = gradcheck(fn, [a, b], eps=1e-4)
assert torch.allclose(analytical[0], numerical[0], atol=1e-8)
assert torch.allclose(analytical[1], numerical[1], atol=1e-8)
print("\t-", Group, "Passed act-grad test")
def test_matrix_grad(Group, device='cuda'):
D = Group.manifold_dim
X = Group.exp(torch.randn(1, D, device=device).double())
def fn(a):
return (Group.exp(a) * X).matrix()
a = torch.zeros(1, D, requires_grad=True, device=device).double()
analytical, numerical = gradcheck(fn, [a], eps=1e-4)
assert torch.allclose(analytical[0], numerical[0], atol=1e-6)
print("\t-", Group, "Passed matrix-grad test")
def extract_translation_grad(Group, device='cuda'):
""" prototype function """
D = Group.manifold_dim
X = Group.exp(5*torch.randn(1,D, device=device).double())
def fn(a):
return (Group.exp(a)*X).translation()
a = torch.zeros(1, D, requires_grad=True, device=device).double()
analytical, numerical = gradcheck(fn, [a], eps=1e-4)
assert torch.allclose(analytical[0], numerical[0], atol=1e-8)
print("\t-", Group, "Passed translation grad test")
def test_vec_grad(Group, device='cuda', tol=1e-6):
D = Group.manifold_dim
X = Group.exp(5*torch.randn(1,D, device=device).double())
def fn(a):
return (Group.exp(a)*X).vec()
a = torch.zeros(1, D, requires_grad=True, device=device).double()
analytical, numerical = gradcheck(fn, [a], eps=1e-4)
assert torch.allclose(analytical[0], numerical[0], atol=tol)
print("\t-", Group, "Passed tovec grad test")
def test_fromvec_grad(Group, device='cuda', tol=1e-6):
def fn(a):
if Group == SO3:
a = a / a.norm(dim=-1, keepdim=True)
elif Group == RxSO3:
q, s = a.split([4, 1], dim=-1)
q = q / q.norm(dim=-1, keepdim=True)
a = torch.cat([q, s.exp()], dim=-1)
elif Group == SE3:
t, q = a.split([3, 4], dim=-1)
q = q / q.norm(dim=-1, keepdim=True)
a = torch.cat([t, q], dim=-1)
elif Group == Sim3:
t, q, s = a.split([3, 4, 1], dim=-1)
q = q / q.norm(dim=-1, keepdim=True)
a = torch.cat([t, q, s.exp()], dim=-1)
return Group.InitFromVec(a).vec()
D = Group.embedded_dim
a = torch.randn(1, 2, D, requires_grad=True, device=device).double()
analytical, numerical = gradcheck(fn, [a], eps=1e-4)
assert torch.allclose(analytical[0], numerical[0], atol=tol)
print("\t-", Group, "Passed fromvec grad test")
def scale(device='cuda'):
def fn(a, s):
X = SE3.exp(a)
X.scale(s)
return X.log()
s = torch.rand(1, requires_grad=True, device=device).double()
a = torch.randn(1, 6, requires_grad=True, device=device).double()
analytical, numerical = gradcheck(fn, [a, s], eps=1e-3)
print(analytical[1])
print(numerical[1])
assert torch.allclose(analytical[0], numerical[0], atol=1e-8)
assert torch.allclose(analytical[1], numerical[1], atol=1e-8)
print("\t-", "Passed se3-to-sim3 test")
if __name__ == '__main__':
print("Testing lietorch forward pass (CPU) ...")
for Group in [SO3, RxSO3, SE3, Sim3]:
test_exp_log(Group, device='cpu')
test_inv(Group, device='cpu')
test_adj(Group, device='cpu')
test_act(Group, device='cpu')
print("Testing lietorch backward pass (CPU)...")
for Group in [SO3, RxSO3, SE3, Sim3]:
if Group == Sim3:
tol = 1e-3
else:
tol = 1e-8
test_exp_log_grad(Group, device='cpu', tol=tol)
test_inv_log_grad(Group, device='cpu', tol=tol)
test_adj_grad(Group, device='cpu')
test_adjT_grad(Group, device='cpu')
test_act_grad(Group, device='cpu')
test_matrix_grad(Group, device='cpu')
extract_translation_grad(Group, device='cpu')
test_vec_grad(Group, device='cpu')
test_fromvec_grad(Group, device='cpu')
print("Testing lietorch forward pass (GPU) ...")
for Group in [SO3, RxSO3, SE3, Sim3]:
test_exp_log(Group, device='cuda')
test_inv(Group, device='cuda')
test_adj(Group, device='cuda')
test_act(Group, device='cuda')
print("Testing lietorch backward pass (GPU)...")
for Group in [SO3, RxSO3, SE3, Sim3]:
if Group == Sim3:
tol = 1e-3
else:
tol = 1e-8
test_exp_log_grad(Group, device='cuda', tol=tol)
test_inv_log_grad(Group, device='cuda', tol=tol)
test_adj_grad(Group, device='cuda')
test_adjT_grad(Group, device='cuda')
test_act_grad(Group, device='cuda')
test_matrix_grad(Group, device='cuda')
extract_translation_grad(Group, device='cuda')
test_vec_grad(Group, device='cuda')
test_fromvec_grad(Group, device='cuda')