def run_experiment(model_fn,
                   train_input_fn,
                   eval_input_fn,
                   exporters=None,
                   params=None,
                   params_fname=None):
  """Run an experiment using estimators.

  This is a light wrapper around typical estimator usage to avoid boilerplate
  code. Please use the following components separately for more complex
  usages.

  Args:
    model_fn: A model function to be passed to the estimator. See
      https://www.tensorflow.org/api_docs/python/tf/estimator/Estimator#args_1
    train_input_fn: An input function to be passed to the estimator that
      corresponds to the training data. See
      https://www.tensorflow.org/api_docs/python/tf/estimator/Estimator#train
    eval_input_fn: An input function to be passed to the estimator that
      corresponds to the held-out eval data. See
      https://www.tensorflow.org/api_docs/python/tf/estimator/Estimator#evaluate
    exporters: (Optional) An tf.estimator.Exporter or a list of them.
    params: (Optional) A dictionary of parameters that will be accessible by the
      model_fn and input_fns. The 'batch_size' and 'use_tpu' values will be set
      automatically.
    params_fname: (Optional) If specified, `params` will be written to here
      under `FLAGS.model_dir` in JSON format.
  """
  params = params if params is not None else {}
  params.setdefault("use_tpu", FLAGS.use_tpu)

  if FLAGS.model_dir and params_fname:
    tf.io.gfile.makedirs(FLAGS.model_dir)
    params_path = os.path.join(FLAGS.model_dir, params_fname)
    with tf.io.gfile.GFile(params_path, "w") as params_file:
      json.dump(params, params_file, indent=2, sort_keys=True)

  if params["use_tpu"]:
    if FLAGS.tpu_name:
      tpu_cluster_resolver = tf.distribute.cluster_resolver.TPUClusterResolver(
          FLAGS.tpu_name, zone=FLAGS.tpu_zone, project=FLAGS.gcp_project)
    else:
      tpu_cluster_resolver = None
    run_config = tf_estimator.tpu.RunConfig(
        cluster=tpu_cluster_resolver,
        master=FLAGS.master,
        model_dir=FLAGS.model_dir,
        tf_random_seed=FLAGS.tf_random_seed,
        save_checkpoints_steps=FLAGS.save_checkpoints_steps,
        tpu_config=tf_estimator.tpu.TPUConfig(
            iterations_per_loop=FLAGS.save_checkpoints_steps))
    if "batch_size" in params:
      # Let the TPUEstimator fill in the batch size.
      params.pop("batch_size")
    estimator = tf_estimator.tpu.TPUEstimator(
        use_tpu=True,
        model_fn=model_fn,
        params=params,
        config=run_config,
        train_batch_size=FLAGS.batch_size,
        eval_batch_size=FLAGS.eval_batch_size,
        predict_batch_size=FLAGS.eval_batch_size)
  else:
    run_config = tf_estimator.RunConfig(
        model_dir=FLAGS.model_dir,
        tf_random_seed=FLAGS.tf_random_seed,
        save_checkpoints_steps=FLAGS.save_checkpoints_steps,
        keep_checkpoint_max=FLAGS.keep_checkpoint_max)
    params["batch_size"] = FLAGS.batch_size
    estimator = tf_estimator.Estimator(
        config=run_config,
        model_fn=model_fn,
        params=params,
        model_dir=FLAGS.model_dir)

  train_spec = tf_estimator.TrainSpec(
      input_fn=train_input_fn,
      max_steps=FLAGS.num_train_steps)
  eval_spec = tf_estimator.EvalSpec(
      name="default",
      input_fn=eval_input_fn,
      exporters=exporters,
      start_delay_secs=FLAGS.eval_start_delay_secs,
      throttle_secs=FLAGS.eval_throttle_secs,
      steps=FLAGS.num_eval_steps)

  tf.logging.set_verbosity(tf.logging.INFO)
  tf_estimator.train_and_evaluate(
      estimator=estimator,
      train_spec=train_spec,
      eval_spec=eval_spec)
Run an experiment using estimators.

  This is a light wrapper around typical estimator usage to avoid boilerplate
  code. Please use the following components separately for more complex
  usages.

  Args:
    model_fn: A model function to be passed to the estimator. See
      https://www.tensorflow.org/api_docs/python/tf/estimator/Estimator#args_1
    train_input_fn: An input function to be passed to the estimator that
      corresponds to the training data. See
      https://www.tensorflow.org/api_docs/python/tf/estimator/Estimator#train
    eval_input_fn: An input function to be passed to the estimator that
      corresponds to the held-out eval data. See
      https://www.tensorflow.org/api_docs/python/tf/estimator/Estimator#evaluate
    exporters: (Optional) An tf.estimator.Exporter or a list of them.
    params: (Optional) A dictionary of parameters that will be accessible by the
      model_fn and input_fns. The 'batch_size' and 'use_tpu' values will be set
      automatically.
    params_fname: (Optional) If specified, `params` will be written to here
      under `FLAGS.model_dir` in JSON format.
  
language/common/utils/experiment_utils.py