liveBook · Manning

Jax.value_and_grad

As explained in Deep Learning with R, Third Edition

jax.value_and_grad is a JAX transformation that constructs a function returning both a function's value and its gradient.

`jax$value_and_grad()` turns a scalar-loss function into a function that returns both the loss and its gradients. Use it when a training step needs to report the loss and update weights: unlike `jax$grad()`, it supplies the loss without a separate call to compute it. section 3.5.3

Get a value and gradient together

```r compute_loss <- function(input_var) { jnp$square(input_var) } grad_fn <- jax$value_and_grad(compute_loss) input_var <- jnp$array(3) .[loss, gradient] <- grad_fn(input_var) ``` `grad_fn()` accepts the same input as `compute_loss()`. Its first result is the loss value; its second is the gradient with respect to the first argument. section 3.5.3

For several weights, put them together in the loss function’s first argument, `state`, and pass other inputs afterward. The state can be a list or a nested tree. In a linear classifier, `state` holds `W` and `b`; the resulting gradients are used to calculate new weights, which a stateless training step returns rather than modifying in place. section 3.5.3 section 3.5.4

learning_rate <- 0.1

training_step <- jax$jit(\(inputs, targets, W, b) {  #1
  .[loss, grads] <- grad_fn(list(W, b), inputs, targets)  #2
  .[grad_wrt_W, grad_wrt_b] <- grads
  W <- W - grad_wrt_W * learning_rate  #3
  b <- b - grad_wrt_b * learning_rate  #3
  tuple(loss, W, b)  #4
})

This training step gets loss and gradients in one call, updates both classifier weights, and returns the loss with the new weights. It also wraps the step in `jax$jit()`. section 3.5.4

If computing the loss also produces information that must be kept—such as updated nontrainable weights—return it alongside the scalar loss and set `has_aux = TRUE`. The auxiliary result is then available separately from the gradients. Keras uses this pattern with `stateless_call()` before applying gradients through an optimizer’s `stateless_apply()` method. section 3.5.3 section 7.4.2

optimizer <- optimizer_adam()
optimizer$build(model$trainable_variables)

train_step <- function(state, inputs, targets) {  #1
  .[trainable_variables, non_trainable_variables, optimizer_variables] <-
    state  #2


  .[.[loss, non_trainable_variables], grads] <- grad_fn(  #3
    trainable_variables, non_trainable_variables,
    inputs, targets 
  )
  .[trainable_variables, optimizer_variables] <- optimizer$stateless_apply(  #4
    optimizer_variables, grads, trainable_variables 
  )
  new_state <- list(  #5
    trainable_variables,
    non_trainable_variables,
    optimizer_variables
  )
  list(loss, new_state) 
}

The Keras training step carries trainable weights, nontrainable weights, and optimizer variables explicitly through one stateless update. section 7.4.2

How Deep Learning with R, Third Edition covers it

How deep it goes
Works from a single-array loss through nested weight state and auxiliary outputs to complete training steps, without deriving gradient internals.
Examples
Uses a squared-input loss, a linear classifier with mean squared error, and a Keras custom training step.
What it assumes
Introduces JAX gradient computation from a simple array loss before combining weights into state.
What you can do after
Build it from scratch in a JAX classifier loop or apply it via Keras stateless training methods.
How it connects
Connects `jax.grad`, scalar loss functions, stateless training, `jax.jit`, and Keras stateless optimizer updates.

Also explained in

Compare how 3 books explain jax.value_and_grad →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Deep Learning with R, Third Edition. The section links point to the parts of the book it draws on.