The simplest version of scan repeatedly applies the callable fn to a
sequence of elements from first to last. The elements are made of the tensors
unpacked from elems on dimension 0. The callable fn takes two tensors as
arguments. The first argument is the accumulated value computed from the
preceding invocation of fn, and the second is the value at the current
position of elems. If initializer is None, elems must contain at least
one element, and its first element is used as the initializer.
Suppose that elems is unpacked into values, a list of tensors. The shape
of the result tensor is [len(values)] + fn(initializer, values[0]).shape.
If reverse=True, it's fn(initializer, values[-1]).shape.
This method also allows multi-arity elems and accumulator. If elems
is a (possibly nested) list or tuple of tensors, then each of these tensors
must have a matching first (unpack) dimension. The second argument of
fn must match the structure of elems.
If no initializer is provided, the output structure and dtypes of fn
are assumed to be the same as its input; and in this case, the first
argument of fn must match the structure of elems.
If an initializer is provided, then the output of fn must have the same
structure as initializer; and the first argument of fn must match
this structure.
For example, if elems is (t1, [t2, t3]) and initializer is
[i1, i2] then an appropriate signature for fn in python2 is:
fn = lambda (acc_p1, acc_p2), (t1, [t2, t3]): and fn must return a list,
[acc_n1, acc_n2]. An alternative correct signature for fn, and the
one that works in python3, is:
fn = lambda a, t:, where a and t correspond to the input tuples.
Args
fn
The callable to be performed. It accepts two arguments. The first will
have the same structure as initializer if one is provided, otherwise it
will have the same structure as elems. The second will have the same
(possibly nested) structure as elems. Its output must have the same
structure as initializer if one is provided, otherwise it must have the
same structure as elems.
elems
A tensor or (possibly nested) sequence of tensors, each of which will
be unpacked along their first dimension. The nested sequence of the
resulting slices will be the first argument to fn.
initializer
(optional) A tensor or (possibly nested) sequence of tensors,
initial value for the accumulator, and the expected output type of fn.
parallel_iterations
(optional) The number of iterations allowed to run in
parallel.
back_prop
(optional) Deprecated. False disables support for back
propagation. Prefer using tf.stop_gradient instead.
swap_memory
(optional) True enables GPU-CPU memory swapping.
infer_shape
(optional) False disables tests for consistent output shapes.
reverse
(optional) True scans the tensor last to first (instead of first to
last).
name
(optional) Name prefix for the returned tensors.
Returns
A tensor or (possibly nested) sequence of tensors. Each tensor packs the
results of applying fn to tensors unpacked from elems along the first
dimension, and the previous accumulator value(s), from first to last (or
last to first, if reverse=True).
Raises
TypeError
if fn is not callable or the structure of the output of
fn and initializer do not match.
ValueError
if the lengths of the output of fn and initializer
do not match.
Examples
elems=np.array([1,2,3,4,5,6])sum=scan(lambdaa,x:a+x,elems)# sum == [1, 3, 6, 10, 15, 21]sum=scan(lambdaa,x:a+x,elems,reverse=True)# sum == [21, 20, 18, 15, 11, 6]
[null,null,["Last updated 2024-04-26 UTC."],[],[],null,["# tf.scan\n\n\u003cbr /\u003e\n\n|----------------------------------------------------------------------------------------------------------------------------------|\n| [View source on GitHub](https://github.com/tensorflow/tensorflow/blob/v2.16.1/tensorflow/python/ops/functional_ops.py#L691-L812) |\n\nscan on the list of tensors unpacked from `elems` on dimension 0. (deprecated argument values) \n\n tf.scan(\n fn,\n elems,\n initializer=None,\n parallel_iterations=10,\n back_prop=True,\n swap_memory=False,\n infer_shape=True,\n reverse=False,\n name=None\n )\n\n| **Deprecated:** SOME ARGUMENT VALUES ARE DEPRECATED: `(back_prop=False)`. They will be removed in a future version. Instructions for updating: back_prop=False is deprecated. Consider using tf.stop_gradient instead. Instead of: results = tf.scan(fn, elems, back_prop=False) Use: results = tf.nest.map_structure(tf.stop_gradient, tf.scan(fn, elems))\n\nThe simplest version of `scan` repeatedly applies the callable `fn` to a\nsequence of elements from first to last. The elements are made of the tensors\nunpacked from `elems` on dimension 0. The callable fn takes two tensors as\narguments. The first argument is the accumulated value computed from the\npreceding invocation of fn, and the second is the value at the current\nposition of `elems`. If `initializer` is None, `elems` must contain at least\none element, and its first element is used as the initializer.\n\nSuppose that `elems` is unpacked into `values`, a list of tensors. The shape\nof the result tensor is `[len(values)] + fn(initializer, values[0]).shape`.\nIf reverse=True, it's fn(initializer, values\\[-1\\]).shape.\n\nThis method also allows multi-arity `elems` and accumulator. If `elems`\nis a (possibly nested) list or tuple of tensors, then each of these tensors\nmust have a matching first (unpack) dimension. The second argument of\n`fn` must match the structure of `elems`.\n\nIf no `initializer` is provided, the output structure and dtypes of `fn`\nare assumed to be the same as its input; and in this case, the first\nargument of `fn` must match the structure of `elems`.\n\nIf an `initializer` is provided, then the output of `fn` must have the same\nstructure as `initializer`; and the first argument of `fn` must match\nthis structure.\n\nFor example, if `elems` is `(t1, [t2, t3])` and `initializer` is\n`[i1, i2]` then an appropriate signature for `fn` in `python2` is:\n`fn = lambda (acc_p1, acc_p2), (t1, [t2, t3]):` and `fn` must return a list,\n`[acc_n1, acc_n2]`. An alternative correct signature for `fn`, and the\none that works in `python3`, is:\n`fn = lambda a, t:`, where `a` and `t` correspond to the input tuples.\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n| Args ---- ||\n|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `fn` | The callable to be performed. It accepts two arguments. The first will have the same structure as `initializer` if one is provided, otherwise it will have the same structure as `elems`. The second will have the same (possibly nested) structure as `elems`. Its output must have the same structure as `initializer` if one is provided, otherwise it must have the same structure as `elems`. |\n| `elems` | A tensor or (possibly nested) sequence of tensors, each of which will be unpacked along their first dimension. The nested sequence of the resulting slices will be the first argument to `fn`. |\n| `initializer` | (optional) A tensor or (possibly nested) sequence of tensors, initial value for the accumulator, and the expected output type of `fn`. |\n| `parallel_iterations` | (optional) The number of iterations allowed to run in parallel. |\n| `back_prop` | (optional) Deprecated. False disables support for back propagation. Prefer using [`tf.stop_gradient`](../tf/stop_gradient) instead. |\n| `swap_memory` | (optional) True enables GPU-CPU memory swapping. |\n| `infer_shape` | (optional) False disables tests for consistent output shapes. |\n| `reverse` | (optional) True scans the tensor last to first (instead of first to last). |\n| `name` | (optional) Name prefix for the returned tensors. |\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n| Returns ------- ||\n|---|---|\n| A tensor or (possibly nested) sequence of tensors. Each tensor packs the results of applying `fn` to tensors unpacked from `elems` along the first dimension, and the previous accumulator value(s), from first to last (or last to first, if `reverse=True`). ||\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n| Raises ------ ||\n|--------------|------------------------------------------------------------------------------------------------|\n| `TypeError` | if `fn` is not callable or the structure of the output of `fn` and `initializer` do not match. |\n| `ValueError` | if the lengths of the output of `fn` and `initializer` do not match. |\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n| Examples -------- ||\n|---|---|\n| \u003cbr /\u003e elems = np.array([1, 2, 3, 4, 5, 6]) sum = scan(lambda a, x: a + x, elems) # sum == [1, 3, 6, 10, 15, 21] sum = scan(lambda a, x: a + x, elems, reverse=True) # sum == [21, 20, 18, 15, 11, 6] elems = np.array([1, 2, 3, 4, 5, 6]) initializer = np.array(0) sum_one = scan( lambda a, x: x[0] - x[1] + a, (elems + 1, elems), initializer) # sum_one == [1, 2, 3, 4, 5, 6] elems = np.array([1, 0, 0, 0, 0, 0]) initializer = (np.array(0), np.array(1)) fibonaccis = scan(lambda a, _: (a[1], a[0] + a[1]), elems, initializer) # fibonaccis == ([1, 1, 2, 3, 5, 8], [1, 2, 3, 5, 8, 13]) \u003cbr /\u003e ||\n\n\u003cbr /\u003e"]]