mod_train_helpers¶
Routines helpful during training. author: Alexander Knoll, Alea Tokita, Moritz R. Schaefer, Redouan El Haouari
Dependencies¶
Procedures Summary¶
| Name | Type | Description |
|---|---|---|
get_loss_threshold_scale |
Function | Match the update threshold to the normalization of the selected samples. |
calc_num_updates |
Function | Helper function for estimate_num_updates_per_optimizer to calculate `num_updates =... |
is_cost_output_required |
Function | Determines if cost information should be displayed for a given epoch. This elemental function... |
cost_threshold_crossed |
Function | Check if the cost threshold is crossed. Can be used to abort the training if the cost is below... |
get_precalc_loss_norm |
Function | Obtain the normalization factor that is applied to the reference and predicted values before... |
evaluate_normalized_loss |
Subroutine | Evaluate a local training loss and differentiate its input normalization. scale is independent... |
update_optimizers_multiple_models |
Subroutine | Update routine for simultaneous updates on parameters of multiple models. This routine iterates... |
update_optimizers_single_model |
Subroutine | Update routine for updates on parameters of a single model. This routine iterates through all... |
adjust_loss_threshold_factor |
Subroutine | Adjust the loss threshold factor. The loss threshold is the cost mutliplied by a factor. This... |
warn_threshold |
Subroutine | Add formated warning to warning handler if loss_threshold is adjusted. |
set_force_update_scaling |
Subroutine | Scale factor for force update is calculated if factor set below 0. This routine determines the... |
estimate_num_updates_per_optimizer |
Subroutine | Estimates the projected number of updates per optimizer within an epoch. Note: For... |
write_optimal_epoch |
Subroutine | Writes a formattated message about the optimal epoch. |
Interface Details¶
interface update_optimizers¶
Procedure Details¶
function get_loss_threshold_scale¶
function get_loss_threshold_scale( &
norm &
)
Match the update threshold to the normalization of the selected samples.
Arguments
-
norm: real(DP) (dim: (:)) [in]
Called By
function calc_num_updates¶
function calc_num_updates( &
num_samples, &
sample_multiplier, &
sample_fraction, &
test_fraction, &
batchsize &
)
Helper function for estimate_num_updates_per_optimizer to calculate
num_updates = int(num_samples * sample_multiplier * sample_fraction
* (1 - test_fraction) * (1 / batchsize) * (1 / num_images))
Arguments
-
num_samples: integer [in] -
sample_multiplier: integer [in] -
sample_fraction: real(DP) [in] -
test_fraction: real(DP) [in] -
batchsize: integer [in]
Called By
function is_cost_output_required¶
function is_cost_output_required( &
iepoch &
)
Determines if cost information should be displayed for a given epoch.
This elemental function evaluates whether the current training epoch (iepoch)
meets the criteria for calculating the cost.
Output is required if at least one of the following is true:
1. The epoch number is a multiple of global_settings%cost_frequency.
2. The epoch is the last epoch (global_settings%num_epochs).
3. The epoch is within the initial phase defined by global_settings%cost_frequency_start.
Arguments
-
iepoch: integer [in]
Called By
function cost_threshold_crossed¶
function cost_threshold_crossed( &
cost, &
epoch &
)
Check if the cost threshold is crossed.
Can be used to abort the training if the cost is below the lower cost threshold or above the upper cost threshold. The cost is checked against the set threshold only after the lower and upper cost threshold epochs have been reached.
Arguments
-
cost: real(DP) (dim: (global_settings%num_committee_members)) [in]– Cost of the current epoch, e.g. the RMSE. -
epoch: integer [in]– Current epoch of the training.
Called By
function get_precalc_loss_norm¶
function get_precalc_loss_norm( &
name, &
num_atoms_sample &
)
Obtain the normalization factor that is applied to the reference and predicted values before loss calculation for arbitrary properties.
Arguments
-
name: character [in] -
num_atoms_sample: integer [in]
Called By
subroutine evaluate_normalized_loss¶
subroutine evaluate_normalized_loss( &
loss_function, &
prediction, &
reference, &
scale, &
loss, &
gradients &
)
Evaluate a local training loss and differentiate its input normalization.
scale is independent of the model parameters; gradients are with respect
to the unscaled prediction. Training losses must use collect = .false.
Arguments
-
loss_function: class(AbstractLossFunction) [in] -
prediction: real(DP) (dim: (:)) [in] -
reference: real(DP) (dim: (:)) [in] -
scale: real(DP) (dim: (:)) [in] -
loss: real(DP) [out] -
gradients: real(DP) (dim: (size(prediction))) [out]
Called By
subroutine update_optimizers_multiple_models¶
subroutine update_optimizers_multiple_models( &
models, &
optimizers, &
loss, &
loss_function, &
atomic_numbers, &
mpi_update &
)
Update routine for simultaneous updates on parameters of multiple models.
This routine iterates through all provided optimizers. For each optimizer, it aggregates the parameters and their corresponding gradients from all models that are associated with that specific optimizer and share a loss function type.
The batch loss and its parameter gradients are passed without
additional normalization.
Finally, the optimizer's step method is called to update the parameters,
and the updated parameters are distributed back into the respective models.
The models and their parameter gradients are then reset.
Arguments
-
models: class(ModelPtr) (dim: (:)) [inout]– Array of models. The parameters of these models are updated. The loss gradient has to be already backward passed through the models. Parameter gradients are stored on the models. -
optimizers: type(OptimizerPtr) (dim: (:)) [inout]– Optimizers potentially used to update the models. Each optimizer performs maximum one update during this routine. -
loss: real(DP) [in]– Calculated total loss of the batch. -
loss_function: type(LossFunctionPtr) [in]– Loss function that was used to calculate the loss and perform the backward pass. Optimizers which use a different loss function are not updated. -
atomic_numbers: integer (dim: (:)) [in]– Atomic numbers of active atoms, used to select participating optimizers. -
mpi_update: integer [in]– Signals if this process should do an update. A value of 0 signals no update, a value of 1 an update. There is e.g. no update if the loss is below the loss threshold.
Called By
subroutine update_optimizers_single_model¶
subroutine update_optimizers_single_model( &
model, &
optimizers, &
loss, &
loss_function, &
atomic_numbers, &
mpi_update &
)
Update routine for updates on parameters of a single model.
This routine iterates through all provided optimizers. For each optimizer, it aggregates the parameters and their corresponding gradients from the model if the model is associated with the optimizer and they share a loss function type.
The batch loss and its parameter gradients are passed without
additional normalization.
Finally, the optimizer's step method is called to update the parameters,
and the updated parameters are distributed back into the model.
The model and its parameter gradients are then reset.
Arguments
-
model: class(AbstractPropertyModel) [inout]– Model for which the parameters are updated. The loss gradient has to be already backward passed through the model. Parameter gradients are stored on the model. -
optimizers: type(OptimizerPtr) (dim: (:)) [inout]– Optimizers potentially used to update the model. Each optimizer performs maximum one update during this routine. -
loss: real(DP) [in]– Calculated total loss of the batch. -
loss_function: type(LossFunctionPtr) [in]– Loss function that was used to calculate the loss and perform the backward pass. Optimizers which use a different loss function are not updated. -
atomic_numbers: integer (dim: (:)) [in]– Atomic numbers of active atoms, used to select participating optimizers. -
mpi_update: integer [in]– Signals if this process should do an update. A value of 0 signals no update, a value of 1 an update. There is e.g. no update if the loss is below the loss threshold.
Called By
subroutine adjust_loss_threshold_factor¶
subroutine adjust_loss_threshold_factor( &
num_updates, &
initial_threshold_factor, &
threshold_factor, &
lallow_reset, &
property_label &
)
Adjust the loss threshold factor.
The loss threshold is the cost mutliplied by a factor. This factor is adjusted here. In case no structures were updated during the last epoch, the factor is decreased to make the loss threshold less restrictive and allow for more updates.
If then an epoch performed updates again, the factor is increased slowly up to the starting value. author: Alea Tokita and Moritz Schaefer
Arguments
-
num_updates: integer [in]– Number of updates in the last epoch. -
initial_threshold_factor: real(DP) [in]– Initial loss threshold factor as defined by the user in the input.nn file. -
threshold_factor: real(DP) [inout]– Current loss threshold factor as modified by this routine. -
lallow_reset: logical [in]– If set to false the loss threshold factor can not increase again. -
property_label: character [in]– Name of property of which the threshold is checked.
Called By
subroutine warn_threshold¶
subroutine warn_threshold( &
threshold, &
property_label &
)
Add formated warning to warning handler if loss_threshold is adjusted.
Arguments
-
threshold: real(DP) [in]– New loss threshold factor after change. -
property_label: character [in]– Name of property of which the threshold is adjusted.
Called By
subroutine set_force_update_scaling¶
subroutine set_force_update_scaling( &
force_update_scaling_in, &
batchsize_forces, &
batchsize_structures, &
energy_fraction, &
force_fraction, &
num_atoms_per_element, &
force_update_scaling &
)
Scale factor for force update is calculated if factor set below 0.
This routine determines the force update scaling factor for each element. If the input scaling factor for a specific element is set to a negative value, the routine calculates an element-specific scaling factor based on batchsizes of energies and forces, the energy and force fractions, and the number of atoms of that element. The factor is calculated in a way to make sure that the total importance of the force updates of each element over the structure batch is equal to the total importance of the energy updates in the structure batch.
If the force update scaling factor is positive, it is used directly. @todo Element decoupeled Kalman Filter routines have more advanced method, could be used here author: Alea Tokita, Alexander Knoll
Arguments
-
force_update_scaling_in: real(DP) (dim: (MAX_ELEM_NUM)) [in]– Array of original force update scaling factors for each element. -
batchsize_forces: integer (dim: (MAX_ELEM_NUM)) [in]– Force batchsize for each element. -
batchsize_structures: integer [in]– Structure batchsize. -
energy_fraction: real(DP) [in]– Fraction of energies of the structurebatch used for training in each epoch. -
force_fraction: real(DP) (dim: (MAX_ELEM_NUM)) [in]– Fraction of forces of the structurebatch used for training in each epoch. -
num_atoms_per_element: integer (dim: (MAX_ELEM_NUM)) [in]– Number of atoms per element in the structurebatch. -
force_update_scaling: real(DP) (dim: (MAX_ELEM_NUM)) [out]– Actual used force update scaling factor calculated in this routine.
Called By
subroutine estimate_num_updates_per_optimizer¶
subroutine estimate_num_updates_per_optimizer( &
optimizers, &
fit_target, &
test_fraction, &
tot_num_structures, &
use_energy, &
use_forces, &
use_force_vectors, &
lrepeated_energy_update, &
energy_fraction, &
force_fraction, &
batchsize_structures, &
batchsize_forces, &
atomic_nn_opt_ids, &
atomic_numbers, &
num_atoms_element, &
atomic_property_fraction, &
batchsize_elements, &
num_updates_energy, &
num_updates_forces, &
num_updates_property &
)
Estimates the projected number of updates per optimizer within an epoch.
Note: For "energy_and_force" fits, the routine doesn't account for
differing update rates in case of datasets with structures
which don't include all elements.
Author: Redouan El Haouari
Arguments
-
optimizers: type(OptimizerPtr) (dim: (:)) [in]– List of `optimizer`s for which the number of projected updates is estimated. -
fit_target: character [in]– Target can be either a `"energy_and_force"` fit or an `"atomic_property"` fit. -
test_fraction: real(DP) [in]– Fraction of the structure contained in `input.data` which are used as test set. -
tot_num_structures: integer [in]– Total number of structures in the dataset. -
use_energy: logical [in]– Sets, whether energy updates are performed. -
use_forces: logical [in]– Sets, whether force updates are performed. -
use_force_vectors: logical [in]– Sets, whetehr force updates are performed with the norm of the force vectors. If `.false.`, force components are used (which is the default anyway). -
lrepeated_energy_update: logical [in]– Sets, whether a force update is followed by an energy updates. Not affected by `use_energy`. -
energy_fraction: real(DP) [in]– Fraction of the structure samples, excluding those in the test set, used for energy training. -
force_fraction: real(DP) (dim: (MAX_ELEM_NUM)) [in]– Fraction of the force samples, excluding those in the test set, used for force training. -
batchsize_structures: integer [in]– Size of the structure batch in each energy update. -
batchsize_forces: integer (dim: (MAX_ELEM_NUM)) [in]– Size of the force batch in each force update. -
atomic_nn_opt_ids: integer (dim: (:)) [in]– List of all atomic neural networks present in the `HDNN` model. -
atomic_numbers: integer (dim: (:)) [in]– List of all atomic numbers present in the `HDNN` model. -
num_atoms_element: integer (dim: (MAX_ELEM_NUM)) [in]– Number of atoms per element in the dataset. -
atomic_property_fraction: real(DP) (dim: (MAX_ELEM_NUM)) [in]– Fraction of the atomic property samples, excluding those in the test set, used for atomic property training. -
batchsize_elements: integer (dim: (MAX_ELEM_NUM)) [in]– Size of the atomic property batch in each atomic property update. -
num_updates_energy: integer (dim: (:)) [out]– Projected number of energy updates for this epoch. All entries in the array are identical. -
num_updates_forces: integer (dim: (:)) [out]– Projected number of force updates for this epoch. All entries in the array are identical. -
num_updates_property: integer (dim: (:)) [out]– Projected number of atomic property updates per optimizer for this epoch.
Called By
subroutine write_optimal_epoch¶
subroutine write_optimal_epoch( &
optimal_epoch, &
opt_epoch_property, &
ltest &
)
Writes a formattated message about the optimal epoch.
Arguments
-
optimal_epoch: integer [in]– The optimal epoch, which is determined as the epoch with lowest cost with respect to the train/test set of a trained property. -
opt_epoch_property: character [in]– Property that is used to determine the optimal epoch. -
ltest: logical [in]– Flag whether train or test set is used to determine the optimal epoch.
Called By