Example #1
0
    def _actor_loss_debug_summaries(self, actor_loss, actions, log_pi,
                                    target_q_values, time_steps):
        if self._debug_summaries:
            common.generate_tensor_summaries('actor_loss', actor_loss,
                                             self.train_step_counter)
            try:
                for name, action in nest_utils.flatten_with_joined_paths(
                        actions):
                    common.generate_tensor_summaries(name, action,
                                                     self.train_step_counter)
            except ValueError:
                pass  # Guard against internal SAC variants that do not directly
                # generate actions.

            common.generate_tensor_summaries('log_pi', log_pi,
                                             self.train_step_counter)
            tf.compat.v2.summary.scalar(
                name='entropy_avg',
                data=-tf.reduce_mean(input_tensor=log_pi),
                step=self.train_step_counter)
            common.generate_tensor_summaries('target_q_values',
                                             target_q_values,
                                             self.train_step_counter)
            batch_size = nest_utils.get_outer_shape(time_steps,
                                                    self._time_step_spec)[0]
            policy_state = self._train_policy.get_initial_state(batch_size)
            action_distribution = self._train_policy.distribution(
                time_steps, policy_state).action
            if isinstance(action_distribution, tfp.distributions.Normal):
                common.generate_tensor_summaries('act_mean',
                                                 action_distribution.loc,
                                                 self.train_step_counter)
                common.generate_tensor_summaries('act_stddev',
                                                 action_distribution.scale,
                                                 self.train_step_counter)
            elif isinstance(action_distribution,
                            tfp.distributions.Categorical):
                common.generate_tensor_summaries('act_mode',
                                                 action_distribution.mode(),
                                                 self.train_step_counter)
            try:
                for name, action_dist in nest_utils.flatten_with_joined_paths(
                        action_distribution):
                    common.generate_tensor_summaries('entropy_' + name,
                                                     action_dist.entropy(),
                                                     self.train_step_counter)
            except NotImplementedError:
                pass  # Some distributions do not have an analytic entropy.
Example #2
0
    def __init__(self, time_step_spec=None, action_spec=None, batch_size=1):
        """Initialize instances of `BanditTFEnvironment`.

    Args:
      time_step_spec: A `TimeStep` namedtuple containing `TensorSpec`s
        defining the tensors returned by
        `step()` (step_type, reward, discount, and observation).
      action_spec: A nest of BoundedTensorSpec representing the actions of the
        environment.
      batch_size: The batch size expected for the actions and observations.
    """
        self._reset_called = tf.compat.v2.Variable(False,
                                                   trainable=False,
                                                   name='reset_called')

        def _variable_from_spec(name, spec):
            full_shape = [batch_size] + spec.shape.as_list()
            if not name:
                name = 'spec_var'
            return common.create_variable(name,
                                          0,
                                          shape=full_shape,
                                          dtype=spec.dtype)

        paths_and_specs = nest_utils.flatten_with_joined_paths(time_step_spec)
        variables = [
            _variable_from_spec(path, spec) for path, spec in paths_and_specs
        ]
        self._time_step_variables = tf.nest.pack_sequence_as(
            time_step_spec, variables)

        super(BanditTFEnvironment,
              self).__init__(time_step_spec=time_step_spec,
                             action_spec=action_spec,
                             batch_size=batch_size)
Example #3
0
  def __init__(self,
               time_step_spec,
               action_spec,
               batch_size=1,
               episode_end_probability=0.1):
    """Initializes the environment.

    Args:
      time_step_spec: A `TimeStep` namedtuple containing `TensorSpec`s defining
        the Tensors returned by `step()` (step_type, reward, discount, and
        observation).
      action_spec: A nest of BoundedTensorSpec representing the actions of the
        environment.
      batch_size: The batch size expected for the actions and observations.
      episode_end_probability: Probability an episode will end when the
        environment is stepped.
    """
    super(RandomTFEnvironment, self).__init__(
        time_step_spec, action_spec, batch_size=batch_size)
    self._episode_end_probability = episode_end_probability

    def _variable_from_spec(name, spec):
      full_shape = [batch_size] + spec.shape.as_list()
      if not name:
        name = "spec_var"
      return common.create_variable(name, 0, shape=full_shape, dtype=spec.dtype)

    paths_and_specs = nest_utils.flatten_with_joined_paths(time_step_spec)
    variables = [
        _variable_from_spec(path, spec) for path, spec in paths_and_specs
    ]
    self._time_step_variables = tf.nest.pack_sequence_as(
        time_step_spec, variables)
Example #4
0
def get_example_encoder(spec):
    """Get example encoder function for the given spec.

  Given a spec, returns an example encoder function. The example encoder
  function takes a nest of np.array feature values as input and returns a
  TF Example proto.

  Example:
    spec = {
        'lidar': array_spec.ArraySpec((900,), np.float32),
        'joint_positions': {
            'arm': array_spec.ArraySpec((7,), np.float32),
            'hand': array_spec.BoundedArraySpec((3, 3), np.int32, -1, 1)
        },
    }

    example_encoder = get_example_encoder(spec)
    serialized = example_encoder({
        'lidar': np.zeros((900,), np.float32),
        'joint_positions': {
            'arm': np.array([0.0, 1.57, 0.707, 0.2, 0.0, -1.57, 0.0],
                            np.float32),
            'hand': np.ones((3, 3), np.int32)
        },
    })

  The returned example encoder function requires that the feature nest passed
  has the shape and exact dtype specified in the spec. For example, it is
  an error to pass an array with np.float64 dtype where np.float32 is expected.

  Args:
    spec: list/tuple/nest of ArraySpecs describing a single example.

  Returns:
    Function

    ```python
    encoder(features_nest of np.arrays) -> tf.train.Example
    ```
  """
    # pylint: disable=g-complex-comprehension
    feature_encoders = [
        (path, _get_feature_encoder(spec.shape, spec.dtype))
        for (path, spec) in nest_utils.flatten_with_joined_paths(spec)
    ]

    # pylint: enable=g-complex-comprehension

    def _example_encoder(features_nest):
        flat_features = tf.nest.flatten(features_nest)
        feature_dict = {
            path: feature_encoder(feature)
            for feature, (
                path, feature_encoder) in zip(flat_features, feature_encoders)
        }
        return tf.train.Example(features=tf.train.Features(
            feature=feature_dict))

    return _example_encoder
Example #5
0
def get_example_decoder(example_spec, batched=False, compress_image=False):
    """Get an example decoder function for a nested spec.

  Given a spec, returns an example decoder function. The decoder function parses
  string serialized example protos into tensors according to the given spec.

  Args:
    example_spec: list/tuple/nest of ArraySpecs describing a single example.
    batched: Boolean indicating if the decoder will receive batches of
      serialized data.
    compress_image: Whether to decompress image. It is assumed that any uint8
      tensor of rank 3 with shape (w,h,c) is an image.
      If the tensor was compressed in the encoder, it needs to be decompressed.

  Returns:
    Function

    ```python
    decoder(serialized_proto: tf.tensor[string]) -> example_spec nest of tensors
    ```
  """
    features_dict = {}
    parsers = []

    for (path, spec) in nest_utils.flatten_with_joined_paths(example_spec):
        feature, parser = _get_feature_parser(spec.shape, spec.dtype,
                                              compress_image)
        features_dict[path] = feature
        parsers.append((path, parser))

    def _example_decoder(serialized):
        """Parses string serialized example protos into tensors."""
        if batched:
            raw_features = tf.io.parse_example(serialized=serialized,
                                               features=features_dict)

            decoded_features = []

            dtypes = [s.dtype for s in tf.nest.flatten(example_spec)]
            if len(parsers) != len(dtypes):
                raise ValueError(
                    'Decoding failed: Number of parsers (%d) does not match the number '
                    'of items in the example_spec (%d)' %
                    (len(parsers), len(dtypes)))

            for (path, parser), dtype in zip(parsers, dtypes):
                decoded_features.append(
                    tf.map_fn(parser, raw_features[path], dtype=dtype))

            return tf.nest.pack_sequence_as(example_spec, decoded_features)
        else:
            raw_features = tf.io.parse_single_example(serialized=serialized,
                                                      features=features_dict)
            return tf.nest.pack_sequence_as(
                example_spec,
                [parser(raw_features[path]) for path, parser in parsers])

    return _example_decoder
Example #6
0
def parameters_to_dict(value: Params) -> Mapping[Text, Any]:
    """Converts `value` to a nested `dict` (excluding all `type_` info).

  Sub-dicts represent `Params` objects; keys represent flattened nest structures
  in `value.params`.

  Example:

  ```python
  scale_matrix = tf.Variable([[1.0, 2.0], [-1.0, 0.0]])
  d = tfp.distributions.MultivariateNormalDiag(
      loc=[1.0, 1.0], scale_diag=[2.0, 3.0], validate_args=True)
  b = tfp.bijectors.ScaleMatvecLinearOperator(
      scale=tf.linalg.LinearOperatorFullMatrix(matrix=scale_matrix),
      adjoint=True)
  b_d = b(d)
  p = utils.get_parameters(b_d)
  params_dict = utils.parameters_to_dict(p)
  ```

  results in the nested dictionary:

  ```python
  {"bijector": {"adjoint": True,
                "scale": {"matrix": scale_matrix}},
   "distribution": {"validate_args": True,
                    # These are deeply nested because we passed lists
                    # intead of numpy arrays for `loc` and `scale_diag`.
                    "scale_diag:0": 2.0,
                    "scale_diag:1": 3.0,
                    "loc:0": 1.0,
                    "loc:1": 1.0}
  }
  ```

  The dictionary may then be modified or updated (e.g., in place), and converted
  back to a `Params` object using `merge_to_parameters_from_dict`.

  Args:
    value: The (possibly recursively defined) `Params`.

  Returns:
    A `dict` mapping `value.params` to flattened key/value pairs.  Any
    sub-`Params` objects become nested dicts.
  """
    convert = lambda p: parameters_to_dict(p) if isinstance(p, Params) else p

    output_entries = {}
    for k, v in value.params.items():
        if tf.nest.is_nested(v):
            flattened_params = nest_utils.flatten_with_joined_paths(v)
            for (param_k, param_v) in flattened_params:
                key = "{}:{}".format(k, param_k)
                output_entries[key] = convert(param_v)
        else:
            output_entries[k] = convert(v)
    return output_entries
Example #7
0
def get_example_decoder(example_spec, batched=False):
    """Get an example decoder function for a nested spec.

  Given a spec, returns an example decoder function. The decoder function parses
  string serialized example protos into tensors according to the given spec.

  Args:
    example_spec: list/tuple/nest of ArraySpecs describing a single example.
    batched: Boolean indicating if the decoder will receive batches of
      serialized data.

  Returns:
    Function

    ```python
    decoder(serialized_proto: tf.tensor[string]) -> example_spec nest of tensors
    ```
  """
    features_dict = {}
    parsers = []

    for (path, spec) in nest_utils.flatten_with_joined_paths(example_spec):
        feature, parser = _get_feature_parser(spec.shape, spec.dtype)
        features_dict[path] = feature
        parsers.append((path, parser))

    def _example_decoder(serialized):
        """Parses string serialized example protos into tensors."""
        if batched:
            raw_features = tf.io.parse_example(serialized=serialized,
                                               features=features_dict)

            decoded_features = []

            dtypes = [s.dtype for s in tf.nest.flatten(example_spec)]
            for (path, parser), dtype in zip(parsers, dtypes):
                decoded_features.append(
                    tf.map_fn(parser, raw_features[path], dtype=dtype))

            return tf.nest.pack_sequence_as(example_spec, decoded_features)
        else:
            raw_features = tf.io.parse_single_example(serialized=serialized,
                                                      features=features_dict)
            return tf.nest.pack_sequence_as(
                example_spec,
                [parser(raw_features[path]) for path, parser in parsers])

    return _example_decoder
def _rename_spec_with_nest_paths(spec):
    renamed_spec = [
        tf.TensorSpec(shape=s.shape, name=path, dtype=s.dtype)
        for path, s in nest_utils.flatten_with_joined_paths(spec)
    ]
    return tf.nest.pack_sequence_as(spec, renamed_spec)
Example #9
0
def parameters_to_dict(
    value: Params,
    tensors_only: bool = False) -> Mapping[Text, Any]:
  """Converts `value` to a nested `dict` (excluding all `type_` info).

  Sub-dicts represent `Params` objects; keys represent flattened nest structures
  in `value.params`.

  Example:

  ```python
  scale_matrix = tf.Variable([[1.0, 2.0], [-1.0, 0.0]])
  d = tfp.distributions.MultivariateNormalDiag(
      loc=[1.0, 1.0], scale_diag=[2.0, 3.0], validate_args=True)
  b = tfp.bijectors.ScaleMatvecLinearOperator(
      scale=tf.linalg.LinearOperatorFullMatrix(matrix=scale_matrix),
      adjoint=True)
  b_d = b(d)
  p = utils.get_parameters(b_d)
  params_dict = utils.parameters_to_dict(p, tensors_only)
  ```

  results in the nested dictionary, if `tensors_only=False`:

  ```python
  {
    "bijector": {"adjoint": True,
                 "scale": {"matrix": scale_matrix}},
    "distribution": {"validate_args": True,
                     # These are deeply nested because we passed lists
                     # intead of numpy arrays for `loc` and `scale_diag`.
                     "scale_diag:0": 2.0,
                     "scale_diag:1": 3.0,
                     "loc:0": 1.0,
                     "loc:1": 1.0}
  }
  ```

  results if `tensors_only=True`:

  ```python
  {
    "bijector": {"scale": {"matrix": scale_matrix}},
    "distribution": {},
  }
  ```

  The dictionary may then be modified or updated (e.g., in place), and converted
  back to a `Params` object using `merge_to_parameters_from_dict`.

  Args:
    value: The (possibly recursively defined) `Params`.
    tensors_only: Whether to include all parameters or only
      tensors and TypeSpecs.  If `True`, then only
      `tf.Tensor` and `tf.TypeSpec` leaf parameters are emitted.

  Returns:
    A `dict` mapping `value.params` to flattened key/value pairs.  Any
    sub-`Params` objects become nested dicts.
  """
  output_entries = {}

  # All tensors and TensorSpecs will be included for purposes of this test.
  is_tensor_or_spec = (
      lambda p: tf.is_tensor(p) or isinstance(p, tf.TypeSpec))

  def convert(key, p):
    if isinstance(p, Params):
      output_entries[key] = parameters_to_dict(p, tensors_only)
    elif not tensors_only or is_tensor_or_spec(p):
      output_entries[key] = p

  for k, v in value.params.items():
    if tf.nest.is_nested(v):
      flattened_params = nest_utils.flatten_with_joined_paths(v)
      for (param_k, param_v) in flattened_params:
        key = "{}:{}".format(k, param_k)
        convert(key, param_v)
    else:
      convert(k, v)

  return output_entries
Example #10
0
def get_example_encoder(spec, compress_image=False, image_quality=95):
    """Get example encoder function for the given spec.

  Given a spec, returns an example encoder function. The example encoder
  function takes a nest of np.array feature values as input and returns a
  TF Example proto.

  Example:
    spec = {
        'lidar': array_spec.ArraySpec((900,), np.float32),
        'joint_positions': {
            'arm': array_spec.ArraySpec((7,), np.float32),
            'hand': array_spec.BoundedArraySpec((3, 3), np.int32, -1, 1)
        },
    }

    example_encoder = get_example_encoder(spec)
    serialized = example_encoder({
        'lidar': np.zeros((900,), np.float32),
        'joint_positions': {
            'arm': np.array([0.0, 1.57, 0.707, 0.2, 0.0, -1.57, 0.0],
                            np.float32),
            'hand': np.ones((3, 3), np.int32)
        },
    })

  The returned example encoder function requires that the feature nest passed
  has the shape and exact dtype specified in the spec. For example, it is
  an error to pass an array with np.float64 dtype where np.float32 is expected.

  Args:
    spec: list/tuple/nest of ArraySpecs describing a single example.
    compress_image: Whether to compress image. It is assumed that any uint8
      tensor of rank 3 with shape (w,h,c) is an image.
    image_quality: An optional int. Defaults to 95. Quality of the compression
      from 0 to 100 (higher is better and slower).

  Returns:
    Function

    ```python
    encoder(features_nest of np.arrays) -> tf.train.Example
    ```
  """
    # pylint: disable=g-complex-comprehension
    feature_encoders = [
        (path,
         _get_feature_encoder(spec.shape, spec.dtype, compress_image,
                              image_quality))
        for (path, spec) in nest_utils.flatten_with_joined_paths(spec)
    ]

    # pylint: enable=g-complex-comprehension

    def _example_encoder(features_nest):
        flat_features = tf.nest.flatten(features_nest)
        if len(flat_features) != len(feature_encoders):
            raise ValueError(
                'Encoding failed: The number of items to encode does not match the '
                'number of encoders generated. Num features %d, num_encoders:%d'
                % (len(flat_features), len(feature_encoders)))

        feature_dict = {
            path: feature_encoder(feature)
            for feature, (
                path, feature_encoder) in zip(flat_features, feature_encoders)
        }
        return tf.train.Example(features=tf.train.Features(
            feature=feature_dict))

    return _example_encoder