-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodel_training.py
124 lines (99 loc) · 3.7 KB
/
model_training.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# imports
from dataloader import *
from model import SentimentCLF
import torch
from torch.optim import SGD
from torch.nn import CrossEntropyLoss
from params import EPOCHS, LR, MAX_TOKENS, VOCAB_SIZE
import time
def data(load=False):
"""
Call this function if you want to regenerate
the same 'batches.pt' file locally.
In this way you don't need to
rerun this function everytime
the script is ran.
"""
# Define training and eval/test data
if load:
data_train, data_eval = data2df(final=False)
data_train, data_eval = DatasetSentiment(data_train), DatasetSentiment(data_eval)
train_loader = DynamicBatchLoader(dataset=data_train, max_tokens=MAX_TOKENS, debug=False).dynamic()
eval_loader = DynamicBatchLoader(dataset=data_eval, max_tokens=MAX_TOKENS, debug=False).dynamic()
torch.save(train_loader, 'train_batches.pt')
torch.save(eval_loader, 'eval_batches.pt')
else:
pass
data(load=False)
batches = torch.load('train_batches.pt')
batches_eval = torch.load('eval_batches.pt')
model = SentimentCLF(nr_embed=VOCAB_SIZE)
loss_func = CrossEntropyLoss()
optimizer = SGD(model.parameters(), lr=LR)
def train(epochs):
"""
Trains a pytorch model that
stops training if after x
epochs there ha
"""
train_acc_epoch = []
eval_acc_epoch = []
train_loss_epoch = []
eval_loss_epoch = []
start = time.time()
epoch_len = [x for x in range(1, epochs)]
for epoch in range(epochs):
current_loss = 0.0
for i, batch in enumerate(batches):
sequences, labels = batch[0], batch[1]
optimizer.zero_grad()
outputs = model(sequences)
loss = loss_func(outputs, labels)
loss.backward()
optimizer.step()
current_loss += loss.item()
print(f'================= Epoch {epoch + 1} =================')
train_1, train_2 = accuracy(current_loss=current_loss, type_acc='train')
train_acc_epoch.append(train_1)
train_loss_epoch.append(train_2)
eval_1, eval_2 = accuracy(current_loss=0, type_acc='eval')
eval_acc_epoch.append(eval_1)
eval_loss_epoch.append(eval_2)
end = time.time()
total = end - start
minute = total / 60
pool = model.pool
torch.save(model.state_dict(), f'{pool}_{LR}_{MAX_TOKENS}.pt')
print(f"Training time is {round(minute, 2)} minutes")
def accuracy(current_loss, type_acc='train'):
truth = []
pred = []
with torch.no_grad():
if type_acc == 'train':
model.train()
loss = current_loss / 20000
for sequences, labels in batches:
outputs = model(sequences)
truth.append(labels)
pred.append(torch.argmax(outputs, dim=1))
truth = torch.cat(truth, dim=0)
pred = torch.cat(pred, dim=0)
acc = (truth == pred).float().mean().item()
print(f"Training Loss: {loss:.4f}, Training Accuracy: {(acc * 100):.2f}%")
return loss, acc
elif type_acc == 'eval':
model.eval()
eval_loss = 0.0
for sequences, labels in batches_eval:
outputs = model(sequences)
loss = loss_func(outputs, labels)
eval_loss += loss.item()
truth.append(labels)
pred.append(torch.argmax(outputs, dim=1))
truth = torch.cat(truth, dim=0)
pred = torch.cat(pred, dim=0)
acc = (truth == pred).float().mean().item()
eval_loss /= 5000
print(f"Validation Loss: {eval_loss:.4f}, Validation Accuracy: {(acc * 100):.2f}%")
return loss, acc
train(epochs=EPOCHS)