From 4460935f3e8d19cbc069096f1e5826d4525022b0 Mon Sep 17 00:00:00 2001 From: Yuheng Wang Date: Mon, 10 Feb 2025 19:06:53 +0800 Subject: [PATCH] add application/cdvae in MindChemistry --- MindChemistry/applications/cdvae/README.md | 131 +++++++ .../applications/cdvae/compute_metrics.py | 321 +++++++++++++++++ .../applications/cdvae/conf/configs.yaml | 65 ++++ .../cdvae/conf/data/carbon_24.yaml | 12 + .../applications/cdvae/conf/data/mp_20.yaml | 12 + .../applications/cdvae/conf/data/perov_5.yaml | 12 + .../applications/cdvae/create_dataset.py | 341 ++++++++++++++++++ .../applications/cdvae/evaluation.py | 192 ++++++++++ .../cdvae/images/illustrative.png | Bin 0 -> 177452 bytes .../applications/cdvae/mp_20_process.py | 72 ++++ .../applications/cdvae/requirements.txt | 12 + .../applications/cdvae/src/__init__.py | 15 + .../applications/cdvae/src/dataloader.py | 233 ++++++++++++ .../applications/cdvae/src/evaluate_utils.py | 191 ++++++++++ .../applications/cdvae/src/metrics_utils.py | 191 ++++++++++ MindChemistry/applications/cdvae/train.py | 185 ++++++++++ .../cell/gemnet/layers/base_layers.py | 4 +- 17 files changed, 1987 insertions(+), 2 deletions(-) create mode 100644 MindChemistry/applications/cdvae/README.md create mode 100644 MindChemistry/applications/cdvae/compute_metrics.py create mode 100644 MindChemistry/applications/cdvae/conf/configs.yaml create mode 100644 MindChemistry/applications/cdvae/conf/data/carbon_24.yaml create mode 100644 MindChemistry/applications/cdvae/conf/data/mp_20.yaml create mode 100644 MindChemistry/applications/cdvae/conf/data/perov_5.yaml create mode 100644 MindChemistry/applications/cdvae/create_dataset.py create mode 100644 MindChemistry/applications/cdvae/evaluation.py create mode 100644 MindChemistry/applications/cdvae/images/illustrative.png create mode 100644 MindChemistry/applications/cdvae/mp_20_process.py create mode 100644 MindChemistry/applications/cdvae/requirements.txt create mode 100644 MindChemistry/applications/cdvae/src/__init__.py create mode 100644 MindChemistry/applications/cdvae/src/dataloader.py create mode 100644 MindChemistry/applications/cdvae/src/evaluate_utils.py create mode 100644 MindChemistry/applications/cdvae/src/metrics_utils.py create mode 100644 MindChemistry/applications/cdvae/train.py diff --git a/MindChemistry/applications/cdvae/README.md b/MindChemistry/applications/cdvae/README.md new file mode 100644 index 000000000..167242284 --- /dev/null +++ b/MindChemistry/applications/cdvae/README.md @@ -0,0 +1,131 @@ +# 模型名称 + +> CDVAE + +## 介绍 + +> Crystal Diffusion Variational AutoEncoder (CDVAE)是用来生成材料的周期性结构的SOTA模型,相关论文已发表在ICLR上。模型主要有两个部分组成,首先是encoder部分,将输入得信息转化成隐变量z,部分简单得特性,如原子数量和晶格常数等,直接使用MLP进行decode得到输出,其他部分如原子种类和原子在晶格中得位置等,则通过扩散模型得到。具体模型结构如下图所示: + +
+ model_structure +
+ +## 数据集 + +> 提供了三个数据集: + +1. Perov_5 (Castelli et al., 2012): 包含接近19000个钙钛矿晶体结构,结构相似,但是组成不同,下载地址:[Perov_5](https://figshare.com/articles/dataset/Perov5/22705189)。 +2. Carbon_24 (Pickard, 2020): 包含10000个仅包含碳原子的晶体结构,因此其具有相同的组成,但是结构不同,下载地址:[Carbon_24](https://figshare.com/articles/dataset/Carbon24/22705192)。 +3. MP_20(Jain et al., 2013): 包含有45000个无机材料结构,包含绝大多数小于单胞小于20个原子的实验已知材料,下载地址:[mp_20](https://figshare.com/articles/dataset/mp_20/25563693)。 + +前两个数据集下载后直接放在./data目录下即可。MP_20数据集下载后运行`python ./cdvae/dataloader/mp_20_process.py --init_path ./data/mp_20.json --data_path ./data/mp_20`, 其中 init_path是下载得到的json格式数据集的位置,而data_path是dataset存放的位置。 + +## 环境要求 + +> 1. 安装`pip install -r requirements.txt` + +## 脚本说明 + +### 代码目录结构 + +```txt +└─cdvae + │ README.md README文件 + │ train.py 训练启动脚本 + │ evaluation.py 推理启动脚本 + │ compute_metrics.py 评估结果脚本 + │ create_dataset.py 生成数据集 + │ + └─src + │ evaluate_utils.py 推理结果生成 + │ metrics_utils.py 评估结果计算 + │ dataloader.py 将数据集加载到网络 + | mp_20_process.py 对mp_20数据集预处理 + │ + └─conf 参数配置 + │ config.yaml 网络参数 + └─data 数据集参数 +``` + +## 训练 + +## 快速开始 + +> 训练命令: `python train.py --dataset 'perov_5'` + +### 命令行参数 + +```txt +dataset: 使用得数据集,perov_5, carbon_24, mp_20 +create_dataset: 是否重新对数据集进行处理 +num_sample_train: 如重新处理数据集,训练集得大小,-1为使用全部原始数据 +num_samples_val:如重新处理数据集,验证集得大小,-1为使用全部原始数据 +num_samples_test:如重新处理数据集,测试集得大小,-1为使用全部原始数据 +name_ckpt:保存权重的路径和名称 +load_ckpt:是否读取权重 +device_target:MindSpore使用的后端 +device_id:如MindSpore使用昇腾后端,使用的NPU卡号 +epoch_num:训练的epoch数 +``` + +## 推理评估过程 + +### 推理过程 + +```txt +1.将权重checkpoint文件保存至 `/loss/`目录下(默认读取目录) +2.执行推理脚本:reconstruction任务: + python evaluation.py --dataset perov_5 --tasks 'recon' (指定dataset为perov_5) + generation任务: + python evaluation.py --dataset perov_5 --tasks 'gen' + optimization任务(如需使用optimization,在训练时请在configs.yaml中将predict_property设置为True): + python evaluation.py --dataset perov_5 --tasks 'opt' +``` + +### 命令行参数 + +```txt +device_target:MindSpore使用的后端 +device_id:如MindSpore使用昇腾后端,使用的NPU卡号 +model_path: 权重保存路径 +dataset: 使用得数据集,perov_5, carbon_24, mp_20 +tasks:推理执行的任务,可选:recon,gen,opt +n_step_each:执行的denoising的步数 +step_lr:opt任务中设置的lr +min_sigma:生成随机噪声的最小值 +save_traj:是否保存traj +disable_bar:是否展示进度条 +num_evals:gen任务中产生的结果数量 +start_from:随机或从头开始读取数据集,可选:randon, data +batch_size: batch_size大小 +force_num_atoms:是否限制原子数不变 +force_atom_types:是否限制原子种类不变 +label:推理结果保存时的名称 +``` + +推理结果 + +```txt +可以在`/eval_result/`路径下找到推理的输出文件。 +reconstruction的输出文件为eval_recon.npy和gt_recon.npy,分别包含了reconstruction后的晶体结构信息以及作为ground truth的晶体结构信息; +generation的输出文件为eval_gen.npy,包含了随机生成结果的晶体结构信息; +optimization的输出文件为eval_opt.npy,包含了基于特定性质优化的晶体结构信息。 +``` + +### 结果评估 + +```txt +运行 python comput_metrics.py --eval_path './eval_result' --dataset 'perov_5' --task recon, 结果会保存在./eval_path文件夹下的eval_metrics.json文件中(目前支持recon和generation两种模式) +``` + +## 引用 + +[1] Xie T, Fu X, Ganea O E, et al. Crystal diffusion variational autoencoder for periodic material generation[J]. arXiv preprint arXiv:2110.06197, 2021. + +[2] Castelli I E, Landis D D, Thygesen K S, et al. New cubic perovskites for one-and two-photon water splitting using the computational materials repository[J]. Energy & Environmental Science, 2012, 5(10): 9034-9043. + +[3] Castelli I E, Olsen T, Datta S, et al. Computational screening of perovskite metal oxides for optimal solar light capture[J]. Energy & Environmental Science, 2012, 5(2): 5814-5819. + +[4] Pickard C J. AIRSS data for carbon at 10GPa and the C+ N+ H+ O system at 1GPa[J]. (No Title), 2020. + +[5] Jain A, Ong S P, Hautier G, et al. Commentary: The Materials Project: A materials genome approach to accelerating materials innovation[J]. APL materials, 2013, 1(1). \ No newline at end of file diff --git a/MindChemistry/applications/cdvae/compute_metrics.py b/MindChemistry/applications/cdvae/compute_metrics.py new file mode 100644 index 000000000..e51be922e --- /dev/null +++ b/MindChemistry/applications/cdvae/compute_metrics.py @@ -0,0 +1,321 @@ +# Copyright 2025 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +"""Compute metrics +""" +from collections import Counter +import logging +import argparse +import os +import json + +import numpy as np +from tqdm import tqdm +from p_tqdm import p_map +from scipy.stats import wasserstein_distance +from pymatgen.core.structure import Structure +from pymatgen.core.composition import Composition +from pymatgen.core.lattice import Lattice +from pymatgen.analysis.structure_matcher import StructureMatcher +from matminer.featurizers.site.fingerprint import CrystalNNFingerprint +from matminer.featurizers.composition.composite import ElementProperty +from mindchemistry.cell.gemnet.data_utils import StandardScaler +from src.metrics_utils import ( + smact_validity, structure_validity, get_fp_pdist, + get_crystals_list, compute_cov) + +CRYSTALNNFP = CrystalNNFingerprint.from_preset("ops") +COMPFP = ElementProperty.from_preset("magpie") + +COV_CUTOFFS = { + "mp_20": {"struct": 0.4, "comp": 10.}, + "carbon_24": {"struct": 0.2, "comp": 4.}, + "perov_5": {"struct": 0.2, "comp": 4}, +} +# threshold for coverage metrics, olny struct distance and comp distance +# smaller than the threshold will be counted as covered. + + +class Crystal(): + """get crystal structures""" + + def __init__(self, crys_array_dict): + self.frac_coords = crys_array_dict["frac_coords"] + self.atom_types = crys_array_dict["atom_types"] + self.lengths = crys_array_dict["lengths"] + self.angles = crys_array_dict["angles"] + self.dict = crys_array_dict + + self.get_structure() + self.get_composition() + self.get_validity() + self.get_fingerprints() + + def get_structure(self): + """get structure""" + if min(self.lengths.tolist()) < 0: + self.constructed = False + self.invalid_reason = "non_positive_lattice" + else: + try: + self.structure = Structure( + lattice=Lattice.from_parameters( + *(self.lengths.tolist() + self.angles.tolist())), + species=self.atom_types, coords=self.frac_coords, coords_are_cartesian=False) + self.constructed = True + except (ValueError, AttributeError, TypeError): + self.constructed = False + self.invalid_reason = "construction_raises_exception" + if self.structure.volume < 0.1: + self.constructed = False + self.invalid_reason = "unrealistically_small_lattice" + + def get_composition(self): + elem_counter = Counter(self.atom_types) + composition = [(elem, elem_counter[elem]) + for elem in sorted(elem_counter.keys())] + elems, counts = list(zip(*composition)) + counts = np.array(counts) + counts = counts / np.gcd.reduce(counts) + self.elems = elems + self.comps = tuple(counts.astype("int").tolist()) + + def get_validity(self): + self.comp_valid = smact_validity(self.elems, self.comps) + if self.constructed: + self.struct_valid = structure_validity(self.structure) + else: + self.struct_valid = False + self.valid = self.comp_valid and self.struct_valid + + def get_fingerprints(self): + """get fingerprints""" + elem_counter = Counter(self.atom_types) + comp = Composition(elem_counter) + self.comp_fp = COMPFP.featurize(comp) + try: + site_fps = [CRYSTALNNFP.featurize( + self.structure, i) for i in range(len(self.structure))] + except (ValueError, AttributeError, TypeError): + # counts crystal as invalid if fingerprint cannot be constructed. + self.valid = False + self.comp_fp = None + self.struct_fp = None + return + self.struct_fp = np.array(site_fps).mean(axis=0) + + +class RecEval(): + """reconstruction evaluation result""" + + def __init__(self, pred_crys, gt_crys, stol=0.5, angle_tol=10, ltol=0.3): + assert len(pred_crys) == len(gt_crys) + self.matcher = StructureMatcher( + stol=stol, angle_tol=angle_tol, ltol=ltol) + self.preds = pred_crys + self.gts = gt_crys + + def get_match_rate_and_rms(self): + """get match rate and rms, match rate shows how much rate of the prediction has + the same structure as the ground truth.""" + def process_one(pred, gt, is_valid): + if not is_valid: + return None + try: + rms_dist = self.matcher.get_rms_dist( + pred.structure, gt.structure) + rms_dist = None if rms_dist is None else rms_dist[0] + return rms_dist + except (ValueError, AttributeError, TypeError): + return None + validity = [c.valid for c in self.preds] + + rms_dists = [] + for i in tqdm(range(len(self.preds))): + rms_dists.append(process_one( + self.preds[i], self.gts[i], validity[i])) + rms_dists = np.array(rms_dists) + match_rate = sum(x is not None for x in rms_dists) / len(self.preds) + mean_rms_dist = np.array( + [x for x in rms_dists if x is not None]).mean() + return {"match_rate": match_rate, + "rms_dist": mean_rms_dist} + + def get_metrics(self): + return self.get_match_rate_and_rms() + + +class GenEval(): + """Generation Evaluation result""" + + def __init__(self, pred_crys, gt_crys, comp_scaler, n_samples=10, eval_model_name=None): + self.crys = pred_crys + self.gt_crys = gt_crys + self.n_samples = n_samples + self.eval_model_name = eval_model_name + self.comp_scaler = comp_scaler + + valid_crys = [c for c in pred_crys if c.valid] + if len(valid_crys) >= n_samples: + sampled_indices = np.random.choice( + len(valid_crys), n_samples, replace=False) + self.valid_samples = [valid_crys[i] for i in sampled_indices] + else: + raise Exception( + f"not enough valid crystals in the predicted set: {len(valid_crys)}/{n_samples}") + + def get_validity(self): + """ + Compute Validity, which means whether the structure is reasonable and phyically stable + in both composition and structure. + """ + comp_valid = np.array([c.comp_valid for c in self.crys]).mean() + struct_valid = np.array([c.struct_valid for c in self.crys]).mean() + valid = np.array([c.valid for c in self.crys]).mean() + return {"comp_valid": comp_valid, + "struct_valid": struct_valid, + "valid": valid} + + def get_comp_diversity(self): + """the earth mover’s distance (EMD) between the property distribution of + generated materials and test materials. + """ + comp_fps = [c.comp_fp for c in self.valid_samples] + comp_fps = self.comp_scaler.transform(comp_fps) + comp_div = get_fp_pdist(comp_fps) + return {"comp_div": comp_div} + + def get_struct_diversity(self): + return {"struct_div": get_fp_pdist([c.struct_fp for c in self.valid_samples])} + + def get_density_wdist(self): + pred_densities = [c.structure.density for c in self.valid_samples] + gt_densities = [c.structure.density for c in self.gt_crys] + wdist_density = wasserstein_distance(pred_densities, gt_densities) + return {"wdist_density": wdist_density} + + def get_num_elem_wdist(self): + pred_nelems = [len(set(c.structure.species)) + for c in self.valid_samples] + gt_nelems = [len(set(c.structure.species)) for c in self.gt_crys] + wdist_num_elems = wasserstein_distance(pred_nelems, gt_nelems) + return {"wdist_num_elems": wdist_num_elems} + + def get_coverage(self): + """measure the similarity between ensembles of generated materials + and ground truth materials. COV-R measures the percentage of + ground truth materials being correctly predicted. + """ + cutoff_dict = COV_CUTOFFS[self.eval_model_name] + (cov_metrics_dict, _) = compute_cov( + self.crys, self.gt_crys, self.comp_scaler, + struc_cutoff=cutoff_dict["struct"], + comp_cutoff=cutoff_dict["comp"]) + return cov_metrics_dict + + def get_metrics(self): + metrics = {} + metrics.update(self.get_validity()) + metrics.update(self.get_comp_diversity()) + metrics.update(self.get_struct_diversity()) + metrics.update(self.get_density_wdist()) + metrics.update(self.get_num_elem_wdist()) + print(f'evaluation metrics:{metrics}') + metrics.update(self.get_coverage()) + return metrics + + +def get_crystal_array_list(data, gt_data=None, ground_truth=False): + """get crystal array list""" + crys_array_list = get_crystals_list( + np.concatenate(data["frac_coords"], axis=1).squeeze(0), + np.concatenate(data["atom_types"], axis=1).squeeze(0), + np.concatenate(data["lengths"], axis=1).squeeze(0), + np.concatenate(data["angles"], axis=1).squeeze(0), + np.concatenate(data["num_atoms"], axis=1).squeeze(0)) + + # if "input_data_batch" in data: + if ground_truth: + true_crystal_array_list = get_crystals_list( + np.concatenate(gt_data["frac_coords"], axis=0).squeeze(), + np.concatenate(gt_data["atom_types"], axis=0).squeeze(), + np.concatenate(gt_data["lengths"], + axis=0).squeeze().reshape(-1, 3), + np.concatenate(gt_data["angles"], axis=0).squeeze().reshape(-1, 3), + np.concatenate(gt_data["num_atoms"], axis=0).squeeze()) + else: + true_crystal_array_list = None + + return crys_array_list, true_crystal_array_list + + +def main(args): + all_metrics = {} + eval_model_name = args.dataset + + if "recon" in args.tasks: + out_data = np.load(args.eval_path+"/eval_recon.npy", + allow_pickle=True).item() + gt_data = np.load(args.eval_path+"/gt_recon.npy", + allow_pickle=True).item() + crys_array_list, true_crystal_array_list = get_crystal_array_list( + out_data, gt_data, ground_truth=True) + pred_crys = p_map(Crystal, crys_array_list) + gt_crys = p_map(Crystal, true_crystal_array_list) + + rec_evaluator = RecEval(pred_crys, gt_crys) + recon_metrics = rec_evaluator.get_metrics() + all_metrics.update(recon_metrics) + + if "gen" in args.tasks: + out_data = np.load(args.eval_path+"/eval_gen.npy", + allow_pickle=True).item() + gt_data = np.load(args.eval_path+"/gt_recon.npy", + allow_pickle=True).item() + crys_array_list, true_crystal_array_list = get_crystal_array_list( + out_data, gt_data, ground_truth=True) + + gen_crys = p_map(Crystal, crys_array_list) + gt_crys = p_map(Crystal, true_crystal_array_list) + gt_comp_fps = [c.comp_fp for c in gt_crys] + gt_fp_np = np.array(gt_comp_fps) + comp_scaler = StandardScaler(replace_nan_token=0.) + comp_scaler.fit(gt_fp_np) + + gen_evaluator = GenEval( + gen_crys, gt_crys, comp_scaler, eval_model_name=eval_model_name) + gen_metrics = gen_evaluator.get_metrics() + all_metrics.update(gen_metrics) + + logging.info(all_metrics) + + if args.label == "": + metrics_out_file = "eval_metrics.json" + else: + metrics_out_file = f"eval_metrics_{args.label}.json" + metrics_out_file = os.path.join(args.eval_path, metrics_out_file) + + with open(metrics_out_file, "w") as f: + json.dump(all_metrics, f) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--dataset", default="perov_5") + parser.add_argument("--eval_path", default="./eval_result") + parser.add_argument("--label", default="") + parser.add_argument("--tasks", nargs="+", default=["recon"]) + main_args = parser.parse_args() + logging.basicConfig(format="%(levelname)s:%(message)s", level=logging.INFO) + main(main_args) diff --git a/MindChemistry/applications/cdvae/conf/configs.yaml b/MindChemistry/applications/cdvae/conf/configs.yaml new file mode 100644 index 000000000..a75a20a86 --- /dev/null +++ b/MindChemistry/applications/cdvae/conf/configs.yaml @@ -0,0 +1,65 @@ +hidden_dim: 256 +latent_dim: 256 +fc_num_layers: 0 +max_atoms: 20 +cost_natom: 1. +cost_coord: 10. +cost_type: 1. +cost_lattice: 10. +cost_composition: 1. +cost_edge: 10. +cost_property: 1. +beta: 0.01 +max_neighbors: 20 +radius: 7. +sigma_begin: 10. +sigma_end: 0.01 +type_sigma_begin: 5. +type_sigma_end: 0.01 +num_noise_level: 50 +teacher_forcing_lattice: True +predict_property: True + +Encoder: + hidden_channels: 128 + num_blocks: 4 + int_emb_size: 64 + basis_emb_size: 8 + out_emb_channels: 256 + num_spherical: 7 + num_radial: 6 + cutoff: 7.0 + max_num_neighbors: 20 + envelope_exponent: 5 + num_before_skip: 1 + num_after_skip: 2 + num_output_layers: 3 + +Decoder: + hidden_dim: 128 + +Optimizer: + learning_rate: 0.001 + factor: 0.6 + patience: 30 + cooldown: 10 + min_lr: 0.0001 + +Scaler: + TripInteraction_1_had_rbf: 18.873615264892578 + TripInteraction_1_sum_cbf: 7.996850490570068 + AtomUpdate_1_sum: 1.220463752746582 + TripInteraction_2_had_rbf: 16.10817527770996 + TripInteraction_2_sum_cbf: 7.614634037017822 + AtomUpdate_2_sum: 0.9690994620323181 + TripInteraction_3_had_rbf: 15.01930046081543 + TripInteraction_3_sum_cbf: 7.025179862976074 + AtomUpdate_3_sum: 0.8903237581253052 + OutBlock_0_sum: 1.6437848806381226 + OutBlock_0_had: 16.161039352416992 + OutBlock_1_sum: 1.1077653169631958 + OutBlock_1_had: 13.54678726196289 + OutBlock_2_sum: 0.9477927684783936 + OutBlock_2_had: 12.754337310791016 + OutBlock_3_sum: 0.9059251546859741 + OutBlock_3_had: 13.484951972961426 diff --git a/MindChemistry/applications/cdvae/conf/data/carbon_24.yaml b/MindChemistry/applications/cdvae/conf/data/carbon_24.yaml new file mode 100644 index 000000000..8a7c7093b --- /dev/null +++ b/MindChemistry/applications/cdvae/conf/data/carbon_24.yaml @@ -0,0 +1,12 @@ +prop: energy_per_atom +num_targets: 1 +niggli: true +primitive: false +graph_method: crystalnn +lattice_scale_method: scale_length +preprocess_workers: 30 +readout: mean +max_atoms: 24 +otf_graph: false +eval_model_name: carbon +batch_size: 50 diff --git a/MindChemistry/applications/cdvae/conf/data/mp_20.yaml b/MindChemistry/applications/cdvae/conf/data/mp_20.yaml new file mode 100644 index 000000000..f43fb448d --- /dev/null +++ b/MindChemistry/applications/cdvae/conf/data/mp_20.yaml @@ -0,0 +1,12 @@ +prop: formation_energy_per_atom +num_targets: 1 +niggli: true +primitive: False +graph_method: crystalnn +lattice_scale_method: scale_length +preprocess_workers: 30 +readout: mean +max_atoms: 20 +otf_graph: false +eval_model_name: mp20 +batch_size: 50 diff --git a/MindChemistry/applications/cdvae/conf/data/perov_5.yaml b/MindChemistry/applications/cdvae/conf/data/perov_5.yaml new file mode 100644 index 000000000..f25a93abd --- /dev/null +++ b/MindChemistry/applications/cdvae/conf/data/perov_5.yaml @@ -0,0 +1,12 @@ +prop: heat_ref +num_targets: 1 +niggli: true +primitive: false +graph_method: crystalnn +lattice_scale_method: scale_length +preprocess_workers: 24 +readout: mean +max_atoms: 20 +otf_graph: false +eval_model_name: perovskite +batch_size: 128 diff --git a/MindChemistry/applications/cdvae/create_dataset.py b/MindChemistry/applications/cdvae/create_dataset.py new file mode 100644 index 000000000..827a1f2ba --- /dev/null +++ b/MindChemistry/applications/cdvae/create_dataset.py @@ -0,0 +1,341 @@ +# Copyright 2025 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +"""create_dataset""" + +import os +import logging +import argparse +import numpy as np +import pandas as pd +from p_tqdm import p_umap +from pymatgen.core.structure import Structure +from pymatgen.core.lattice import Lattice +from pymatgen.analysis.graphs import StructureGraph +from pymatgen.analysis import local_env + +from mindchemistry.utils.load_config import load_yaml_config_from_path +from mindchemistry.cell.gemnet.data_utils import get_scaler_from_data_list +from mindchemistry.cell.gemnet.data_utils import lattice_params_to_matrix +from mindchemistry.cell.dimenet.preprocess import PreProcess +logging.basicConfig(format="%(levelname)s:%(message)s", level=logging.INFO) + + +class CreateDataset: + """Create Dataset for crystal structures + + Args: + name (str): Name of the dataset + path (str): Path to the dataset + prop (str): Property to predict + niggli (bool): Whether to convert to Niggli reduced cell + primitive (bool): Whether to convert to primitive cell + graph_method (str): Method to create graph + preprocess_workers (int): Number of workers for preprocessing + lattice_scale_method (str): Method to scale lattice + num_samples (int): Number of samples to use, if None use all + """ + + def __init__(self, name, path, + prop, niggli, primitive, + graph_method, preprocess_workers, + lattice_scale_method, config_path, + num_samples=None): + super().__init__() + self.path = path + self.name = name + self.num_samples = num_samples + self.prop = prop + self.niggli = niggli + self.primitive = primitive + self.graph_method = graph_method + self.lattice_scale_method = lattice_scale_method + self.config = load_yaml_config_from_path(config_path).get("Encoder") + self.preprocess = PreProcess( + num_spherical=self.config.get("num_spherical"), + num_radial=self.config.get("num_radial"), + envelope_exponent=self.config.get("envelope_exponent"), + otf_graph=False, + cutoff=self.config.get("cutoff"), + max_num_neighbors=self.config.get("max_num_neighbors"),) + + self.cached_data = data_preprocess( + self.path, + preprocess_workers, + niggli=self.niggli, + primitive=self.primitive, + graph_method=self.graph_method, + prop_list=[prop], + num_samples=self.num_samples + )[:self.num_samples] + add_scaled_lattice_prop(self.cached_data, lattice_scale_method) + self.lattice_scaler = None + self.scaler = None + + def __len__(self): + return len(self.cached_data) + + def __getitem__(self, index): + data = self.cached_data[index] + + # scaler is set in DataModule set stage + prop = self.scaler.transform(data[self.prop]) + (frac_coords, atom_types, lengths, angles, edge_indices, + to_jimages, num_atoms) = data["graph_arrays"] + data_res = self.preprocess.data_process(angles.reshape(1, -1), lengths.reshape(1, -1), + np.array([num_atoms]), edge_indices.T, frac_coords, + edge_indices.shape[0], to_jimages, atom_types, prop) + return data_res + + def __repr__(self): + return f"CrystDataset({self.name}, {self.path})" + + def get_dataset_size(self): + return len(self.cached_data) + + +# match element with its chemical symbols +chemical_symbols = [ + # 0 + "X", + # 1 + "H", "He", + # 2 + "Li", "Be", "B", "C", "N", "O", "F", "Ne", + # 3 + "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", + # 4 + "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", + "Ga", "Ge", "As", "Se", "Br", "Kr", + # 5 + "Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", + "In", "Sn", "Sb", "Te", "I", "Xe", + # 6 + "Cs", "Ba", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", + "Ho", "Er", "Tm", "Yb", "Lu", + "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", + "Po", "At", "Rn", + # 7 + "Fr", "Ra", "Ac", "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", + "Cf", "Es", "Fm", "Md", "No", "Lr", + "Rf", "Db", "Sg", "Bh", "Hs", "Mt", "Ds", "Rg", "Cn", "Nh", "Fl", "Mc", + "Lv", "Ts", "Og" +] + +# used for crystal matching +CRYSTALNN = local_env.CrystalNN( + distance_cutoffs=None, x_diff_weight=-1, porous_adjustment=False) + + +def build_crystal(crystal_str, niggli=True, primitive=False): + """Build crystal from cif string.""" + crystal = Structure.from_str(crystal_str, fmt="cif") + + if primitive: + crystal = crystal.get_primitive_structure() + + if niggli: + crystal = crystal.get_reduced_structure() + + canonical_crystal = Structure( + lattice=Lattice.from_parameters(*crystal.lattice.parameters), + species=crystal.species, + coords=crystal.frac_coords, + coords_are_cartesian=False, + ) + # match is gaurantteed because cif only uses lattice params & frac_coords + assert canonical_crystal.matches(crystal) + return canonical_crystal + + +def build_crystal_graph(crystal, graph_method="crystalnn"): + """build crystal graph""" + + if graph_method == "crystalnn": + crystal_graph = StructureGraph.with_local_env_strategy( + crystal, CRYSTALNN) + elif graph_method == "none": + pass + else: + raise NotImplementedError + + frac_coords = crystal.frac_coords + atom_types = crystal.atomic_numbers + lattice_parameters = crystal.lattice.parameters + lengths = lattice_parameters[:3] + angles = lattice_parameters[3:] + + assert np.allclose(crystal.lattice.matrix, + lattice_params_to_matrix(*lengths, *angles)) + + edge_indices, to_jimages = [], [] + if graph_method != "none": + for i, j, to_jimage in crystal_graph.graph.edges(data="to_jimage"): + edge_indices.append([j, i]) + to_jimages.append(to_jimage) + edge_indices.append([i, j]) + to_jimages.append(tuple(-tj for tj in to_jimage)) + + atom_types = np.array(atom_types) + lengths, angles = np.array(lengths), np.array(angles) + edge_indices = np.array(edge_indices) + to_jimages = np.array(to_jimages) + num_atoms = atom_types.shape[0] + + return frac_coords, atom_types, lengths, angles, edge_indices, to_jimages, num_atoms + + +def save_data(dataset, is_train, dataset_name): + """save created dataset to npy""" + processed_data = dict() + data_parameters = ["atom_types", "dist", "angle", "idx_kj", "idx_ji", + "edge_j", "edge_i", "pos", "batch", "lengths", + "num_atoms", "angles", "frac_coords", + "num_bonds", "num_triplets", "sbf", "y"] + for j, name in enumerate(data_parameters): + if j == 16: + # Here, y is mindspore.Tensor, while others are all numpy.array, so need to change the type first. + processed_data[name] = [i[j].astype(np.float32) for i in dataset] + elif j == 14: + # Here, we need the sum of num_triplets, so get the summary before we save it. + processed_data[name] = [i[j].sum() for i in dataset] + else: + processed_data[name] = [i[j] for i in dataset] + + if not os.path.exists(f"./data/{dataset_name}/{is_train}"): + os.makedirs(f"./data/{dataset_name}/{is_train}") + logging.info("%s has been created", + f"./data/{dataset_name}/{is_train}") + if is_train == "train": + np.savetxt(f"./data/{dataset_name}/{is_train}/scaler_mean.csv", + dataset.scaler.means.reshape(-1)) + np.savetxt(f"./data/{dataset_name}/{is_train}/scaler_std.csv", + dataset.scaler.stds.reshape(-1)) + np.savetxt( + f"./data/{dataset_name}/{is_train}/lattice_scaler_mean.csv", dataset.lattice_scaler.means) + np.savetxt( + f"./data/{dataset_name}/{is_train}/lattice_scaler_std.csv", dataset.lattice_scaler.stds) + np.save( + f"./data/{dataset_name}/{is_train}/processed_data.npy", processed_data) + + +def process_one(row, niggli, primitive, graph_method, prop_list): + """process one one sample""" + crystal_str = row["cif"] + crystal = build_crystal( + crystal_str, niggli=niggli, primitive=primitive) + graph_arrays = build_crystal_graph(crystal, graph_method) + properties = {k: row[k] for k in prop_list if k in row.keys()} + result_dict = { + "mp_id": row["material_id"], + "cif": crystal_str, + "graph_arrays": graph_arrays, + } + result_dict.update(properties) + return result_dict + + +def data_preprocess(input_file, num_workers, niggli, primitive, graph_method, prop_list, num_samples): + """process data""" + df = pd.read_csv(input_file)[:num_samples] + + unordered_results = p_umap( + process_one, + [df.iloc[idx] for idx in range(len(df))], + [niggli] * len(df), + [primitive] * len(df), + [graph_method] * len(df), + [prop_list] * len(df), + num_cpus=num_workers) + + mpid_to_results = {result["mp_id"]: result for result in unordered_results} + ordered_results = [mpid_to_results[df.iloc[idx]["material_id"]] + for idx in range(len(df))] + + return ordered_results + + +def add_scaled_lattice_prop(data_list, lattice_scale_method): + """add scaled lattice prop to dataset""" + for data in data_list: + graph_arrays = data["graph_arrays"] + # the indexes are brittle if more objects are returned + lengths = graph_arrays[2] + angles = graph_arrays[3] + num_atoms = graph_arrays[-1] + assert lengths.shape[0] == angles.shape[0] == 3 + assert isinstance(num_atoms, int) + + if lattice_scale_method == "scale_length": + lengths = lengths / float(num_atoms)**(1 / 3) + + data["scaled_lattice"] = np.concatenate([lengths, angles]) + + +def create_dataset(args): + """create dataset""" + config_data_path = f"./conf/data/{args.dataset}.yaml" + config_path = f"./conf/configs.yaml" + config_data = load_yaml_config_from_path(config_data_path) + prop = config_data.get("prop") + niggli = config_data.get("niggli") + primitive = config_data.get("primitive") + graph_method = config_data.get("graph_method") + lattice_scale_method = config_data.get("lattice_scale_method") + preprocess_workers = config_data.get("preprocess_workers") + path_train = f"./data/{args.dataset}/train.csv" + train_dataset = CreateDataset("Formation energy train", path_train, prop, + niggli, primitive, graph_method, + preprocess_workers, lattice_scale_method, + config_path, args.num_samples_train) + lattice_scaler = get_scaler_from_data_list( + train_dataset.cached_data, + key="scaled_lattice") + scaler = get_scaler_from_data_list( + train_dataset.cached_data, + key=train_dataset.prop) + train_dataset.lattice_scaler = lattice_scaler + train_dataset.scaler = scaler + save_data(train_dataset, "train", args.dataset) + + path_val = f"./data/{args.dataset}/val.csv" + val_dataset = CreateDataset("Formation energy val", path_val, prop, + niggli, primitive, graph_method, + preprocess_workers, lattice_scale_method, args.num_samples_val) + val_dataset.lattice_scaler = lattice_scaler + val_dataset.scaler = scaler + save_data(val_dataset, "val", args.dataset) + + path_test = f"./data/{args.dataset}/test.csv" + test_dataset = CreateDataset("Formation energy test", path_test, prop, + niggli, primitive, graph_method, + preprocess_workers, lattice_scale_method, + args.num_samples_test) + test_dataset.lattice_scaler = lattice_scaler + test_dataset.scaler = scaler + save_data(test_dataset, "test", args.dataset) + + +def main(args): + create_dataset(args) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--dataset", default="perov_5") + parser.add_argument("--num_samples_train", default=300, type=int) + parser.add_argument("--num_samples_val", default=300, type=int) + parser.add_argument("--num_samples_test", default=300, type=int) + main_args = parser.parse_args() + main(main_args) diff --git a/MindChemistry/applications/cdvae/evaluation.py b/MindChemistry/applications/cdvae/evaluation.py new file mode 100644 index 000000000..4361fb5e4 --- /dev/null +++ b/MindChemistry/applications/cdvae/evaluation.py @@ -0,0 +1,192 @@ +# Copyright 2025 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +"""Evaluation +""" + +import os +import time +import logging +from types import SimpleNamespace +import argparse +import mindspore as ms +import numpy as np + +from mindchemistry.cell.cdvae import CDVAE +from src.dataloader import DataLoaderBaseCDVAE +from src.evaluate_utils import (get_reconstructon_res, get_generation_res, + get_optimization_res) +from train import get_scaler + + +def task_reconstruction(model, ld_kwargs, graph_dataset, recon_args): + """Evaluate model on the reconstruction task.""" + logging.info("Evaluate model on the reconstruction task.") + (frac_coords, num_atoms, atom_types, lengths, angles, + gt_frac_coords, gt_num_atoms, gt_atom_types, + gt_lengths, gt_angles) = get_reconstructon_res( + graph_dataset, model, ld_kwargs, recon_args.num_evals, + recon_args.force_num_atoms, recon_args.force_atom_types) + + if recon_args.label == "": + recon_out_name = "eval_recon.npy" + else: + recon_out_name = f"eval_recon_{recon_args.label}.npy" + + result = { + "eval_setting": recon_args, + "frac_coords": frac_coords, + "num_atoms": num_atoms, + "atom_types": atom_types, + "lengths": lengths, + "angles": angles, + } + # save result as numpy + np.save("./eval_result/" + recon_out_name, result) + groundtruth = { + "frac_coords": gt_frac_coords, + "num_atoms": gt_num_atoms, + "atom_types": gt_atom_types, + "lengths": gt_lengths, + "angles": gt_angles, + } + # save ground truth as numpy + np.save("./eval_result/gt_recon.npy", groundtruth) + + +def task_generation(model, ld_kwargs, gen_args): + """Evaluate model on the generation task.""" + logging.info("Evaluate model on the generation task.") + + (frac_coords, num_atoms, atom_types, lengths, angles, + all_frac_coords_stack, all_atom_types_stack) = get_generation_res( + model, ld_kwargs, gen_args.num_batches_to_samples, gen_args.num_evals, + gen_args.batch_size, gen_args.down_sample_traj_step) + + if gen_args.label == "": + gen_out_name = "eval_gen.npy" + else: + gen_out_name = f"eval_gen_{gen_args.label}.npy" + + result = { + "eval_setting": gen_args, + "frac_coords": frac_coords, + "num_atoms": num_atoms, + "atom_types": atom_types, + "lengths": lengths, + "angles": angles, + "all_frac_coords_stack": all_frac_coords_stack, + "all_atom_types_stack": all_atom_types_stack, + } + # save result as numpy + np.save("./eval_result/" + gen_out_name, result) + + +def task_optimization(model, ld_kwargs, graph_dataset, opt_args): + """Evaluate model on the property optimization task.""" + logging.info("Evaluate model on the property optimization task.") + if opt_args.start_from == "data": + loader = graph_dataset + else: + loader = None + optimized_crystals = get_optimization_res(model, ld_kwargs, loader) + if opt_args.label == "": + gen_out_name = "eval_opt.npy" + else: + gen_out_name = f"eval_opt_{opt_args.label}.npy" + # save result as numpy + np.save("./eval_result/" + gen_out_name, optimized_crystals) + + +def main(args): + # check whether path exists, if not exists create the direction + folder_path = os.path.dirname(args.model_path) + if not os.path.exists(folder_path): + os.makedirs(folder_path) + logging.info("%s has been created", folder_path) + result_path = "./eval_result/" + if not os.path.exists(result_path): + os.makedirs(result_path) + logging.info("%s has been created", result_path) + config_path = "./conf/configs.yaml" + data_config_path = f"./conf/data/{args.dataset}.yaml" + # load model + model = CDVAE(config_path, data_config_path) + # load mindspore check point + param_dict = ms.load_checkpoint(args.model_path) + param_not_load, _ = ms.load_param_into_net(model, param_dict) + logging.info("parameter not load: %s.", param_not_load) + model.set_train(False) + + ld_kwargs = SimpleNamespace(n_step_each=args.n_step_each, + step_lr=args.step_lr, + min_sigma=args.min_sigma, + save_traj=args.save_traj, + disable_bar=args.disable_bar) + # load dataset + graph_dataset = DataLoaderBaseCDVAE( + args.batch_size, args.dataset, shuffle_dataset=False, mode="test") + # load scaler + lattice_scaler, scaler = get_scaler(args) + model.lattice_scaler = lattice_scaler + model.scaler = scaler + + start_time_eval = time.time() + if "recon" in args.tasks: + task_reconstruction(model, ld_kwargs, graph_dataset, args) + if "gen" in args.tasks: + task_generation(model, ld_kwargs, args) + if "opt" in args.tasks: + task_optimization(model, ld_kwargs, graph_dataset, args) + logging.info("end evaluation, time: %f s.", time.time() - start_time_eval) + +def get_args(): + """args used for evaluation""" + parser = argparse.ArgumentParser() + parser.add_argument("--device_target", default="Ascend", help="device target") + parser.add_argument("--device_id", default=7, type=int, help="device id") + parser.add_argument("--model_path", default="./loss/loss.ckpt", + help="path to checkpoint") + parser.add_argument("--dataset", default="perov_5", help="name of dataset") + parser.add_argument("--tasks", nargs="+", default=["gen"], + help="tasks to evaluate, choose from 'recon, gen, opt'") + parser.add_argument("--n_step_each", default=1, type=int, + help="number of steps in diffusion") + parser.add_argument("--step_lr", default=1e-3, type=float, help="learning rate") + parser.add_argument("--min_sigma", default=0, type=float, help="minimum sigma") + parser.add_argument("--save_traj", default=False, type=bool, + help="whether to save trajectory") + parser.add_argument("--disable_bar", default=False, type=bool, + help="disable progress bar") + parser.add_argument("--num_evals", default=1, type=int, + help="number of evaluations returned for each task") + parser.add_argument("--num_batches_to_samples", default=1, type=int, + help="number of batches to sample") + parser.add_argument("--start_from", default="data", type=str, + help="start from data or random") + parser.add_argument("--batch_size", default=128, type=int, help="batch size") + parser.add_argument("--force_num_atoms", action="store_true", + help="fixed num atoms or not") + parser.add_argument("--force_atom_types", action="store_true", + help="fixed atom types or not") + parser.add_argument("--down_sample_traj_step", default=10, type=int, help="down sample") + parser.add_argument("--label", default="", help="label for output file") + return parser.parse_args() + +if __name__ == "__main__": + main_args = get_args() + logging.basicConfig(format="%(levelname)s:%(message)s", level=logging.INFO) + ms.context.set_context(device_target=main_args.device_target, + device_id=main_args.device_id, mode=1) + main(main_args) diff --git a/MindChemistry/applications/cdvae/images/illustrative.png b/MindChemistry/applications/cdvae/images/illustrative.png new file mode 100644 index 0000000000000000000000000000000000000000..a70858f7f67a881ba63606c03ec3eba13fb7ef1a GIT binary patch literal 177452 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˻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. + """ + result_frac_coords = [] + result_num_atoms = [] + result_atom_types = [] + result_lengths = [] + result_angles = [] + gt_frac_coords = [] + groundtruth_num_atoms = [] + groundtruth_atom_types = [] + gt_lengths = [] + gt_angles = [] + for idx, data in enumerate(loader): + logging.info("Reconstructing %d", int(idx * data[-3])) + batch_frac_coords, batch_num_atoms, batch_atom_types = [], [], [] + batch_lengths, batch_angles = [], [] + + # only sample one z, multiple evals for stoichaticity in langevin dynamics + (atom_types, dist, _, idx_kj, idx_ji, + edge_j, edge_i, batch, lengths, num_atoms, + angles, frac_coords, _, batch_size, sbf, + total_atoms) = data + gt_frac_coords.append(frac_coords.asnumpy()) + gt_angles.append(angles.asnumpy()) + gt_lengths.append(lengths.asnumpy()) + groundtruth_atom_types.append(atom_types.asnumpy()) + groundtruth_num_atoms.append(num_atoms.asnumpy()) + _, _, z = model.encode(atom_types, dist, + idx_kj, idx_ji, edge_j, edge_i, + batch, total_atoms, batch_size, sbf) + for _ in range(num_evals): + gt_num_atoms = num_atoms if force_num_atoms else None + gt_atom_types = atom_types if force_atom_types else None + outputs = model.langevin_dynamics( + z, ld_kwargs, batch_size, total_atoms, gt_num_atoms, gt_atom_types) + # collect sampled crystals in this batch. + batch_frac_coords.append(outputs["frac_coords"].asnumpy()) + batch_num_atoms.append(outputs["num_atoms"].asnumpy()) + batch_atom_types.append(outputs["atom_types"].asnumpy()) + batch_lengths.append(outputs["lengths"].asnumpy()) + batch_angles.append(outputs["angles"].asnumpy()) + # collect sampled crystals for this z. + result_frac_coords.append(batch_frac_coords) + result_num_atoms.append(batch_num_atoms) + result_atom_types.append(batch_atom_types) + result_lengths.append(batch_lengths) + result_angles.append(batch_angles) + + return ( + result_frac_coords, result_num_atoms, result_atom_types, + result_lengths, result_angles, + gt_frac_coords, groundtruth_num_atoms, groundtruth_atom_types, + gt_lengths, gt_angles) + + +def get_generation_res(model, ld_kwargs, num_batches_to_sample, num_samples_per_z, + batch_size=512, down_sample_traj_step=1): + """ + generate new crystals based on randomly sampled z. + """ + all_frac_coords_stack = [] + all_atom_types_stack = [] + result_frac_coords = [] + result_num_atoms = [] + result_atom_types = [] + result_lengths = [] + result_angles = [] + + for _ in range(num_batches_to_sample): + batch_all_frac_coords = [] + batch_all_atom_types = [] + batch_frac_coords, batch_num_atoms, batch_atom_types = [], [], [] + batch_lengths, batch_angles = [], [] + + z = ms.ops.randn(batch_size, model.hidden_dim) + + for _ in range(num_samples_per_z): + samples = model.langevin_dynamics(z, ld_kwargs, batch_size) + + # collect sampled crystals in this batch. + batch_frac_coords.append(samples["frac_coords"].asnumpy()) + batch_num_atoms.append(samples["num_atoms"].asnumpy()) + batch_atom_types.append(samples["atom_types"].asnumpy()) + batch_lengths.append(samples["lengths"].asnumpy()) + batch_angles.append(samples["angles"].asnumpy()) + if ld_kwargs.save_traj: + batch_all_frac_coords.append( + samples["all_frac_coords"][::down_sample_traj_step].asnumpy()) + batch_all_atom_types.append( + samples["all_atom_types"][::down_sample_traj_step].asnumpy()) + + # collect sampled crystals for this z. + result_frac_coords.append(batch_frac_coords) + result_num_atoms.append(batch_num_atoms) + result_atom_types.append(batch_atom_types) + result_lengths.append(batch_lengths) + result_angles.append(batch_angles) + if ld_kwargs.save_traj: + all_frac_coords_stack.append( + batch_all_frac_coords) + all_atom_types_stack.append( + batch_all_atom_types) + + return (result_frac_coords, result_num_atoms, result_atom_types, + result_lengths, result_angles, + all_frac_coords_stack, all_atom_types_stack) + + +def get_optimization_res(model, ld_kwargs, data_loader, + num_starting_points=128, num_gradient_steps=5000, + lr=1e-3, num_saved_crys=10): + """ + optimize the structure based on specific proprety. + """ + model.set_train(True) + if data_loader is not None: + data = next(iter(data_loader)) + (atom_types, dist, _, idx_kj, idx_ji, + edge_j, edge_i, batch, _, num_atoms, + _, _, _, batch_size, sbf, + total_atoms) = data + _, _, z = model.encode(atom_types, dist, + idx_kj, idx_ji, edge_j, edge_i, + batch, total_atoms, batch_size, sbf) + z = mint.narrow(z, 0, 0, num_starting_points) + z = ms.Parameter(z, requires_grad=True) + else: + z = mint.randn(num_starting_points, model.hparams.hidden_dim) + z = ms.Parameter(z, requires_grad=True) + + opt = Adam([z], learning_rate=lr) + freeze_model(model) + + loss_fn = model.fc_property + + def forward_fn(data): + loss = loss_fn(data) + return loss + grad_fn = ms.value_and_grad(forward_fn, None, opt.parameters) + + def train_step(data): + loss, grads = grad_fn(data) + opt(grads) + return loss + + all_crystals = [] + total_atoms = mint.sum(mint.narrow( + num_atoms, 0, 0, num_starting_points)).item() + interval = num_gradient_steps // (num_saved_crys - 1) + for i in tqdm(range(num_gradient_steps)): + loss = mint.mean(train_step(z)) + logging.info("Task opt step: %d, loss: %f", i, loss) + if i % interval == 0 or i == (num_gradient_steps - 1): + crystals = model.langevin_dynamics( + z, ld_kwargs, batch_size, total_atoms) + all_crystals.append(crystals) + return {k: mint.cat([d[k] for d in all_crystals]).unsqueeze(0).asnumpy() for k in + ["frac_coords", "atom_types", "num_atoms", "lengths", "angles"]} + + +def freeze_model(model): + """ The model is fixed, only optimize z""" + for param in model.get_parameters(): + param.requires_grad = False diff --git a/MindChemistry/applications/cdvae/src/metrics_utils.py b/MindChemistry/applications/cdvae/src/metrics_utils.py new file mode 100644 index 000000000..cf179ec10 --- /dev/null +++ b/MindChemistry/applications/cdvae/src/metrics_utils.py @@ -0,0 +1,191 @@ +# Copyright 2025 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +"""utils for compute metrics""" +import itertools +import numpy as np + +from scipy.spatial.distance import pdist +from scipy.spatial.distance import cdist + +import smact +from smact.screening import pauling_test + +from create_dataset import chemical_symbols + + +def get_crystals_list( + frac_coords, atom_types, lengths, angles, num_atoms): + """ + args: + frac_coords: (num_atoms, 3) + atom_types: (num_atoms) + lengths: (num_crystals) + angles: (num_crystals) + num_atoms: (num_crystals) + """ + assert frac_coords.shape[0] == atom_types.shape[0] == num_atoms.sum() + assert lengths.shape[0] == angles.shape[0] == num_atoms.shape[0] + + start_idx = 0 + crystal_array_list = [] + for batch_idx, num_atom in enumerate(num_atoms.tolist()): + cur_frac_coords = frac_coords[start_idx:start_idx+num_atom] + cur_atom_types = atom_types[start_idx:start_idx+num_atom] + cur_lengths = lengths[batch_idx] + cur_angles = angles[batch_idx] + + crystal_array_list.append({ + "frac_coords": cur_frac_coords, + "atom_types": cur_atom_types, + "lengths": cur_lengths, + "angles": cur_angles, + }) + start_idx = start_idx + num_atom + return crystal_array_list + + +def smact_validity(comp, count, + use_pauling_test=True, + include_alloys=True): + """compute smact validity""" + elem_symbols = tuple([chemical_symbols[elem] for elem in comp]) + space = smact.element_dictionary(elem_symbols) + smact_elems = [e[1] for e in space.items()] + electronegs = [e.pauling_eneg for e in smact_elems] + ox_combos = [e.oxidation_states for e in smact_elems] + if len(set(elem_symbols)) == 1: + return True + if include_alloys: + is_metal_list = [elem_s in smact.metals for elem_s in elem_symbols] + if all(is_metal_list): + return True + + threshold = np.max(count) + compositions = [] + for ox_states in itertools.product(*ox_combos): + stoichs = [(c,) for c in count] + # Test for charge balance + cn_e, cn_r = smact.neutral_ratios( + ox_states, stoichs=stoichs, threshold=threshold) + # Electronegativity test + if cn_e: + if use_pauling_test: + try: + electroneg_pass = pauling_test(ox_states, electronegs) + except TypeError: + # if no electronegativity data, assume it is okay + electroneg_pass = True + else: + electroneg_pass = True + if electroneg_pass: + for ratio in cn_r: + compositions.append( + tuple([elem_symbols, ox_states, ratio])) + compositions = [(i[0], i[2]) for i in compositions] + compositions = list(set(compositions)) + res = bool(compositions) + return res + + +def structure_validity(crystal, cutoff=0.5): + """compute structure validity""" + dist_mat = crystal.distance_matrix + # Pad diagonal with a large number + dist_mat = dist_mat + np.diag( + np.ones(dist_mat.shape[0]) * (cutoff + 10.)) + res = None + if dist_mat.min() < cutoff or crystal.volume < 0.1: + res = False + else: + res = True + return res + + +def get_fp_pdist(fp_array): + if isinstance(fp_array, list): + fp_array = np.array(fp_array) + fp_pdists = pdist(fp_array) + return fp_pdists.mean() + + +def filter_fps(struc_fps, comp_fps): + assert len(struc_fps) == len(comp_fps) + + filtered_struc_fps, filtered_comp_fps = [], [] + + for struc_fp, comp_fp in zip(struc_fps, comp_fps): + if struc_fp is not None and comp_fp is not None: + filtered_struc_fps.append(struc_fp) + filtered_comp_fps.append(comp_fp) + return filtered_struc_fps, filtered_comp_fps + + +def compute_cov(crys, gt_crys, comp_scaler, + struc_cutoff, comp_cutoff, num_gen_crystals=None): + """compute COV""" + struc_fps = [c.struct_fp for c in crys] + comp_fps = [c.comp_fp for c in crys] + gt_struc_fps = [c.struct_fp for c in gt_crys] + gt_comp_fps = [c.comp_fp for c in gt_crys] + + assert len(struc_fps) == len(comp_fps) + assert len(gt_struc_fps) == len(gt_comp_fps) + + # Use number of crystal before filtering to compute COV + if num_gen_crystals is None: + num_gen_crystals = len(struc_fps) + + struc_fps, comp_fps = filter_fps(struc_fps, comp_fps) + + comp_fps = comp_scaler.transform(comp_fps) + gt_comp_fps = comp_scaler.transform(gt_comp_fps) + + struc_fps = np.array(struc_fps) + gt_struc_fps = np.array(gt_struc_fps) + comp_fps = np.array(comp_fps) + gt_comp_fps = np.array(gt_comp_fps) + + struc_pdist = cdist(struc_fps, gt_struc_fps) + comp_pdist = cdist(comp_fps, gt_comp_fps) + + struc_recall_dist = struc_pdist.min(axis=0) + struc_precision_dist = struc_pdist.min(axis=1) + comp_recall_dist = comp_pdist.min(axis=0) + comp_precision_dist = comp_pdist.min(axis=1) + + cov_recall = np.mean(np.logical_and( + struc_recall_dist <= struc_cutoff, + comp_recall_dist <= comp_cutoff)) + cov_precision = np.sum(np.logical_and( + struc_precision_dist <= struc_cutoff, + comp_precision_dist <= comp_cutoff)) / num_gen_crystals + + metrics_dict = { + "cov_recall": cov_recall, + "cov_precision": cov_precision, + "amsd_recall": np.mean(struc_recall_dist), + "amsd_precision": np.mean(struc_precision_dist), + "amcd_recall": np.mean(comp_recall_dist), + "amcd_precision": np.mean(comp_precision_dist), + } + + combined_dist_dict = { + "struc_recall_dist": struc_recall_dist.tolist(), + "struc_precision_dist": struc_precision_dist.tolist(), + "comp_recall_dist": comp_recall_dist.tolist(), + "comp_precision_dist": comp_precision_dist.tolist(), + } + + return metrics_dict, combined_dist_dict diff --git a/MindChemistry/applications/cdvae/train.py b/MindChemistry/applications/cdvae/train.py new file mode 100644 index 000000000..1b73927f5 --- /dev/null +++ b/MindChemistry/applications/cdvae/train.py @@ -0,0 +1,185 @@ +# Copyright 2025 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +"""Train +""" + +import os +import logging +import argparse +import time +import numpy as np +import mindspore as ms +from mindspore.experimental import optim +from mindchemistry.utils.load_config import load_yaml_config_from_path +from mindchemistry.cell.cdvae import CDVAE +from mindchemistry.cell.gemnet.data_utils import StandardScalerMindspore +from create_dataset import create_dataset +from src.dataloader import DataLoaderBaseCDVAE + + +def train_epoch(epoch, model, optimizer, scheduler, train_dataset): + """Train the model for one epoch""" + model.set_train() + # Define forward function + + def forward_fn(data): + (atom_types, dist, _, idx_kj, idx_ji, + edge_j, edge_i, batch, lengths, num_atoms, + angles, frac_coords, y, batch_size, sbf, total_atoms) = data + loss = model(atom_types, dist, idx_kj, idx_ji, edge_j, edge_i, + batch, lengths, num_atoms, angles, frac_coords, + y, batch_size, sbf, total_atoms, True, True) + return loss + # Get gradient function + grad_fn = ms.value_and_grad( + forward_fn, None, optimizer.parameters, has_aux=False) + + # Define function of one-step training + def train_step(data): + loss, grads = grad_fn(data) + scheduler.step(loss) + optimizer(grads) + return loss + + start_time_step = time.time() + for batch, data in enumerate(train_dataset): + loss = train_step(data) + time_step = time.time() - start_time_step + start_time_step = time.time() + if batch % 10 == 0: + logging.info("Train Epoch: %d [%d]\tLoss: %4f,\t time_step: %4f", + epoch, batch, loss, time_step) + + +def test_epoch(model, val_dataset): + """test for one epoch""" + model.set_train(False) + test_loss = 0 + i = 1 + for i, data in enumerate(val_dataset): + (atom_types, dist, _, idx_kj, idx_ji, + edge_j, edge_i, batch, lengths, num_atoms, + angles, frac_coords, y, batch_size, sbf, total_atoms) = data + output = model(atom_types, dist, + idx_kj, idx_ji, edge_j, edge_i, + batch, lengths, num_atoms, + angles, frac_coords, y, batch_size, + sbf, total_atoms, False, True) + test_loss += float(output) + test_loss /= (i+1) + logging.info("Val Loss: %4f", test_loss) + return test_loss + +def get_scaler(args): + """get scaler""" + lattice_scaler_mean = ms.Tensor(np.loadtxt( + f"./data/{args.dataset}/train/lattice_scaler_mean.csv"), ms.float32) + lattice_scaler_std = ms.Tensor(np.loadtxt( + f"./data/{args.dataset}/train/lattice_scaler_std.csv"), ms.float32) + scaler_std = ms.Tensor(np.loadtxt( + f"./data/{args.dataset}/train/scaler_std.csv"), ms.float32) + scaler_mean = ms.Tensor(np.loadtxt( + f"./data/{args.dataset}/train/scaler_mean.csv"), ms.float32) + lattice_scaler = StandardScalerMindspore( + lattice_scaler_mean, lattice_scaler_std) + scaler = StandardScalerMindspore(scaler_mean, scaler_std) + return lattice_scaler, scaler + +def train_net(args): + """training process""" + folder_path = os.path.dirname(args.name_ckpt) + if not os.path.exists(folder_path): + os.makedirs(folder_path) + logging.info("%s has been created", folder_path) + config_path = "./conf/configs.yaml" + data_config_path = f"./conf/data/{args.dataset}.yaml" + + model = CDVAE(config_path, data_config_path) + + # load checkpoint + if args.load_ckpt: + model_path = args.name_ckpt + param_dict = ms.load_checkpoint(model_path) + param_not_load, _ = ms.load_param_into_net(model, param_dict) + logging.info("%s have not been loaded", param_not_load) + + # create dataset when running the model first-time or when dataset is not exist + if args.create_dataset or not os.path.exists(f"./data/{args.dataset}/train/processed_data.npy"): + logging.info("Creating dataset......") + create_dataset(args) # dataset created will be save to the dir based on args.dataset as npy + + # read dataset from processed_data + batch_size = load_yaml_config_from_path(data_config_path).get("batch_size") + train_dataset = DataLoaderBaseCDVAE( + batch_size, args.dataset, shuffle_dataset=True, mode="train") + val_dataset = DataLoaderBaseCDVAE( + batch_size, args.dataset, shuffle_dataset=False, mode="val") + lattice_scaler, scaler = get_scaler(args) + model.lattice_scaler = lattice_scaler + model.scaler = scaler + + config_opt = load_yaml_config_from_path(config_path).get("Optimizer") + learning_rate = config_opt.get("learning_rate") + min_lr = config_opt.get("min_lr") + factor = config_opt.get("factor") + patience = config_opt.get("patience") + + optimizer = optim.Adam(model.trainable_params(), learning_rate) + scheduler = optim.lr_scheduler.ReduceLROnPlateau( + optimizer, 'min', factor=factor, patience=patience, min_lr=min_lr) + + min_test_loss = float("inf") + for epoch in range(args.epoch_num): + train_epoch(epoch, model, optimizer, scheduler, train_dataset) + if epoch % 10 == 0: + test_loss = test_epoch(model, val_dataset) + if test_loss < min_test_loss: + min_test_loss = test_loss + ms.save_checkpoint(model, args.name_ckpt) + logging.info("Updata best acc: %f", test_loss) + + logging.info('Finished Training') + +def get_args(): + """get args""" + parser = argparse.ArgumentParser() + parser.add_argument("--dataset", default="perov_5", help="dataset name") + parser.add_argument("--create_dataset", default=False, + type=bool, help="whether create dataset again or not") + parser.add_argument("--num_samples_train", default=500, type=int, + help="number of samples for training,\ + only valid when create_dataset is True") + parser.add_argument("--num_samples_val", default=300, type=int, + help="number of samples for validation,\ + only valid when create_dataset is True") + parser.add_argument("--num_samples_test", default=300, type=int, + help="number of samples for test,\ + only valid when create_dataset is True") + parser.add_argument("--name_ckpt", default="./loss/loss.ckpt", + help="the path to save checkpoint") + parser.add_argument("--load_ckpt", default=False, type=bool, + help="whether load checkpoint or not") + parser.add_argument("--device_target", default="Ascend", help="device target") + parser.add_argument("--device_id", default=3, type=int, help="device id") + parser.add_argument("--epoch_num", default=100, type=int, help="number of epoch") + return parser.parse_args() + +if __name__ == "__main__": + main_args = get_args() + logging.basicConfig(format="%(levelname)s:%(message)s", level=logging.INFO) + ms.context.set_context(device_target=main_args.device_target, + device_id=main_args.device_id, + mode=1) + train_net(main_args) diff --git a/MindChemistry/mindchemistry/cell/gemnet/layers/base_layers.py b/MindChemistry/mindchemistry/cell/gemnet/layers/base_layers.py index fe6193abf..deae89f36 100644 --- a/MindChemistry/mindchemistry/cell/gemnet/layers/base_layers.py +++ b/MindChemistry/mindchemistry/cell/gemnet/layers/base_layers.py @@ -132,7 +132,7 @@ class MLP(ms.nn.Cell): super().__init__() self.activation = activation self.last_activation = last_activation - self.in_layer = mint.nn.Linear(in_dim, hidden_dim, bias=False) + self.in_layer = mint.nn.Linear(in_dim, hidden_dim, bias=True) self.dense_mlp = ms.nn.SequentialCell( *[ mint.nn.Linear( @@ -143,7 +143,7 @@ class MLP(ms.nn.Cell): for _ in range(fc_num_layers) ] ) - self.out_layer = mint.nn.Linear(hidden_dim, out_dim, bias=False) + self.out_layer = mint.nn.Linear(hidden_dim, out_dim, bias=True) def construct(self, x): """MLP construct""" -- Gitee