def testNewFocalLossParameters(self):
        """Tests that the loss weight ratio is updated appropriately."""
        original_alpha = 1.0
        original_gamma = 1.0
        new_alpha = 0.3
        new_gamma = 2.0
        hparams = tf.contrib.training.HParams(focal_loss_alpha=new_alpha,
                                              focal_loss_gamma=new_gamma)
        pipeline_config_path = os.path.join(self.get_temp_dir(),
                                            "pipeline.config")

        pipeline_config = pipeline_pb2.TrainEvalPipelineConfig()
        classification_loss = pipeline_config.model.ssd.loss.classification_loss
        classification_loss.weighted_sigmoid_focal.alpha = original_alpha
        classification_loss.weighted_sigmoid_focal.gamma = original_gamma
        _write_config(pipeline_config, pipeline_config_path)

        configs = config_util.get_configs_from_pipeline_file(
            pipeline_config_path)
        configs = config_util.merge_external_params_with_configs(
            configs, hparams)
        classification_loss = configs["model"].ssd.loss.classification_loss
        self.assertAlmostEqual(
            new_alpha, classification_loss.weighted_sigmoid_focal.alpha)
        self.assertAlmostEqual(
            new_gamma, classification_loss.weighted_sigmoid_focal.gamma)
def _get_configs_for_model(model_name):
  """Returns configurations for model."""
  filename = model_test_util.GetPipelineConfigPath(model_name)
  data_path = _get_data_path()
  label_map_path = _get_labelmap_path()
  configs = config_util.get_configs_from_pipeline_file(filename)
  configs = config_util.merge_external_params_with_configs(
      configs,
      train_input_path=data_path,
      eval_input_path=data_path,
      label_map_path=label_map_path)
  return configs
    def testNewBatchSizeWithClipping(self):
        """Tests that batch size is clipped to 1 from below."""
        original_batch_size = 2
        hparams = tf.contrib.training.HParams(batch_size=0.5)
        pipeline_config_path = os.path.join(self.get_temp_dir(),
                                            "pipeline.config")

        pipeline_config = pipeline_pb2.TrainEvalPipelineConfig()
        pipeline_config.train_config.batch_size = original_batch_size
        _write_config(pipeline_config, pipeline_config_path)

        configs = config_util.get_configs_from_pipeline_file(
            pipeline_config_path)
        configs = config_util.merge_external_params_with_configs(
            configs, hparams)
        new_batch_size = configs["train_config"].batch_size
        self.assertEqual(1, new_batch_size)  # Clipped to 1.0.
    def testNewBatchSize(self):
        """Tests that batch size is updated appropriately."""
        original_batch_size = 2
        hparams = tf.contrib.training.HParams(batch_size=16)
        pipeline_config_path = os.path.join(self.get_temp_dir(),
                                            "pipeline.config")

        pipeline_config = pipeline_pb2.TrainEvalPipelineConfig()
        pipeline_config.train_config.batch_size = original_batch_size
        _write_config(pipeline_config, pipeline_config_path)

        configs = config_util.get_configs_from_pipeline_file(
            pipeline_config_path)
        configs = config_util.merge_external_params_with_configs(
            configs, hparams)
        new_batch_size = configs["train_config"].batch_size
        self.assertEqual(16, new_batch_size)
def _get_configs_for_model(model_name):
  """Returns configurations for model."""
  # TODO: Make sure these tests work fine outside google3.
  fname = os.path.join(
      FLAGS.test_srcdir,
      ('google3/third_party/tensorflow_models/'
       'object_detection/samples/configs/' + model_name + '.config'))
  label_map_path = os.path.join(FLAGS.test_srcdir,
                                ('google3/third_party/tensorflow_models/'
                                 'object_detection/data/pet_label_map.pbtxt'))
  data_path = os.path.join(FLAGS.test_srcdir,
                           ('google3/third_party/tensorflow_models/'
                            'object_detection/test_data/pets_examples.record'))
  configs = config_util.get_configs_from_pipeline_file(fname)
  return config_util.merge_external_params_with_configs(
      configs,
      train_input_path=data_path,
      eval_input_path=data_path,
      label_map_path=label_map_path)
    def testNewTrainInputPathList(self):
        """Tests that train input path can be overwritten with multiple files."""
        original_train_path = ["path/to/data"]
        new_train_path = ["another/path/to/data", "yet/another/path/to/data"]
        pipeline_config_path = os.path.join(self.get_temp_dir(),
                                            "pipeline.config")

        pipeline_config = pipeline_pb2.TrainEvalPipelineConfig()
        reader_config = pipeline_config.train_input_reader.tf_record_input_reader
        reader_config.input_path.extend(original_train_path)
        _write_config(pipeline_config, pipeline_config_path)

        configs = config_util.get_configs_from_pipeline_file(
            pipeline_config_path)
        configs = config_util.merge_external_params_with_configs(
            configs, train_input_path=new_train_path)
        reader_config = configs["train_input_config"].tf_record_input_reader
        final_path = reader_config.input_path
        self.assertEqual(new_train_path, final_path)
    def testNewMomentumOptimizerValue(self):
        """Tests that new momentum value is updated appropriately."""
        original_momentum_value = 0.4
        hparams = tf.contrib.training.HParams(momentum_optimizer_value=1.1)
        pipeline_config_path = os.path.join(self.get_temp_dir(),
                                            "pipeline.config")

        pipeline_config = pipeline_pb2.TrainEvalPipelineConfig()
        optimizer_config = pipeline_config.train_config.optimizer.rms_prop_optimizer
        optimizer_config.momentum_optimizer_value = original_momentum_value
        _write_config(pipeline_config, pipeline_config_path)

        configs = config_util.get_configs_from_pipeline_file(
            pipeline_config_path)
        configs = config_util.merge_external_params_with_configs(
            configs, hparams)
        optimizer_config = configs["train_config"].optimizer.rms_prop_optimizer
        new_momentum_value = optimizer_config.momentum_optimizer_value
        self.assertAlmostEqual(1.0, new_momentum_value)  # Clipped to 1.0.
    def testNewMaskType(self):
        """Tests that mask type can be overwritten in input readers."""
        original_mask_type = input_reader_pb2.NUMERICAL_MASKS
        new_mask_type = input_reader_pb2.PNG_MASKS
        pipeline_config_path = os.path.join(self.get_temp_dir(),
                                            "pipeline.config")

        pipeline_config = pipeline_pb2.TrainEvalPipelineConfig()
        train_input_reader = pipeline_config.train_input_reader
        train_input_reader.mask_type = original_mask_type
        eval_input_reader = pipeline_config.eval_input_reader
        eval_input_reader.mask_type = original_mask_type
        _write_config(pipeline_config, pipeline_config_path)

        configs = config_util.get_configs_from_pipeline_file(
            pipeline_config_path)
        configs = config_util.merge_external_params_with_configs(
            configs, mask_type=new_mask_type)
        self.assertEqual(new_mask_type,
                         configs["train_input_config"].mask_type)
        self.assertEqual(new_mask_type, configs["eval_input_config"].mask_type)
    def testNewLabelMapPath(self):
        """Tests that label map path can be overwritten in input readers."""
        original_label_map_path = "path/to/original/label_map"
        new_label_map_path = "path//to/new/label_map"
        pipeline_config_path = os.path.join(self.get_temp_dir(),
                                            "pipeline.config")

        pipeline_config = pipeline_pb2.TrainEvalPipelineConfig()
        train_input_reader = pipeline_config.train_input_reader
        train_input_reader.label_map_path = original_label_map_path
        eval_input_reader = pipeline_config.eval_input_reader
        eval_input_reader.label_map_path = original_label_map_path
        _write_config(pipeline_config, pipeline_config_path)

        configs = config_util.get_configs_from_pipeline_file(
            pipeline_config_path)
        configs = config_util.merge_external_params_with_configs(
            configs, label_map_path=new_label_map_path)
        self.assertEqual(new_label_map_path,
                         configs["train_input_config"].label_map_path)
        self.assertEqual(new_label_map_path,
                         configs["eval_input_config"].label_map_path)
    def testMergingKeywordArguments(self):
        """Tests that keyword arguments get merged as do hyperparameters."""
        original_num_train_steps = 100
        original_num_eval_steps = 5
        desired_num_train_steps = 10
        desired_num_eval_steps = 1
        pipeline_config_path = os.path.join(self.get_temp_dir(),
                                            "pipeline.config")

        pipeline_config = pipeline_pb2.TrainEvalPipelineConfig()
        pipeline_config.train_config.num_steps = original_num_train_steps
        pipeline_config.eval_config.num_examples = original_num_eval_steps
        _write_config(pipeline_config, pipeline_config_path)

        configs = config_util.get_configs_from_pipeline_file(
            pipeline_config_path)
        configs = config_util.merge_external_params_with_configs(
            configs,
            train_steps=desired_num_train_steps,
            eval_steps=desired_num_eval_steps)
        train_steps = configs["train_config"].num_steps
        eval_steps = configs["eval_config"].num_examples
        self.assertEqual(desired_num_train_steps, train_steps)
        self.assertEqual(desired_num_eval_steps, eval_steps)
    def testNewClassificationLocalizationWeightRatio(self):
        """Tests that the loss weight ratio is updated appropriately."""
        original_localization_weight = 0.1
        original_classification_weight = 0.2
        new_weight_ratio = 5.0
        hparams = tf.contrib.training.HParams(
            classification_localization_weight_ratio=new_weight_ratio)
        pipeline_config_path = os.path.join(self.get_temp_dir(),
                                            "pipeline.config")

        pipeline_config = pipeline_pb2.TrainEvalPipelineConfig()
        pipeline_config.model.ssd.loss.localization_weight = (
            original_localization_weight)
        pipeline_config.model.ssd.loss.classification_weight = (
            original_classification_weight)
        _write_config(pipeline_config, pipeline_config_path)

        configs = config_util.get_configs_from_pipeline_file(
            pipeline_config_path)
        configs = config_util.merge_external_params_with_configs(
            configs, hparams)
        loss = configs["model"].ssd.loss
        self.assertAlmostEqual(1.0, loss.localization_weight)
        self.assertAlmostEqual(new_weight_ratio, loss.classification_weight)
    def _assertOptimizerWithNewLearningRate(self, optimizer_name):
        """Asserts successful updating of all learning rate schemes."""
        original_learning_rate = 0.7
        learning_rate_scaling = 0.1
        hparams = tf.contrib.training.HParams(learning_rate=0.15)
        pipeline_config_path = os.path.join(self.get_temp_dir(),
                                            "pipeline.config")

        # Constant learning rate.
        pipeline_config = pipeline_pb2.TrainEvalPipelineConfig()
        optimizer = getattr(pipeline_config.train_config.optimizer,
                            optimizer_name)
        _update_optimizer_with_constant_learning_rate(optimizer,
                                                      original_learning_rate)
        _write_config(pipeline_config, pipeline_config_path)

        configs = config_util.get_configs_from_pipeline_file(
            pipeline_config_path)
        configs = config_util.merge_external_params_with_configs(
            configs, hparams)
        optimizer = getattr(configs["train_config"].optimizer, optimizer_name)
        constant_lr = optimizer.learning_rate.constant_learning_rate
        self.assertAlmostEqual(hparams.learning_rate,
                               constant_lr.learning_rate)

        # Exponential decay learning rate.
        pipeline_config = pipeline_pb2.TrainEvalPipelineConfig()
        optimizer = getattr(pipeline_config.train_config.optimizer,
                            optimizer_name)
        _update_optimizer_with_exponential_decay_learning_rate(
            optimizer, original_learning_rate)
        _write_config(pipeline_config, pipeline_config_path)

        configs = config_util.get_configs_from_pipeline_file(
            pipeline_config_path)
        configs = config_util.merge_external_params_with_configs(
            configs, hparams)
        optimizer = getattr(configs["train_config"].optimizer, optimizer_name)
        exponential_lr = optimizer.learning_rate.exponential_decay_learning_rate
        self.assertAlmostEqual(hparams.learning_rate,
                               exponential_lr.initial_learning_rate)

        # Manual step learning rate.
        pipeline_config = pipeline_pb2.TrainEvalPipelineConfig()
        optimizer = getattr(pipeline_config.train_config.optimizer,
                            optimizer_name)
        _update_optimizer_with_manual_step_learning_rate(
            optimizer, original_learning_rate, learning_rate_scaling)
        _write_config(pipeline_config, pipeline_config_path)

        configs = config_util.get_configs_from_pipeline_file(
            pipeline_config_path)
        configs = config_util.merge_external_params_with_configs(
            configs, hparams)
        optimizer = getattr(configs["train_config"].optimizer, optimizer_name)
        manual_lr = optimizer.learning_rate.manual_step_learning_rate
        self.assertAlmostEqual(hparams.learning_rate,
                               manual_lr.initial_learning_rate)
        for i, schedule in enumerate(manual_lr.schedule):
            self.assertAlmostEqual(
                hparams.learning_rate * learning_rate_scaling**i,
                schedule.learning_rate)
Beispiel #13
0
def create_estimator(run_config,
                     hparams,
                     pipeline_config_path,
                     train_steps=None,
                     eval_steps=None,
                     train_batch_size=None,
                     model_fn_creator=model.create_model_fn,
                     use_tpu=False,
                     num_shards=1,
                     params=None,
                     **kwargs):
  """Creates an `Estimator` object.

  Args:
    run_config: A `RunConfig`.
    hparams: A `HParams`.
    pipeline_config_path: A path to a pipeline config file.
    train_steps: Number of training steps. If None, the number of training steps
      is set from the `TrainConfig` proto.
    eval_steps: Number of evaluation steps per evaluation cycle. If None, the
      number of evaluation steps is set from the `EvalConfig` proto.
    train_batch_size: Training batch size. If none, use batch size from
      `TrainConfig` proto.
    model_fn_creator: A function that creates a `model_fn` for `Estimator`.
      Follows the signature:

      * Args:
        * `detection_model_fn`: Function that returns `DetectionModel` instance.
        * `configs`: Dictionary of pipeline config objects.
        * `hparams`: `HParams` object.
      * Returns:
        `model_fn` for `Estimator`.

    use_tpu: Boolean, whether training and evaluation should run on TPU.
    num_shards: Number of shards (TPU cores).
    params: Parameter dictionary passed from the estimator.
    **kwargs: Additional keyword arguments for configuration override.

  Returns:
    Estimator: A estimator object used for training and evaluation
    train_input_fn: Input function for the training loop
    eval_input_fn: Input function for the evaluation run
    train_steps: Number of training steps either from arg `train_steps` or
      `TrainConfig` proto
    eval_steps: Number of evaluation steps either from arg `eval_steps` or
      `EvalConfig` proto
  """
  configs = config_util.get_configs_from_pipeline_file(pipeline_config_path)
  configs = config_util.merge_external_params_with_configs(
      configs,
      hparams,
      train_steps=train_steps,
      eval_steps=eval_steps,
      batch_size=train_batch_size,
      **kwargs)
  model_config = configs['model']
  train_config = configs['train_config']
  train_input_config = configs['train_input_config']
  eval_config = configs['eval_config']
  eval_input_config = configs['eval_input_config']

  if params is None:
    params = {}

  if train_steps is None:
    train_steps = train_config.num_steps if train_config.num_steps else None

  if eval_steps is None:
    eval_steps = eval_config.num_examples if eval_config.num_examples else None

  detection_model_fn = functools.partial(
      model_builder.build, model_config=model_config)

  # Create the input functions for TRAIN/EVAL.
  train_input_fn = inputs.create_train_input_fn(
      train_config=train_config,
      train_input_config=train_input_config,
      model_config=model_config)
  eval_input_fn = inputs.create_eval_input_fn(
      eval_config=eval_config,
      eval_input_config=eval_input_config,
      model_config=model_config)

  estimator = tpu_estimator.TPUEstimator(
      model_fn=model_fn_creator(detection_model_fn, configs, hparams,
                                use_tpu),
      train_batch_size=train_config.batch_size,
      # For each core, only batch size 1 is supported for eval.
      eval_batch_size=num_shards * 1 if use_tpu else 1,
      use_tpu=use_tpu,
      config=run_config,
      params=params)
  return estimator, train_input_fn, eval_input_fn, train_steps, eval_steps
def populate_experiment(run_config,
                        hparams,
                        pipeline_config_path,
                        train_steps=None,
                        eval_steps=None,
                        model_fn_creator=create_model_fn,
                        **kwargs):
  """Populates an `Experiment` object.

  Args:
    run_config: A `RunConfig`.
    hparams: A `HParams`.
    pipeline_config_path: A path to a pipeline config file.
    train_steps: Number of training steps. If None, the number of training steps
      is set from the `TrainConfig` proto.
    eval_steps: Number of evaluation steps per evaluation cycle. If None, the
      number of evaluation steps is set from the `EvalConfig` proto.
    model_fn_creator: A function that creates a `model_fn` for `Estimator`.
      Follows the signature:

      * Args:
        * `detection_model_fn`: Function that returns `DetectionModel` instance.
        * `configs`: Dictionary of pipeline config objects.
        * `hparams`: `HParams` object.
      * Returns:
        `model_fn` for `Estimator`.

    **kwargs: Additional keyword arguments for configuration override.

  Returns:
    An `Experiment` that defines all aspects of training, evaluation, and
    export.
  """
  configs = config_util.get_configs_from_pipeline_file(pipeline_config_path)
  configs = config_util.merge_external_params_with_configs(
      configs,
      hparams,
      train_steps=train_steps,
      eval_steps=eval_steps,
      **kwargs)
  model_config = configs['model']
  train_config = configs['train_config']
  train_input_config = configs['train_input_config']
  eval_config = configs['eval_config']
  eval_input_config = configs['eval_input_config']

  if train_steps is None:
    train_steps = train_config.num_steps if train_config.num_steps else None

  if eval_steps is None:
    eval_steps = eval_config.num_examples if eval_config.num_examples else None

  detection_model_fn = functools.partial(
      model_builder.build, model_config=model_config)

  # Create the input functions for TRAIN/EVAL.
  train_input_fn = inputs.create_train_input_fn(
      train_config=train_config,
      train_input_config=train_input_config,
      model_config=model_config)
  eval_input_fn = inputs.create_eval_input_fn(
      eval_config=eval_config,
      eval_input_config=eval_input_config,
      model_config=model_config)

  export_strategies = [
      tf.contrib.learn.utils.saved_model_export_utils.make_export_strategy(
          serving_input_fn=inputs.create_predict_input_fn(
              model_config=model_config))
  ]

  estimator = tf.estimator.Estimator(
      model_fn=model_fn_creator(detection_model_fn, configs, hparams),
      config=run_config)

  if run_config.is_chief:
    # Store the final pipeline config for traceability.
    pipeline_config_final = config_util.create_pipeline_proto_from_configs(
        configs)
    pipeline_config_final_path = os.path.join(estimator.model_dir,
                                              'pipeline.config')
    config_text = text_format.MessageToString(pipeline_config_final)
    with tf.gfile.Open(pipeline_config_final_path, 'wb') as f:
      tf.logging.info('Writing as-run pipeline config file to %s',
                      pipeline_config_final_path)
      f.write(config_text)

  return tf.contrib.learn.Experiment(
      estimator=estimator,
      train_input_fn=train_input_fn,
      eval_input_fn=eval_input_fn,
      train_steps=train_steps,
      eval_steps=eval_steps,
      export_strategies=export_strategies,
      eval_delay_secs=120,)