### Fixed
- Fixed issues related to hirshfeld volume training / prediction in the 3G.
The initialization of the model indices is still not perfect, but will be
changed anyway with the 4G.
- fixed a severe memory leak in the LAMMPS interface caused by a vector index
into the `structures` array in the prediction routines. Calls to
`FeatureCalculator%calculate_...` do not need a list of structures anymore.
- the LAMMPS interface no works when there are no atoms on an MPI process.
- the LAMMPS interface now always updates the number of local atoms on a process,
even when the total number of atoms does not change.
- Correct mapping to the feature map name, min and max during the check of the feature map range
- Rewrite of `add_line_breaks` should be correct and much more stable now
- Feature maps which had more than one feature ((smooth) overlap matrix and SF 1)
were fundamentally broken. This is fixed now.
- fixed a memory bug. During prediction, if features could be precomputed but feature
derivatives could not, memory was not properly deallocated. This also affected
the RMSE calculation.
- fixed bug with automatic force_update_scaling: with DEBUG flags, the code
crashed due to a division by zero.
- force training: if the estimated number of force updates in a structure batch
is below 50% we now correctly use the towards_atom evaluation route of the
`FeatureCalculator`.
- fixed output in `*`.test.nnatoms.out/`*`.train.nnatoms.out files. Previously,
the mapping was always wrong. Hence, the output was wrong if there was at least
one test structure.
- fixed output in `*`.train.forces.out and `*`.test.forces.out during MPI training.
- fixed memory management issues related to the feature calculator during force
training.
- Force training now correctly calculates only the necessary feature derivatives
if a low force fraction is used, which increases efficiency.
- `max_num_structures_per_chunk_per_process` was too small for the case that number
of train and test structures are both not dividable across the number of processes
which lead to allocation of too small result class objects.
- fixed incorrect comparison operator in gradient clipping.
- Fix calculation of feature derivatives with respect to the target atom of a
force training step. This may have affected training performance for large
datasets when using a small force fraction.
- The derivatives of the loss functions are now fully consistent with the loss,
i.e. are divided by the batch size.
### Added
- `epoch`.train/test.energy.out, `epoch`.train/test.forces.out and
`epoch`.train/test.nnatoms.out are now written for each `epoch` which is
divisable by the argument given to `write_frequency` in input.nn and for
the "optimal" epoch.
- It is reported which epoch is the "optimal" epoch (the one with the lowest
energy training error).
- New unittest for results sort routine.
- d_chain_d_features is now OMP-parallelized.
- During training, the code now prints the elapsed time since the last RMSE was
calculated (with default settings, this is the time for a single epoch).
- `feature_minmax_threshold` if functional again: if the range of the features is
smaller than the threshold, an erro is thrown listing all feature maps which
lead to this error.
- More useful error messages if parsing the overlap matrix keywords fails.
- All feature maps, which produce a range of features which is below the set
threshold, are now report together in the output and the program is only killed
after all feature maps have been checked.
- 4G charge training (alpha stage):
- implemented working 4G charge cost calculation and training loop including
different batching strategies and training with and without fixed hardness.
- implemented separate 4G charge prediction routines using the
`TrainingChargeEquilibrator`.
- reverse QeQ based on reference charges for electronegativity initialization
(as long as hardness is fixed). This is done by default if any `precondition`
or advanced `initialization_method` is chosen.
- New keyword `model_type_*` for all possible suffixes. Can be either
`elemental` or `hdnn`. This is mostly helpful to switch between an elemental
hardness or environment-dependent hardness.
- renamed file `hardness.data` to `weightshardness` for consistency.
- Introduced `scalinghardness.data` file.
- new activation function $f(x) = x^2$. Key is `sq`. This may be especially
helpful for scaling electronegativitity, hardness, or charge nodes.
- if hardness is not read from file, initialization of hardness is possible
based on CRC handbook Pearson hardness values.
- added additional printing of electronegativity statistics.
- improved memory scaling for 3G and 4G applications by getting rid of
intermediate d_property_d_xyz arrays.
- new batchsize option `num_atoms_in_structure_batch`. Specify
`batchsize_elements num_atoms_in_structure_batch` in your input.nn file.
- completely generalized and rewritten interface bindings based on more modular
prediction workflows.
- all `bindc(c)` routines are collected in `interface_bindings`
- new routine `runner_interface_finalize_step` to handle graceful exit and
printing of timings.
- new routine `runner_interface_reinitialize_electrostatics` to reallocate
charge equlibrators and electrostatics calculators only when necessary (e.g.
when the number of atoms in the simulation changes).
- training and prediction are fully committee compatible. Specify
`num_committee_members` in your input.nn. This also requires creating separate
folders with continuous indices (starting from 1) in the calculation directory.
These need to contain the weights files for each committee member when parsing
weights from a file.
- Separate optimizers can be assigned to each committee member.
In case of separate optimizers for each atomic NN and committee member,
`optimizer_comm [optimizer_idx] [committee_idx] [optimizer_type] ...`
must be specified, where `[optimizer_idx]` corresponds to the index given to
`opt_short`. In case of default optimizers for all atomic NNs of
each committee member, `default_optimizer_comm [committee_idx] [optimizer_type]`
must be specified.
Note: Mixing of `default_optimizer` with `default_optimizer` and
`optimizer` with `optimizer_comm` for identical `[optimizer_idx]` is not
possible and results in that an error is thrown for atomic NNs being assigned
with more than one optimizer.
- training on the total energy of the structure (like in n2p2) is now possible by
setting `pre_calc_energy_norm` to `1_over_num_atoms` and `pre_calc_force_norm`,
`post_calc_energy_loss_norm`, `post_calc_energy_grads_norm`,
`post_calc_force_loss_norm` and `post_calc_force_grads_norm` to `none`.
Good training results are obtained with the non-fading memory (i.e. standard)
Kalman Filter (`kalman_std`) with its default hyperparameters.
- in 4G charge training, the hardness weights/values are now written.
- when training an elemental hardness model, one may now specify `initialization_method`:
- `read` for reading from file weightshardness.data
- `uniform` and `normal` for initialization from a uniform or normal distribution
whose range can be controlled via the keywords `parameter_min_hardness` and
`parameter_max_hardness`.
- `reference` for setting literature values for each element.
- `reference_uniform` for initialization from a uniform distribution
centered around each literature value with a range of 30% of that value.
- `reference_normal` for initialization from a normal distribution
centered around each literature value with a standard deviation of 10% of
that value.
In the case of a 4G hardness model, the literature values are automatically chosen
to be the Pearson hardness values.
### Changed
- In the 3G prediction it is now neccessary to specify the keywords
predict_long_range_energy
and predict_short_range_energy explicitly. Previously, if specifying none of
the two, both were assumed for convenience.
Since this prevents predicting only hirshfeld volumes this was changed.
- Renamed `predict_long_range_energy` to `predict_electrostatics` and
`predict_short_range_energy` to `predict_short_range` which are both `True` by
default.
- renamed `use_vdw hirshfeld` to `predict_vdw hirshfeld`
- parsing of input.data file has been sped up.
- added committees to all output dimensions of generic interface
- pair_style takes additional inline argument `total_charge`
- new keyword `constrain_predicted_charges_before_evaluation`. This turns on the
projection to the total charge constraint during 3G charge training. `False`
by default.
- changed the STDOUT during all training procedures.
- new keyword `cost_functions` which takes a space-separated list of cost
function names (`rmse`, `mae`, `mse`). All given cost functions are used
to calculate the cost for each epoch and print it in a separate line.
- new keyword `optimal_epoch_property [property] [train|test]` to specify how
the optimal epoch is determined. The first entry must be the name of the property
to use and the second, optional column specifies whether train or test set
are used.
- keywords `force_update_scaling`, `force_Fraction`, and `batchsize_forces` can
now be specified element-specific, which is respected during training.
- new memory management strategy during training. Either all data is precomputed
or none.
- descriptors can be shared between models. Specify `feature_map default` in your
input.nn to exploit this behavior.
- hardness model can be initialized from input.nn
- LAMMPS interface is now built differently (see README.md).
- Elementwise batching and application of fractions during training was much
improved. Relevant keywords are:
- `batchsize_forces` or `batchsize_atomic_property` to control how many samples
are put into one batch. Possible formats are:
- `batchsize_forces [atomic_number] [value]` to set the batchsize for one
specific element.
- `batchsize_forces [value]` to define one global batchsize for all elements.
- The keywords `force_fraction` or `atomic_property_fraction` to control how many
samples are selected. They follow the same format as given above.
- The logical keywords `batch_atomic_properties_by_element` and `batch_forces_by_element`
as well as `apply_force_fraction_by_element` and `apply_atomic_property_fraction_by_element`.
These control whether batching and fractions are done on a per-element basis or
whether atoms are treated completely independently of their element.
- `batchsize_elements num_atoms_in_structure_batch` can still be used to make batches dynamically just
large enough to accomodate all atoms in one structure batch. This is element-specific by default.
- The normalization of loss and its gradients for energy and force batches have been remodeled.
Here, the reference and predicted quantities can be normalized by the number of atoms in the
respective structure (`num_atoms`) before the calculation of the loss and its gradients and
are controlled by the `pre_calc_[energy,force]_norm` keywords. Alternatively, these quantities
can be multiplied with number of atoms by passing `1_over_num_atoms`, enabling the training on
the total energy of the structure like in n2p2.
Additionally, the loss and its gradients can be normalized after their calculation with the
number of atoms (`num_atoms_batch`) or backward passes (`num_backward_passes_batch`)
in the respective structure batch and are controlled by the
`post_calc_[energy,force]_[loss,grads]_norm` keywords.
A summary of the available keywords is shown here,
| Keyword | Available values | Default |
|:-------:|:----------------:|:-------:|
| `pre_calc_energy_norm` | `none`, `num_atoms`, `1_over_num_atoms` | `none` |
| `pre_calc_force_norm` | `none`, `num_atoms`, `1_over_num_atoms` | `num_atoms` |
| `post_calc_energy_loss_norm` | `none`, `num_atoms_batch`, `num_backward_passes_batch` | `num_atoms_batch` |
| `post_calc_energy_grads_norm` | `none`, `num_atoms_batch`, `num_backward_passes_batch` | `none` |
| `post_calc_force_loss_norm` | `none`, `num_atoms_batch`, `num_backward_passes_batch` | `none` |
| `post_calc_force_grads_norm` | `none`, `num_atoms_batch`, `num_backward_passes_batch` | `num_atoms_batch` |
- `none` means no normalization, i.e. multiplication by 1.
- The keywords `normalize_loss_energy`, `dont_normalize_gradients_energy`
`dont_normalize_loss_forces`, `dont_normalize_gradients_forces` and
`gradient_divisor` are now no longer supported.