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)