+
+### Training
+
+Run from PaddleMaterials root:
+
+```bash
+python property_prediction/train.py \
+ -c property_prediction/configs/transpolymer/transpolymer_pe_i_finetune.yaml
+```
+
+Replace `transpolymer_pe_i_finetune.yaml` with any other
+`transpolymer_*_finetune.yaml` file to finetune a different downstream task.
+
+### Validation
+
+Evaluate a finetuned checkpoint on the validation split:
+
+```bash
+python property_prediction/train.py \
+ -c property_prediction/configs/transpolymer/transpolymer_pe_i_finetune.yaml \
+ Global.do_train=False \
+ Global.do_eval=True \
+ Trainer.pretrained_model_path=./output/PE_I \
+ Trainer.pretrained_weight_name=PE_I_best_model.pdparams
+```
+
+### Testing
+
+Evaluate a finetuned checkpoint on the test split:
+
+```bash
+python property_prediction/train.py \
+ -c property_prediction/configs/transpolymer/transpolymer_pe_i_finetune.yaml \
+ Global.do_train=False \
+ Global.do_test=True \
+ Trainer.pretrained_model_path=./output/PE_I \
+ Trainer.pretrained_weight_name=PE_I_best_model.pdparams
+```
+
+For other tasks, replace the config path and checkpoint name with the
+corresponding dataset checkpoint, for example
+`Trainer.pretrained_model_path=./output/Eea` and
+`Trainer.pretrained_weight_name=Eea_best_model.pdparams`.
+
+### Prediction
+
+Run from PaddleMaterials root:
+
+```bash
+python property_prediction/predict.py \
+ --config_path property_prediction/configs/transpolymer/transpolymer_pe_i_finetune.yaml \
+ --checkpoint_path ./output/PE_I/PE_I_best_model.pdparams \
+ --csv_file_path ./property_prediction/example_data/transpolymer_predict.csv \
+ --save_path ./output/transpolymer_prediction.csv
+```
+
+The input CSV should contain the SMILES column required by the selected config,
+for example `smiles`, `CSMILES`, or `SMILES descriptor 1`. The prediction result
+is saved to the path specified by `--save_path`.
+
+## Citation
+
+```bibtex
+@article{xu2022transpolymer,
+ title={TransPolymer: a Transformer-based language model for polymer property predictions},
+ author={Xu, Changwen and Wang, Yuyang and Farimani, Amir Barati},
+ journal={arXiv preprint arXiv:2209.01307},
+ year={2022}
+}
+```
diff --git a/property_prediction/configs/transpolymer/transpolymer_eea_finetune.yaml b/property_prediction/configs/transpolymer/transpolymer_eea_finetune.yaml
new file mode 100644
index 00000000..ca59524a
--- /dev/null
+++ b/property_prediction/configs/transpolymer/transpolymer_eea_finetune.yaml
@@ -0,0 +1,123 @@
+Global:
+ label_names: ["value"]
+ do_train: True
+ do_eval: False
+ do_test: False
+
+Trainer:
+ max_epochs: 20
+ seed: 1
+ output_dir: ./output/transpolymer_eea
+ save_freq: 1
+ log_freq: 20
+ start_eval_epoch: 1
+ eval_freq: 1
+ resume_from_checkpoint: null
+ use_amp: False
+ amp_level: "O1"
+ eval_with_no_grad: True
+ gradient_accumulation_steps: 1
+ best_metric_indicator: "eval_metric"
+ name_for_best_metric: "value"
+ greater_is_better: True
+ compute_metric_during_train: True
+ metric_strategy_during_eval: "epoch"
+ use_visualdl: False
+ use_wandb: False
+ use_tensorboard: False
+ tolerance: 5
+
+Model:
+ __class_name__: TransPolymerRegressor
+ __init_params__:
+ pretrained_model_path: ./ckpt/pretrain.pt
+ pretrained_model_url: https://28bf65435bc4c13f5b89a153488f09972c18f7f4@git.aistudio.baidu.com/TransPolymer/TransPolymer123.git
+ property_name: ${Global.label_names}
+ tokenizer_name_or_path: roberta-base
+ vocab_sup_file: null
+ blocksize: 411
+ smiles_key: smiles
+ use_token_cache: True
+ drop_rate: 0.1
+ hidden_dropout_prob: 0.1
+ attention_probs_dropout_prob: 0.1
+ data_mean: 0.0
+ data_std: 1.0
+ loss_type: mse_loss
+
+Metric:
+ value:
+ __class_name__: R2Metric
+ __init_params__: {}
+
+Optimizer:
+ __class_name__: AdamW
+ __init_params__:
+ lr:
+ __class_name__: Linear
+ __init_params__:
+ learning_rate: 0.00005
+ warmup_epoch: 1
+ warmup_start_lr: 0.0
+ by_epoch: False
+ weight_decay: 0.01
+ no_weight_decay_name: "bias LayerNorm.bias LayerNorm.weight layer_norm.bias layer_norm.weight"
+
+Dataset:
+ transform:
+ __class_name__: mean_std_scaling
+ __init_params__: {}
+ train:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/Eea.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: True
+ drop_last: False
+ batch_size: 32
+ val:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/Eea.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 32
+ test:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/Eea.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 32
+
+Predict:
+ eval_with_no_grad: True
diff --git a/property_prediction/configs/transpolymer/transpolymer_egb_finetune.yaml b/property_prediction/configs/transpolymer/transpolymer_egb_finetune.yaml
new file mode 100644
index 00000000..4a3506cf
--- /dev/null
+++ b/property_prediction/configs/transpolymer/transpolymer_egb_finetune.yaml
@@ -0,0 +1,123 @@
+Global:
+ label_names: ["value"]
+ do_train: True
+ do_eval: False
+ do_test: False
+
+Trainer:
+ max_epochs: 20
+ seed: 1
+ output_dir: ./output/transpolymer_egb
+ save_freq: 1
+ log_freq: 20
+ start_eval_epoch: 1
+ eval_freq: 1
+ resume_from_checkpoint: null
+ use_amp: False
+ amp_level: "O1"
+ eval_with_no_grad: True
+ gradient_accumulation_steps: 1
+ best_metric_indicator: "eval_metric"
+ name_for_best_metric: "value"
+ greater_is_better: True
+ compute_metric_during_train: True
+ metric_strategy_during_eval: "epoch"
+ use_visualdl: False
+ use_wandb: False
+ use_tensorboard: False
+ tolerance: 5
+
+Model:
+ __class_name__: TransPolymerRegressor
+ __init_params__:
+ pretrained_model_path: ./ckpt/pretrain.pt
+ pretrained_model_url: https://28bf65435bc4c13f5b89a153488f09972c18f7f4@git.aistudio.baidu.com/TransPolymer/TransPolymer123.git
+ property_name: ${Global.label_names}
+ tokenizer_name_or_path: roberta-base
+ vocab_sup_file: null
+ blocksize: 411
+ smiles_key: smiles
+ use_token_cache: True
+ drop_rate: 0.1
+ hidden_dropout_prob: 0.1
+ attention_probs_dropout_prob: 0.1
+ data_mean: 0.0
+ data_std: 1.0
+ loss_type: mse_loss
+
+Metric:
+ value:
+ __class_name__: R2Metric
+ __init_params__: {}
+
+Optimizer:
+ __class_name__: AdamW
+ __init_params__:
+ lr:
+ __class_name__: Linear
+ __init_params__:
+ learning_rate: 0.00005
+ warmup_epoch: 1
+ warmup_start_lr: 0.0
+ by_epoch: False
+ weight_decay: 0.01
+ no_weight_decay_name: "bias LayerNorm.bias LayerNorm.weight layer_norm.bias layer_norm.weight"
+
+Dataset:
+ transform:
+ __class_name__: mean_std_scaling
+ __init_params__: {}
+ train:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/Egb.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: True
+ drop_last: False
+ batch_size: 32
+ val:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/Egb.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 32
+ test:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/Egb.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 32
+
+Predict:
+ eval_with_no_grad: True
diff --git a/property_prediction/configs/transpolymer/transpolymer_egc_finetune.yaml b/property_prediction/configs/transpolymer/transpolymer_egc_finetune.yaml
new file mode 100644
index 00000000..91c9dc68
--- /dev/null
+++ b/property_prediction/configs/transpolymer/transpolymer_egc_finetune.yaml
@@ -0,0 +1,123 @@
+Global:
+ label_names: ["value"]
+ do_train: True
+ do_eval: False
+ do_test: False
+
+Trainer:
+ max_epochs: 20
+ seed: 1
+ output_dir: ./output/transpolymer_egc
+ save_freq: 1
+ log_freq: 20
+ start_eval_epoch: 1
+ eval_freq: 1
+ resume_from_checkpoint: null
+ use_amp: False
+ amp_level: "O1"
+ eval_with_no_grad: True
+ gradient_accumulation_steps: 1
+ best_metric_indicator: "eval_metric"
+ name_for_best_metric: "value"
+ greater_is_better: True
+ compute_metric_during_train: True
+ metric_strategy_during_eval: "epoch"
+ use_visualdl: False
+ use_wandb: False
+ use_tensorboard: False
+ tolerance: 5
+
+Model:
+ __class_name__: TransPolymerRegressor
+ __init_params__:
+ pretrained_model_path: ./ckpt/pretrain.pt
+ pretrained_model_url: https://28bf65435bc4c13f5b89a153488f09972c18f7f4@git.aistudio.baidu.com/TransPolymer/TransPolymer123.git
+ property_name: ${Global.label_names}
+ tokenizer_name_or_path: roberta-base
+ vocab_sup_file: null
+ blocksize: 411
+ smiles_key: smiles
+ use_token_cache: True
+ drop_rate: 0.1
+ hidden_dropout_prob: 0.1
+ attention_probs_dropout_prob: 0.1
+ data_mean: 0.0
+ data_std: 1.0
+ loss_type: mse_loss
+
+Metric:
+ value:
+ __class_name__: R2Metric
+ __init_params__: {}
+
+Optimizer:
+ __class_name__: AdamW
+ __init_params__:
+ lr:
+ __class_name__: Linear
+ __init_params__:
+ learning_rate: 0.00005
+ warmup_epoch: 1
+ warmup_start_lr: 0.0
+ by_epoch: False
+ weight_decay: 0.01
+ no_weight_decay_name: "bias LayerNorm.bias LayerNorm.weight layer_norm.bias layer_norm.weight"
+
+Dataset:
+ transform:
+ __class_name__: mean_std_scaling
+ __init_params__: {}
+ train:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/Egc.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: True
+ drop_last: False
+ batch_size: 32
+ val:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/Egc.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 32
+ test:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/Egc.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 32
+
+Predict:
+ eval_with_no_grad: True
diff --git a/property_prediction/configs/transpolymer/transpolymer_ei_finetune.yaml b/property_prediction/configs/transpolymer/transpolymer_ei_finetune.yaml
new file mode 100644
index 00000000..2e5ea036
--- /dev/null
+++ b/property_prediction/configs/transpolymer/transpolymer_ei_finetune.yaml
@@ -0,0 +1,123 @@
+Global:
+ label_names: ["value"]
+ do_train: True
+ do_eval: False
+ do_test: False
+
+Trainer:
+ max_epochs: 20
+ seed: 1
+ output_dir: ./output/transpolymer_ei
+ save_freq: 1
+ log_freq: 20
+ start_eval_epoch: 1
+ eval_freq: 1
+ resume_from_checkpoint: null
+ use_amp: False
+ amp_level: "O1"
+ eval_with_no_grad: True
+ gradient_accumulation_steps: 1
+ best_metric_indicator: "eval_metric"
+ name_for_best_metric: "value"
+ greater_is_better: True
+ compute_metric_during_train: True
+ metric_strategy_during_eval: "epoch"
+ use_visualdl: False
+ use_wandb: False
+ use_tensorboard: False
+ tolerance: 5
+
+Model:
+ __class_name__: TransPolymerRegressor
+ __init_params__:
+ pretrained_model_path: ./ckpt/pretrain.pt
+ pretrained_model_url: https://28bf65435bc4c13f5b89a153488f09972c18f7f4@git.aistudio.baidu.com/TransPolymer/TransPolymer123.git
+ property_name: ${Global.label_names}
+ tokenizer_name_or_path: roberta-base
+ vocab_sup_file: null
+ blocksize: 411
+ smiles_key: smiles
+ use_token_cache: True
+ drop_rate: 0.1
+ hidden_dropout_prob: 0.1
+ attention_probs_dropout_prob: 0.1
+ data_mean: 0.0
+ data_std: 1.0
+ loss_type: mse_loss
+
+Metric:
+ value:
+ __class_name__: R2Metric
+ __init_params__: {}
+
+Optimizer:
+ __class_name__: AdamW
+ __init_params__:
+ lr:
+ __class_name__: Linear
+ __init_params__:
+ learning_rate: 0.00005
+ warmup_epoch: 1
+ warmup_start_lr: 0.0
+ by_epoch: False
+ weight_decay: 0.01
+ no_weight_decay_name: "bias LayerNorm.bias LayerNorm.weight layer_norm.bias layer_norm.weight"
+
+Dataset:
+ transform:
+ __class_name__: mean_std_scaling
+ __init_params__: {}
+ train:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/Ei.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: True
+ drop_last: False
+ batch_size: 32
+ val:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/Ei.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 32
+ test:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/Ei.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 32
+
+Predict:
+ eval_with_no_grad: True
diff --git a/property_prediction/configs/transpolymer/transpolymer_eps_finetune.yaml b/property_prediction/configs/transpolymer/transpolymer_eps_finetune.yaml
new file mode 100644
index 00000000..a86ab022
--- /dev/null
+++ b/property_prediction/configs/transpolymer/transpolymer_eps_finetune.yaml
@@ -0,0 +1,123 @@
+Global:
+ label_names: ["value"]
+ do_train: True
+ do_eval: False
+ do_test: False
+
+Trainer:
+ max_epochs: 20
+ seed: 1
+ output_dir: ./output/transpolymer_eps
+ save_freq: 1
+ log_freq: 20
+ start_eval_epoch: 1
+ eval_freq: 1
+ resume_from_checkpoint: null
+ use_amp: False
+ amp_level: "O1"
+ eval_with_no_grad: True
+ gradient_accumulation_steps: 1
+ best_metric_indicator: "eval_metric"
+ name_for_best_metric: "value"
+ greater_is_better: True
+ compute_metric_during_train: True
+ metric_strategy_during_eval: "epoch"
+ use_visualdl: False
+ use_wandb: False
+ use_tensorboard: False
+ tolerance: 5
+
+Model:
+ __class_name__: TransPolymerRegressor
+ __init_params__:
+ pretrained_model_path: ./ckpt/pretrain.pt
+ pretrained_model_url: https://28bf65435bc4c13f5b89a153488f09972c18f7f4@git.aistudio.baidu.com/TransPolymer/TransPolymer123.git
+ property_name: ${Global.label_names}
+ tokenizer_name_or_path: roberta-base
+ vocab_sup_file: null
+ blocksize: 411
+ smiles_key: smiles
+ use_token_cache: True
+ drop_rate: 0.1
+ hidden_dropout_prob: 0.1
+ attention_probs_dropout_prob: 0.1
+ data_mean: 0.0
+ data_std: 1.0
+ loss_type: mse_loss
+
+Metric:
+ value:
+ __class_name__: R2Metric
+ __init_params__: {}
+
+Optimizer:
+ __class_name__: AdamW
+ __init_params__:
+ lr:
+ __class_name__: Linear
+ __init_params__:
+ learning_rate: 0.00005
+ warmup_epoch: 1
+ warmup_start_lr: 0.0
+ by_epoch: False
+ weight_decay: 0.01
+ no_weight_decay_name: "bias LayerNorm.bias LayerNorm.weight layer_norm.bias layer_norm.weight"
+
+Dataset:
+ transform:
+ __class_name__: mean_std_scaling
+ __init_params__: {}
+ train:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/EPS.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: True
+ drop_last: False
+ batch_size: 32
+ val:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/EPS.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 32
+ test:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/EPS.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 32
+
+Predict:
+ eval_with_no_grad: True
diff --git a/property_prediction/configs/transpolymer/transpolymer_nc_finetune.yaml b/property_prediction/configs/transpolymer/transpolymer_nc_finetune.yaml
new file mode 100644
index 00000000..6c1909d4
--- /dev/null
+++ b/property_prediction/configs/transpolymer/transpolymer_nc_finetune.yaml
@@ -0,0 +1,123 @@
+Global:
+ label_names: ["value"]
+ do_train: True
+ do_eval: False
+ do_test: False
+
+Trainer:
+ max_epochs: 20
+ seed: 1
+ output_dir: ./output/transpolymer_nc
+ save_freq: 1
+ log_freq: 20
+ start_eval_epoch: 1
+ eval_freq: 1
+ resume_from_checkpoint: null
+ use_amp: False
+ amp_level: "O1"
+ eval_with_no_grad: True
+ gradient_accumulation_steps: 1
+ best_metric_indicator: "eval_metric"
+ name_for_best_metric: "value"
+ greater_is_better: True
+ compute_metric_during_train: True
+ metric_strategy_during_eval: "epoch"
+ use_visualdl: False
+ use_wandb: False
+ use_tensorboard: False
+ tolerance: 5
+
+Model:
+ __class_name__: TransPolymerRegressor
+ __init_params__:
+ pretrained_model_path: ./ckpt/pretrain.pt
+ pretrained_model_url: https://28bf65435bc4c13f5b89a153488f09972c18f7f4@git.aistudio.baidu.com/TransPolymer/TransPolymer123.git
+ property_name: ${Global.label_names}
+ tokenizer_name_or_path: roberta-base
+ vocab_sup_file: null
+ blocksize: 411
+ smiles_key: smiles
+ use_token_cache: True
+ drop_rate: 0.1
+ hidden_dropout_prob: 0.1
+ attention_probs_dropout_prob: 0.1
+ data_mean: 0.0
+ data_std: 1.0
+ loss_type: mse_loss
+
+Metric:
+ value:
+ __class_name__: R2Metric
+ __init_params__: {}
+
+Optimizer:
+ __class_name__: AdamW
+ __init_params__:
+ lr:
+ __class_name__: Linear
+ __init_params__:
+ learning_rate: 0.00005
+ warmup_epoch: 1
+ warmup_start_lr: 0.0
+ by_epoch: False
+ weight_decay: 0.01
+ no_weight_decay_name: "bias LayerNorm.bias LayerNorm.weight layer_norm.bias layer_norm.weight"
+
+Dataset:
+ transform:
+ __class_name__: mean_std_scaling
+ __init_params__: {}
+ train:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/Nc.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: True
+ drop_last: False
+ batch_size: 32
+ val:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/Nc.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 32
+ test:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/Nc.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 32
+
+Predict:
+ eval_with_no_grad: True
diff --git a/property_prediction/configs/transpolymer/transpolymer_opv_finetune.yaml b/property_prediction/configs/transpolymer/transpolymer_opv_finetune.yaml
new file mode 100644
index 00000000..ff1d2104
--- /dev/null
+++ b/property_prediction/configs/transpolymer/transpolymer_opv_finetune.yaml
@@ -0,0 +1,123 @@
+Global:
+ label_names: ["PCE_ave"]
+ do_train: True
+ do_eval: False
+ do_test: False
+
+Trainer:
+ max_epochs: 20
+ seed: 1
+ output_dir: ./output/transpolymer_opv
+ save_freq: 1
+ log_freq: 20
+ start_eval_epoch: 1
+ eval_freq: 1
+ resume_from_checkpoint: null
+ use_amp: False
+ amp_level: "O1"
+ eval_with_no_grad: True
+ gradient_accumulation_steps: 1
+ best_metric_indicator: "eval_metric"
+ name_for_best_metric: "PCE_ave"
+ greater_is_better: True
+ compute_metric_during_train: True
+ metric_strategy_during_eval: "epoch"
+ use_visualdl: False
+ use_wandb: False
+ use_tensorboard: False
+ tolerance: 5
+
+Model:
+ __class_name__: TransPolymerRegressor
+ __init_params__:
+ pretrained_model_path: ./ckpt/pretrain.pt
+ pretrained_model_url: https://28bf65435bc4c13f5b89a153488f09972c18f7f4@git.aistudio.baidu.com/TransPolymer/TransPolymer123.git
+ property_name: ${Global.label_names}
+ tokenizer_name_or_path: roberta-base
+ vocab_sup_file: ./data/vocab/vocab_sup_OPV.csv
+ blocksize: 411
+ smiles_key: CSMILES
+ use_token_cache: True
+ drop_rate: 0.1
+ hidden_dropout_prob: 0.1
+ attention_probs_dropout_prob: 0.1
+ data_mean: 0.0
+ data_std: 1.0
+ loss_type: mse_loss
+
+Metric:
+ PCE_ave:
+ __class_name__: R2Metric
+ __init_params__: {}
+
+Optimizer:
+ __class_name__: AdamW
+ __init_params__:
+ lr:
+ __class_name__: Linear
+ __init_params__:
+ learning_rate: 0.00005
+ warmup_epoch: 1
+ warmup_start_lr: 0.0
+ by_epoch: False
+ weight_decay: 0.01
+ no_weight_decay_name: "bias LayerNorm.bias LayerNorm.weight layer_norm.bias layer_norm.weight"
+
+Dataset:
+ transform:
+ __class_name__: mean_std_scaling
+ __init_params__: {}
+ train:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/OPV.csv
+ property_names: ${Global.label_names}
+ smiles_key: CSMILES
+ loader:
+ num_workers: 0
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: True
+ drop_last: False
+ batch_size: 8
+ val:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/OPV.csv
+ property_names: ${Global.label_names}
+ smiles_key: CSMILES
+ loader:
+ num_workers: 0
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 8
+ test:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/OPV.csv
+ property_names: ${Global.label_names}
+ smiles_key: CSMILES
+ loader:
+ num_workers: 0
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 8
+
+Predict:
+ eval_with_no_grad: True
diff --git a/property_prediction/configs/transpolymer/transpolymer_pe_i_finetune.yaml b/property_prediction/configs/transpolymer/transpolymer_pe_i_finetune.yaml
new file mode 100644
index 00000000..180f4cbb
--- /dev/null
+++ b/property_prediction/configs/transpolymer/transpolymer_pe_i_finetune.yaml
@@ -0,0 +1,142 @@
+Global:
+ label_names: ["Conductivity [S/cm]"]
+ do_train: True
+ do_eval: False
+ do_test: False
+
+Trainer:
+ # Max epochs to train
+ max_epochs: 20
+ # Random seed
+ seed: 1
+ # Save path for checkpoints and logs
+ output_dir: ./output/transpolymer_pe_i
+ # Save frequency [epoch], set 0 to disable saving during training
+ save_freq: 1
+ # Logging frequency [step]
+ log_freq: 20
+ # Start evaluation epoch
+ start_eval_epoch: 1
+ # Evaluation frequency [epoch]
+ eval_freq: 1
+ # Resume from checkpoint path, useful for resuming training
+ resume_from_checkpoint: null
+ # Whether use automatic mixed precision
+ use_amp: False
+ # Automatic mixed precision level
+ amp_level: "O1"
+ # Whether run the model on no_grad mode during evaluation
+ eval_with_no_grad: True
+ # Gradient accumulation steps
+ gradient_accumulation_steps: 1
+ # Best metric settings
+ best_metric_indicator: "eval_metric"
+ name_for_best_metric: "Conductivity [S/cm]"
+ greater_is_better: True
+ # Compute metric during training or evaluation
+ compute_metric_during_train: True
+ metric_strategy_during_eval: "epoch"
+ # Logging backends
+ use_visualdl: False
+ use_wandb: False
+ use_tensorboard: False
+ # Early stop tolerance
+ tolerance: 5
+
+Model:
+ __class_name__: TransPolymerRegressor
+ __init_params__:
+ pretrained_model_path: ./ckpt/pretrain.pt
+ pretrained_model_url: https://28bf65435bc4c13f5b89a153488f09972c18f7f4@git.aistudio.baidu.com/TransPolymer/TransPolymer123.git
+ property_name: ${Global.label_names}
+ tokenizer_name_or_path: roberta-base
+ vocab_sup_file: ./data/vocab/vocab_sup_PE_I.csv
+ blocksize: 411
+ smiles_key: smiles
+ use_token_cache: True
+ drop_rate: 0.1
+ hidden_dropout_prob: 0.1
+ attention_probs_dropout_prob: 0.1
+ data_mean: 0.0
+ data_std: 1.0
+ loss_type: mse_loss
+
+Metric:
+ Conductivity [S/cm]:
+ __class_name__: R2Metric
+ __init_params__: {}
+
+Optimizer:
+ __class_name__: AdamW
+ __init_params__:
+ lr:
+ __class_name__: Linear
+ __init_params__:
+ learning_rate: 0.00005
+ warmup_epoch: 1
+ warmup_start_lr: 0.0
+ by_epoch: False
+ weight_decay: 0.01
+ no_weight_decay_name: "bias LayerNorm.bias LayerNorm.weight layer_norm.bias layer_norm.weight"
+
+Dataset:
+ transform:
+ __class_name__: mean_std_scaling
+ __init_params__: {}
+
+ train:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/train_PE_I.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: True
+ drop_last: False
+ batch_size: 32
+
+ val:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/test_PE_I.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 32
+
+ test:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/test_PE_I.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 32
+
+Predict:
+ eval_with_no_grad: True
diff --git a/property_prediction/configs/transpolymer/transpolymer_pe_ii_finetune.yaml b/property_prediction/configs/transpolymer/transpolymer_pe_ii_finetune.yaml
new file mode 100644
index 00000000..9af0acea
--- /dev/null
+++ b/property_prediction/configs/transpolymer/transpolymer_pe_ii_finetune.yaml
@@ -0,0 +1,123 @@
+Global:
+ label_names: ["logCond60"]
+ do_train: True
+ do_eval: False
+ do_test: False
+
+Trainer:
+ max_epochs: 20
+ seed: 1
+ output_dir: ./output/transpolymer_pe_ii
+ save_freq: 1
+ log_freq: 20
+ start_eval_epoch: 1
+ eval_freq: 1
+ resume_from_checkpoint: null
+ use_amp: False
+ amp_level: "O1"
+ eval_with_no_grad: True
+ gradient_accumulation_steps: 1
+ best_metric_indicator: "eval_metric"
+ name_for_best_metric: "logCond60"
+ greater_is_better: True
+ compute_metric_during_train: True
+ metric_strategy_during_eval: "epoch"
+ use_visualdl: False
+ use_wandb: False
+ use_tensorboard: False
+ tolerance: 5
+
+Model:
+ __class_name__: TransPolymerRegressor
+ __init_params__:
+ pretrained_model_path: ./ckpt/pretrain.pt
+ pretrained_model_url: https://28bf65435bc4c13f5b89a153488f09972c18f7f4@git.aistudio.baidu.com/TransPolymer/TransPolymer123.git
+ property_name: ${Global.label_names}
+ tokenizer_name_or_path: roberta-base
+ vocab_sup_file: ./data/vocab/vocab_sup_PE_II.csv
+ blocksize: 411
+ smiles_key: "SMILES descriptor 1"
+ use_token_cache: True
+ drop_rate: 0.1
+ hidden_dropout_prob: 0.1
+ attention_probs_dropout_prob: 0.1
+ data_mean: 0.0
+ data_std: 1.0
+ loss_type: mse_loss
+
+Metric:
+ logCond60:
+ __class_name__: R2Metric
+ __init_params__: {}
+
+Optimizer:
+ __class_name__: AdamW
+ __init_params__:
+ lr:
+ __class_name__: Linear
+ __init_params__:
+ learning_rate: 0.00005
+ warmup_epoch: 1
+ warmup_start_lr: 0.0
+ by_epoch: False
+ weight_decay: 0.01
+ no_weight_decay_name: "bias LayerNorm.bias LayerNorm.weight layer_norm.bias layer_norm.weight"
+
+Dataset:
+ transform:
+ __class_name__: mean_std_scaling
+ __init_params__: {}
+ train:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/PE_II.csv
+ property_names: ${Global.label_names}
+ smiles_key: "SMILES descriptor 1"
+ loader:
+ num_workers: 0
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: True
+ drop_last: False
+ batch_size: 8
+ val:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/PE_II.csv
+ property_names: ${Global.label_names}
+ smiles_key: "SMILES descriptor 1"
+ loader:
+ num_workers: 0
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 8
+ test:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/PE_II.csv
+ property_names: ${Global.label_names}
+ smiles_key: "SMILES descriptor 1"
+ loader:
+ num_workers: 0
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 8
+
+Predict:
+ eval_with_no_grad: True
diff --git a/property_prediction/configs/transpolymer/transpolymer_xc_finetune.yaml b/property_prediction/configs/transpolymer/transpolymer_xc_finetune.yaml
new file mode 100644
index 00000000..6a924ba1
--- /dev/null
+++ b/property_prediction/configs/transpolymer/transpolymer_xc_finetune.yaml
@@ -0,0 +1,123 @@
+Global:
+ label_names: ["value"]
+ do_train: True
+ do_eval: False
+ do_test: False
+
+Trainer:
+ max_epochs: 20
+ seed: 1
+ output_dir: ./output/transpolymer_xc
+ save_freq: 1
+ log_freq: 20
+ start_eval_epoch: 1
+ eval_freq: 1
+ resume_from_checkpoint: null
+ use_amp: False
+ amp_level: "O1"
+ eval_with_no_grad: True
+ gradient_accumulation_steps: 1
+ best_metric_indicator: "eval_metric"
+ name_for_best_metric: "value"
+ greater_is_better: True
+ compute_metric_during_train: True
+ metric_strategy_during_eval: "epoch"
+ use_visualdl: False
+ use_wandb: False
+ use_tensorboard: False
+ tolerance: 5
+
+Model:
+ __class_name__: TransPolymerRegressor
+ __init_params__:
+ pretrained_model_path: ./ckpt/pretrain.pt
+ pretrained_model_url: https://28bf65435bc4c13f5b89a153488f09972c18f7f4@git.aistudio.baidu.com/TransPolymer/TransPolymer123.git
+ property_name: ${Global.label_names}
+ tokenizer_name_or_path: roberta-base
+ vocab_sup_file: null
+ blocksize: 411
+ smiles_key: smiles
+ use_token_cache: True
+ drop_rate: 0.1
+ hidden_dropout_prob: 0.1
+ attention_probs_dropout_prob: 0.1
+ data_mean: 0.0
+ data_std: 1.0
+ loss_type: mse_loss
+
+Metric:
+ value:
+ __class_name__: R2Metric
+ __init_params__: {}
+
+Optimizer:
+ __class_name__: AdamW
+ __init_params__:
+ lr:
+ __class_name__: Linear
+ __init_params__:
+ learning_rate: 0.00005
+ warmup_epoch: 1
+ warmup_start_lr: 0.0
+ by_epoch: False
+ weight_decay: 0.01
+ no_weight_decay_name: "bias LayerNorm.bias LayerNorm.weight layer_norm.bias layer_norm.weight"
+
+Dataset:
+ transform:
+ __class_name__: mean_std_scaling
+ __init_params__: {}
+ train:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/Xc.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: True
+ drop_last: False
+ batch_size: 32
+ val:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/Xc.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 32
+ test:
+ dataset:
+ __class_name__: TransPolymerCsvDataset
+ __init_params__:
+ path: ./data/Xc.csv
+ property_names: ${Global.label_names}
+ smiles_key: smiles
+ loader:
+ num_workers: 8
+ use_shared_memory: False
+ collate_fn: DefaultCollator
+ sampler:
+ __class_name__: BatchSampler
+ __init_params__:
+ shuffle: False
+ drop_last: False
+ batch_size: 32
+
+Predict:
+ eval_with_no_grad: True
diff --git a/property_prediction/example_data/transpolymer_predict.csv b/property_prediction/example_data/transpolymer_predict.csv
new file mode 100644
index 00000000..5fb26aa7
--- /dev/null
+++ b/property_prediction/example_data/transpolymer_predict.csv
@@ -0,0 +1,4 @@
+smiles
+[*]CC[*]
+[*]C(=O)OCC[*]
+[*]c1ccccc1[*]
diff --git a/property_prediction/predict.py b/property_prediction/predict.py
index 3866bcba..3d80311d 100644
--- a/property_prediction/predict.py
+++ b/property_prediction/predict.py
@@ -101,7 +101,7 @@ def __init__(
self.model.eval()
- predict_config = config.get("Predict", None)
+ predict_config = config.get("Predict", None) or {}
self.predict_config = predict_config
self.eval_with_no_grad = predict_config.get("eval_with_no_grad", True)
@@ -117,6 +117,9 @@ def __init__(
else:
self.post_transforms = None
+ model_params = config.get("Model", {}).get("__init_params__", {})
+ self.smiles_key = model_params.get("smiles_key", "smiles")
+
def graph_converter(self, structure):
if self.graph_converter_fn is None:
return structure
@@ -182,6 +185,35 @@ def from_cif_file(self, cif_file_path, save_path=None):
return result
+ @staticmethod
+ def _flatten_prediction(value):
+ if isinstance(value, paddle.Tensor):
+ value = value.numpy()
+ if hasattr(value, "reshape"):
+ return value.reshape([-1]).tolist()
+ if isinstance(value, (list, tuple)):
+ return list(value)
+ return [value]
+
+ def from_csv_file(self, csv_file_path, smiles_column="smiles", save_path=None):
+ if save_path is not None:
+ assert save_path.endswith(".csv"), "save_path must end with .csv"
+
+ df = pd.read_csv(csv_file_path)
+ if smiles_column not in df.columns:
+ smiles_column = df.columns[0]
+
+ data = {self.smiles_key: df[smiles_column].astype(str).tolist()}
+ result = self.from_structures(data)
+
+ if save_path is not None:
+ for key, value in result.items():
+ df[key] = self._flatten_prediction(value)
+ df.to_csv(save_path, index=False)
+ logger.info(f"Saved the prediction result to {save_path}")
+
+ return result
+
if __name__ == "__main__":
@@ -216,6 +248,18 @@ def from_cif_file(self, cif_file_path, save_path=None):
default="./property_prediction/example_data/cifs/",
help="Path to the CIF file whose material properties you want to predict.",
)
+ argparse.add_argument(
+ "--csv_file_path",
+ type=str,
+ default=None,
+ help="Path to the CSV file whose SMILES properties you want to predict.",
+ )
+ argparse.add_argument(
+ "--smiles_column",
+ type=str,
+ default="smiles",
+ help="SMILES column name in the input CSV file.",
+ )
argparse.add_argument(
"--save_path",
type=str,
@@ -231,5 +275,10 @@ def from_cif_file(self, cif_file_path, save_path=None):
checkpoint_path=args.checkpoint_path,
)
- results = predictor.from_cif_file(args.cif_file_path, args.save_path)
+ if args.csv_file_path is not None:
+ results = predictor.from_csv_file(
+ args.csv_file_path, args.smiles_column, args.save_path
+ )
+ else:
+ results = predictor.from_cif_file(args.cif_file_path, args.save_path)
print(results)
diff --git a/test/test_transpolymer_smoke.py b/test/test_transpolymer_smoke.py
new file mode 100644
index 00000000..c5fb40ef
--- /dev/null
+++ b/test/test_transpolymer_smoke.py
@@ -0,0 +1,38 @@
+import paddle
+
+from ppmat.models.transpolymer.modeling import RobertaConfig
+from ppmat.models.transpolymer.modeling import RobertaModel
+from ppmat.models.transpolymer.transpolymer import TransPolymerRegressor
+
+
+def test_transpolymer_model_forward():
+ config = RobertaConfig(
+ vocab_size=128,
+ hidden_size=32,
+ num_hidden_layers=1,
+ num_attention_heads=4,
+ intermediate_size=64,
+ max_position_embeddings=32,
+ type_vocab_size=1,
+ )
+ model = RobertaModel(config)
+ input_ids = paddle.randint(0, 128, shape=[2, 16], dtype="int64")
+ attention_mask = paddle.ones([2, 16], dtype="int64")
+ outputs = model(input_ids=input_ids, attention_mask=attention_mask)
+ assert list(outputs.last_hidden_state.shape) == [2, 16, 32]
+
+
+def test_transpolymer_regressor_forward():
+ model = TransPolymerRegressor(
+ vocab_size=128,
+ hidden_size=32,
+ intermediate_size=64,
+ max_position_embeddings=32,
+ num_attention_heads=4,
+ num_hidden_layers=1,
+ resize_vocab_size=128,
+ )
+ input_ids = paddle.randint(0, 128, shape=[2, 16], dtype="int64")
+ attention_mask = paddle.ones([2, 16], dtype="int64")
+ pred = model(input_ids, attention_mask)
+ assert list(pred.shape) == [2, 1]