tfp.substrates.numpy.math.diag_jacobian
Stay organized with collections
Save and categorize content based on your preferences.
Computes diagonal of the Jacobian matrix of ys=fn(xs)
wrt xs
.
tfp.substrates.numpy.math.diag_jacobian(
xs, ys=None, sample_shape=None, fn=None, parallel_iterations=10, name=None
)
If ys
is a tensor or a list of tensors of the form (ys_1, .., ys_n)
and
xs
is of the form (xs_1, .., xs_n)
, the function jacobians_diag
computes the diagonal of the Jacobian matrix, i.e., the partial derivatives
(dys_1/dxs_1,.., dys_n/dxs_n
). For definition details, see
https://en.wikipedia.org/wiki/Jacobian_matrix_and_determinant
Example
Diagonal Hessian of the log-density of a 3D Gaussian distribution
In this example we sample from a standard univariate normal
distribution using MALA with step_size
equal to 0.75.
from tensorflow_probability.python.internal.backend import numpy as tf
import tensorflow_probability as tfp; tfp = tfp.substrates.numpy
import numpy as np
tfd = tfp.distributions
dtype = np.float32
with tf.Session(graph=tf.Graph()) as sess:
true_mean = dtype([0, 0, 0])
true_cov = dtype([[1, 0.25, 0.25], [0.25, 2, 0.25], [0.25, 0.25, 3]])
chol = tf.linalg.cholesky(true_cov)
target = tfd.MultivariateNormalTriL(loc=true_mean, scale_tril=chol)
# Assume that the state is passed as a list of tensors `x` and `y`.
# Then the target function is defined as follows:
def target_fn(x, y):
# Stack the input tensors together
z = tf.concat([x, y], axis=-1) - true_mean
return target.log_prob(z)
sample_shape = [3, 5]
state = [tf.ones(sample_shape + [2], dtype=dtype),
tf.ones(sample_shape + [1], dtype=dtype)]
fn_val, grads = tfp.math.value_and_gradient(target_fn, state)
# We can either pass the `sample_shape` of the `state` or not, which impacts
# computational speed of `diag_jacobian`
_, diag_jacobian_shape_passed = diag_jacobian(
xs=state, ys=grads, sample_shape=tf.shape(fn_val))
_, diag_jacobian_shape_none = diag_jacobian(
xs=state, ys=grads)
diag_jacobian_shape_passed_ = sess.run(diag_jacobian_shape_passed)
diag_jacobian_shape_none_ = sess.run(diag_jacobian_shape_none)
print('hessian computed through `diag_jacobian`, sample_shape passed: ',
np.concatenate(diag_jacobian_shape_passed_, -1))
print('hessian computed through `diag_jacobian`, sample_shape skipped',
np.concatenate(diag_jacobian_shape_none_, -1))
Args |
xs
|
Tensor or a python list of Tensors of real-like dtypes and shapes
sample_shape + event_shape_i , where event_shape_i can be different
for different tensors.
|
ys
|
Tensor or a python list of Tensors of the same dtype as xs . Must
broadcast with the shape of xs . Can be omitted if fn is provided.
|
sample_shape
|
A common sample_shape of the input tensors of xs . If not,
provided, assumed to be [1] , which may result in a slow performance of
jacobians_diag .
|
fn
|
Python callable that takes xs as an argument (or *xs , if it is a
list) and returns ys . Might be skipped if ys is provided and
tf.enable_eager_execution() is disabled.
|
parallel_iterations
|
int that specifies the allowed number of coordinates
of the input tensor xs , for which the partial derivatives dys_i/dxs_i
can be computed in parallel.
|
name
|
Python str name prefixed to Ops created by this function.
Default value: None (i.e., "diag_jacobian").
|
Returns |
ys
|
a list, which coincides with the input ys , when provided.
If the input ys is None, fn(*xs) gets computed and returned as a list.
|
jacobians_diag_res
|
a Tensor or a Python list of Tensor s of the same
dtypes and shapes as the input xs . This is the diagonal of the Jacobian
of ys wrt xs.
|
Raises |
ValueError
|
if lists xs and ys have different length or both ys and
fn are None , or fn is None in the eager execution mode.
|
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2023-11-21 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2023-11-21 UTC."],[],[],null,["# tfp.substrates.numpy.math.diag_jacobian\n\n\u003cbr /\u003e\n\n|--------------------------------------------------------------------------------------------------------------------------------------------------------|\n| [View source on GitHub](https://github.com/tensorflow/probability/blob/v0.23.0/tensorflow_probability/substrates/numpy/math/diag_jacobian.py#L28-L239) |\n\nComputes diagonal of the Jacobian matrix of `ys=fn(xs)` wrt `xs`.\n\n#### View aliases\n\n\n**Main aliases**\n\n[`tfp.experimental.substrates.numpy.math.diag_jacobian`](https://www.tensorflow.org/probability/api_docs/python/tfp/substrates/numpy/math/diag_jacobian)\n\n\u003cbr /\u003e\n\n tfp.substrates.numpy.math.diag_jacobian(\n xs, ys=None, sample_shape=None, fn=None, parallel_iterations=10, name=None\n )\n\nIf `ys` is a tensor or a list of tensors of the form `(ys_1, .., ys_n)` and\n`xs` is of the form `(xs_1, .., xs_n)`, the function `jacobians_diag`\ncomputes the diagonal of the Jacobian matrix, i.e., the partial derivatives\n`(dys_1/dxs_1,.., dys_n/dxs_n`). For definition details, see\n\u003chttps://en.wikipedia.org/wiki/Jacobian_matrix_and_determinant\u003e\n\n#### Example\n\n##### Diagonal Hessian of the log-density of a 3D Gaussian distribution\n\nIn this example we sample from a standard univariate normal\ndistribution using MALA with `step_size` equal to 0.75. \n\n from tensorflow_probability.python.internal.backend import numpy as tf\n import tensorflow_probability as tfp; tfp = tfp.substrates.numpy\n import numpy as np\n\n tfd = tfp.distributions\n\n dtype = np.float32\n with tf.Session(graph=tf.Graph()) as sess:\n true_mean = dtype([0, 0, 0])\n true_cov = dtype([[1, 0.25, 0.25], [0.25, 2, 0.25], [0.25, 0.25, 3]])\n chol = tf.linalg.cholesky(true_cov)\n target = tfd.MultivariateNormalTriL(loc=true_mean, scale_tril=chol)\n\n # Assume that the state is passed as a list of tensors `x` and `y`.\n # Then the target function is defined as follows:\n def target_fn(x, y):\n # Stack the input tensors together\n z = tf.concat([x, y], axis=-1) - true_mean\n return target.log_prob(z)\n\n sample_shape = [3, 5]\n state = [tf.ones(sample_shape + [2], dtype=dtype),\n tf.ones(sample_shape + [1], dtype=dtype)]\n fn_val, grads = tfp.math.value_and_gradient(target_fn, state)\n\n # We can either pass the `sample_shape` of the `state` or not, which impacts\n # computational speed of `diag_jacobian`\n _, diag_jacobian_shape_passed = diag_jacobian(\n xs=state, ys=grads, sample_shape=tf.shape(fn_val))\n _, diag_jacobian_shape_none = diag_jacobian(\n xs=state, ys=grads)\n\n diag_jacobian_shape_passed_ = sess.run(diag_jacobian_shape_passed)\n diag_jacobian_shape_none_ = sess.run(diag_jacobian_shape_none)\n\n print('hessian computed through `diag_jacobian`, sample_shape passed: ',\n np.concatenate(diag_jacobian_shape_passed_, -1))\n print('hessian computed through `diag_jacobian`, sample_shape skipped',\n np.concatenate(diag_jacobian_shape_none_, -1))\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n| Args ---- ||\n|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `xs` | `Tensor` or a python `list` of `Tensors` of real-like dtypes and shapes `sample_shape` + `event_shape_i`, where `event_shape_i` can be different for different tensors. |\n| `ys` | `Tensor` or a python `list` of `Tensors` of the same dtype as `xs`. Must broadcast with the shape of `xs`. Can be omitted if `fn` is provided. |\n| `sample_shape` | A common `sample_shape` of the input tensors of `xs`. If not, provided, assumed to be `[1]`, which may result in a slow performance of `jacobians_diag`. |\n| `fn` | Python callable that takes `xs` as an argument (or `*xs`, if it is a list) and returns `ys`. Might be skipped if `ys` is provided and `tf.enable_eager_execution()` is disabled. |\n| `parallel_iterations` | `int` that specifies the allowed number of coordinates of the input tensor `xs`, for which the partial derivatives `dys_i/dxs_i` can be computed in parallel. |\n| `name` | Python `str` name prefixed to `Ops` created by this function. Default value: `None` (i.e., \"diag_jacobian\"). |\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n| Returns ------- ||\n|----------------------|----------------------------------------------------------------------------------------------------------------------------------------------|\n| `ys` | a list, which coincides with the input `ys`, when provided. If the input `ys` is None, `fn(*xs)` gets computed and returned as a list. |\n| `jacobians_diag_res` | a `Tensor` or a Python list of `Tensor`s of the same dtypes and shapes as the input `xs`. This is the diagonal of the Jacobian of ys wrt xs. |\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n| Raises ------ ||\n|--------------|-----------------------------------------------------------------------------------------------------------------------------|\n| `ValueError` | if lists `xs` and `ys` have different length or both `ys` and `fn` are `None`, or `fn` is None in the eager execution mode. |\n\n\u003cbr /\u003e"]]