Views
No views yet
1import torch
2import torch.nn as nn
3from transformers import AutoTokenizer, T5ForConditionalGeneration, AutoConfig, PreTrainedModel
4
5class ReactionT5Yield(PreTrainedModel):
6 config_class = AutoConfig
7 def __init__(self, config):
8 super().__init__(config)
9 self.config = config
10 self.model = T5ForConditionalGeneration.from_pretrained(self.config._name_or_path)
11 self.model.resize_token_embeddings(self.config.vocab_size)
12 self.fc1 = nn.Linear(self.config.hidden_size, self.config.hidden_size//2)
13 self.fc2 = nn.Linear(self.config.hidden_size, self.config.hidden_size//2)
14 self.fc3 = nn.Linear(self.config.hidden_size//2*2, self.config.hidden_size)
15 self.fc4 = nn.Linear(self.config.hidden_size, self.config.hidden_size)
16 self.fc5 = nn.Linear(self.config.hidden_size, 1)
17
18 self._init_weights(self.fc1)
19 self._init_weights(self.fc2)
20 self._init_weights(self.fc3)
21 self._init_weights(self.fc4)
22 self._init_weights(self.fc5)
23
24 def _init_weights(self, module):
25 if isinstance(module, nn.Linear):
26 module.weight.data.normal_(mean=0.0, std=0.01)
27 if module.bias is not None:
28 module.bias.data.zero_()
29 elif isinstance(module, nn.Embedding):
30 module.weight.data.normal_(mean=0.0, std=0.01)
31 if module.padding_idx is not None:
32 module.weight.data[module.padding_idx].zero_()
33 elif isinstance(module, nn.LayerNorm):
34 module.bias.data.zero_()
35 module.weight.data.fill_(1.0)
36
37 def forward(self, inputs):
38 encoder_outputs = self.model.encoder(**inputs)
39 encoder_hidden_states = encoder_outputs[0]
40 outputs = self.model.decoder(input_ids=torch.full((inputs['input_ids'].size(0),1),
41 self.config.decoder_start_token_id,
42 dtype=torch.long), encoder_hidden_states=encoder_hidden_states)
43 last_hidden_states = outputs[0]
44 output1 = self.fc1(last_hidden_states.view(-1, self.config.hidden_size))
45 output2 = self.fc2(encoder_hidden_states[:, 0, :].view(-1, self.config.hidden_size))
46 output = self.fc3(torch.hstack((output1, output2)))
47 output = self.fc4(output)
48 output = self.fc5(output)
49 return output*100
50
51
52model = ReactionT5Yield.from_pretrained('sagawa/ReactionT5v1-yield')
53tokenizer = AutoTokenizer.from_pretrained('sagawa/ReactionT5v1-yield')
54inp = tokenizer(['REACTANT:CC(C)n1ncnc1-c1cn2c(n1)-c1cnc(O)cc1OCC2.CCN(C(C)C)C(C)C.Cl.NC(=O)[C@@H]1C[C@H](F)CN1REAGENT: PRODUCT:O=C(NNC(=O)C(F)(F)F)C(F)(F)F'], return_tensors='pt')
55print(model(inp)) # tensor([[19.1666]], grad_fn=<MulBackward0>)1python train.py
2 --data_path='all_ord_reaction_uniq_with_attr_v3.tsv'
3 --pretrained_model_name_or_path='sagawa/ZINC-t5'
4 --model='t5'
5 --epochs=100
6 --batch_size=50
7 --max_len=400
8 --num_workers=4
9 --weight_decay=0.05
10 --gradient_accumulation_steps=1
11 --batch_scheduler
12 --print_freq=100
13 --output_dir='./'| R^2 | DFT | MFF | Yield-BERT | T5Chem | CompoundT5 | ReactionT5 (without finetuning) |
|---|---|---|---|---|---|---|
| Random 70/30 | 0.92 | 0.927 ± 0.007 | 0.951 ± 0.005 | 0.970 ± 0.003 | 0.971 ± 0.002 | 0.904 ± 0.0007 |
| Test 1 | 0.80 | 0.851 | 0.838 | 0.811 | 0.855 | 0.919 |
| Test 2 | 0.77 | 0.713 | 0.836 | 0.907 | 0.852 | 0.927 |
| Test 3 | 0.64 | 0.635 | 0.738 | 0.789 | 0.712 | 0.847 |
| Test 4 | 0.54 | 0.184 | 0.538 | 0.627 | 0.547 | 0.909 |
| Avg. Tests 1–4 | 0.69 ± 0.104 | 0.596 ± 0.251 | 0.738 ± 0.122 | 0.785 ± 0.094 | 0.741 ± 0.126 | 0.900 ± 0.031 |
@misc{sagawa2023reactiont5,
title={ReactionT5: a large-scale pre-trained model towards application of limited reaction data},
author={Tatsuya Sagawa and Ryosuke Kojima},
year={2023},
eprint={2311.06708},
archivePrefix={arXiv},
primaryClass={physics.chem-ph}
}