Scalar Activation Derivatives #
Real calculus lemmas (HasDerivAt, etc.) for scalar activation functions, used as building blocks
for TorchLean autograd correctness proofs.
These identify derivatives of the real specifications, not the behavior of native kernels.
Related PyTorch operators #
The operator references below give context for the formulas. Native evaluation, rounding, and implementation-specific branches are outside these exact-real theorems.
- ReLU:
torch.relu/torch.nn.functional.reluhttps://pytorch.org/docs/stable/generated/torch.relu.html https://pytorch.org/docs/stable/generated/torch.nn.functional.relu.html - Leaky ReLU:
torch.nn.functional.leaky_reluhttps://pytorch.org/docs/stable/generated/torch.nn.functional.leaky_relu.html - Sigmoid (logistic):
torch.sigmoidhttps://pytorch.org/docs/stable/generated/torch.sigmoid.html - Tanh:
torch.tanhhttps://pytorch.org/docs/stable/generated/torch.tanh.html - Softplus:
torch.nn.functional.softplushttps://pytorch.org/docs/stable/generated/torch.nn.functional.softplus.html - SiLU / Swish:
torch.nn.functional.siluhttps://pytorch.org/docs/stable/generated/torch.nn.functional.silu.html - ELU:
torch.nn.functional.eluhttps://pytorch.org/docs/stable/generated/torch.nn.functional.elu.html - GELU:
torch.nn.functional.gelu(..., approximate="tanh")https://pytorch.org/docs/stable/generated/torch.nn.functional.gelu.html - Hyperbolic sine/cosine:
torch.sinh,torch.coshhttps://pytorch.org/docs/stable/generated/torch.sinh.html https://pytorch.org/docs/stable/generated/torch.cosh.html
The ReLU, leaky-ReLU, and ELU theorems assume x ≠ 0. ReLU has a kink there; leaky ReLU
and ELU are differentiable there when their slope parameter is 1, but these statements do not
cover that case.
Correctness of the ReLU derivative spec away from the kink at 0.
PyTorch note: torch.relu uses a subgradient convention at 0; in this file we avoid that
subtlety by assuming x ≠ 0.
Correctness of the leaky-ReLU derivative spec away from the kink at 0.
PyTorch correspondence: torch.nn.functional.leaky_relu(x, negative_slope = αₗ) with αₗ > 0.
Correctness of the square derivative spec: d/dx x^2 = 2x.
Correctness of the hyperbolic-sine derivative spec: sinh' = cosh.
Correctness of the hyperbolic-cosine derivative spec: cosh' = sinh.
The compensated exponential difference agrees with exp x - 1 over the reals.
Correctness of the ELU derivative spec away from the kink at 0.
PyTorch correspondence: torch.nn.functional.elu(x, alpha = α). For arbitrary α, the left
derivative at 0 is α and the right derivative is 1, so the clean reusable statement is the
pointwise theorem away from 0.
Both evaluation branches of sigmoid define (1 + exp (-x))⁻¹ over the reals.
The negative branch multiplies numerator and denominator by exp x. This identity lets the
calculus proofs use one smooth expression, including at the branch boundary x = 0.
The real sigmoid is nonnegative.
The real sigmoid is at most 1.
Sigmoid also equals exp x / (1 + exp x) over the reals.
This form is the negative-input evaluation branch and the derivative obtained by differentiating
log (1 + exp x).
The decaying-exponential slope is the usual real sigmoid derivative.
Correctness of the sigmoid derivative spec.
PyTorch correspondence: torch.sigmoid.
Differentiating σ(x)(1 - σ(x)) gives σ'(x)(1 - 2σ(x)).
This is the scalar second derivative used when a sigmoid VJP is evaluated over dual numbers. The real identity holds at zero as well as on either evaluation branch.
Over the reals the logistic formula exp x / (exp x + 1) is the sigmoid, despite their
different floating-point evaluation schedules.
Correctness of the derivative spec for Activation.Math.logisticSpec.
This is the scalar logistic formula exp x / (exp x + 1). It is not named
softmax: a one-entry softmax is always 1, while TorchLean's actual axis-normalizing softmax is
the tensor-level Activation.softmaxSpec in NN/Spec/Layers/Activation.lean. Over the reals it
is the sigmoid (logisticSpec_eq_sigmoidSpec). Its output-form derivative equals the input-based
sigmoid slope by sigmoid_deriv_spec_eq, so correctness follows from sigmoid_deriv_correct.
Squaring the scaled reciprocal cosh preserves the exact real tanh derivative.
Correctness of the tanh derivative spec.
PyTorch correspondence: torch.tanh.
The real tanh chain rule, using the same derivative expression as the runtime.
Correctness of the tanh-approximate GELU derivative spec.
PyTorch correspondence: torch.nn.functional.gelu(x, approximate = "tanh"). The proof follows
the product rule for
x * (1 + tanh(c * (x + k*x^3))) / 2, plus the chain rule through the tanh inner polynomial.
The compensated formula agrees with log(1 + x) over the reals.
The branch-stable real softplus specification is extensionally log (1 + exp x).
Correctness of the softplus derivative spec.
PyTorch correspondence: torch.nn.functional.softplus.
The softplus derivative is sigmoid, so its derivative is σ(x)(1 - σ(x)) at every real
input. This supplies the second-derivative identity without differentiating the branch test.
Splitting the negative exponential does not change the real SiLU function.
The split-exponential slope is the real product-rule derivative of SiLU.
Correctness of the SiLU derivative spec.
silu(x) = x * sigmoid(x), so the proof is just the product rule plus the already-proved
sigmoid derivative. This is the scalar calculus fact used by the tensor-level VJP proof bridge.
Correctness of the safeLog derivative spec (a smooth log surrogate).
safeLog is not a standard PyTorch primitive; conceptually it is “log-like but always defined”
using softplus to avoid a strict-positivity side condition.
Related PyTorch primitives: https://pytorch.org/docs/stable/generated/torch.log.html
Scaling before squaring preserves the real smooth-absolute-value function.
For positive ε, sqrt(x² + ε) is differentiable with derivative x / sqrt(x² + ε).