JAX Vision Functions Guide
Pure array functions plus composable transforms, so one snippet gets gradients, vectorization and compilation without leaving Python.
Why Does This Exist?
Vision training repeats three wishes: differentiate any function, run it over a batch without a loop, and compile it to fast code. Most frameworks give you two of the three with effort. JAX gives all three as composable transforms over plain functions: grad for the derivative, vmap for the batch, jit for the compiler. PyTorch code stays object-oriented beside it, while JAX code stays functional.
This page covers the function contract, one gradient fixture, and appropriate use. Tensor shapes follow the PyTorch page and batch math follows TensorFlow.
Think of It Like This
A recipe card with three stamps
A kitchen writes each recipe as plain steps on a card. Three rubber stamps upgrade any card: differentiate stamps the slope version, batch stamps the serving-for-twelve version, compile stamps the laminated fast version.
JAX stamps are those three. The card never changes, only the stamped copies do. The analogy stops at state: cards hold no leftovers between runs, and functions that mutate hidden state break the stamping.
How It Actually Works
Input is a pure function over arrays: same inputs always give same outputs, no side effects. Output is a transformed function with the same contract: grad(f) returns the slope function, vmap(f) the batched one, jit(f) the compiled one, and they nest. Purpose is exact gradients plus fast batched execution for vision losses and models. Appropriate use is research training loops and custom vision ops. Randomness comes from explicit keys you split and pass, never from hidden global state.
Gradient fixture
Take at . The derivative is , so . With step size , one descent step gives . The diagram draws this pair: the value 4 and the compiled step to 1.6.
Code
The fixture in plain Python, the same arithmetic grad returns:
def f(w: float) -> float: return w * w # pure: no hidden state
def grad_f(w: float) -> float: return 2.0 * w # exact slope of the square
print(grad_f(2.0)) # -> 4.0print(2.0 - 0.1 * grad_f(2.0)) # -> 1.6Slope 4.0 at 2.0, and one small step lands at 1.6.
Watch Out For
Mutating arrays inside a compiled function
JAX arrays are immutable, so in-place updates silently build new tracers instead of changing values. The symptom is a training loop whose weights never move while loss prints normally. Fix it by returning updated values functionally and threading them through the loop.
The Quick Version
- JAX maps pure array functions to gradient, batched, or compiled versions of themselves.
- The slope of w squared at 2 is 4, and a 0.1 step reaches 1.6.
- Randomness travels in explicit keys, never in global state.
- Use it for research loops and custom ops with exact derivatives.
- Keep functions pure or compilation silently misleads.