# Path: tf_slim/training/training.py
# def add_gradients_summaries(grads_and_vars):
# def clip_gradient_norms(gradients_to_variables, max_norm):
# def clip_gradient_norms_fn(max_norm):
#   def clip_norms(gradients_to_variables):
# def multiply_gradients(grads_and_vars, gradient_multipliers):
# def create_train_op(total_loss,
#                     optimizer,
#                     global_step=_USE_GLOBAL_STEP,
#                     update_ops=None,
#                     variables_to_train=None,
#                     transform_grads_fn=None,
#                     summarize_gradients=False,
#                     gate_gradients=tf_optimizer.Optimizer.GATE_OP,
#                     aggregation_method=None,
#                     colocate_gradients_with_ops=False,
#                     check_numerics=True):
# def train(train_op,
#           logdir,
#           master='',
#           is_chief=True,
#           scaffold=None,
#           hooks=None,
#           chief_only_hooks=None,
#           save_checkpoint_secs=600,
#           save_summaries_steps=100,
#           config=None,
#           max_wait_secs=7200,
#           run_metadata=None):
# _USE_GLOBAL_STEP = 0


import os
import sys
import time
from tf_slim.training import training
from tensorflow.core.protobuf import config_pb2
from tensorflow.python.client import timeline
from tensorflow.python.framework import constant_op
from tensorflow.python.framework import errors
from tensorflow.python.framework import ops
from tensorflow.python.lib.io import file_io
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import clip_ops
from tensorflow.python.ops import control_flow_ops
from tensorflow.python.ops import lookup_ops
from tensorflow.python.ops import math_ops
from tensorflow.python.ops import variables
from tensorflow.python.platform import tf_logging as logging
from tensorflow.python.summary import summary
from tensorflow.python.training import optimizer as tf_optimizer
from tensorflow.python.training import saver as tf_saver
from tensorflow.python.training import supervisor
from tensorflow.python.training import sync_replicas_optimizer
from tensorflow.python.training import training_util
      default to all tf.compat.v1.trainable_variables().
    clip_gradient_norm: If greater than 0 then the gradients would be clipped by
      it.
    summarize_gradients: Whether or not add summaries for each gradient.
    gate_gradients: How to gate the computation of gradients. See tf.Optimizer.
    aggregation_method: Specifies the method used to combine gradient terms.
      Valid values are defined in the class `AggregationMethod`.
    colocate_gradients_with_ops: Whether or not to try colocating the gradients
      with the ops that generated them.
    gradient_multipliers: A dictionary of either `Variables` or `Variable` op
      names to the coefficient by which the associated gradient should be
      scaled.
    check_numerics: Whether or not we apply check_numerics.

  Returns:
    A `Tensor` that when evaluated, computes the gradients and returns the total
      loss value.
  """

  def transform_grads_fn(grads):
    if gradient_multipliers:
      with ops.name_scope('multiply_grads'):
        grads = multiply_gradients(grads, gradient_multipliers)

    # Clip gradients.
    if clip_gradient_norm > 0:
      with ops.name_scope('clip_grads'):
        grads = clip_gradient_norms(grads, clip_gradient_norm)
    return grads


# Path: tf_slim/training/training.py
# def add_gradients_summaries(grads_and_vars):
# def clip_gradient_norms(gradients_to_variables, max_norm):
# def clip_gradient_norms_fn(max_norm):
#   def clip_norms(gradients_to_variables):
# def multiply_gradients(grads_and_vars, gradient_multipliers):
# def create_train_op(total_loss,
#                     optimizer,
#                     global_step=_USE_GLOBAL_STEP,
#                     update_ops=None,
#                     variables_to_train=None,
#                     transform_grads_fn=None,
#                     summarize_gradients=False,
#                     gate_gradients=tf_optimizer.Optimizer.GATE_OP,
#                     aggregation_method=None,
#                     colocate_gradients_with_ops=False,
#                     check_numerics=True):
# def train(train_op,
#           logdir,
#           master='',
#           is_chief=True,
#           scaffold=None,
#           hooks=None,
#           chief_only_hooks=None,
#           save_checkpoint_secs=600,
#           save_summaries_steps=100,
#           config=None,
#           max_wait_secs=7200,
#           run_metadata=None):
# _USE_GLOBAL_STEP = 0


# Path: tf_slim/learning.py
import os
import sys
import time
from tf_slim.training import training
from tensorflow.core.protobuf import config_pb2
from tensorflow.python.client import timeline
from tensorflow.python.framework import constant_op
from tensorflow.python.framework import errors
from tensorflow.python.framework import ops
from tensorflow.python.lib.io import file_io
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import clip_ops
from tensorflow.python.ops import control_flow_ops
from tensorflow.python.ops import lookup_ops
from tensorflow.python.ops import math_ops
from tensorflow.python.ops import variables
from tensorflow.python.platform import tf_logging as logging
from tensorflow.python.summary import summary
from tensorflow.python.training import optimizer as tf_optimizer
from tensorflow.python.training import saver as tf_saver
from tensorflow.python.training import supervisor
from tensorflow.python.training import sync_replicas_optimizer
from tensorflow.python.training import training_util

      default to all tf.compat.v1.trainable_variables().
    clip_gradient_norm: If greater than 0 then the gradients would be clipped by
      it.
    summarize_gradients: Whether or not add summaries for each gradient.
    gate_gradients: How to gate the computation of gradients. See tf.Optimizer.
    aggregation_method: Specifies the method used to combine gradient terms.
      Valid values are defined in the class `AggregationMethod`.
    colocate_gradients_with_ops: Whether or not to try colocating the gradients
      with the ops that generated them.
    gradient_multipliers: A dictionary of either `Variables` or `Variable` op
      names to the coefficient by which the associated gradient should be
      scaled.
    check_numerics: Whether or not we apply check_numerics.

  Returns:
    A `Tensor` that when evaluated, computes the gradients and returns the total
      loss value.
  """

  def transform_grads_fn(grads):
    if gradient_multipliers:
      with ops.name_scope('multiply_grads'):
        grads = multiply_gradients(grads, gradient_multipliers)

    # Clip gradients.
    if clip_gradient_norm > 0:
      with ops.name_scope('clip_grads'):
        grads = clip_gradient_norms(grads, clip_gradient_norm)
    return grads


  return training.create_train_op(