mrazhou commited on
Commit
91dd2ed
·
verified ·
1 Parent(s): 507eec2

Upload get_best_tex.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. get_best_tex.py +243 -0
get_best_tex.py ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import argparse
4
+ from typing import List
5
+ from tabulate import tabulate
6
+
7
+ from abc import ABC, abstractmethod
8
+ class Result(ABC):
9
+
10
+ def __init__(self, res_path, com_path_len, end_flag_len, metric_key:List[str]=[]) -> None:
11
+ super().__init__()
12
+ self.ab_path = res_path
13
+ self.rl_path = res_path[com_path_len:-end_flag_len]
14
+ self.metric_key = metric_key
15
+
16
+ @abstractmethod
17
+ def read_metric(self):
18
+ pass
19
+
20
+ @abstractmethod
21
+ def process_metric(self, metric):
22
+ pass
23
+
24
+ def get(self):
25
+ # read and process
26
+ metric = self.read_metric()
27
+ processed_metric = self.process_metric(metric)
28
+
29
+ # set result
30
+ res = {
31
+ 'ab_path': self.ab_path,
32
+ 'rl_path': self.rl_path,
33
+ 'metric': processed_metric
34
+ }
35
+ return res
36
+
37
+ def get_all_res_path(paths, flag):
38
+ all_files = []
39
+ for path in paths:
40
+ for root, dirs, files in os.walk(path):
41
+ for file in files:
42
+ if file.endswith(flag):
43
+ all_files.append(os.path.join(root, file))
44
+ return all_files
45
+
46
+ def get_len_tuple(paths:List[str], end_flag:str) -> tuple:
47
+ if len(paths) > 1:
48
+ common_path_len = len(os.path.commonpath(paths))
49
+ end_flag_len = len(end_flag) + 1 # +1 for the '/'
50
+ max_path_len = max(len(path) for path in paths) - common_path_len - end_flag_len
51
+ elif len(paths) == 1:
52
+ path = paths[0]
53
+ p_name_len = len(path.split('/')[-2])
54
+ end_flag_len = len(end_flag) + 1 # +1 for the '/'
55
+ common_path_len = len(path) - p_name_len - end_flag_len
56
+ max_path_len = p_name_len
57
+ else:
58
+ print('No path found! Maybe you should specify the path for [baseline] by --base !')
59
+ exit(-1)
60
+ return [common_path_len, end_flag_len, max_path_len]
61
+
62
+
63
+ class AllResult:
64
+ def __init__(
65
+ self,
66
+ paths:List[str],
67
+ baseline_paths:List[str],
68
+ end_flag:str,
69
+ res_cls:Result,
70
+ incl:List[str] = None,
71
+ excl:List[str] = None,
72
+ metric_key:List[str] = []
73
+ ) -> None:
74
+ super().__init__()
75
+ self.incl = incl
76
+ self.excl = excl
77
+ self.res_cls = res_cls
78
+
79
+ self.all_res = []
80
+
81
+ self.base_paths, self.base_len_tuple = self.get_base_paths(baseline_paths, end_flag)
82
+ self.res_paths, self.len_tuple = self.get_res_paths(paths, end_flag)
83
+
84
+ if self.base_len_tuple[2] + 2 > self.len_tuple[2]:
85
+ self.len_tuple[2] = self.base_len_tuple[2] + 2
86
+
87
+ self.metric_key = metric_key
88
+
89
+ def filter_paths(self, paths:List[str]):
90
+ if self.incl:
91
+ paths = [path
92
+ for path in paths
93
+ if any(tag in path for tag in self.incl)]
94
+ if self.excl:
95
+ paths = [path
96
+ for path in paths
97
+ if all(tag not in path for tag in self.excl)]
98
+ if len(paths) == 0:
99
+ print('No result found with the given tags (incl/excl)')
100
+ exit(-1)
101
+ return paths
102
+
103
+ def get_res_paths(self, paths, end_flag):
104
+ all_paths = get_all_res_path(paths, end_flag)
105
+ res_paths = self.filter_paths(all_paths)
106
+ res_paths = [path
107
+ for path in res_paths
108
+ if path not in self.base_paths]
109
+ len_tuple = get_len_tuple(res_paths, end_flag)
110
+ return res_paths, len_tuple
111
+
112
+ def get_base_paths(self, paths, end_flag):
113
+ all_paths = get_all_res_path(paths, end_flag)
114
+ len_tuple = get_len_tuple(all_paths, end_flag)
115
+ return all_paths, len_tuple
116
+
117
+ def color_best(self):
118
+ all_res = self.get()
119
+ max_info = {
120
+ key: {'idx': 0, 'value': 0, 'len': len(key)}
121
+ for key in all_res[0]['metric'].keys()
122
+ }
123
+ for i, res in enumerate(all_res):
124
+ for key, value in res['metric'].items():
125
+ key_len = max_info[key]['len']
126
+ self.all_res[i]['metric'][key] = f'{value:^{key_len}.1f}'
127
+ if value > max_info[key]['value']:
128
+ max_info[key]['value'] = value
129
+ max_info[key]['idx'] = i
130
+
131
+ for key, item in max_info.items():
132
+ idx = item['idx']
133
+ value = item['value']
134
+ key_len = max_info[key]['len']
135
+ self.all_res[idx]['metric'][key] = f'\033m\033[31m{value:^{key_len}.2f}\033[0m'
136
+ return max_info
137
+
138
+ def sorted_by(self, key:str):
139
+ all_res = self.get()
140
+ self.all_res = sorted(
141
+ all_res,
142
+ key=lambda x: x['metric'][key],
143
+ reverse=True
144
+ )
145
+
146
+ def header(self, all_res, delimiter='\t'):
147
+ if not all_res:
148
+ return 'name\tmetric'
149
+ first = '{:^{}}'.format('name', self.len_tuple[2])
150
+ metric_key = self.metric_key or all_res[0]['metric'].keys()
151
+ others = f'{delimiter}'.join(metric_key)
152
+ return f'{first} | {others}'
153
+
154
+ def print(self, delimiter='\t'):
155
+ all_res = self.get()
156
+ print(self.header(all_res, delimiter=delimiter))
157
+ for res in all_res:
158
+ rl_path = f'{res["rl_path"]:{self.len_tuple[2]}}'
159
+ if self.metric_key:
160
+ metric = f'{delimiter}'.join([f'{res["metric"][k]}' for k in self.metric_key])
161
+ else:
162
+ metric = f'{delimiter}'.join([f'{v}' for v in res['metric'].values()])
163
+ print(f'{rl_path} | {metric}')
164
+
165
+ def print_table(self):
166
+ all_res = self.get()
167
+ data = []
168
+ headers = ['name', *self.metric_key]
169
+ for res in all_res:
170
+ data.append([res['rl_path'], *res['metric'].values()])
171
+ print(tabulate(data, headers=headers, tablefmt='plain', floatfmt='.2f', numalign='center'))
172
+
173
+ def get(self):
174
+ if self.all_res:
175
+ return self.all_res
176
+
177
+ for res_path in self.res_paths:
178
+ res = self.res_cls(
179
+ res_path,
180
+ self.len_tuple[0],
181
+ self.len_tuple[1],
182
+ self.metric_key
183
+ ).get()
184
+ self.all_res.append(res)
185
+
186
+ # baseline res
187
+ for i, res_path in enumerate(self.base_paths):
188
+ res = self.res_cls(
189
+ res_path,
190
+ self.base_len_tuple[0],
191
+ self.base_len_tuple[1],
192
+ self.metric_key
193
+ ).get()
194
+ res['rl_path'] = f'[{res["rl_path"]}]'
195
+ self.all_res.append(res)
196
+
197
+ return self.all_res
198
+
199
+ class CapRes(Result):
200
+ sub_metric_key = 'CIDEr'
201
+
202
+ def read_metric(self):
203
+ with open(self.ab_path, 'r') as infile:
204
+ metrics = json.load(infile)
205
+ return metrics
206
+
207
+ def process_metric(self, metric):
208
+ processed_metric = {}
209
+ for key, value in metric.items():
210
+ processed_metric[key] = round(value[CapRes.sub_metric_key] * 100, 2)
211
+ for key in self.metric_key:
212
+ if key not in processed_metric:
213
+ processed_metric[key] = 0
214
+ return processed_metric
215
+
216
+ def main(args):
217
+ CapRes.sub_metric_key = args.sub_metric_key
218
+ all_res = AllResult(
219
+ args.paths,
220
+ args.base,
221
+ args.end_flag,
222
+ CapRes,
223
+ incl=args.incl,
224
+ excl=args.excl,
225
+ metric_key=['coco', 'indomain', 'neardomain', 'outdomain', 'overall', 'msrvtt', 'spotdiff', 'flickr30k'],
226
+ )
227
+ all_res.sorted_by(args.sort_by)
228
+ all_res.color_best()
229
+ all_res.print(delimiter='& ')
230
+
231
+ if __name__ == '__main__':
232
+ parser = argparse.ArgumentParser()
233
+ parser.add_argument('paths_', nargs='+', default=['./checkpoints/reproduce'], help='path of result files')
234
+ parser.add_argument('--paths', nargs='+', default=[], help='path of result files')
235
+ parser.add_argument('--base', nargs='+', default=['checkpoints/main/1.0-msrvtt/'], help='path of baseline files')
236
+ parser.add_argument('--end_flag', type=str, default='eval.json')
237
+ parser.add_argument('-e', '--excl', type=str, nargs='*', default=[])
238
+ parser.add_argument('-i', '--incl', type=str, nargs='*', default=[])
239
+ parser.add_argument('-s', '--sort_by', type=str, default='coco')
240
+ parser.add_argument('-m', '--sub_metric_key', type=str, default='CIDEr')
241
+ args = parser.parse_args()
242
+ args.paths += args.paths_
243
+ main(args)