Reverse-Mode Automatic Differentiation #
Implementation of reverse-mode AD (backpropagation) similar to Haskell's ad package.
This enables efficient gradient computation for machine learning optimization.
Features #
- Dual numbers with forward value and backward gradient
- Reverse-mode differentiation (backpropagation)
- Support for common math operations
- Efficient gradient computation via computational graph
Usage Example #
-- Define a function
def f (x : Float) : Float := x * x + 2.0 * x + 1.0
-- Compute gradient at x = 3.0
let grad := diff f 3.0
-- Result: 8.0 (derivative of x² + 2x + 1 at x=3 is 2x + 2 = 8)
Tape entry for reverse-mode AD. Stores the operation index, parent indices, and local derivatives.
- idx : Nat
Index of this operation in the tape
Parent indices (inputs to this operation)
Local derivatives with respect to each parent
Instances For
Equations
Instances For
Equations
Equations
- One or more equations did not get rendered due to their size.
Instances For
Instances For
Equations
Create an empty tape
Instances For
Dual number for reverse-mode AD. Contains the primal value and a reference to the tape.
Instances For
Instances For
Equations
Equations
Equations
- One or more equations did not get rendered due to their size.
Instances For
Create a constant (no gradient)
Equations
- Hesper.AD.Reverse.Dual.const x = { primal := x, tapeIdx := 0 }
Instances For
Lift a unary function to Dual numbers
Equations
Instances For
Lift a generic Differentiable operation to Dual numbers
Equations
Instances For
Equations
Instances For
Create a new AD context
Equations
Instances For
Power (x^n)
Equations
Instances For
ReLU activation
Equations
Instances For
Verified op integration #
The methods above (add, mul, sub, …) hardcode each op's local
gradient in the body, which is fine for the built-in arithmetic but
forces every new op to be hand-coded. liftBinaryVerified plugs the
gap by reading the local gradient straight out of the
Differentiable instance — i.e. the same forward/backward pair we'd
register for any Hesper verified op.
The cost is the function-pointer indirection through the typeclass;
the benefit is that any Differentiable Op (Float × Float) Float
becomes a Dual op with no further wiring. Used by Ch11 for
SquaredErrorOp so the MSE training loop is built from a verified
loss op rather than ad-hoc mul/sub/pow.