Gradient Policies¶
Gradient policies control how backpropagation interacts with the absorptive bottom ⊥. They live in zeroproofml.autodiff.policies and can be overridden for the current execution context via the gradient_policy context manager.
Available Policies¶
- CLAMP (default): Zeroes gradients on ⊥ paths and clamps finite gradients to
[-1, 1]. - PROJECT: Masks gradients when the forward value is ⊥; used for projective heads where ⊥ indicates points at infinity.
- REJECT: Always returns zero gradient on the local path; learning must come from other differentiable objectives or explicit soft surrogates. The hard
rejection_loss(is_bottom)helper is metric-style accounting. - PASSTHROUGH: For debugging; gradients propagate even through ⊥.
Usage¶
from zeroproofml.autodiff.policies import GradientPolicy, gradient_policy, apply_policy
with gradient_policy(GradientPolicy.PROJECT):
loss.backward()
Design Notes¶
- Policies are deterministic and compatible with XLA/TorchScript because they avoid Python-side branching on tensors.
- Selection precedence is explicit policy argument, then the active context override, then a registered layer default, then
CLAMP. An explicit layer-levelgradient_policytherefore remains stronger than a surrounding context. - Policy defaults can be registered per-layer using
register_policy(layer, policy). Layer identifiers are trimmed and normalized to lowercase; empty identifiers and non-enum policies are refused. POLICY_REGISTRYis a read-only compatibility view. Usepolicy_registry_snapshot()for an immutable point-in-time mapping andrestore_policy_registry(snapshot)for a fully validated atomic replacement.GradientPolicyConfig.to_dict()serializes the stable enum value, andfrom_dict()rejects unknown values.gradient_policy(...)overrides registered layer defaults while the context is active (layers can still set an explicitgradient_policy=...parameter to opt out).- Context overrides use Python context-local state. A child asyncio task inherits its parent's active policy when the child is created, then keeps an isolated copy; later changes do not leak between parent and child or between overlapping tasks. New threads start with no override and therefore use layer defaults or
CLAMP. - Projective mode typically pairs
GradientPolicy.PROJECTwith detached renormalisation to avoid NaN gradients.