@@ -157,6 +157,18 @@ def __init__(self, covariance=None, calculator=None, process_group=None, meta=No
157
157
trajectory. A tape can be used for training a model by
158
158
calc.include_tape(file)
159
159
160
+ test:
161
+ For instance, if test=100 and 100 steps have passed since the last
162
+ exact calculation, an exact calculation will be performed.
163
+ This can be used for monitoring the on-the-fly ML accuracy and
164
+ has no effect on training. The exact calculation (FP) will be saved
165
+ in 'active_FP.traj' while the models predictions (ML) will be saved
166
+ in 'active_ML.traj'. These files will be overwritten in the next
167
+ simulation. The following command can be used for a quick description
168
+ of ML errors
169
+
170
+ python -m theforce.regression.scores active_ML.traj active_FP.traj
171
+
160
172
ediff, ediff_lb, ediff_ub: -> for sampling the LCEs for sparse representation
161
173
ediff controls the LCE sampling rate. You decrease ediff for higher accuracy
162
174
or increase ediff for higher speed.
@@ -383,9 +395,9 @@ def _test(self):
383
395
self ._ktest += 1
384
396
mode = 'a' if self ._ktest > 1 else 'w'
385
397
if self .rank == 0 :
386
- ase .io .Trajectory ('active_test .traj' , mode ).write (tmp )
398
+ ase .io .Trajectory ('active_FP .traj' , mode ).write (tmp )
387
399
tmp .set_calculator (SinglePointCalculator (tmp , ** self .results ))
388
- ase .io .Trajectory ('active_pred .traj' , mode ).write (tmp )
400
+ ase .io .Trajectory ('active_ML .traj' , mode ).write (tmp )
389
401
# log
390
402
self .log ('testing energy: {}' .format (energy ))
391
403
dE = self .results ['energy' ] - energy
@@ -472,13 +484,18 @@ def get_covloss(self):
472
484
return beta * vscale
473
485
474
486
def update_lce (self , loc , beta = None ):
487
+ if beta is None :
488
+ k = self .model .gp .kern (loc , self .model .X )
489
+ b = self .model .choli @k .detach ().t ()
490
+ c = (b * b ).sum () # /self.model.gp.kern(loc, loc)
491
+ beta = ((1 - c )* self .model ._vscale [loc .number ]).clamp (min = 0. ).sqrt ()
475
492
added = 0
476
493
m = self .model .indu_counts [loc .number ]
477
494
if loc .number in self .model .gp .species :
478
- if beta and beta >= self .ediff_ub :
495
+ if beta >= self .ediff_ub :
479
496
self .model .add_inducing (loc )
480
497
added = - 1 if m < 2 else 1
481
- elif beta and beta < self .ediff_lb :
498
+ elif beta < self .ediff_lb :
482
499
pass
483
500
else :
484
501
ediff = (self .ediff if m > 1
@@ -557,6 +574,8 @@ def update(self, inducing=True, data=True):
557
574
m = self .update_inducing () if inducing else 0
558
575
try_real = self .blind or type (self ._calc ) == SinglePointCalculator
559
576
update_data = (m > 0 and data ) or not inducing
577
+ if update_data and not inducing : # for include_tape
578
+ update_data = self .get_covloss ().max () > self .ediff
560
579
n = self .update_data (try_fake = not try_real ) if update_data else 0
561
580
if m > 0 or n > 0 :
562
581
self .log ('fit error (mean,std): E: {:.2g} {:.2g} F: {:.2g} {:.2g} R2: {:.4g}' .format (
@@ -565,8 +584,6 @@ def update(self, inducing=True, data=True):
565
584
self .log (f'noise: { self .model .scaled_noise } ' )
566
585
if self .pckl :
567
586
self .model .to_folder (self .pckl )
568
- if n == 0 and type (self ._calc ) == SinglePointCalculator :
569
- self ._test ()
570
587
self ._update_args = {}
571
588
return m , n
572
589
@@ -578,6 +595,7 @@ def include_data(self, data):
578
595
self ._calc = atoms .calc
579
596
atoms .set_calculator (self )
580
597
atoms .get_potential_energy ()
598
+ atoms .set_calculator (self ._calc )
581
599
self ._calc = _calc
582
600
583
601
def include_tape (self , tape ):
@@ -594,6 +612,7 @@ def include_tape(self, tape):
594
612
self ._calc = obj .calc
595
613
obj .set_calculator (self )
596
614
obj .get_potential_energy ()
615
+ obj .set_calculator (self ._calc )
597
616
added_lce = [0 , 0 ]
598
617
elif cls == 'local' :
599
618
obj .stage (self .model .descriptors , True )
0 commit comments