jvp(func: Callable[..., Tensor | tuple[Tensor, ...]], inputs: Tensor | tuple[Tensor, ...], v: Tensor | tuple[Tensor, ...] | None = None, create_graph: bool = False, strict: bool = False)Jacobian-vector product (forward-mode directional derivative).
Given with Jacobian and a tangent vector , returns
along with the primal output . JVPs are useful for propagating tangent information (sensitivities) through a network, for directional derivatives, and as a building block for second-order methods.
Computed exactly with two reverse-mode passes (the double-vjp
trick): is linear in a dummy cotangent
, so its vector-Jacobian product with is
— or, through an op whose backward has
no graph mode (LSTM, a padded avg_pool), one reverse pass per
output element. No finite differences are involved.
Parameters
funccallableTensor inputs to a Tensor (or
tuple thereof).inputs is one single-element
tensor, which is then seeded with 1.create_graphbool= FalseTrue the returned outputs and tangents are differentiable
with respect to the inputs that require grad (and v).
Defaults to False.strictbool= FalseTrue, refuse an output that does not require grad, an input
the outputs do not depend on and an output whose tangent would be
zeros for want of a path — and, under create_graph, a tangent
that is a constant. Defaults to False.Returns
tuple of (Tensor or tuple of Tensor, Tensor or tuple of Tensor)(primals_out, tangents_out) where
primals_out = func(*inputs) — detached unless
create_graph — and tangents_out has the same structure
and shapes as primals_out and holds . An output
that does not depend on the inputs has a zero tangent.
Raises
RuntimeErrorv has the wrong number of entries, or is left out when
inputs is not one single-element tensor, or strict
refuses a result.NotImplementedErrorcreate_graph through an op whose backward has no graph mode.(ShapeMismatch, DeviceMismatch)v does not have its input's shape or device.Notes
The complementary operation is vjp, which computes
with one reverse pass. This JVP costs two.
Examples
>>> import lucid
>>> from lucid.autograd import jvp
>>> x = lucid.tensor([1.0, 2.0, 3.0])
>>> v = lucid.tensor([1.0, 0.0, 0.0])
>>> def f(x):
... return x * x
>>> y, tangent = jvp(f, x, v)
>>> tangent
tensor([2., 0., 0.])