Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 28 additions & 35 deletions doc/sphinx/source/n3fit/runcard_detailed.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,16 @@ It is possible to run a fit with no validation set by setting the fraction to ``
Network Architecture
--------------------
There are different network architectures implemented in ``n3fit``.
Which can be selected by changing the ``fitting:parameters::layer_type`` parameter in the runcard.
Which can be selected by changing the ``parameters::layer_type`` parameter in the runcard.
All layer types implement the ``nodes_per_layer``, ``activation_per_layer`` and ``initializer`` parameters.

.. code-block:: yaml

fitting:
parameters:
nodes_per_layer: [5, 3, 8]
activation_per_layer: ['tanh', 'tanh', 'linear']
layer_type: 'dense_per_flavour'
initializer: 'glorot_normal'
parameters:
nodes_per_layer: [5, 3, 8]
activation_per_layer: ['tanh', 'tanh', 'linear']
layer_type: 'dense_per_flavour'
initializer: 'glorot_normal'

- **One single network** (``layer_type: dense``):

Expand Down Expand Up @@ -117,12 +116,11 @@ of optimizer (and its corresponding options).

.. code-block:: yaml

fitting:
parameters:
optimizer:
optimizer_name: 'Adadelta'
learning_rate: 1.0
clipnorm: 1.0
parameters:
optimizer:
optimizer_name: 'Adadelta'
learning_rate: 1.0
clipnorm: 1.0


The full list of optimizers accepted by the ``n3fit`` and their arguments
Expand All @@ -136,13 +134,13 @@ Positivity
----------

In ``n3fit`` the behavior of the positivity observables has changed with respect to ``nnfit``.
In ``nnfit`` the loss due to the positivity observable was multiplied by a ``poslambda`` for each observable, defined in the runcard as:
In ``nnfit`` the loss due to the positivity observable was multiplied by a ``maxlambda`` for each observable, defined in the runcard as:

.. code-block:: yaml

positivity:
posdatasets:
- {dataset: POSF2U, poslambda: 1e6}
- {dataset: POSF2U, maxlambda: 1e6}


This behavior was found to be very inefficient for gradient descent based strategies and was exchanged for a dynamical Lagrange multiplier.
Expand All @@ -152,19 +150,18 @@ the Neural Network as:

.. code-block:: yaml

fitting:
parameters:
positivity:
threshold: 1e-6
multiplier: 1.05
initial: 14.5
parameters:
positivity:
threshold: 1e-6
multiplier: 1.05
initial: 14.5

Note that by defining the positivity in this way all datasets will share the same Lagrange multiplier.

It is also possible to not define the positivity hyperparameters (or define them only partially).
In this case ``n3fit`` will set the initial Lagrange multiplier as ``initial`` (default: 1.0)
while the ``multiplier`` will be such that after the last epoch the final Lagrange multiplier
equals the ``poslambda`` defined for the dataset.
equals the ``maxlambda`` defined for the dataset.

Finally we have the positivity threshold, which is set to ``1e-6`` by default.
During the fit, the positivity loss will be compared to this value. If it is above it,
Expand Down Expand Up @@ -200,9 +197,8 @@ Threshold :math:`\chi2`

.. code-block:: yaml

fitting:
parameters:
threshold_chi2: 4.0
parameters:
threshold_chi2: 4.0

- ``threshold_chi2``: sets a maximum validation :math:`\chi2` for the stopping to activate. Avoids (too) early stopping.

Expand All @@ -220,10 +216,9 @@ In order to enable the TensorBoard callback in ``n3fit`` it is enough with addin

.. code-block:: yaml

fitting:
tensorboard:
weight_freq: 100
profiling: True
tensorboard:
weight_freq: 100
profiling: True


The ``weight_freq`` flag controls each how many epochs the weights of the NN are stored.
Expand Down Expand Up @@ -267,9 +262,8 @@ Threshold :math:`\chi2`

.. code-block:: yaml

fitting:
parameters:
threshold_chi2: 4.0
parameters:
threshold_chi2: 4.0

- ``threshold_chi2``: sets a maximum validation :math:`\chi2` for the stopping to activate. Avoids (too) early stopping.

Expand All @@ -279,9 +273,8 @@ Save and load weights of the model

.. code-block:: yaml

fitting:
save: "weights.h5"
load: "weights.h5"
save: "weights.h5"
load: "weights.h5"

- ``save``: saves the weights of the PDF model in the selected file in the replica folder.
- ``load``: loads the weights of the PDF model from the selected file.
Expand Down
2 changes: 1 addition & 1 deletion doc/sphinx/source/tutorials/pseudodata.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Suppose one has obtained a fit using the N3FIT framework and wants to do some analysis that requires
knowing exactly the data that the neural networks saw during the fitting procedure. Thankfully, this
information is reproducible due to the various seeds in the `fitting` namespace in the fit runcard.
information is reproducible due to the various seeds in the fit runcard.

The 3 seeds of interest are `trvlseed` which determines the training/validation splitting, `nnseed`
which concerns the initialization of the neural netowrks themselves, and finally `mcseed` which is the
Expand Down
44 changes: 19 additions & 25 deletions doc/sphinx/source/tutorials/run-fit.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,40 +28,34 @@ experimental data, the theory setup and the fitting setup.
The `n3fit` code accepts the same YAML keys used by `nnfit` and extra keys
required by the new techniques introduced in [Methodology](methodology).

In particular we introduce new keys in the `fitting` section such as:
In particular we introduce new keys in the fit runcard such as:
- different seeds for the training and validation split (`trvlseed`), neural
network intialization (`nnseed`) and the MC data replica generation (`mcseed`).
- some debug flags to store or load the model in/from hd5 files (`save`,
`savefile`, `load`, `loadfile`, `plot`)
- some debug flags to store or load the model in/from hd5 files (`save`, `load`)
- a new `parameters` dictionnary with the model specifications based on the
arguments described in [Methodology](methodology).

See, as an example, the following self explanatory runcard fragment:
```yaml
# runcard example
...
fitting:
trvlseed: 1
nnseed: 2
mcseed: 3
save: False
savefile: 'weights.hd5'
load: False
loadfile: 'weights.hd5'
plot: False

parameters: # This defines the parameter dictionary that is passed to the Model Trainer
nodes_per_layer: [15, 10, 8]
activation_per_layer: ['sigmoid', 'sigmoid', 'linear']
initializer: 'glorot_normal'
learning_rate: 0.01
optimizer: 'RMSprop'
epochs: 900
pos_multiplier: 1.05
pos_initial: # believe the pos_lambda below
stopping_patience: 0.30 # percentage of the number of epochs
layer_type: 'dense'
dropout: 0.0
trvlseed: 1
nnseed: 2
mcseed: 3
genrep: true

parameters: # This defines the parameter dictionary that is passed to the Model Trainer
nodes_per_layer: [15, 10, 8]
activation_per_layer: ['sigmoid', 'sigmoid', 'linear']
initializer: 'glorot_normal'
learning_rate: 0.01
optimizer: 'RMSprop'
epochs: 900
pos_multiplier: 1.05
pos_initial: # believe the pos_lambda below
stopping_patience: 0.30 # percentage of the number of epochs
layer_type: 'dense'
dropout: 0.0
...
```

Expand Down
16 changes: 8 additions & 8 deletions doc/validphys2/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -2848,7 +2848,7 @@ resource we are providing does. The docstring will be seen in
```python
def parse_posdataset(self, posset:dict, * ,theoryid):
"""An observable used as positivity constrain in the fit.
It is a mapping containing 'dataset' and 'poslambda'."""
It is a mapping containing 'dataset' and 'maxlambda'."""
...
```

Expand Down Expand Up @@ -2938,10 +2938,10 @@ errors (see the other examples in the class).
The `PositivytySetSpec` could be defined roughly like:
```python
class PositivitySetSpec():
def __init__(self, commondataspec, fkspec, poslambda, thspec):
def __init__(self, commondataspec, fkspec, maxlambda, thspec):
self.commondataspec = commondataspec
self.fkspec = fkspec
self.poslambda = poslambda
self.maxlambda = maxlambda
self.thspec = thspec

@property
Expand All @@ -2955,7 +2955,7 @@ The `PositivytySetSpec` could be defined roughly like:
def load(self):
cd = self.commondataspec.load()
fk = self.fkspec.load()
return PositivitySet(cd, fk, self.poslambda)
return PositivitySet(cd, fk, self.maxlambda)
```
Here `PositivitySet` is the `libnnpdf` object. It is generally better
to pass around the spec objects because they are lighter and have more
Expand All @@ -2966,21 +2966,21 @@ With this, our parser method could look like this:

def parse_posdataset(self, posset:dict, * ,theoryid):
"""An observable used as positivity constrain in the fit.
It is a mapping containing 'dataset' and 'poslambda'."""
It is a mapping containing 'dataset' and 'maxlambda'."""
bad_msg = ("posset must be a mapping with a name ('dataset') and "
"a float multiplier(poslambda)")
"a float multiplier(maxlambda)")

theoryno, theopath = theoryid
try:
name = posset['dataset']
poslambda = float(posset['poslambda'])
maxlambda = float(posset['maxlambda'])
except KeyError as e:
raise ConfigError(bad_msg, e.args[0], posset.keys()) from e
except ValueError as e:
raise ConfigError(bad_msg) from e

try:
return self.loader.check_posset(theoryno, name, poslambda)
return self.loader.check_posset(theoryno, name, maxlambda)
except FileNotFoundError as e:
raise ConfigError(e) from e
```
Expand Down
79 changes: 38 additions & 41 deletions n3fit/runcards/Basic_feature_scaling.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,40 +34,37 @@ theory:
theoryid: 53 # database id

############################################################
fitting:
trvlseed: 1
nnseed: 2
mcseed: 3
epochs: 900
save: 'weights.h5'
# load: '/path/to/weights.h5/file'

trvlseed: 1
nnseed: 2
mcseed: 3
genrep : True # true = generate MC replicas, false = use real data

tensorboard:
weight_freq: 100
profiling: False
save: 'weights.h5'

genrep : True # true = generate MC replicas, false = use real data
tensorboard:
weight_freq: 100
profiling: False

parameters: # This defines the parameter dictionary that is passed to the Model Trainer
nodes_per_layer: [15, 10, 8]
activation_per_layer: ['sigmoid', 'sigmoid', 'linear']
initializer: 'glorot_normal'
optimizer:
optimizer_name: 'RMSprop'
learning_rate: 0.01
clipnorm: 1.0
epochs: 900
positivity:
multiplier: 1.05 # When any of the multiplier and/or the initial is not set
initial: # the poslambda will be used instead to compute these values per dataset
threshold: 1e-5
stopping_patience: 0.30 # percentage of the number of epochs
layer_type: 'dense'
dropout: 0.0
interpolation_points: 40
threshold_chi2: 5.0
parameters: # This defines the parameter dictionary that is passed to the Model Trainer
nodes_per_layer: [15, 10, 8]
activation_per_layer: ['sigmoid', 'sigmoid', 'linear']
initializer: 'glorot_normal'
optimizer:
optimizer_name: 'RMSprop'
learning_rate: 0.01
clipnorm: 1.0
epochs: 900
positivity:
multiplier: 1.05 # When any of the multiplier and/or the initial is not set
initial: # the maxlambda will be used instead to compute these values per dataset
threshold: 1e-5
stopping_patience: 0.30 # percentage of the number of epochs
layer_type: 'dense'
dropout: 0.0
interpolation_points: 40
threshold_chi2: 5.0

fitting:
# NN23(QED) = sng=0,g=1,v=2,t3=3,ds=4,sp=5,sm=6,(pht=7)
# EVOL(QED) = sng=0,g=1,v=2,v3=3,v8=4,t3=5,t8=6,(pht=7)
# EVOLS(QED)= sng=0,g=1,v=2,v8=4,t3=4,t8=5,ds=6,(pht=7)
Expand All @@ -79,25 +76,25 @@ fitting:
# mutsize: mutation size
# mutprob: mutation probability
# smallx, largex: preprocessing ranges
- { fl: sng, pos: False, mutsize: [15], mutprob: [0.05], smallx: [1.05,1.19], largex: [1.47,2.70], trainable: False }
- { fl: g, pos: False, mutsize: [15], mutprob: [0.05], smallx: [0.94,1.25], largex: [0.11,5.87], trainable: False }
- { fl: v, pos: False, mutsize: [15], mutprob: [0.05], smallx: [0.54,0.75], largex: [1.15,2.76], trainable: False }
- { fl: v3, pos: False, mutsize: [15], mutprob: [0.05], smallx: [0.21,0.57], largex: [1.35,3.08] }
- { fl: v8, pos: False, mutsize: [15], mutprob: [0.05], smallx: [0.52,0.76], largex: [0.77,3.56], trainable: True }
- { fl: t3, pos: False, mutsize: [15], mutprob: [0.05], smallx: [-0.37,1.52], largex: [1.74,3.39] }
- { fl: t8, pos: False, mutsize: [15], mutprob: [0.05], smallx: [0.56,1.29], largex: [1.45,3.03] }
- { fl: cp, pos: False, mutsize: [15], mutprob: [0.05], smallx: [0.12,1.19], largex: [1.83,6.70] }
- { fl: sng, pos: False, smallx: [1.05,1.19], largex: [1.47,2.70], trainable: False }
- { fl: g, pos: False, smallx: [0.94,1.25], largex: [0.11,5.87], trainable: False }
- { fl: v, pos: False, smallx: [0.54,0.75], largex: [1.15,2.76], trainable: False }
- { fl: v3, pos: False, smallx: [0.21,0.57], largex: [1.35,3.08] }
- { fl: v8, pos: False, smallx: [0.52,0.76], largex: [0.77,3.56], trainable: True }
- { fl: t3, pos: False, smallx: [-0.37,1.52], largex: [1.74,3.39] }
- { fl: t8, pos: False, smallx: [0.56,1.29], largex: [1.45,3.03] }
- { fl: cp, pos: False, smallx: [0.12,1.19], largex: [1.83,6.70] }

############################################################
positivity:
posdatasets:
- { dataset: POSF2U, poslambda: 1e6 } # Positivity Lagrange Multiplier
- { dataset: POSFLL, poslambda: 1e4 }
- { dataset: POSF2U, maxlambda: 1e6 } # Positivity Lagrange Multiplier
- { dataset: POSFLL, maxlambda: 1e4 }

############################################################
integrability:
integdatasets:
- {dataset: INTEGXT3, poslambda: 1e2}
- {dataset: INTEGXT3, maxlambda: 1e2}

############################################################
debug: True
Expand Down
Loading