Add normalizer option to remove global mean surface temperature#1191
Closed
mcgibbon wants to merge 3 commits into
Closed
Add normalizer option to remove global mean surface temperature#1191mcgibbon wants to merge 3 commits into
mcgibbon wants to merge 3 commits into
Conversation
Adds an opt-in flag on NormalizationConfig that, on the network normalizer only, computes a per-sample offset from the input surface_temperature (surface_temperature norm mean minus the sample's cell-wise mean) and adds it to every temperature field on normalize / subtracts it on denormalize. Preserves cross-channel and horizontal temperature gradients while pulling the normalized surface_temperature near zero. Temperature field list is hard-coded; the loss normalizer always strips the flag since offsets do not cancel cleanly across separate target/prediction normalize() calls. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…mperature Renames the NormalizationConfig field and the corresponding StandardNormalizer parameter, attribute, property, and helper for a clearer description of what the feature does. The module-level constant _SHARED_TEMPERATURE_OFFSET_REFERENCE becomes _GLOBAL_MEAN_SURFACE_TEMPERATURE_REFERENCE. StandardNormalizer.from_state still reads the legacy "use_shared_temperature_offset" state-dict key as a fallback so existing checkpoints continue to load. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Contributor
Author
|
I'm still not sure the normalization is the right place for the code, as I'm wondering if I should add the global mean surface temperature back in as a separate (constant) field, and the normalizer wouldn't be the right level to do that. |
Contributor
Author
|
Superceded by #1193. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Atmospheric warming/cooling signals show up as large temperature anomalies across many vertical levels at once. Normalizing each temperature field by its global mean leaves a slowly-varying global temperature offset embedded in every channel, which the network has to re-learn at every layer. This PR adds an opt-in normalization mode that strips the global-mean surface temperature anomaly from all temperature fields before normalization (and restores it after denormalization), so the network sees temperature gradients rather than absolute global temperatures.
The offset is computed per sample as
surface_temperature_norm_mean - sample.surface_temperature.mean(spatial dims)and added to every temperature field onnormalize(), then subtracted back ondenormalize(). Cross-channel and horizontal gradients are preserved; only the global mean shifts. The flag is meaningful only for the network normalizer (paired normalize/denormalize); the loss normalizer always strips it because offsets computed independently from target vs. prediction inputs would not cancel cleanly.Changes:
fme.core.normalizer.NormalizationConfig.remove_global_mean_surface_temperature: new opt-in bool flag (defaultFalse).fme.core.normalizer.StandardNormalizer: caches the per-sample offset duringnormalize()and inverts it indenormalize(); raises ifsurface_temperatureis missing from means or input tensors, or ifdenormalize()runs beforenormalize().fme.core.normalizer.NetworkAndLossNormalizationConfig.get_loss_normalizer: strips the flag from the loss normalizer via the new_disable_global_mean_surface_temperature_removalhelper.fme.core.normalizer._GLOBAL_MEAN_SURFACE_TEMPERATURE_REFERENCE/_TEMPERATURE_FIELD_NAMES: hard-coded reference field and target field list.StandardNormalizer.from_statereads the legacyuse_shared_temperature_offsetstate-dict key as a fallback so existing checkpoints continue to load.Tests added
If dependencies changed, "deps only" image rebuilt and "latest_deps_only_image.txt" file updated