diff --git a/2026_tdl_challenge/outputs/hhgconv_reapprox/results.json b/2026_tdl_challenge/outputs/hhgconv_reapprox/results.json new file mode 100644 index 000000000..6092896b4 --- /dev/null +++ b/2026_tdl_challenge/outputs/hhgconv_reapprox/results.json @@ -0,0 +1,1240 @@ +{ + "metadata": { + "study_id": "hgconv_reapprox", + "model_config": "hypergraph/hypergraph_convolution", + "generated_at_utc": "2026-08-01T07:44:05.290422+00:00", + "n_runs": 72, + "train_seeds": [ + 42, + 43, + 44 + ], + "heatmap_note": "Cells show mean \u00b1 std over train_seeds (in-distribution test)." + }, + "results": [ + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_1-2.5__gamma_1.5-2__s42", + "train_seed": 42, + "homophily": "h_lo", + "avg_degree": "d_lo", + "power_law": "pl_lo", + "run_slug": "h_lo__d_lo__pl_lo", + "test_loss": 2.2220866680145264, + "test_best_rerun_accuracy": 0.3098403215408325, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_lo__d_lo__pl_lo__s42" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_1-2.5__gamma_1.5-2__s43", + "train_seed": 43, + "homophily": "h_lo", + "avg_degree": "d_lo", + "power_law": "pl_lo", + "run_slug": "h_lo__d_lo__pl_lo", + "test_loss": 2.2163760662078857, + "test_best_rerun_accuracy": 0.30945831537246704, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_lo__d_lo__pl_lo__s43" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_1-2.5__gamma_1.5-2__s44", + "train_seed": 44, + "homophily": "h_lo", + "avg_degree": "d_lo", + "power_law": "pl_lo", + "run_slug": "h_lo__d_lo__pl_lo", + "test_loss": 2.200658082962036, + "test_best_rerun_accuracy": 0.3153793215751648, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_lo__d_lo__pl_lo__s44" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_1-2.5__gamma_1.5-2__s42", + "train_seed": 42, + "homophily": "h_lo", + "avg_degree": "d_lo", + "power_law": "pl_lo", + "run_slug": "h_lo__d_lo__pl_lo", + "test_loss": 106.1955337524414, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 101.48812866210938, + "test_triangles_total_structural": 1388.0, + "test_mse_by_total_triangles": 0.07311824831564076, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_lo__d_lo__pl_lo__s42" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_1-2.5__gamma_1.5-2__s43", + "train_seed": 43, + "homophily": "h_lo", + "avg_degree": "d_lo", + "power_law": "pl_lo", + "run_slug": "h_lo__d_lo__pl_lo", + "test_loss": 100.56791687011719, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 95.9585189819336, + "test_triangles_total_structural": 1388.0, + "test_mse_by_total_triangles": 0.06913437966998097, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_lo__d_lo__pl_lo__s43" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_1-2.5__gamma_1.5-2__s44", + "train_seed": 44, + "homophily": "h_lo", + "avg_degree": "d_lo", + "power_law": "pl_lo", + "run_slug": "h_lo__d_lo__pl_lo", + "test_loss": 88.70556640625, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 89.3862533569336, + "test_triangles_total_structural": 1388.0, + "test_mse_by_total_triangles": 0.0643993179804997, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_lo__d_lo__pl_lo__s44" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_1-2.5__gamma_4-5__s42", + "train_seed": 42, + "homophily": "h_lo", + "avg_degree": "d_lo", + "power_law": "pl_hi", + "run_slug": "h_lo__d_lo__pl_hi", + "test_loss": 2.2212162017822266, + "test_best_rerun_accuracy": 0.30877071619033813, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_lo__d_lo__pl_hi__s42" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_1-2.5__gamma_4-5__s43", + "train_seed": 43, + "homophily": "h_lo", + "avg_degree": "d_lo", + "power_law": "pl_hi", + "run_slug": "h_lo__d_lo__pl_hi", + "test_loss": 2.2196223735809326, + "test_best_rerun_accuracy": 0.3080449104309082, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_lo__d_lo__pl_hi__s43" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_1-2.5__gamma_4-5__s44", + "train_seed": 44, + "homophily": "h_lo", + "avg_degree": "d_lo", + "power_law": "pl_hi", + "run_slug": "h_lo__d_lo__pl_hi", + "test_loss": 2.219992160797119, + "test_best_rerun_accuracy": 0.3065169155597687, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_lo__d_lo__pl_hi__s44" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_1-2.5__gamma_4-5__s42", + "train_seed": 42, + "homophily": "h_lo", + "avg_degree": "d_lo", + "power_law": "pl_hi", + "run_slug": "h_lo__d_lo__pl_hi", + "test_loss": 3.6658568382263184, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 3.5184240341186523, + "test_triangles_total_structural": 190.0, + "test_mse_by_total_triangles": 0.018518021232203433, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_lo__d_lo__pl_hi__s42" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_1-2.5__gamma_4-5__s43", + "train_seed": 43, + "homophily": "h_lo", + "avg_degree": "d_lo", + "power_law": "pl_hi", + "run_slug": "h_lo__d_lo__pl_hi", + "test_loss": 2.854748487472534, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 2.76094388961792, + "test_triangles_total_structural": 190.0, + "test_mse_by_total_triangles": 0.014531283629568, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_lo__d_lo__pl_hi__s43" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_1-2.5__gamma_4-5__s44", + "train_seed": 44, + "homophily": "h_lo", + "avg_degree": "d_lo", + "power_law": "pl_hi", + "run_slug": "h_lo__d_lo__pl_hi", + "test_loss": 4.03803014755249, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 3.9579100608825684, + "test_triangles_total_structural": 190.0, + "test_mse_by_total_triangles": 0.020831105583592465, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_lo__d_lo__pl_hi__s44" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_4-5__gamma_1.5-2__s42", + "train_seed": 42, + "homophily": "h_lo", + "avg_degree": "d_hi", + "power_law": "pl_lo", + "run_slug": "h_lo__d_hi__pl_lo", + "test_loss": 2.1975533962249756, + "test_best_rerun_accuracy": 0.31476813554763794, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_lo__d_hi__pl_lo__s42" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_4-5__gamma_1.5-2__s43", + "train_seed": 43, + "homophily": "h_lo", + "avg_degree": "d_hi", + "power_law": "pl_lo", + "run_slug": "h_lo__d_hi__pl_lo", + "test_loss": 2.1847939491271973, + "test_best_rerun_accuracy": 0.3177095353603363, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_lo__d_hi__pl_lo__s43" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_4-5__gamma_1.5-2__s44", + "train_seed": 44, + "homophily": "h_lo", + "avg_degree": "d_hi", + "power_law": "pl_lo", + "run_slug": "h_lo__d_hi__pl_lo", + "test_loss": 2.1810123920440674, + "test_best_rerun_accuracy": 0.32091832160949707, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_lo__d_hi__pl_lo__s44" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_4-5__gamma_1.5-2__s42", + "train_seed": 42, + "homophily": "h_lo", + "avg_degree": "d_hi", + "power_law": "pl_lo", + "run_slug": "h_lo__d_hi__pl_lo", + "test_loss": 4095.79248046875, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 3908.0888671875, + "test_triangles_total_structural": 13185.0, + "test_mse_by_total_triangles": 0.2964041613339022, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_lo__d_hi__pl_lo__s42" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_4-5__gamma_1.5-2__s43", + "train_seed": 43, + "homophily": "h_lo", + "avg_degree": "d_hi", + "power_law": "pl_lo", + "run_slug": "h_lo__d_hi__pl_lo", + "test_loss": 3932.098388671875, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 3766.6103515625, + "test_triangles_total_structural": 13185.0, + "test_mse_by_total_triangles": 0.285673898487865, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_lo__d_hi__pl_lo__s43" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_4-5__gamma_1.5-2__s44", + "train_seed": 44, + "homophily": "h_lo", + "avg_degree": "d_hi", + "power_law": "pl_lo", + "run_slug": "h_lo__d_hi__pl_lo", + "test_loss": 3875.919189453125, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 3809.2724609375, + "test_triangles_total_structural": 13185.0, + "test_mse_by_total_triangles": 0.2889095533513462, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_lo__d_hi__pl_lo__s44" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_4-5__gamma_4-5__s42", + "train_seed": 42, + "homophily": "h_lo", + "avg_degree": "d_hi", + "power_law": "pl_hi", + "run_slug": "h_lo__d_hi__pl_hi", + "test_loss": 2.179140090942383, + "test_best_rerun_accuracy": 0.32034534215927124, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_lo__d_hi__pl_hi__s42" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_4-5__gamma_4-5__s43", + "train_seed": 43, + "homophily": "h_lo", + "avg_degree": "d_hi", + "power_law": "pl_hi", + "run_slug": "h_lo__d_hi__pl_hi", + "test_loss": 2.196190357208252, + "test_best_rerun_accuracy": 0.3170219361782074, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_lo__d_hi__pl_hi__s43" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_4-5__gamma_4-5__s44", + "train_seed": 44, + "homophily": "h_lo", + "avg_degree": "d_hi", + "power_law": "pl_hi", + "run_slug": "h_lo__d_hi__pl_hi", + "test_loss": 2.2067387104034424, + "test_best_rerun_accuracy": 0.31316372752189636, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_lo__d_hi__pl_hi__s44" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_4-5__gamma_4-5__s42", + "train_seed": 42, + "homophily": "h_lo", + "avg_degree": "d_hi", + "power_law": "pl_hi", + "run_slug": "h_lo__d_hi__pl_hi", + "test_loss": 139.57333374023438, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 136.06581115722656, + "test_triangles_total_structural": 2967.0, + "test_mse_by_total_triangles": 0.04585972738699918, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_lo__d_hi__pl_hi__s42" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_4-5__gamma_4-5__s43", + "train_seed": 43, + "homophily": "h_lo", + "avg_degree": "d_hi", + "power_law": "pl_hi", + "run_slug": "h_lo__d_hi__pl_hi", + "test_loss": 139.59112548828125, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 136.24752807617188, + "test_triangles_total_structural": 2967.0, + "test_mse_by_total_triangles": 0.045920973399451254, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_lo__d_hi__pl_hi__s43" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0-0.1__deg_4-5__gamma_4-5__s44", + "train_seed": 44, + "homophily": "h_lo", + "avg_degree": "d_hi", + "power_law": "pl_hi", + "run_slug": "h_lo__d_hi__pl_hi", + "test_loss": 149.37551879882812, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 145.01759338378906, + "test_triangles_total_structural": 2967.0, + "test_mse_by_total_triangles": 0.048876843068348184, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_lo__d_hi__pl_hi__s44" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_1-2.5__gamma_1.5-2__s42", + "train_seed": 42, + "homophily": "h_mid", + "avg_degree": "d_lo", + "power_law": "pl_lo", + "run_slug": "h_mid__d_lo__pl_lo", + "test_loss": 2.0954947471618652, + "test_best_rerun_accuracy": 0.3527389466762543, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_mid__d_lo__pl_lo__s42" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_1-2.5__gamma_1.5-2__s43", + "train_seed": 43, + "homophily": "h_mid", + "avg_degree": "d_lo", + "power_law": "pl_lo", + "run_slug": "h_mid__d_lo__pl_lo", + "test_loss": 2.1056065559387207, + "test_best_rerun_accuracy": 0.3488425314426422, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_mid__d_lo__pl_lo__s43" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_1-2.5__gamma_1.5-2__s44", + "train_seed": 44, + "homophily": "h_mid", + "avg_degree": "d_lo", + "power_law": "pl_lo", + "run_slug": "h_mid__d_lo__pl_lo", + "test_loss": 2.0978341102600098, + "test_best_rerun_accuracy": 0.35132554173469543, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_mid__d_lo__pl_lo__s44" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_1-2.5__gamma_1.5-2__s42", + "train_seed": 42, + "homophily": "h_mid", + "avg_degree": "d_lo", + "power_law": "pl_lo", + "run_slug": "h_mid__d_lo__pl_lo", + "test_loss": 5498.6416015625, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 5670.37646484375, + "test_triangles_total_structural": 7485.0, + "test_mse_by_total_triangles": 0.7575653259644288, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_mid__d_lo__pl_lo__s42" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_1-2.5__gamma_1.5-2__s43", + "train_seed": 43, + "homophily": "h_mid", + "avg_degree": "d_lo", + "power_law": "pl_lo", + "run_slug": "h_mid__d_lo__pl_lo", + "test_loss": 5286.0498046875, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 5465.728515625, + "test_triangles_total_structural": 7485.0, + "test_mse_by_total_triangles": 0.7302242505845024, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_mid__d_lo__pl_lo__s43" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_1-2.5__gamma_1.5-2__s44", + "train_seed": 44, + "homophily": "h_mid", + "avg_degree": "d_lo", + "power_law": "pl_lo", + "run_slug": "h_mid__d_lo__pl_lo", + "test_loss": 5340.4443359375, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 5501.697265625, + "test_triangles_total_structural": 7485.0, + "test_mse_by_total_triangles": 0.7350296948062792, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_mid__d_lo__pl_lo__s44" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_1-2.5__gamma_4-5__s42", + "train_seed": 42, + "homophily": "h_mid", + "avg_degree": "d_lo", + "power_law": "pl_hi", + "run_slug": "h_mid__d_lo__pl_hi", + "test_loss": 2.1086275577545166, + "test_best_rerun_accuracy": 0.3459393382072449, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_mid__d_lo__pl_hi__s42" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_1-2.5__gamma_4-5__s43", + "train_seed": 43, + "homophily": "h_mid", + "avg_degree": "d_lo", + "power_law": "pl_hi", + "run_slug": "h_mid__d_lo__pl_hi", + "test_loss": 2.0953803062438965, + "test_best_rerun_accuracy": 0.34819313883781433, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_mid__d_lo__pl_hi__s43" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_1-2.5__gamma_4-5__s44", + "train_seed": 44, + "homophily": "h_mid", + "avg_degree": "d_lo", + "power_law": "pl_hi", + "run_slug": "h_mid__d_lo__pl_hi", + "test_loss": 2.0850584506988525, + "test_best_rerun_accuracy": 0.35189855098724365, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_mid__d_lo__pl_hi__s44" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_1-2.5__gamma_4-5__s42", + "train_seed": 42, + "homophily": "h_mid", + "avg_degree": "d_lo", + "power_law": "pl_hi", + "run_slug": "h_mid__d_lo__pl_hi", + "test_loss": 143.88186645507812, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 151.5059051513672, + "test_triangles_total_structural": 1158.0, + "test_mse_by_total_triangles": 0.13083411498390948, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_mid__d_lo__pl_hi__s42" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_1-2.5__gamma_4-5__s43", + "train_seed": 43, + "homophily": "h_mid", + "avg_degree": "d_lo", + "power_law": "pl_hi", + "run_slug": "h_mid__d_lo__pl_hi", + "test_loss": 139.2274932861328, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 146.42425537109375, + "test_triangles_total_structural": 1158.0, + "test_mse_by_total_triangles": 0.12644581638263708, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_mid__d_lo__pl_hi__s43" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_1-2.5__gamma_4-5__s44", + "train_seed": 44, + "homophily": "h_mid", + "avg_degree": "d_lo", + "power_law": "pl_hi", + "run_slug": "h_mid__d_lo__pl_hi", + "test_loss": 152.0172576904297, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 159.37301635742188, + "test_triangles_total_structural": 1158.0, + "test_mse_by_total_triangles": 0.13762782068861992, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_mid__d_lo__pl_hi__s44" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_4-5__gamma_1.5-2__s42", + "train_seed": 42, + "homophily": "h_mid", + "avg_degree": "d_hi", + "power_law": "pl_lo", + "run_slug": "h_mid__d_hi__pl_lo", + "test_loss": 2.0919461250305176, + "test_best_rerun_accuracy": 0.35568034648895264, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_mid__d_hi__pl_lo__s42" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_4-5__gamma_1.5-2__s43", + "train_seed": 43, + "homophily": "h_mid", + "avg_degree": "d_hi", + "power_law": "pl_lo", + "run_slug": "h_mid__d_hi__pl_lo", + "test_loss": 2.0909392833709717, + "test_best_rerun_accuracy": 0.35667353868484497, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_mid__d_hi__pl_lo__s43" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_4-5__gamma_1.5-2__s44", + "train_seed": 44, + "homophily": "h_mid", + "avg_degree": "d_hi", + "power_law": "pl_lo", + "run_slug": "h_mid__d_hi__pl_lo", + "test_loss": 2.085005760192871, + "test_best_rerun_accuracy": 0.3577813506126404, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_mid__d_hi__pl_lo__s44" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_4-5__gamma_1.5-2__s42", + "train_seed": 42, + "homophily": "h_mid", + "avg_degree": "d_hi", + "power_law": "pl_lo", + "run_slug": "h_mid__d_hi__pl_lo", + "test_loss": 113720.0625, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 79835.0546875, + "test_triangles_total_structural": 43064.0, + "test_mse_by_total_triangles": 1.8538699305104032, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_mid__d_hi__pl_lo__s42" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_4-5__gamma_1.5-2__s43", + "train_seed": 43, + "homophily": "h_mid", + "avg_degree": "d_hi", + "power_law": "pl_lo", + "run_slug": "h_mid__d_hi__pl_lo", + "test_loss": 113403.7890625, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 79469.734375, + "test_triangles_total_structural": 43064.0, + "test_mse_by_total_triangles": 1.8453867354402749, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_mid__d_hi__pl_lo__s43" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_4-5__gamma_1.5-2__s44", + "train_seed": 44, + "homophily": "h_mid", + "avg_degree": "d_hi", + "power_law": "pl_lo", + "run_slug": "h_mid__d_hi__pl_lo", + "test_loss": 113634.828125, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 79593.4140625, + "test_triangles_total_structural": 43064.0, + "test_mse_by_total_triangles": 1.848258732642114, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_mid__d_hi__pl_lo__s44" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_4-5__gamma_4-5__s42", + "train_seed": 42, + "homophily": "h_mid", + "avg_degree": "d_hi", + "power_law": "pl_hi", + "run_slug": "h_mid__d_hi__pl_hi", + "test_loss": 2.042598009109497, + "test_best_rerun_accuracy": 0.36794254183769226, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_mid__d_hi__pl_hi__s42" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_4-5__gamma_4-5__s43", + "train_seed": 43, + "homophily": "h_mid", + "avg_degree": "d_hi", + "power_law": "pl_hi", + "run_slug": "h_mid__d_hi__pl_hi", + "test_loss": 2.038547992706299, + "test_best_rerun_accuracy": 0.36969974637031555, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_mid__d_hi__pl_hi__s43" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_4-5__gamma_4-5__s44", + "train_seed": 44, + "homophily": "h_mid", + "avg_degree": "d_hi", + "power_law": "pl_hi", + "run_slug": "h_mid__d_hi__pl_hi", + "test_loss": 2.086423635482788, + "test_best_rerun_accuracy": 0.3598441481590271, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_mid__d_hi__pl_hi__s44" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_4-5__gamma_4-5__s42", + "train_seed": 42, + "homophily": "h_mid", + "avg_degree": "d_hi", + "power_law": "pl_hi", + "run_slug": "h_mid__d_hi__pl_hi", + "test_loss": 8585.7998046875, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 8198.3779296875, + "test_triangles_total_structural": 14262.0, + "test_mse_by_total_triangles": 0.5748406906245618, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_mid__d_hi__pl_hi__s42" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_4-5__gamma_4-5__s43", + "train_seed": 43, + "homophily": "h_mid", + "avg_degree": "d_hi", + "power_law": "pl_hi", + "run_slug": "h_mid__d_hi__pl_hi", + "test_loss": 8462.1533203125, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 8088.7001953125, + "test_triangles_total_structural": 14262.0, + "test_mse_by_total_triangles": 0.5671504834744425, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_mid__d_hi__pl_hi__s43" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.4-0.6__deg_4-5__gamma_4-5__s44", + "train_seed": 44, + "homophily": "h_mid", + "avg_degree": "d_hi", + "power_law": "pl_hi", + "run_slug": "h_mid__d_hi__pl_hi", + "test_loss": 8372.935546875, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 8005.818359375, + "test_triangles_total_structural": 14262.0, + "test_mse_by_total_triangles": 0.5613391080756556, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_mid__d_hi__pl_hi__s44" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_1-2.5__gamma_1.5-2__s42", + "train_seed": 42, + "homophily": "h_hi", + "avg_degree": "d_lo", + "power_law": "pl_lo", + "run_slug": "h_hi__d_lo__pl_lo", + "test_loss": 1.8361661434173584, + "test_best_rerun_accuracy": 0.4446863830089569, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_hi__d_lo__pl_lo__s42" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_1-2.5__gamma_1.5-2__s43", + "train_seed": 43, + "homophily": "h_hi", + "avg_degree": "d_lo", + "power_law": "pl_lo", + "run_slug": "h_hi__d_lo__pl_lo", + "test_loss": 1.8382230997085571, + "test_best_rerun_accuracy": 0.44556498527526855, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_hi__d_lo__pl_lo__s43" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_1-2.5__gamma_1.5-2__s44", + "train_seed": 44, + "homophily": "h_hi", + "avg_degree": "d_lo", + "power_law": "pl_lo", + "run_slug": "h_hi__d_lo__pl_lo", + "test_loss": 1.858949899673462, + "test_best_rerun_accuracy": 0.440178781747818, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_hi__d_lo__pl_lo__s44" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_1-2.5__gamma_1.5-2__s42", + "train_seed": 42, + "homophily": "h_hi", + "avg_degree": "d_lo", + "power_law": "pl_lo", + "run_slug": "h_hi__d_lo__pl_lo", + "test_loss": 27931.322265625, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 28362.59375, + "test_triangles_total_structural": 19509.0, + "test_mse_by_total_triangles": 1.4538209928750834, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_hi__d_lo__pl_lo__s42" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_1-2.5__gamma_1.5-2__s43", + "train_seed": 43, + "homophily": "h_hi", + "avg_degree": "d_lo", + "power_law": "pl_lo", + "run_slug": "h_hi__d_lo__pl_lo", + "test_loss": 27384.875, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 27843.017578125, + "test_triangles_total_structural": 19509.0, + "test_mse_by_total_triangles": 1.4271883529717053, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_hi__d_lo__pl_lo__s43" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_1-2.5__gamma_1.5-2__s44", + "train_seed": 44, + "homophily": "h_hi", + "avg_degree": "d_lo", + "power_law": "pl_lo", + "run_slug": "h_hi__d_lo__pl_lo", + "test_loss": 27376.353515625, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 27824.271484375, + "test_triangles_total_structural": 19509.0, + "test_mse_by_total_triangles": 1.4262274583205188, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_hi__d_lo__pl_lo__s44" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_1-2.5__gamma_4-5__s42", + "train_seed": 42, + "homophily": "h_hi", + "avg_degree": "d_lo", + "power_law": "pl_hi", + "run_slug": "h_hi__d_lo__pl_hi", + "test_loss": 1.7885019779205322, + "test_best_rerun_accuracy": 0.4680647850036621, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_hi__d_lo__pl_hi__s42" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_1-2.5__gamma_4-5__s43", + "train_seed": 43, + "homophily": "h_hi", + "avg_degree": "d_lo", + "power_law": "pl_hi", + "run_slug": "h_hi__d_lo__pl_hi", + "test_loss": 1.778948187828064, + "test_best_rerun_accuracy": 0.4677973985671997, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_hi__d_lo__pl_hi__s43" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_1-2.5__gamma_4-5__s44", + "train_seed": 44, + "homophily": "h_hi", + "avg_degree": "d_lo", + "power_law": "pl_hi", + "run_slug": "h_hi__d_lo__pl_hi", + "test_loss": 1.7869094610214233, + "test_best_rerun_accuracy": 0.4663075804710388, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_hi__d_lo__pl_hi__s44" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_1-2.5__gamma_4-5__s42", + "train_seed": 42, + "homophily": "h_hi", + "avg_degree": "d_lo", + "power_law": "pl_hi", + "run_slug": "h_hi__d_lo__pl_hi", + "test_loss": 2653.28662109375, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 2811.577392578125, + "test_triangles_total_structural": 5625.0, + "test_mse_by_total_triangles": 0.49983598090277775, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_hi__d_lo__pl_hi__s42" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_1-2.5__gamma_4-5__s43", + "train_seed": 43, + "homophily": "h_hi", + "avg_degree": "d_lo", + "power_law": "pl_hi", + "run_slug": "h_hi__d_lo__pl_hi", + "test_loss": 2617.212158203125, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 2767.001220703125, + "test_triangles_total_structural": 5625.0, + "test_mse_by_total_triangles": 0.491911328125, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_hi__d_lo__pl_hi__s43" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_1-2.5__gamma_4-5__s44", + "train_seed": 44, + "homophily": "h_hi", + "avg_degree": "d_lo", + "power_law": "pl_hi", + "run_slug": "h_hi__d_lo__pl_hi", + "test_loss": 2639.13623046875, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 2796.378662109375, + "test_triangles_total_structural": 5625.0, + "test_mse_by_total_triangles": 0.497133984375, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_hi__d_lo__pl_hi__s44" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_4-5__gamma_1.5-2__s42", + "train_seed": 42, + "homophily": "h_hi", + "avg_degree": "d_hi", + "power_law": "pl_lo", + "run_slug": "h_hi__d_hi__pl_lo", + "test_loss": 1.7479785680770874, + "test_best_rerun_accuracy": 0.48674458265304565, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_hi__d_hi__pl_lo__s42" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_4-5__gamma_1.5-2__s43", + "train_seed": 43, + "homophily": "h_hi", + "avg_degree": "d_hi", + "power_law": "pl_lo", + "run_slug": "h_hi__d_hi__pl_lo", + "test_loss": 1.752018928527832, + "test_best_rerun_accuracy": 0.484796404838562, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_hi__d_hi__pl_lo__s43" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_4-5__gamma_1.5-2__s44", + "train_seed": 44, + "homophily": "h_hi", + "avg_degree": "d_hi", + "power_law": "pl_lo", + "run_slug": "h_hi__d_hi__pl_lo", + "test_loss": 1.742499589920044, + "test_best_rerun_accuracy": 0.4888837933540344, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_hi__d_hi__pl_lo__s44" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_4-5__gamma_1.5-2__s42", + "train_seed": 42, + "homophily": "h_hi", + "avg_degree": "d_hi", + "power_law": "pl_lo", + "run_slug": "h_hi__d_hi__pl_lo", + "test_loss": 507176.0, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 326783.03125, + "test_triangles_total_structural": 88403.0, + "test_mse_by_total_triangles": 3.696515177652342, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_hi__d_hi__pl_lo__s42" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_4-5__gamma_1.5-2__s43", + "train_seed": 43, + "homophily": "h_hi", + "avg_degree": "d_hi", + "power_law": "pl_lo", + "run_slug": "h_hi__d_hi__pl_lo", + "test_loss": 505133.65625, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 325649.96875, + "test_triangles_total_structural": 88403.0, + "test_mse_by_total_triangles": 3.683698163523862, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_hi__d_hi__pl_lo__s43" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_4-5__gamma_1.5-2__s44", + "train_seed": 44, + "homophily": "h_hi", + "avg_degree": "d_hi", + "power_law": "pl_lo", + "run_slug": "h_hi__d_hi__pl_lo", + "test_loss": 508413.5, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 326733.25, + "test_triangles_total_structural": 88403.0, + "test_mse_by_total_triangles": 3.6959520604504372, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_hi__d_hi__pl_lo__s44" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_4-5__gamma_4-5__s42", + "train_seed": 42, + "homophily": "h_hi", + "avg_degree": "d_hi", + "power_law": "pl_hi", + "run_slug": "h_hi__d_hi__pl_hi", + "test_loss": 1.6107715368270874, + "test_best_rerun_accuracy": 0.5439299941062927, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_hi__d_hi__pl_hi__s42" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_4-5__gamma_4-5__s43", + "train_seed": 43, + "homophily": "h_hi", + "avg_degree": "d_hi", + "power_law": "pl_hi", + "run_slug": "h_hi__d_hi__pl_hi", + "test_loss": 1.634343147277832, + "test_best_rerun_accuracy": 0.5387347936630249, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_hi__d_hi__pl_hi__s43" + }, + { + "experiment": "community_detection", + "wandb_project": "hgconv-cd", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_4-5__gamma_4-5__s44", + "train_seed": 44, + "homophily": "h_hi", + "avg_degree": "d_hi", + "power_law": "pl_hi", + "run_slug": "h_hi__d_hi__pl_hi", + "test_loss": 1.5953055620193481, + "test_best_rerun_accuracy": 0.5458782315254211, + "test_best_rerun_mse": null, + "test_triangles_total_structural": null, + "test_mse_by_total_triangles": null, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__community_detection__00__h_hi__d_hi__pl_hi__s44" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_4-5__gamma_4-5__s42", + "train_seed": 42, + "homophily": "h_hi", + "avg_degree": "d_hi", + "power_law": "pl_hi", + "run_slug": "h_hi__d_hi__pl_hi", + "test_loss": 115034.7265625, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 110156.2109375, + "test_triangles_total_structural": 60093.0, + "test_mse_by_total_triangles": 1.8330955508545088, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_hi__d_hi__pl_hi__s42" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_4-5__gamma_4-5__s43", + "train_seed": 43, + "homophily": "h_hi", + "avg_degree": "d_hi", + "power_law": "pl_hi", + "run_slug": "h_hi__d_hi__pl_hi", + "test_loss": 113723.4765625, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 109443.5703125, + "test_triangles_total_structural": 60093.0, + "test_mse_by_total_triangles": 1.8212365884961643, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_hi__d_hi__pl_hi__s43" + }, + { + "experiment": "triangle_counting", + "wandb_project": "hgconv-tri", + "wandb_run_name": "hypergraph_convolution_hom_0.9-1__deg_4-5__gamma_4-5__s44", + "train_seed": 44, + "homophily": "h_hi", + "avg_degree": "d_hi", + "power_law": "pl_hi", + "run_slug": "h_hi__d_hi__pl_hi", + "test_loss": 110779.6640625, + "test_best_rerun_accuracy": null, + "test_best_rerun_mse": 106560.75, + "test_triangles_total_structural": 60093.0, + "test_mse_by_total_triangles": 1.773263940891618, + "ood_test": {}, + "output_dir": "/mnt/gs21/scratch/f0101291/math/shuffle/topo/topobench_challenge/logs/train/runs/notebook_gu_grid_hgconv_reapprox__triangle_counting__00__h_hi__d_hi__pl_hi__s44" + } + ] +} diff --git a/configs/model/hypergraph/hypergraph_convolution.yaml b/configs/model/hypergraph/hypergraph_convolution.yaml new file mode 100644 index 000000000..a62e9366c --- /dev/null +++ b/configs/model/hypergraph/hypergraph_convolution.yaml @@ -0,0 +1,44 @@ +_target_: topobench.model.TBModel + +model_name: hypergraph_convolution +model_domain: hypergraph + +feature_encoder: + _target_: topobench.nn.encoders.${model.feature_encoder.encoder_name} + encoder_name: AllCellFeatureEncoder + in_channels: ${infer_in_channels:${dataset},${oc.select:transforms,null}} + out_channels: 32 + proj_dropout: 0.0 + selected_dimensions: + - 0 + - 1 + +backbone: + _target_: topobench.nn.backbones.hypergraph.hypergraph_convolution.HyperGraphConvolution + a: ${model.feature_encoder.out_channels} + b: ${model.feature_encoder.out_channels} + # False -> propagate with the raw incidence matrix (works only because the khop + # lifting produces a square [N, N] incidence). + # True -> build the actual HyperGCN Laplacian from the hyperedges each forward. + reapproximate: True + cuda: 0 + +backbone_wrapper: + _target_: topobench.nn.wrappers.HypergraphWrapper + _partial_: true + wrapper_name: HypergraphWrapper + out_channels: ${model.feature_encoder.out_channels} + num_cell_dimensions: 1 + +readout: + _target_: topobench.nn.readouts.${model.readout.readout_name} + readout_name: PropagateSignalDown + # Must stay 1: PropagateSignalDown would otherwise look for model_out["x_1"] + # and batch["incidence_1"], neither of which exists for the hypergraph domain. + num_cell_dimensions: 1 + hidden_dim: ${model.feature_encoder.out_channels} + out_channels: ${dataset.parameters.num_classes} + task_level: ${define_task_level:${dataset.parameters.task_level},${dataset.split_params.learning_setting}} + pooling_type: sum + +compile: false diff --git a/configs/transforms/hypergraph_laplacian.yaml b/configs/transforms/hypergraph_laplacian.yaml new file mode 100644 index 000000000..5051a290e --- /dev/null +++ b/configs/transforms/hypergraph_laplacian.yaml @@ -0,0 +1,4 @@ +_target_: topobench.transforms.data_transform.DataTransform +transform_name: "HypergraphLaplacian" +transform_type: "liftings" +m: true diff --git a/pyproject.toml b/pyproject.toml index 1918105d7..299b8355e 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -120,12 +120,12 @@ explicit = true # Default find-links (will be overwritten by bash script) [tool.uv] -find-links = ["https://data.pyg.org/whl/torch-2.3.0+cu121.html"] +find-links = ["https://data.pyg.org/whl/torch-2.3.0+cpu.html"] [tool.uv.sources] torch = [ { index = "pytorch-cpu", marker = "sys_platform == 'darwin' or sys_platform == 'win32'" }, - { index = "pytorch-cu121", marker = "sys_platform == 'linux'" }, + { index = "pytorch-cpu", marker = "sys_platform == 'linux'" }, ] [tool.uv.extra-build-dependencies] diff --git a/test/nn/backbones/hypergraph/test_hypergraph_convolution.py b/test/nn/backbones/hypergraph/test_hypergraph_convolution.py new file mode 100644 index 000000000..a24c5f17f --- /dev/null +++ b/test/nn/backbones/hypergraph/test_hypergraph_convolution.py @@ -0,0 +1,195 @@ +"""Unit tests for HyperGraphConvolution.""" + +import pytest +import torch +import torch_geometric + +from topobench.nn.backbones.hypergraph.hypergraph_convolution import ( + HyperGraphConvolution, + SparseMM, + incidence_to_hyperedges, +) +from topobench.nn.wrappers import HypergraphWrapper + + +def _square_incidence(num_nodes, seed=0): + """Build a square sparse incidence matrix with no empty hyperedge. + + Parameters + ---------- + num_nodes : int + Number of nodes, also used as the number of hyperedges. + seed : int, optional + Seed for reproducibility, by default 0. + + Returns + ------- + torch.Tensor + Sparse incidence matrix of shape ``[num_nodes, num_nodes]``. + """ + generator = torch.Generator().manual_seed(seed) + incidence = ( + torch.rand(num_nodes, num_nodes, generator=generator) > 0.4 + ).float() + # Guarantee every hyperedge has at least two members. + incidence[0, :] = 1.0 + incidence[1, :] = 1.0 + return incidence.to_sparse_coo() + + +def test_incidence_to_hyperedges(): + """Unit test for incidence_to_hyperedges.""" + incidence = torch.tensor( + [ + [1.0, 0.0, 1.0], + [1.0, 0.0, 0.0], + [0.0, 1.0, 0.0], + [1.0, 0.0, 0.0], + ] + ).to_sparse_coo() + + # Hyperedges 1 and 2 are singletons and must be dropped. + hyperedges = incidence_to_hyperedges(incidence) + assert set(hyperedges) == {0} + assert sorted(hyperedges[0]) == [0, 1, 3] + + # Lowering min_size keeps them. + hyperedges = incidence_to_hyperedges(incidence, min_size=1) + assert set(hyperedges) == {0, 1, 2} + assert sorted(hyperedges[1]) == [2] + assert sorted(hyperedges[2]) == [0] + + # Every hyperedge is a singleton -> empty dict. + assert incidence_to_hyperedges(torch.eye(4).to_sparse_coo()) == {} + + +def test_forward_without_reapproximation(): + """Unit test for the forward pass reusing the incidence matrix.""" + num_nodes, in_channels, out_channels = 6, 5, 3 + x_0 = torch.randn(num_nodes, in_channels) + incidence = _square_incidence(num_nodes) + + model = HyperGraphConvolution( + in_channels, out_channels, reapproximate=False + ) + x_0_out, x_1_out = model(x_0, incidence) + + assert x_0_out.shape == (num_nodes, out_channels) + assert x_1_out.shape == (num_nodes, out_channels) + assert torch.isfinite(x_0_out).all() + + +@pytest.mark.parametrize("mediators", [True, False]) +def test_forward_with_reapproximation(mediators): + """Unit test for the forward pass rebuilding the Laplacian. + + Parameters + ---------- + mediators : bool + Whether the Laplacian approximation uses mediators. + """ + num_nodes, num_hyperedges, in_channels, out_channels = 8, 5, 4, 3 + x_0 = torch.randn(num_nodes, in_channels) + + incidence = torch.zeros(num_nodes, num_hyperedges) + for edge in range(num_hyperedges): + members = torch.arange(edge, min(edge + 3, num_nodes)) + incidence[members, edge] = 1.0 + incidence = incidence.to_sparse_coo() + + model = HyperGraphConvolution( + in_channels, out_channels, reapproximate=True + ) + x_0_out, x_1_out = model(x_0, incidence, m=mediators) + + assert x_0_out.shape == (num_nodes, out_channels) + assert x_1_out.shape == (num_hyperedges, out_channels) + assert torch.isfinite(x_0_out).all() + + +def test_forward_with_only_singleton_hyperedges(): + """Unit test for the identity fallback when no hyperedge survives.""" + num_nodes, in_channels, out_channels = 4, 3, 2 + x_0 = torch.randn(num_nodes, in_channels) + incidence = torch.eye(num_nodes).to_sparse_coo() + + model = HyperGraphConvolution( + in_channels, out_channels, reapproximate=True + ) + x_0_out, _ = model(x_0, incidence) + + expected = x_0 @ model.W + model.bias + assert torch.allclose(x_0_out, expected, atol=1e-5) + + +def test_backward(): + """Unit test that gradients reach the layer parameters.""" + num_nodes, in_channels, out_channels = 6, 5, 3 + x_0 = torch.randn(num_nodes, in_channels) + incidence = _square_incidence(num_nodes) + + model = HyperGraphConvolution( + in_channels, out_channels, reapproximate=False + ) + x_0_out, _ = model(x_0, incidence) + x_0_out.sum().backward() + + assert model.W.grad is not None + assert model.W.grad.shape == model.W.shape + assert model.bias.grad is not None + + +def test_sparse_mm(): + """Unit test for SparseMM covering both backward branches.""" + m1 = torch.randn(3, 4, requires_grad=True) + m2 = torch.randn(4, 2, requires_grad=True) + + out = SparseMM.apply(m1, m2) + assert torch.allclose(out, m1 @ m2, atol=1e-6) + + out.sum().backward() + assert m1.grad.shape == m1.shape + assert m2.grad.shape == m2.shape + + +def test_reset_parameters(): + """Unit test that parameters are reinitialised in range.""" + model = HyperGraphConvolution(4, 16) + model.reset_parameters() + + bound = 1.0 / (16**0.5) + assert model.W.abs().max().item() <= bound + assert model.bias.abs().max().item() <= bound + + +def test_repr(): + """Unit test for the string representation.""" + model = HyperGraphConvolution(4, 3) + assert repr(model) == "HyperGraphConvolution (4 -> 3)" + + +def test_hypergraph_wrapper(): + """Unit test for HyperGraphConvolution behind its wrapper.""" + num_nodes, channels = 6, 4 + x_0 = torch.randn(num_nodes, channels) + incidence = _square_incidence(num_nodes) + + batch = torch_geometric.data.Data( + x_0=x_0, + y=torch.randint(0, 2, (num_nodes,)), + incidence_hyperedges=incidence, + batch_0=torch.zeros(num_nodes, dtype=torch.long), + ) + + backbone = HyperGraphConvolution(channels, channels, reapproximate=False) + wrapper = HypergraphWrapper( + backbone, **{"out_channels": channels, "num_cell_dimensions": 1} + ) + + _ = wrapper.__repr__() + model_out = wrapper(batch) + + assert model_out["x_0"].shape == x_0.shape + assert model_out["hyperedge"].shape == (num_nodes, channels) + assert "labels" in model_out + assert "batch_0" in model_out diff --git a/test/pipeline/test_pipeline.py b/test/pipeline/test_pipeline.py index a61165ae9..f0cbc7992 100644 --- a/test/pipeline/test_pipeline.py +++ b/test/pipeline/test_pipeline.py @@ -7,7 +7,7 @@ DATASET = "graph/MUTAG" # ADD YOUR DATASET HERE -MODELS = ["graph/gcn", "cell/topotune", "simplicial/topotune"] # ADD ONE OR SEVERAL MODELS +MODELS = ["graph/gcn", "cell/topotune", "simplicial/topotune","hypergraph/hypergraph_convolution"] # ADD ONE OR SEVERAL MODELS class TestPipeline: diff --git a/test/transforms/liftings/graph2hypergraph/test_hypergraph_laplacian.py b/test/transforms/liftings/graph2hypergraph/test_hypergraph_laplacian.py new file mode 100644 index 000000000..e517cde0d --- /dev/null +++ b/test/transforms/liftings/graph2hypergraph/test_hypergraph_laplacian.py @@ -0,0 +1,100 @@ +"""Unit tests for the hypergraph Laplacian approximation.""" + +import numpy as np +import pytest +import scipy.sparse as sp +import torch + +from topobench.transforms.liftings.graph2hypergraph.hypergraph_laplacian import ( + Laplacian, + adjacency, + normalise, + ssm2tst, + symnormalise, + update, +) + + +@pytest.mark.parametrize("mediators", [True, False]) +def test_laplacian(mediators): + """Unit test for Laplacian. + + Parameters + ---------- + mediators : bool + Whether the approximation uses mediators. + """ + num_nodes = 6 + hyperedges = {0: [0, 1, 2], 1: [2, 3], 2: [3, 4, 5]} + features = np.random.default_rng(0).normal(size=(num_nodes, 4)) + + A = Laplacian(num_nodes, hyperedges, features, mediators) + + assert A.shape == (num_nodes, num_nodes) + assert A.is_sparse + dense = A.to_dense() + assert torch.isfinite(dense).all() + # Self loops are added before normalisation, so the diagonal is non-zero. + assert (dense.diagonal() > 0).all() + + +def test_update(): + """Unit test for update.""" + weights = update(0, 1, 2, {}, c=3.0) + + assert set(weights) == {(0, 2), (1, 2), (2, 0), (2, 1)} + for value in weights.values(): + assert value == pytest.approx(1 / 3) + + # Calling again accumulates on the existing keys. + weights = update(0, 1, 2, weights, c=3.0) + for value in weights.values(): + assert value == pytest.approx(2 / 3) + + +def test_adjacency(): + """Unit test for adjacency.""" + edges = [[0, 1], [1, 0], [0, 1]] # duplicated pair is deduplicated + weights = {(0, 1): 0.5, (1, 0): 0.5} + + A = adjacency(edges, weights, n=3) + dense = A.to_dense() + + assert dense.shape == (3, 3) + assert torch.allclose(dense, dense.t(), atol=1e-6) + # Isolated node 2 only has its self loop, normalised to one. + assert dense[2, 2].item() == pytest.approx(1.0, abs=1e-6) + + +def test_symnormalise(): + """Unit test for symnormalise.""" + M = sp.csr_matrix(np.array([[2.0, 0.0], [0.0, 4.0]], dtype=np.float32)) + out = np.asarray(symnormalise(M).todense()) + + assert np.allclose(out, np.eye(2), atol=1e-6) + + # A zero row yields a zero scaling factor rather than an infinity. + M = sp.csr_matrix(np.array([[0.0, 0.0], [0.0, 4.0]], dtype=np.float32)) + out = np.asarray(symnormalise(M).todense()) + assert np.isfinite(out).all() + + +def test_normalise(): + """Unit test for normalise.""" + M = sp.csr_matrix(np.array([[1.0, 3.0], [0.0, 0.0]], dtype=np.float32)) + out = np.asarray(normalise(M).todense()) + + assert out[0].sum() == pytest.approx(1.0) + assert np.isfinite(out).all() + + +def test_ssm2tst(): + """Unit test for ssm2tst.""" + M = sp.coo_matrix(np.array([[1.0, 0.0], [0.0, 2.0]], dtype=np.float32)) + A = ssm2tst(M) + + assert A.is_sparse + assert A.shape == (2, 2) + assert torch.allclose( + A.to_dense(), torch.tensor([[1.0, 0.0], [0.0, 2.0]]), atol=1e-6 + ) diff --git a/topobench/nn/backbones/hypergraph/hypergraph_convolution.py b/topobench/nn/backbones/hypergraph/hypergraph_convolution.py new file mode 100644 index 000000000..9fe144db9 --- /dev/null +++ b/topobench/nn/backbones/hypergraph/hypergraph_convolution.py @@ -0,0 +1,206 @@ +"""Define the hypergraph convolution neural network layer.""" + +import math + +import torch +from torch.nn.modules.module import Module +from torch.nn.parameter import Parameter + +from topobench.transforms.liftings.graph2hypergraph.hypergraph_laplacian import ( + Laplacian, +) + + +class SparseMM(torch.autograd.Function): + """Provide sparse times dense matrix multiplication with autograd support.""" + + @staticmethod + def forward(ctx, M1, M2): + """Compute the forward pass for sparse matrix multiplication. + + Parameters + ---------- + ctx : object + The context object. + M1 : torch.Tensor + The sparse matrix. + M2 : torch.Tensor + The dense matrix. + + Returns + ------- + torch.Tensor + The resulting multiplied matrix. + """ + ctx.save_for_backward(M1, M2) + return torch.mm(M1, M2) + + @staticmethod + def backward(ctx, g): + """Compute the backward pass for sparse matrix multiplication. + + Parameters + ---------- + ctx : object + The context object. + g : torch.Tensor + The gradient tensor. + + Returns + ------- + tuple + The gradients for M1 and M2. + """ + M1, M2 = ctx.saved_tensors + g1 = g2 = None + + if ctx.needs_input_grad[0]: + g1 = torch.mm(g, M2.t()) + + if ctx.needs_input_grad[1]: + g2 = torch.mm(M1.t(), g) + + return g1, g2 + + +def incidence_to_hyperedges(incidence, min_size=2): + """Convert a sparse node-hyperedge incidence matrix to a hyperedge dict. + + ``Laplacian`` expects hyperedges as a mapping from hyperedge id to the list + of node ids it contains, whereas ``HypergraphWrapper`` hands the backbone + the sparse ``[num_nodes, num_hyperedges]`` incidence matrix. + + Hyperedges with fewer than ``min_size`` nodes are dropped: for a singleton + the supremum and the infimum coincide and the normalisation constant + ``2 * len(e) - 3`` becomes negative, which would inject negative weights + into the adjacency and break the symmetric normalisation. Singletons do + occur here, since the k-hop lifting gives every isolated node a hyperedge + containing only itself. + + Parameters + ---------- + incidence : torch.Tensor + Sparse incidence matrix of shape ``[num_nodes, num_hyperedges]``. + min_size : int, optional + Minimum number of nodes for a hyperedge to be kept, by default 2. + + Returns + ------- + dict + Mapping from hyperedge index to the list of its node indices. + """ + indices = incidence.coalesce().indices().cpu() + nodes = indices[0].tolist() + edges = indices[1].tolist() + + hyperedges = {} + for node, edge in zip(nodes, edges, strict=True): + hyperedges.setdefault(edge, []).append(node) + + return { + edge: members + for edge, members in hyperedges.items() + if len(members) >= min_size + } + + +class HyperGraphConvolution(Module): + """Define a simple GCN layer. + + Parameters + ---------- + a : int + The input feature dimension. + b : int + The output feature dimension. + reapproximate : bool, optional + Whether to reapproximate the Laplacian, by default True. + cuda : int or None, optional + The CUDA device index, by default None. + **kwargs : dict, optional + Required for TopoBench to do evaluation. + """ + + def __init__(self, a, b, reapproximate=True, cuda=None, **kwargs): + super().__init__() + self.a, self.b = a, b + self.reapproximate = reapproximate + self.device = torch.device( + "cuda:" + str(cuda) if cuda is not None else "cpu" + ) + + self.W = Parameter(torch.FloatTensor(a, b)) + self.bias = Parameter(torch.FloatTensor(b)) + self.reset_parameters() + + def reset_parameters(self): + """Reset the layer parameters.""" + std = 1.0 / math.sqrt(self.W.size(1)) + self.W.data.uniform_(-std, std) + self.bias.data.uniform_(-std, std) + + def forward(self, H, structure, m=True): + """Compute the forward pass of the HyperGraph Convolution layer. + + Parameters + ---------- + H : torch.Tensor + The hidden node features. + structure : torch.Tensor + The sparse node-hyperedge incidence matrix, of shape + ``[num_nodes, num_hyperedges]``. + m : bool, optional + Whether to use mediators, by default True. + + Returns + ------- + tuple + A tuple containing the updated node features and hyperedge features. + """ + W, b = self.W, self.bias + HW = torch.mm(H, W) + + n = H.shape[0] + num_hyperedges = structure.shape[1] + + if self.reapproximate: + X = HW.cpu().detach().numpy() + hyperedges = incidence_to_hyperedges(structure) + + if len(hyperedges) > 0: + A = Laplacian(n, hyperedges, X, m) + else: + # Every hyperedge was a singleton: fall back to the identity, + # i.e. self-loops only, which is what the normalised Laplacian + # would reduce to anyway. + A = torch.sparse_coo_tensor( + torch.arange(n).repeat(2, 1), + torch.ones(n), + (n, n), + ) + else: + A = structure + + A = A.to(H.device) + + AHW = SparseMM.apply(A, HW) + + x_1 = torch.zeros((num_hyperedges, self.b), device=H.device) + return AHW + b, x_1 + + def __repr__(self): + """Return the string representation of the module. + + Returns + ------- + str + The module string representation. + """ + return ( + self.__class__.__name__ + + " (" + + str(self.a) + + " -> " + + str(self.b) + + ")" + ) diff --git a/topobench/transforms/liftings/graph2hypergraph/hypergraph_laplacian.py b/topobench/transforms/liftings/graph2hypergraph/hypergraph_laplacian.py new file mode 100644 index 000000000..598912d98 --- /dev/null +++ b/topobench/transforms/liftings/graph2hypergraph/hypergraph_laplacian.py @@ -0,0 +1,219 @@ +"""Provide functions to compute the hypergraph Laplacian.""" + +import numpy as np +import scipy.sparse as sp +import torch + + +def Laplacian(V, E, X, m): + """Approximate the hypergraph Laplacian with or without mediators. + + Parameters + ---------- + V : int + The number of vertices. + E : dict + The dictionary of hyperedges. + X : numpy.ndarray + The node feature matrix. + m : bool + Whether to use mediators. + + Returns + ------- + torch.sparse.FloatTensor + The approximate hypergraph Laplacian matrix. + """ + edges, weights = [], {} + rv = np.random.rand(X.shape[1]) + + for k in E: + hyperedge = list(E[k]) + + p = np.dot(X[hyperedge], rv) # projection onto a random vector rv + s, i = np.argmax(p), np.argmin(p) + Se, Ie = hyperedge[s], hyperedge[i] + + # two stars with mediators + c = 2 * len(hyperedge) - 3 # normalisation constant + if m: + # connect the supremum (Se) with the infimum (Ie) + edges.extend([[Se, Ie], [Ie, Se]]) + + if (Se, Ie) not in weights: + weights[(Se, Ie)] = 0 + weights[(Se, Ie)] += float(1 / c) + + if (Ie, Se) not in weights: + weights[(Ie, Se)] = 0 + weights[(Ie, Se)] += float(1 / c) + + # connect the supremum (Se) and the infimum (Ie) with each mediator + for mediator in hyperedge: + if mediator != Se and mediator != Ie: + edges.extend( + [ + [Se, mediator], + [Ie, mediator], + [mediator, Se], + [mediator, Ie], + ] + ) + weights = update(Se, Ie, mediator, weights, c) + else: + edges.extend([[Se, Ie], [Ie, Se]]) + e = len(hyperedge) + + if (Se, Ie) not in weights: + weights[(Se, Ie)] = 0 + weights[(Se, Ie)] += float(1 / e) + + if (Ie, Se) not in weights: + weights[(Ie, Se)] = 0 + weights[(Ie, Se)] += float(1 / e) + + return adjacency(edges, weights, V) + + +def update(Se, Ie, mediator, weights, c): + """Update the weights on edges connecting extremes to the mediator. + + Parameters + ---------- + Se : int + The supremum node index. + Ie : int + The infimum node index. + mediator : int + The mediator node index. + weights : dict + The dictionary tracking edge weights. + c : float + The normalization constant. + + Returns + ------- + dict + The updated edge weights dictionary. + """ + if (Se, mediator) not in weights: + weights[(Se, mediator)] = 0 + weights[(Se, mediator)] += float(1 / c) + + if (Ie, mediator) not in weights: + weights[(Ie, mediator)] = 0 + weights[(Ie, mediator)] += float(1 / c) + + if (mediator, Se) not in weights: + weights[(mediator, Se)] = 0 + weights[(mediator, Se)] += float(1 / c) + + if (mediator, Ie) not in weights: + weights[(mediator, Ie)] = 0 + weights[(mediator, Ie)] += float(1 / c) + + return weights + + +def adjacency(edges, weights, n): + """Compute a sparse adjacency matrix from given edges and weights. + + Parameters + ---------- + edges : list + The list of edges. + weights : dict + The dictionary of weights for each edge. + n : int + The number of nodes in the graph. + + Returns + ------- + torch.sparse.FloatTensor + The normalized sparse PyTorch tensor. + """ + dictionary = {tuple(item): index for index, item in enumerate(edges)} + edges = [list(itm) for itm in dictionary] + organised = [] + + for e in edges: + i, j = e[0], e[1] + w = weights[(i, j)] + organised.append(w) + + edges, weights = np.array(edges), np.array(organised) + adj = sp.coo_matrix( + (weights, (edges[:, 0], edges[:, 1])), shape=(n, n), dtype=np.float32 + ) + adj = adj + sp.eye(n) + + A = symnormalise(sp.csr_matrix(adj, dtype=np.float32)) + A = ssm2tst(A) + return A + + +def symnormalise(M): + """Symmetrically normalize a sparse matrix. + + Parameters + ---------- + M : scipy.sparse.csr_matrix + The input sparse matrix. + + Returns + ------- + scipy.sparse.csr_matrix + The symmetrically normalized sparse matrix. + """ + d = np.array(M.sum(1)) + + dhi = np.power(d, -1 / 2).flatten() + dhi[np.isinf(dhi)] = 0.0 + DHI = sp.diags(dhi) # D half inverse i.e. D^{-1/2} + + return (DHI.dot(M)).dot(DHI) + + +def ssm2tst(M): + """Convert a scipy sparse matrix to a torch sparse tensor. + + Parameters + ---------- + M : scipy.sparse.coo_matrix + The input scipy sparse matrix. + + Returns + ------- + torch.sparse.FloatTensor + The converted PyTorch sparse tensor. + """ + M = M.tocoo().astype(np.float32) + + indices = torch.from_numpy(np.vstack((M.row, M.col))).long() + values = torch.from_numpy(M.data) + shape = torch.Size(M.shape) + + return torch.sparse.FloatTensor(indices, values, shape) + + +def normalise(M): + """Row-normalize a sparse matrix. + + Parameters + ---------- + M : scipy.sparse.csr_matrix + The input sparse matrix. + + Returns + ------- + scipy.sparse.csr_matrix + The row-normalized sparse matrix. + """ + d = np.array(M.sum(1)) + + di = np.power(d, -1).flatten() + di[np.isinf(di)] = 0.0 + di = np.nan_to_num(di) + DI = sp.diags(di) # D inverse i.e. D^{-1} + + return DI.dot(M) diff --git a/tutorials/tutorial_custom_data_transformation.ipynb b/tutorials/tutorial_custom_data_transformation.ipynb index c1d046f68..3c089c1a2 100644 --- a/tutorials/tutorial_custom_data_transformation.ipynb +++ b/tutorials/tutorial_custom_data_transformation.ipynb @@ -105,9 +105,17 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "PROJECT_ROOT set to: /home/luigi_13/TopoBench\n" + ] + } + ], "source": [ "import os\n", "from pathlib import Path\n", @@ -127,7 +135,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -179,26 +187,22 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 11, "metadata": {}, "outputs": [ { - "name": "stderr", - "output_type": "stream", - "text": [ - "/tmp/ipykernel_2458422/3549809466.py:1: UserWarning: \n", - "The version_base parameter is not specified.\n", - "Please specify a compatability version level, or None.\n", - "Will assume defaults for version 1.1\n", - " initialize(config_path=\"../configs\", job_name=\"job\")\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Transform name: dict_keys(['graph2hypergraph_lifting'])\n", - "Transform parameters: {'_target_': 'topobench.transforms.data_transform.DataTransform', 'transform_type': 'lifting', 'transform_name': 'HypergraphKHopLifting', 'k_value': 1, 'feature_lifting': 'ProjectionSum', 'preserve_edge_attr': False, 'complex_dim': 1, 'neighborhoods': '${oc.select:model.backbone.neighborhoods,null}'}\n" + "ename": "ValueError", + "evalue": "GlobalHydra is already initialized, call GlobalHydra.instance().clear() if you want to re-initialize", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mValueError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[11]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m initialize(config_path=\u001b[33m\"../configs\"\u001b[39m, job_name=\u001b[33m\"job\"\u001b[39m)\n\u001b[32m 2\u001b[39m cfg = compose(\n\u001b[32m 3\u001b[39m config_name=\u001b[33m\"run.yaml\"\u001b[39m,\n\u001b[32m 4\u001b[39m overrides=[\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/TopoBench/.venv/lib/python3.11/site-packages/hydra/initialize.py:91\u001b[39m, in \u001b[36minitialize.__init__\u001b[39m\u001b[34m(self, config_path, job_name, caller_stack_depth, version_base)\u001b[39m\n\u001b[32m 86\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m job_name \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m 87\u001b[39m job_name = detect_task_name(\n\u001b[32m 88\u001b[39m calling_file=calling_file, calling_module=calling_module\n\u001b[32m 89\u001b[39m )\n\u001b[32m---> \u001b[39m\u001b[32m91\u001b[39m \u001b[30;43mHydra\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mcreate_main_hydra_file_or_module\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 92\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mcalling_file\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mcalling_file\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 93\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mcalling_module\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mcalling_module\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 94\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mconfig_path\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mconfig_path\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 95\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mjob_name\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mjob_name\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 96\u001b[39m \u001b[30;43m\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/TopoBench/.venv/lib/python3.11/site-packages/hydra/_internal/hydra.py:53\u001b[39m, in \u001b[36mHydra.create_main_hydra_file_or_module\u001b[39m\u001b[34m(cls, calling_file, calling_module, config_path, job_name)\u001b[39m\n\u001b[32m 41\u001b[39m \u001b[38;5;129m@classmethod\u001b[39m\n\u001b[32m 42\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mcreate_main_hydra_file_or_module\u001b[39m(\n\u001b[32m 43\u001b[39m \u001b[38;5;28mcls\u001b[39m: Type[\u001b[33m\"\u001b[39m\u001b[33mHydra\u001b[39m\u001b[33m\"\u001b[39m],\n\u001b[32m (...)\u001b[39m\u001b[32m 47\u001b[39m job_name: \u001b[38;5;28mstr\u001b[39m,\n\u001b[32m 48\u001b[39m ) -> \u001b[33m\"\u001b[39m\u001b[33mHydra\u001b[39m\u001b[33m\"\u001b[39m:\n\u001b[32m 49\u001b[39m config_search_path = create_automatic_config_search_path(\n\u001b[32m 50\u001b[39m calling_file, calling_module, config_path\n\u001b[32m 51\u001b[39m )\n\u001b[32m---> \u001b[39m\u001b[32m53\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mHydra\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mcreate_main_hydra2\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mjob_name\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mconfig_search_path\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/TopoBench/.venv/lib/python3.11/site-packages/hydra/_internal/hydra.py:68\u001b[39m, in \u001b[36mHydra.create_main_hydra2\u001b[39m\u001b[34m(cls, task_name, config_search_path)\u001b[39m\n\u001b[32m 65\u001b[39m hydra = \u001b[38;5;28mcls\u001b[39m(task_name=task_name, config_loader=config_loader)\n\u001b[32m 66\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mhydra\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mcore\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mglobal_hydra\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m GlobalHydra\n\u001b[32m---> \u001b[39m\u001b[32m68\u001b[39m \u001b[30;43mGlobalHydra\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43minstance\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43minitialize\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mhydra\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 69\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m hydra\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/TopoBench/.venv/lib/python3.11/site-packages/hydra/core/global_hydra.py:16\u001b[39m, in \u001b[36mGlobalHydra.initialize\u001b[39m\u001b[34m(self, hydra)\u001b[39m\n\u001b[32m 14\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(hydra, Hydra), \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mUnexpected Hydra type : \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mtype\u001b[39m(hydra)\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m\n\u001b[32m 15\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m.is_initialized():\n\u001b[32m---> \u001b[39m\u001b[32m16\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[32m 17\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mGlobalHydra is already initialized, call GlobalHydra.instance().clear() if you want to re-initialize\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 18\u001b[39m )\n\u001b[32m 19\u001b[39m \u001b[38;5;28mself\u001b[39m.hydra = hydra\n", + "\u001b[31mValueError\u001b[39m: GlobalHydra is already initialized, call GlobalHydra.instance().clear() if you want to re-initialize" ] } ], @@ -248,7 +252,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -269,20 +273,9 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Data(edge_index=[2, 480], y=[1], num_nodes=218)" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "dataset[0]" ] @@ -296,18 +289,9 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Transform name: dict_keys(['equal_gaus_features', 'graph2hypergraph_lifting'])\n", - "Transform parameters: {'_target_': 'topobench.transforms.data_transform.DataTransform', 'transform_name': 'EqualGausFeatures', 'transform_type': 'data manipulation', 'mean': 0, 'std': 0.1, 'num_features': '${dataset.parameters.num_features}'}\n" - ] - } - ], + "outputs": [], "source": [ "print('Transform name:', cfg.transforms.keys())\n", "print('Transform parameters:', cfg.transforms['equal_gaus_features'])" @@ -315,18 +299,9 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Processing...\n", - "Done!\n" - ] - } - ], + "outputs": [], "source": [ "from topobench.data.preprocessor import PreProcessor\n", "preprocessed_dataset = PreProcessor(dataset, dataset_dir, cfg['transforms'])" @@ -334,20 +309,9 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Data(x=[218, 10], edge_index=[2, 480], y=[1], incidence_hyperedges=[218, 218], num_hyperedges=[1], x_0=[218, 10], x_hyperedges=[218, 10], num_nodes=218)" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "preprocessed_dataset[0]" ] @@ -514,7 +478,7 @@ ], "metadata": { "kernelspec": { - "display_name": "tb", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -528,9 +492,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.3" + "version": "3.11.15" } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 }