Skip to content

← JAX Foundations step 11 of 25

Easy Primitives

jax.value_and_grad

Jump to the task

Get the loss and its gradient together

A training step needs a gradient to update the parameters. It often also needs the loss value to show progress. jax.value_and_grad returns both from one transformed function call:

import jax
import jax.numpy as jnp

def loss(w, x):
    return jnp.sum((w * x) ** 2)

value, grad_w = jax.value_and_grad(loss)(3.0, jnp.array([1.0, 2.0]))
# value = 9 + 36 = 45.0
# grad_w = 2 * 3 * (1 + 4) = 30.0

The value comes first, then the gradient. They have different meanings and need not be equal. jax.grad alone returns only the gradient.

Using value_and_grad lets JAX return the value computed for the derivative rather than asking you to evaluate the loss separately. This is not a promise of a fixed speedup or a single device operation: compilation and the operations in the loss determine the actual work.

Select what to differentiate

argnums=0, the default, differentiates with respect to the first positional argument. Other arguments still affect the loss, but are held fixed for that derivative. The loss must return a scalar with shape (), not a one-element array with shape (1,).

If a loss also returns a metric, has_aux=True handles the pair (loss, metric). The transformed result is ((value, metric), grad). Only the loss determines that gradient. This exercise does not need auxiliary output.

Problem

Implement loss_and_grad(w, b, x) using jax.value_and_grad. w and b are real floating-point scalars, and x is a one-dimensional floating-point array. The loss is sum((w*x + b)**2).

Differentiate with respect to w only, holding b and x fixed. Return a JAX array with shape (2,), containing [loss, grad_w]. The inner loss is scalar; this two-element array is the outer function's result. Use a sum, not a mean.

For w=0.0, b=1.0, and x=[1.0, 2.0], the loss is 1 + 1 = 2. Its derivative is 2*1*1 + 2*1*2 = 6, so return [2.0, 6.0].

The exercise is practice using value_and_grad. Numerical output checks verify the result, but cannot enforce how you computed it.