Loss Laplacian#

laplacian #

CLASS DESCRIPTION
LaplacianLoss

Graph Laplacian regularization loss.

FUNCTION DESCRIPTION
laplacian_loss

Computes regularization based on the graph Laplacian to encourage

Classes#

LaplacianLoss(reduce: Literal['sum', 'mean', 'trace'] = 'trace', sign: float = 1.0, normalize: bool = True, context_prefix: str | None = None, **kwargs) #

Bases: Loss

Graph Laplacian regularization loss.

Computes regularization based on the graph Laplacian to encourage smoothness of embeddings over the graph structure: \(L_{lap} = \frac{1}{2} \sum_{kl} K_{kl} \| z_k - z_l \|^2_2 = z^\top L z\), where \(K\) is the adjacency matrix, \(L\) is the graph Laplacian, and \(z\) is the embedding vector.

For multiple dimensions: \(L_{lap} = \text{tr}(Z^T L Z)\), where \(Z\) is the embedding matrix.

PARAMETER DESCRIPTION
reduce

Reduction method.

  • "trace": Trace of Z^T L Z (standard Laplacian regularization)
  • "sum": Sum of all elements in Z^T L Z
  • "mean": Mean of all elements in Z^T L Z

TYPE: Literal["sum", "mean", "trace"], optional, by default "trace" DEFAULT: 'trace'

sign

Loss sign multiplier.

TYPE: float, optional, by default 1.0 DEFAULT: 1.0

normalize

Whether to normalize by the number of nodes.

TYPE: bool, optional, by default True DEFAULT: True

**kwargs

Additional keyword arguments.

TYPE: dict DEFAULT: {}

Examples:

>>> loss_fn = LaplacianLoss(reduce="trace", sign=1.0)
>>> # Laplacian matrix
>>> L = torch.tensor([[1.0, -1.0, 0.0], [-1.0, 2.0, -1.0], [0.0, -1.0, 1.0]])
>>> # Embedding matrix
>>> Z = torch.randn(3, 2)
>>> context = {"laplacian": L, "embedding": Z}
>>> loss = loss_fn(context)
METHOD DESCRIPTION
forward

Compute Laplacian regularization loss.

Source code in spectre/loss/laplacian.py
def __init__(
    self,
    reduce: Literal["sum", "mean", "trace"] = "trace",
    sign: float = 1.0,
    normalize: bool = True,
    context_prefix: str | None = None,
    **kwargs,
):
    super().__init__(
        reduce=reduce, sign=sign, context_prefix=context_prefix, **kwargs
    )

    if not isinstance(normalize, bool):
        raise TypeError("`normalize` must be a boolean.")
    self.normalize = normalize
Functions#
forward(context: dict, **kwargs) -> torch.Tensor #

Compute Laplacian regularization loss.

PARAMETER DESCRIPTION
context

Dictionary containing the graph Laplacian and embedding.

TYPE: dict

**kwargs

Additional keyword arguments.

TYPE: dict DEFAULT: {}

RETURNS DESCRIPTION
Tensor

Laplacian regularization loss.

Source code in spectre/loss/laplacian.py
def forward(self, context: dict, **kwargs) -> torch.Tensor:
    """
    Compute Laplacian regularization loss.

    Parameters
    ----------
    context : dict
        Dictionary containing the graph Laplacian and embedding.

    **kwargs : dict
        Additional keyword arguments.

    Returns
    -------
    torch.Tensor
        Laplacian regularization loss.
    """
    K = self._get_context(context, "K", None)
    Z = self._get_context(context, "Z", None)

    if K is None:
        raise ValueError("`LaplacianLoss` requires `K` in context.")
    if Z is None:
        raise ValueError("`LaplacianLoss` requires `Z` in context.")

    return laplacian_loss(
        K=K,
        Z=Z,
        reduce=self.reduce,
        sign=self.sign,
        normalize=self.normalize,
    )

Functions#

laplacian_loss(K: torch.Tensor, Z: torch.Tensor, reduce: Literal['sum', 'mean', 'trace'] = 'trace', sign: float = 1.0, normalize: bool = True) -> torch.Tensor #

Computes regularization based on the graph Laplacian to encourage smoothness of embeddings over the graph structure: \(L_{lap} = \frac{1}{2} \sum_{kl} K_{kl} \| z_k - z_l \|^2_2 = z^\top L z\), where \(K\) is the adjacency matrix, \(L\) is the graph Laplacian, and \(z\) is the embedding vector.

For multiple dimensions: \(L_{lap} = \text{tr}(Z^T L Z)\), where \(Z\) is the embedding matrix.

PARAMETER DESCRIPTION
K

Graph Laplacian matrix (n_nodes, n_nodes).

TYPE: Tensor

Z

Node embedding matrix (n_nodes, n_features).

TYPE: Tensor

reduce

Reduction method, by default "trace".

TYPE: Literal['sum', 'mean', 'trace'] DEFAULT: 'trace'

sign

Loss sign multiplier, by default 1.0.

TYPE: float DEFAULT: 1.0

normalize

Whether to normalize by number of nodes, by default True.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION
Tensor

Laplacian regularization loss.

Source code in spectre/loss/laplacian.py
def laplacian_loss(
    K: torch.Tensor,
    Z: torch.Tensor,
    reduce: Literal["sum", "mean", "trace"] = "trace",
    sign: float = 1.0,
    normalize: bool = True,
) -> torch.Tensor:
    """
    Computes regularization based on the graph Laplacian to encourage
    smoothness of embeddings over the graph structure:
    $L_{lap} = \\frac{1}{2} \\sum_{kl} K_{kl} \\| z_k - z_l \\|^2_2 = z^\\top L z$,
    where $K$ is the adjacency matrix, $L$ is the graph Laplacian, and $z$ is
    the embedding vector.

    For multiple dimensions: $L_{lap} = \\text{tr}(Z^T L Z)$, where $Z$ is
    the embedding matrix.

    Parameters
    ----------
    K : torch.Tensor
        Graph Laplacian matrix (n_nodes, n_nodes).

    Z : torch.Tensor
        Node embedding matrix (n_nodes, n_features).

    reduce : Literal["sum", "mean", "trace"], optional
        Reduction method, by default "trace".

    sign : float, optional
        Loss sign multiplier, by default 1.0.

    normalize : bool, optional
        Whether to normalize by number of nodes, by default True.

    Returns
    -------
    torch.Tensor
        Laplacian regularization loss.
    """
    check_2d(K)
    check_2d(Z)
    check_square_shape(K)
    check_same_shape(Z, K, axis=0)

    # Compute Z^T L Z
    laplacian_quad = Z.T @ K @ Z

    if reduce == "trace":
        loss = torch.trace(laplacian_quad)
    elif reduce == "sum":
        loss = torch.sum(laplacian_quad)
    elif reduce == "mean":
        loss = torch.mean(laplacian_quad)
    else:
        raise ValueError(
            f"Unknown reduce method: {reduce}. Choose from ['sum', 'mean', 'trace']."
        )

    if normalize:
        loss = loss / Z.shape[0]

    return sign * loss