|
15 | 15 | import torch
|
16 | 16 |
|
17 | 17 | from deepmd.entrypoints.test import test as dp_test
|
| 18 | +from deepmd.entrypoints.test import test_ener as dp_test_ener |
| 19 | +from deepmd.infer.deep_eval import ( |
| 20 | + DeepEval, |
| 21 | +) |
18 | 22 | from deepmd.pt.entrypoints.main import (
|
19 | 23 | get_trainer,
|
20 | 24 | )
|
21 | 25 | from deepmd.pt.utils.utils import (
|
22 | 26 | to_numpy_array,
|
23 | 27 | )
|
| 28 | +from deepmd.utils.data import ( |
| 29 | + DeepmdData, |
| 30 | +) |
24 | 31 |
|
25 | 32 | from .model.test_permutation import (
|
26 | 33 | model_property,
|
@@ -140,6 +147,98 @@ def setUp(self) -> None:
|
140 | 147 | json.dump(self.config, fp, indent=4)
|
141 | 148 |
|
142 | 149 |
|
| 150 | +class TestDPTestForceWeight(DPTest, unittest.TestCase): |
| 151 | + def setUp(self) -> None: |
| 152 | + self.detail_file = "test_dp_test_force_weight_detail" |
| 153 | + input_json = str(Path(__file__).parent / "water/se_atten.json") |
| 154 | + with open(input_json) as f: |
| 155 | + self.config = json.load(f) |
| 156 | + self.config["training"]["numb_steps"] = 1 |
| 157 | + self.config["training"]["save_freq"] = 1 |
| 158 | + system_dir = self._prepare_weighted_system() |
| 159 | + data_file = [system_dir] |
| 160 | + self.config["training"]["training_data"]["systems"] = data_file |
| 161 | + self.config["training"]["validation_data"]["systems"] = data_file |
| 162 | + self.config["model"] = deepcopy(model_se_e2_a) |
| 163 | + self.system_dir = system_dir |
| 164 | + self.input_json = "test_dp_test_force_weight.json" |
| 165 | + with open(self.input_json, "w") as fp: |
| 166 | + json.dump(self.config, fp, indent=4) |
| 167 | + |
| 168 | + def _prepare_weighted_system(self) -> str: |
| 169 | + src = Path(__file__).parent / "water/data/single" |
| 170 | + tmp_dir = tempfile.mkdtemp() |
| 171 | + shutil.copytree(src, tmp_dir, dirs_exist_ok=True) |
| 172 | + set_dir = Path(tmp_dir) / "set.000" |
| 173 | + forces = np.load(set_dir / "force.npy") |
| 174 | + forces[0, :3] += 1.0 |
| 175 | + forces[0, -3:] += 10.0 |
| 176 | + np.save(set_dir / "force.npy", forces) |
| 177 | + natoms = forces.shape[1] // 3 |
| 178 | + atom_pref = np.ones((forces.shape[0], natoms), dtype=forces.dtype) |
| 179 | + atom_pref[:, 0] = 2.0 |
| 180 | + atom_pref[:, -1] = 0.0 |
| 181 | + np.save(set_dir / "atom_pref.npy", atom_pref) |
| 182 | + return tmp_dir |
| 183 | + |
| 184 | + def test_force_weight(self) -> None: |
| 185 | + trainer = get_trainer(deepcopy(self.config)) |
| 186 | + with torch.device("cpu"): |
| 187 | + trainer.get_data(is_train=False) |
| 188 | + model = torch.jit.script(trainer.model) |
| 189 | + tmp_model = tempfile.NamedTemporaryFile(delete=False, suffix=".pth") |
| 190 | + torch.jit.save(model, tmp_model.name) |
| 191 | + dp = DeepEval(tmp_model.name) |
| 192 | + data = DeepmdData( |
| 193 | + self.system_dir, |
| 194 | + set_prefix="set", |
| 195 | + shuffle_test=False, |
| 196 | + type_map=dp.get_type_map(), |
| 197 | + sort_atoms=False, |
| 198 | + ) |
| 199 | + err = dp_test_ener( |
| 200 | + dp, |
| 201 | + data, |
| 202 | + self.system_dir, |
| 203 | + numb_test=1, |
| 204 | + detail_file=None, |
| 205 | + has_atom_ener=False, |
| 206 | + ) |
| 207 | + test_data = data.get_test() |
| 208 | + coord = test_data["coord"].reshape([1, -1]) |
| 209 | + box = test_data["box"][:1] |
| 210 | + atype = test_data["type"][0] |
| 211 | + ret = dp.eval( |
| 212 | + coord, |
| 213 | + box, |
| 214 | + atype, |
| 215 | + fparam=None, |
| 216 | + aparam=None, |
| 217 | + atomic=False, |
| 218 | + efield=None, |
| 219 | + mixed_type=False, |
| 220 | + spin=None, |
| 221 | + ) |
| 222 | + force_pred = ret[1].reshape([1, -1]) |
| 223 | + force_true = test_data["force"][:1] |
| 224 | + weight = test_data["atom_pref"][:1] |
| 225 | + diff = force_pred - force_true |
| 226 | + mae_unweighted = np.sum(np.abs(diff)) / diff.size |
| 227 | + rmse_unweighted = np.sqrt(np.sum(diff * diff) / diff.size) |
| 228 | + denom = weight.sum() |
| 229 | + mae_weighted = np.sum(np.abs(diff) * weight) / denom |
| 230 | + rmse_weighted = np.sqrt(np.sum(diff * diff * weight) / denom) |
| 231 | + np.testing.assert_allclose(err["mae_f"][0], mae_unweighted) |
| 232 | + np.testing.assert_allclose(err["rmse_f"][0], rmse_unweighted) |
| 233 | + np.testing.assert_allclose(err["mae_fw"][0], mae_weighted) |
| 234 | + np.testing.assert_allclose(err["rmse_fw"][0], rmse_weighted) |
| 235 | + os.unlink(tmp_model.name) |
| 236 | + |
| 237 | + def tearDown(self) -> None: |
| 238 | + super().tearDown() |
| 239 | + shutil.rmtree(self.system_dir) |
| 240 | + |
| 241 | + |
143 | 242 | class TestDPTestPropertySeA(unittest.TestCase):
|
144 | 243 | def setUp(self) -> None:
|
145 | 244 | self.detail_file = "test_dp_test_property_detail"
|
|
0 commit comments