We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← JAX Foundations step 10 of 25
Gradient with jax.grad
A gradient measures sensitivity
A derivative tells you how a function's output changes when one input
changes slightly. For a scalar loss with several inputs, its gradient
collects these derivatives. JAX computes them from the operations in
your function using jax.grad.
Pass the function itself to jax.grad, then call the function it returns:
import jax
import jax.numpy as jnp
def score(w, x):
return jnp.sum(w * x)
x = jnp.array([1.0, 3.0])
jax.grad(score)(2.0, x) # 4.0
jax.grad(score, argnums=1)(2.0, x) # [2.0, 2.0]
The first call varies w while holding x fixed. Here the score is
4*w, so its derivative is 4. The second call varies each element of
x while holding w fixed. Each element is multiplied by 2, giving
a gradient with two entries.
Choose the loss and the argument
By default, argnums=0 selects the first positional argument. Use
argnums=(0, 1) to return a tuple containing both gradients.
The loss must be scalar: an array with shape () qualifies, but shape
(1,) does not. If your function returns several values, decide which
scalar objective you want to differentiate. Summing and averaging give
different gradients; neither is an automatic fix for every problem.
To keep the derivatives of separate outputs, use a Jacobian instead.
This exercise uses real floating-point inputs. An integer argument
selected for differentiation is rejected by default. Write 1.0
instead of 1 when you mean a continuous scalar parameter.
Problem
Implement grad_of_quadratic(w, b, x) using jax.grad.
w and b are real floating-point scalars, and x is a one-dimensional
floating-point array. Define the loss as sum((w*x + b)**2) and return
its derivative with respect to w only, as a scalar. Hold b and
x fixed. Use a sum, not a mean.
For example, with w=1.0, b=2.0, and x=[3.0], the term before
squaring is 5. Its derivative with respect to w is 3, so the loss
derivative is 2 * 5 * 3 = 30.0.
To check your result by hand, sum 2 * (w*x_i + b) * x_i over the
entries of x. Practice constructing the derivative with jax.grad;
numerical output checks alone cannot distinguish it from this formula.
Understand the ideas behind this exercise. The Problem tab contains the exact implementation requirements.
A gradient measures sensitivity
A derivative tells you how a function's output changes when one input
changes slightly. For a scalar loss with several inputs, its gradient
collects these derivatives. JAX computes them from the operations in
your function using jax.grad.
Pass the function itself to jax.grad, then call the function it returns:
import jax
import jax.numpy as jnp
def score(w, x):
return jnp.sum(w * x)
x = jnp.array([1.0, 3.0])
jax.grad(score)(2.0, x) # 4.0
jax.grad(score, argnums=1)(2.0, x) # [2.0, 2.0]
The first call varies w while holding x fixed. Here the score is
4*w, so its derivative is 4. The second call varies each element of
x while holding w fixed. Each element is multiplied by 2, giving
a gradient with two entries.
Choose the loss and the argument
By default, argnums=0 selects the first positional argument. Use
argnums=(0, 1) to return a tuple containing both gradients.
The loss must be scalar: an array with shape () qualifies, but shape
(1,) does not. If your function returns several values, decide which
scalar objective you want to differentiate. Summing and averaging give
different gradients; neither is an automatic fix for every problem.
To keep the derivatives of separate outputs, use a Jacobian instead.
This exercise uses real floating-point inputs. An integer argument
selected for differentiation is rejected by default. Write 1.0
instead of 1 when you mean a continuous scalar parameter.
Compute derivatives by following the operations
Automatic differentiation computes derivatives by applying the chain rule to a program's operations. It does not estimate them by evaluating nearby inputs, as finite differences do, or rearrange the whole expression using symbolic algebra.
For f(g(x)), the chain rule combines the derivative of g with the derivative
of f at g(x). Repeating this process lets a framework differentiate a long
sequence of operations.
Forward mode follows an input change
For a function with n inputs and m outputs, the Jacobian J is an (m, n)
matrix of derivatives. Entry (i, j) describes how output i changes with input
j.
Forward-mode differentiation computes Jv: the output's rate of change when the
input moves in direction v. For example, if f(x) = sum(x_i^2), then at
x = [1, 2] the gradient is [2, 4]. In direction v = [3, 0], the rate of
change is 2 * 3 + 4 * 0 = 6.
This is a directional derivative. It gives one Jacobian column only when v
selects one input coordinate, such as [1, 0].
Reverse mode works backward from an output
Reverse mode computes J^T u, where u weights the outputs. For a scalar loss,
choosing u = 1 gives the gradient with respect to all inputs. This makes reverse
mode useful for training: a model can have many parameters but just one loss.
Forward mode can be useful when you need sensitivity to only a few input directions. Neither mode needs to construct the full Jacobian for these products. That can save substantial memory. Higher-order differentiation can similarly compute a Hessian-vector product without storing the full matrix of second derivatives.
Changing gradient flow changes what is differentiated
A stop-gradient operation keeps a value in the forward calculation but treats it as constant during differentiation. A custom derivative supplies a derivative rule explicitly. It should match the intended function unless the exercise asks for a surrogate, such as an approximation used during training.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
JAX reference solution
Sign in to track your attempts toward unlocking the reference solution.