class Runner(object): def __init__(self, exp_name: str): self.exp_name = exp_name self.model_dir = 'saved_models' self.hyper = Hyper(os.path.join('experiments', self.exp_name + '.json')) self.gpu = self.hyper.gpu self.preprocessor = None self.triplet_metrics = F1_triplet() self.ner_metrics = F1_ner() self.optimizer = None self.model = None def _optimizer(self, name, model): m = { 'adam': Adam(model.parameters()), 'sgd': SGD(model.parameters(), lr=0.5), 'adamw': AdamW(model.parameters()) } return m[name] def _init_model(self): self.model = MultiHeadSelection(self.hyper).cuda( self.gpu) if torch.cuda.is_available() else MultiHeadSelection( self.hyper) def preprocessing(self): if self.exp_name == 'conll_selection_re': self.preprocessor = Conll_selection_preprocessing(self.hyper) elif self.exp_name == 'chinese_selection_re': self.preprocessor = Chinese_selection_preprocessing(self.hyper) elif self.exp_name == 'conll_bert_re': self.preprocessor = Conll_bert_preprocessing(self.hyper) self.preprocessor.gen_relation_vocab() self.preprocessor.gen_all_data() self.preprocessor.gen_vocab(min_freq=1) # for ner only self.preprocessor.gen_bio_vocab() def run(self, mode: str): if mode == 'preprocessing': self.preprocessing() elif mode == 'train': self._init_model() self.optimizer = self._optimizer(self.hyper.optimizer, self.model) self.train() elif mode == 'evaluation': self._init_model() self.load_model(epoch=self.hyper.evaluation_epoch) self.evaluation() else: raise ValueError('invalid mode') def load_model(self, epoch: int): self.model.load_state_dict( torch.load( os.path.join(self.model_dir, self.exp_name + '_' + str(epoch)))) def save_model(self, epoch: int): if not os.path.exists(self.model_dir): os.mkdir(self.model_dir) torch.save( self.model.state_dict(), os.path.join(self.model_dir, self.exp_name + '_' + str(epoch))) def evaluation(self): dev_set = Selection_Dataset(self.hyper, self.hyper.dev) loader = Selection_loader(dev_set, batch_size=self.hyper.eval_batch, pin_memory=True) self.triplet_metrics.reset() self.model.eval() pbar = tqdm(enumerate(BackgroundGenerator(loader)), total=len(loader)) with torch.no_grad(): for batch_ndx, sample in pbar: output = self.model(sample, is_train=False) self.triplet_metrics(output['selection_triplets'], output['spo_gold']) self.ner_metrics(output['gold_tags'], output['decoded_tag']) triplet_result = self.triplet_metrics.get_metric() ner_result = self.ner_metrics.get_metric() print('Triplets-> ' + ', '.join([ "%s: %.4f" % (name[0], value) for name, value in triplet_result.items() if not name.startswith("_") ]) + ' ||' + 'NER->' + ', '.join([ "%s: %.4f" % (name[0], value) for name, value in ner_result.items() if not name.startswith("_") ])) def train(self): train_set = Selection_Dataset(self.hyper, self.hyper.train) loader = Selection_loader(train_set, batch_size=self.hyper.train_batch, pin_memory=True) for epoch in range(self.hyper.epoch_num): self.model.train() pbar = tqdm(enumerate(BackgroundGenerator(loader)), total=len(loader)) for batch_idx, sample in pbar: self.optimizer.zero_grad() output = self.model(sample, is_train=True) loss = output['loss'] loss.backward() self.optimizer.step() pbar.set_description(output['description']( epoch, self.hyper.epoch_num)) # break self.save_model(epoch) if epoch % self.hyper.print_epoch == 0 and epoch > 3: self.evaluation()
class Runner(object): def __init__(self, exp_name: str): self.exp_name = exp_name self.model_dir = 'saved_models' self.hyper = Hyper(os.path.join('experiments', self.exp_name + '.json')) self.gpu = self.hyper.gpu self.preprocessor = None self.selection_metrics = F1_selection() self.optimizer = None self.model = None def _optimizer(self, name, model): m = { 'adam': Adam(model.parameters()), 'sgd': SGD(model.parameters(), lr=0.5), 'adamw': AdamW(model.parameters()) } return m[name] def _init_model(self): # if hyper.use_multi_gpu == 1: # self.model = nn.DataParallel(MultiHeadSelection(self.hyper).cuda()) # else: self.model = MultiHeadSelection(self.hyper).cuda(self.gpu) self.criterion = nn.BCEWithLogitsLoss() def preprocessing(self): if self.exp_name == 'DuIE_selection_re': self.preprocessor = Chinese_selection_preprocessing(self.hyper) self.preprocessor.gen_relation_vocab() self.preprocessor.gen_all_data() self.preprocessor.gen_vocab(min_freq=1) # for ner only self.preprocessor.gen_bio_vocab() def run(self, mode: str): if mode == 'preprocessing': self.preprocessing() elif mode == 'train': self._init_model() self.optimizer = self._optimizer(self.hyper.optimizer, self.model) self.train() elif mode == 'evaluation': self._init_model() self.load_model(epoch=self.hyper.evaluation_epoch) self.evaluation() else: raise ValueError('invalid mode') def load_model(self, epoch: int): self.model.load_state_dict( torch.load( os.path.join(self.model_dir, self.exp_name + '_' + str(epoch)))) def save_model(self, epoch: int): if not os.path.exists(self.model_dir): os.mkdir(self.model_dir) torch.save( self.model.state_dict(), os.path.join(self.model_dir, self.exp_name + '_' + str(epoch))) @staticmethod def description(epoch, epoch_num, output): return "L: {:.7f} epoch: {}/{}:".format(output.item(), epoch, epoch_num) def evaluation(self): dev_set = Selection_Dataset(self.hyper, self.hyper.dev) loader = Selection_loader(dev_set, batch_size=self.hyper.eval_batch, pin_memory=True) self.selection_metrics.reset() self.model.eval() pbar = tqdm(enumerate(BackgroundGenerator(loader)), total=len(loader)) with torch.no_grad(): for batch_ndx, sample in pbar: pred = self.model(sample, is_train=False) pred = torch.sigmoid(pred) > 0.5 labels = sample.selection_id self.selection_metrics( np.array(pred.cpu().numpy(), dtype=int).tolist(), np.array(labels.cpu().numpy(), dtype=int).tolist()) triplet_result = self.selection_metrics.get_metric() print('Triplets-> ' + ', '.join([ "%s: %.4f" % (name[0], value) for name, value in triplet_result.items() if not name.startswith("_") ])) def train(self): train_set = Selection_Dataset(self.hyper, self.hyper.train) loader = Selection_loader(train_set, batch_size=self.hyper.train_batch, pin_memory=True) for epoch in range(self.hyper.epoch_num): self.model.train() pbar = tqdm(enumerate(BackgroundGenerator(loader)), total=len(loader)) for batch_idx, sample in pbar: self.optimizer.zero_grad() output = self.model(sample, is_train=True) output = output.to('cpu') loss = self.criterion(output, sample.selection_id) loss.backward() self.optimizer.step() pbar.set_description( self.description(epoch, self.hyper.epoch_num, loss)) self.save_model(epoch) if epoch % self.hyper.print_epoch == 0: self.evaluation()
class Runner(object): def __init__(self, exp_name: str): self.exp_name = exp_name self.model_dir = 'saved_models' self.hyper = Hyper(os.path.join('experiments', self.exp_name + '.json')) self.gpu = self.hyper.gpu if self.hyper.is_bert == 'ERNIE': self.preprocessor = Chinese_selection_preprocessing(self.hyper) elif self.hyper.is_bert == "bert_bilstem_crf": self.preprocessor = NYT_selection_preprocessing(self.hyper) elif self.hyper.is_bert == "nyt_bert_tokenizer": self.preprocessor = NYT_bert_selection_preprocessing(self.hyper) elif self.hyper.is_bert == "nyt11_bert_tokenizer": self.preprocessor = NYT11_bert_selection_preprocessing(self.hyper) elif self.hyper.is_bert == "nyt10_bert_tokenizer": self.preprocessor = NYT10_bert_selection_preprocessing(self.hyper) self.metrics = F1_triplet() def _optimizer(self, name, model): m = { 'adam': Adam(model.parameters()), 'sgd': SGD(model.parameters(), lr=0.01) } return m[name] def init_MultiHeadSelection(self): self.model = MultiHeadSelection(self.hyper).cuda(self.gpu) self.optimizer = self._optimizer(self.hyper.optimizer, self.model) def preprocessing(self): self.preprocessor.gen_relation_vocab() self.preprocessor.gen_all_data() self.preprocessor.gen_vocab(min_freq=1) self.preprocessor.gen_ERNIE_vocab() # for ner only self.preprocessor.gen_bio_vocab() def run(self, mode: str): if mode == 'preprocessing': self.preprocessing() elif mode == 'train': self.init_MultiHeadSelection() #self.load_lastest_models() #self.load_model(40) self.train() elif mode == 'evaluation': self.init_MultiHeadSelection() #self.load_model(epoch=self.hyper.evaluation_epoch) self.load_lastest_models() #self.load_model(0) self.evaluation() else: raise ValueError('invalid mode') def get_lastest_model_dir(self, model_dir: str): file_new = '' lists = os.listdir(model_dir) if len(lists) != 0: lists.sort(key=lambda fn: os.path.getmtime(model_dir + "/" + fn)) file_new = os.path.join(model_dir, lists[-1]) return file_new def load_lastest_models(self): model_dir = self.get_lastest_model_dir(self.model_dir) if model_dir != '': self.model.load_state_dict(torch.load(model_dir)) return None def load_model(self, epoch: int): self.model.load_state_dict( torch.load( os.path.join(self.model_dir, self.exp_name + '_' + str(epoch)))) def save_model(self, epoch: int): if not os.path.exists(self.model_dir): os.mkdir(self.model_dir) torch.save( self.model.state_dict(), os.path.join(self.model_dir, self.exp_name + '_' + str(epoch))) def evaluation(self): if self.hyper.is_bert == "nyt_bert_tokenizer" or \ self.hyper.is_bert == "nyt11_bert_tokenizer" or \ self.hyper.is_bert == "nyt10_bert_tokenizer": dev_set = Selection_bert_Nyt_Dataset(self.hyper, self.hyper.dev) loader = Selection_bert_loader(dev_set, batch_size=100, pin_memory=True) elif self.hyper.is_bert == "bert_bilstem_crf": dev_set = Selection_Nyt_Dataset(self.hyper, self.hyper.dev) loader = Selection_loader(dev_set, batch_size=100, pin_memory=True) else: dev_set = Selection_Dataset(self.hyper, self.hyper.dev) loader = Selection_loader(dev_set, batch_size=100, pin_memory=True) self.metrics.reset() self.model.eval() pbar = tqdm(enumerate(BackgroundGenerator(loader)), total=len(loader)) with torch.no_grad(): for batch_ndx, sample in pbar: output = self.model(sample, is_train=False) #self.metrics(output['selection_triplets'], output['spo_gold']) self.metrics(output, output) result = self.metrics.get_metric() print(', '.join([ "%s: %.4f" % (name, value) for name, value in result.items() if not name.startswith("_") ]) + " ||") def train(self): if self.hyper.is_bert == "bert_bilstem_crf": train_set = Selection_Nyt_Dataset(self.hyper, self.hyper.train) loader = Selection_loader(train_set, batch_size=100, pin_memory=True) elif self.hyper.is_bert == "nyt_bert_tokenizer" or \ self.hyper.is_bert == "nyt11_bert_tokenizer" or \ self.hyper.is_bert == "nyt10_bert_tokenizer": train_set = Selection_bert_Nyt_Dataset(self.hyper, self.hyper.train) loader = Selection_bert_loader(train_set, batch_size=100, pin_memory=True) else: train_set = Selection_Dataset(self.hyper, self.hyper.train) loader = Selection_loader(train_set, batch_size=100, pin_memory=True) for epoch in range(self.hyper.epoch_num): self.model.train() pbar = tqdm(enumerate(BackgroundGenerator(loader)), total=len(loader)) for batch_idx, sample in pbar: self.optimizer.zero_grad() output = self.model(sample, is_train=True) loss = output['loss'] loss.backward() self.optimizer.step() pbar.set_description(output['description']( epoch, self.hyper.epoch_num)) self.save_model(epoch) if epoch > 3: self.evaluation() #if epoch >= 6: # self.evaluation() '''
class Runner(object): def __init__(self, exp_name: str): self.exp_name = exp_name self.model_dir = 'saved_models' self.device = torch.device('cpu') self.hyper = Hyper(os.path.join('experiments', self.exp_name + '.json')) self.gpu = self.hyper.gpu self.preprocessor = None self.triplet_metrics = F1_triplet() self.ner_metrics = F1_ner() self.optimizer = None self.model = None def _optimizer(self, name, model): m = { 'adam': Adam(model.parameters()), 'sgd': SGD(model.parameters(), lr=0.5), 'adamw': AdamW(model.parameters()) } return m[name] def _init_model(self): self.model = MultiHeadSelection(self.hyper).to(self.device) def preprocessing(self): if self.exp_name == 'conll_selection_re': self.preprocessor = Conll_selection_preprocessing(self.hyper) elif self.exp_name == 'chinese_selection_re': self.preprocessor = Chinese_selection_preprocessing(self.hyper) elif self.exp_name == 'conll_bert_re': self.preprocessor = Conll_bert_preprocessing(self.hyper) elif self.exp_name == 'datafountain_selection_re': self.preprocessor = Datafountain_selection_preprocessing( self.hyper) self.preprocessor.gen_relation_vocab() self.preprocessor.gen_all_data() self.preprocessor.gen_vocab(min_freq=1) # for ner only self.preprocessor.gen_bio_vocab() def run(self, mode: str): if mode == 'preprocessing': self.preprocessing() elif mode == 'train': self._init_model() self.optimizer = self._optimizer(self.hyper.optimizer, self.model) self.train() elif mode == 'evaluation': self._init_model() self.load_model(epoch=self.hyper.evaluation_epoch) self.evaluation() else: raise ValueError('invalid mode') def load_model(self, epoch: int): self.model.load_state_dict( torch.load( os.path.join(self.model_dir, self.exp_name + '_' + str(epoch)))) def save_model(self, epoch: int): if not os.path.exists(self.model_dir): os.mkdir(self.model_dir) torch.save( self.model.state_dict(), os.path.join(self.model_dir, self.exp_name + '_' + str(epoch))) def evaluation(self): dev_set = Selection_Dataset(self.hyper, self.hyper.dev) loader = Selection_loader(dev_set, batch_size=self.hyper.eval_batch, pin_memory=True) self.triplet_metrics.reset() self.model.eval() pbar = tqdm(enumerate(BackgroundGenerator(loader)), total=len(loader)) with torch.no_grad(): with open('./output/sub00.csv', 'w') as file: id = 0 for batch_ndx, sample in pbar: tokens = sample.tokens_id.to(self.device) selection_gold = sample.selection_id.to(self.device) bio_gold = sample.bio_id.to(self.device) text_list = sample.text spo_gold = sample.spo_gold bio_text = sample.bio output = self.model(sample, is_train=False) self.triplet_metrics(output['selection_triplets'], output['spo_gold']) self.ner_metrics(output['gold_tags'], output['decoded_tag']) for i in range(len(output['decoded_tag'])): file.write(str(8001 + id) + ',') if len(output['selection_triplets'][i]) != 0: file.write(output['selection_triplets'][i][0] ['predicate'] + ',') file.write( output['selection_triplets'][i][0]['subject'] + ',') file.write( output['selection_triplets'][i][0]['object'] + '\n') else: if output['decoded_tag'][i].count('B') < 2: file.write('Other' + ',' + 'Other' + ',' + 'Other') else: BIO = output['decoded_tag'][i] tt = ''.join(reversed(BIO)) index1 = BIO.index('B') index2 = len(tt) - tt.index('B') - 1 file.write('Other' + ',' + text_list[i][index2] + ',' + text_list[i][index1]) file.write('\n') id += 1 # file.write('sentence {} BIO:\n'.format(i)) # for j in range(len(text_list[i])): # file.write(text_list[i][j]+' ') # file.write('\n') # file.writelines(bio_text[i]) # file.write('\n') # # file.writelines(output['decoded_tag'][i]) # file.write('\n') # file.writelines(output['gold_tags'][i]) # file.write('\n') # file.write('sentence {} relation:\n'.format(i)) # file.write('\n') # if len(output['selection_triplets']) == 0: # file.write('empty') # else: # file.writelines(str(output['selection_triplets'][i])) # file.write('\n') # file.writelines(str(output['spo_gold'][i])) # file.write('\n') triplet_result = self.triplet_metrics.get_metric() ner_result = self.ner_metrics.get_metric() # print('triplet_result=', triplet_result) # print('ner_result=', ner_result) print('Triplets-> ' + ', '.join([ "%s: %.4f" % (name[0], value) for name, value in triplet_result.items() if not name.startswith("_") ]) + ' ||' + 'NER->' + ', '.join([ "%s: %.4f" % (name[0], value) for name, value in ner_result.items() if not name.startswith("_") ])) def train(self): #** self.load_model(epoch=self.hyper.epoch_num) # ** train_set = Selection_Dataset(self.hyper, self.hyper.train) loader = Selection_loader(train_set, batch_size=self.hyper.train_batch, pin_memory=True) for epoch in range(self.hyper.epoch_num): self.model.train() pbar = tqdm(enumerate(BackgroundGenerator(loader)), total=len(loader)) for batch_idx, sample in pbar: # txt = sample.text # for j in range(len(txt)): # print(txt[j]) self.optimizer.zero_grad() output = self.model(sample, is_train=True) loss = output['loss'] loss.backward() self.optimizer.step() pbar.set_description(output['description']( epoch, self.hyper.epoch_num)) ## self.hyper.epoch_num self.save_model(self.hyper.epoch_num) if epoch % self.hyper.print_epoch == 0 and epoch > 3: self.evaluation()