spd_learn.modules.LogEuclideanResidual#
- class spd_learn.modules.LogEuclideanResidual(device=None, dtype=None)[source]#
Bases:
ModuleResidual/skip connection for SPD networks using the Log-Euclidean metric.
This module implements a Riemannian residual connection based on the Log-Euclidean framework [Katsman et al., 2023]. It enables skip connections in SPD neural networks while respecting the manifold geometry, addressing a fundamental challenge in geometric deep learning.
Notes
Standard residual connections \(y = x + f(x)\) from ResNets [He et al., 2016] cannot be directly applied to SPD manifolds because the sum of two SPD matrices does not preserve the geometric structure needed for Riemannian operations. The Log-Euclidean residual provides a geometrically principled alternative by performing addition in the tangent space (via matrix logarithm) and mapping back to the manifold (via matrix exponential).
The residual connection is computed as:
\[Z = \exp(\log(X) + \log(Y))\]where \(X\) is the input tensor, \(Y\) is the residual tensor, and \(\log\) and \(\exp\) denote the matrix logarithm and exponential, respectively.
This formulation corresponds to the Log-Euclidean midpoint when both inputs have equal weight, making it a natural and geometrically meaningful choice for residual connections on SPD manifolds. The operation is:
Commutative: \(\text{residual}(X, Y) = \text{residual}(Y, X)\)
Identity-preserving: \(\text{residual}(X, I) = X\) when \(Y = I\)
SPD-preserving: Output is guaranteed to be SPD if inputs are SPD
The authors of Katsman et al. [2023] demonstrate that Riemannian ResNets:
Outperform existing manifold neural networks on hyperbolic graph learning
Achieve superior performance on video classification using SPD matrices (videos represented as covariance matrices)
Exhibit improved training dynamics compared to non-residual architectures
Require only the exponential map (geodesic information) for implementation
- Parameters:
device (torch.device, optional) – The device on which the module will be allocated. Default: None.
dtype (torch.dtype, optional) – The data type of the module. Default: None.
See also
spd_learn.functional.matrix_logMatrix logarithm for SPD matrices.
spd_learn.functional.matrix_expMatrix exponential for symmetric matrices.
spd_learn.functional.log_euclidean_meanWeighted Log-Euclidean mean.
Examples
Basic usage with random SPD matrices:
>>> import torch >>> from spd_learn.modules import LogEuclideanResidual >>> residual = LogEuclideanResidual() >>> X = torch.randn(4, 8, 8) >>> X = X @ X.mT + 0.1 * torch.eye(8) # Make SPD >>> Y = torch.randn(4, 8, 8) >>> Y = Y @ Y.mT + 0.1 * torch.eye(8) # Make SPD >>> Z = residual(X, Y) >>> Z.shape torch.Size([4, 8, 8])
Using in a residual block within an SPD network:
>>> from spd_learn.modules import BiMap, ReEig, LogEuclideanResidual >>> class SPDResidualBlock(torch.nn.Module): ... def __init__(self, n_features): ... super().__init__() ... self.bimap = BiMap(n_features, n_features) ... self.reeig = ReEig() ... self.residual = LogEuclideanResidual() ... ... def forward(self, x): ... y = self.bimap(x) ... y = self.reeig(y) ... return self.residual(x, y) # Skip connection >>> block = SPDResidualBlock(8) >>> X = torch.randn(2, 8, 8) >>> X = X @ X.mT + 0.1 * torch.eye(8) >>> out = block(X) >>> out.shape torch.Size([2, 8, 8])
- forward(x: Tensor, y: Tensor) Tensor[source]#
Forward pass computing the Log-Euclidean residual.
Computes \(Z = \exp(\log(X) + \log(Y))\), which combines two SPD matrices in a geometrically principled way using the Log-Euclidean framework.
- Parameters:
x (torch.Tensor) – Input SPD tensor of shape (…, n, n). Must be symmetric positive definite.
y (torch.Tensor) – Residual SPD tensor of shape (…, n, n). Must be symmetric positive definite and have the same shape as x.
- Returns:
The Log-Euclidean combination of x and y, with the same shape as the inputs. The output is guaranteed to be SPD.
- Return type:
Notes
The operation is performed in three steps:
Map both inputs to the tangent space via matrix logarithm
Add the tangent vectors (standard Euclidean addition)
Map back to the SPD manifold via matrix exponential
This is equivalent to computing:
\[Z = X^{1/2} (X^{-1/2} Y X^{-1/2})^{1/2} X^{1/2}\]but the Log-Euclidean formulation is computationally more efficient and numerically stable.