Skip to content

Commit a1e2642

Browse files
Add dpmodel
1 parent c834131 commit a1e2642

3 files changed

Lines changed: 30 additions & 22 deletions

File tree

deepmd/dpmodel/atomic_model/property_atomic_model.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def __init__(
2727

2828
def get_compute_stats_distinguish_types(self) -> bool:
2929
"""Get whether the fitting net computes stats which are not distinguished between different types of atoms."""
30-
return False
30+
return self.fitting_net.get_distinguish_types()
3131

3232
def get_intensive(self) -> bool:
3333
"""Whether the fitting property is intensive."""
@@ -51,6 +51,10 @@ def apply_out_stat(
5151
5252
"""
5353
out_bias, out_std = self._fetch_out_stat(self.bias_keys)
54-
for kk in self.bias_keys:
55-
ret[kk] = ret[kk] * out_std[kk][0] + out_bias[kk][0]
54+
if self.get_compute_stats_distinguish_types:
55+
for kk in self.bias_keys:
56+
ret[kk] = ret[kk] * out_std[kk][0] + out_bias[kk][atype]
57+
else:
58+
for kk in self.bias_keys:
59+
ret[kk] = ret[kk] * out_std[kk][0] + out_bias[kk][0]
5660
return ret

deepmd/dpmodel/fitting/property_fitting.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ class PropertyFittingNet(InvarFitting):
6565
default_fparam: list[float], optional
6666
The default frame parameter. If set, when `fparam.npy` files are not included in the data system,
6767
this value will be used as the default value for the frame parameter in the fitting net.
68+
distinguish_types : bool
69+
Whether to distinguish atom types when computing output statistics.
6870
"""
6971

7072
def __init__(

deepmd/dpmodel/utils/stat.py

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def _post_process_stat(
135135
"""Post process the statistics.
136136
137137
For global statistics, we do not have the std for each type of atoms,
138-
thus fake the output std by ones for all the types.
138+
thus broadcast the global std to all the types.
139139
If the shape of out_std is already the same as out_bias,
140140
we do not need to do anything.
141141
"""
@@ -144,7 +144,9 @@ def _post_process_stat(
144144
if vv.shape == out_std[kk].shape:
145145
new_std[kk] = out_std[kk]
146146
else:
147-
new_std[kk] = np.ones_like(vv)
147+
ntypes = vv.shape[0]
148+
reps = [ntypes] + [1] * (vv.ndim - 1)
149+
new_std[kk] = np.tile(out_std[kk], reps)
148150
return out_bias, new_std
149151

150152

@@ -481,6 +483,7 @@ def _compute_output_stats_global(
481483
merged_natoms[kk],
482484
assigned_bias=assigned_atom_ener[kk],
483485
rcond=rcond,
486+
intensive=intensive,
484487
)
485488
else:
486489
# this key does not have global labels, skip it.
@@ -491,26 +494,25 @@ def _compute_output_stats_global(
491494
def rmse(x: np.ndarray) -> float:
492495
return np.sqrt(np.mean(np.square(x)))
493496

494-
if model_pred is None:
495-
unbias_e = {
496-
kk: merged_natoms[kk] @ bias_atom_e[kk].reshape(ntypes, -1)
497-
for kk in bias_atom_e.keys()
498-
}
499-
else:
500-
unbias_e = {
501-
kk: model_pred[kk].reshape(nf[kk], -1)
502-
+ merged_natoms[kk] @ bias_atom_e[kk].reshape(ntypes, -1)
503-
for kk in bias_atom_e.keys()
504-
}
505-
atom_numbs = {kk: merged_natoms[kk].sum(-1) for kk in bias_atom_e.keys()}
497+
unbias_e = {}
498+
for kk in bias_atom_e.keys():
499+
coeffs = merged_natoms[kk]
500+
if intensive:
501+
total_atoms = coeffs.sum(axis=1, keepdims=True)
502+
coeffs = coeffs / total_atoms
503+
recon = coeffs @ bias_atom_e[kk].reshape(ntypes, -1)
504+
if model_pred is not None:
505+
recon += model_pred[kk].reshape(nf[kk], -1)
506+
unbias_e[kk] = recon
506507

507508
for kk in bias_atom_e.keys():
508-
rmse_ae = rmse(
509-
(unbias_e[kk].reshape(nf[kk], -1) - merged_output[kk].reshape(nf[kk], -1))
510-
/ atom_numbs[kk][:, None]
511-
)
509+
diff = unbias_e[kk].reshape(nf[kk], -1) - merged_output[kk].reshape(nf[kk], -1)
510+
if not intensive:
511+
diff /= merged_natoms[kk].sum(axis=-1, keepdims=True)
512+
rmse_ae = rmse(diff)
513+
stat_type = "per atom " if not intensive else ""
512514
log.info(
513-
f"RMSE of {kk} per atom after linear regression is: {rmse_ae} in the unit of {kk}."
515+
f"RMSE of {kk} {stat_type}after linear regression is: {rmse_ae} in the unit of {kk}."
514516
)
515517
return bias_atom_e, std_atom_e
516518

0 commit comments

Comments
 (0)