Skip to content
Draft
Changes from 1 commit
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
1918b45
gbp implementation for pose graph problem, euclidean and lie algebra
joeaortiz Mar 16, 2022
6edf81b
Merge branch 'main' into joe.gbp_optimizer
joeaortiz Mar 16, 2022
31a8874
gbp uses exp_map jacobians
joeaortiz Mar 16, 2022
1a6eae4
gaussian for Manifold rather than Variable class
joeaortiz Mar 16, 2022
a7a6e4d
Merge branch 'main' into joe.gbp_optimizer
joeaortiz Mar 17, 2022
e93aa49
uses proper theseus exp_map jacobian
joeaortiz Apr 4, 2022
aa7062e
gaussian class plus marginals and message class
joeaortiz Apr 5, 2022
4479f3b
updated gaussian class
joeaortiz Apr 7, 2022
fc12a98
message scheduler
joeaortiz Apr 8, 2022
264ed22
added mean damping in lin point space
joeaortiz Apr 13, 2022
d5937b4
Merge branch 'main' into joe.gbp_optimizer
joeaortiz Apr 20, 2022
8092a03
fix in linearise and add ba exmple
joeaortiz Apr 20, 2022
106b57d
Merge branch 'main' into joe.gbp_optimizer
joeaortiz Apr 20, 2022
4100342
use th.Manifold gaussian
joeaortiz Apr 22, 2022
b26e1a3
ba tests, fixing numerical issues
joeaortiz Apr 25, 2022
b4c387a
ba viewer
joeaortiz May 5, 2022
b75cfca
bundle adjustment trimesh vis
joeaortiz Jun 1, 2022
40575f4
soft huber-like loss on norm of x,y error
joeaortiz Jun 1, 2022
a91754e
remove prints and fix viewer
joeaortiz Jun 6, 2022
32380fb
remove symmetric check
joeaortiz Jun 6, 2022
2aa58a1
ba visualisation and derivates setup for pgo
joeaortiz Jun 6, 2022
4c91944
lin system damping for ftov msgs
joeaortiz Jun 10, 2022
d1244e8
static dense solver methods
joeaortiz Jun 10, 2022
87cac1e
ba with damping in linear system
joeaortiz Jun 10, 2022
34133be
backward modes
joeaortiz Jun 10, 2022
4263ef5
msgs are class variables to fix implicit backward mode
joeaortiz Jun 10, 2022
7b1bf78
test different backward modes for pgo
joeaortiz Jun 10, 2022
b6f6748
Merge branch 'main' into joe.gbp_optimizer
joeaortiz Jun 10, 2022
6c07c34
fixed copy_impl for reprojection error fn
joeaortiz Jun 11, 2022
d2bd2ae
fix order of args in copy fn
joeaortiz Jun 12, 2022
9f6eb09
used vectorization for part of relin, rename VariableDifference
joeaortiz Jun 12, 2022
78bb120
handles batched problems
joeaortiz Jul 4, 2022
c1b2449
vectorized relinearization and ftov msg passing, schedule class
joeaortiz Jul 5, 2022
c7d9b1c
added missing aux vars to reprojection error cf
joeaortiz Jul 5, 2022
c81210a
Merge branch main into joe.gbp_optimizer
joeaortiz Jul 6, 2022
954a154
vectorized vtof msg passing
joeaortiz Jul 7, 2022
8bcd2cd
handles vectorized inversion with some singular matrices, only comput…
joeaortiz Jul 7, 2022
eaeab00
removed random message schedule
joeaortiz Jul 8, 2022
0700e2e
merge with main
joeaortiz Jul 15, 2022
d8c774a
damping linear system
joeaortiz Jul 18, 2022
ea5173f
local linear damping, fixes for gbp on gpu
joeaortiz Jul 18, 2022
c2507e3
handle loading different format bal file and drop observations
joeaortiz Jul 18, 2022
400091b
gbp check unary factor, fix bug in ba viewer
joeaortiz Jul 20, 2022
9db9612
ba error plot
joeaortiz Jul 20, 2022
12f0b77
fixed are calculation
joeaortiz Jul 22, 2022
255a5b5
tensor for linear system damping, rename message damping
joeaortiz Aug 2, 2022
634ce74
fixes bug where beleifs and factors are created twice
joeaortiz Aug 4, 2022
39be1f1
nesterov, no grad for lm damping, ba batch experiments
joeaortiz Aug 26, 2022
25e87de
nesterov acceleration, two modes
joeaortiz Sep 6, 2022
4e1a4b1
swarm exp
joeaortiz Sep 8, 2022
37f7ed5
learning target for agents
joeaortiz Sep 9, 2022
a6b7274
target character and joint mlp + gbp
joeaortiz Sep 16, 2022
89f0c78
fixed jacobians for gnn factor
joeaortiz Sep 20, 2022
8a75767
implicit backward mode for GBP using GN step
joeaortiz Sep 26, 2022
75c3157
implicit derivatives using gbp and plot backward modes against time
joeaortiz Sep 30, 2022
a7db963
Merge main
joeaortiz Dec 22, 2022
53e4b91
moved into optimizer, removed experiments
joeaortiz Dec 30, 2022
82fc597
Moved import, fixed single wrapper vectorization
joeaortiz Jan 4, 2023
8a01154
update vectorization before truncated steps
joeaortiz Jan 4, 2023
0644e94
Moved bundle adjustment edits to experimental branch
joeaortiz Jan 4, 2023
4a81901
flake8 on github not gitlab
joeaortiz Jan 4, 2023
4489141
Remove nesterov acceleration and timing
joeaortiz Jan 5, 2023
9d5d5f7
End of iter callback, updated mypy version
joeaortiz Jan 6, 2023
748fe38
First attempt at GBP linear solver test
joeaortiz Jan 6, 2023
e597451
Fixed poor conditioning problems with linear test
joeaortiz Jan 6, 2023
c2cebbe
dropout starts later
joeaortiz Jan 6, 2023
d90138f
Merge branch 'main' into joe.gbp_optimizer
joeaortiz Jan 9, 2023
a94225f
Comments and references for understanding GBP code
joeaortiz Jan 13, 2023
b3551fa
Reduced atol threshold for symmetric precision matrix
joeaortiz Jan 13, 2023
aade379
Detach hessian in implicit GBP backward mode
joeaortiz Jan 16, 2023
4c905b9
Fix linearization for truncated, exception for DLM
joeaortiz Jan 16, 2023
4331f71
Fixed bug in linear system damping with vectorization
joeaortiz Jan 17, 2023
633f670
Zero messages correctly when using vectorization
joeaortiz Jan 19, 2023
f9a1c8d
Merged NL optimizer hierarchy refactor
joeaortiz Feb 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
test different backward modes for pgo
  • Loading branch information
joeaortiz committed Jun 10, 2022
commit 7b1bf78df8e8ae0e9c37d5c794c34ae729dc6c18
226 changes: 130 additions & 96 deletions theseus/optimizer/gbp/pgo_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
size = 3
dim = 2

noise_cov = np.array([0.05, 0.05])
noise_cov = np.array([0.01, 0.01])

prior_noise_std = 0.2
prior_sigma = np.array([1.3**2, 1.3**2])
Expand All @@ -31,128 +31,162 @@

# create theseus objective -------------------------------------

objective = th.Objective()
inputs = {}

n_poses = size * size
def create_pgo():

# create variables
poses = []
for i in range(n_poses):
poses.append(th.Vector(data=torch.rand(1, 2), name=f"x{i}"))
objective = th.Objective()
inputs = {}

# add prior cost constraints with VariableDifference cost
prior_std = 1.3
anchor_std = 0.01
prior_w = th.ScaleCostWeight(1 / prior_std, name="prior_weight")
anchor_w = th.ScaleCostWeight(1 / anchor_std, name="anchor_weight")
n_poses = size * size

gt_poses = []
# create variables
poses = []
for i in range(n_poses):
poses.append(th.Vector(data=torch.rand(1, 2), name=f"x{i}"))

p = 0
for i in range(size):
for j in range(size):
init = torch.Tensor([j, i])
gt_poses.append(init[None, :])
if i == 0 and j == 0:
w = anchor_w
else:
# noise_init = torch.normal(torch.zeros(2), prior_noise_std)
init = init + torch.FloatTensor(init_noises[p])
w = prior_w
# add prior cost constraints with VariableDifference cost
prior_std = 1.3
anchor_std = 0.01
prior_w = th.ScaleCostWeight(1 / prior_std, name="prior_weight")
anchor_w = th.ScaleCostWeight(1 / anchor_std, name="anchor_weight")

prior_target = th.Vector(data=init, name=f"prior_{p}")
inputs[f"x{p}"] = init[None, :]
inputs[f"prior_{p}"] = init[None, :]
gt_poses = []

cf_prior = th.eb.VariableDifference(
poses[p], w, prior_target, name=f"prior_cost_{p}"
)
p = 0
for i in range(size):
for j in range(size):
init = torch.Tensor([j, i])
gt_poses.append(init[None, :])
if i == 0 and j == 0:
w = anchor_w
else:
# noise_init = torch.normal(torch.zeros(2), prior_noise_std)
init = init + torch.FloatTensor(init_noises[p])
w = prior_w

objective.add(cf_prior)
prior_target = th.Vector(data=init, name=f"prior_{p}")
inputs[f"x{p}"] = init[None, :]
inputs[f"prior_{p}"] = init[None, :]

p += 1
cf_prior = th.eb.VariableDifference(
poses[p], w, prior_target, name=f"prior_cost_{p}"
)

# Measurement cost functions
objective.add(cf_prior)

meas_std_tensor = torch.nn.Parameter(torch.tensor([0.1]))
meas_w = th.ScaleCostWeight(1 / meas_std_tensor, name="prior_weight")
p += 1

m = 0
for i in range(size):
for j in range(size):
if j < size - 1:
measurement = torch.Tensor([1.0, 0.0])
# measurement += torch.normal(torch.zeros(2), meas_std)
measurement += torch.FloatTensor(meas_noises[m])
ix0 = i * size + j
ix1 = i * size + j + 1
# Measurement cost functions

meas = th.Vector(data=measurement, name=f"meas_{m}")
inputs[f"meas_{m}"] = measurement[None, :]
meas_std_tensor = torch.nn.Parameter(torch.tensor([0.1]))
meas_w = th.ScaleCostWeight(1 / meas_std_tensor, name="prior_weight")

cf_meas = th.eb.Between(
poses[ix0], poses[ix1], meas_w, meas, name=f"meas_cost_{m}"
)
objective.add(cf_meas)
m += 1
m = 0
for i in range(size):
for j in range(size):
if j < size - 1:
measurement = torch.Tensor([1.0, 0.0])
# measurement += torch.normal(torch.zeros(2), meas_std)
measurement += torch.FloatTensor(meas_noises[m])
ix0 = i * size + j
ix1 = i * size + j + 1

if i < size - 1:
measurement = torch.Tensor([0.0, 1.0])
# measurement += torch.normal(torch.zeros(2), meas_std)
measurement += torch.FloatTensor(meas_noises[m])
ix0 = i * size + j
ix1 = (i + 1) * size + j
meas = th.Vector(data=measurement, name=f"meas_{m}")
inputs[f"meas_{m}"] = measurement[None, :]

meas = th.Vector(data=measurement, name=f"meas_{m}")
inputs[f"meas_{m}"] = measurement[None, :]
cf_meas = th.eb.Between(
poses[ix0], poses[ix1], meas_w, meas, name=f"meas_cost_{m}"
)
objective.add(cf_meas)
m += 1

if i < size - 1:
measurement = torch.Tensor([0.0, 1.0])
# measurement += torch.normal(torch.zeros(2), meas_std)
measurement += torch.FloatTensor(meas_noises[m])
ix0 = i * size + j
ix1 = (i + 1) * size + j

meas = th.Vector(data=measurement, name=f"meas_{m}")
inputs[f"meas_{m}"] = measurement[None, :]

cf_meas = th.eb.Between(
poses[ix0], poses[ix1], meas_w, meas, name=f"meas_cost_{m}"
)
objective.add(cf_meas)
m += 1

return objective, gt_poses, meas_std_tensor, inputs


def linear_solve_pgo():
print("\n\nLinear solver...\n")

objective, gt_poses, meas_std_tensor, inputs = create_pgo()

# outer optimizer
gt_poses_tensor = torch.cat(gt_poses)
lr = 1e-3
outer_optimizer = torch.optim.Adam([meas_std_tensor], lr=lr)
outer_optimizer.zero_grad()

linear_optimizer = th.LinearOptimizer(objective, th.CholeskyDenseSolver)
th_layer = th.TheseusLayer(linear_optimizer)
outputs_linsolve, _ = th_layer.forward(inputs, {"verbose": True})

out_ls_tensor = torch.cat(list(outputs_linsolve.values()))
loss = torch.norm(gt_poses_tensor - out_ls_tensor)
loss.backward()

print("loss", loss.item())
print("grad", meas_std_tensor.grad.item())

print("outputs\n", outputs_linsolve)

cf_meas = th.eb.Between(
poses[ix0], poses[ix1], meas_w, meas, name=f"meas_cost_{m}"
)
objective.add(cf_meas)
m += 1

def gbp_solve_pgo(backward_mode, max_iterations=20):
print("\n\nWith GBP...")
print("backward mode:", backward_mode, "\n")

# outer optimizer
lr = 1e-3
model_optimizer = torch.optim.Adam([meas_std_tensor], lr=lr)
objective, gt_poses, meas_std_tensor, inputs = create_pgo()

gt_poses_tensor = torch.cat(gt_poses)
lr = 1e-3
outer_optimizer = torch.optim.Adam([meas_std_tensor], lr=lr)
outer_optimizer.zero_grad()

linear_optimizer = th.LinearOptimizer(objective, th.CholeskyDenseSolver)
th_layer = th.TheseusLayer(linear_optimizer)
outputs, _ = th_layer.forward(inputs)
optimizer = GaussianBeliefPropagation(
objective,
max_iterations=max_iterations,
)
theseus_optim = th.TheseusLayer(optimizer)

optim_arg = {
"verbose": True,
# "track_best_solution": True,
# "track_err_history": True,
"backward_mode": backward_mode,
"backward_num_iterations": 5,
"relin_threshold": 1e-8,
"damping": 0.0,
"dropout": 0.0,
"schedule": synchronous_schedule(max_iterations, optimizer.n_edges),
}

gt_poses_tensor = torch.cat(gt_poses)
output_poses = torch.cat([x.data for x in poses])
outputs_gbp, info = theseus_optim.forward(inputs, optim_arg)

loss = torch.norm(gt_poses_tensor - output_poses)
loss.backward()
out_gbp_tensor = torch.cat(list(outputs_gbp.values()))
loss = torch.norm(gt_poses_tensor - out_gbp_tensor)
loss.backward()

# da_dx = torch.autograd.grad(loss, data_x, retain_graph=True)[0].squeeze()
# print("\n--- backward_mode=IMPLICIT")
# print(da_dx.numpy())
print("loss", loss.item())
print("grad", meas_std_tensor.grad.item())

max_iterations = 100
optimizer = GaussianBeliefPropagation(
objective,
max_iterations=max_iterations,
)
theseus_optim = th.TheseusLayer(optimizer)
print("outputs\n", outputs_gbp)


optim_arg = {
"track_best_solution": True,
"track_err_history": True,
"verbose": True,
"backward_mode": th.BackwardMode.FULL,
"damping": 0.0,
"dropout": 0.0,
"schedule": synchronous_schedule(max_iterations, optimizer.n_edges),
}
linear_solve_pgo()

updated_inputs, info = theseus_optim.forward(inputs, optim_arg)
gbp_solve_pgo(backward_mode=th.BackwardMode.FULL, max_iterations=20)

print("gbp outputs\n", updated_inputs)
print("linear solver\n", updated_inputs)
gbp_solve_pgo(backward_mode=th.BackwardMode.TRUNCATED, max_iterations=20)