|
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() |
|
|
|
|
|
def forward(self, input_ids=None, mask=None, attn=None, labels=None, targets=None): |
|
outputs = self.bert(input_ids, mask) |
|
|
|
out=outputs[0] |
|
logits = self.token_classifier(self.token_dropout(out)) |
|
|
|
|
|
|
|
|
|
|
|
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() |
|
|
|
|
|
|
|
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 |
|
|