spd_learn.models.SPDResBlock#

class spd_learn.models.SPDResBlock(num_features: int | None = None, hidden_channels: int = 16, eps: float = 1e-06, device: device | None = None, dtype: dtype | None = None)[source]#

Bases: Module

Spectral 1D-CNN Riemannian Residual Block on the SPD Manifold.

This module implements a Riemannian residual block for SPD manifolds [Chen et al., 2024]. Given an SPD matrix \(X \in \mathcal{S}_{++}^d\), it computes the spectral decomposition \(X = U \Lambda U^\top\), extracts log-eigenvalues \(\log(\text{clamp}(\Lambda, \varepsilon))\), maps them through a 1D spectral convolutional network, reconstructs the SPD residual \(F(X) = U \text{Diag}(\exp(s)) U^\top\), and combines it with the skip connection via the Log-Euclidean geodesic residual:

\[Z = \exp(\log(X) + \log(F(X)))\]
Parameters:
  • num_features (int, optional) – Matrix dimension \(d\). Default is None.

  • hidden_channels (int, default=16) – Number of hidden channels in the 1D spectral CNN.

  • eps (float, default=1e-6) – Lower clamp threshold for eigenvalues to maintain strict positive definiteness.

  • device (torch.device, optional) – Device on which module parameters are allocated. Default is None.

  • dtype (torch.dtype, optional) – Data type of module parameters. Default is None.

See also

SPDResNet

Complete ResNet architecture using this block.

LogEuclideanResidual

Log-Euclidean skip connection.

Examples

>>> import torch
>>> from spd_learn.models import SPDResBlock
>>> block = SPDResBlock(num_features=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) → Tensor[source]#

Forward pass computing the Riemannian residual transformation.

Parameters:

X (torch.Tensor) – Input SPD tensor of shape (…, d, d).

Returns:

Output SPD tensor of shape (…, d, d).

Return type:

torch.Tensor

reset_parameters() → None[source]#

Initialize residual spectral CNN near the identity map.