Skip to content

Commit 0b8aec9

Browse files
committed
change interpolation_points to feature_scaling_points ; now the n3fit checks are much more strict: no largex exponent is allowed when feature scaling is on, before they were silently dropped so no change of functionality is introduced by this PR, only change of checks ; vp-nextfitruncard automatically changes interpolation_points to feature_scaling_points and will drop largex if it is found together with feature_scaling_points
1 parent a14befa commit 0b8aec9

File tree

7 files changed

+64
-39
lines changed

7 files changed

+64
-39
lines changed

doc/sphinx/source/n3fit/methodology.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ incapable of distinguishing features across many orders of magnitude of ``x``, t
323323
scaling means that the algorithm is limited to learning features on a logarithmic and linear scale.
324324

325325
To solve this problem there is the possibility to apply a different feature scaling to the input by
326-
adding a ``interpolation_points: [number of points]`` flag to the ``n3fit`` runcard. By adding this
326+
adding a ``feature_scaling_points: [number of points]`` flag to the ``n3fit`` runcard. By adding this
327327
flag the ``(x,log(x))`` scaling is replaced by a scaling in such a way that all input ``x`` values
328328
are evenly distributed on the domain ``[-1,1]``, and the input node is no longer split in two.
329329

@@ -333,7 +333,7 @@ increasing cubic spline is used to interpolate after the scaling has been applie
333333
function from the scipy library is used. However, this way the neural network will be agnostic to
334334
the existence of this interpolation function meaning it can no longer learn the true underlying law.
335335
To fix this, the interpolation function has to be probed as well. This is done by only using
336-
``[number of points]`` set by the ``interpolation_points`` flag to define the interpolation function
336+
``[number of points]`` set by the ``feature_scaling_points`` flag to define the interpolation function
337337
after the scaling has been applied. Using this methodology the points used in the interpolation are
338338
again evenly distributed.
339339

extra_tests/regression_fits/feature_scaling.yml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,20 @@ parameters: # This defines the parameter dictionary that is passed to the Model
5050
layer_type: 'dense'
5151
dropout: 0.0
5252
threshold_chi2: 10.0
53-
interpolation_points: 15
53+
feature_scaling_points: 15
5454

5555
fitting:
5656
savepseudodata: False
5757
fitbasis: EVOL
5858
basis:
59-
- {fl: sng, trainable: false, smallx: [1.094, 1.118], largex: [1.46, 3.003]}
60-
- {fl: g, trainable: false, smallx: [0.8189, 1.044], largex: [2.791, 5.697]}
61-
- {fl: v, trainable: false, smallx: [0.457, 0.7326], largex: [1.56, 3.431]}
62-
- {fl: v3, trainable: false, smallx: [0.1462, 0.4061], largex: [1.745, 3.452]}
63-
- {fl: v8, trainable: false, smallx: [0.5401, 0.7665], largex: [1.539, 3.393]}
64-
- {fl: t3, trainable: false, smallx: [-0.4401, 0.9163], largex: [1.773, 3.333]}
65-
- {fl: t8, trainable: false, smallx: [0.5852, 0.8537], largex: [1.533, 3.436]}
66-
- {fl: t15, trainable: false, smallx: [1.082, 1.142], largex: [1.461, 3.1]}
59+
- {fl: sng, trainable: false, smallx: [1.094, 1.118]}
60+
- {fl: g, trainable: false, smallx: [0.8189, 1.044]}
61+
- {fl: v, trainable: false, smallx: [0.457, 0.7326]}
62+
- {fl: v3, trainable: false, smallx: [0.1462, 0.4061]}
63+
- {fl: v8, trainable: false, smallx: [0.5401, 0.7665]}
64+
- {fl: t3, trainable: false, smallx: [-0.4401, 0.9163]}
65+
- {fl: t8, trainable: false, smallx: [0.5852, 0.8537]}
66+
- {fl: t15, trainable: false, smallx: [1.082, 1.142]}
6767

6868
############################################################
6969
positivity:

n3fit/runcards/example-nnpdf41.yml

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -127,21 +127,22 @@ parameters: # This defines the parameter dictionary that is passed to the Model
127127
layer_type: dense
128128
dropout: 0.0
129129
threshold_chi2: 3.5
130-
interpolation_points: 5
130+
feature_scaling_points: 5
131131

132132
fitting:
133133
fitbasis: CCBAR_ASYMM # EVOL (7), EVOLQED (8), etc.
134134
savepseudodata: true
135135
basis:
136-
- {fl : sng, trainable : false, smallx : [1.095, 1.146], largex : [0., 0.]}
137-
- {fl : g, trainable : false, smallx : [0.7978, 1.087], largex : [0., 0.]}
138-
- {fl : v, trainable : false, smallx : [0.4775, 0.6577], largex : [0., 0.]}
139-
- {fl : v3, trainable : false, smallx : [0.1068, 0.493], largex : [0., 0.]}
140-
- {fl : v8, trainable : false, smallx : [0.5914, 0.7776], largex : [0., 0.]}
141-
- {fl : t3, trainable : false, smallx : [-0.3737, 1.0], largex : [0., 0.]}
142-
- {fl : t8, trainable : false, smallx : [0.5771, 0.9486], largex : [0., 0.]}
143-
- {fl : t15, trainable : false, smallx : [1.062, 1.153], largex : [0., 0.]}
144-
- {fl : v15, trainable : false, smallx : [0.4515, 0.7648], largex : [0., 0.]}
136+
- {fl : sng , trainable : false , smallx : [1.095 , 1.146] }
137+
- {fl : g , trainable : false , smallx : [0.7978 , 1.087] }
138+
- {fl : v , trainable : false , smallx : [0.4775 , 0.6577] }
139+
- {fl : v3 , trainable : false , smallx : [0.1068 , 0.493] }
140+
- {fl : v8 , trainable : false , smallx : [0.5914 , 0.7776] }
141+
- {fl : t3 , trainable : false , smallx : [-0.3737 , 1.0] }
142+
- {fl : t8 , trainable : false , smallx : [0.5771 , 0.9486] }
143+
- {fl : t15 , trainable : false , smallx : [1.062 , 1.153] }
144+
- {fl : v15 , trainable : false , smallx : [0.4515 , 0.7648] }
145+
145146

146147
################################################################################
147148
positivity:

n3fit/runcards/examples/Basic_feature_scaling.yml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,21 +49,21 @@ parameters: # This defines the parameter dictionary that is passed to the Model
4949
stopping_patience: 0.30 # percentage of the number of epochs
5050
layer_type: 'dense'
5151
dropout: 0.0
52-
interpolation_points: 40
52+
feature_scaling_points: 40
5353
threshold_chi2: 5.0
5454

5555
fitting:
5656
fitbasis: NN31IC # EVOL (7), EVOLQED (8), etc.
5757
basis:
5858
# remeber to change the name of PDF accordingly with fitbasis
59-
- { fl: sng, smallx: [1.05,1.19], largex: [1.47,2.70], trainable: False }
60-
- { fl: g, smallx: [0.94,1.25], largex: [0.11,5.87], trainable: False }
61-
- { fl: v, smallx: [0.54,0.75], largex: [1.15,2.76], trainable: False }
62-
- { fl: v3, smallx: [0.21,0.57], largex: [1.35,3.08] }
63-
- { fl: v8, smallx: [0.52,0.76], largex: [0.77,3.56], trainable: True }
64-
- { fl: t3, smallx: [-0.37,1.52], largex: [1.74,3.39] }
65-
- { fl: t8, smallx: [0.56,1.29], largex: [1.45,3.03] }
66-
- { fl: cp, smallx: [0.12,1.19], largex: [1.83,6.70] }
59+
- { fl: sng, smallx: [1.05,1.19], trainable: False }
60+
- { fl: g, smallx: [0.94,1.25], trainable: False }
61+
- { fl: v, smallx: [0.54,0.75], trainable: False }
62+
- { fl: v3, smallx: [0.21,0.57] }
63+
- { fl: v8, smallx: [0.52,0.76], trainable: True }
64+
- { fl: t3, smallx: [-0.37,1.52] }
65+
- { fl: t8, smallx: [0.56,1.29] }
66+
- { fl: cp, smallx: [0.12,1.19] }
6767

6868
############################################################
6969
positivity:

n3fit/src/n3fit/checks.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ def check_consistent_basis(sum_rules, fitbasis, basis, theoryid, parameters):
396396
- Checks the sum rules can be imposed
397397
- Correct flavours for the selected basis
398398
- Correct ranges (min < max) for the small and large-x exponents
399+
- When feature scaling is active, the large_x interpolation is not set
399400
"""
400401
check_sumrules(sum_rules)
401402
# Check that there are no duplicate flavours and that parameters are sane
@@ -405,12 +406,19 @@ def check_consistent_basis(sum_rules, fitbasis, basis, theoryid, parameters):
405406
smallx = flavour_dict["smallx"]
406407
if smallx[0] > smallx[1]:
407408
raise CheckError(f"Wrong smallx range for flavour {name}: {smallx}")
408-
largex = flavour_dict.get("largex")
409-
if largex is not None and largex[0] > largex[1]:
410-
raise CheckError(f"Wrong largex range for flavour {name}: {largex}")
411409
if name in flavs:
412410
raise CheckError(f"Repeated flavour name: {name}. Check basis dictionary")
413411
flavs.append(name)
412+
413+
# Large-x is allowed to not exist if feature scaling is enabled
414+
if parameters.get("feature_scaling_points") is not None:
415+
if "largex" in flavour_dict and not flavour_dict["largex"] == [0.0, 0.0]:
416+
raise CheckError("No largex exponent allowed when feature_scaling_points is set")
417+
else:
418+
largex = flavour_dict["largex"]
419+
if largex[0] > largex[1]:
420+
raise CheckError(f"Wrong largex range for flavour {name}: {largex}")
421+
414422
# Finally check whether the basis considers or not charm
415423
# Check that the basis given in the runcard is one of those defined in validphys.pdfbases
416424
vp_basis = check_basis(fitbasis, flavs)["basis"]
@@ -438,7 +446,7 @@ def check_consistent_parallel(parameters, parallel_models):
438446

439447

440448
@make_argcheck
441-
def check_deprecated_options(fitting):
449+
def check_deprecated_options(fitting, parameters):
442450
"""Checks whether the runcard is using deprecated options"""
443451
options_outside = ["trvlseed", "nnseed", "mcseed", "save", "load", "genrep", "parameters"]
444452
for option in options_outside:
@@ -452,6 +460,10 @@ def check_deprecated_options(fitting):
452460
for option in nnfit_options:
453461
if option in fitting:
454462
log.warning("'fitting::%s' is an nnfit-only key, it will be ignored", option)
463+
if "interpolation_points" in parameters:
464+
raise CheckError(
465+
"`interpolation_points` no longer accepted, please change to `feature_scaling_points`"
466+
)
455467

456468

457469
@make_argcheck

n3fit/src/n3fit/model_trainer.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818
from n3fit import model_gen
1919
from n3fit.backends import NN_LAYER_ALL_REPLICAS, MetaModel, callbacks, clear_backend_state
2020
from n3fit.backends import operations as op
21-
from n3fit.layers import losses
2221
from n3fit.hyper_optimization.hyper_scan import HYPEROPT_STATUSES
2322
import n3fit.hyper_optimization.penalties
2423
from n3fit.hyper_optimization.rewards import HyperLoss
24+
from n3fit.layers import losses
2525
from n3fit.scaler import generate_scaler
2626
from n3fit.stopping import Stopping
2727
from n3fit.vpinterface import N3PDF, compute_hyperopt_metrics
@@ -876,7 +876,7 @@ def hyperparametrizable(self, params):
876876
integrability_dict.get("multiplier"),
877877
integrability_dict.get("initial"),
878878
epochs,
879-
params.get("interpolation_points"),
879+
params.get("feature_scaling_points"),
880880
)
881881
threshold_pos = positivity_dict.get("threshold", 1e-6)
882882
threshold_chi2 = params.get("threshold_chi2", CHI2_THRESHOLD)
@@ -1077,11 +1077,11 @@ def hyperparametrizable(self, params):
10771077

10781078
# Compute the loss over all folds for hyperopt
10791079
final_hyper_loss = self._hyper_loss.reduce_over_folds(l_hyper)
1080-
1080+
10811081
# Add penalty term to ensure convergence
10821082
exp_chi2_fitted_data = np.average(trvl_chi2exp_per_fold)
10831083
expchi2_penalty = losses.LossHyperopt()
1084-
final_hyper_loss += expchi2_penalty(exp_chi2_fitted_data)
1084+
final_hyper_loss += expchi2_penalty(exp_chi2_fitted_data)
10851085

10861086
# Hyperopt needs a dictionary with information about the losses
10871087
# it is possible to store arbitrary information in the trial file

validphys2/src/validphys/eff_exponents.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,12 @@ def iterate_preprocessing_yaml(fit, next_fit_eff_exps_table, _flmap_np_clip_arg=
509509
checked = check_basis(basis, None)
510510
basis = checked["basis"]
511511

512+
# If the runcard still has the old option `interpolation_points` change it to `feature_scaling_points`:
513+
if "interpolation_points" in filtermap["parameters"]:
514+
filtermap["parameters"]["feature_scaling_points"] = filtermap["parameters"].pop(
515+
"interpolation_points"
516+
)
517+
512518
# use order defined in runcard.
513519
runcard_flavours = [f"{basis.elementlabel(ref_fl['fl'])}" for ref_fl in previous_exponents]
514520
for i, fl in enumerate(runcard_flavours):
@@ -523,7 +529,13 @@ def iterate_preprocessing_yaml(fit, next_fit_eff_exps_table, _flmap_np_clip_arg=
523529
if largex_args is not None:
524530
betas = np.clip(betas, **largex_args)
525531
previous_exponents[i]["smallx"] = [fmt(alpha) for alpha in alphas]
526-
previous_exponents[i]["largex"] = [fmt(beta) for beta in betas]
532+
# Regardless of whether there was a large x in the original runcard
533+
# drop it if feature scaling is set, to avoid future mistakes
534+
if filtermap["parameters"].get("feature_scaling_points") is None:
535+
previous_exponents[i]["largex"] = [fmt(beta) for beta in betas]
536+
else:
537+
# NB previous exponents is = filtermap (see above), if it dies here it dies in real life
538+
previous_exponents[i].pop("largex", None)
527539
with tempfile.NamedTemporaryFile() as fp:
528540
path = Path(fp.name)
529541
yaml_rt.dump(filtermap, path)

0 commit comments

Comments
 (0)