Apply gradients to variables. This is the second part of `minimize()`. It returns an `Operation` that applies gradients. Args: grads_and_vars: List of (gradient, variable) pairs as returned by `compute_gradients()`. global_step: Optional `Variable` to increment by o
(self, grads_and_vars, global_step=None, name=None)
| 617 | return grad * loss_scale_reciprical |
| 618 | |
| 619 | def apply_gradients(self, grads_and_vars, global_step=None, name=None): |
| 620 | """Apply gradients to variables. |
| 621 | |
| 622 | This is the second part of `minimize()`. It returns an `Operation` that |
| 623 | applies gradients. |
| 624 | |
| 625 | Args: |
| 626 | grads_and_vars: List of (gradient, variable) pairs as returned by |
| 627 | `compute_gradients()`. |
| 628 | global_step: Optional `Variable` to increment by one after the |
| 629 | variables have been updated. |
| 630 | name: Optional name for the returned operation. Default to the |
| 631 | name passed to the `Optimizer` constructor. |
| 632 | |
| 633 | Returns: |
| 634 | An `Operation` that applies the specified gradients. If `global_step` |
| 635 | was not None, that operation also increments `global_step`. |
| 636 | |
| 637 | Raises: |
| 638 | TypeError: If `grads_and_vars` is malformed. |
| 639 | ValueError: If none of the variables have gradients. |
| 640 | RuntimeError: If you should use `_distributed_apply()` instead. |
| 641 | """ |
| 642 | # This is a default implementation of apply_gradients() that can be shared |
| 643 | # by most optimizers. It relies on the subclass implementing the following |
| 644 | # methods: _create_slots(), _prepare(), _apply_dense(), and _apply_sparse(). |
| 645 | |
| 646 | # TODO(isaprykin): Get rid of `has_strategy()` check by |
| 647 | # always calling _distributed_apply(), using the default distribution |
| 648 | # as needed. |
| 649 | if distribute_ctx.has_strategy(): |
| 650 | # Handle DistributionStrategy case. |
| 651 | if distribute_ctx.in_cross_replica_context(): |
| 652 | raise RuntimeError("Use `_distributed_apply()` instead of " |
| 653 | "`apply_gradients()` in a cross-replica context.") |
| 654 | |
| 655 | grads_and_vars = get_filtered_grad_fn(lambda: grads_and_vars)() |
| 656 | return distribute_ctx.get_replica_context().merge_call( |
| 657 | self._distributed_apply, args=(grads_and_vars, global_step, name)) |
| 658 | |
| 659 | name = name if name is not None else self.get_name() |
| 660 | grads_and_vars = tuple(grads_and_vars) # Make sure repeat iteration works. |
| 661 | def apply_fn(): |
| 662 | # No DistributionStrategy case. |
| 663 | if not grads_and_vars: |
| 664 | raise ValueError("No variables provided.") |
| 665 | converted_grads_and_vars = [] |
| 666 | for g, v in grads_and_vars: |
| 667 | if g is not None: |
| 668 | try: |
| 669 | # Convert the grad to Tensor or IndexedSlices if necessary. |
| 670 | g = ops.convert_to_tensor_or_indexed_slices(g) |
| 671 | except TypeError: |
| 672 | raise TypeError( |
| 673 | "Gradient must be convertible to a Tensor" |
| 674 | " or IndexedSlices, or None: %s" % g) |
| 675 | if not isinstance(g, (ops.Tensor, ops.IndexedSlices)): |
| 676 | raise TypeError( |