mlatom 2.0.1__py3.7.egg
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- EGG-INFO/PKG-INFO +145 -0
- EGG-INFO/SOURCES.txt +40 -0
- EGG-INFO/dependency_links.txt +1 -0
- EGG-INFO/native_libs.txt +1 -0
- EGG-INFO/not-zip-safe +1 -0
- EGG-INFO/requires.txt +2 -0
- EGG-INFO/scripts/MLatomF +12 -0
- EGG-INFO/scripts/mlatom +12 -0
- EGG-INFO/top_level.txt +1 -0
- MLatom/ML_NEA.py +2697 -0
- MLatom/MLatom.py +151 -0
- MLatom/MLatomF +0 -0
- MLatom/MLtasks.py +784 -0
- MLatom/__init__.py +0 -0
- MLatom/__pycache__/ML_NEA.cpython-37.pyc +0 -0
- MLatom/__pycache__/MLatom.cpython-37.pyc +0 -0
- MLatom/__pycache__/MLtasks.cpython-37.pyc +0 -0
- MLatom/__pycache__/__init__.cpython-37.pyc +0 -0
- MLatom/__pycache__/args_class.cpython-37.pyc +0 -0
- MLatom/__pycache__/doc.cpython-37.pyc +0 -0
- MLatom/__pycache__/header.cpython-37.pyc +0 -0
- MLatom/__pycache__/interface_MLatomF.cpython-37.pyc +0 -0
- MLatom/__pycache__/sliceData.cpython-37.pyc +0 -0
- MLatom/__pycache__/stopper.cpython-37.pyc +0 -0
- MLatom/args_class.py +396 -0
- MLatom/cs.so +0 -0
- MLatom/doc.py +620 -0
- MLatom/header.py +64 -0
- MLatom/interface_MLatomF.py +87 -0
- MLatom/interfaces/DeePMDkit/DP_inference.py +20 -0
- MLatom/interfaces/DeePMDkit/__init__.py +0 -0
- MLatom/interfaces/DeePMDkit/__pycache__/DP_inference.cpython-37.pyc +0 -0
- MLatom/interfaces/DeePMDkit/__pycache__/__init__.cpython-37.pyc +0 -0
- MLatom/interfaces/DeePMDkit/__pycache__/interface_DeePMDkit.cpython-37.pyc +0 -0
- MLatom/interfaces/DeePMDkit/interface_DeePMDkit.py +327 -0
- MLatom/interfaces/DeePMDkit/template.json +70 -0
- MLatom/interfaces/GAP/__init__.py +0 -0
- MLatom/interfaces/GAP/__pycache__/__init__.cpython-37.pyc +0 -0
- MLatom/interfaces/GAP/__pycache__/interface_GAP.cpython-37.pyc +0 -0
- MLatom/interfaces/GAP/interface_GAP.py +415 -0
- MLatom/interfaces/PhysNet/PhysNet_predict.py +180 -0
- MLatom/interfaces/PhysNet/PhysNet_train.py +425 -0
- MLatom/interfaces/PhysNet/__init__.py +0 -0
- MLatom/interfaces/PhysNet/__pycache__/PhysNet_predict.cpython-37.pyc +0 -0
- MLatom/interfaces/PhysNet/__pycache__/PhysNet_train.cpython-37.pyc +0 -0
- MLatom/interfaces/PhysNet/__pycache__/__init__.cpython-37.pyc +0 -0
- MLatom/interfaces/PhysNet/__pycache__/interface_PhysNet.cpython-37.pyc +0 -0
- MLatom/interfaces/PhysNet/interface_PhysNet.py +270 -0
- MLatom/interfaces/TorchANI/TorchANI_predict.py +82 -0
- MLatom/interfaces/TorchANI/TorchANI_train.py +217 -0
- MLatom/interfaces/TorchANI/__init__.py +0 -0
- MLatom/interfaces/TorchANI/__pycache__/TorchANI_predict.cpython-37.pyc +0 -0
- MLatom/interfaces/TorchANI/__pycache__/TorchANI_train.cpython-37.pyc +0 -0
- MLatom/interfaces/TorchANI/__pycache__/__init__.cpython-37.pyc +0 -0
- MLatom/interfaces/TorchANI/__pycache__/interface_TorchANI.cpython-37.pyc +0 -0
- MLatom/interfaces/TorchANI/interface_TorchANI.py +323 -0
- MLatom/interfaces/__init__.py +0 -0
- MLatom/interfaces/__pycache__/__init__.cpython-37.pyc +0 -0
- MLatom/interfaces/sGDML/__init__.py +0 -0
- MLatom/interfaces/sGDML/__pycache__/__init__.cpython-37.pyc +0 -0
- MLatom/interfaces/sGDML/__pycache__/interface_sGDML.cpython-37.pyc +0 -0
- MLatom/interfaces/sGDML/__pycache__/sgdml_dataset_from_extxyz.cpython-37.pyc +0 -0
- MLatom/interfaces/sGDML/interface_sGDML.py +276 -0
- MLatom/interfaces/sGDML/sgdml_dataset_from_extxyz.py +199 -0
- MLatom/ref.json +23 -0
- MLatom/sliceData.py +334 -0
- MLatom/stopper.py +17 -0
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import os
|
|
3
|
+
import numpy as np
|
|
4
|
+
import sys
|
|
5
|
+
import logging
|
|
6
|
+
import string
|
|
7
|
+
import random
|
|
8
|
+
|
|
9
|
+
PhysNetdir = os.environ['PhysNet']
|
|
10
|
+
sys.path.append(PhysNetdir)
|
|
11
|
+
|
|
12
|
+
import tensorflow.compat.v1 as tf
|
|
13
|
+
tf.disable_v2_behavior()
|
|
14
|
+
from shutil import copyfile
|
|
15
|
+
from datetime import datetime
|
|
16
|
+
from neural_network.NeuralNetwork import *
|
|
17
|
+
from neural_network.activation_fn import *
|
|
18
|
+
from training.Trainer import *
|
|
19
|
+
from training.DataContainer import *
|
|
20
|
+
from training.DataProvider import *
|
|
21
|
+
from training.DataQueue import *
|
|
22
|
+
|
|
23
|
+
def train(args):
|
|
24
|
+
tf.compat.v1.reset_default_graph()
|
|
25
|
+
#used for creating a "unique" id for a run (almost impossible to generate the same twice)
|
|
26
|
+
def id_generator(size=8, chars=string.ascii_uppercase + string.ascii_lowercase + string.digits):
|
|
27
|
+
return ''.join(random.SystemRandom().choice(chars) for _ in range(size))
|
|
28
|
+
|
|
29
|
+
logging.basicConfig(filename='train.log',level=logging.DEBUG)
|
|
30
|
+
|
|
31
|
+
#create directories
|
|
32
|
+
#a unique directory name is created for this run based on the input
|
|
33
|
+
if args.physnet.restart is None:
|
|
34
|
+
os.system('rm -rf '+args.mlmodelout+' > /dev/null 2>&1')
|
|
35
|
+
directory = args.mlmodelout
|
|
36
|
+
else:
|
|
37
|
+
directory=args.mlmodelin
|
|
38
|
+
logging.info("creating directories...")
|
|
39
|
+
if not os.path.exists(directory):
|
|
40
|
+
os.makedirs(directory)
|
|
41
|
+
best_dir = os.path.join(directory, 'best')
|
|
42
|
+
if not os.path.exists(best_dir):
|
|
43
|
+
os.makedirs(best_dir)
|
|
44
|
+
log_dir = os.path.join(directory, 'logs')
|
|
45
|
+
if not os.path.exists(log_dir):
|
|
46
|
+
os.makedirs(log_dir)
|
|
47
|
+
best_loss_file = os.path.join(best_dir, 'best_loss.npz')
|
|
48
|
+
best_checkpoint = os.path.join(best_dir, 'best_model.ckpt')
|
|
49
|
+
step_checkpoint = os.path.join(log_dir, 'model.ckpt')
|
|
50
|
+
|
|
51
|
+
#load dataset
|
|
52
|
+
# logging.info("loading dataset...")
|
|
53
|
+
# data = DataContainer(args.physnet.dataset)
|
|
54
|
+
subtrain = DataContainer('PhysNet_subtrain.npz')
|
|
55
|
+
validate = DataContainer('PhysNet_validate.npz')
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
args.physnet.num_train = len(subtrain)
|
|
59
|
+
args.physnet.num_valid = len(validate)
|
|
60
|
+
#write config file (to restore command line arguments)
|
|
61
|
+
logging.info("writing args to file...")
|
|
62
|
+
with open(os.path.join(directory, 'config.txt'), 'w') as f:
|
|
63
|
+
for k, v in args.data.physnet.data.items():
|
|
64
|
+
if k[0] != '_' and k != 'batch_sizes':
|
|
65
|
+
f.write('--'+ k + '='+ str(v) + "\n")
|
|
66
|
+
|
|
67
|
+
#generate DataProvider (splits dataset into training, validation and test set based on seed)
|
|
68
|
+
# data_provider = DataProvider(data, args.physnet.num_train, args.physnet.num_valid, args.physnet.batch_size, args.physnet.valid_batch_size, seed=args.physnet.seed)
|
|
69
|
+
subtrain_provider = DataProvider(subtrain, args.physnet.num_train, 0, args.physnet.batch_size, 0, seed=args.physnet.seed)
|
|
70
|
+
validate_provider = DataProvider(validate, 0, args.physnet.num_valid, 0, args.physnet.valid_batch_size, seed=args.physnet.seed)
|
|
71
|
+
|
|
72
|
+
#create neural network
|
|
73
|
+
logging.info("creating neural network...")
|
|
74
|
+
nn = NeuralNetwork(F=args.physnet.num_features,
|
|
75
|
+
K=args.physnet.num_basis,
|
|
76
|
+
sr_cut=args.physnet.cutoff,
|
|
77
|
+
num_blocks=args.physnet.num_blocks,
|
|
78
|
+
num_residual_atomic=args.physnet.num_residual_atomic,
|
|
79
|
+
num_residual_interaction=args.physnet.num_residual_interaction,
|
|
80
|
+
num_residual_output=args.physnet.num_residual_output,
|
|
81
|
+
use_electrostatic=(args.physnet.use_electrostatic==1),
|
|
82
|
+
use_dispersion=(args.physnet.use_dispersion==1),
|
|
83
|
+
s6=args.physnet.grimme_s6,
|
|
84
|
+
s8=args.physnet.grimme_s8,
|
|
85
|
+
a1=args.physnet.grimme_a1,
|
|
86
|
+
a2=args.physnet.grimme_a2,
|
|
87
|
+
Eshift=subtrain_provider.EperA_mean,
|
|
88
|
+
Escale=subtrain_provider.EperA_stdev,
|
|
89
|
+
activation_fn=shifted_softplus,
|
|
90
|
+
seed=None,
|
|
91
|
+
scope="neural_network")
|
|
92
|
+
NASdict = {'Eshift': subtrain_provider.EperA_mean,'Escale': subtrain_provider.EperA_stdev}
|
|
93
|
+
np.savez(os.path.join(directory, 'NAS.npz'), **NASdict)
|
|
94
|
+
|
|
95
|
+
logging.info("prepare training...")
|
|
96
|
+
#generate data queues for efficient training
|
|
97
|
+
train_queue = DataQueue(subtrain_provider.next_batch, capacity=1000, scope="train_data_queue")
|
|
98
|
+
valid_queue = DataQueue(validate_provider.next_valid_batch, capacity=args.physnet.num_valid//args.physnet.valid_batch_size, scope="valid_data_queue")
|
|
99
|
+
|
|
100
|
+
#get values for training and validation set
|
|
101
|
+
Eref_t, Earef_t, Fref_t, Z_t, Dref_t, Qref_t, Qaref_t, R_t, idx_i_t, idx_j_t, batch_seg_t = train_queue.dequeue_op
|
|
102
|
+
Eref_v, Earef_v, Fref_v, Z_v, Dref_v, Qref_v, Qaref_v, R_v, idx_i_v, idx_j_v, batch_seg_v = valid_queue.dequeue_op
|
|
103
|
+
|
|
104
|
+
#calculate all necessary quantities (unscaled partial charges, energies, forces)
|
|
105
|
+
Ea_t, Qa_t, Dij_t, nhloss_t = nn.atomic_properties(Z_t, R_t, idx_i_t, idx_j_t)
|
|
106
|
+
Ea_v, Qa_v, Dij_v, nhloss_v = nn.atomic_properties(Z_v, R_v, idx_i_v, idx_j_v)
|
|
107
|
+
energy_t, forces_t = nn.energy_and_forces_from_atomic_properties(Ea_t, Qa_t, Dij_t, Z_t, R_t, idx_i_t, idx_j_t, Qref_t, batch_seg_t)
|
|
108
|
+
energy_v, forces_v = nn.energy_and_forces_from_atomic_properties(Ea_v, Qa_v, Dij_v, Z_v, R_v, idx_i_v, idx_j_v, Qref_v, batch_seg_v)
|
|
109
|
+
#total charge
|
|
110
|
+
Qtot_t = tf.segment_sum(Qa_t, batch_seg_t)
|
|
111
|
+
Qtot_v = tf.segment_sum(Qa_v, batch_seg_v)
|
|
112
|
+
#dipole moment vector
|
|
113
|
+
QR_t = tf.stack([Qa_t*R_t[:,0], Qa_t*R_t[:,1], Qa_t*R_t[:,2]],1)
|
|
114
|
+
QR_v = tf.stack([Qa_v*R_v[:,0], Qa_v*R_v[:,1], Qa_v*R_v[:,2]],1)
|
|
115
|
+
D_t = tf.segment_sum(QR_t, batch_seg_t)
|
|
116
|
+
D_v = tf.segment_sum(QR_v, batch_seg_v)
|
|
117
|
+
|
|
118
|
+
#function to calculate loss, mean squared error, mean absolute error between two values
|
|
119
|
+
def calculate_errors(val1, val2, weights=1):
|
|
120
|
+
with tf.name_scope("calculate_errors"):
|
|
121
|
+
delta = tf.abs(val1-val2)
|
|
122
|
+
delta2 = delta**2
|
|
123
|
+
mse = tf.reduce_mean(delta2)
|
|
124
|
+
mae = tf.reduce_mean(delta)
|
|
125
|
+
loss = mae #mean absolute error loss
|
|
126
|
+
return loss, mse, mae
|
|
127
|
+
|
|
128
|
+
with tf.name_scope("loss"):
|
|
129
|
+
#calculate energy, force, charge and dipole errors/loss
|
|
130
|
+
#energy
|
|
131
|
+
if subtrain.E is not None:
|
|
132
|
+
eloss_t, emse_t, emae_t = calculate_errors(Eref_t, energy_t)
|
|
133
|
+
eloss_v, emse_v, emae_v = calculate_errors(Eref_v, energy_v)
|
|
134
|
+
else:
|
|
135
|
+
eloss_t, emse_t, emae_t = tf.constant(0.0), tf.constant(0.0), tf.constant(0.0)
|
|
136
|
+
eloss_v, emse_v, emae_v = tf.constant(0.0), tf.constant(0.0), tf.constant(0.0)
|
|
137
|
+
#atomic energies
|
|
138
|
+
if subtrain.Ea is not None:
|
|
139
|
+
ealoss_t, eamse_t, eamae_t = calculate_errors(Earef_t, Ea_t)
|
|
140
|
+
ealoss_v, eamse_v, eamae_v = calculate_errors(Earef_v, Ea_v)
|
|
141
|
+
else:
|
|
142
|
+
ealoss_t, eamse_t, eamae_t = tf.constant(0.0), tf.constant(0.0), tf.constant(0.0)
|
|
143
|
+
ealoss_v, eamse_v, eamae_v = tf.constant(0.0), tf.constant(0.0), tf.constant(0.0)
|
|
144
|
+
#forces
|
|
145
|
+
if subtrain.F is not None:
|
|
146
|
+
floss_t, fmse_t, fmae_t = calculate_errors(Fref_t, forces_t)
|
|
147
|
+
floss_v, fmse_v, fmae_v = calculate_errors(Fref_v, forces_v)
|
|
148
|
+
else:
|
|
149
|
+
floss_t, fmse_t, fmae_t = tf.constant(0.0), tf.constant(0.0), tf.constant(0.0)
|
|
150
|
+
floss_v, fmse_v, fmae_v = tf.constant(0.0), tf.constant(0.0), tf.constant(0.0)
|
|
151
|
+
#charge
|
|
152
|
+
if subtrain.Q is not None:
|
|
153
|
+
qloss_t, qmse_t, qmae_t = calculate_errors(Qref_t, Qtot_t)
|
|
154
|
+
qloss_v, qmse_v, qmae_v = calculate_errors(Qref_v, Qtot_v)
|
|
155
|
+
else:
|
|
156
|
+
qloss_t, qmse_t, qmae_t = tf.constant(0.0), tf.constant(0.0), tf.constant(0.0)
|
|
157
|
+
qloss_v, qmse_v, qmae_v = tf.constant(0.0), tf.constant(0.0), tf.constant(0.0)
|
|
158
|
+
#atomic charges
|
|
159
|
+
if subtrain.Qa is not None:
|
|
160
|
+
qaloss_t, qamse_t, qamae_t = calculate_errors(Qaref_t, Qa_t)
|
|
161
|
+
qaloss_v, qamse_v, qamae_v = calculate_errors(Qaref_v, Qa_v)
|
|
162
|
+
else:
|
|
163
|
+
qaloss_t, qamse_t, qamae_t = tf.constant(0.0), tf.constant(0.0), tf.constant(0.0)
|
|
164
|
+
qaloss_v, qamse_v, qamae_v = tf.constant(0.0), tf.constant(0.0), tf.constant(0.0)
|
|
165
|
+
#dipole
|
|
166
|
+
if subtrain.D is not None:
|
|
167
|
+
dloss_t, dmse_t, dmae_t = calculate_errors(Dref_t, D_t)
|
|
168
|
+
dloss_v, dmse_v, dmae_v = calculate_errors(Dref_v, D_v)
|
|
169
|
+
else:
|
|
170
|
+
dloss_t, dmse_t, dmae_t = tf.constant(0.0), tf.constant(0.0), tf.constant(0.0)
|
|
171
|
+
dloss_v, dmse_v, dmae_v = tf.constant(0.0), tf.constant(0.0), tf.constant(0.0)
|
|
172
|
+
|
|
173
|
+
#define additional variables (such that certain losses can be overwritten)
|
|
174
|
+
eloss_train = eloss_t
|
|
175
|
+
floss_train = floss_t
|
|
176
|
+
qloss_train = qloss_t
|
|
177
|
+
dloss_train = dloss_t
|
|
178
|
+
eloss_valid = eloss_v
|
|
179
|
+
floss_valid = floss_v
|
|
180
|
+
qloss_valid = qloss_v
|
|
181
|
+
dloss_valid = dloss_v
|
|
182
|
+
|
|
183
|
+
#atomic energies are present, so they replace the normal energy loss
|
|
184
|
+
if subtrain.Ea is not None:
|
|
185
|
+
eloss_train = ealoss_t
|
|
186
|
+
eloss_valid = ealoss_v
|
|
187
|
+
|
|
188
|
+
#atomic charges are present, so they replace the normal charge loss and nullify dipole loss
|
|
189
|
+
if subtrain.Qa is not None:
|
|
190
|
+
qloss_train = qaloss_t
|
|
191
|
+
qloss_valid = qaloss_v
|
|
192
|
+
dloss_train = tf.constant(0.0)
|
|
193
|
+
dloss_valid = tf.constant(0.0)
|
|
194
|
+
|
|
195
|
+
#define loss function (used to train the model)
|
|
196
|
+
l2loss = tf.reduce_mean(tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES))
|
|
197
|
+
loss_t = eloss_train + args.physnet.force_weight*floss_train + args.physnet.charge_weight*qloss_train + args.physnet.dipole_weight*dloss_train + args.physnet.nhlambda*nhloss_t + args.physnet.l2lambda*l2loss
|
|
198
|
+
loss_v = eloss_valid + args.physnet.force_weight*floss_valid + args.physnet.charge_weight*qloss_valid + args.physnet.dipole_weight*dloss_valid + args.physnet.nhlambda*nhloss_v + args.physnet.l2lambda*l2loss
|
|
199
|
+
|
|
200
|
+
#create trainer
|
|
201
|
+
trainer = Trainer(args.physnet.learning_rate, args.physnet.decay_steps, args.physnet.decay_rate, scope="trainer")
|
|
202
|
+
with tf.name_scope("trainer_ops"):
|
|
203
|
+
train_op = trainer.build_train_op(loss_t, args.physnet.ema_decay, args.physnet.max_norm)
|
|
204
|
+
save_variable_backups_op = trainer.save_variable_backups()
|
|
205
|
+
load_averaged_variables_op = trainer.load_averaged_variables()
|
|
206
|
+
restore_variable_backups_op = trainer.restore_variable_backups()
|
|
207
|
+
|
|
208
|
+
#creates a summary from key-value pairs given a dictionary
|
|
209
|
+
def create_summary(dictionary):
|
|
210
|
+
summary = tf.Summary()
|
|
211
|
+
for key, value in dictionary.items():
|
|
212
|
+
summary.value.add(tag=key, simple_value=value)
|
|
213
|
+
return summary
|
|
214
|
+
|
|
215
|
+
#create summary writer
|
|
216
|
+
nn_summary_op = tf.summary.merge_all()
|
|
217
|
+
summary_writer = tf.summary.FileWriter(logdir=log_dir, graph=tf.get_default_graph())
|
|
218
|
+
|
|
219
|
+
#create saver
|
|
220
|
+
with tf.name_scope("saver"):
|
|
221
|
+
saver = tf.train.Saver(max_to_keep=50)
|
|
222
|
+
|
|
223
|
+
#save/load best recorded loss (only the best model is saved)
|
|
224
|
+
if os.path.isfile(best_loss_file):
|
|
225
|
+
loss_file = np.load(best_loss_file)
|
|
226
|
+
best_loss = loss_file["loss"].item()
|
|
227
|
+
best_emae = loss_file["emae"].item()
|
|
228
|
+
best_ermse = loss_file["ermse"].item()
|
|
229
|
+
best_fmae = loss_file["fmae"].item()
|
|
230
|
+
best_frmse = loss_file["frmse"].item()
|
|
231
|
+
best_qmae = loss_file["qmae"].item()
|
|
232
|
+
best_qrmse = loss_file["qrmse"].item()
|
|
233
|
+
best_dmae = loss_file["dmae"].item()
|
|
234
|
+
best_drmse = loss_file["drmse"].item()
|
|
235
|
+
best_step = loss_file["step"].item()
|
|
236
|
+
else:
|
|
237
|
+
best_loss = np.Inf #initialize best loss to infinity
|
|
238
|
+
best_emae = np.Inf
|
|
239
|
+
best_ermse = np.Inf
|
|
240
|
+
best_fmae = np.Inf
|
|
241
|
+
best_frmse = np.Inf
|
|
242
|
+
best_qmae = np.Inf
|
|
243
|
+
best_qrmse = np.Inf
|
|
244
|
+
best_dmae = np.Inf
|
|
245
|
+
best_drmse = np.Inf
|
|
246
|
+
best_step = 0.
|
|
247
|
+
np.savez(best_loss_file, loss=best_loss, emae=best_emae, ermse=best_ermse,
|
|
248
|
+
fmae=best_fmae, frmse=best_frmse,
|
|
249
|
+
qmae=best_qmae, qrmse=best_qrmse,
|
|
250
|
+
dmae=best_dmae, drmse=best_drmse,
|
|
251
|
+
step=best_step)
|
|
252
|
+
|
|
253
|
+
#for calculating average performance on the training set
|
|
254
|
+
def reset_averages():
|
|
255
|
+
return 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
|
|
256
|
+
|
|
257
|
+
def update_averages(num, tmploss_avg, tmploss, emse_avg, emse, emae_avg, emae, fmse_avg, fmse, fmae_avg, fmae,
|
|
258
|
+
qmse_avg, qmse, qmae_avg, qmae, dmse_avg, dmse, dmae_avg, dmae):
|
|
259
|
+
num += 1
|
|
260
|
+
tmploss_avg += (tmploss-tmploss_avg)/num
|
|
261
|
+
emse_avg += (emse-emse_avg)/num
|
|
262
|
+
emae_avg += (emae-emae_avg)/num
|
|
263
|
+
fmse_avg += (fmse-fmse_avg)/num
|
|
264
|
+
fmae_avg += (fmae-fmae_avg)/num
|
|
265
|
+
qmse_avg += (qmse-qmse_avg)/num
|
|
266
|
+
qmae_avg += (qmae-qmae_avg)/num
|
|
267
|
+
dmse_avg += (dmse-dmse_avg)/num
|
|
268
|
+
dmae_avg += (dmae-dmae_avg)/num
|
|
269
|
+
return num, tmploss_avg, emse_avg, emae_avg, fmse_avg, fmae_avg, qmse_avg, qmae_avg, dmse_avg, dmae_avg
|
|
270
|
+
|
|
271
|
+
#initialize training set error averages
|
|
272
|
+
num_t, tmploss_avg_t, emse_avg_t, emae_avg_t, fmse_avg_t, fmae_avg_t, qmse_avg_t, qmae_avg_t, dmse_avg_t, dmae_avg_t = reset_averages()
|
|
273
|
+
|
|
274
|
+
#create tensorflow session
|
|
275
|
+
with tf.Session() as sess:
|
|
276
|
+
if (args.physnet.record_run_metadata > 0):
|
|
277
|
+
run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
|
|
278
|
+
run_metadata = tf.RunMetadata()
|
|
279
|
+
else:
|
|
280
|
+
run_options = None
|
|
281
|
+
run_metadata = None
|
|
282
|
+
|
|
283
|
+
#start data queues
|
|
284
|
+
coord = tf.train.Coordinator()
|
|
285
|
+
train_queue.create_thread(sess, coord)
|
|
286
|
+
valid_queue.create_thread(sess, coord)
|
|
287
|
+
|
|
288
|
+
#initialize variables
|
|
289
|
+
tf.global_variables_initializer().run()
|
|
290
|
+
|
|
291
|
+
#restore latest checkpoint
|
|
292
|
+
checkpoint = tf.train.latest_checkpoint(log_dir)
|
|
293
|
+
if checkpoint is not None:
|
|
294
|
+
step = int(checkpoint.split('-')[-1]) #reads step from checkpoint filename
|
|
295
|
+
saver.restore(sess, checkpoint)
|
|
296
|
+
sess.run(trainer.global_step.assign(step))
|
|
297
|
+
else:
|
|
298
|
+
step = 0
|
|
299
|
+
|
|
300
|
+
#training loop
|
|
301
|
+
logging.info("starting training...")
|
|
302
|
+
while not coord.should_stop():
|
|
303
|
+
#finish training when maximum number of iterations is reached
|
|
304
|
+
if step > args.physnet.max_steps:
|
|
305
|
+
coord.request_stop()
|
|
306
|
+
break
|
|
307
|
+
|
|
308
|
+
#perform training step
|
|
309
|
+
step += 1
|
|
310
|
+
_, tmploss, emse, emae, fmse, fmae, qmse, qmae, dmse, dmae = sess.run([train_op, loss_t, emse_t, emae_t, fmse_t, fmae_t, qmse_t, qmae_t, dmse_t, dmae_t], options=run_options, feed_dict={nn.keep_prob: args.physnet.keep_prob}, run_metadata=run_metadata)
|
|
311
|
+
|
|
312
|
+
#update averages
|
|
313
|
+
num_t, tmploss_avg_t, emse_avg_t, emae_avg_t, fmse_avg_t, fmae_avg_t, qmse_avg_t, qmae_avg_t, dmse_avg_t, dmae_avg_t = update_averages(num_t, tmploss_avg_t, tmploss, emse_avg_t, emse, emae_avg_t, emae, fmse_avg_t, fmse, fmae_avg_t, fmae, qmse_avg_t, qmse, qmae_avg_t, qmae, dmse_avg_t, dmse, dmae_avg_t, dmae)
|
|
314
|
+
|
|
315
|
+
#save progress
|
|
316
|
+
if (step % args.physnet.save_interval == 0):
|
|
317
|
+
saver.save(sess, step_checkpoint, global_step=step)
|
|
318
|
+
|
|
319
|
+
#check performance on the validation set
|
|
320
|
+
if (step % args.physnet.validation_interval == 0):
|
|
321
|
+
#save backup variables and load averaged variables
|
|
322
|
+
sess.run(save_variable_backups_op)
|
|
323
|
+
sess.run(load_averaged_variables_op)
|
|
324
|
+
|
|
325
|
+
#initialize averages to 0
|
|
326
|
+
num_v, tmploss_avg_v, emse_avg_v, emae_avg_v, fmse_avg_v, fmae_avg_v, qmse_avg_v, qmae_avg_v, dmse_avg_v, dmae_avg_v = reset_averages()
|
|
327
|
+
#compute averages
|
|
328
|
+
for i in range(args.physnet.num_valid//args.physnet.valid_batch_size):
|
|
329
|
+
tmploss, emse, emae, fmse, fmae, qmse, qmae, dmse, dmae = sess.run([loss_v, emse_v, emae_v, fmse_v, fmae_v, qmse_v, qmae_v, dmse_v, dmae_v])
|
|
330
|
+
num_v, tmploss_avg_v, emse_avg_v, emae_avg_v, fmse_avg_v, fmae_avg_v, qmse_avg_v, qmae_avg_v, dmse_avg_v, dmae_avg_v = update_averages(num_v, tmploss_avg_v, tmploss, emse_avg_v, emse, emae_avg_v, emae, fmse_avg_v, fmse, fmae_avg_v, fmae, qmse_avg_v, qmse, qmae_avg_v, qmae, dmse_avg_v, dmse, dmae_avg_v, dmae)
|
|
331
|
+
|
|
332
|
+
#store results in dictionary
|
|
333
|
+
results = {}
|
|
334
|
+
results["loss_valid"] = tmploss_avg_v
|
|
335
|
+
if subtrain.E is not None:
|
|
336
|
+
results["energy_mae_valid"] = emae_avg_v
|
|
337
|
+
results["energy_rmse_valid"] = np.sqrt(emse_avg_v)
|
|
338
|
+
if subtrain.F is not None:
|
|
339
|
+
results["forces_mae_valid"] = fmae_avg_v
|
|
340
|
+
results["forces_rmse_valid"] = np.sqrt(fmse_avg_v)
|
|
341
|
+
if subtrain.Q is not None:
|
|
342
|
+
results["charge_mae_valid"] = qmae_avg_v
|
|
343
|
+
results["charge_rmse_valid"] = np.sqrt(qmse_avg_v)
|
|
344
|
+
if subtrain.D is not None:
|
|
345
|
+
results["dipole_mae_valid"] = dmae_avg_v
|
|
346
|
+
results["dipole_rmse_valid"] = np.sqrt(dmse_avg_v)
|
|
347
|
+
|
|
348
|
+
if results["loss_valid"] < best_loss:
|
|
349
|
+
best_loss = results["loss_valid"]
|
|
350
|
+
if subtrain.E is not None:
|
|
351
|
+
best_emae = results["energy_mae_valid"]
|
|
352
|
+
best_ermse = results["energy_rmse_valid"]
|
|
353
|
+
else:
|
|
354
|
+
best_emae = np.Inf
|
|
355
|
+
best_ermse = np.Inf
|
|
356
|
+
if subtrain.F is not None:
|
|
357
|
+
best_fmae = results["forces_mae_valid"]
|
|
358
|
+
best_frmse = results["forces_rmse_valid"]
|
|
359
|
+
else:
|
|
360
|
+
best_fmae = np.Inf
|
|
361
|
+
best_frmse = np.Inf
|
|
362
|
+
if subtrain.Q is not None:
|
|
363
|
+
best_qmae = results["charge_mae_valid"]
|
|
364
|
+
best_qrmse = results["charge_rmse_valid"]
|
|
365
|
+
else:
|
|
366
|
+
best_qmae = np.Inf
|
|
367
|
+
best_qrmse = np.Inf
|
|
368
|
+
if subtrain.D is not None:
|
|
369
|
+
best_dmae = results["dipole_mae_valid"]
|
|
370
|
+
best_drmse = results["dipole_rmse_valid"]
|
|
371
|
+
else:
|
|
372
|
+
best_dmae = np.Inf
|
|
373
|
+
best_drmse = np.Inf
|
|
374
|
+
best_step = step
|
|
375
|
+
np.savez(best_loss_file, loss=best_loss, emae=best_emae, ermse=best_ermse,
|
|
376
|
+
fmae=best_fmae, frmse=best_frmse,
|
|
377
|
+
qmae=best_qmae, qrmse=best_qrmse,
|
|
378
|
+
dmae=best_dmae, drmse=best_drmse,
|
|
379
|
+
step=best_step)
|
|
380
|
+
nn.save(sess, best_checkpoint, global_step=step)
|
|
381
|
+
results["loss_best"] = best_loss
|
|
382
|
+
if subtrain.E is not None:
|
|
383
|
+
results["energy_mae_best"] = best_emae
|
|
384
|
+
results["energy_rmse_best"] = best_ermse
|
|
385
|
+
if subtrain.F is not None:
|
|
386
|
+
results["forces_mae_best"] = best_fmae
|
|
387
|
+
results["forces_rmse_best"] = best_frmse
|
|
388
|
+
if subtrain.Q is not None:
|
|
389
|
+
results["charge_mae_best"] = best_qmae
|
|
390
|
+
results["charge_rmse_best"] = best_qrmse
|
|
391
|
+
if subtrain.D is not None:
|
|
392
|
+
results["dipole_mae_best"] = best_dmae
|
|
393
|
+
results["dipole_rmse_best"] = best_drmse
|
|
394
|
+
summary = create_summary(results)
|
|
395
|
+
summary_writer.add_summary(summary, global_step=step)
|
|
396
|
+
|
|
397
|
+
#restore backup variables
|
|
398
|
+
sess.run(restore_variable_backups_op)
|
|
399
|
+
|
|
400
|
+
#generate summaries
|
|
401
|
+
if (step % args.physnet.summary_interval == 0) and (step > 0):
|
|
402
|
+
results = {}
|
|
403
|
+
results["loss_train"] = tmploss_avg_t
|
|
404
|
+
if subtrain.E is not None:
|
|
405
|
+
results["energy_mae_train"] = emae_avg_t
|
|
406
|
+
results["energy_rmse_train"] = np.sqrt(emse_avg_t)
|
|
407
|
+
if subtrain.F is not None:
|
|
408
|
+
results["forces_mae_train"] = fmae_avg_t
|
|
409
|
+
results["forces_rmse_train"] = np.sqrt(fmse_avg_t)
|
|
410
|
+
if subtrain.Q is not None:
|
|
411
|
+
results["charge_mae_train"] = qmae_avg_t
|
|
412
|
+
results["charge_rmse_train"] = np.sqrt(qmse_avg_t)
|
|
413
|
+
if subtrain.D is not None:
|
|
414
|
+
results["dipole_mae_train"] = dmae_avg_t
|
|
415
|
+
results["dipole_rmse_train"] = np.sqrt(dmse_avg_t)
|
|
416
|
+
num_t, tmploss_avg_t, emse_avg_t, emae_avg_t, fmse_avg_t, fmae_avg_t, qmse_avg_t, qmae_avg_t, dmse_avg_t, dmae_avg_t = reset_averages()
|
|
417
|
+
|
|
418
|
+
summary = create_summary(results)
|
|
419
|
+
summary_writer.add_summary(summary, global_step=step)
|
|
420
|
+
nn_summary = nn_summary_op.eval()
|
|
421
|
+
summary_writer.add_summary(nn_summary, global_step=step)
|
|
422
|
+
if (args.physnet.record_run_metadata > 0):
|
|
423
|
+
summary_writer.add_run_metadata(run_metadata, 'step %d' % step, global_step=step)
|
|
424
|
+
if subtrain.E is not None:
|
|
425
|
+
print(str(step)+'/'+str(args.physnet.max_steps), "loss:", results["loss_train"], "best:", best_loss, "emae:", results["energy_mae_train"], "best:", best_emae)
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|