skillrecommender / Main.py
ashuonnet's picture
Update Main.py
43b5bd6
Raw History Blame Contribute Delete
3.66 kB
import json
import re
import logging
import numpy as np
import torch
from transformers import BertTokenizerFast, BertForTokenClassification
class Main:
def __init__(self):
self.MAX_LEN = 500
#self.EPOCHS = 6
#self.NUM_LABELS = 12
self.DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
MODEL_PATH = './models/bert-base-uncased'
self.STATE_DICT = torch.load('./models/model_e6.tar', map_location=self.DEVICE)
#tokenizer = BertTokenizerFast('../input/bert-base-uncased/vocab.txt', lowercase=True)
self.tokenizer = BertTokenizerFast('./models/bert-base-uncased/vocab.txt',lowercase=True)
self.model = BertForTokenClassification.from_pretrained(MODEL_PATH,state_dict=self.STATE_DICT['model_state_dict'], num_labels=12)
self.model.to(self.DEVICE);
self.tags_vals = ["UNKNOWN", "O", "Name", "Degree","Skills","College Name","Email Address","Designation","Companies worked at","Graduation Year","Years of Experience","Location"]
#self.tag2idx = {t: i for i, t in enumerate(tags_vals)}
self.idx2tag = {i:t for i, t in enumerate(self.tags_vals)}
#self.data = self.trim_entity_spans(self.convert_dataturks_to_spacy('./data/annotated_resumes.json'))
#self.model = MODEL
def process_resume(self,text):
max_len = self.MAX_LEN
tok = self.tokenizer.encode_plus(text, max_length=max_len, return_offsets_mapping=True)
curr_sent = dict()
padding_length = max_len - len(tok['input_ids'])
curr_sent['input_ids'] = tok['input_ids'] + ([0] * padding_length)
curr_sent['token_type_ids'] = tok['token_type_ids'] + ([0] * padding_length)
curr_sent['attention_mask'] = tok['attention_mask'] + ([0] * padding_length)
final_data = {
'input_ids': torch.tensor(curr_sent['input_ids'], dtype=torch.long),
'token_type_ids': torch.tensor(curr_sent['token_type_ids'], dtype=torch.long),
'attention_mask': torch.tensor(curr_sent['attention_mask'], dtype=torch.long),
'offset_mapping': tok['offset_mapping']
}
return final_data
def predict(self,test_resume):
return self._predict(self.model,test_resume)
def _predict(self,model,test_resume):
model.eval()
data = self.process_resume(test_resume)
input_ids, input_mask = data['input_ids'].unsqueeze(0), data['attention_mask'].unsqueeze(0)
labels = torch.tensor([1] * input_ids.size(0), dtype=torch.long).unsqueeze(0)
with torch.no_grad():
outputs = model(
input_ids,
token_type_ids=None,
attention_mask=input_mask,
labels=labels,
)
tmp_eval_loss, logits = outputs[:2]
logits = logits.cpu().detach().numpy()
label_ids = np.argmax(logits, axis=2)
entities = []
for label_id, offset in zip(label_ids[0], data['offset_mapping']):
curr_id = self.idx2tag[label_id]
curr_start = offset[0]
curr_end = offset[1]
if curr_id != 'O':
if len(entities) > 0 and entities[-1]['entity'] == curr_id and curr_start - entities[-1]['end'] in [0, 1]:
entities[-1]['end'] = curr_end
else:
entities.append({'entity': curr_id, 'start': curr_start, 'end':curr_end})
for ent in entities:
ent['text'] = test_resume[ent['start']:ent['end']]
return entities