jax.custom_vjp.defvjp#
- custom_vjp.defvjp(fwd, bwd, symbolic_zeros=False, optimize_remat=False)[源代码]#
为该实例表示的函数定义一个自定义 VJP 规则。
- 参数:
fwd (Callable[..., tuple[ReturnValue, Any]]) – 一个 Python 可调用对象,表示自定义 VJP 规则的前向传递。当没有
nondiff_argnums
时,fwd
函数具有与底层原始函数相同的输入签名。它应该返回一对作为输出,其中第一个元素表示原始输出,第二个元素表示从前向传递存储的任何“残余”值,供函数bwd
在后向传递中使用。输入参数和输出对的元素可以是数组或嵌套的元组/列表/字典。bwd (Callable[..., tuple[Any, ...]]) – 一个 Python 可调用对象,表示自定义 VJP 规则的后向传递。当没有
nondiff_argnums
时,bwd
函数接受两个参数,其中第一个参数是fwd
在前向传递中产生的“残余”值,第二个参数是与原始函数输出具有相同结构的输出余切。bwd
的输出必须是一个长度等于原始函数参数数量的元组,并且元组元素可以是数组或嵌套的元组/列表/字典,以匹配原始输入参数的结构。symbolic_zeros (bool) –
布尔值,确定是否向
fwd
和bwd
规则指示符号零。启用此选项允许自定义导数规则检测何时某些输入以及何时某些输出余切不参与微分。如果True
fwd
必须接受一个对象(类型为jax.custom_derivatives.CustomVJPPrimal
),而不是构成原始函数参数的 pytree 中的每个叶值x
,该对象有两个属性:value
和perturbed
。value
字段是原始的原始参数,而perturbed
是一个布尔值。perturbed
位指示该参数是否参与微分(即,如果它是False
,则相应的雅可比矩阵“列”为零)。bwd
将传递表示与其未扰动值对应的余切参数中的静态符号零的对象;否则,只传递标准的 JAX 类型(例如类数组)。
将此选项设置为
True
允许这些规则检测某些输入和输出是否不参与微分,但代价是需要特殊处理。例如fwd
的签名发生变化,并且传递给它的对象不能直接从规则中输出。bwd
规则传递的对象不是完全类数组,并且不能传递给大多数jax.numpy
函数。任何参与原始函数参数的自定义 pytree 节点都必须在其解平坦化函数中接受作为输入叶子提供给
fwd
规则的双字段记录对象。
默认值
False
。optimize_remat (bool) – 布尔值,一个实验性标志,用于在
jax.remat()
下使用此函数时启用自动优化。当fwd
规则是不透明调用(例如 Pallas 内核或自定义调用)时,这将最有用。默认值False
。
- 返回:
无。
- 返回类型:
无
示例
>>> @jax.custom_vjp ... def f(x, y): ... return jnp.sin(x) * y ... >>> def f_fwd(x, y): ... return f(x, y), (jnp.cos(x), jnp.sin(x), y) ... >>> def f_bwd(res, g): ... cos_x, sin_x, y = res ... return (cos_x * g * y, sin_x * g) ... >>> f.defvjp(f_fwd, f_bwd)
>>> x = jnp.float32(1.0) >>> y = jnp.float32(2.0) >>> with jnp.printoptions(precision=2): ... print(jax.value_and_grad(f)(x, y)) (Array(1.68, dtype=float32), Array(1.08, dtype=float32))