gluonts.mx.block.feature module#

class gluonts.mx.block.feature.FeatureAssembler(T: int, use_static_cat: bool = False, use_static_real: bool = False, use_dynamic_cat: bool = False, use_dynamic_real: bool = False, embed_static: typing.Optional[gluonts.mx.block.feature.FeatureEmbedder] = None, embed_dynamic: typing.Optional[gluonts.mx.block.feature.FeatureEmbedder] = None, dtype: typing.Type = <class 'numpy.float32'>, **kwargs)[source]#

Bases: mxnet.gluon.block.HybridBlock

Assemble features into an MXNet tensor. Input features are distinguished based on the following criteria:

  • static (time-independent) features vs dynamic (that is, time-dependent)

  • categorical vs real-valued features.

Dynamic features have shape (N, T, C) and static features have shape (N, C), where

  • N is the number of elements in the processed batch,

  • T is the time dimension,

  • C is the number of features.

If multiple feature types are used, the FeatureAssembler will assume that the N and T dimensions are the same for all passed arguments.

Categorical features can be optionally embedded using trained embedding layers via nested FeatureEmbedder components.

>>> embed_static = FeatureEmbedder(
...     cardinalities=[2],
...     embedding_dims=[3],
...     prefix='embed_static_',
... )
>>> embed_dynamic = FeatureEmbedder(
...     cardinalities=[5, 5],
...     embedding_dims=[6, 9],
...     prefix='embed_dynamic_',
... )

The above snippet with four nn.Embedding corresponding to the one static and two dynamic categorical features. The (input_dim, output_dim) of these layers are going to be (2, 3), (5, 6), and (5, 9). The created assemble_feature instance will not handle real-valued features.

The subset of feature types to be used by the FeatureAssembler instance is determined using corresponding constructor parameters. Here is an example that constructs a feature assembler consuming only real-valued features.

>>> N, T = 50, 168
>>> assemble_feature = FeatureAssembler(
...     T=T,
...     # use_static_cat=True,
...     # use_static_real=False,
...     # use_dynamic_cat=True,
...     # use_dynamic_real=False,
...     embed_static=embed_static,
...     embed_dynamic=embed_dynamic
... )

When the __call__, forward, or hybrid_forward methods of a FeatureAssembler are called, we always have to pass a full set of features. Missing features are represented as zero tensors with a suitable shape.

For example,

>>> import mxnet as mx
>>> feat_static_cat = mx.nd.random.uniform(0, 2, shape=(N, 1)).floor()
>>> feat_dynamic_cat = mx.nd.random.uniform(
    0, 5, shape=(N, 168, 2)
).floor()
>>> feat_static_real = mx.nd.zeros(shape=(N, 1,)) # empty feature
>>> feat_dynamic_real = mx.nd.zeros(shape=(N, T, 1,)) # empty feature

After initializing the embedder parameters to one and instantiating some random static_cat and dynamic_cat vectors,

>>> assemble_feature.collect_params().initialize(mx.initializer.One())

one can do a forward pass as follows.

>>> assembled_feature = assemble_feature(
    feat_static_cat, feat_static_real, feat_dynamic_cat, feat_dynamic_real
)
>>> assembled_feature.shape
(50, 168, 20)
>>>

However, relative order of static_cat and dynamic_cat in the call above is determined by the fact that use_static_cat is defined before use_dynamic_cat in the class constructor.

hybrid_forward(F, feat_static_cat: Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol], feat_static_real: Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol], feat_dynamic_cat: Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol], feat_dynamic_real: Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol]) Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol][source]#

Overrides to construct symbolic graph for this Block.

Parameters
  • x (Symbol or NDArray) – The first input tensor.

  • *args (list of Symbol or list of NDArray) – Additional input tensors.

process_dynamic_cat(F, feature: Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol]) Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol][source]#
process_dynamic_real(F, feature: Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol]) Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol][source]#
process_static_cat(F, feature: Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol]) Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol][source]#
process_static_real(F, feature: Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol]) Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol][source]#
class gluonts.mx.block.feature.FeatureEmbedder(cardinalities: typing.List[int], embedding_dims: typing.List[int], dtype: typing.Type = <class 'numpy.float32'>, **kwargs)[source]#

Bases: mxnet.gluon.block.HybridBlock

Embed a sequence of categorical features.

Parameters
  • cardinalities – cardinality for each categorical feature.

  • embedding_dims – number of dimensions to embed each categorical feature.

  • dtype – Data type of the embedded features.

hybrid_forward(F, features: Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol]) Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol][source]#
Parameters
  • F

  • features – Categorical features with shape: (N,T,C) or (N,C), where C is the number of categorical features.

Returns

concatenated_tensor – Concatenated tensor of embeddings with shape: (N,T,C) or (N,C), where C is the sum of the embedding dimensions for each categorical feature, i.e. C = sum(self.config.embedding_dims).

Return type

Tensor