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
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 = []
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
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())
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
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
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
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
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
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