|
|
|
|
| """Hub-compliant kernel layer for the szl-lambda-gate kernel.
|
|
|
| Per the Kernel Hub `kernel-requirements`, layers exposed for extension must be
|
| PURE torch.nn.Module subclasses:
|
| - no custom __init__,
|
| - no class variables,
|
| - only a `forward` method.
|
|
|
| The layer therefore reads its parameters (weights / threshold) off the module
|
| instance it is bound to (set by the host model) and only defines `forward`.
|
|
|
| HONESTY: `LambdaGate` emits an ADVISORY governance signal (the weighted
|
| geometric mean Λ plus a pass/fail vs threshold). Λ is NOT proven trust; its
|
| uniqueness is Conjecture 1 (open).
|
| """
|
| import torch
|
| from torch import nn
|
|
|
| from ._lambda import lambda_aggregate, lambda_gate
|
|
|
|
|
| class LambdaGate(nn.Module):
|
| """Pure Λ-gate layer.
|
|
|
| Reads optional ``self.weights`` (1-D, length k) and ``self.threshold``
|
| (float, default 0.5) off the bound module instance.
|
|
|
| forward(axes) -> LambdaGateResult(score, passed, threshold, advisory) where
|
| ``score`` = Λ(axes) over the last dim and ``passed`` = score >= threshold.
|
| Differentiable in ``score`` w.r.t. ``axes``.
|
| """
|
|
|
| def forward(self, axes: torch.Tensor):
|
| weights = getattr(self, "weights", None)
|
| threshold = getattr(self, "threshold", 0.5)
|
| return lambda_gate(axes, weights=weights, threshold=float(threshold))
|
|
|
|
|
| class LambdaAggregate(nn.Module):
|
| """Pure Λ-aggregator layer: forward(axes) -> Λ(axes) tensor in [0,1].
|
|
|
| Reads optional ``self.weights`` (1-D, length k) off the bound module
|
| instance; uniform weights when absent. Returns just the score (no gate),
|
| fully differentiable w.r.t. ``axes``.
|
| """
|
|
|
| def forward(self, axes: torch.Tensor) -> torch.Tensor:
|
| weights = getattr(self, "weights", None)
|
| return lambda_aggregate(axes, weights=weights)
|
|
|