-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtrain.py
executable file
·92 lines (75 loc) · 2.88 KB
/
train.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
import json
import torch.nn as nn
from tqdm import tqdm
import torch.nn.functional as F
import utils.config as config
def compute_score_with_logits(logits, labels):
_, log_index = logits.max(dim=1, keepdim=True)
scores = labels.gather(dim=1, index=log_index)
return scores
def saved_for_eval(dataloader, results, question_ids, answer_preds):
""" Save as a format accepted by the evaluation server. """
_, answer_ids = answer_preds.max(dim=1)
answers = [dataloader.dataset.label2ans[i] for i in answer_ids]
for q, a in zip(question_ids, answers):
entry = {
'question_id': q.item(),
'answer': a,
}
results.append(entry)
return results
def train(model, optim, train_loader, loss_fn, tracker, writer, tb_count):
loader = tqdm(train_loader, ncols=0)
loss_trk = tracker.track('loss', tracker.MovingMeanMonitor(momentum=0.99))
acc_trk = tracker.track('acc', tracker.MovingMeanMonitor(momentum=0.99))
for v, q, a, a_m, a_s, bias, q_id in loader:
v = v.cuda()
q = q.cuda()
a = a.cuda()
a_m = a_m.cuda()
a_s = a_s.cuda()
bias = bias.cuda()
pred, mask, hidden, _ = model(v, q)
dict_args = {'bias': bias, 'hidden': hidden}
if config.use_miu:
dict_args['miu'] = a_s
dict_args['mask'] = a_m
loss = loss_fn(pred, a, **dict_args)
if config.use_mask:
loss_mask = F.binary_cross_entropy_with_logits(mask, a_m)
loss += loss_mask
# writer.add_scalars('data/losses', {
# 'loss_back': loss - loss_mask,
# 'loss_mask': loss_mask
# }, tb_count)
# tb_count += 1
loss.backward()
nn.utils.clip_grad_norm_(model.parameters(), 0.25)
optim.step()
optim.zero_grad()
batch_score = compute_score_with_logits(pred, a.data)
fmt = '{:.4f}'.format
loss_trk.append(loss.item())
acc_trk.append(batch_score.mean())
loader.set_postfix(loss=fmt(loss_trk.mean.value),
acc=fmt(acc_trk.mean.value))
return tb_count
def evaluate(model, dataloader, epoch=0, write=False):
score = 0
results = [] # saving for evaluation
for v, q, a, a_m, a_s, _, q_id in tqdm(dataloader, leave=False):
v = v.cuda()
q = q.cuda()
pred, _, _, _ = model(v, q)
if write:
results = saved_for_eval(dataloader, results, q_id, pred)
batch_score = compute_score_with_logits(pred, a.cuda()).sum()
score += batch_score
score = score / len(dataloader.dataset)
if write:
print("saving prediction results to disk...")
result_file = 'vqa_{}_{}_{}_{}_results.json'.format(
config.task, config.test_split, config.version, epoch)
with open(result_file, 'w') as fd:
json.dump(results, fd)
return score