Notebook source code: notebooks/how_to/18_neural_adjoint_maps.ipynb
Run it yourself on binder Binder badge

How to compute a Neural Adjoint Map#

A neural adjoint map can be seen a functional map plus a non linear module. Given a correspondence, we can compute a neural adjoint map as we do for functional maps.

 In [ ]:
import geomstats.backend as gs

from geomfum.dataset import NotebooksDataset
from geomfum.refine import NeuralZoomOut, ZoomOut
from geomfum.shape import TriangleMesh
 In [ ]:
dataset = NotebooksDataset()

mesh_a = TriangleMesh.from_file(dataset.get_filename("cat-00"))
mesh_b = TriangleMesh.from_file(dataset.get_filename("lion-00"))

mesh_a.n_vertices, mesh_b.n_vertices
 In [ ]:
mesh_a.laplacian.find_spectrum(spectrum_size=50, set_as_basis=True)
mesh_b.laplacian.find_spectrum(spectrum_size=50, set_as_basis=True)

We start by estimating a correspondence

 In [ ]:
from geomfum.convert import NearestNeighbors

finder = NearestNeighbors(n_neighbors=1)
finder.fit(mesh_b.vertices)
p2p = finder.kneighbors(mesh_a.vertices)[1].flatten()

Then we convert it into a NAM

 In [ ]:
from geomfum.convert import NamFromP2pConverter

mesh_a.basis.use_k = 10
mesh_b.basis.use_k = 10
nam_converter = NamFromP2pConverter(device="cpu")

nam = nam_converter(p2p, mesh_a.basis, mesh_b.basis)

 In [ ]:
print(nam)

We can visualize the linear part of the model

 In [ ]:
import matplotlib.pyplot as plt

fmap = nam.linear_module.weight.detach().cpu().numpy()
plt.imshow(fmap)

Given a NAM, we can obtain a correspondence.

 In [ ]:
from geomfum.convert import P2pFromNamConverter

p2p_from_nam = P2pFromNamConverter()

p2p_from_nam(nam, mesh_a.basis, mesh_b.basis)

As in ZoomOut, we can perform spectral upsampling on NAMS.

 In [ ]:
nzo = NeuralZoomOut(nit=2, step=2, device="cpu")

nam_ref = nzo(nam, mesh_a.basis, mesh_b.basis)