144 lines
5.0 KiB
Python
144 lines
5.0 KiB
Python
|
# Copyright (c) OpenMMLab. All rights reserved.
|
||
|
import argparse
|
||
|
import datetime
|
||
|
import json
|
||
|
import os
|
||
|
import os.path as osp
|
||
|
from collections import OrderedDict
|
||
|
|
||
|
from utils import load_config
|
||
|
|
||
|
# automatically collect all the results
|
||
|
|
||
|
# The structure of the directory:
|
||
|
# ├── work-dir
|
||
|
# │ ├── config_1
|
||
|
# │ │ ├── time1.log.json
|
||
|
# │ │ ├── time2.log.json
|
||
|
# │ │ ├── time3.log.json
|
||
|
# │ │ ├── time4.log.json
|
||
|
# │ ├── config_2
|
||
|
# │ │ ├── time5.log.json
|
||
|
# │ │ ├── time6.log.json
|
||
|
# │ │ ├── time7.log.json
|
||
|
# │ │ ├── time8.log.json
|
||
|
|
||
|
|
||
|
def parse_args():
|
||
|
parser = argparse.ArgumentParser(description='extract info from log.json')
|
||
|
parser.add_argument('config_dir')
|
||
|
args = parser.parse_args()
|
||
|
return args
|
||
|
|
||
|
|
||
|
def has_keyword(name: str, keywords: list):
|
||
|
for a_keyword in keywords:
|
||
|
if a_keyword in name:
|
||
|
return True
|
||
|
return False
|
||
|
|
||
|
|
||
|
def main():
|
||
|
args = parse_args()
|
||
|
cfg = load_config(args.config_dir)
|
||
|
work_dir = cfg['work_dir']
|
||
|
metric = cfg['metric']
|
||
|
log_items = cfg.get('log_items', [])
|
||
|
ignore_keywords = cfg.get('ignore_keywords', [])
|
||
|
other_info_keys = cfg.get('other_info_keys', [])
|
||
|
markdown_file = cfg.get('markdown_file', None)
|
||
|
json_file = cfg.get('json_file', None)
|
||
|
|
||
|
if json_file and osp.split(json_file)[0] != '':
|
||
|
os.makedirs(osp.split(json_file)[0], exist_ok=True)
|
||
|
if markdown_file and osp.split(markdown_file)[0] != '':
|
||
|
os.makedirs(osp.split(markdown_file)[0], exist_ok=True)
|
||
|
|
||
|
assert not (log_items and ignore_keywords), \
|
||
|
'log_items and ignore_keywords cannot be specified at the same time'
|
||
|
assert metric not in other_info_keys, \
|
||
|
'other_info_keys should not contain metric'
|
||
|
|
||
|
if ignore_keywords and isinstance(ignore_keywords, str):
|
||
|
ignore_keywords = [ignore_keywords]
|
||
|
if other_info_keys and isinstance(other_info_keys, str):
|
||
|
other_info_keys = [other_info_keys]
|
||
|
if log_items and isinstance(log_items, str):
|
||
|
log_items = [log_items]
|
||
|
|
||
|
if not log_items:
|
||
|
log_items = [
|
||
|
item for item in sorted(os.listdir(work_dir))
|
||
|
if not has_keyword(item, ignore_keywords)
|
||
|
]
|
||
|
|
||
|
experiment_info_list = []
|
||
|
for config_dir in log_items:
|
||
|
preceding_path = os.path.join(work_dir, config_dir)
|
||
|
log_list = [
|
||
|
item for item in os.listdir(preceding_path)
|
||
|
if item.endswith('.log.json')
|
||
|
]
|
||
|
log_list = sorted(
|
||
|
log_list,
|
||
|
key=lambda time_str: datetime.datetime.strptime(
|
||
|
time_str, '%Y%m%d_%H%M%S.log.json'))
|
||
|
val_list = []
|
||
|
last_iter = 0
|
||
|
for log_name in log_list:
|
||
|
with open(os.path.join(preceding_path, log_name), 'r') as f:
|
||
|
# ignore the info line
|
||
|
f.readline()
|
||
|
all_lines = f.readlines()
|
||
|
val_list.extend([
|
||
|
json.loads(line) for line in all_lines
|
||
|
if json.loads(line)['mode'] == 'val'
|
||
|
])
|
||
|
for index in range(len(all_lines) - 1, -1, -1):
|
||
|
line_dict = json.loads(all_lines[index])
|
||
|
if line_dict['mode'] == 'train':
|
||
|
last_iter = max(last_iter, line_dict['iter'])
|
||
|
break
|
||
|
|
||
|
new_log_dict = dict(
|
||
|
method=config_dir, metric_used=metric, last_iter=last_iter)
|
||
|
for index, log in enumerate(val_list, 1):
|
||
|
new_ordered_dict = OrderedDict()
|
||
|
new_ordered_dict['eval_index'] = index
|
||
|
new_ordered_dict[metric] = log[metric]
|
||
|
for key in other_info_keys:
|
||
|
if key in log:
|
||
|
new_ordered_dict[key] = log[key]
|
||
|
val_list[index - 1] = new_ordered_dict
|
||
|
|
||
|
assert len(val_list) >= 1, \
|
||
|
f"work dir {config_dir} doesn't contain any evaluation."
|
||
|
new_log_dict['last eval'] = val_list[-1]
|
||
|
new_log_dict['best eval'] = max(val_list, key=lambda x: x[metric])
|
||
|
experiment_info_list.append(new_log_dict)
|
||
|
print(f'{config_dir} is processed')
|
||
|
|
||
|
if json_file:
|
||
|
with open(json_file, 'w') as f:
|
||
|
json.dump(experiment_info_list, f, indent=4)
|
||
|
|
||
|
if markdown_file:
|
||
|
lines_to_write = []
|
||
|
for index, log in enumerate(experiment_info_list, 1):
|
||
|
lines_to_write.append(
|
||
|
f"|{index}|{log['method']}|{log['best eval'][metric]}"
|
||
|
f"|{log['best eval']['eval_index']}|"
|
||
|
f"{log['last eval'][metric]}|"
|
||
|
f"{log['last eval']['eval_index']}|{log['last_iter']}|\n")
|
||
|
with open(markdown_file, 'w') as f:
|
||
|
f.write(f'|exp_num|method|{metric} best|best index|'
|
||
|
f'{metric} last|last index|last iter num|\n')
|
||
|
f.write('|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n')
|
||
|
f.writelines(lines_to_write)
|
||
|
|
||
|
print('processed successfully')
|
||
|
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
main()
|