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