openkim / kliff

KIM-based Learning-Integrated Fitting Framework for interatomic potentials.
https://kliff.readthedocs.io
GNU Lesser General Public License v2.1
34 stars 20 forks source link

How to use multiple calculators in the loss function? #93

Open yonatank93 opened 1 year ago

yonatank93 commented 1 year ago

Hello,

I have a test case where I need to use multiple calculators when training an empirical potential. Specifically, I have a dataset consisting diamond silicon configurations with various lattice constants. For each lattice constant, I have configurations with and without perturbation. My thought is to create a calculator for the unperturbed configurations, where I only compute the energy (due to symmetry, the forces will always be zero), and another calculator for the perturbed configurations that compute both the energy and forces. I was thinking of doing this because it might speed up the calculation, since I don't need to compute forces for some configurations.

I noticed that there is _WrapperCalculator for this case, however I had several issues when using this. First, when I used _WrapperCalculator, Loss created a neural network loss function instead. If I change this line with

if isinstance(calculator, (Calculator, _WrapperCalculator)):

so that I can get the physics motivated loss function, the next error I got is related to line 266,

AttributeError: '_WrapperCalculator' object has no attribute 'use_energy'

Do you have any suggestions about this? A work around for this case that I can think of is to use the weights. However, this alternative might not work in general, e.g., if we also want to fit elastic properties that requires a separate calculator.

mjwen commented 1 year ago

Hi @yonatank93, yes, _WrapperCalculator is one way to do it. It was disabled (thus the leading underscore in its name) at certain point because the lack of testing. I am not surprised it is not working now. Did a quick fix #95 to make it work. However, it is not well tested, so please use with caution. Would be happy to discuss how to make it more formal if you are interested.

mjwen commented 1 year ago

Forget to mention that there was an example script to use it. Updated as well. https://github.com/openkim/kliff/blob/master/examples/legacy/multiple_calculators.py

yonatank93 commented 1 year ago

Thanks for this quick fix. This works for me, at least with some optimizers. If I use scipy.optimize.least_squares-based optimizer.

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/nobackup/scratch/usr/yonatank/practice/KLIFF/bootstrap/SW_multicalculators.py in <module>
    110
    111 # Train the model
--> 112 loss. Minimize(method="lm")
    113 model.echo_opt_params()

/nobackup/scratch/usr/yonatank/modules/kliff/kliff/loss.py in minimize(self, method, **kwargs)
    308             kwargs: extra keyword arguments that can be used by the scipy optimizer
    309         """
--> 310         kwargs = self._adjust_kwargs(method, **kwargs)
    311
    312         logger.info(f"Start minimization using method: {method}.")

/nobackup/scratch/usr/yonatank/modules/kliff/kliff/loss.py in _adjust_kwargs(self, method, **kwargs)
    335
    336             # adjust bounds
--> 337             if self.calculator.has_opt_params_bounds():
    338                 if method in ["trf", "dogbox"]:
    339                     bounds = self.calculator.get_opt_params_bounds()

AttributeError: '_WrapperCalculator' object has no attribute 'has_opt_params_bounds'

This is not a pressing matter, at least for my calculations. I still don't find a need to train the potential to other quantities beside energy and forces. And again for energy and forces calculation, I can still get around it with the weights. However, this might be something to consider in the future.