To turn off forces, force_coefficient=None or force_coefficient=0.?

Issue #144 resolved
Alireza Khorshidi created an issue

In the documentation here, lets make sure that "force_coefficient=None" is the way to turn off force training and not "force_coefficient=0".

Comments (6)

  1. Alireza Khorshidi reporter

    If you run this code, calculator number 3 and 4 will crash

    #! /usr/bin/env python
    
    from ase.calculators.emt import EMT
    from ase import Atoms, Atom
    from amp import Amp
    from amp.descriptor.gaussian import Gaussian
    from amp.model.neuralnetwork import NeuralNetwork
    from amp.model import LossFunction
    
    
    def generate_data():
        """Generates test or training data."""
    
        images = [Atoms([Atom('Au', (0, 0., 0.)),
                         Atom('Au', (1.9, 0., 0.))]),
                    Atoms([Atom('Au', (0, 0., 0.)),
                         Atom('Au', (6., 0., 0.))]),]
    
        for atoms in images:
            atoms.set_calculator(EMT())
            atoms.get_potential_energy()
    #        atoms.get_forces(apply_constraint=False) 
    
        return images
    
    if True:
        images = generate_data()
    
        # force_coefficient is None on a single core
        calc1 = Amp(descriptor=Gaussian(),
               model=NeuralNetwork(hiddenlayers=(2, 2),),
                  label='1',
               cores=1)
        calc1.model.lossfunction = LossFunction(force_coefficient=None,
                                                convergence={'energy_rmse': 0.02,
                                                             'force_rmse': None})
        calc1.train(images=images)
    
        # force_coefficient is 0. on a single core
        calc2 = Amp(descriptor=Gaussian(),
               model=NeuralNetwork(hiddenlayers=(2, 2),),
                  label='2',
               cores=1)
        calc2.model.lossfunction = LossFunction(force_coefficient=0.,
                                                convergence={'energy_rmse': 0.02,
                                                             'force_rmse': None})
        calc2.train(images=images)
    
        # force_coefficient is None on two cores
        calc3 = Amp(descriptor=Gaussian(),
               model=NeuralNetwork(hiddenlayers=(2, 2),),
                  label='3',
               cores=2)
        calc3.model.lossfunction = LossFunction(force_coefficient=None,
                                                convergence={'energy_rmse': 0.02,
                                                             'force_rmse': None})
        calc3.train(images=images)
    
        # force_coefficient is 0. on two cores
        calc4 = Amp(descriptor=Gaussian(),
               model=NeuralNetwork(hiddenlayers=(2, 2),),
                  label='4',
               cores=2)
        calc4.model.lossfunction = LossFunction(force_coefficient=0.,
                                                convergence={'energy_rmse': 0.02,
                                                             'force_rmse': None})
        calc4.train(images=images)
    
  2. andrew_peterson repo owner

    Good catch that it is only a bug on multiple cores. That should make it easier to troubleshoot.

  3. andrew_peterson repo owner

    This bug is in your commit lines @akhorshi. See below; I think line 119 is the culprit, where it sends data to fortran.

    Traceback (most recent call last):
      File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main
        "__main__", fname, loader, pkg_name)
      File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
        exec code in run_globals
      File "/home/aap/Dropbox/repositories/Amp/amp/amp/model/__main__.py", line 119, in <module>
        fingerprintprimes,)
      File "/home/aap/Dropbox/repositories/Amp/amp/amp/model/__init__.py", line 996, in ravel_data
        fingerprintprimes)
      File "/home/aap/Dropbox/repositories/Amp/amp/amp/model/__init__.py", line 966, in ravel_neighborlists_and_fingerprintprimes
        for key, derafp in fingerprintprimes[hash].iteritems():
    TypeError: 'NoneType' object has no attribute '__getitem__'
    

    But I think we should have a larger conversation about this. I think we have some duplicate code that should be removed. I think (or at least suspect) that we can move the whole if model.fortran clauses from model/__main__.py, and that can be handled in model.LossFunction.get_loss as it is now for fortran-mode on a single core. That is, from the worker's perspective, it is running in serial (cores=1) mode, even though from the master's perspective is is running in parallel. Does that make sense? Probably easier to look at it in person.

    What I'm not clear about is why/if this changed when we made it so you can turn off force training by the None keyword.

  4. Log in to comment