Exemplo n.º 1
0
def get_initializer(hparams=None):
    """Returns an initializer instance.

    Args:
        hparams (dict or HParams, optional): Hyperparameters.

    Returns:
        An initializer instance. `None` if :attr:`hparams` is `None`.
    """
    if hparams is None:
        return None

    if is_str(hparams["type"]):
        kwargs = hparams["kwargs"]
        if isinstance(kwargs, HParams):
            kwargs = kwargs.todict()
        modules = [
            "tensorflow.initializers", "tensorflow.keras.initializers",
            "tensorflow", "texar.custom"
        ]
        try:
            initializer = utils.get_instance(hparams["type"], kwargs, modules)
        except TypeError:
            modules += ['tensorflow.contrib.layers']
            initializer_fn = utils.get_function(hparams["type"], modules)
            initializer = initializer_fn(**kwargs)
    else:
        initializer = hparams["type"]
    return initializer
Exemplo n.º 2
0
    def __init__(self,
                 env_config,
                 sess=None,
                 actor=None,
                 actor_kwargs=None,
                 critic=None,
                 critic_kwargs=None,
                 hparams=None):
        EpisodicAgentBase.__init__(self, env_config=env_config, hparams=hparams)

        self._sess = sess
        self._num_actions = self._env_config.action_space.high - \
                            self._env_config.action_space.low

        with tf.variable_scope(self.variable_scope):
            if actor is None:
                kwargs = utils.get_instance_kwargs(
                    actor_kwargs, self._hparams.actor_hparams)
                kwargs.update(dict(env_config=env_config, sess=sess))
                actor = utils.get_instance(
                    class_or_name=self._hparams.actor_type,
                    kwargs=kwargs,
                    module_paths=['texar.agents', 'texar.custom'])
            self._actor = actor

            if critic is None:
                kwargs = utils.get_instance_kwargs(
                    critic_kwargs, self._hparams.critic_hparams)
                kwargs.update(dict(env_config=env_config, sess=sess))
                critic = utils.get_instance(
                    class_or_name=self._hparams.critic_type,
                    kwargs=kwargs,
                    module_paths=['texar.agents', 'texar.custom'])
            self._critic = critic

            if self._actor._discount_factor != self._critic._discount_factor:
                raise ValueError('discount_factor of the actor and the critic '
                                 'must be the same.')
            self._discount_factor = self._actor._discount_factor

            self._observs = []
            self._actions = []
            self._rewards = []
Exemplo n.º 3
0
    def __init__(self,
                 env_config,
                 sess=None,
                 actor=None,
                 actor_kwargs=None,
                 critic=None,
                 critic_kwargs=None,
                 hparams=None):
        EpisodicAgentBase.__init__(self,
                                   env_config=env_config,
                                   hparams=hparams)

        self._sess = sess
        self._num_actions = self._env_config.action_space.high - \
                            self._env_config.action_space.low

        with tf.variable_scope(self.variable_scope):
            if actor is None:
                kwargs = utils.get_instance_kwargs(actor_kwargs,
                                                   self._hparams.actor_kwargs)
                kwargs.update(dict(env_config=env_config, sess=sess))
                actor = utils.get_instance(
                    class_or_name=self._hparams.actor_type,
                    kwargs=kwargs,
                    module_paths=['texar.agents', 'texar.custom'])
            self.actor = actor

            if critic is None:
                kwargs = utils.get_instance_kwargs(critic_kwargs,
                                                   self._hparams.critic_kwargs)
                kwargs.update(dict(env_config=env_config, sess=sess))
                critic = utils.get_instance(
                    class_or_name=self._hparams.critic_type,
                    kwargs=kwargs,
                    module_paths=['texar.agents', 'texar.custom'])
            self.critic = critic

            assert self.actor._discount_factor == self.critic._discount_factor
            self._discount_factor = self.actor._discount_factor
Exemplo n.º 4
0
    def __init__(self, actions, state_shape, hparams=None):
        AgentBase.__init__(self, actions, state_shape, hparams=hparams)
        self.discount_factor = self._hparams.discount_factor

        self.network = get_instance(
            self._hparams.network.type,
            {"hparams": self._hparams.network.hparams},
            module_paths=['texar.modules', 'texar.custom'])

        with tf.variable_scope(self.network.variable_scope):
            self.state_input = tf.placeholder(dtype=tf.float64,
                                              shape=[
                                                  None,
                                              ] + list(state_shape))

            self.action_inputs = tf.placeholder(dtype=tf.int32, shape=[
                None,
            ])

            self.qvalues = tf.placeholder(dtype=tf.float64, shape=[
                None,
            ])

            self.outputs = self.network(self.state_input)
            self.probs = tf.nn.softmax(self.outputs)

            self.loss = self._hparams.trainer.loss_fn(
                outputs=self.outputs,
                action_inputs=self.action_inputs,
                advantages=self.qvalues)
            self.trainer = opt.get_train_op(
                loss=self.loss,
                variables=None,
                hparams=self._hparams.trainer.optimization_hparams)

        self.record = list()

        self.sess = tf.Session()
        self.sess.run(tf.global_variables_initializer())
Exemplo n.º 5
0
def get_regularizer(hparams=None):
    """Returns a variable regularizer instance.

    See :func:`~texar.core.layers.default_regularizer_hparams` for all
    hyperparameters and default values.

    Args:
        hparams (dict or HParams, optional): Hyperparameters. Missing
            hyperparameters are set to default values.

    Returns:
        A :tf_main:`Regularizer <keras/regularizers/Regularizer>` instance.
        `None` if :attr:`hparams` is `None` or takes the default
        hyperparameter value.

    Raises:
        ValueError: The resulting regularizer is not an instance of
            :tf_main:`Regularizer <keras/regularizers/Regularizer>`.
    """
    if hparams is None:
        return None

    if isinstance(hparams, dict):
        hparams = HParams(hparams, default_regularizer_hparams())
    if is_str(hparams.type):
        rgl = utils.get_instance(
            hparams.type, hparams.kwargs.todict(),
            ["tensorflow.keras.regularizers", "texar.custom"])
    else:
        rgl = hparams.type
    if not isinstance(rgl, tf.keras.regularizers.Regularizer):
        raise ValueError("The regularizer must be an instance of "
                         "tf.keras.regularizers.Regularizer.")
    if isinstance(rgl, tf.keras.regularizers.L1L2) and \
            rgl.l1 == 0. and rgl.l2 == 0.:
        return None
    return rgl
def get_layer(hparams: Union[HParams, Dict[str, Any]]) -> nn.Module:
    r"""Makes a layer instance.

    The layer must be an instance of :torch_nn:`Module`.

    Args:
        hparams (dict or HParams): Hyperparameters of the layer, with
            structure:

            .. code-block:: python

                {
                    "type": "LayerClass",
                    "kwargs": {
                        # Keyword arguments of the layer class
                        # ...
                    }
                }

            Here:

            `"type"`: str or layer class or layer instance
                The layer type. This can be

                - The string name or full module path of a layer class. If
                  the class name is provided, the class must be in module
                  :torch_nn:`Module`, :mod:`texar.core`, or :mod:`texar.custom`.
                - A layer class.
                - An instance of a layer class.

                For example

                .. code-block:: python

                    "type": "Conv1D"                 ..no         # class name
                    "type": "texar.core.MaxReducePooling1D"   # module path
                    "type": "my_module.MyLayer"               # module path
                    "type": torch.nn.Module.Linear            # class
                    "type": Conv1D(filters=10, kernel_size=2) # cell instance
                    "type": MyLayer(...)                      # cell instance

            `"kwargs"`: dict
                A dictionary of keyword arguments for constructor of the
                layer class. Ignored if :attr:`"type"` is a layer instance.

                - Arguments named "activation" can be a callable, or a `str` of
                  the name or module path to the activation function.
                - Arguments named "\*_regularizer" and "\*_initializer" can be a
                  class instance, or a `dict` of hyperparameters of respective
                  regularizers and initializers. See
                - Arguments named "\*_constraint" can be a callable, or a `str`
                  of the name or full path to the constraint function.

    Returns:
        A layer instance. If ``hparams["type"]`` is a layer instance, returns it
        directly.

    Raises:
        ValueError: If :attr:`hparams` is `None`.
        ValueError: If the resulting layer is not an instance of
            :torch_nn:`Module`.
    """
    if hparams is None:
        raise ValueError("`hparams` must not be `None`.")

    layer_type = hparams["type"]
    if not is_str(layer_type) and not isinstance(layer_type, type):
        layer = layer_type
    else:
        layer_modules = ["torch.nn", "texar.core", "texar.custom"]
        layer_class = utils.check_or_get_class(layer_type, layer_modules)
        if isinstance(hparams, dict):
            if (layer_class.__name__ == "Linear"
                    and "in_features" not in hparams["kwargs"]):
                raise ValueError("\"in_features\" should be specified for "
                                 "\"torch.nn.{}\"".format(
                                     layer_class.__name__))
            elif (layer_class.__name__ in ["Conv1d", "Conv2d", "Conv3d"]
                  and "in_channels" not in hparams["kwargs"]):
                raise ValueError("\"in_channels\" should be specified for "
                                 "\"torch.nn.{}\"".format(
                                     layer_class.__name__))
            default_kwargs = _layer_class_to_default_kwargs_map.get(
                layer_class, {})
            default_hparams = {"type": layer_type, "kwargs": default_kwargs}
            hparams = HParams(hparams, default_hparams)

        # this case needs to be handled separately because
        # :torch_nn:`Sequential`
        # does not accept kwargs
        if layer_type == "Sequential":
            names: List[str] = []
            layer = nn.Sequential()
            sub_hparams = hparams.kwargs.layers
            for hparam in sub_hparams:
                sub_layer = get_layer(hparam)
                name = utils.uniquify_str(sub_layer._get_name(), names)
                names.append(name)
                layer.add_module(name=name, module=sub_layer)
        else:
            layer = utils.get_instance(layer_type, hparams.kwargs.todict(),
                                       layer_modules)

    if not isinstance(layer, nn.Module):
        raise ValueError("layer must be an instance of `torch.nn.Module`.")

    return layer
Exemplo n.º 7
0
def get_layer(hparams):
    """Makes a layer instance.

    The layer must be an instance of :tf_main:`tf.layers.Layer <layers/Layer>`.

    Args:
        hparams (dict or HParams): Hyperparameters of the layer, with
            structure:

            .. code-block:: python

                {
                    "type": "LayerClass",
                    "kwargs": {
                        # Keyword arguments of the layer class
                        # ...
                    }
                }

            Here:

            "type" : str or layer class or layer instance
                The layer type. This can be

                - The string name or full module path of a layer class. If \
                the class name is provided, the class must be in module \
                :tf_main:`tf.layers <layers>`, :mod:`texar.core`, \
                or :mod:`texar.custom`.
                - A layer class.
                - An instance of a layer class.

                For example

                .. code-block:: python

                    "type": "Conv1D" # class name
                    "type": "texar.core.MaxReducePooling1D" # module path
                    "type": "my_module.MyLayer" # module path
                    "type": tf.layers.Conv2D # class
                    "type": Conv1D(filters=10, kernel_size=2) # cell instance
                    "type": MyLayer(...) # cell instance

            "kwargs" : dict
                A dictionary of keyword arguments for constructor of the
                layer class. Ignored if :attr:`"type"` is a layer instance.

                - Arguments named "activation" can be a callable, \
                or a `str` of \
                the name or module path to the activation function.
                - Arguments named "*_regularizer" and "*_initializer" \
                can be a class instance, or a `dict` of \
                hyperparameters of \
                respective regularizers and initializers. See
                - Arguments named "*_constraint" can be a callable, or a `str` \
                of the name or full path to the constraint function.

    Returns:
        A layer instance. If hparams["type"] is a layer instance, returns it
        directly.

    Raises:
        ValueError: If :attr:`hparams` is `None`.
        ValueError: If the resulting layer is not an instance of
            :tf_main:`tf.layers.Layer <layers/Layer>`.
    """
    if hparams is None:
        raise ValueError("`hparams` must not be `None`.")

    layer_type = hparams["type"]
    if not is_str(layer_type) and not isinstance(layer_type, type):
        layer = layer_type
    else:
        layer_modules = ["tensorflow.layers", "texar.core", "texar.costum"]
        layer_class = utils.check_or_get_class(layer_type, layer_modules)
        if isinstance(hparams, dict):
            default_kwargs = _layer_class_to_default_kwargs_map.get(
                layer_class, {})
            default_hparams = {"type": layer_type, "kwargs": default_kwargs}
            hparams = HParams(hparams, default_hparams)

        kwargs = {}
        for k, v in hparams.kwargs.items():
            if k.endswith('_regularizer'):
                kwargs[k] = get_regularizer(v)
            elif k.endswith('_initializer'):
                kwargs[k] = get_initializer(v)
            elif k.endswith('activation'):
                kwargs[k] = get_activation_fn(v)
            elif k.endswith('_constraint'):
                kwargs[k] = get_constraint_fn(v)
            else:
                kwargs[k] = v
        layer = utils.get_instance(layer_type, kwargs, layer_modules)

    if not isinstance(layer, tf.layers.Layer):
        raise ValueError("layer must be an instance of `tf.layers.Layer`.")

    return layer
Exemplo n.º 8
0
def get_layer(hparams):
    """Makes a layer instance.

    The layer must be an instance of :tf_main:`Layer <layers/Layer>`.

    Args:
        hparams (dict or HParams): Hyperparameters of the layer, with
            structure:

            .. code-block:: python

                {
                    "type": "LayerClass",
                    "kwargs": {
                        # Keyword arguments of the layer class
                        # ...
                    }
                }

            Here:

            "type" : str or layer instance
                Name, full path, or instance of the layer class. The
                class can be

                - Built-in layer defined in \
                  :tf_main:`tf.layers <layers>` (e.g., \
                  :tf_main:`tf.layers.Conv2D <layers/Conv2D>`), or \
                  :mod:`tx.core <texar.core>` (e.g., \
                  :class:`tx.core.MergeLayer <texar.core.MergeLayer>`)
                - User-defined layer class in :mod:`tx.custom <texar.custom>`.\
                  The class must inherit :tf_main:`Layer <layers/Layer>`.
                - External layer. If str, must provide the full path, \
                  e.g., :attr:`"my_module.MyInitializer"`.

            "kwargs" : dict
                A dictionary of arguments for constructor of the
                layer class. Ignored if :attr:`"type"` is a layer instance.

                - Arguments named "activation" can be a callable, \
                or a `str` of \
                the name or full path to the activation function. \
                - Arguments named "*_regularizer" and "*_initializer" \
                can be a class instance, or a `dict` of \
                hyperparameters of \
                respective regularizers and initializers.
                - Arguments named "*_constraint" can be a callable, or a `str` \
                of the name or full path to the constraint function. \

    Returns:
        A layer instance. If :attr:`hparams["type"]` is already a layer
        instance, returns it directly.

    Raises:
        ValueError: If :attr:`hparams` is `None`.
        ValueError: If the resulting layer is not an instance of
            :tf_main:`Layer <layers/Layer>`.
    """
    if hparams is None:
        raise ValueError("`hparams` must not be `None`.")

    layer_type = hparams["type"]
    if not is_str(layer_type):
        layer = layer_type
    else:
        layer_modules = ["tensorflow.layers", "texar.core", "texar.costum"]
        layer_class = utils.get_class(layer_type, layer_modules)
        if isinstance(hparams, dict):
            default_kwargs = _layer_class_to_default_kwargs_map.get(
                layer_class, {})
            default_hparams = {"type": layer_type, "kwargs": default_kwargs}
            hparams = HParams(hparams, default_hparams)

        kwargs = {}
        for k, v in hparams.kwargs.items():
            if k.endswith('_regularizer'):
                kwargs[k] = get_regularizer(v)
            elif k.endswith('_initializer'):
                kwargs[k] = get_initializer(v)
            elif k.endswith('activation'):
                kwargs[k] = get_activation_fn(v)
            elif k.endswith('_constraint'):
                kwargs[k] = get_constraint_fn(v)
            else:
                kwargs[k] = v
        layer = utils.get_instance(layer_type, kwargs, layer_modules)

    if not isinstance(layer, tf.layers.Layer):
        raise ValueError("layer must be an instance of `tf.layers.Layer`.")

    return layer
Exemplo n.º 9
0
def get_rnn_cell(hparams=None, mode=None):
    """Creates an RNN cell.

    See :meth:`~texar.core.layers.default_rnn_cell_hparams` for all
    hyperparameters and default values.

    Args:
        hparams (dict or HParams, optional): Cell hyperparameters. Missing
            hyperparameters are set to default values. If
            :attr:`hparams["type"]` is a cell instance (rather
            than the name or path to the cell class), then
            :attr:`hparams["num_layers"]` must be 1.
        mode (optional): A Tensor taking value in
            :tf_main:`tf.estimator.ModeKeys <estimator/ModeKeys>`, including
            `TRAIN`, `EVAL`, and `PREDICT`. If `None`, dropout will be
            controlled by :func:`texar.context.global_mode`.

    Returns:
        An instance of :tf_main:`RNNCell <contrib/rnn/RNNCell>`.

    Raises:
        ValueError: If :attr:`hparams["num_layers"]` > 1 and
            :attr:`hparams["type"]` is not of type string.
        ValueError: The cell is not an
            :tf_main:`RNNCell <contrib/rnn/RNNCell>` instance.
    """
    if hparams is None or isinstance(hparams, dict):
        hparams = HParams(hparams, default_rnn_cell_hparams())

    d_hp = hparams["dropout"]
    if d_hp["variational_recurrent"] and \
            len(d_hp["input_size"]) != hparams["num_layers"]:
        raise ValueError(
            "If variational_recurrent=True, input_size must be a list of "
            "num_layers(%d) integers. Got len(input_size)=%d." %
            (hparams["num_layers"], len(d_hp["input_size"])))

    cells = []
    cell_kwargs = hparams["kwargs"].todict()
    num_layers = hparams["num_layers"]
    for layer_i in range(num_layers):
        # Create the basic cell
        cell_type = hparams["type"]
        if is_str(cell_type):
            cell_modules = ['tensorflow.contrib.rnn', 'texar.custom']
            cell = utils.get_instance(cell_type, cell_kwargs, cell_modules)
        else:
            if num_layers > 1:
                raise ValueError(
                    "If `hparams['num_layers']`>1, then "
                    "`hparams['type']` must be a string name or path "
                    "to the class.")
            cell = cell_type
        if not isinstance(cell, rnn.RNNCell):
            raise ValueError("cell must be an instance of RNNCell.")

        # Optionally add dropout
        if d_hp["input_keep_prob"] < 1.0 or \
                d_hp["output_keep_prob"] < 1.0 or \
                d_hp["state_keep_prob"] < 1.0:
            vr_kwargs = {}
            if d_hp["variational_recurrent"]:
                vr_kwargs = {
                    "variational_recurrent": True,
                    "input_size": d_hp["input_size"][layer_i],
                    "dtype": tf.float32
                }
            input_keep_prob = switch_dropout(d_hp["input_keep_prob"], mode)
            output_keep_prob = switch_dropout(d_hp["output_keep_prob"], mode)
            state_keep_prob = switch_dropout(d_hp["state_keep_prob"], mode)
            cell = rnn.DropoutWrapper(cell=cell,
                                      input_keep_prob=input_keep_prob,
                                      output_keep_prob=output_keep_prob,
                                      state_keep_prob=state_keep_prob,
                                      **vr_kwargs)

        # Optionally add residual and highway connections
        if layer_i > 0:
            if hparams["residual"]:
                cell = rnn.ResidualWrapper(cell)
            if hparams["highway"]:
                cell = rnn.HighwayWrapper(cell)

        cells.append(cell)

    if hparams["num_layers"] > 1:
        cell = rnn.MultiRNNCell(cells)
    else:
        cell = cells[0]

    return cell
Exemplo n.º 10
0
    def _build(self,
               distribution=None,
               distribution_type='MultivariateNormalDiag',
               distribution_kwargs=None,
               transform=False,
               num_samples=None):
        """Samples from a distribution and optionally performs transformation.

        Gradients would not propagate through the random samples.

        Args:
            distribution (optional): An instance of
                :class:`~tensorflow.contrib.distributions.Distribution`. If
                `None` (default), distribution is constructed based on
                :attr:`distribution_type`
            distribution_type (str, optional): Name or path to the distribution
                class which inherits
                :class:`~tensorflow.contrib.distributions.Distribution`. Ignored
                if :attr:`distribution` is specified.
            distribution_kwargs (dict, optional): Keyword arguments of the
                distribution class specified in :attr:`distribution_type`.
            transform (bool): Whether to perform MLP transformation of the
                samples. If `False`, the shape of a sample must match the
                :attr:`output_size`.
            num_samples (int or scalar int Tensor, optional): Number of samples
                to generate. `None` is required in training stage.

        Returns:
            If `num_samples`==None, returns a Tensor of shape `[batch_size x
            output_size]`, else returns a Tensor of shape `[num_samples x
            output_size]`. `num_samples` should be specified if not in
            training stage.

        Raises:
            ValueError: The output does not match the :attr:`output_size`.
        """
        if distribution:
            dstr = distribution
        elif distribution_type and distribution_kwargs:
            dstr = get_instance(
                distribution_type, distribution_kwargs,
                ["texar.custom", "tensorflow.contrib.distributions"])

        if num_samples:
            output = dstr.sample(num_samples)
        else:
            output = dstr.sample()

        if dstr.event_shape == []:
            output = tf.reshape(output,
                                output.shape.concatenate(tf.TensorShape(1)))

        # Disable gradients through samples
        output = tf.stop_gradient(output)

        output = tf.cast(output, tf.float32)

        if transform:
            fn_modules = ['texar.custom', 'tensorflow', 'tensorflow.nn']
            activation_fn = get_function(self.hparams.activation_fn,
                                         fn_modules)
            output = _mlp_transform(output, self._output_size, activation_fn)
        _assert_same_size(output, self._output_size)

        if not self._built:
            self._add_internal_trainable_variables()
            self._built = True

        return output
Exemplo n.º 11
0
    def _build(self,
               distribution=None,
               distribution_type='MultivariateNormalDiag',
               distribution_kwargs=None,
               transform=True,
               num_samples=None):
        """Samples from a distribution and optionally performs transformation.

        The distribution must be reparameterizable, i.e.,
        `distribution.reparameterization_type = FULLY_REPARAMETERIZED`.

        Args:
            distribution (optional): An instance of
                :class:`~tensorflow.contrib.distributions.Distribution`. If
                `None` (default), distribution is constructed based on
                :attr:`distribution_type` or
                :attr:`hparams['distribution']['type']`.
            distribution_type (str, optional): Name or path to the distribution
                class which inherits
                :class:`~tensorflow.contrib.distributions.Distribution`. Ignored
                if :attr:`distribution` is specified.
            distribution_kwargs (dict, optional): Keyword arguments of the
                distribution class specified in :attr:`distribution_type`.
            transform (bool): Whether to perform MLP transformation of the
                samples. If `False`, the shape of a sample must match the
                :attr:`output_size`.
            num_samples (int or scalar int Tensor, optional): Number of samples
                to generate. `None` is required in training stage.

        Returns:
            output: If `num_samples`==None, returns a Tensor of shape
                `[batch_size x output_size]`, else returns a Tensor of shape
                `[num_samples x output_size]`. `num_samples` should be specified
                if not in training stage.
            latent_z: The latent sampled z

        Raises:
            ValueError: If distribution cannot be reparametrized.
            ValueError: The output does not match the :attr:`output_size`.
        """
        if distribution:
            dstr = distribution
        elif distribution_type and distribution_kwargs:
            dstr = get_instance(
                distribution_type, distribution_kwargs,
                ["texar.custom", "tensorflow.contrib.distributions"])

        if dstr.reparameterization_type == tf_dstr.NOT_REPARAMETERIZED:
            raise ValueError("Distribution is not reparameterized: %s" %
                             dstr.name)

        if num_samples:
            latent_z = dstr.sample(num_samples)
        else:
            latent_z = dstr.sample()

        #if dstr.event_shape == []:
        #    latent_z = tf.reshape(
        #        latent_z,
        #        latent_z.shape.concatenate(tf.TensorShape(1)))

        # latent_z = tf.cast(latent_z, tf.float32)
        if transform:
            fn_modules = ['texar.custom', 'tensorflow', 'tensorflow.nn']
            activation_fn = get_function(self.hparams.activation_fn,
                                         fn_modules)
            output = _mlp_transform(latent_z, self._output_size, activation_fn)
        _assert_same_size(output, self._output_size)

        if not self._built:
            self._add_internal_trainable_variables()
            self._built = True

        return output, latent_z