Upload 12 files
Browse files- Checkpoints_Q8/.ipynb_checkpoints/thota4-checkpoint.ipynb +502 -0
- Checkpoints_Q8/combined_model.pth +3 -0
- Checkpoints_Q8/combined_model_checkpoint_epoch1.pth +3 -0
- Checkpoints_Q8/combined_model_checkpoint_epoch10.pth +3 -0
- Checkpoints_Q8/combined_model_checkpoint_epoch2.pth +3 -0
- Checkpoints_Q8/combined_model_checkpoint_epoch3.pth +3 -0
- Checkpoints_Q8/combined_model_checkpoint_epoch4.pth +3 -0
- Checkpoints_Q8/combined_model_checkpoint_epoch5.pth +3 -0
- Checkpoints_Q8/combined_model_checkpoint_epoch6.pth +3 -0
- Checkpoints_Q8/combined_model_checkpoint_epoch7.pth +3 -0
- Checkpoints_Q8/combined_model_checkpoint_epoch8.pth +3 -0
- Checkpoints_Q8/combined_model_checkpoint_epoch9.pth +3 -0
Checkpoints_Q8/.ipynb_checkpoints/thota4-checkpoint.ipynb
ADDED
@@ -0,0 +1,502 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "markdown",
|
5 |
+
"source": [
|
6 |
+
" **Midterm: Neural Network-Based Language\n",
|
7 |
+
"Model for Next Token Prediction**\n"
|
8 |
+
],
|
9 |
+
"metadata": {
|
10 |
+
"id": "hOqh8ZFysD6G"
|
11 |
+
}
|
12 |
+
},
|
13 |
+
{
|
14 |
+
"cell_type": "code",
|
15 |
+
"source": [
|
16 |
+
"import torch\n",
|
17 |
+
"import torch.nn as nn\n",
|
18 |
+
"import torch.optim as optim\n",
|
19 |
+
"from torch.utils.data import Dataset, DataLoader\n",
|
20 |
+
"import numpy as np\n",
|
21 |
+
"import re\n",
|
22 |
+
"from collections import Counter\n",
|
23 |
+
"from sklearn.model_selection import train_test_split\n"
|
24 |
+
],
|
25 |
+
"metadata": {
|
26 |
+
"id": "14bhPtpVtqk5"
|
27 |
+
},
|
28 |
+
"execution_count": 16,
|
29 |
+
"outputs": []
|
30 |
+
},
|
31 |
+
{
|
32 |
+
"cell_type": "code",
|
33 |
+
"source": [
|
34 |
+
"# Load Icelandic and English text files\n",
|
35 |
+
"with open('/content/Icelandic_sampled.txt', 'r', encoding='utf-8') as f:\n",
|
36 |
+
" icelandic_text = f.read()\n",
|
37 |
+
"\n",
|
38 |
+
"with open('/content/alpaca_sampled.txt', 'r', encoding='utf-8') as f:\n",
|
39 |
+
" english_text = f.read()\n",
|
40 |
+
"\n",
|
41 |
+
"print(\"Datasets loaded successfully.\")\n",
|
42 |
+
"\n",
|
43 |
+
"# Preprocessing function to clean text\n",
|
44 |
+
"def preprocess_text(text):\n",
|
45 |
+
" text = text.lower()\n",
|
46 |
+
" text = re.sub(r'[^a-zA-ZÍÚÁÉÓÖÞÆÉíúáéóöþæ ]', '', text) # Retain Icelandic letters\n",
|
47 |
+
" return text\n",
|
48 |
+
"\n",
|
49 |
+
"# Apply preprocessing to both datasets\n",
|
50 |
+
"english_text = preprocess_text(english_text)\n",
|
51 |
+
"icelandic_text = preprocess_text(icelandic_text)\n",
|
52 |
+
"\n",
|
53 |
+
"print(f\"Sample of English Text: {english_text[:100]}\")\n",
|
54 |
+
"print(f\"Sample of Icelandic Text: {icelandic_text[:100]}\")\n",
|
55 |
+
"\n"
|
56 |
+
],
|
57 |
+
"metadata": {
|
58 |
+
"colab": {
|
59 |
+
"base_uri": "https://localhost:8080/"
|
60 |
+
},
|
61 |
+
"id": "43x2PjLihFr2",
|
62 |
+
"outputId": "286106bb-9e22-4afc-dba8-c44fa351d36c"
|
63 |
+
},
|
64 |
+
"execution_count": 2,
|
65 |
+
"outputs": [
|
66 |
+
{
|
67 |
+
"output_type": "stream",
|
68 |
+
"name": "stdout",
|
69 |
+
"text": [
|
70 |
+
"Datasets loaded successfully.\n",
|
71 |
+
"Sample of English Text: instruction explain newtons third law of motion input output newtons third law of motion states tha\n",
|
72 |
+
"Sample of Icelandic Text: instruction kindly translate the given sentence into icelandic input write a comment praising the gi\n"
|
73 |
+
]
|
74 |
+
}
|
75 |
+
]
|
76 |
+
},
|
77 |
+
{
|
78 |
+
"cell_type": "code",
|
79 |
+
"source": [
|
80 |
+
"# Tokenization function\n",
|
81 |
+
"def tokenize(text):\n",
|
82 |
+
" return text.split()\n",
|
83 |
+
"\n",
|
84 |
+
"english_tokens = tokenize(english_text)\n",
|
85 |
+
"icelandic_tokens = tokenize(icelandic_text)\n",
|
86 |
+
"\n",
|
87 |
+
"print(f\"English tokens: {len(english_tokens)}\")\n",
|
88 |
+
"print(f\"Icelandic tokens: {len(icelandic_tokens)}\")\n",
|
89 |
+
"\n",
|
90 |
+
"# Build vocabulary\n",
|
91 |
+
"def build_vocab(tokens):\n",
|
92 |
+
" vocab = Counter(tokens)\n",
|
93 |
+
" vocab = {word: i for i, (word, _) in enumerate(vocab.items())}\n",
|
94 |
+
" return vocab\n",
|
95 |
+
"\n",
|
96 |
+
"# Create vocabularies for both languages\n",
|
97 |
+
"english_vocab = build_vocab(english_tokens)\n",
|
98 |
+
"icelandic_vocab = build_vocab(icelandic_tokens)\n",
|
99 |
+
"\n",
|
100 |
+
"print(f\"English Vocabulary Size: {len(english_vocab)}\")\n",
|
101 |
+
"print(f\"Icelandic Vocabulary Size: {len(icelandic_vocab)}\")\n",
|
102 |
+
"\n",
|
103 |
+
"# Convert tokens to indices\n",
|
104 |
+
"english_data = [english_vocab[word] for word in english_tokens]\n",
|
105 |
+
"icelandic_data = [icelandic_vocab[word] for word in icelandic_tokens]\n",
|
106 |
+
"\n",
|
107 |
+
"# Combine datasets\n",
|
108 |
+
"combined_data = english_data + icelandic_data\n",
|
109 |
+
"print(f\"Combined dataset size: {len(combined_data)}\")\n"
|
110 |
+
],
|
111 |
+
"metadata": {
|
112 |
+
"colab": {
|
113 |
+
"base_uri": "https://localhost:8080/"
|
114 |
+
},
|
115 |
+
"id": "3LnwrEBKhFuT",
|
116 |
+
"outputId": "7c931294-0b22-45b1-927f-4013a97a1b53"
|
117 |
+
},
|
118 |
+
"execution_count": 3,
|
119 |
+
"outputs": [
|
120 |
+
{
|
121 |
+
"output_type": "stream",
|
122 |
+
"name": "stdout",
|
123 |
+
"text": [
|
124 |
+
"English tokens: 32477\n",
|
125 |
+
"Icelandic tokens: 36422\n",
|
126 |
+
"English Vocabulary Size: 6221\n",
|
127 |
+
"Icelandic Vocabulary Size: 9601\n",
|
128 |
+
"Combined dataset size: 68899\n"
|
129 |
+
]
|
130 |
+
}
|
131 |
+
]
|
132 |
+
},
|
133 |
+
{
|
134 |
+
"cell_type": "code",
|
135 |
+
"source": [
|
136 |
+
"# Dataset class for sequence prediction\n",
|
137 |
+
"class TextDataset(Dataset):\n",
|
138 |
+
" def __init__(self, data, sequence_length):\n",
|
139 |
+
" self.data = data\n",
|
140 |
+
" self.sequence_length = sequence_length\n",
|
141 |
+
"\n",
|
142 |
+
" def __len__(self):\n",
|
143 |
+
" return len(self.data) - self.sequence_length\n",
|
144 |
+
"\n",
|
145 |
+
" def __getitem__(self, idx):\n",
|
146 |
+
" return (torch.tensor(self.data[idx:idx + self.sequence_length]),\n",
|
147 |
+
" torch.tensor(self.data[idx + self.sequence_length]))\n",
|
148 |
+
"\n",
|
149 |
+
"# Sequence length for training\n",
|
150 |
+
"sequence_length = 5\n",
|
151 |
+
"\n",
|
152 |
+
"# Create the combined dataset\n",
|
153 |
+
"combined_dataset = TextDataset(combined_data, sequence_length)\n",
|
154 |
+
"print(f\"Dataset length: {len(combined_dataset)}\")\n",
|
155 |
+
"\n",
|
156 |
+
"# Split into training and validation sets\n",
|
157 |
+
"train_data, val_data = train_test_split(combined_dataset, test_size=0.1)\n",
|
158 |
+
"print(f\"Training samples: {len(train_data)}, Validation samples: {len(val_data)}\")\n",
|
159 |
+
"\n",
|
160 |
+
"# Create DataLoaders for training and validation\n",
|
161 |
+
"batch_size = 64\n",
|
162 |
+
"train_loader = DataLoader(train_data, batch_size=batch_size, shuffle=True)\n",
|
163 |
+
"val_loader = DataLoader(val_data, batch_size=batch_size, shuffle=False)\n",
|
164 |
+
"\n",
|
165 |
+
"print(f\"Batch size: {batch_size}\")\n",
|
166 |
+
"print(f\"Training batches: {len(train_loader)}, Validation batches: {len(val_loader)}\")\n"
|
167 |
+
],
|
168 |
+
"metadata": {
|
169 |
+
"colab": {
|
170 |
+
"base_uri": "https://localhost:8080/"
|
171 |
+
},
|
172 |
+
"id": "6eyfZ2klhFw1",
|
173 |
+
"outputId": "058f0dba-c5d3-48b4-edd0-95c12a4521aa"
|
174 |
+
},
|
175 |
+
"execution_count": 4,
|
176 |
+
"outputs": [
|
177 |
+
{
|
178 |
+
"output_type": "stream",
|
179 |
+
"name": "stdout",
|
180 |
+
"text": [
|
181 |
+
"Dataset length: 68894\n",
|
182 |
+
"Training samples: 62004, Validation samples: 6890\n",
|
183 |
+
"Batch size: 64\n",
|
184 |
+
"Training batches: 969, Validation batches: 108\n"
|
185 |
+
]
|
186 |
+
}
|
187 |
+
]
|
188 |
+
},
|
189 |
+
{
|
190 |
+
"cell_type": "code",
|
191 |
+
"source": [
|
192 |
+
"# Loss function and optimizer\n",
|
193 |
+
"criterion = nn.CrossEntropyLoss()\n",
|
194 |
+
"optimizer = optim.Adam(combined_model.parameters(), lr=0.001)\n",
|
195 |
+
"\n",
|
196 |
+
"# Function to train the model and validate\n",
|
197 |
+
"def train_model(model, train_loader, val_loader, optimizer, num_epochs, checkpoint_path):\n",
|
198 |
+
" model.train()\n",
|
199 |
+
" train_losses, val_losses = [], []\n",
|
200 |
+
"\n",
|
201 |
+
" for epoch in range(num_epochs):\n",
|
202 |
+
" epoch_train_loss = 0\n",
|
203 |
+
" for inputs, targets in train_loader:\n",
|
204 |
+
" optimizer.zero_grad()\n",
|
205 |
+
" outputs = model(inputs)\n",
|
206 |
+
" loss = criterion(outputs, targets)\n",
|
207 |
+
" loss.backward()\n",
|
208 |
+
" optimizer.step()\n",
|
209 |
+
" epoch_train_loss += loss.item()\n",
|
210 |
+
"\n",
|
211 |
+
" # Validation step\n",
|
212 |
+
" model.eval()\n",
|
213 |
+
" val_loss = 0\n",
|
214 |
+
" with torch.no_grad():\n",
|
215 |
+
" for inputs, targets in val_loader:\n",
|
216 |
+
" outputs = model(inputs)\n",
|
217 |
+
" loss = criterion(outputs, targets)\n",
|
218 |
+
" val_loss += loss.item()\n",
|
219 |
+
"\n",
|
220 |
+
" train_losses.append(epoch_train_loss / len(train_loader))\n",
|
221 |
+
" val_losses.append(val_loss / len(val_loader))\n",
|
222 |
+
"\n",
|
223 |
+
" # Save checkpoint for every epoch\n",
|
224 |
+
" torch.save(model.state_dict(), f'{checkpoint_path}_epoch{epoch+1}.pth')\n",
|
225 |
+
"\n",
|
226 |
+
" print(f'Epoch {epoch+1}/{num_epochs}, Train Loss: {train_losses[-1]:.4f}, Val Loss: {val_losses[-1]:.4f}')\n",
|
227 |
+
"\n",
|
228 |
+
" return train_losses, val_losses\n",
|
229 |
+
"\n",
|
230 |
+
" import pandas as pd\n",
|
231 |
+
"import numpy as np\n",
|
232 |
+
"\n",
|
233 |
+
"# Train the model\n",
|
234 |
+
"num_epochs = 10\n",
|
235 |
+
"train_losses, val_losses = train_model(combined_model, train_loader, val_loader, optimizer, num_epochs, 'combined_model_checkpoint')\n",
|
236 |
+
"\n",
|
237 |
+
"# Save training and validation losses to a CSV file\n",
|
238 |
+
"losses_df = pd.DataFrame({\n",
|
239 |
+
" 'Epoch': range(1, num_epochs + 1),\n",
|
240 |
+
" 'Train_Loss': train_losses,\n",
|
241 |
+
" 'Val_Loss': val_losses\n",
|
242 |
+
"})\n",
|
243 |
+
"losses_df.to_csv('training_validation_losses.csv', index=False)\n"
|
244 |
+
],
|
245 |
+
"metadata": {
|
246 |
+
"colab": {
|
247 |
+
"base_uri": "https://localhost:8080/"
|
248 |
+
},
|
249 |
+
"id": "ESRw-m00hFz_",
|
250 |
+
"outputId": "9a489cb6-90b8-47c0-e647-799213667927"
|
251 |
+
},
|
252 |
+
"execution_count": 7,
|
253 |
+
"outputs": [
|
254 |
+
{
|
255 |
+
"output_type": "stream",
|
256 |
+
"name": "stdout",
|
257 |
+
"text": [
|
258 |
+
"Epoch 1/10, Train Loss: 7.6275, Val Loss: 7.1583\n",
|
259 |
+
"Epoch 2/10, Train Loss: 6.6923, Val Loss: 6.9158\n",
|
260 |
+
"Epoch 3/10, Train Loss: 5.9922, Val Loss: 6.8872\n",
|
261 |
+
"Epoch 4/10, Train Loss: 5.1496, Val Loss: 7.0510\n",
|
262 |
+
"Epoch 5/10, Train Loss: 4.2123, Val Loss: 7.2246\n",
|
263 |
+
"Epoch 6/10, Train Loss: 3.2722, Val Loss: 7.5333\n",
|
264 |
+
"Epoch 7/10, Train Loss: 2.4096, Val Loss: 7.8671\n",
|
265 |
+
"Epoch 8/10, Train Loss: 1.6956, Val Loss: 8.1713\n",
|
266 |
+
"Epoch 9/10, Train Loss: 1.1467, Val Loss: 8.4934\n",
|
267 |
+
"Epoch 10/10, Train Loss: 0.7460, Val Loss: 8.7863\n"
|
268 |
+
]
|
269 |
+
}
|
270 |
+
]
|
271 |
+
},
|
272 |
+
{
|
273 |
+
"cell_type": "code",
|
274 |
+
"source": [
|
275 |
+
"# Save the final model\n",
|
276 |
+
"torch.save(combined_model.state_dict(), 'combined_model.pth')"
|
277 |
+
],
|
278 |
+
"metadata": {
|
279 |
+
"id": "lg4Fzwker0IQ"
|
280 |
+
},
|
281 |
+
"execution_count": 15,
|
282 |
+
"outputs": []
|
283 |
+
},
|
284 |
+
{
|
285 |
+
"cell_type": "code",
|
286 |
+
"source": [
|
287 |
+
"\n",
|
288 |
+
"# Plot losses\n",
|
289 |
+
"import matplotlib.pyplot as plt\n",
|
290 |
+
"\n",
|
291 |
+
"def plot_losses(train_losses, val_losses, title):\n",
|
292 |
+
" plt.plot(train_losses, label='Training Loss')\n",
|
293 |
+
" plt.plot(val_losses, label='Validation Loss')\n",
|
294 |
+
" plt.title(title)\n",
|
295 |
+
" plt.xlabel('Epoch')\n",
|
296 |
+
" plt.ylabel('Loss')\n",
|
297 |
+
" plt.legend()\n",
|
298 |
+
" plt.savefig('model_loss.png')\n",
|
299 |
+
" plt.show()\n",
|
300 |
+
"\n",
|
301 |
+
"# Plot combined model losses\n",
|
302 |
+
"plot_losses(train_losses, val_losses, 'Combined Model Loss')\n",
|
303 |
+
"\n"
|
304 |
+
],
|
305 |
+
"metadata": {
|
306 |
+
"colab": {
|
307 |
+
"base_uri": "https://localhost:8080/",
|
308 |
+
"height": 472
|
309 |
+
},
|
310 |
+
"id": "cGOHhDm8hF2z",
|
311 |
+
"outputId": "69498d44-8384-4b62-85bd-c3a04eb68e9c"
|
312 |
+
},
|
313 |
+
"execution_count": 14,
|
314 |
+
"outputs": [
|
315 |
+
{
|
316 |
+
"output_type": "display_data",
|
317 |
+
"data": {
|
318 |
+
"text/plain": [
|
319 |
+
"<Figure size 640x480 with 1 Axes>"
|
320 |
+
],
|
321 |
+
"image/png": "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xYosXrwYgH///ZeYmBgGDBiAu7t75vP17dsXf3//69ZxKavVSo8ePfjxxx8BxyTakJAQWrRoka3tsWPH2LRpE3379qVYsWKZx2vVqsU999yT+fuw2WzMmzePrl27Zvm5Vq1aNdtwUk7fc25auHAhaWlpDBs2DBeXi/9cP/300/j5+WX+ubnws5w3b94Vh+gAAgICAPjjjz+y9cCJODMFFZGb4OfnB0BCQkKO2kdHR+Pi4kKFChWyHA8MDCQgIIDo6Ogsxy/90ISLH0QhISFXPH727Nksx11cXAgPD89yrFKlSgBZhj2u5vLXL1q0aJbX2bNnD4ZhULFiRUqWLJnlsWPHDmJiYjLfN0DFihWzPJ+bm1u2+nLi0UcfJTIyks2bNzNt2jQeeeSRK+51cuF1K1eunO1c1apVOXXqFElJSZw8eZLk5ORs9V3p2py+59x0tffh7u5OeHh45vly5crx/PPP89///pcSJUrQrl07Pv/88yzzUx5++GGaNWtGv379KF26NI888gg///yzQos4Peef7i/ihPz8/AgODmbbtm03dF1ONxCzWq03dNy4bJLsrbre69jtdiwWC3PmzLli25xuOHejGjduTPny5Rk2bBhRUVE8+uijt+V1rsSs95xTH330EX379uWPP/5g/vz5DBkyhDFjxrBmzRrKlCmDl5cXy5YtY/HixcyePZu5c+fy008/cddddzF//vyr/s5FzKYeFZGb1KlTJ/bt28fq1auv2zY0NBS73c6ePXuyHD9x4gSxsbGEhobmam12uz3bcNDu3bsBcmXH1PLly2MYBuXKlaNt27bZHnfeeSdA5vu6/H2np6cTFRV1U6/ds2dPlixZQtWqValTp84V21x43V27dmU7t3PnTkqUKIGPjw8lS5bEy8srW31Xujan7zk3Xe19pKWlERUVle3PTc2aNXn11VdZtmwZy5cv58iRI3z55ZeZ511cXLj77rsZO3YskZGRvP322/z999+3ZdhKJLcoqIjcpP/85z/4+PjQr18/Tpw4ke38vn37+PTTTwG47777APjkk0+ytBk7dizAbdkHZPz48ZlfG4bB+PHjcXNz4+67777l537ggQewWq2MHj06W2+OYRicPn0agAYNGlCyZEm+/PJL0tLSMttMmTLlplfJ9OvXj5EjR/LRRx9dtU1QUBB16tTh22+/zfI627ZtY/78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K/aeZPaW48yPzBpaSvt50KFGEB1rBVG/bP4ILQV2joqIiEhh5O7qwl1VSnNXldKkZtRg5d5TzNpyjAXbT3AiPpUpqw4wZdWBzNDSqVYQ9fJJaLkeU4NKYmIie/fuzfw+KiqKTZs2UaxYMcqWLWtiZSIiIs7Jw9V6SWixsWKPY07LgsisoSXQz5MONR0TcfNzaDF16GfJkiW0adMm2/E+ffowZcqU616voR8RERGH1Awby3c7ljwviDxBQurF4aFAP0/uqxlEx1qB1A0xP7TkyzkqN0NBRUREJLuUdBvL91wMLYmXhJYgf8/Mibh1QwJMCS0KKiIiIgJcDC2ztxxl4Y6YLKEl2N+TDjUdE3HrhgRgseRNaFFQERERkWxS0m0s230ys6clKc2WeS7Y/8LwUBB1bnNoUVARERGRa0pJt7H0fGhZeFlouSPAi/tqOjaXux2hRUFFREREciwl3caSXedDy44TnLsktDSvUIIf+jXO1dfTPioiIiKSY55uVtrXCKR9jcDM0DJ76zEW7ThB3bIBptamoCIiIiKZLg8tqRl2U+tRUBEREZEr8nSz4ulmNbUGF1NfXUREROQaFFRERETEaSmoiIiIiNNSUBERERGnpaAiIiIiTktBRURERJyWgoqIiIg4LQUVERERcVoKKiIiIuK0FFRERETEaSmoiIiIiNNSUBERERGnpaAiIiIiTitf3z3ZMAwA4uPjTa5EREREcurC5/aFz/FryddBJSEhAYCQkBCTKxEREZEblZCQgL+//zXbWIycxBknZbfbOXr0KL6+vlgsllx97vj4eEJCQjh06BB+fn65+txy4/T7cC76fTgX/T6cj34n12YYBgkJCQQHB+Picu1ZKPm6R8XFxYUyZcrc1tfw8/PTHzInot+Hc9Hvw7no9+F89Du5uuv1pFygybQiIiLitBRURERExGkpqFyFh4cHI0eOxMPDw+xSBP0+nI1+H85Fvw/no99J7snXk2lFRESkYFOPioiIiDgtBRURERFxWgoqIiIi4rQUVERERMRpKahcweeff05YWBienp40btyYtWvXml1SoTVmzBgaNmyIr68vpUqVomvXruzatcvssgR49913sVgsDBs2zOxSCrUjR47w2GOPUbx4cby8vKhZsyb//vuv2WUVSjabjddee41y5crh5eVF+fLlefPNN3N0Pxu5OgWVy/z00088//zzjBw5kg0bNlC7dm3atWtHTEyM2aUVSkuXLiUiIoI1a9awYMEC0tPTuffee0lKSjK7tEJt3bp1TJw4kVq1apldSqF29uxZmjVrhpubG3PmzCEyMpKPPvqIokWLml1aofTee+8xYcIExo8fz44dO3jvvfd4//33GTdunNml5WtannyZxo0b07BhQ8aPHw847icUEhLC4MGDeemll0yuTk6ePEmpUqVYunQpLVu2NLucQikxMZF69erxxRdf8NZbb1GnTh0++eQTs8sqlF566SVWrlzJ8uXLzS5FgE6dOlG6dGm+/vrrzGPdu3fHy8uLH374wcTK8jf1qFwiLS2N9evX07Zt28xjLi4utG3bltWrV5tYmVwQFxcHQLFixUyupPCKiIigY8eOWf6eiDlmzpxJgwYNeOihhyhVqhR169blq6++MrusQqtp06YsWrSI3bt3A7B582ZWrFhBhw4dTK4sf8vXNyXMbadOncJms1G6dOksx0uXLs3OnTtNqkousNvtDBs2jGbNmlGjRg2zyymUpk+fzoYNG1i3bp3ZpQiwf/9+JkyYwPPPP8/LL7/MunXrGDJkCO7u7vTp08fs8gqdl156ifj4eKpUqYLVasVms/H222/Tq1cvs0vL1xRUJN+IiIhg27ZtrFixwuxSCqVDhw4xdOhQFixYgKenp9nlCI7w3qBBA9555x0A6taty7Zt2/jyyy8VVEzw888/M3XqVKZNm0b16tXZtGkTw4YNIzg4WL+PW6CgcokSJUpgtVo5ceJEluMnTpwgMDDQpKoEYNCgQcyaNYtly5ZRpkwZs8splNavX09MTAz16tXLPGaz2Vi2bBnjx48nNTUVq9VqYoWFT1BQENWqVctyrGrVqvzvf/8zqaLC7YUXXuCll17ikUceAaBmzZpER0czZswYBZVboDkql3B3d6d+/fosWrQo85jdbmfRokU0adLExMoKL8MwGDRoEDNmzODvv/+mXLlyZpdUaN19991s3bqVTZs2ZT4aNGhAr1692LRpk0KKCZo1a5Ztuf7u3bsJDQ01qaLC7dy5c7i4ZP1YtVqt2O12kyoqGNSjcpnnn3+ePn360KBBAxo1asQnn3xCUlISTzzxhNmlFUoRERFMmzaNP/74A19fX44fPw6Av78/Xl5eJldXuPj6+mabG+Tj40Px4sU1Z8gkzz33HE2bNuWdd96hR48erF27lkmTJjFp0iSzSyuUOnfuzNtvv03ZsmWpXr06GzduZOzYsTz55JNml5a/GZLNuHHjjLJlyxru7u5Go0aNjDVr1phdUqEFXPExefJks0sTwzBatWplDB061OwyCrU///zTqFGjhuHh4WFUqVLFmDRpktklFVrx8fHG0KFDjbJlyxqenp5GeHi48corrxipqalml5avaR8VERERcVqaoyIiIiJOS0FFREREnJaCioiIiDgtBRURERFxWgoqIiIi4rQUVERERMRpKaiIiIiI01JQEZECxWKx8Pvvv5tdhojkEgUVEck1ffv2xWKxZHu0b9/e7NJEJJ/SvX5EJFe1b9+eyZMnZznm4eFhUjUikt+pR0VEcpWHhweBgYFZHkWLFgUcwzITJkygQ4cOeHl5ER4ezq+//prl+q1bt3LXXXfh5eVF8eLF6d+/P4mJiVnafPPNN1SvXh0PDw+CgoIYNGhQlvOnTp2iW7dueHt7U7FiRWbOnHl737SI3DYKKiKSp1577TW6d+/O5s2b6dWrF4888gg7duwAICkpiXbt2lG0aFHWrVvHL7/8wsKFC7MEkQkTJhAREUH//v3ZunUrM2fOpEKFClleY/To0fTo0YMtW7Zw33330atXL86cOZOn71NEconZd0UUkYKjT58+htVqNXx8fLI83n77bcMwHHfDHjBgQJZrGjdubAwcONAwDMOYNGmSUbRoUSMxMTHz/OzZsw0XFxfj+PHjhmEYRnBwsPHKK69ctQbAePXVVzO/T0xMNABjzpw5ufY+RSTvaI6KiOSqNm3aMGHChCzHihUrlvl1kyZNspxr0qQJmzZtAmDHjh3Url0bHx+fzPPNmjXDbreza9cuLBYLR48e5e67775mDbVq1cr82sfHBz8/P2JiYm72LYmIiRRURCRX+fj4ZBuKyS1eXl45aufm5pble4vFgt1uvx0lichtpjkqIpKn1qxZk+37qlWrAlC1alU2b95MUlJS5vmVK1fi4uJC5cqV8fX1JSwsjEWLFuVpzSJiHvWoiEiuSk1N5fjx41mOubq6UqJECQB++eUXGjRoQPPmzZk6dSpr167l66+/BqBXr16MHDmSPn36MGrUKE6ePMngwYN5/PHHKV26NACjRo1iwIABlCpVig4dOpCQkMDKlSsZPHhw3r5REckTCioikqvmzp1LUFBQlmOVK1dm586dgGNFzvTp03n22WcJCgrixx9/pFq1agB4e3szb948hg4dSsOGDfH29qZ79+6MHTs287n69OlDSkoKH3/8McOHD6dEiRI8+OCDefcGRSRPWQzDMMwuQkQKB4vFwowZM+jatavZpYhIPqE5KiIiIuK0FFRERETEaWmOiojkGY00i8iNUo+KiIiIOC0FFREREXFaCioiIiLitBRURERExGkpqIiIiIjTUlARERERp6WgIiIiIk5LQUVEREScloKKiIiIOK3/B5iKgT50eamDAAAAAElFTkSuQmCC\n"
|
322 |
+
},
|
323 |
+
"metadata": {}
|
324 |
+
}
|
325 |
+
]
|
326 |
+
},
|
327 |
+
{
|
328 |
+
"cell_type": "code",
|
329 |
+
"source": [
|
330 |
+
"# Calculate perplexity based on the validation set\n",
|
331 |
+
"def calculate_perplexity(model, val_loader):\n",
|
332 |
+
" model.eval()\n",
|
333 |
+
" total_loss = 0\n",
|
334 |
+
" total_words = 0\n",
|
335 |
+
"\n",
|
336 |
+
" with torch.no_grad():\n",
|
337 |
+
" for inputs, targets in val_loader:\n",
|
338 |
+
" outputs = model(inputs)\n",
|
339 |
+
" loss = criterion(outputs, targets)\n",
|
340 |
+
" total_loss += loss.item()\n",
|
341 |
+
" total_words += targets.size(0)\n",
|
342 |
+
"\n",
|
343 |
+
" avg_loss = total_loss / len(val_loader)\n",
|
344 |
+
" perplexity = np.exp(avg_loss)\n",
|
345 |
+
"\n",
|
346 |
+
" return perplexity\n",
|
347 |
+
"\n",
|
348 |
+
"# Perplexity calculation for the combined model\n",
|
349 |
+
"combined_perplexity = calculate_perplexity(combined_model, val_loader)\n",
|
350 |
+
"print(f'Combined Model Perplexity: {combined_perplexity:.2f}')"
|
351 |
+
],
|
352 |
+
"metadata": {
|
353 |
+
"colab": {
|
354 |
+
"base_uri": "https://localhost:8080/"
|
355 |
+
},
|
356 |
+
"id": "j29uMcyKjKge",
|
357 |
+
"outputId": "21b4437a-54e3-445a-f7c5-7017882d6645"
|
358 |
+
},
|
359 |
+
"execution_count": 9,
|
360 |
+
"outputs": [
|
361 |
+
{
|
362 |
+
"output_type": "stream",
|
363 |
+
"name": "stdout",
|
364 |
+
"text": [
|
365 |
+
"Combined Model Perplexity: 6543.78\n"
|
366 |
+
]
|
367 |
+
}
|
368 |
+
]
|
369 |
+
},
|
370 |
+
{
|
371 |
+
"cell_type": "code",
|
372 |
+
"source": [
|
373 |
+
"import torch.nn.functional as F\n",
|
374 |
+
"\n",
|
375 |
+
"# Ensure '<UNK>' token is in the vocabularies\n",
|
376 |
+
"if '<UNK>' not in english_vocab:\n",
|
377 |
+
" english_vocab['<UNK>'] = len(english_vocab)\n",
|
378 |
+
"if '<UNK>' not in icelandic_vocab:\n",
|
379 |
+
" icelandic_vocab['<UNK>'] = len(icelandic_vocab)\n",
|
380 |
+
"\n",
|
381 |
+
"# Reverse vocab dictionaries\n",
|
382 |
+
"english_reverse_vocab = {idx: word for word, idx in english_vocab.items()}\n",
|
383 |
+
"icelandic_reverse_vocab = {idx: word for word, idx in icelandic_vocab.items()}\n",
|
384 |
+
"\n",
|
385 |
+
"# Function to generate text\n",
|
386 |
+
"def generate_text(model, vocab, reverse_vocab, seed_text, max_length=50):\n",
|
387 |
+
" model.eval()\n",
|
388 |
+
"\n",
|
389 |
+
" # Tokenize and convert seed text to indices\n",
|
390 |
+
" seed_tokens = [vocab.get(word, vocab['<UNK>']) for word in seed_text.split()]\n",
|
391 |
+
" input_seq = torch.tensor(seed_tokens).unsqueeze(0) # Add batch dimension\n",
|
392 |
+
"\n",
|
393 |
+
" generated_text = seed_text.split()\n",
|
394 |
+
"\n",
|
395 |
+
" with torch.no_grad():\n",
|
396 |
+
" for _ in range(max_length):\n",
|
397 |
+
" output = model(input_seq) # Forward pass\n",
|
398 |
+
"\n",
|
399 |
+
" # Check the shape of the output\n",
|
400 |
+
" if len(output.shape) == 2:\n",
|
401 |
+
" # Handle (batch_size, vocab_size)\n",
|
402 |
+
" predictions = F.softmax(output, dim=-1)\n",
|
403 |
+
" else:\n",
|
404 |
+
" # Handle (batch_size, sequence_length, vocab_size)\n",
|
405 |
+
" predictions = F.softmax(output[:, -1, :], dim=-1)\n",
|
406 |
+
"\n",
|
407 |
+
" next_token_idx = torch.argmax(predictions, dim=-1).item()\n",
|
408 |
+
"\n",
|
409 |
+
" # Append the predicted token\n",
|
410 |
+
" next_token_word = reverse_vocab.get(next_token_idx, '<UNK>')\n",
|
411 |
+
" generated_text.append(next_token_word)\n",
|
412 |
+
"\n",
|
413 |
+
" # Update input sequence with the predicted token\n",
|
414 |
+
" input_seq = torch.cat([input_seq, torch.tensor([[next_token_idx]])], dim=1)\n",
|
415 |
+
"\n",
|
416 |
+
" return ' '.join(generated_text)\n",
|
417 |
+
"\n",
|
418 |
+
"# Generate text in English\n",
|
419 |
+
"print(\"Generating text in English...\")\n",
|
420 |
+
"seed_text = \"Today is a good ohh yes\"\n",
|
421 |
+
"generated_english = generate_text(combined_model, english_vocab, english_reverse_vocab, seed_text)\n",
|
422 |
+
"print(\"Generated English Text:\", generated_english)\n",
|
423 |
+
"\n",
|
424 |
+
"# Generate text in Icelandic\n",
|
425 |
+
"print(\"Generating text in Icelandic...\")\n",
|
426 |
+
"seed_text_icelandic = \"þetta mun auka\"\n",
|
427 |
+
"generated_icelandic = generate_text(combined_model, icelandic_vocab, icelandic_reverse_vocab, seed_text_icelandic)\n",
|
428 |
+
"print(\"Generated Icelandic Text:\", generated_icelandic)\n"
|
429 |
+
],
|
430 |
+
"metadata": {
|
431 |
+
"colab": {
|
432 |
+
"base_uri": "https://localhost:8080/"
|
433 |
+
},
|
434 |
+
"id": "N09nTZPNqRXw",
|
435 |
+
"outputId": "bd5a1748-694c-493f-c631-fcb29ffe9374"
|
436 |
+
},
|
437 |
+
"execution_count": 22,
|
438 |
+
"outputs": [
|
439 |
+
{
|
440 |
+
"output_type": "stream",
|
441 |
+
"name": "stdout",
|
442 |
+
"text": [
|
443 |
+
"Generating text in English...\n",
|
444 |
+
"Generated English Text: Today is a good ohh yes in three research input output one is an object input output there are several types of these disasters can vary these can can can find the instance and accuracy the behavior of the given polynomial input x x x x can can add as the sentence but the speaker she\n",
|
445 |
+
"Generating text in Icelandic...\n",
|
446 |
+
"Generated Icelandic Text: þetta mun auka áberandi í utan eins og vieigandi alaandi og hjálpa til a gera gera get um a afslætti sínu sé einföld og sigrast og sanngjarnan til vinnu og gera er almennt á núverandi me frammistöu og getu getu okkar eins og okkar okkar til þátttöku og málverk til a draga úr\n"
|
447 |
+
]
|
448 |
+
}
|
449 |
+
]
|
450 |
+
},
|
451 |
+
{
|
452 |
+
"cell_type": "code",
|
453 |
+
"source": [],
|
454 |
+
"metadata": {
|
455 |
+
"id": "3_URP8RbqRLT"
|
456 |
+
},
|
457 |
+
"execution_count": null,
|
458 |
+
"outputs": []
|
459 |
+
},
|
460 |
+
{
|
461 |
+
"cell_type": "markdown",
|
462 |
+
"source": [
|
463 |
+
"END END"
|
464 |
+
],
|
465 |
+
"metadata": {
|
466 |
+
"id": "BENy15FBq52n"
|
467 |
+
}
|
468 |
+
},
|
469 |
+
{
|
470 |
+
"cell_type": "code",
|
471 |
+
"source": [],
|
472 |
+
"metadata": {
|
473 |
+
"id": "IjtIYqGpjKlm"
|
474 |
+
},
|
475 |
+
"execution_count": null,
|
476 |
+
"outputs": []
|
477 |
+
},
|
478 |
+
{
|
479 |
+
"cell_type": "code",
|
480 |
+
"source": [],
|
481 |
+
"metadata": {
|
482 |
+
"id": "N5V6k9mthGEW"
|
483 |
+
},
|
484 |
+
"execution_count": null,
|
485 |
+
"outputs": []
|
486 |
+
}
|
487 |
+
],
|
488 |
+
"metadata": {
|
489 |
+
"colab": {
|
490 |
+
"provenance": []
|
491 |
+
},
|
492 |
+
"kernelspec": {
|
493 |
+
"display_name": "Python 3",
|
494 |
+
"name": "python3"
|
495 |
+
},
|
496 |
+
"language_info": {
|
497 |
+
"name": "python"
|
498 |
+
}
|
499 |
+
},
|
500 |
+
"nbformat": 4,
|
501 |
+
"nbformat_minor": 0
|
502 |
+
}
|
Checkpoints_Q8/combined_model.pth
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:0f9106497ecf842d11a75df9b636d7753070d798595d7c44a28ef6a4efd26a24
|
3 |
+
size 28056286
|
Checkpoints_Q8/combined_model_checkpoint_epoch1.pth
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:cd0e1bb4406fb99103a7e13defe11fee5fdc3f8201f918f6ec822af2c31f8671
|
3 |
+
size 28056748
|
Checkpoints_Q8/combined_model_checkpoint_epoch10.pth
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:88cbedb9db0eed9bb6c1aa9c123030554dc982fbeef678e37d106f41f324b8ba
|
3 |
+
size 28056763
|
Checkpoints_Q8/combined_model_checkpoint_epoch2.pth
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:b52ac36a4573ac09f403142ec903999bf0f26d667a3fb383687581ac9cfebdd0
|
3 |
+
size 28056748
|
Checkpoints_Q8/combined_model_checkpoint_epoch3.pth
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:8bc972ab9636e4a358a9906cb74c3d20f4bbfdca6edb891820ca13a88818063d
|
3 |
+
size 28056748
|
Checkpoints_Q8/combined_model_checkpoint_epoch4.pth
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:adb3b735c81b299780039e5d34501141a67981567677169324a75f70bd9c0860
|
3 |
+
size 28056748
|
Checkpoints_Q8/combined_model_checkpoint_epoch5.pth
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:1e3cb73e086c50b91ec7107542f15e359ff5ecc2bb2ec8d8e2ae40beb2e108be
|
3 |
+
size 9736192
|
Checkpoints_Q8/combined_model_checkpoint_epoch6.pth
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:d90121d28fce9d3dd48cdd55e509c037eefd0fa5e93d7c51267dd64beb82f001
|
3 |
+
size 28056748
|
Checkpoints_Q8/combined_model_checkpoint_epoch7.pth
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:61f4cdba1fa3adf92f33278f41523ebd2c8085b5765648b216273b25e65f8f4c
|
3 |
+
size 28056748
|
Checkpoints_Q8/combined_model_checkpoint_epoch8.pth
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:8abf81c9c0521609dc75ab29b6a1bafef093ceb2763571d1a01a1c1647f98041
|
3 |
+
size 28056748
|
Checkpoints_Q8/combined_model_checkpoint_epoch9.pth
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:6a7e464858f32fa1180df21046e797916ac37b4842865ca03abc4629b6d46f50
|
3 |
+
size 28056748
|