Computes the gradient using operations recorded in context of this tape. Args: target: a list or nested structure of Tensors or Variables to be differentiated. sources: a list or nested structure of Tensors or Variables. `target` will be differentiated against elemen
(self,
target,
sources,
output_gradients=None,
unconnected_gradients=UnconnectedGradients.NONE)
| 933 | return self._tape.watched_variables() |
| 934 | |
| 935 | def gradient(self, |
| 936 | target, |
| 937 | sources, |
| 938 | output_gradients=None, |
| 939 | unconnected_gradients=UnconnectedGradients.NONE): |
| 940 | """Computes the gradient using operations recorded in context of this tape. |
| 941 | |
| 942 | Args: |
| 943 | target: a list or nested structure of Tensors or Variables to be |
| 944 | differentiated. |
| 945 | sources: a list or nested structure of Tensors or Variables. `target` |
| 946 | will be differentiated against elements in `sources`. |
| 947 | output_gradients: a list of gradients, one for each element of |
| 948 | target. Defaults to None. |
| 949 | unconnected_gradients: a value which can either hold 'none' or 'zero' and |
| 950 | alters the value which will be returned if the target and sources are |
| 951 | unconnected. The possible values and effects are detailed in |
| 952 | 'UnconnectedGradients' and it defaults to 'none'. |
| 953 | |
| 954 | Returns: |
| 955 | a list or nested structure of Tensors (or IndexedSlices, or None), |
| 956 | one for each element in `sources`. Returned structure is the same as |
| 957 | the structure of `sources`. |
| 958 | |
| 959 | Raises: |
| 960 | RuntimeError: if called inside the context of the tape, or if called more |
| 961 | than once on a non-persistent tape. |
| 962 | ValueError: if the target is a variable or if unconnected gradients is |
| 963 | called with an unknown value. |
| 964 | """ |
| 965 | if self._tape is None: |
| 966 | raise RuntimeError("GradientTape.gradient can only be called once on " |
| 967 | "non-persistent tapes.") |
| 968 | if self._recording: |
| 969 | if not self._persistent: |
| 970 | self._pop_tape() |
| 971 | else: |
| 972 | logging.log_first_n( |
| 973 | logging.WARN, "Calling GradientTape.gradient on a persistent " |
| 974 | "tape inside its context is significantly less " |
| 975 | "efficient than calling it outside the context (it " |
| 976 | "causes the gradient ops to be recorded on the " |
| 977 | "tape, leading to increased CPU and memory usage). " |
| 978 | "Only call GradientTape.gradient inside the " |
| 979 | "context if you actually want to trace the " |
| 980 | "gradient in order to compute higher order " |
| 981 | "derivatives.", 1) |
| 982 | |
| 983 | flat_targets = [] |
| 984 | for t in nest.flatten(target): |
| 985 | if not t.dtype.is_floating: |
| 986 | logging.vlog( |
| 987 | logging.WARN, "The dtype of the target tensor must be " |
| 988 | "floating (e.g. tf.float32) when calling GradientTape.gradient, " |
| 989 | "got %r", t.dtype) |
| 990 | if resource_variable_ops.is_resource_variable(t): |
| 991 | with self: |
| 992 | t = ops.convert_to_tensor(t) |