HighFive-OPJ/Deep_Learning
036
1import pandas as pd
2import numpy as np
3import torch
4import torch.nn as nn
5from torch.utils.data import DataLoader, Dataset
6from gensim.models.fasttext import load_facebook_vectors
7from sklearn.metrics import classification_report
8from collections import defaultdict
9
10train_df = pd.read_csv("Train-1.tsv", sep="\t")
11test_df = pd.read_csv("Test-1.tsv", sep="\t")
12
13train_sentences, train_labels = train_df['Sentence'].values, train_df['Label'].values
14test_sentences, test_labels = test_df['Sentence'].values, test_df['Label'].values
15
16def tokenize(text):
17 return text.lower().split()
18
19word_to_idx = {}
20idx = 2
21word_to_idx['<PAD>'] = 0
22word_to_idx['<UNK>'] = 1
23
24def build_vocab(sentences):
25 global idx
26 for sentence in sentences:
27 for word in tokenize(sentence):
28 if word not in word_to_idx:
29 word_to_idx[word] = idx
30 idx += 1
31
32build_vocab(train_sentences)
33
34fasttext_model = load_facebook_vectors("FastText.bin")
35
36embedding_dim = 300
37embedding_matrix = np.zeros((len(word_to_idx), embedding_dim))
38
39for word, i in word_to_idx.items():
40 if word in fasttext_model:
41 embedding_matrix[i] = fasttext_model[word]
42 else:
43 embedding_matrix[i] = np.random.normal(scale=0.6, size=(embedding_dim,))
44
45def encode_sentence(sentence, max_len=100):
46 tokens = tokenize(sentence)
47 ids = [word_to_idx.get(w, word_to_idx['<UNK>']) for w in tokens[:max_len]]
48 if len(ids) < max_len:
49 ids += [word_to_idx['<PAD>']] * (max_len - len(ids))
50 return ids
51
52class ReviewDataset(Dataset):
53 def __init__(self, sentences, labels):
54 self.sentences = [encode_sentence(s) for s in sentences]
55 self.labels = torch.tensor(labels, dtype=torch.long)
56
57 def __len__(self):
58 return len(self.labels)
59
60 def __getitem__(self, idx):
61 return torch.tensor(self.sentences[idx]), self.labels[idx]
62
63train_dataset = ReviewDataset(train_sentences, train_labels)
64test_dataset = ReviewDataset(test_sentences, test_labels)
65
66train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
67test_loader = DataLoader(test_dataset, batch_size=32)
68
69class SentimentLSTM(nn.Module):
70 def __init__(self, embedding_matrix, hidden_dim=128, output_dim=3):
71 super().__init__()
72 vocab_size, embedding_dim = embedding_matrix.shape
73 self.embedding = nn.Embedding.from_pretrained(torch.FloatTensor(embedding_matrix), freeze=False)
74 self.lstm = nn.LSTM(embedding_dim, hidden_dim, batch_first=True)
75 self.dropout = nn.Dropout(0.5)
76 self.fc = nn.Linear(hidden_dim, output_dim)
77
78 def forward(self, x):
79 x = self.embedding(x)
80 _, (hidden, _) = self.lstm(x)
81 out = self.dropout(hidden[-1])
82 return self.fc(out)
83
84class SentimentGRU(nn.Module):
85 def __init__(self, embedding_matrix, hidden_dim=128, output_dim=3):
86 super().__init__()
87 vocab_size, embedding_dim = embedding_matrix.shape
88 self.embedding = nn.Embedding.from_pretrained(torch.FloatTensor(embedding_matrix), freeze=False)
89 self.gru = nn.GRU(embedding_dim, hidden_dim, batch_first=True)
90 self.dropout = nn.Dropout(0.5)
91 self.fc = nn.Linear(hidden_dim, output_dim)
92
93 def forward(self, x):
94 x = self.embedding(x)
95 _, hidden = self.gru(x)
96 out = self.dropout(hidden[-1])
97 return self.fc(out)
98
99class SentimentCNN(nn.Module):
100 def __init__(self, embedding_matrix, output_dim=3, filter_sizes=[3, 4, 5], num_filters=100):
101 super().__init__()
102 vocab_size, embedding_dim = embedding_matrix.shape
103 self.embedding = nn.Embedding.from_pretrained(torch.FloatTensor(embedding_matrix), freeze=False)
104
105 self.convs = nn.ModuleList([
106 nn.Conv2d(1, num_filters, (fs, embedding_dim)) for fs in filter_sizes
107 ])
108
109 self.fc = nn.Linear(num_filters * len(filter_sizes), output_dim)
110 self.dropout = nn.Dropout(0.5)
111
112 def forward(self, x):
113 x = self.embedding(x).unsqueeze(1) # Add channel dimension
114 x = [torch.relu(conv(x)).squeeze(3) for conv in self.convs]
115 x = [torch.max(i, dim=2)[0] for i in x]
116 x = torch.cat(x, dim=1)
117 x = self.dropout(x)
118 return self.fc(x)
119
120device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
121
122def train_model(model, train_loader, epochs=5, lr=1e-3):
123 model.to(device)
124 loss_fn = nn.CrossEntropyLoss()
125 optimizer = torch.optim.Adam(model.parameters(), lr=lr)
126
127 for epoch in range(epochs):
128 model.train()
129 total_loss = 0
130 for x_batch, y_batch in train_loader:
131 x_batch, y_batch = x_batch.to(device), y_batch.to(device)
132 optimizer.zero_grad()
133 preds = model(x_batch)
134 loss = loss_fn(preds, y_batch)
135 loss.backward()
136 optimizer.step()
137 total_loss += loss.item()
138 print(f"Epoch {epoch+1}, Loss: {total_loss:.4f}")
139
140def evaluate_model(model, test_loader):
141 model.eval()
142 all_preds = []
143 all_labels = []
144 with torch.no_grad():
145 for x_batch, y_batch in test_loader:
146 x_batch = x_batch.to(device)
147 preds = model(x_batch)
148 pred_labels = torch.argmax(preds, dim=1).cpu().numpy()
149 all_preds.extend(pred_labels)
150 all_labels.extend(y_batch.numpy())
151
152 print(classification_report(all_labels, all_preds))
153
154print("\nTraining LSTM model...")
155lstm_model = SentimentLSTM(embedding_matrix)
156train_model(lstm_model, train_loader)
157evaluate_model(lstm_model, test_loader)
158
159print("\nTraining GRU model...")
160gru_model = SentimentGRU(embedding_matrix)
161train_model(gru_model, train_loader)
162evaluate_model(gru_model, test_loader)
163
164print("\nTraining CNN model...")
165cnn_model = SentimentCNN(embedding_matrix)
166train_model(cnn_model, train_loader)
167evaluate_model(cnn_model, test_loader)
168 