Learnable component - Nutrition modifier - #62
Conversation
| return cast(az.InferenceData, idata), model | ||
|
|
||
|
|
||
| def clip_defaults_to_priors( |
There was a problem hiding this comment.
question: why do we need this at all? I suppose we should rather always set defaults to the mode of the prior, no?
There was a problem hiding this comment.
Defaults are set from literature values, not the prior's mode. They're already the best starting guess we have. The issue is that some literature defaults sit exactly at their prior's min/max, crashing NUTS at initialization. clip_defaults_to_priors just put the values at the boundary to just inside it, so it doesn't fail.
| site, | ||
| species, | ||
| deposition=None, | ||
| extended_params=None, |
There was a problem hiding this comment.
chore: explain what is the role of extended_params, deposition, etc. and type hint them.
| for name, degree in zip(input_vars, poly_params.shape, strict=True) | ||
| ] | ||
| operands = ",".join(f"...{letter}" for letter in letters) | ||
| return jnp.einsum(f"{operands},{letters}->...", *powers, poly_params) |
There was a problem hiding this comment.
question: I am familiar with the Einstein notation, but can you provide an example of what are operands and letters in the specific context of our case here?
There was a problem hiding this comment.
If input_vars = ("N", "S") and poly_params.shape = (2, 2):
letters = "ab" # one letter per variable
powers = [N_powers, S_powers], each shape (..., 2)
operands = "...a,...b" , i.e. one term per power array, batch dims kept as ...
einsum string becomes "...a,...b,ab->..."
So the call is jnp.einsum("...a,...b,ab->...", N_powers, S_powers, poly_params),
which computes:
poly = Σ_a Σ_b N_powers[..., a] * S_powers[..., b] * poly_params[a, b]
matching the docstring's example.
I wanted to generalize this, as in case we add other metric later, for e.g. T_avg (average temperature)
With a third variable
(input_vars = ("N", "S", "T_avg"), poly_params.shape = (2,2,2)), it'd extend to
letters = "abc", operands = "...a,...b,...c",
einsum string "...a,...b,...c,abc->...".
poly = Σ_a Σ_b Σ_c N_powers[..., a] * S_powers[..., b] * T_avg_powers[..., b] * poly_params[a, b, c]
There was a problem hiding this comment.
@gmgivi but N_powers contains powers of N, up to which degree?
There was a problem hiding this comment.
For the moment, set to powers of 2.
|
Thanks for this @gmgivi. Can you clarify:
|
This is just a first step towards learnable components (LC). The aim here is to implement a small LC, run a training loop and see if it has some effect. From the plots, we could see that it's doing 'something'. Now, the question is
Yes, I will make these adjustments.
The cross polynomial terms takes the intra and inter-dependence of input variable, for the plot shown above we took nitrogen and sulphur depositions as input variables. We can add other terms, for e.g. other depositions or T_avg to it. I wanted to check the impact of these variables, if any. Now we see that there is some impact, and need to verify whether it makes sense. From here we can progress towards introducing MLP. I wanted to get this approach working first.
We compare default with nutriment modifier fitted. |
Co-authored-by: gmgivi <55590372+gmgivi@users.noreply.github.com>
In this PR, I plan to implement training of a simple learnable component using monthly depositions of sulphur and nitrogen.
The learnable components is implemented using the function
poly_nm.poly_nmevaluates a cross-term polynomial over the selected inputs, then squashes it into a growth multiplier centered at 1:@gmermoud @CedricTravelletti