MMSRL

Our Multimodal Semantic Role Labeling model for CONSTRAINT 2022
git clone https://esimon.eu/repos/MMSRL.git
Log | Files | Refs | Submodules | README

baseline.py (2604B)


      1 import torch
      2 import transformers
      3 
      4 import mmsrl.loss
      5 
      6 
      7 class Model(torch.nn.Module):
      8     def __init__(self, config, label_weights):
      9         super().__init__()
     10         self.config = config
     11         self.transformer = transformers.AutoModel.from_pretrained(self.config.modelname)
     12         # TODO tune the smaller output size for the linears to compute attention?
     13         self.text_linear= torch.nn.Linear(self.transformer.config.hidden_size, self.config.hidden_size)
     14         self.entities_linear= torch.nn.Linear(self.transformer.config.hidden_size, self.config.hidden_size)
     15         self.classifier = torch.nn.Linear(self.transformer.config.hidden_size, 4) # output * number of classes
     16         #self.relu = torch.nn.ReLU()
     17         self.loss = mmsrl.loss.Loss(self.config, label_weights)
     18 
     19     def forward(self, input_ids, attention_mask, entities_mask, entities_input_ids, entities_attention_mask, labels=None, **kwargs):
     20         # entities are tri-dimensionnal (batch * nb of entities * emb dim) while text is bi-dimensional
     21         nb_entities = entities_input_ids.shape[1]
     22         batch_size = entities_input_ids.shape[0]
     23         fake_batch_size = batch_size*nb_entities
     24 
     25         text_output = self.transformer(input_ids, attention_mask)
     26 
     27         text = self.text_linear(text_output.last_hidden_state)
     28         entities = self.entities_linear(self.transformer(entities_input_ids.view(fake_batch_size, -1), entities_attention_mask.view(fake_batch_size, -1)).pooler_output).view(batch_size, nb_entities, -1)
     29         attention = torch.einsum("blf,bef->bel", text, entities)
     30 
     31         # attention = dot product on each element of the batch, on the entities
     32         attention_entities_mask = entities_mask.unsqueeze(2) & attention_mask.unsqueeze(1) # make the softmax only on entities and words --> be->be1 & bl->b1l --> bel
     33 
     34         attention_max = torch.max(attention,dim=2,keepdim=True)[0] # max along sentence length
     35         attention_exp = torch.exp(attention-attention_max)
     36         attention_exp = attention_exp * attention_entities_mask.float()
     37         attention_softmax = attention_exp /( torch.sum(attention_exp,dim=2,keepdim=True) + (1-attention_entities_mask.float()) )
     38 
     39         # use this as query for image transformer output
     40         entity_attention_output = torch.sum(attention_softmax.unsqueeze(3) * text_output.last_hidden_state.unsqueeze(1), dim=2) # sum along sentence length: torch.Size([8, 10, 64, 1]) + torch.Size([8, 1, 64, 768] --> torch.Size([8, 10, 768])
     41 
     42         logits = self.classifier(entity_attention_output) # batch * entity * nb_labels (4)
     43         return self.loss(logits, labels)