### Install PyTorch Hyperbolic Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/README.md Install the library using pip or from source. Ensure torch-sparse is also installed. ```bash pip install torch-hyperbolic pip install torch-sparse ``` ```bash git clone https://github.com/fratajcz/pytorch_hyperbolic.git cd pytorch_hyperbolic pip install . pip install -r requirements.yml ``` -------------------------------- ### Visualize Bias Addition with Larger Parameters Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/intuition.md This snippet demonstrates the effect of using larger parameters in the bias addition process, which can cause points to be pushed off the hyperbolic manifold. It calls the same `plot_addition` function as the previous example but with amplified parameters. ```ipython3 plot_addition(x, parameters * 10, point_indices) ``` -------------------------------- ### Compare Distances for Points Near Origin Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/intuition.md Repeats the distance comparison from the previous example, but selects two points that are initially closer to the origin. This further illustrates how hyperbolic distances are affected by curvature and proximity to the manifold's center. ```ipython3 ball = PoincareBall() curvatures = [None, 1, 3, 5] point_indices = x.pow(2).sum(dim=-1).argsort()[0:2].tolist() fig, axes = plt.subplots(ncols= 4, nrows=1, figsize=(16,4)) for ax, curvature in zip(axes, curvatures): if curvature is None: ax.scatter(x[:, 0], x[:, 1], s=1, c=colors) ax.scatter(x[point_indices, 0], x[point_indices, 1], s=5, c="r") distance_x = x[point_indices[0], 0] - x[point_indices[1], 0] ``` -------------------------------- ### Train Node Classification Model Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/README.md Example script to train a node classification task on the Cora dataset. The script handles data downloading, processing, model training, and evaluation. ```bash $python example_train.py ``` ```text Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.x Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.tx Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.allx Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.y Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.ty Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.ally Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.graph Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.test.index Processing... Done! Model curvatures before training: [1.0, 1.0, 1.0, 1.0] Epoch: 4, Train Loss: 0.6340, Val Loss: 0.6468 Epoch: 9, Train Loss: 0.5058, Val Loss: 0.5066 Epoch: 14, Train Loss: 0.4296, Val Loss: 0.4553 Epoch: 19, Train Loss: 0.3863, Val Loss: 0.4190 Epoch: 24, Train Loss: 0.3640, Val Loss: 0.4007 Epoch: 29, Train Loss: 0.3450, Val Loss: 0.3895 Epoch: 34, Train Loss: 0.3284, Val Loss: 0.3765 Epoch: 39, Train Loss: 0.3149, Val Loss: 0.3665 Epoch: 44, Train Loss: 0.3012, Val Loss: 0.3593 Epoch: 49, Train Loss: 0.2873, Val Loss: 0.3550 Epoch: 54, Train Loss: 0.2735, Val Loss: 0.3456 Epoch: 59, Train Loss: 0.2594, Val Loss: 0.3378 Epoch: 64, Train Loss: 0.2446, Val Loss: 0.3276 Epoch: 69, Train Loss: 0.2286, Val Loss: 0.3177 Epoch: 74, Train Loss: 0.2120, Val Loss: 0.3116 Epoch: 79, Train Loss: 0.1948, Val Loss: 0.3043 Epoch: 84, Train Loss: 0.1775, Val Loss: 0.2970 Epoch: 89, Train Loss: 0.1609, Val Loss: 0.2919 Epoch: 94, Train Loss: 0.1450, Val Loss: 0.2886 Epoch: 99, Train Loss: 0.1300, Val Loss: 0.2874 Test Loss: 0.28 Model curvatures after training: [1.136, 0.977, 0.318, 0.172] ``` -------------------------------- ### Initialize and Visualize Random 2D Data Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/intuition.md Initializes a tensor of 100 random 2D points and visualizes them using a viridis colormap based on their distance from the origin. This serves as a baseline Euclidean visualization. ```ipython3 import torch import matplotlib.pyplot as plt def map_colors(values): import matplotlib as mpl cmap = mpl.colormaps["viridis"] values = values.pow(2).sum(dim=1).sqrt() values = values - values.min() values = values / values.max() return cmap(values) fig, ax = plt.subplots(figsize=(5,5)) x = torch.rand(100,2) * 10 x = x - x.mean() colors = map_colors(x) ax.scatter(x[:, 0], x[:, 1], s=1, c=colors) ``` -------------------------------- ### Visualize Euclidean and Hyperbolic Transformations Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/intuition.md This snippet visualizes the transformation of points in both Euclidean and hyperbolic spaces. It demonstrates the effect of matrix multiplication in Euclidean space and Möbius matrix-vector multiplication in hyperbolic space, along with projections between these spaces. Use this to understand how transformations affect points and their distances. ```ipython3 from torch_hyperbolic.manifolds import PoincareBall ball = PoincareBall() parameters = torch.rand((2,2)).double() point_indices = [1, 14] def plot_transformations(x, parameters, point_indices): a = x.double() b = torch.mm(a, parameters) curvature = 1 c = ball.proj(ball.expmap0(b, c=curvature), c=curvature) d = ball.proj(ball.expmap0(a, c=curvature), c=curvature) e = ball.proj(ball.mobius_matvec(parameters, d, c=curvature), c=curvature) f = ball.logmap0(e, c = curvature) fig, axes = plt.subplots(ncols= 3, nrows=2, figsize=(16,8)) titles = ["a. Euclidean Input\n$d={}$", "b. Euclidean Transformation\n$d={}$", "c. Euclidean Transf. into Hyperbolic\n$d={}$", "d. Hyperbolic Input\n$d={}$", "e. Möbius Matvec Transformation\n$d={}$", "f.Möbius Transf. into Euclidean\n$d={}$"] for i, (ax, values) in enumerate(zip(axes.flatten(), [a, b, c, d, e, f])): ax.scatter(values[:, 0], values[:, 1], s=1, c=colors) ax.scatter(values[point_indices, 0], values[point_indices, 1], s=5, c="r") if i < 2 or i == 5: distance_x = values[point_indices[0], 0] - values[point_indices[1], 0] distance_y = values[point_indices[0], 1] - values[point_indices[1], 1] distance = math.sqrt((distance_x ** 2) + (distance_y ** 2)) else: distance = math.sqrt(ball.sqdist(values[point_indices[0],:], values[point_indices[1], :], c=curvature)) radius = 1/math.sqrt(curvature) circle2 = plt.Circle((0, 0), radius, color='lightgray', fill=False) ax.add_patch(circle2) ax.set_title(titles[i].format(round(distance,2))) plt.tight_layout() plot_transformations(x, parameters, point_indices) ``` -------------------------------- ### Visualize Poincaré Ball Manifold with Varying Curvature Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/intuition.md Visualizes the projection of the same initial 2D data onto the Poincaré Ball manifold using different curvature values (1, 3, and 5). This demonstrates how curvature influences the distribution and apparent density of points within the disk. ```ipython3 ball = PoincareBall() curvatures = [1, 3, 5] fig, axes = plt.subplots(ncols= 3, nrows=1, figsize=(15,5)) for ax, curvature in zip(axes, curvatures): x_balled = ball.proj(ball.expmap0(x, c=curvature), c=curvature) ax.scatter(x_balled[:, 0], x_balled[:, 1], s=1,c=colors) radius = 1/math.sqrt(curvature) circle2 = plt.Circle((0, 0), radius, color='lightgray', fill=False) ax.add_patch(circle2) ax.set_title("Curvature {}".format(curvature)) ax.set_ylim((-1,1)) ax.set_xlim((-1,1)) ``` -------------------------------- ### Visualize Transformations with Scaled Parameters Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/intuition.md This snippet demonstrates the effect of using scaled parameters in the transformation visualization. It highlights how larger parameter values can lead to points being pushed towards the manifold's border, illustrating the impact of the `proj()` method in resetting points near or across the border. ```ipython3 plot_transformations(x, parameters*5, point_indices) ``` -------------------------------- ### Visualize Random Points in 2D Euclidean Space Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/intuition_lorentz.md Generates 1000 random points in a 2D Euclidean space, centers them by subtracting their mean, and visualizes them using a scatter plot with colors determined by their distance from the origin. ```ipython3 import torch import matplotlib.pyplot as plt fig, ax = plt.subplots(figsize=(5,5)) x = torch.rand(1000,2) x = x - x.mean() colors = map_colors(x) ax.scatter(x[:, 0], x[:, 1], s=1, c=colors) ``` -------------------------------- ### Project Data onto Poincaré Ball Manifold Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/intuition.md Projects the initialized 2D data onto a 2-dimensional Poincaré Ball manifold with a specified curvature. It then maps the points back to Euclidean space and visualizes the original, hyperbolic, and re-projected data, highlighting two tracked points and the manifold's boundary. ```ipython3 from torch_hyperbolic.manifolds import PoincareBall import math curvature = 1 point_indices = [1, 14] ball = PoincareBall() x_balled = ball.expmap0(x, c=curvature) x_back_euclidean = ball.logmap0(x_balled, c=curvature) fig, axes = plt.subplots(ncols=3, nrows=1, figsize=(15,5)) for ax, values, title in zip(axes, [x, x_balled, x_back_euclidean], ["Euclidean", "Hyperbolic", "Back to Euclidean"]): ax.scatter(values[:, 0], values[:, 1], s=1, c=colors) ax.scatter(values[point_indices, 0], values[point_indices, 1], s=3, c="r") radius = 1/math.sqrt(curvature) circle2 = plt.Circle((0, 0), radius, color='lightgray', fill=False) ax.add_patch(circle2) ax.set_title(title) ``` -------------------------------- ### HypLinear Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/nn.md Standard hyperbolic linear layer. ```APIDOC ## class torch_hyperbolic.nn.HypLinear(in_channels, out_channels, c, dropout=0, manifold='PoincareBall', use_bias=True) ### Description Hyperbolic linear layer. ``` -------------------------------- ### Hyperbolic Bias Addition Visualization Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/intuition_lorentz.md Visualizes the process of bias addition in hyperbolic space using the Möbius addition and compares it with Euclidean addition followed by projection. This snippet is useful for understanding the geometric differences between the two methods. ```ipython3 from torch_hyperbolic.manifolds import Hyperboloid ball = Hyperboloid() parameters = torch.rand(3,).double() point_indices = [1, 14] def plot_addition(x, parameters, point_indices): curvature = 10 a = x.double() parameters = ball.proj_tan0(parameters.squeeze().view(1, -1), c=curvature) b = a + parameters c = ball.proj(ball.expmap0(b, c=curvature), c=curvature) d = ball.proj(ball.expmap0(a, c=curvature), c=curvature) hyperbolic_bias = ball.proj(ball.expmap0(parameters, c=curvature),c=curvature) e = ball.proj(ball.mobius_add(d, hyperbolic_bias, c=curvature), c=curvature) f = ball.logmap0(e, c = curvature) f = ball.proj_tan0(f, c = curvature) fig = plt.figure(figsize=plt.figaspect(0.47)) titles = ["a. Euclidean Input\n$d={}$", "b. Euclidean Addition\n$d={}$", "c. Euclidean Add. into Hyperbolic\n$d={}$", "d. Hyperbolic Input\n$d={}$", "e. Möbius Addition\n$d={}$", "f. Möbius Add. into Euclidean\n$d={}$"] for i, values in enumerate([a, b, c, d, e, f]): ax = fig.add_subplot(2,3,i+1, projection='3d') ax.scatter(values[:, 1], values[:, 2], values[:, 0], s=1, c=colors) ax.scatter(values[point_indices, 1], values[point_indices, 2], values[point_indices, 0], s=3, c="r") if i < 2 or i == 5: distance_x = values[point_indices[0], 0] - values[point_indices[1], 0] distance_y = values[point_indices[0], 1] - values[point_indices[1], 1] distance = math.sqrt((distance_x ** 2) + (distance_y ** 2)) else: distance = math.sqrt(ball.sqdist(values[point_indices[0],:], values[point_indices[1], :], c=curvature)) ax.set_title(titles[i].format(round(distance,2))) plt.tight_layout() plot_addition(x_0, parameters, point_indices) ``` -------------------------------- ### Compare Distances in Euclidean and Hyperbolic Spaces Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/intuition.md Compares the Euclidean distance between two points in the input space with their hyperbolic distances on Poincaré Balls of varying curvatures (1, 3, 5). This highlights how perceived distances change significantly with curvature, especially near the manifold's boundary. ```ipython3 ball = PoincareBall() curvatures = [None, 1, 3, 5] point_indices = [1, 14] fig, axes = plt.subplots(ncols= 4, nrows=1, figsize=(16,4)) for ax, curvature in zip(axes, curvatures): if curvature is None: ax.scatter(x[:, 0], x[:, 1], s=1, c=colors) ax.scatter(x[point_indices, 0], x[point_indices, 1], s=5, c="r") distance_x = x[point_indices[0], 0] - x[point_indices[1], 0] distance_y = x[point_indices[0], 1] - x[point_indices[1], 1] distance = math.sqrt((distance_x ** 2) + (distance_y ** 2)) ax.set_title("Input Space\nd={:.2}".format(distance)) else: x_balled = ball.proj(ball.expmap0(x, c=curvature), c=curvature) ax.scatter(x_balled[:, 0], x_balled[:, 1], s=1, c=colors) ax.scatter(x_balled[point_indices, 0], x_balled[point_indices, 1], s=5, c="r") distance = math.sqrt(ball.sqdist(x_balled[point_indices[0],:], x_balled[point_indices[1], :], c=curvature)) radius = 1/math.sqrt(curvature) circle2 = plt.Circle((0, 0), radius, color='lightgray', fill=False) ax.add_patch(circle2) ax.set_title("Curvature {} d={}".format(curvature, round(distance, 1))) ax.set_ylim((-1,1)) ax.set_xlim((-1,1)) ``` -------------------------------- ### Map Euclidean Points to Hyperboloid Manifold Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/intuition_lorentz.md This snippet demonstrates mapping 2D Euclidean points to a 3D Hyperboloid manifold. It adds a zero-filled dimension, projects the points onto the Hyperboloid using exponential and projection maps, and then maps them back to Euclidean space for visualization. ```ipython3 from torch_hyperbolic.manifolds import Hyperboloid import math curvature = 1 point_indices = [1, 14] ball = Hyperboloid() colors = map_colors(x) x_0 = torch.zeros((x.shape[0],)).unsqueeze(-1) x_0 = torch.cat((x_0, x), dim=-1) x_balled = ball.proj(ball.expmap0(x_0, c=curvature), c=curvature) x_back_euclidean = ball.proj_tan0(ball.logmap0(x_balled, c=curvature), c=curvature) fig = plt.figure(figsize=plt.figaspect(0.33)) for i, (values, title) in enumerate(zip([x_0, x_balled, x_back_euclidean], ["Euclidean", "Hyperbolic", "Back to Euclidean"])): ax = fig.add_subplot(1,3,i+1, projection='3d') ax.scatter(values[:, 1], values[:, 2], values[:, 0], s=1, c=colors) ax.set_title(title) plt.tight_layout() ``` -------------------------------- ### Visualize Euclidean and Hyperbolic Bias Addition Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/intuition.md This snippet visualizes the process of adding bias to points in both Euclidean and hyperbolic spaces. It requires `torch_hyperbolic.manifolds.PoincareBall`, `torch` and `matplotlib.pyplot`. The function `plot_addition` generates plots comparing Euclidean addition with hyperbolic Möbius addition. ```ipython3 from torch_hyperbolic.manifolds import PoincareBall ball = PoincareBall() parameters = torch.rand(2,).double() point_indices = [1, 14] def plot_addition(x, parameters, point_indices): a = x.double() b = a + parameters curvature = 1 c = ball.proj(ball.expmap0(b, c=curvature), c=curvature) d = ball.proj(ball.expmap0(a, c=curvature), c=curvature) hyperbolic_bias = ball.proj(ball.expmap0(parameters, c=curvature),c=curvature) e = ball.proj(ball.mobius_add(d, hyperbolic_bias, c=curvature), c=curvature) f = ball.logmap0(e, c = curvature) fig, axes = plt.subplots(ncols= 3, nrows=2, figsize=(16,8)) titles = ["a. Euclidean Input\n$d={}$", "b. Euclidean Addition\n$d={}$", "c. Euclidean Add. into Hyperbolic\n$d={}$", "d. Hyperbolic Input\n$d={}$", "e. Möbius Additionn\n$d={}$", "f. Möbius Add. into Euclidean\n$d={}$"] for i, (ax, values) in enumerate(zip(axes.flatten(), [a, b, c, d, e, f])): ax.scatter(values[:, 0], values[:, 1], s=1, c=colors) ax.scatter(values[point_indices, 0], values[point_indices, 1], s=5, c="r") if i < 2 or i == 5: distance_x = values[point_indices[0], 0] - values[point_indices[1], 0] distance_y = values[point_indices[0], 1] - values[point_indices[1], 1] distance = math.sqrt((distance_x ** 2) + (distance_y ** 2)) else: distance = math.sqrt(ball.sqdist(values[point_indices[0],:], values[point_indices[1], :], c=curvature)) radius = 1/math.sqrt(curvature) circle2 = plt.Circle((0, 0), radius, color='lightgray', fill=False) ax.add_patch(circle2) ax.set_title(titles[i].format(round(distance,2))) plt.tight_layout() plot_addition(x, parameters, point_indices) ``` -------------------------------- ### Plotting Transformations with Scaled Parameters Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/intuition_lorentz.md This snippet demonstrates the effect of applying a linear transformation with significantly larger parameters, illustrating how the hyperbolic geometry library handles large values to prevent numerical instability. ```ipython3 plot_transformations(x, parameters*100, point_indices) ``` -------------------------------- ### Plotting Linear Transformations in Euclidean and Hyperbolic Spaces Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/intuition_lorentz.md This function visualizes the effect of Euclidean matrix multiplication and Möbius matrix-vector multiplication on point clouds in both Euclidean and hyperbolic spaces. It requires PyTorch, Matplotlib, and a hyperbolic geometry library (like `ball`). ```ipython3 parameters = torch.rand((3,3)).double() point_indices = [1, 14] def plot_transformations(x, parameters, point_indices): curvature = 10 a = x_0.double() b = torch.mm(a, parameters) b[:, 0] = 0 c = ball.proj(ball.expmap0(b, c=curvature), c=curvature) d = ball.proj(ball.expmap0(a, c=curvature), c=curvature) e = ball.proj(ball.mobius_matvec(parameters, d, c=curvature), c=curvature) f = ball.logmap0(e, c = curvature) f[:, 0] = 0 titles = ["a. Euclidean Input\n$d={}$", "b. Euclidean Transformation\n$d={}$", "c. Euclidean Transf. into Hyperbolic\n$d={}$", "d. Hyperbolic Input\n$d={}$", "e. Möbius Matvec Transformation\n$d={}$", "f.Möbius Transf. into Euclidean\n$d={}$"] fig = plt.figure(figsize=plt.figaspect(0.4)) for i, values in enumerate([a, b, c, d, e, f]): ax = fig.add_subplot(2,3,i+1, projection='3d') ax.scatter(values[:, 1], values[:, 2], values[:, 0], s=1 , c=colors) ax.scatter(values[point_indices, 1], values[point_indices, 2], values[point_indices, 0], s=10, c="r") if i < 2 or i == 5: distance_x = values[point_indices[0], 1] - values[point_indices[1], 1] distance_y = values[point_indices[0], 2] - values[point_indices[1], 2] distance = math.sqrt((distance_x ** 2) + (distance_y ** 2)) else: distance = math.sqrt(ball.sqdist(values[point_indices[0],:], values[point_indices[1], :], c=curvature)) ax.set_title(titles[i].format(round(distance,2))) plt.tight_layout() plot_transformations(x, parameters, point_indices) ``` -------------------------------- ### Visualize Hyperboloid Manifold with Varying Curvature Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/intuition_lorentz.md This code visualizes the Hyperboloid manifold with different curvature values. It plots the input space, the mapped hyperbolic space, and calculates the distance between two selected points in each space to show the impact of curvature. ```ipython3 curvatures = [None, 1, 5, 10] #point_indices = x.pow(2).sum(dim=-1).argsort()[0:2].tolist() fig = plt.figure(figsize=plt.figaspect(0.25)) for i, curvature in enumerate(curvatures): ax = fig.add_subplot(1,4,i+1, projection='3d') if curvature is None: ax.scatter(x_0[:, 1], x_0[:, 2], x_0[:, 0], s=1, c=colors) ax.scatter(x_0[point_indices, 1], x_0[point_indices, 2], x_0[point_indices, 0], s=10, c="r") distance_x = x_0[point_indices[0], 0] - x_0[point_indices[1], 0] distance_y = x_0[point_indices[0], 1] - x_0[point_indices[1], 1] distance = math.sqrt((distance_x ** 2) + (distance_y ** 2)) ax.set_title("Input Space\nd={:.2}".format(distance)) else: values = ball.proj(ball.expmap0(x_0, c=curvature), c=curvature) ax.scatter(values[:, 1], values[:, 2], values[:, 0], s=1, c=colors) ax.scatter(values[point_indices, 1], values[point_indices, 2], values[point_indices, 0], s=10, c="r") distance = math.sqrt(ball.sqdist(values[point_indices[0],:], values[point_indices[1], :], c=curvature)) ax.set_title("Curvature {} d={}".format(curvature, round(distance, 3))) ax.set_xlim((-1,1)) ax.set_ylim((-1,1)) ``` -------------------------------- ### Map Colors Based on Point Distance Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/intuition_lorentz.md This function maps input values to colors using the 'viridis' colormap. It calculates the Euclidean distance of each point from the origin and normalizes these distances to the range [0, 1] for color mapping. ```ipython3 def map_colors(values): import matplotlib as mpl cmap = mpl.colormaps["viridis"] values = values.pow(2).sum(dim=1).sqrt() values = values - values.min() values = values / values.max() return cmap(values) ``` -------------------------------- ### Lorentz Model Visualization and Distance Calculation Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/intuition_lorentz.md This snippet visualizes points in the Lorentz model, highlights specific points, and calculates the hyperbolic distance between two points. It requires the 'ball' module and matplotlib for plotting. ```python x_balled = ball.proj(ball.expmap0(x_0, c=curvature), c=curvature) ax.scatter(x_balled[:, 1], x_balled[:, 2], x_balled[:, 0], s=1, c=colors) ax.scatter(x_balled[point_indices, 1], x_balled[point_indices, 2], x_balled[point_indices, 0], s=10, c="r") distance = math.sqrt(ball.sqdist(x_balled[point_indices[0],:], x_balled[point_indices[1], :], c=curvature)) ax.set_title("Curvature {} d={}".format(curvature, round(distance, 5))) ax.set_ylim((-1,1)) ax.set_xlim((-1,1)) ``` -------------------------------- ### HypAct Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/nn.md Hyperbolic activation layer that translates features between Euclidean and hyperbolic spaces, applying an activation function in between. ```APIDOC ## class torch_hyperbolic.nn.HypAct(act, c_in=None, c_out=None, manifold='PoincareBall') ### Description Hyperbolic activation layer. Assumes input features are on a manifold with curvature c_in, brings them into euclidean space, applies the activation, and transforms the output into hyperbolic space with curvature c_out. In case only translation between two curvatures is desired, torch.nn.Identity() can be passed as activation. ``` -------------------------------- ### HyperbolicEncoder Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/nn.md Projects features from Euclidean space onto a hyperbolic manifold. It supports different manifolds like PoincareBall and Hyperboloid (Lorentz Model). ```APIDOC ## class torch_hyperbolic.nn.HyperbolicEncoder(manifold: str = 'PoincareBall', curvature=None) ### Description The encode() method of the HGCN and HNN from [https://github.com/HazyResearch/hgcn/edit/master/models/encoders.py](https://github.com/HazyResearch/hgcn/edit/master/models/encoders.py) as an explicit class. This layer does not include any linear layers, it only translates the features from euclidean space onto the manifold with curvature c. #### forward(x) Projects x into hyperbolic space: $$ \mathbf{X}^{\prime} = \textrm{exp}_\mathbf{o}^c \left( \mathbf{X} \right) $$ where exp() $\textrm{exp} \left( \right)$ is given as $$ \textrm{exp}_\mathbf{o}^c \left( \mathbf{v} \right) = \mathbf{0} \oplus_c \left( \textrm{tanh} \left( \sqrt{|c|} \frac{\lambda_\mathbf{o}^c || \mathbf{v} || _{2}}{2} \frac{\mathbf{v}}{\sqrt{|c| \mathbf{v} || _{2}}} \right) \right) $$ for PoincareBall Manifold and $$ \textrm{exp}_\mathbf{o}^c \left( \mathbf{v} \right) = \textrm{cosh} \left( \sqrt{|c|} || \mathbf{v} || _{\mathcal{L}} \right) \mathbf{0} + \mathbf{v} \frac{\textrm{sinh} \left( \sqrt{|c|} || \mathbf{v} || _{\mathcal{L}} \right) }{\sqrt{|c| || \mathbf{v} || _{\mathcal{L}}}} $$ for Hyperboloid Manifold (Lorentz Model) In case the manifold is a hyperoloid (Lorentz model), the output will have n+1 dimensions * **Parameters:** **x** (*torch.Tensor*) – The node features in euclidean space. * **Returns:** The node features in hyperbolic space. * **Return type:** torch.Tensor ``` -------------------------------- ### HyperbolicDecoder Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/nn.md Projects features from a hyperbolic manifold back into Euclidean space. It handles translations between different curvatures. ```APIDOC ## class torch_hyperbolic.nn.HyperbolicDecoder(manifold: str = 'PoincareBall', curvature=None) ### Description The decode() method of the LinearDecoder from [https://github.com/HazyResearch/hgcn/edit/master/models/decoders.py](https://github.com/HazyResearch/hgcn/edit/master/models/decoders.py) as an explicit class. This layer doe snot include any linear layers, it only translates the features from the manifold with curvature c into euclidean space. #### forward(x) Projects x from hyperbolic back into euclidean space. In case the manifold is a hyperboloid (Lorentz Model), the output will have n-1 dimensions than the input ``` -------------------------------- ### HyperbolicEncoder Forward Pass Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/nn.md Projects node features from Euclidean space onto a hyperbolic manifold. The specific projection method depends on the chosen manifold (PoincareBall or Hyperboloid). ```python def forward(x): """ Projects x into hyperbolic space: $$ \mathbf{X}^{\prime} = \textrm{exp}_\mathbf{o}^c \left( \mathbf{X} \right) $$ where exp() $\textrm{exp} \left( \right)$ is given as $$ \textrm{exp}_\mathbf{o}^c \left( \mathbf{v} \right) = \mathbf{0} \oplus_c \left( \textrm{tanh} \left( \sqrt{|c|} \frac{\lambda_\mathbf{o}^c || \mathbf{v} || _{2}}{2} \frac{\mathbf{v}}{\sqrt{|c| \mathbf{v} || _{2}}} \right) \right) $$ for PoincareBall Manifold and $$ \textrm{exp}_\mathbf{o}^c \left( \mathbf{v} \right) = \textrm{cosh} \left( \sqrt{|c|} || \mathbf{v} || _{\mathcal{L}} \right) \mathbf{0} + \mathbf{v} \frac{\textrm{sinh} \left( \sqrt{|c|} || \mathbf{v} || _{\mathcal{L}} \right) }{\sqrt{|c| || \mathbf{v} || _{\mathcal{L}}}} $$ for Hyperboloid Manifold (Lorentz Model) In case the manifold is a hyperoloid (Lorentz model), the output will have n+1 dimensions * **Parameters:** **x** (*torch.Tensor*) – The node features in euclidean space. * **Returns:** The node features in hyperbolic space. * **Return type:** torch.Tensor """ pass ``` -------------------------------- ### Calculate Hyperbolic Distance Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/intuition.md Calculates the distance between two points in a hyperbolic space projected onto a ball model. Requires a curvature value. ```python distance_y = x[point_indices[0], 1] - x[point_indices[1], 1] distance = math.sqrt((distance_x ** 2) + (distance_y ** 2)) ax.set_title("Input Space\nd={:.2}".format(distance)) else: x_balled = ball.proj(ball.expmap0(x, c=curvature), c=curvature) ax.scatter(x_balled[:, 0], x_balled[:, 1], c=colors, s=1) ax.scatter(x_balled[point_indices, 0], x_balled[point_indices, 1], s=5, c="r") distance = math.sqrt(ball.sqdist(x_balled[point_indices[0],:], x_balled[point_indices[1], :], c=curvature)) radius = 1/math.sqrt(curvature) circle2 = plt.Circle((0, 0), radius, color='lightgray', fill=False) ax.add_patch(circle2) ax.set_title("Curvature {} d={}".format(curvature, round(distance, 3))) ax.set_ylim((-1,1)) ax.set_xlim((-1,1)) ``` -------------------------------- ### HyperbolicDecoder Forward Pass Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/nn.md Projects node features from a hyperbolic manifold back into Euclidean space. For the Hyperboloid manifold, the output dimensions will differ from the input. ```python def forward(x): """ Projects x from hyperbolic back into euclidean space. In case the manifold is a hyperboloid (Lorentz Model), the output will have n-1 dimensions than the input """ pass ``` -------------------------------- ### HGATConv Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/nn.md Hyperbolic graph attention convolution layer that operates on features already on the manifold. ```APIDOC ## class torch_hyperbolic.nn.HGATConv(in_channels, out_channels, c, manifold='PoincareBall', dropout=0, heads=1, use_bias=True, edge_dim=None, aggr='add', local_agg=False, concat: bool = True, negative_slope: float = 0.2, fill_value: float | Tensor | str = 'mean', **kwargs) ### Description Hyperbolic graph attention layer. It assumes that the input is already on the manifold and outputs the feature matrix on the manifold. ``` -------------------------------- ### Analyze Distance Impact of Curvature on Closer Points Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/intuition_lorentz.md This snippet visualizes the Hyperboloid manifold with varying curvatures, focusing on two points closer to the center. It highlights that curvature has less impact on the distance between points near the origin, as distances grow exponentially further away. ```ipython3 curvatures = [None, 1, 5, 10] point_indices = x.pow(2).sum(dim=-1).argsort()[0:2].tolist() fig = plt.figure(figsize=plt.figaspect(0.25)) for i, curvature in enumerate(curvatures): ax = fig.add_subplot(1,4,i+1, projection='3d') if curvature is None: ax.scatter(x_0[:, 1], x_0[:, 2], x_0[:, 0], s=1, c=colors) ax.scatter(x_0[point_indices, 1], x_0[point_indices, 2], x_0[point_indices, 0], s=10, c="r") distance_x = x[point_indices[0], 0] - x[point_indices[1], 0] distance_y = x[point_indices[0], 1] - x[point_indices[1], 1] distance = math.sqrt((distance_x ** 2) + (distance_y ** 2)) ax.set_title("Input Space\nd={:.5}".format(distance)) else: ``` -------------------------------- ### HGCNConv Forward Pass Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/nn.md Performs hyperbolic graph convolution. Assumes input features are already on the manifold and outputs features that remain on the manifold. ```python def forward(x, edge_index): """ Assumes that x is already on the manifold, i.e. that features are hyperbolic """ pass ``` -------------------------------- ### HGCNConv Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/nn.md Hyperbolic graph convolution layer that operates on features already on the manifold. It's implemented for the MessagePassing framework. ```APIDOC ## class torch_hyperbolic.nn.HGCNConv(in_channels, out_channels, c, manifold='PoincareBall', dropout=0, use_bias=True, aggr='add', normalize=False, use_att=False, local_agg=False) ### Description Hyperbolic graph convolution layer. It assumes that the input is already on the manifold and outputs the feature matrix on the manifold. Implementation based on [https://github.com/HazyResearch/hgcn/blob/master/layers/hyp_layers.py](https://github.com/HazyResearch/hgcn/blob/master/layers/hyp_layers.py) but implemented for the MessagePassing framework using the GCN template from [https://pytorch-geometric.readthedocs.io/en/latest/tutorial/create_gnn.html#implementing-the-gcn-layer](https://pytorch-geometric.readthedocs.io/en/latest/tutorial/create_gnn.html#implementing-the-gcn-layer) #### forward(x, edge_index) Assumes that x is already on the manifold, i.e. that features are hyperbolic #### message(x_i, x_j, norm) If we use local aggregation, x_i and x_j are still on the manifold, else they are in tangent space of origin ``` -------------------------------- ### HFiLMConv Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/nn.md Hyperbolic feature-wise linear modulation graph convolution layer. It operates on features already on the manifold. ```APIDOC ## class torch_hyperbolic.nn.HFiLMConv(in_channels, out_channels, c, num_relations: int = 1, nn: Callable | None = None, act: Callable | None = ReLU(), manifold='PoincareBall', dropout=0, aggr='mean', local_agg=False, c_per_relation=False, c_per_relation_init_value=1, c_per_relation_trainable=True) ### Description Hyperbolic feature-wise linear modulation graph convolution layer. It assumes that the input is already on the manifold and outputs the feature matrix on the manifold. #### forward(x: Tensor | Tuple[Tensor, Tensor], edge_index: Tensor | SparseTensor, edge_type: Tensor | None = None) → Tensor Assumes that x is already on the manifold, i.e. that features are hyperbolic with curvature c ``` -------------------------------- ### HGCNConv Message Function Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/nn.md Defines the message passing logic for HGCNConv. If local aggregation is used, features remain on the manifold; otherwise, they are in the tangent space of the origin. ```python def message(x_i, x_j, norm): """ If we use local aggregation, x_i and x_j are still on the manifold, else they are in tangent space of origin """ pass ``` -------------------------------- ### HFiLMConv Forward Pass Source: https://github.com/fratajcz/pytorch_hyperbolic/blob/master/docs/source/nn.md Performs hyperbolic feature-wise linear modulation graph convolution. Assumes input features are on the manifold and outputs features that remain on the manifold. ```python def forward(x: Tensor | Tuple[Tensor, Tensor], edge_index: Tensor | SparseTensor, edge_type: Tensor | None = None) -> Tensor: """ Assumes that x is already on the manifold, i.e. that features are hyperbolic with curvature c """ pass ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.