コード例 #1
0
    def __init__(self,
                 in_channels,
                 hidden_channels1,
                 hidden_channels2,
                 kernel_size,
                 include_original,
                 include_time,
                 sig_depth,
                 out_channels,
                 batch_norm=False):
        """
        Inputs:
            in_channels: As SignatureModel.
            hidden_channels1: How large to make certain hidden channels within the model.
            hidden_channels2: How large to make certain hidden channels within the model.
            kernel_size: How far to look back in time.
            include_original: As SignatureModel.
            include_time: As SignatureModel.
            sig_depth: As SignatureModel.
            out_channels: As SignatureModel.
        """
        super().__init__()
        self.kernel_size = kernel_size
        self.batch_norm = batch_norm
        self.padding1 = torch.nn.ConstantPad1d((kernel_size - 1, 0), 0)
        self.augment1 = signatory.Augment(in_channels=in_channels,
                                          layer_sizes=(hidden_channels1,
                                                       hidden_channels1,
                                                       hidden_channels2),
                                          kernel_size=kernel_size,
                                          include_original=include_original,
                                          include_time=include_time)
        self.signature1 = signatory.Signature(depth=sig_depth, stream=True)

        sig_hidden_channels = hidden_channels2
        if include_original:
            sig_hidden_channels += in_channels
        if include_time:
            sig_hidden_channels += 1
        sig_channels1 = signatory.signature_channels(
            channels=sig_hidden_channels, depth=sig_depth)
        self.padding2 = torch.nn.ConstantPad1d((kernel_size - 1, 0), 0)
        self.augment2 = signatory.Augment(in_channels=sig_channels1,
                                          layer_sizes=(hidden_channels1,
                                                       hidden_channels1,
                                                       hidden_channels2),
                                          kernel_size=kernel_size,
                                          include_original=False,
                                          include_time=False)
        self.signature2 = signatory.Signature(depth=sig_depth, stream=False)

        sig_channels2 = signatory.signature_channels(channels=hidden_channels2,
                                                     depth=sig_depth)
        self.linear = torch.nn.Linear(sig_channels2, out_channels)

        if self.batch_norm:
            self.bn1 = nn.BatchNorm1d(num_features=sig_channels1)
            self.bn2 = nn.BatchNorm1d(num_features=sig_channels2)
コード例 #2
0
def setup(obj):
    torch.set_num_threads(1)

    obj.path = torch.rand(obj.size, dtype=torch.float, requires_grad=True)
    shape = obj.size[-3], signatory.signature_channels(obj.size[-1], obj.depth)
    obj.grad = torch.rand(shape)
    obj.signature = signatory.signature(obj.path, obj.depth)
コード例 #3
0
def _rescale_signature(signature, channels, depth, length, by_length=False):
    sigtensor_channels = signature.size(-1)
    if signatory.signature_channels(channels, depth) != sigtensor_channels:
        raise ValueError(
            "Given a sigtensor with {} channels, a path with {} channels and a depth of {}, which are "
            "not consistent.".format(sigtensor_channels, channels, depth))

    if by_length:
        length_reciprocal = length.reciprocal()
        for i in range(len(signature.shape) - len(length.shape)):
            length_reciprocal.unsqueeze_(-1)

    end = 0
    term_length = 1
    val = 1
    terms = []
    for d in range(1, depth + 1):
        start = end
        term_length *= channels
        end = start + term_length

        val *= d
        if by_length:
            val *= length_reciprocal

        terms.append(signature[..., start:end] * val)

    return torch.cat(terms, dim=-1)
コード例 #4
0
 def __init__(self, in_channels, out_dimension, sig_depth):
     super(SigNet, self).__init__()
     self.augment = signatory.Augment(in_channels=in_channels,
                                      layer_sizes=(),
                                      kernel_size=1,
                                      include_original=True,
                                      include_time=True)
     self.signature = signatory.Signature(depth=sig_depth)
     # +1 because signatory.Augment is used to add time as well
     sig_channels = signatory.signature_channels(channels=in_channels + 1,
                                                 depth=sig_depth)
     self.linear = torch.nn.Linear(sig_channels, out_dimension)
コード例 #5
0
def X_limit(N, depth, time):
    """Returns limiting rough path in p-var top for the pure area path problem (with signatory)"""
    X_inf = torch.zeros((1, N, signatory.signature_channels(2,
                                                            depth)))  #.cuda()
    for k in range(N):
        X_inf[0, k, 0] = 0.
        X_inf[0, k, 1] = 0.
        X_inf[0, k, 2] = 0.
        X_inf[0, k, 3] = time[k]
        X_inf[0, k, 4] = -time[k]
        X_inf[0, k, 5] = 0.
    return signatory.Path(X_inf, 1, basepoint=True)
コード例 #6
0
ファイル: example3.py プロジェクト: zeta1999/signatory
    def __init__(self, in_channels, out_dimension, sig_depth):
        super(SigNet3, self).__init__()
        self.augment1 = signatory.Augment(in_channels=in_channels,
                                          layer_sizes=(8, 8, 4),
                                          kernel_size=4,
                                          include_original=True,
                                          include_time=True)
        self.signature1 = signatory.Signature(depth=sig_depth, stream=True)

        # +5 because self.augment1 is used to add time, and 4 other
        # channels, as well
        sig_channels1 = signatory.signature_channels(channels=in_channels + 5,
                                                     depth=sig_depth)
        self.augment2 = signatory.Augment(in_channels=sig_channels1,
                                          layer_sizes=(8, 8, 4),
                                          kernel_size=4,
                                          include_original=False,
                                          include_time=False)
        self.signature2 = signatory.Signature(depth=sig_depth, stream=False)

        # 4 because that's the final layer size in self.augment2
        sig_channels2 = signatory.signature_channels(channels=4,
                                                     depth=sig_depth)
        self.linear = torch.nn.Linear(sig_channels2, out_dimension)
コード例 #7
0
    def __init__(self, input_dim, depth, logsig, basepoint=True):
        super().__init__()

        self.basepoint = basepoint
        self.depth = depth
        self.logsig = logsig
        self.sig_func = signatory.logsignature if self.logsig else signatory.signature
        self.terms = signatory.logsignature_channels(
            input_dim,
            self.depth) if self.logsig else signatory.signature_channels(
                input_dim, self.depth)
        if self.terms >= TERMS_LIMIT:
            raise ImportError(
                "Number of signature terms {} is greater than {}..".format(
                    self.terms, TERMS_LIMIT))
コード例 #8
0
ファイル: DST.py プロジェクト: MLforHealth/rl_representations
    def __init__(self, input_dim, latent_dim, gru_n_layers = 2, augment_chs = 8):
        super().__init__()
        self.latent_dim = latent_dim
        self.augment1 = signatory.Augment(in_channels=input_dim,
                          layer_sizes=(32, augment_chs),
                          kernel_size=1,
                          include_original=True,
                          include_time=True)

        self.signature1 = signatory.Signature(depth=2,
                             stream=True)

        sig_channels1 = signatory.signature_channels(channels=input_dim + augment_chs + 1,
                                              depth=2)

        self.gru = nn.GRU(input_size = sig_channels1, hidden_size = latent_dim, num_layers = gru_n_layers, batch_first = True)
コード例 #9
0
ファイル: bsde.py プロジェクト: msabvid/Deep-PPDE
    def __init__(self, d: int, mu: float, depth: int, rnn_hidden: int,
                 ffn_hidden: List[int]):
        super().__init__()
        self.d = d
        self.mu = mu  # risk free rate

        self.depth = depth
        self.augmentations = (LeadLag(with_time=False), )
        self.sig_channels = signatory.signature_channels(
            channels=2 * d, depth=depth)  # x2 because we do lead-lag
        self.f = RNN(rnn_in=self.sig_channels + 1,
                     rnn_hidden=rnn_hidden,
                     ffn_sizes=ffn_hidden + [1])  # +1 is for time
        self.dfdx = RNN(rnn_in=self.sig_channels + 1,
                        rnn_hidden=rnn_hidden,
                        ffn_sizes=ffn_hidden + [d])  # +1 is for time
コード例 #10
0
def invert_signature(signature, depth, channels, initial_position=None):
    """Reconstruct the path from its signature

    Arguments:
        signature: torch.Tensor, shape (batch, channels + channels^2 + ... + channels^depth)
            Batch of signatures truncated at order depth: output of signatory.signature(path, depth), where path is a
            tensor of shape (batch, length, channels)

        depth: int
            Depth of the signature.
        
        channels: int
            The number of channels of the paths that were used to compute signature.

        initial_position: optional, torch.Tensor, shape (batch, channels)
            Initial point of the paths. If None, the reconstructed paths are set to begin at zero.

    Returns:
        path: torch.Tensor, shape (batch, depth+1, channels)
            Batch of inverted paths.
    """
    if signatory.signature_channels(channels, depth) != signature.shape[1]:
        raise ValueError(
            "channels and depth do not correspond to signature shape.")

    batch = signature.shape[0]
    path_derivatives = torch.zeros((batch, depth, channels))
    path = torch.zeros((batch, depth + 1, channels))

    if initial_position is not None:
        path[:, 0, :] = initial_position

    if depth == 1:
        path[:, 1, :] = path[:, 0, :] + signature
    else:
        for insertion_position in torch.arange(1, depth + 1):
            x_optimal = solve_optimization_problem(signature,
                                                   insertion_position, depth,
                                                   channels)
            path_derivatives[:, insertion_position - 1, :] = x_optimal
            path[:, insertion_position, :] = (
                path[:, insertion_position - 1, :] +
                path_derivatives[:, insertion_position - 1, :] * (1 / depth))

    return path
コード例 #11
0
    def transform(self, sequence) -> torch.Tensor:
        embedded = sequence['embedded']

        sig_func = signatory.logsignature if self.logsig else signatory.signature

        terms = signatory.logsignature_channels(
            embedded.shape[-1],
            self.depth) if self.logsig else signatory.signature_channels(
                embedded.shape[-1], self.depth)
        if terms >= TERMS_LIMIT:
            raise ImportError(
                "Number of signature terms is greater than {}..".format(
                    TERMS_LIMIT))

        signature_terms = sig_func(path=embedded,
                                   depth=self.depth,
                                   basepoint=self.basepoint)
        return signature_terms
コード例 #12
0
ファイル: DST.py プロジェクト: MLforHealth/rl_representations
    def __init__(self, latent_dim, output_dim, decoder_hidden_units = 64):
        super().__init__()
        self.latent_dim = latent_dim
        self.decoder_hidden_units = decoder_hidden_units
        self.augment2 = signatory.Augment(in_channels=latent_dim,
                                  layer_sizes=(64, 32),
                                  kernel_size=1,
                                  include_original=False,
                                  include_time=False)

        self.signature2 = signatory.Signature(depth=2,
                             stream=True)

        sig_channels2 = signatory.signature_channels(channels= 32,
                                              depth=2)
        
        self.linear1 = nn.Linear(in_features = sig_channels2, out_features = decoder_hidden_units)
        self.linear2 = nn.Linear(in_features = decoder_hidden_units, out_features = output_dim)
コード例 #13
0
    def __init__(self, in_channels, extra_channels, channel_groups,
                 include_original, include_time, sig_depth, out_channels,
                 final_network):
        """
        Inputs:
            in_channels: An integer specifying the number of input channels in the data.
            extra_channels: How many channels to learn before the signature. Can be set to 0 to not learn any extra
                channels.
            channel_groups: We compute the signature on channel_groups many paths. Note that this is only worth setting
                to something other than 1 if extra_channels is nonzero.
            include_original: Whether to pass the original data to the signature. If True then the original data and the
                extra learnt channels will be concatenated. (So you probably want True if the number of channels in the
                original data is small). If False then the original data will not be included (so you probably want
                False if the number of channels in the original data is large - then you get just the learnt channels.)
            include_time: Whether to include a time parameter in the augmentation. You probably want to set this to
                True.
            sig_depth: What depth of signature to calculate. Careful - you'll get exponentially many more parameters as
                this number is increased. Reducing the value of extra_channels or toggling off include_original will
                also help reduce the number of parameters.
            out_channels: How many channels to output.
            final_network: What kind of network to use on the result of the signature. Should be a tuple or scalars,
                representing the sizes of hidden layers in a small feedforward neural network. ReLU nonlinearities will
                be placed in between. For example, an empty tuple represents no hidden layers; i.e. just a linear map.

        Examples:
            extra_channels=0, include_original=True, channel_groups=1:
                This corresponds to shallow signature models, without any learnt transformation before the signature.

            extra_channels=10, incldue_original=False:
                This corresponds to the simplest possible deep signature model, just learning a simple transformation
                before the signature.
        """

        super().__init__()

        self.channel_groups = channel_groups
        self.sig_depth = sig_depth

        layer_sizes = () if extra_channels == 0 else (extra_channels, )
        self.augments = nn.ModuleList(
            signatory.Augment(
                in_channels=in_channels,
                layer_sizes=layer_sizes,
                # IMPORTANT. We rely on kernel_size=1 to make trick for handling
                # variable-length inputs work.
                kernel_size=1,
                include_original=include_original,
                include_time=include_time) for _ in range(channel_groups))

        in_sig_channels = extra_channels
        if include_original:
            in_sig_channels += in_channels
        if include_time:
            in_sig_channels += 1
        sig_channels = signatory.signature_channels(in_sig_channels, sig_depth)
        sig_channels *= channel_groups

        layers = []
        prev_size = sig_channels
        for size in final_network:
            layers.append(nn.Linear(prev_size, size))
            layers.append(nn.ReLU())
            prev_size = size
        layers.append(nn.Linear(prev_size, out_channels))
        self.neural = nn.Sequential(*layers)
コード例 #14
0
    def __init__(self, in_channels, extra_channels, channel_groups,
                 include_original, include_time, sig_depth, step, length,
                 rnn_channels, out_channels, rnn_type):
        """
        Inputs:
            in_channels: As SignatureModel.
            extra_channels: As SignatureModel.
            channel_groups: As SignatureModel.
            include_original: As SignatureModel.
            include_time: As SignatureModel.
            sig_depth: As SignatureModel.
            step: The number of indices to move the sliding window forward by.
            length: The length of the sliding window that a signature is taken over.
            rnn_channels: The size of the hidden state of the GRU.
            out_channels: As SignatureModel.
            rnn_type: Either 'gru' or 'lstm'.

        Note:
            Unless step, length, and the length of the input stream all suitably line up, then the final pieces of data
            in the input stream may not end up being used, because the next sliding window would go 'off the end' of the
            data.
            This can be avoided by setting the parameters appropriately, e.g. by taking step=1.
        """

        super().__init__()

        self.channel_groups = channel_groups
        self.sig_depth = sig_depth
        self.step = step
        self.length = length
        self.rnn_channels = rnn_channels
        self.out_channels = out_channels
        self.rnn_type = rnn_type

        layer_sizes = () if extra_channels == 0 else (extra_channels, )
        self.augments = nn.ModuleList(
            signatory.Augment(
                in_channels=in_channels,
                layer_sizes=layer_sizes,
                # IMPORTANT. We rely on kernel_size=1 to make trick for handling
                # variable-length inputs work.
                kernel_size=1,
                include_original=include_original,
                include_time=include_time) for _ in range(channel_groups))

        in_sig_channels = extra_channels
        if include_original:
            in_sig_channels += in_channels
        if include_time:
            in_sig_channels += 1
        sig_channels = signatory.signature_channels(in_sig_channels, sig_depth)
        sig_channels *= channel_groups
        if rnn_type == 'gru':
            self.rnn_cell = nn.GRUCell(sig_channels, rnn_channels)
        elif rnn_type == 'lstm':
            self.rnn_cell = nn.LSTMCell(sig_channels, rnn_channels)
        else:
            raise ValueError(
                'rnn_type of value "{}" not understood'.format(rnn_type))

        self.linear = nn.Linear(rnn_channels, out_channels)