Projection

class torchhd.embeddings.Projection(in_features, out_features, vsa: Literal['BSC', 'MAP', 'HRR', 'FHRR', 'BSBC', 'VTB', 'MCR', 'CGR'] = 'MAP', requires_grad=False, device=None, dtype=None)[source]

Embedding using a random projection matrix.

Implemented based on A Theoretical Perspective on Hyperdimensional Computing. It computes \(x \Phi^{\mathsf{T}}\) where \(\Phi \in \mathbb{R}^{d \times m}\) is a matrix whose rows are uniformly sampled at random from the surface of an \(d\)-dimensional unit sphere. This encoding ensures that similarities in the input space are preserved in the hyperspace.

Parameters:
  • in_features (int) – the dimensionality of the input feature vector.

  • out_features (int) – the dimensionality of the hypervectors.

  • vsa – (VSAOptions, optional): specifies the hypervector type to be instantiated. Default: "MAP".

  • requires_grad (bool, optional) – If autograd should record operations on the returned tensor. Default: False.

  • dtype (torch.dtype, optional) – the desired data type of returned tensor. Default: if None, uses a global default (see torch.set_default_tensor_type()).

  • device (torch.device, optional) – the desired device of returned tensor. Default: if None, uses the current device for the default tensor type (see torch.set_default_tensor_type()). device will be the CPU for CPU tensor types and the current CUDA device for CUDA tensor types.

Examples:

>>> embed = embeddings.Projection(6, 5)
>>> x = torch.randn(3, 6)
>>> x
tensor([[ 0.4119, -0.4284,  1.8022,  0.3715, -1.4563, -0.2842],
        [-0.3772, -1.2664, -1.5173,  1.3317,  0.4707, -1.3362],
        [-1.8142,  0.0274, -1.0989,  0.8193,  0.7619,  0.9181]])
>>> embed(x).sign()
MAPTensor([[-1.,  1.,  1.,  1.,  1.],
           [ 1.,  1.,  1.,  1.,  1.],
           [ 1., -1., -1., -1., -1.]])
forward(input: Tensor) Tensor[source]

Define the computation performed at every call.

Should be overridden by all subclasses.

Note

Although the recipe for forward pass needs to be defined within this function, one should call the Module instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.