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.torch.core`, or :mod:`texar.torch.custom`. - A layer class. - An instance of a layer class. For example .. code-block:: python "type": "Conv1D" # class name "type": "texar.torch.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.torch.core", "texar.torch.custom"] layer_class: Type[nn.Module] = 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 _maybe_name_to_id(self, name_or_id): if is_str(name_or_id): if name_or_id not in self._name_to_id: raise ValueError("Unknown data name: {}".format(name_or_id)) return self._name_to_id[name_or_id] return name_or_id