-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathpathvqa_eval.py
More file actions
83 lines (70 loc) · 2.65 KB
/
Copy pathpathvqa_eval.py
File metadata and controls
83 lines (70 loc) · 2.65 KB
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
"""
For AQUA (Art VQA), we don't use the VQAv2 evaluation code.
That's because the VQAv2 evaluation code assumes there are
multiple answers for each question, but in AQUA, there's only
one answer for each question. We just do an exact match evaluation
following the AQUA paper.
"""
import json
from unittest import result
from tqdm import tqdm
import json
from pprint import PrettyPrinter
from vqa_eval_tools import VQA, VQAEval
from argparse import ArgumentParser
from pathlib import Path
import schemas
import pandas as pd
pp = PrettyPrinter()
annotation_file = "/net/acadia4a/data/zkhan/pathvqa/test.json"
def exact_match_eval(annotation_file, result_file):
with open(annotation_file, "r") as f:
annotations = json.load(f)
with open(result_file, "r") as f:
results = json.load(f)
annotations = [schemas.MinimalEvaluationRecord.parse_obj(a) for a in annotations]
annotation_lookup_table = {a.question_id: a for a in annotations}
evaluation_records = []
for answer_record in results:
ground_truth = annotation_lookup_table[answer_record["question_id"]]
# It's a list, but there's only one answer for each VQA art question.
# So we just take the first one and do an exact match.
true_answer = ground_truth.answer
is_correct = answer_record["answer"] == true_answer
question_type = ground_truth.question_type
evaluation_records.append(
{
"question_id": answer_record["question_id"],
"answer": answer_record["answer"],
"question_type": question_type,
"is_correct": is_correct,
"true_answer": true_answer,
"answer_type": ground_truth.answer_type,
}
)
frame = pd.DataFrame(evaluation_records)
answertype_groupby = (
frame.groupby("answer_type")
.apply(lambda s: s["is_correct"].sum() / len(s))
.to_frame()
)
accuracies = {
"overall": frame["is_correct"].sum() / len(frame),
}
accuracies = {
**accuracies,
**{_: float(answertype_groupby.loc[_]) for _ in answertype_groupby.index},
}
accuracies = {k: round(v, 4) for k, v in accuracies.items()}
return accuracies
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument(
"result_file", help="Path to a JSON result file generated by an evaluation."
)
args = parser.parse_args()
results_file = args.result_file
accuracies = exact_match_eval(annotation_file, results_file)
pp.pprint(accuracies)
with open(Path(results_file).parent / "pathvqa_eval.json", "w") as f:
json.dump(accuracies, f)