Source code for mushroom_rl.features.tensors.random_fourier_tensor

import torch
import torch.nn as nn

from mushroom_rl.features.tensors import ConstantTensor
from mushroom_rl.utils.torch import TorchUtils

import numpy as np


[docs]class RandomFourierBasis(nn.Module): r""" Class implementing Random Fourier basis functions. The value of the feature is computed using the formula: .. math:: \sin{\dfrac{PX}{\nu}+\varphi} where :math:`X` is the input, :math:`P` is a random weights matrix, :math:`\nu` is the bandwidth parameter and :math:`\varphi` is a bias vector. These features have been presented in: "Towards generalization and simplicity in continuous control". Rajeswaran A. et Al.. 2017. """
[docs] def __init__(self, P, phi, nu): """ Constructor. Args: P (np.ndarray): weights matrix, every weight should be drawn from a normal distribution; phi (np.ndarray): bias vector, every weight should be drawn from a uniform distribution in the interval :math: `[-\pi, \pi)`; nu (float): bandwidth parameter, it should be chosen approximately as the average pairwise distances between different observation vectors. """ self._P = TorchUtils.to_float_tensor(P) self._phi = TorchUtils.to_float_tensor(phi) self._nu = nu super().__init__()
def forward(self, x): return torch.sin(x @ self._P / self._nu + self._phi) def __str__(self): return str(self._P) + ' ' + str(self._phi)
[docs] @staticmethod def generate(nu, n_output, input_size, use_bias=True): """ Factory method to build random fourier basis. Includes a constant tensor into the output. Args: nu (float): bandwidth parameter, it should be chosen approximately as the average pairwise distances between different observation vectors. n_output (int): number of basis to use; input_size (int): size of the input. Returns: The list of the generated fourier basis functions. """ if use_bias: n_output -= 1 P = np.random.randn(input_size, n_output) phi = np.random.uniform(-np.pi, np.pi, n_output) tensor_list = [RandomFourierBasis(P, phi, nu)] if use_bias: tensor_list.append(ConstantTensor()) return tensor_list
@property def size(self): return self._phi.shape[0]