def get_reconstruction(self,
                           time_steps_to_predict,
                           data,
                           truth_time_steps,
                           mask=None,
                           n_traj_samples=None,
                           mode=None,
                           save_info=False):

        if (len(truth_time_steps) != len(time_steps_to_predict)) or (
                torch.sum(time_steps_to_predict - truth_time_steps) != 0):
            raise Exception("Extrapolation mode not implemented for ODE-RNN")

        # time_steps_to_predict and truth_time_steps should be the same
        assert (len(truth_time_steps) == len(time_steps_to_predict))
        assert (mask is not None)

        data_and_mask = data
        if mask is not None:
            data_and_mask = torch.cat([data, mask], -1)

        _, latent_ys, tuple_sol, ode_info = self.ode_gru.run_odernn(
            data_and_mask,
            truth_time_steps,
            run_backwards=False,
            save_info=save_info)

        # reverse
        #context_vector = utils.reverse_dim1(context_vector)
        context_vector = tuple_sol[1] / tuple_sol[0]

        latent_ys = latent_ys.permute(0, 2, 1,
                                      3)  # permute to (n_traj, n_tp, n_dims)
        last_hidden = latent_ys[:, :, -1, :]

        #print("latent_ys", latent_ys.shape)
        #print("context_vector", context_vector.shape)

        context_vector = context_vector + latent_ys
        #assert(torch.sum(int_lambda[0,0,-1,:] <= 0) == 0.)

        outputs = self.decoder(context_vector)
        # Shift outputs for computing the loss -- we should compare the first output to the second data point, etc.
        first_point = data[:, 0, :]
        outputs = utils.shift_outputs(outputs, first_point)

        #extra_info = {"first_point": (latent_ys[:,:,-1,:], 0.0, latent_ys[:,:,-1,:])}
        extra_info = {"ode_info": ode_info}

        if self.use_binary_classif:
            if self.classif_per_tp:
                extra_info["label_predictions"] = self.classifier(
                    context_vector)
            else:
                extra_info["label_predictions"] = self.classifier(
                    last_hidden).squeeze(-1)

        # outputs shape: [n_traj, n_tp, n_dims]
        return outputs, extra_info
Example #2
0
    def get_reconstruction(self,
                           time_steps_to_predict,
                           data,
                           truth_time_steps,
                           mask=None,
                           n_traj_samples=None,
                           mode=None,
                           save_latents=0):

        if (len(truth_time_steps) != len(time_steps_to_predict)) or (
                torch.sum(time_steps_to_predict - truth_time_steps) != 0):
            raise Exception("Extrapolation mode not implemented for ODE-RNN")

        # time_steps_to_predict and truth_time_steps should be the same
        assert (len(truth_time_steps) == len(time_steps_to_predict))
        assert (mask is not None)

        data_and_mask = data
        if mask is not None:
            data_and_mask = torch.cat([data, mask], -1)

        _, _, latent_ys, _ = self.ode_gru.run_odernn(data_and_mask,
                                                     truth_time_steps,
                                                     run_backwards=False)

        latent_ys = latent_ys.permute(0, 2, 1, 3)
        last_hidden = latent_ys[:, :, -1, :]

        #assert(torch.sum(int_lambda[0,0,-1,:] <= 0) == 0.)

        # do not calculate it, because we don't use it anymore
        #outputs = self.decoder(latent_ys)
        outputs = torch.zeros_like(data_and_mask)[
            None, :, :][:, :, :, :data_and_mask.shape[-1] // 2]
        # Shift outputs for computing the loss -- we should compare the first output to the second data point, etc.
        first_point = data[:, 0, :]
        outputs = utils.shift_outputs(outputs, first_point)

        extra_info = {
            "first_point": (latent_ys[:, :, -1, :], 0.0, latent_ys[:, :,
                                                                   -1, :])
        }

        if self.use_binary_classif:
            if self.classif_per_tp:
                extra_info["label_predictions"] = self.classifier(latent_ys)
            else:
                extra_info["label_predictions"] = self.classifier(
                    last_hidden).squeeze(-1)

        # outputs shape: [n_traj_samples, n_traj, n_tp, n_dims]
        return outputs, extra_info
    def get_reconstruction(self,
                           time_steps_to_predict,
                           data,
                           truth_time_steps,
                           mask=None,
                           n_traj_samples=None,
                           mode=None):

        if (len(truth_time_steps) != len(time_steps_to_predict)) or (
                torch.sum(time_steps_to_predict - truth_time_steps) != 0):
            raise Exception("Extrapolation mode not implemented for ODE-RNN")

        # time_steps_to_predict and truth_time_steps should be the same
        assert (len(truth_time_steps) == len(time_steps_to_predict))
        assert (mask is not None)

        data_and_mask = data
        if mask is not None:
            data_and_mask = torch.cat([data, mask], -1)

        _, _, latent_ys, ode_info = self.ode_gru.run_odernn(
            data_and_mask, truth_time_steps, run_backwards=False)

        latent_ys = latent_ys.permute(0, 2, 1, 3)
        last_hidden = latent_ys[:, :, -1, :]

        outputs = latent_ys
        if self.att:
            latent_ys, attScore = utils.run_attention(latent_ys)

        if self.train_classif_w_reconstr:
            outputs = self.decoder(latent_ys)
            # Shift outputs for computing the loss -- we should compare the first output to the second data point, etc.
            first_point = data[:, 0, :]
            outputs = utils.shift_outputs(outputs, first_point)

        extra_info = {"ode_info": ode_info}

        if self.use_binary_classif:
            if self.classif_per_tp:
                extra_info["label_predictions"] = self.classifier(latent_ys)
            else:
                extra_info["label_predictions"] = self.classifier(
                    last_hidden).squeeze(-1)

        # outputs shape: [n_traj_samples, n_traj, n_tp, n_dims]
        return outputs, extra_info
    def get_reconstruction(self,
                           time_steps_to_predict,
                           data,
                           truth_time_steps,
                           mask=None,
                           n_traj_samples=1,
                           mode=None):

        assert (mask is not None)

        batch_size = data.size(0)
        zero_delta_t = torch.Tensor([0.]).to(self.device)

        # run encoder backwards
        run_backwards = bool(time_steps_to_predict[0] < truth_time_steps[-1])

        if run_backwards:
            # Look at data in the reverse order: from later points to the first
            data = utils.reverse(data)
            mask = utils.reverse(mask)

        delta_ts = truth_time_steps[1:] - truth_time_steps[:-1]
        if run_backwards:
            # we are going backwards in time
            delta_ts = utils.reverse(delta_ts)

        delta_ts = torch.cat((delta_ts, zero_delta_t))
        if len(delta_ts.size()) == 1:
            # delta_ts are shared for all trajectories in a batch
            assert (data.size(1) == delta_ts.size(0))
            delta_ts = delta_ts.unsqueeze(-1).repeat((batch_size, 1, 1))

        input_decay_params = None
        if self.input_space_decay:
            input_decay_params = (self.w_input_decay, self.b_input_decay)

        hidden_state, _ = run_rnn(data,
                                  delta_ts,
                                  cell=self.rnn_cell_enc,
                                  mask=mask,
                                  input_decay_params=input_decay_params)

        z0_mean, z0_std = utils.split_last_dim(self.z0_net(hidden_state))
        z0_std = z0_std.abs()
        z0_sample = utils.sample_standard_gaussian(z0_mean, z0_std)

        # Decoder # # # # # # # # # # # # # # # # # # # #
        delta_ts = torch.cat(
            (zero_delta_t,
             time_steps_to_predict[1:] - time_steps_to_predict[:-1]))
        if len(delta_ts.size()) == 1:
            delta_ts = delta_ts.unsqueeze(-1).repeat((batch_size, 1, 1))

        _, all_hiddens = run_rnn(data,
                                 delta_ts,
                                 cell=self.rnn_cell_dec,
                                 first_hidden=z0_sample,
                                 feed_previous=True,
                                 n_steps=time_steps_to_predict.size(0),
                                 decoder=self.decoder,
                                 input_decay_params=input_decay_params)

        outputs = self.decoder(all_hiddens)
        # Shift outputs for computing the loss -- we should compare the first output to the second data point, etc.
        first_point = data[:, 0, :]
        outputs = utils.shift_outputs(outputs, first_point)

        extra_info = {
            "first_point":
            (z0_mean.unsqueeze(0), z0_std.unsqueeze(0), z0_sample.unsqueeze(0))
        }

        if self.use_binary_classif:
            if self.classif_per_tp:
                extra_info["label_predictions"] = self.classifier(all_hiddens)
            else:
                extra_info["label_predictions"] = self.classifier(
                    z0_mean).reshape(1, -1)

        # outputs shape: [n_traj_samples, n_traj, n_tp, n_dims]
        return outputs, extra_info
    def get_reconstruction(self,
                           time_steps_to_predict,
                           data,
                           truth_time_steps,
                           mask=None,
                           n_traj_samples=1,
                           mode=None):

        assert (mask is not None)
        n_traj, n_tp, n_dims = data.size()

        if (len(truth_time_steps) != len(time_steps_to_predict)) or (
                torch.sum(time_steps_to_predict - truth_time_steps) != 0):
            raise Exception(
                "Extrapolation mode not implemented for RNN models")

        # for classic RNN time_steps_to_predict should be the same as  truth_time_steps
        assert (len(truth_time_steps) == len(time_steps_to_predict))

        batch_size = data.size(0)
        zero_delta_t = torch.Tensor([0.]).to(self.device)

        delta_ts = truth_time_steps[1:] - truth_time_steps[:-1]
        delta_ts = torch.cat((delta_ts, zero_delta_t))
        if len(delta_ts.size()) == 1:
            # delta_ts are shared for all trajectories in a batch
            assert (data.size(1) == delta_ts.size(0))
            delta_ts = delta_ts.unsqueeze(-1).repeat((batch_size, 1, 1))

        input_decay_params = None
        if self.input_space_decay:
            input_decay_params = (self.w_input_decay, self.b_input_decay)

        if mask is not None:
            utils.check_mask(data, mask)

        hidden_state, all_hiddens = run_rnn(
            data,
            delta_ts,
            cell=self.rnn_cell,
            mask=mask,
            input_decay_params=input_decay_params,
            feed_previous_w_prob=(0. if self.use_binary_classif else 0.5),
            decoder=self.decoder)

        outputs = self.decoder(all_hiddens)
        # Shift outputs for computing the loss -- we should compare the first output to the second data point, etc.
        first_point = data[:, 0, :]
        outputs = utils.shift_outputs(outputs, first_point)

        extra_info = {
            "first_point":
            (hidden_state.unsqueeze(0), 0.0, hidden_state.unsqueeze(0))
        }

        if self.use_binary_classif:
            if self.classif_per_tp:
                extra_info["label_predictions"] = self.classifier(all_hiddens)
            else:
                extra_info["label_predictions"] = self.classifier(
                    hidden_state).reshape(1, -1)

        # outputs shape: [n_traj_samples, n_traj, n_tp, n_dims]
        return outputs, extra_info
Example #6
0
    def get_reconstruction(self,
                           time_steps_to_predict,
                           data,
                           truth_time_steps,
                           mask=None,
                           n_traj_samples=None,
                           mode=None,
                           testing=False):

        if (len(truth_time_steps) != len(time_steps_to_predict)) or (
                torch.sum(time_steps_to_predict - truth_time_steps) != 0):
            raise Exception("Extrapolation mode not implemented for ODE-RNN")

        # time_steps_to_predict and truth_time_steps should be the same
        assert (len(truth_time_steps) == len(time_steps_to_predict))
        assert (mask is not None)

        data_and_mask = data
        if mask is not None:
            data_and_mask = torch.cat([data, mask], -1)

        All_latent_ys = []
        All_latent_extra_info = []
        first_layer = True

        n_traj, n_tp, n_dims = data_and_mask.size()

        # run for every layer
        for s in range(self.stacking):

            if first_layer:

                # if it is the first RNN-layer, transform the dimensionality of the input down using the topper NN
                if self.include_topper:
                    pure_data = data_and_mask[:, :, :self.input_dim]
                    mask2 = torch.sum(data_and_mask[:, :,
                                                    self.input_dim:].bool(),
                                      dim=2).nonzero()

                    # create tensor of topperoutput, and fill in the corresponding locations
                    data_topped = torch.zeros(n_traj, n_tp,
                                              self.latent_dim).to(self.device)
                    if self.use_BN:
                        data_topped[mask2[:, 0], mask2[:, 1]] = self.topper_bn(
                            self.topper(pure_data[mask2[:, 0], mask2[:, 1]]))
                    else:
                        data_topped[mask2[:, 0], mask2[:, 1]] = self.topper(
                            pure_data[mask2[:, 0], mask2[:, 1]])

                    # create mask with the new size
                    new_mask = data_and_mask[:, :, self.
                                             input_dim:][:, :,
                                                         0][:, :, None].repeat(
                                                             1, 1,
                                                             self.latent_dim)

                    #replace the data_and_mask
                    data_and_mask = torch.cat([data_topped, new_mask], -1)

                input_sequence = data_and_mask

                first_layer = False
            else:
                new_latent = latent_ys[0, :, :, :]
                latent_dim = new_latent.shape[-1]
                latent_mask = mask[:, :,
                                   0].unsqueeze(2).repeat(1, 1, latent_dim)

                #destroy latent trajectoy informations that are not observed.
                new_latent[~latent_mask.bool()] = 0

                input_sequence = torch.cat([new_latent, latent_mask], -1)

            # run one trajectory of ODE-RNN for every stacking-layer "s"
            _, _, latent_ys, latent_extra_info = self.ode_gru[s].run_odernn(
                input_sequence,
                truth_time_steps,
                run_backwards=False,
                testing=testing)

            latent_ys = latent_ys.permute(0, 2, 1, 3)

            # add the output as a residual, if it is a ResNet
            if self.resnet:
                latent_ys = latent_ys + input_sequence.unsqueeze(
                    0)[:, :, :, :self.latent_dim]

            All_latent_ys.append(latent_ys)
            All_latent_extra_info.append(latent_extra_info)

        # get the last hidden state of the last latent ode-rnn trajectory
        last_hidden = All_latent_ys[-1][:, :, -1, :]

        # do not calculate it, because we don't use it anymore
        #outputs = self.decoder(latent_ys)
        outputs = torch.zeros_like(data)[None, :, :]
        # Shift outputs for computing the loss -- we should compare the first output to the second data point, etc.
        first_point = data[:, 0, :]

        outputs = utils.shift_outputs(outputs, first_point)

        extra_info = {
            "first_point":
            (All_latent_ys[-1][:, :, -1, :], 0.0, All_latent_ys[-1][:, :,
                                                                    -1, :])
        }

        if self.use_binary_classif:
            if self.classif_per_tp:
                extra_info["label_predictions"] = self.classifier(latent_ys)
            else:
                if self.use_BN:
                    last_hidden = self.bn_lasthidden(
                        last_hidden.squeeze()).unsqueeze(0)
                extra_info["label_predictions"] = self.classifier(
                    last_hidden).squeeze(-1)

        # outputs shape: [n_traj_samples, n_traj, n_tp, n_dims]
        return outputs, extra_info, All_latent_extra_info