How to use multiple calculators in the loss function?
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.
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.
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
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.