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)
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)
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)
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)
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)
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)
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)