balamaniansp commited on
Commit
87546cb
·
verified ·
1 Parent(s): 13e908a

custom bidirectional gru mode

Browse files
Files changed (1) hide show
  1. model.py +73 -0
model.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ import torch.nn.functional as F
4
+ from huggingface_hub import PyTorchModelHubMixin
5
+
6
+ class CustomBiGRUMCQModel(nn.Module, PyTorchModelHubMixin):
7
+ """
8
+ Bidirectional GRU model with custom global attention pooling
9
+ """
10
+ #vocab_size, embedding_dim=256, hidden_dim=256, num_layers=2, dropout=0.1
11
+ def __init__(self, config:dict):
12
+ super().__init__()
13
+ self.config = config
14
+ self.vocab_size = config.get('vocab_size', 30000)
15
+ self.embedding_dim = config.get('embedding_dim',256)
16
+ self.hidden_dim = config.get('hidden_dim',256)
17
+ self.num_layers = config.get('num_layers',2)
18
+
19
+ self.embedding = nn.Embedding(self.vocab_size, self.embedding_dim, padding_idx=0)
20
+ self.embedding_dropout = nn.Dropout(config.get('dropout', 0.1))
21
+
22
+ self.gru = nn.GRU(
23
+ input_size = self.embedding_dim,
24
+ hidden_size = self.hidden_dim,
25
+ num_layers = self.num_layers,
26
+ bidirectional=True,
27
+ batch_first=True,
28
+ dropout = config.get('dropout',0.1) if self.num_layers > 1 else 0
29
+ )
30
+
31
+ # Dot product attention pooling head
32
+ self.attention_query = nn.Linear(self.hidden_dim * 2, 1, bias=False)
33
+
34
+ #Final classification layer
35
+ self.classifier = nn.Linear(self.hidden_dim*2, 1)
36
+ self.dropout = nn.Dropout(config.get('dropout',0.1))
37
+
38
+ def forward(self, input_ids, attention_mask=None, label=None, **kwargs):
39
+ input_idx = input_ids
40
+ #expected shape [batch_size, num_of_choice=5, seq_length]
41
+ batch_size, num_of_choices, seq_length = input_idx.shape
42
+
43
+ flat_input_idx = input_ids.view(batch_size * num_of_choices, seq_length)
44
+
45
+ embedded = self.embedding(flat_input_idx)
46
+ embedded = self.embedding_dropout(embedded)
47
+
48
+ gru_out, _ = self.gru(embedded) # Shape: [batch_size * 5, seq_length, hidden_dim * 2]
49
+
50
+ attentions_scores = self.attention_query(gru_out).squeeze(-1)
51
+
52
+ # Adapt Attentions mask to the choice dimension
53
+ flaten_mask = None
54
+ if attention_mask is not None:
55
+ flat_mask = attention_mask.view(batch_size * num_of_choices, seq_length)
56
+ attentions_scores = attentions_scores.masked_fill(flat_mask == 0, -1e9)
57
+
58
+ attention_weight = F.softmax(attentions_scores, dim=-1).unsqueeze(-1)
59
+ pooled_output = torch.sum(gru_out * attention_weight, dim=1)
60
+ pooled_output = self.dropout(pooled_output)
61
+
62
+ raw_scores = self.classifier(pooled_output).squeeze(-1) # Shape: [batch_size * 5]
63
+ reshape_logits = raw_scores.view(batch_size, num_of_choices) # Shape: [batch_size, 5]
64
+
65
+ loss = None
66
+ if label is not None:
67
+ loss_fct = nn.CrossEntropyLoss()
68
+ loss = loss_fct(reshape_logits, label)
69
+
70
+ return {
71
+ 'loss': loss,
72
+ 'logits': reshape_logits
73
+ }