177vasanth's picture
Upload folder using huggingface_hub
3c9d491 verified
Raw
History Blame Contribute Delete
2.18 kB
from collections import Counter
import torch
import torch.nn as nn
class Vocabulary:
def __init__(self, min_freq=1):
self.min_freq = min_freq
self.token2id = {'<PAD>': 0, '<UNK>': 1}
self.id2token = {0: '<PAD>', 1: '<UNK>'}
def build(self, texts):
counter = Counter(tok for text in texts for tok in text.split())
for token, freq in counter.items():
if freq >= self.min_freq and token not in self.token2id:
idx = len(self.token2id)
self.token2id[token] = idx
self.id2token[idx] = token
return self
def encode(self, text, max_len=None):
ids = [self.token2id.get(t, 1) for t in text.split()]
if max_len:
ids = ids[:max_len]
return ids if ids else [1]
def __len__(self):
return len(self.token2id)
class AttentionPooling(nn.Module):
def __init__(self, hidden_dim):
super().__init__()
self.attn = nn.Linear(hidden_dim, 1)
def forward(self, h, mask=None):
scores = self.attn(h).squeeze(-1)
if mask is not None:
scores = scores.masked_fill(mask == 0, float('-inf'))
weights = torch.softmax(scores, dim=-1)
return (h * weights.unsqueeze(-1)).sum(dim=1)
class BiLSTMClassifier(nn.Module):
def __init__(self, vocab_size, embed_dim, hidden_dim, num_layers, num_classes, dropout=0.3):
super().__init__()
self.embedding = nn.Embedding(vocab_size, embed_dim, padding_idx=0)
self.lstm = nn.LSTM(
embed_dim, hidden_dim,
num_layers=num_layers,
batch_first=True,
bidirectional=True,
dropout=dropout if num_layers > 1 else 0.0,
)
self.attention = AttentionPooling(hidden_dim * 2)
self.classifier = nn.Sequential(
nn.Dropout(dropout),
nn.Linear(hidden_dim * 2, num_classes),
)
def forward(self, input_ids, attention_mask=None):
x = self.embedding(input_ids)
output, _ = self.lstm(x)
pooled = self.attention(output, attention_mask)
return self.classifier(pooled)