import torch from transformers import AutoModelForTokenClassification, AutoModelForSequenceClassification, AdamW, get_linear_schedule_with_warmup, AutoModel from transformers import BertForTokenClassification, BertForSequenceClassification,BertPreTrainedModel, BertModel import torch.nn as nn from .utils import * import torch.nn.functional as F from ekphrasis.classes.preprocessor import TextPreProcessor from ekphrasis.classes.tokenizer import SocialTokenizer from ekphrasis.dicts.emoticons import emoticons import re from transformers import AutoTokenizer, AutoModelForTokenClassification, AdamW, get_linear_schedule_with_warmup from torch.utils.data import TensorDataset, DataLoader, RandomSampler, SequentialSampler class Model_Rational_Label(BertPreTrainedModel): def __init__(self,config,params): super().__init__(config) self.num_labels=params['num_classes'] self.num_targets=params['targets_num'] self.impact_factor=params['rationale_impact'] self.target_factor=params['target_impact'] self.bert = BertModel(config,add_pooling_layer=False) self.pooler=BertPooler(config) self.token_dropout = nn.Dropout(0.2) self.token_classifier = nn.Linear(config.hidden_size, 2) self.dropout = nn.Dropout(0.2) self.classifier = nn.Linear(config.hidden_size, self.num_labels) self.target_dropout = nn.Dropout(0.2) self.target_classifier = nn.Linear(config.hidden_size, self.num_targets) self.init_weights() # self.embeddings = AutoModelForTokenClassification.from_pretrained(params['model_path'], cache_dir=params['cache_path']) def forward(self, input_ids=None, mask=None, attn=None, labels=None, targets=None): outputs = self.bert(input_ids, mask) # out = outputs.last_hidden_state out=outputs[0] logits = self.token_classifier(self.token_dropout(out)) # mean_pooling = torch.mean(out, 1) # max_pooling, _ = torch.max(out, 1) # embed = torch.cat((mean_pooling, max_pooling), 1) embed=self.pooler(outputs[0]) y_pred = self.classifier(self.dropout(embed)) y_pred_target = torch.sigmoid(self.target_classifier(self.target_dropout(embed))) loss_token = None loss_target= None loss_label = None loss_total = None if attn is not None: loss_fct = nn.CrossEntropyLoss() ### Adding weighted # Only keep active parts of the loss if mask is not None: class_weights=torch.tensor([1.0,1.0],dtype=torch.float).to(input_ids.device) loss_funct = nn.CrossEntropyLoss(class_weights) active_loss = mask.view(-1) == 1 active_logits = logits.view(-1, 2) active_labels = torch.where( active_loss, attn.view(-1), torch.tensor(loss_fct.ignore_index).type_as(attn) ) loss_token = loss_funct(active_logits, active_labels) else: loss_token = loss_funct(logits.view(-1, 2), attn.view(-1)) loss_total=self.impact_factor*loss_token if targets is not None: loss_funct = nn.BCELoss() loss_logits = loss_funct(y_pred_target.view(-1, self.num_targets), targets.view(-1, self.num_targets)) loss_targets= loss_logits loss_total+=self.target_factor*loss_targets if labels is not None: loss_funct = nn.CrossEntropyLoss() loss_logits = loss_funct(y_pred.view(-1, self.num_labels), labels.view(-1)) loss_label= loss_logits if(loss_total is not None): loss_total+=loss_label else: loss_total=loss_label if(loss_total is not None): return y_pred,y_pred_target,logits, loss_total else: return y_pred,y_pred_target,logits