shchur / ifl-tpp

Implementation of "Intensity-Free Learning of Temporal Point Processes" (Spotlight @ ICLR 2020)
https://openreview.net/forum?id=HygOjhEYDH
MIT License
80 stars 31 forks source link

How could I get the predicted results? #6

Closed Ying-Kang closed 2 years ago

Ying-Kang commented 4 years ago

This repo hightlights me a lot

However, I focus more on the predicted results In my work.

It's hard for me to understand your implementation datails to deduct the predict results as I just step into the area for few months.

Could you please tell me how to get the predicted results based on your code?

I'd appreciated it if you can help .

Thanks any way

shchur commented 4 years ago

Hi, please have a look at #3 and #5.

shchur commented 4 years ago

Please have a look at my answer https://github.com/shchur/ifl-tpp/issues/5#issuecomment-640561771

KristenMoore commented 4 years ago

@Kouin - did you figure it out? I'm trying to do the same.

shchur commented 4 years ago

I provided the code for generating predictions in the thread for another issue https://github.com/shchur/ifl-tpp/issues/5#issuecomment-640561771 and it seems to work for the original poster there

KristenMoore commented 4 years ago

Thanks, I was thrown off by the comment in #3 (comment) about the step() function in RNNLayer being needed when generating new sequences. Has it been used in #5 (comment)?

shchur commented 4 years ago

I'm not sure if I understand what exactly you want to do. Can you describe it in more detail?

If you want to sample new trajectories from the TPP, you will need to use RNNLayer.step. At each step you will sample the next inter-event time \tau_{i} from p(\tau_i | History_i) and feed it into the RNN to obtain the parameters for p(\tau_{i+1} | History_{i+1}).

If you want to get the predictions one step into the future (i.e. you want to compute the expected time until the next event \mathbb{E}[\tau_i | \History_i]) you should use the code from #5 that I referenced. The code that I wrote there computes the expected time until the next event for all events in the batch. You can use it to, for example, compute the mean squared error or mean absolute error in the event time prediction task.

KristenMoore commented 4 years ago

Thanks a lot for the explanation - I want to do the former. I'll follow these directions.

shchur commented 4 years ago

One more important detail: make sure that you apply the relevant transformations to the samples before feeding them into the RNN. Under default settings, we transform the RNN input in_times by applying logarithm (code), and also additionally normalize the values to have zero mean and unit standard deviation (code) using the statistics of the training set.

KristenMoore commented 4 years ago

Thanks a lot!

cjchristopher commented 4 years ago

Hi @shchur - apologies if this is a silly question! Just on the above instructions for sampling new trajectories with RNNLayer.step - is the suggestion that this would be done as model.rnn.step() in a sampling loop? I'm running into problems trying to do this correctly after training the model as per your example in the interactive notebook. We're interested in sampling new trajectories from i=0, or extending one of the input samples. Any assistance getting us on the right track is appreciated!

dl_train = torch.utils.data.DataLoader(d_train, batch_size=1, shuffle=False, collate_fn=collate)
for x in dl_train:
    break
y, h = model.rnn.step(x, model.rnn(x))
shchur commented 4 years ago

Hi @cjchristopher, here is my implementation of sampling for entire trajectories

next_in_time = torch.zeros(1, 1, 1)
h = torch.zeros(1, 1, history_size)
inter_times = []
t_max = 1000
with torch.no_grad():
    while sum(inter_times) < t_max:
        _, h = model.rnn.step(next_in_time, h)
        tau = model.decoder.sample(1, h)
        inter_times.append(tau.item())
        next_in_time = ((tau + 1e-8).log() - mean_in_train) / std_in_train
avs123 commented 4 years ago

Hi @shchur, thanks for sharing the code. I need your clarification on how you denormalize the sample generated. The transformation you applied [next_in_time = ((tau + 1e-8).log() - mean_in_train) / std_in_train] doesn't seem to work as my input has discrete integer times and outputs generated are fractional. Please assist by providing possible de-normalization code that works on your model. Thanks :)

shchur commented 4 years ago

Hi @avs123, do I understand it correctly that you want the model to generate discrete inter-event times? This is currently not supported, as the model is learning a continuous probability distribution for the inter-event times, so the sampled inter-event times tau will all be continuous. A potential hacky solution is to discretize the inter-event times after they are sampled with torch.ceil(tau).

avs123 commented 4 years ago

Thanks for responding on time @shchur. Can you please confirm that is the generated tau the actual inter-event time or do we need to apply some transformation to get it in the time space as is the input sequence? Anything to nullify the effect of log and normalisation transformation that is being applied to the input. Please elaborate.

shchur commented 4 years ago

The transformations applied to the RNN input are not related to the transformations applied to the output, so tau should already be the correct inter-event time.

KristenMoore commented 3 years ago

Thanks for the refactored code, @shchur . To sample in the new framework, do I just need to implement sampling from inter_time_dist?

features = self.get_features(batch)  
context = self.get_context(features)   
inter_time_dist = self.get_inter_time_dist(context)

Any tips would be appreciated. Thanks.

shchur commented 3 years ago

Hey @KristenMoore, I have just implemented sampling for the new code. I checked it on a few datasets (see interactive.ipynb) and it seems that the generated sequences look fine. I haven't tested it on marked sequences, though. The code seems simple enough, so I hope that there are no mistakes, but let me know if anything seems odd.

I also realized that there was a very serious bug that I introduced while refactoring. The slicing for context embedding was off-by-one, which means that the model was peeking into the future. This is fixed by the last commit.

KristenMoore commented 3 years ago

Great - thanks @shchur! I will let you know if I notice anything that seems odd.

KristenMoore commented 3 years ago

Hi @shchur - just one question about the sampling. Why is the torch.no_grad() only applied to this one line: https://github.com/shchur/ifl-tpp/blob/master/code/dpp/models/recurrent_tpp.py#L178

Thanks.

shchur commented 3 years ago

There is no reason, really, I guess you could just do .detach() and get the same result. You could also wrap the entire call to sample in a no_grad() context if you don't need to differentiate the samples afterwards.