Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom loss functions #1540

Closed
bnoordijk opened this issue Dec 13, 2024 · 4 comments
Closed

Custom loss functions #1540

bnoordijk opened this issue Dec 13, 2024 · 4 comments

Comments

@bnoordijk
Copy link

Hi!

Thanks for all the great work on this project so far, it's been of great use!
I was wondering what the best way is to adjust the loss function that is being minimised when working with peTAB files. E.g. to assign different weights to measurements at different time points. Couldn't really find anything on that in the documentation unfortunately.

Happy to hear what your thoughts are!

Cheers,
Ben

@dilpath
Copy link
Member

dilpath commented Jan 4, 2025

Hi Ben, do you have a single PEtab problem? On what level do you want to assign weights? What is your noise model?

Weighted observables
If you have a single PEtab problem with the default (additive normal) noise model and want to assign weights on the level of observables, then simply add a scaling factor (e.g. named inverse_sqrt_weight) to your noiseFormula in the observables table. In the negative log-likelihood, the weight of all measurements of this observable will then be 1/inverse_sqrt_weight^2.
e.g., old noiseFormula=sigma, new noiseFormula=inverse_sqrt_weight * sigma

Weighted timepoints
Since you mentioned different time points -- I would suggest separating those measurements into new observables, such that the above strategy can be used. However, if you prefer, there is support for timepoint-specific noise overrides, but you may need to then "flatten" your problem.

To achieve weighted timepoints, assuming additive normal noise:

  1. change your measurement table noiseParameters column to include the inverse square root of the desired weights for each measurement
  2. change your observable table noiseFormula. e.g. if the observable observableId=obsA previously had a noiseFormula=sigma, change it to be noiseFormula=noiseParameter1_obsA * sigma. N.B.: noiseParameter1_obsA is a special symbol in PEtab that you can read in the docs for the noiseFormula column: https://petab.readthedocs.io/en/latest/v1/documentation_data_format.html#observables-table
  3. flatten the problem if required https://petab.readthedocs.io/projects/libpetab-python/en/latest/build/_autosummary/petab.v1.core.html#petab.v1.core.flatten_timepoint_specific_output_overrides
  4. unflatten the optimized simulation result for visualization with the unflattened problem: https://petab.readthedocs.io/projects/libpetab-python/en/latest/build/_autosummary/petab.v1.core.html#petab.v1.core.unflatten_simulation_df

Feel free to share a snippet of your PEtab problem if you want me to check that the weighting is implemented correctly.

@bnoordijk
Copy link
Author

Hi!

Thanks for the response.
In the meantime I think I've already figured out a workaround; instead of doing flattening and changing the noise you suggest (which also sounds clever) I now just duplicate measurements I want to assign a higher weight to and separate them by a tiny fraction of time.

E.g. if I want to assign double the weight to the timepoint at 21.3333333333, I now add these bottom two rows:

observableId simulationConditionId measurement time
some_observable condition_a 3 1
some_observable condition_b 4 1
some_observable condition_a 5 21.3333333333
some_observable condition_b 6 21.3333333333
some_observable condition_a 5 21.3333333332
some_observable condition_b 6 21.3333333332

This effectively doubles the weight for the later timepoint (albeit in a bit of a hacky way) right?

Thanks again and have a great day!

@FFroehlich
Copy link
Contributor

Hi!

Thanks for the response. In the meantime I think I've already figured out a workaround; instead of doing flattening and changing the noise you suggest (which also sounds clever) I now just duplicate measurements I want to assign a higher weight to and separate them by a tiny fraction of time.

E.g. if I want to assign double the weight to the timepoint at 21.3333333333, I now add these bottom two rows:

observableId simulationConditionId measurement time
some_observable condition_a 3 1
some_observable condition_b 4 1
some_observable condition_a 5 21.3333333333
some_observable condition_b 6 21.3333333333
some_observable condition_a 5 21.3333333332
some_observable condition_b 6 21.3333333332
This effectively doubles the weight for the later timepoint (albeit in a bit of a hacky way) right?

Thanks again and have a great day!

There is no need to separate timepoints by that tiny fraction, you can have multiple measurements at the same timepoint.

@bnoordijk
Copy link
Author

Ah didn't know that, thanks for the swift reply and have a happy new year!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants