| import json |
| import os |
|
|
| import pandas as pd |
| import torch |
| import glob |
|
|
| from eval_func.bleu.bleu import Bleu |
| from eval_func.rouge.rouge import Rouge |
| from eval_func.cider.cider import Cider |
|
|
|
|
| def get_eval_score(ref, hypo): |
| scorers = [ |
| (Bleu(4), ["Bleu_1", "Bleu_2", "Bleu_3", "Bleu_4"]), |
| (Rouge(), "ROUGE_L"), |
| (Cider(), "CIDEr") |
| ] |
|
|
| score = [] |
| method = [] |
| for scorer, method_i in scorers: |
| score_i, scores_i = scorer.compute_score(ref, hypo) |
| score.extend(score_i) if isinstance(score_i, list) else score.append(score_i) |
| method.extend(method_i) if isinstance(method_i, list) else method.append(method_i) |
|
|
| score_dict = dict(zip(method, score)) |
| return score_dict |
|
|
|
|
| def get_vocabulary(in_path, out_file): |
| if 'levir' in in_path.lower(): |
| return get_levir_vocabulary(in_path, out_file) |
| elif 'dubai' in in_path.lower(): |
| return get_dubai_vocabulary(in_path, out_file) |
| elif 'clevr' in in_path.lower(): |
| return get_clevr_vocabulary(in_path, out_file) |
|
|
|
|
| def get_levir_vocabulary(in_path, out_file): |
| with open(in_path) as fin: |
| data = json.load(fin)['images'] |
|
|
| sents = [y for x in data for y in x['sentences']] |
| tokens = [y for x in sents for y in x['tokens']] |
| occurencies = pd.Series(tokens).value_counts() |
| selected = occurencies[occurencies > 5] |
| vocab = {w: i + 4 for i, w in enumerate(selected.index)} |
| vocab['PAD'] = 0 |
| vocab['START'] = 1 |
| vocab['UNK'] = 2 |
| vocab['END'] = 3 |
|
|
| with open(out_file, 'w') as fout: |
| json.dump(vocab, fout) |
|
|
| return vocab |
|
|
|
|
| def get_dubai_vocabulary(in_path, out_file): |
| data = [] |
| for path in glob.glob(in_path + '/*.json'): |
| with open(path) as fin: |
| data.extend(json.load(fin)['images']) |
|
|
| sents = [y for x in data for y in x['sentences']] |
| tokens = [y for x in sents for y in x['tokens']] |
| selected = pd.Series(tokens).value_counts() |
| vocab = {w: i + 4 for i, w in enumerate(selected.index)} |
| vocab['PAD'] = 0 |
| vocab['START'] = 1 |
| vocab['UNK'] = 2 |
| vocab['END'] = 3 |
|
|
| with open(out_file, 'w') as fout: |
| json.dump(vocab, fout) |
|
|
| return vocab |
|
|
|
|
| def get_clevr_vocabulary(in_path, out_file): |
| sents = [] |
| with open(os.path.join(in_path, 'change_captions.json'), 'r', encoding='utf-8') as fin: |
| data = json.load(fin) |
| sents += [y for x in data for y in data[x]] |
|
|
| with open(os.path.join(in_path, 'no_change_captions.json'), 'r', encoding='utf-8') as fin: |
| data = json.load(fin) |
| sents += [y for x in data for y in data[x]] |
|
|
| tokens = [y for x in sents for y in x.split(' ')] |
| occurencies = pd.Series(tokens).value_counts() |
| vocab = {w: i + 4 for i, w in enumerate(occurencies.index)} |
| vocab['PAD'] = 0 |
| vocab['START'] = 1 |
| vocab['UNK'] = 2 |
| vocab['END'] = 3 |
|
|
| with open(out_file, 'w') as fout: |
| json.dump(vocab, fout) |
|
|
| return vocab |
|
|
|
|
| def unormalize(tensor, mean=None, std=None): |
| if mean is not None and std is not None: |
| for t, m, s in zip(tensor, mean, std): |
| t.mul_(s).add_(m) |
| return torch.clip(tensor, min=0, max=1) |
|
|
| b, c, h, w = tensor.shape |
| tensor = tensor.view(b, -1) |
| tensor -= tensor.min(1, keepdim=True)[0] |
| tensor /= tensor.max(1, keepdim=True)[0] |
| return tensor.view(b, c, h, w) |
|
|