Convenience wrapper for graph.gradient_override_map().

  This functions provides two conveniences over normal tensorflow gradient
  overrides: it auomatically uses the default graph instead of you needing to
  find the graph, and it automatically

  Example:

    def _foo_grad_alt(op, grad): ...

    with gradient_override({"Foo": _foo_grad_alt}):

  Args:
    override_dict: A dictionary describing how to override the gradient.
      keys: strings correponding to the op type that should have their gradient
        overriden.
      values: functions or strings registered to gradient functions

def gradient_override_map(override_dict):
  """Convenience wrapper for graph.gradient_override_map().

  This functions provides two conveniences over normal tensorflow gradient
  overrides: it auomatically uses the default graph instead of you needing to
  find the graph, and it automatically

  Example:

    def _foo_grad_alt(op, grad): ...

    with gradient_override({"Foo": _foo_grad_alt}):

  Args:
    override_dict: A dictionary describing how to override the gradient.
      keys: strings correponding to the op type that should have their gradient
        overriden.
      values: functions or strings registered to gradient functions

  """
  override_dict_by_name = {}
  for (op_name, grad_f) in override_dict.items():
    if isinstance(grad_f, str):
       override_dict_by_name[op_name] = grad_f
    else:
      override_dict_by_name[op_name] = register_to_random_name(grad_f)
  with tf.get_default_graph().gradient_override_map(override_dict_by_name):
    yield