| import torch |
| import torch.nn as nn |
| from transformers import AutoModel |
| import os |
|
|
| from config import * |
|
|
| |
|
|
| class XLMRBiGRU(nn.Module): |
| def __init__(self, xlmr_model_name, gru_hidden_size, gru_num_layers, dropout, freeze_xlmr_layers): |
| super().__init__() |
| self.xlmr = AutoModel.from_pretrained(xlmr_model_name) |
| |
| |
| for param in self.xlmr.embeddings.parameters(): |
| param.requires_grad = False |
|
|
| |
| for num_layer in range(freeze_xlmr_layers): |
| for param in self.xlmr.encoder.layer[num_layer].parameters(): |
| param.requires_grad = False |
| |
| self.gru = nn.GRU( |
| input_size=self.xlmr.config.hidden_size, |
| hidden_size=gru_hidden_size, |
| num_layers=gru_num_layers, |
| batch_first=True, |
| bidirectional=True, |
| dropout=dropout if gru_num_layers > 1 else 0 |
| ) |
|
|
| self.attention = nn.Linear(gru_hidden_size * 2, 1) |
|
|
| self.classifier = nn.Linear(gru_hidden_size * 2, 1) |
|
|
| self.dropout = nn.Dropout(dropout) |
|
|
|
|
| def forward(self, input_ids, attention_mask, conv_length): |
| batch_size, max_conv_len, max_msg_len = input_ids.size() |
|
|
| |
| input_ids = input_ids.view(-1, max_msg_len) |
| attention_mask = attention_mask.view(-1, max_msg_len) |
|
|
| |
| outputs = self.xlmr(input_ids=input_ids, attention_mask=attention_mask) |
| cls_embeddings = outputs.last_hidden_state[:, 0, :] |
|
|
| |
| cls_embeddings = cls_embeddings.view(batch_size, max_conv_len, -1) |
|
|
| |
| gru_output, _ = self.gru(cls_embeddings) |
|
|
| |
| attn_scores = self.attention(gru_output).squeeze(-1) |
| |
| |
| mask = torch.arange(max_conv_len).unsqueeze(0).to(conv_length.device) < conv_length.unsqueeze(1) |
| attn_scores[~mask] = float('-inf') |
|
|
| attn_weights = torch.softmax(attn_scores, dim=1).unsqueeze(-1) |
| context_vector = torch.sum(attn_weights * gru_output, dim=1) |
|
|
| context_vector = self.dropout(context_vector) |
| |
| logits = self.classifier(context_vector).squeeze(-1) |
| |
| return logits |
| |
|
|
|
|
| if __name__ == "__main__": |
|
|
| device = torch.device("cuda" if torch.cuda.is_available() else "cpu") |
| print(f"Using device: {device}") |
|
|
| model = XLMRBiGRU( |
| xlmr_model_name=XLMR_MODEL_NAME, |
| gru_hidden_size=GRU_HIDDEN_SIZE, |
| gru_num_layers=GRU_NUM_LAYERS, |
| dropout=DROPOUT, |
| freeze_xlmr_layers=FREEZE_XLMR_LAYERS |
| ) |
| |
| |
| input_ids = torch.randint(0, 100, (2, 50, 64)) |
| attention_mask = torch.ones(2, 50, 64, dtype=torch.long) |
| conv_lengths = torch.tensor([50, 30]) |
| |
| output = model(input_ids, attention_mask, conv_lengths) |
| print(output.shape) |
|
|
|
|
|
|