Download scripts/eval_taic.py from SCU-VIP-Lab/FlexICM: direct link, hf CLI and curl.
- Browser
- Download file 8.9 kB
-
https://huggingface.co/SCU-VIP-Lab/FlexICM/resolve/19051ddde5ff4d3bb2d65fa930bb0af2ade29df1/scripts/eval_taic.py
- Command line
-
hf download hf://SCU-VIP-Lab/FlexICM@19051ddde5ff4d3bb2d65fa930bb0af2ade29df1/scripts/eval_taic.py
-
curl -L -o eval_taic.py https://huggingface.co/SCU-VIP-Lab/FlexICM/resolve/19051ddde5ff4d3bb2d65fa930bb0af2ade29df1/scripts/eval_taic.py
8.9 kB
| #!/usr/bin/env python3 | |
| """Test / eval for TAIC: codec stats + optional full task-network metrics. | |
| Codec-only (default): | |
| bpp, feature distortion D, loss; optional --actual-bpp | |
| With task metrics (--with-metrics): | |
| also load official task-network config/checkpoint, run truncated task net from h, | |
| report mAP-bbox / mAP-mask / mIoU / PQ / mAP-OKS (task-dependent). | |
| Examples: | |
| python scripts/eval_taic.py -c configs/eval/taic_detection.yaml | |
| python scripts/eval_taic.py -c configs/eval/taic_detection.yaml --with-metrics | |
| python scripts/eval_taic.py -c configs/eval/taic_detection.yaml --with-metrics --max-batches 50 | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import json | |
| import os | |
| import sys | |
| from datetime import datetime | |
| import torch | |
| from torch.utils.data import DataLoader | |
| REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) | |
| if REPO_ROOT not in sys.path: | |
| sys.path.insert(0, REPO_ROOT) | |
| from flexicm.data import ( | |
| COCOImageDataset, | |
| COCOWholeBodyImageDataset, | |
| ImageFolderDataset, | |
| build_test_transform, | |
| ) | |
| from flexicm.data.coco_eval import COCOEvalDataset, TASK_ANN_FILES, coco_eval_collate | |
| from flexicm.models import TAIC | |
| from flexicm.tasks import TASK_META, build_teacher | |
| from flexicm.tasks.losses import TAICCriterion | |
| from flexicm.tasks.metric_eval import run_task_metric_eval | |
| from flexicm.tasks.metric_runners import ( | |
| DEFAULT_TASK_NET_CKPTS, | |
| DEFAULT_TASK_NET_CONFIGS, | |
| build_metric_runner, | |
| ) | |
| from flexicm.utils.codec_test import resolve_ckpt, test_taic_loader | |
| from flexicm.utils.train_utils import load_checkpoint_dict, load_yaml_config, set_seed | |
| def parse_args(argv): | |
| parser = argparse.ArgumentParser("Test FlexICM TAIC (codec + optional task metrics)") | |
| parser.add_argument("-c", "--config", required=True, help="configs/eval/taic_*.yaml") | |
| given, remaining = parser.parse_known_args(argv) | |
| cfg_path = given.config if os.path.isabs(given.config) else os.path.join(REPO_ROOT, given.config) | |
| cfg = load_yaml_config(cfg_path) | |
| # -c already consumed by the first parse; keep it as a default for the second pass | |
| parser.set_defaults(config=cfg_path, **cfg) | |
| for action in parser._actions: | |
| if "--config" in action.option_strings: | |
| action.required = False | |
| break | |
| parser.add_argument("--actual-bpp", action="store_true") | |
| parser.add_argument("--with-metrics", action="store_true", help="Run full task-network metrics") | |
| parser.add_argument("--max-batches", type=int, default=None) | |
| parser.add_argument("--split", type=str, default=None) | |
| parser.add_argument( | |
| "--eval-size", | |
| type=int, | |
| default=cfg.get("eval_size", None), | |
| help="If set (e.g. 256), resize eval images to eval_size×eval_size", | |
| ) | |
| args = parser.parse_args(remaining) | |
| args.config = cfg_path | |
| if "--actual-bpp" in argv: | |
| args.actual_bpp = True | |
| if "--with-metrics" in argv: | |
| args.with_metrics = True | |
| return args | |
| def build_codec_loader(args, device): | |
| split = args.split or getattr(args, "split", None) or "val2017" | |
| eval_size = getattr(args, "eval_size", None) | |
| tf = build_test_transform(eval_size=eval_size) | |
| root = args.dataset_path | |
| split_dir = os.path.join(root, split) | |
| if os.path.isdir(split_dir): | |
| if args.task == "pose": | |
| dataset = COCOWholeBodyImageDataset(root, split, tf) | |
| else: | |
| dataset = COCOImageDataset(root, split, tf) | |
| else: | |
| dataset = ImageFolderDataset(root, tf) | |
| return DataLoader( | |
| dataset, | |
| batch_size=getattr(args, "test_batch_size", 1), | |
| shuffle=False, | |
| num_workers=getattr(args, "num_workers", 4), | |
| pin_memory=(device == "cuda"), | |
| ) | |
| def build_metric_loader(args, device): | |
| split = args.split or getattr(args, "split", None) or "val2017" | |
| ann_rel = getattr(args, "ann_file", None) or TASK_ANN_FILES.get(args.task) | |
| if ann_rel is None: | |
| raise ValueError(f"No ann_file for task={args.task}") | |
| ann_file = ann_rel if os.path.isabs(ann_rel) else os.path.join(args.dataset_path, ann_rel) | |
| eval_size = getattr(args, "eval_size", None) | |
| dataset = COCOEvalDataset( | |
| args.dataset_path, | |
| ann_file=ann_file, | |
| image_prefix=split, | |
| transform=build_test_transform(eval_size=eval_size), | |
| ) | |
| loader = DataLoader( | |
| dataset, | |
| batch_size=1, | |
| shuffle=False, | |
| num_workers=getattr(args, "num_workers", 4), | |
| pin_memory=(device == "cuda"), | |
| collate_fn=coco_eval_collate, | |
| ) | |
| return loader, ann_file | |
| def main(argv): | |
| args = parse_args(argv) | |
| set_seed(getattr(args, "seed", 42)) | |
| os.environ["CUDA_VISIBLE_DEVICES"] = str(getattr(args, "gpu_id", 0)) | |
| device = "cuda" if getattr(args, "cuda", True) and torch.cuda.is_available() else "cpu" | |
| task = args.task | |
| meta = TASK_META[task] | |
| out_channels = getattr(args, "out_channels", meta["out_channels"]) | |
| align_mode = getattr(args, "align_mode", meta["align_mode"]) | |
| lmbda = getattr(args, "lmbda", 0.0035) | |
| ckpt = resolve_ckpt(args.checkpoint, REPO_ROOT, label="TAIC checkpoint") | |
| print(f"Loading TAIC checkpoint: {ckpt}") | |
| net = TAIC(N=128, M=192, out_channels=out_channels).to(device) | |
| state, _ = load_checkpoint_dict(ckpt, map_location=device) | |
| missing = net.load_state_dict(state, strict=False) | |
| print(f"load_state_dict: missing={len(missing.missing_keys)} unexpected={len(missing.unexpected_keys)}") | |
| net.eval() | |
| # ---- codec test ---- | |
| teacher = build_teacher( | |
| task, | |
| pretrained_backbone=getattr(args, "pretrained_backbone", True), | |
| use_official_teacher=getattr(args, "use_official_teacher", True), | |
| task_config=getattr(args, "task_config", None), | |
| task_checkpoint=getattr(args, "task_checkpoint", None), | |
| device=device, | |
| ) | |
| teacher = teacher.to(device).eval() | |
| criterion = TAICCriterion(lmbda=lmbda, align_mode=align_mode) | |
| codec_loader = build_codec_loader(args, device) | |
| eval_size = getattr(args, "eval_size", None) | |
| size_msg = f"{eval_size}x{eval_size}" if eval_size else "original" | |
| print(f"[codec] test set size: {len(codec_loader.dataset)} device={device} task={task} input={size_msg}") | |
| codec_result = test_taic_loader( | |
| net, | |
| teacher, | |
| codec_loader, | |
| criterion, | |
| device, | |
| align_divisor=256, | |
| run_actual_bpp=bool(getattr(args, "actual_bpp", False)), | |
| max_batches=args.max_batches, | |
| ) | |
| print("==== TAIC codec test summary ====") | |
| for k, v in codec_result.items(): | |
| print(f" {k}: {v:.6f}" if isinstance(v, float) else f" {k}: {v}") | |
| payload = { | |
| "task": task, | |
| "checkpoint": ckpt, | |
| "config": args.config, | |
| "codec_result": codec_result, | |
| } | |
| # ---- optional task metrics ---- | |
| if getattr(args, "with_metrics", False): | |
| task_cfg = getattr(args, "task_config", None) or DEFAULT_TASK_NET_CONFIGS[task] | |
| task_ckpt = getattr(args, "task_checkpoint", None) or DEFAULT_TASK_NET_CKPTS[task] | |
| if not os.path.isabs(task_cfg): | |
| task_cfg = os.path.join(REPO_ROOT, task_cfg) | |
| task_ckpt = resolve_ckpt(task_ckpt, REPO_ROOT, label=f"{task} task-network checkpoint") | |
| print(f"[metric] loading task network:\n config={task_cfg}\n ckpt={task_ckpt}") | |
| runner = build_metric_runner(task, device=device) | |
| runner.load(task_cfg, task_ckpt) | |
| metric_loader, ann_file = build_metric_loader(args, device) | |
| print(f"[metric] COCO eval images: {len(metric_loader.dataset)} ann={ann_file}") | |
| metrics = run_task_metric_eval( | |
| net, | |
| runner, | |
| metric_loader, | |
| device, | |
| ann_file=ann_file, | |
| use_condition=False, | |
| base_codec=None, | |
| max_batches=args.max_batches, | |
| finalize_kwargs={ | |
| "gt_folder": getattr(args, "panoptic_gt_folder", None), | |
| "pred_folder": getattr(args, "panoptic_pred_folder", None), | |
| "num_classes": getattr(args, "num_classes", 133), | |
| }, | |
| ) | |
| print("==== TAIC task metric summary ====") | |
| for k, v in metrics.items(): | |
| print(f" {k}: {v}") | |
| payload["task_config"] = task_cfg | |
| payload["task_checkpoint"] = task_ckpt | |
| payload["task_metrics"] = metrics | |
| out_dir = getattr(args, "result_dir", None) or os.path.join( | |
| REPO_ROOT, "logs", "eval_taic", task, str(getattr(args, "quality_level", 1)) | |
| ) | |
| os.makedirs(out_dir, exist_ok=True) | |
| out_json = os.path.join(out_dir, f"eval_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json") | |
| with open(out_json, "w") as f: | |
| json.dump(payload, f, indent=2, default=str) | |
| print(f"Wrote {out_json}") | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main(sys.argv[1:])) | |