diff --git a/configs/datasets/toy_point_cloud.yaml b/configs/datasets/toy_point_cloud.yaml new file mode 100644 index 00000000..18b8aeb4 --- /dev/null +++ b/configs/datasets/toy_point_cloud.yaml @@ -0,0 +1,12 @@ +data_domain: point_cloud +data_type: toy_dataset +data_name: toy_point_cloud +data_dir: datasets/${data_domain}/${data_type} + +# Dataset parameters +num_points: 8 +num_classes: 2 + +num_features: 1 +task: classification +loss_type: cross_entropy \ No newline at end of file diff --git a/configs/transforms/liftings/pointcloud2simplicial/tangential_lifting.yaml b/configs/transforms/liftings/pointcloud2simplicial/tangential_lifting.yaml new file mode 100644 index 00000000..a472db06 --- /dev/null +++ b/configs/transforms/liftings/pointcloud2simplicial/tangential_lifting.yaml @@ -0,0 +1,3 @@ +transform_type: "lifting" +transform_name: "TangentialLifting" +feature_lifting: ProjectionSum \ No newline at end of file diff --git a/modules/data/load/loaders.py b/modules/data/load/loaders.py index 8ccafb11..4ce265e3 100755 --- a/modules/data/load/loaders.py +++ b/modules/data/load/loaders.py @@ -12,6 +12,7 @@ load_cell_complex_dataset, load_hypergraph_pickle_dataset, load_manual_graph, + load_point_cloud, load_simplicial_dataset, ) @@ -204,3 +205,34 @@ def load( torch_geometric.data.Dataset object containing the loaded data. """ return load_hypergraph_pickle_dataset(self.parameters) + + +class PointCloudLoader(AbstractLoader): + r"""Loader for point-cloud dataset. + Parameters + ---------- + parameters: DictConfig + Configuration parameters + """ + + def __init__(self, parameters: DictConfig): + super().__init__(parameters) + self.parameters = parameters + self.data_dir = self.parameters["data_dir"] + if "num_classes" not in self.cfg: + self.cfg["num_classes"] = 2 + + def load(self) -> torch_geometric.data.Dataset: + r"""Load point-cloud dataset. + Parameters + ---------- + None + Returns + ------- + torch_geometric.data.Dataset + torch_geometric.data.Dataset object containing the loaded data. + """ + data = load_point_cloud( + num_classes=self.cfg["num_classes"], num_points=self.cfg["num_points"] + ) + return CustomDataset([data], self.cfg["data_dir"]) diff --git a/modules/data/utils/utils.py b/modules/data/utils/utils.py index 93ab5021..f1a913bd 100755 --- a/modules/data/utils/utils.py +++ b/modules/data/utils/utils.py @@ -50,16 +50,16 @@ def get_complex_connectivity(complex, max_rank, signed=False): ) except ValueError: # noqa: PERF203 if connectivity_info == "incidence": - connectivity[f"{connectivity_info}_{rank_idx}"] = ( - generate_zero_sparse_connectivity( - m=practical_shape[rank_idx - 1], n=practical_shape[rank_idx] - ) + connectivity[ + f"{connectivity_info}_{rank_idx}" + ] = generate_zero_sparse_connectivity( + m=practical_shape[rank_idx - 1], n=practical_shape[rank_idx] ) else: - connectivity[f"{connectivity_info}_{rank_idx}"] = ( - generate_zero_sparse_connectivity( - m=practical_shape[rank_idx], n=practical_shape[rank_idx] - ) + connectivity[ + f"{connectivity_info}_{rank_idx}" + ] = generate_zero_sparse_connectivity( + m=practical_shape[rank_idx], n=practical_shape[rank_idx] ) connectivity["shape"] = practical_shape return connectivity @@ -283,6 +283,17 @@ def load_hypergraph_pickle_dataset(cfg): return data +def load_point_cloud(num_classes: int = 2, num_points: int = 18, seed: int = 42): + """Create a toy point cloud dataset""" + rng = np.random.default_rng(seed) + + points = torch.tensor(rng.random((num_points, 2)), dtype=torch.float) + classes = torch.tensor(rng.integers(num_classes, size=num_points), dtype=torch.long) + features = torch.tensor(rng.integers(3, size=(num_points, 1)), dtype=torch.float) + + return torch_geometric.data.Data(x=features, y=classes, pos=points) + + def load_manual_graph(): """Create a manual graph for testing purposes.""" # Define the vertices (just 8 vertices) diff --git a/modules/transforms/data_transform.py b/modules/transforms/data_transform.py index 59253ecf..28e4ec1e 100755 --- a/modules/transforms/data_transform.py +++ b/modules/transforms/data_transform.py @@ -15,6 +15,9 @@ from modules.transforms.liftings.graph2simplicial.clique_lifting import ( SimplicialCliqueLifting, ) +from modules.transforms.liftings.pointcloud2simplicial.tangential_lifting import ( + TangentialLifting, +) TRANSFORMS = { # Graph -> Hypergraph @@ -23,6 +26,8 @@ "SimplicialCliqueLifting": SimplicialCliqueLifting, # Graph -> Cell Complex "CellCycleLifting": CellCycleLifting, + # Point-cloud -> Simplicial Complex + "TangentialLifting": TangentialLifting, # Feature Liftings "ProjectionSum": ProjectionSum, # Data Manipulations diff --git a/modules/transforms/liftings/pointcloud2simplicial/tangential_lifting.py b/modules/transforms/liftings/pointcloud2simplicial/tangential_lifting.py new file mode 100644 index 00000000..01f70804 --- /dev/null +++ b/modules/transforms/liftings/pointcloud2simplicial/tangential_lifting.py @@ -0,0 +1,42 @@ +import gudhi as gd +import torch +import torch_geometric +from toponetx.classes import SimplicialComplex + +from modules.data.utils.utils import get_complex_connectivity +from modules.transforms.liftings.pointcloud2simplicial.base import ( + PointCloud2SimplicialLifting, +) + + +class TangentialLifting(PointCloud2SimplicialLifting): + # intrinsic dimension of the manifold set to 1 by default + def __init__(self, intrisic_dim=2, **kwargs): + super().__init__(**kwargs) + self.intrisic_dim = intrisic_dim + + def _get_lifted_topology(self, simplicial_complex: SimplicialComplex) -> dict: + lifted_topology = get_complex_connectivity(simplicial_complex, self.complex_dim) + + lifted_topology["x_0"] = torch.stack( + list(simplicial_complex.get_simplex_attributes("features", 0).values()) + ) + + return lifted_topology + + def lift_topology(self, data: torch_geometric.data.Data, **kwargs) -> dict: + + # initialize tangential complex object + tangential_complex = gd.TangentialComplex(self.intrisic_dim, data.pos) + + # build the complex + tangential_complex.compute_tangential_complex() + + simplicial_complex = SimplicialComplex().from_gudhi(tangential_complex.create_simplex_tree()) + + self.complex_dim = simplicial_complex.dim + + node_features = {i: data.x[i, :] for i in range(data.x.shape[0])} + simplicial_complex.set_simplex_attributes(node_features, name="features") + + return self._get_lifted_topology(simplicial_complex) diff --git a/test/transforms/liftings/pointcloud2simplicial/test_tangential_lifting.py b/test/transforms/liftings/pointcloud2simplicial/test_tangential_lifting.py new file mode 100644 index 00000000..21fb9f89 --- /dev/null +++ b/test/transforms/liftings/pointcloud2simplicial/test_tangential_lifting.py @@ -0,0 +1,62 @@ +import torch + +from modules.data.utils.utils import load_point_cloud +from modules.transforms.liftings.pointcloud2simplicial.tangential_lifting import ( + TangentialLifting, +) + + +class TestTangentialLifting: + """Test the DelaunayLifting class.""" + + def setup_method(self): + # Load the point cloud + SEED = 42 + self.data = load_point_cloud(num_points=5, seed=SEED) + + # Initialise the TangentialLifting class + self.lifting_signed = TangentialLifting(signed=True) + self.lifting_unsigned = TangentialLifting(signed=False) + + def test_lift_topology(self): + """Test the lift_topology method.""" + + # Test the lift_topology method + lifted_data_signed = self.lifting_signed.forward(self.data.clone()) + lifted_data_unsigned = self.lifting_unsigned.forward(self.data.clone()) + + expected_incidence_1 = torch.tensor( + [ + [1., 1., 1., 0., 0., 0., 0.], + [1., 0., 0., 1., 0., 0., 0.], + [0., 0., 0., 0., 1., 1., 0.], + [0., 1., 0., 1., 1., 0., 1.], + [0., 0., 1., 0., 0., 1., 1.] + ] + ) + + assert ( + abs(expected_incidence_1) == lifted_data_unsigned.incidence_1.to_dense() + ).all(), "Something is wrong with unsigned incidence_1 (nodes to edges)." + assert ( + expected_incidence_1 == lifted_data_signed.incidence_1.to_dense() + ).all(), "Something is wrong with signed incidence_1 (nodes to edges)." + + expected_incidence_2 = torch.tensor( + [ + [1., 0., 0.], + [1., 1., 0.], + [0., 1., 0.], + [1., 0., 0.], + [0., 0., 1.], + [0., 0., 1.], + [0., 1., 1.] + ] + ) + + assert ( + abs(expected_incidence_2) == lifted_data_unsigned.incidence_2.to_dense() + ).all(), "Something is wrong with unsigned incidence_2 (edges to triangles)." + assert ( + expected_incidence_2 == lifted_data_signed.incidence_2.to_dense() + ).all(), "Something is wrong with signed incidence_2 (edges to triangles)." diff --git a/tutorials/pointcloud2simplicial/tangential_lifting.ipynb b/tutorials/pointcloud2simplicial/tangential_lifting.ipynb new file mode 100644 index 00000000..b84ec021 --- /dev/null +++ b/tutorials/pointcloud2simplicial/tangential_lifting.ipynb @@ -0,0 +1,274 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "ab9ff375-2012-457b-8cea-d836f2885ff3", + "metadata": {}, + "source": [ + "# Point Cloud-to-Simplicial Complex Lifting Tutorial" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "0d89c203", + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2\n", + "\n", + "from modules.data.load.loaders import PointCloudLoader\n", + "from modules.data.preprocess.preprocessor import PreProcessor\n", + "from modules.utils.utils import (\n", + " describe_data,\n", + " load_dataset_config,\n", + " load_model_config,\n", + " load_transform_config,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "008c11c4-6753-477b-8a5d-aab0e70f9999", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Dataset configuration for toy_point_cloud:\n", + "\n", + "{'data_domain': 'point_cloud',\n", + " 'data_type': 'toy_dataset',\n", + " 'data_name': 'toy_point_cloud',\n", + " 'data_dir': 'datasets/point_cloud/toy_dataset',\n", + " 'num_points': 8,\n", + " 'num_classes': 2,\n", + " 'num_features': 1,\n", + " 'task': 'classification',\n", + " 'loss_type': 'cross_entropy'}\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Processing...\n", + "Done!\n" + ] + } + ], + "source": [ + "dataset_name = \"toy_point_cloud\"\n", + "dataset_config = load_dataset_config(dataset_name)\n", + "loader = PointCloudLoader(dataset_config)\n", + "\n", + "dataset = loader.load()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "eb249eaa-77db-433b-a934-63d3e75f0e15", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Transform configuration for pointcloud2simplicial/tangential_lifting:\n", + "\n", + "{'transform_type': 'lifting',\n", + " 'transform_name': 'TangentialLifting',\n", + " 'feature_lifting': 'ProjectionSum'}\n" + ] + } + ], + "source": [ + "transform_type = \"liftings\"\n", + "# If the transform is a topological lifting, it should include both the type of the lifting and the identifier\n", + "transform_id = \"pointcloud2simplicial/tangential_lifting\"\n", + "\n", + "# Read yaml file\n", + "transform_config = {\n", + " \"lifting\": load_transform_config(transform_type, transform_id)\n", + " # other transforms (e.g. data manipulations, feature liftings) can be added here\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "75e6c321-850c-4852-8c29-fa9fc7cb524b", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Processing...\n", + "Done!\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Dataset only contains 1 sample:\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " - The complex has 8 0-cells.\n", + " - The 0-cells have features dimension 1\n", + " - The complex has 14 1-cells.\n", + " - The 1-cells have features dimension 1\n", + " - The complex has 7 2-cells.\n", + " - The 2-cells have features dimension 1\n", + "\n" + ] + } + ], + "source": [ + "lifted_dataset = PreProcessor(dataset, transform_config, loader.data_dir)\n", + "describe_data(lifted_dataset)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "78a43208-9028-4122-b10f-931bb47fade7", + "metadata": {}, + "source": [ + "# Tangential Complex: theory\n", + "\n", + "(Taken from respective [Gudhi tutorial](https://gudhi.inria.fr/python/latest/tangential_complex_user.html) by Clément Jamin). Tangential complexes were introduced in [1]. A Tangential Delaunay complex is a simplicial complex designed to reconstruct a $k$-dimensional smooth manifold embedded in \n", + "$d$-dimensional Euclidean space.\n", + "\n", + "[1] Jean-Daniel Boissonnat and Arijit Ghosh. Manifold reconstruction using tangential delaunay complexes. _Discrete & Computational Geometry_, 51(1):221–267, 2014. URL: http://dx.doi.org/10.1007/s00454-013-9557-2, doi:10.1007/s00454-013-9557-2.\n", + "\n", + "Consider the following point cloud, being a sample from a 1D curve. \n", + "\n", + "![](https://gudhi.inria.fr/python/latest/_images/tc_example_01.png)\n", + "\n", + "Tangent subspaces of points are estimated with PCA (more points are needed for that, 4 points are shown here for simplicity):\n", + "\n", + "![](https://gudhi.inria.fr/python/latest/_images/tc_example_02.png)\n", + "\n", + "Now consider a Voronoi diagram of these points shown in orange:\n", + "\n", + "![](https://gudhi.inria.fr/python/latest/_images/tc_example_03.png)\n", + "\n", + "For each point, construct its star in the Delaunay triangulation, restricted to its tangent subspace. The Tangential Delaunay complex is the union of those stars.\n", + "\n", + "In practice, neither the whole ambient Voronoi diagram nor the ambient Delaunay triangulation is computed – instead, local \n", + "$k$-dimensional regular triangulations are computed with a limited number of points as we only need the star of each point. More details can be found in [1].\n", + "\n", + "It is worth noting that inconsistencies between the stars may occur (a simplex is not in the star of all its vertices). One way to fix these inconsistencies is to perturb the points – `gudhi.TangentialComplex` [has methods for that](https://gudhi.inria.fr/python/latest/tangential_complex_ref.html).\n", + "\n", + "In the above example, $k$, the intrinsic dimension of the manifold, was set equal to $d$, the ambient dimension, thus the resulting TC resorted to just Delaunay, hence the presence of 2-cells. It is more practically interesting to use TCs when the data is concentrated near some lower-dimensional embedded manifold.\n", + "\n", + "The **lifting** from the original point cloud to the TC is quite straightforward: the points' features are simply transferred to the nodes (0-simplices) of the TC, then, for higher-order simplices, various lifting methods are possible." + ] + }, + { + "cell_type": "markdown", + "id": "d5d6383f-78e9-4a1a-8cd2-44262ca17e0b", + "metadata": {}, + "source": [ + "# Create and Run a Simplicial NN Model\n", + "\n", + "In this section a simple model is created to test that the used lifting works as intended. In this case the model uses the `up_laplacian_1` and the `down_laplacian_1` so the lifting should make sure to add them to the data." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "f5776a9c-b062-4c4a-b479-0bf7a38a037a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Model configuration for simplicial SAN:\n", + "\n", + "{'in_channels': None,\n", + " 'hidden_channels': 32,\n", + " 'out_channels': None,\n", + " 'n_layers': 2,\n", + " 'n_filters': 2,\n", + " 'order_harmonic': 5,\n", + " 'epsilon_harmonic': 0.1}\n" + ] + } + ], + "source": [ + "from modules.models.simplicial.san import SANModel\n", + "\n", + "model_type = \"simplicial\"\n", + "model_id = \"san\"\n", + "model_config = load_model_config(model_type, model_id)\n", + "\n", + "model = SANModel(model_config, dataset_config)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "93f4b784-ce5e-47f5-aa24-833753b4e508", + "metadata": {}, + "outputs": [], + "source": [ + "y_hat = model(lifted_dataset.get(0))" + ] + }, + { + "cell_type": "markdown", + "id": "b0c5b2d1-9557-4c15-b6d7-f336d0db9af0", + "metadata": {}, + "source": [ + "If everything is correct the cell above should execute without errors." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}