tianma commited on
Commit
3482727
·
1 Parent(s): bed503a

Support optional fixed eval_size and update detection configs.

Browse files

Add Resize(eval_size) for TAIC eval with correct COCO box scale_factor; sync README and local detection train/eval settings.

README.md CHANGED
@@ -363,11 +363,7 @@ For C-TAIC, reported `bpp` is **extension-layer only** (base-layer rate is exclu
363
 
364
  ```bash
365
  python scripts/eval_taic.py -c configs/eval/taic_detection.yaml
366
- python scripts/eval_taic.py -c configs/eval/taic_detection.yaml --actual-bpp
367
- python scripts/eval_taic.py -c configs/eval/taic_detection.yaml --max-batches 10
368
-
369
  python scripts/eval_ctaic.py -c configs/eval/ctaic_s1.yaml
370
- python scripts/eval_ctaic.py -c configs/eval/ctaic_s1.yaml --no-condition
371
  ```
372
 
373
  ---
@@ -431,15 +427,15 @@ ann_file: "annotations/instances_val2017.json"
431
  ### Run codec + metrics
432
 
433
  ```bash
434
- python scripts/eval_taic.py -c configs/eval/taic_detection.yaml --with-metrics
435
- python scripts/eval_taic.py -c configs/eval/taic_instance.yaml --with-metrics
436
- python scripts/eval_taic.py -c configs/eval/taic_semantic.yaml --with-metrics
437
- python scripts/eval_taic.py -c configs/eval/taic_panoptic.yaml --with-metrics
438
- python scripts/eval_taic.py -c configs/eval/taic_pose.yaml --with-metrics
439
-
440
- python scripts/eval_ctaic.py -c configs/eval/ctaic_s1.yaml --with-metrics
441
- python scripts/eval_ctaic.py -c configs/eval/ctaic_s2.yaml --with-metrics
442
- python scripts/eval_ctaic.py -c configs/eval/ctaic_s3.yaml --with-metrics
443
  ```
444
 
445
  JSON results (codec + task metrics) are written under `logs/eval_taic/` or `logs/eval_ctaic/`.
 
363
 
364
  ```bash
365
  python scripts/eval_taic.py -c configs/eval/taic_detection.yaml
 
 
 
366
  python scripts/eval_ctaic.py -c configs/eval/ctaic_s1.yaml
 
367
  ```
368
 
369
  ---
 
427
  ### Run codec + metrics
428
 
429
  ```bash
430
+ python scripts/eval_taic.py -c configs/eval/taic_detection.yaml
431
+ python scripts/eval_taic.py -c configs/eval/taic_instance.yaml
432
+ python scripts/eval_taic.py -c configs/eval/taic_semantic.yaml
433
+ python scripts/eval_taic.py -c configs/eval/taic_panoptic.yaml
434
+ python scripts/eval_taic.py -c configs/eval/taic_pose.yaml
435
+
436
+ python scripts/eval_ctaic.py -c configs/eval/ctaic_s1.yaml
437
+ python scripts/eval_ctaic.py -c configs/eval/ctaic_s2.yaml
438
+ python scripts/eval_ctaic.py -c configs/eval/ctaic_s3.yaml
439
  ```
440
 
441
  JSON results (codec + task metrics) are written under `logs/eval_taic/` or `logs/eval_ctaic/`.
configs/eval/taic_detection.yaml CHANGED
@@ -5,8 +5,10 @@ split: "val2017"
5
  ann_file: "annotations/instances_val2017.json"
6
  quality_level: 1
7
  lmbda: 0.0035
8
- checkpoint: "./logs/taic_detection/1/checkpoint_0.1040.pth.tar"
9
  base_codec: "./checkpoints/base_codec/base_codec_1.pth.tar"
 
 
10
  # official task network (required for --with-metrics)
11
  gpu_id: 0
12
  cuda: true
 
5
  ann_file: "annotations/instances_val2017.json"
6
  quality_level: 1
7
  lmbda: 0.0035
8
+ checkpoint: "./logs/taic_detection/1/checkpoint_0.1334.pth.tar"
9
  base_codec: "./checkpoints/base_codec/base_codec_1.pth.tar"
10
+ # null = original COCO resolution; 256 = force 256x256 (aspect stretched)
11
+ eval_size: null
12
  # official task network (required for --with-metrics)
13
  gpu_id: 0
14
  cuda: true
configs/taic/detection.yaml CHANGED
@@ -4,18 +4,18 @@ exp_name: "taic_detection"
4
  task: "detection"
5
  dataset_path: "/data/Dataset/coco2017"
6
  base_codec: "./checkpoints/base_codec/base_codec_1.pth.tar" # quality matches lmbda mapping
7
- checkpoint: null # "./logs/taic_detection/1/checkpoint_60.pth.tar"
8
  freeze_base_codec: false # false = fine-tune the entire TIC + SFMA + Task Connector
9
  epochs: 999
10
  learning_rate: 1.0e-4
11
  gpu_id: 0
12
  quality_level: 1
13
- # paper lambda set: {0.0035, 0.0067, 0.0130, 0.0250}
14
  lmbda: 0.2050
15
  num_workers: 8
16
- batch_size: 32
17
  test_batch_size: 1
18
- patch_size: 256
19
  cuda: true
20
  save: true
21
  seed: 42
 
4
  task: "detection"
5
  dataset_path: "/data/Dataset/coco2017"
6
  base_codec: "./checkpoints/base_codec/base_codec_1.pth.tar" # quality matches lmbda mapping
7
+ checkpoint: "/data/Dataset/FlexICM/logs/taic_detection/1/checkpoint_best_loss.pth.tar"
8
  freeze_base_codec: false # false = fine-tune the entire TIC + SFMA + Task Connector
9
  epochs: 999
10
  learning_rate: 1.0e-4
11
  gpu_id: 0
12
  quality_level: 1
13
+ # paper lambda set: {0.0035, 0.0067, 0.0130, 0.0250, 0.2050}
14
  lmbda: 0.2050
15
  num_workers: 8
16
+ batch_size: 8
17
  test_batch_size: 1
18
+ patch_size: 512
19
  cuda: true
20
  save: true
21
  seed: 42
flexicm/data/datasets.py CHANGED
@@ -28,8 +28,16 @@ def build_train_transform(patch_size: int = 256) -> Callable:
28
  )
29
 
30
 
31
- def build_test_transform() -> Callable:
32
- return transforms.ToTensor()
 
 
 
 
 
 
 
 
33
 
34
 
35
  class ImageFolderDataset(Dataset):
 
28
  )
29
 
30
 
31
+ def build_test_transform(eval_size: Optional[int] = None) -> Callable:
32
+ """Eval preprocess. If ``eval_size`` is set (e.g. 256), force HxW = size×size."""
33
+ if eval_size is None:
34
+ return transforms.ToTensor()
35
+ return transforms.Compose(
36
+ [
37
+ transforms.Resize((int(eval_size), int(eval_size))),
38
+ transforms.ToTensor(),
39
+ ]
40
+ )
41
 
42
 
43
  class ImageFolderDataset(Dataset):
flexicm/tasks/metric_eval.py CHANGED
@@ -55,6 +55,12 @@ def run_task_metric_eval(
55
  for image, meta in zip(images_list, metas):
56
  image = image.unsqueeze(0).to(device)
57
  _, _, H, W = image.shape
 
 
 
 
 
 
58
  x, _ = pad_for_codec(image, divisor=align_divisor, device=device)
59
 
60
  y_b = None
@@ -77,6 +83,7 @@ def run_task_metric_eval(
77
  meta = dict(meta)
78
  meta["pad_height"] = int(x.shape[-2])
79
  meta["pad_width"] = int(x.shape[-1])
 
80
  pred = runner.predict_from_h(h, meta)
81
  predictions.append(pred)
82
 
 
55
  for image, meta in zip(images_list, metas):
56
  image = image.unsqueeze(0).to(device)
57
  _, _, H, W = image.shape
58
+ ori_h = int(meta["height"])
59
+ ori_w = int(meta["width"])
60
+ # If the image was resized (e.g. eval_size=256), boxes must be
61
+ # mapped back with the correct scale_factor for COCO mAP.
62
+ scale_w = float(W) / float(ori_w) if ori_w > 0 else 1.0
63
+ scale_h = float(H) / float(ori_h) if ori_h > 0 else 1.0
64
  x, _ = pad_for_codec(image, divisor=align_divisor, device=device)
65
 
66
  y_b = None
 
83
  meta = dict(meta)
84
  meta["pad_height"] = int(x.shape[-2])
85
  meta["pad_width"] = int(x.shape[-1])
86
+ meta["scale_factor"] = (scale_w, scale_h)
87
  pred = runner.predict_from_h(h, meta)
88
  predictions.append(pred)
89
 
flexicm/tasks/metric_runners.py CHANGED
@@ -204,6 +204,11 @@ class DetectionMetricRunner(TaskMetricRunner):
204
  # FPN strides line up; boxes are rescaled back to ori_shape.
205
  pad_h = int(img_meta.get("pad_height", h.shape[-2] * 4))
206
  pad_w = int(img_meta.get("pad_width", h.shape[-1] * 4))
 
 
 
 
 
207
  try:
208
  # MMDet 3.x style
209
  from mmdet.structures import DetDataSample
@@ -214,7 +219,7 @@ class DetectionMetricRunner(TaskMetricRunner):
214
  img_shape=(pad_h, pad_w),
215
  ori_shape=(ori_h, ori_w),
216
  pad_shape=(pad_h, pad_w),
217
- scale_factor=(1.0, 1.0),
218
  img_id=img_meta.get("image_id"),
219
  )
220
  )
@@ -241,7 +246,7 @@ class DetectionMetricRunner(TaskMetricRunner):
241
  img_shape=(pad_h, pad_w, 3),
242
  ori_shape=(ori_h, ori_w, 3),
243
  pad_shape=(pad_h, pad_w, 3),
244
- scale_factor=1.0,
245
  flip=False,
246
  )
247
  ]
 
204
  # FPN strides line up; boxes are rescaled back to ori_shape.
205
  pad_h = int(img_meta.get("pad_height", h.shape[-2] * 4))
206
  pad_w = int(img_meta.get("pad_width", h.shape[-1] * 4))
207
+ sf = img_meta.get("scale_factor", (1.0, 1.0))
208
+ if isinstance(sf, (int, float)):
209
+ scale_factor = (float(sf), float(sf))
210
+ else:
211
+ scale_factor = (float(sf[0]), float(sf[1]))
212
  try:
213
  # MMDet 3.x style
214
  from mmdet.structures import DetDataSample
 
219
  img_shape=(pad_h, pad_w),
220
  ori_shape=(ori_h, ori_w),
221
  pad_shape=(pad_h, pad_w),
222
+ scale_factor=scale_factor,
223
  img_id=img_meta.get("image_id"),
224
  )
225
  )
 
246
  img_shape=(pad_h, pad_w, 3),
247
  ori_shape=(ori_h, ori_w, 3),
248
  pad_shape=(pad_h, pad_w, 3),
249
+ scale_factor=scale_factor,
250
  flip=False,
251
  )
252
  ]
scripts/eval_taic.py CHANGED
@@ -65,6 +65,12 @@ def parse_args(argv):
65
  parser.add_argument("--with-metrics", action="store_true", help="Run full task-network metrics")
66
  parser.add_argument("--max-batches", type=int, default=None)
67
  parser.add_argument("--split", type=str, default=None)
 
 
 
 
 
 
68
  args = parser.parse_args(remaining)
69
  args.config = cfg_path
70
  if "--actual-bpp" in argv:
@@ -76,7 +82,8 @@ def parse_args(argv):
76
 
77
  def build_codec_loader(args, device):
78
  split = args.split or getattr(args, "split", None) or "val2017"
79
- tf = build_test_transform()
 
80
  root = args.dataset_path
81
  split_dir = os.path.join(root, split)
82
  if os.path.isdir(split_dir):
@@ -101,11 +108,12 @@ def build_metric_loader(args, device):
101
  if ann_rel is None:
102
  raise ValueError(f"No ann_file for task={args.task}")
103
  ann_file = ann_rel if os.path.isabs(ann_rel) else os.path.join(args.dataset_path, ann_rel)
 
104
  dataset = COCOEvalDataset(
105
  args.dataset_path,
106
  ann_file=ann_file,
107
  image_prefix=split,
108
- transform=build_test_transform(),
109
  )
110
  loader = DataLoader(
111
  dataset,
@@ -152,7 +160,9 @@ def main(argv):
152
  teacher = teacher.to(device).eval()
153
  criterion = TAICCriterion(lmbda=lmbda, align_mode=align_mode)
154
  codec_loader = build_codec_loader(args, device)
155
- print(f"[codec] test set size: {len(codec_loader.dataset)} device={device} task={task}")
 
 
156
 
157
  codec_result = test_taic_loader(
158
  net,
 
65
  parser.add_argument("--with-metrics", action="store_true", help="Run full task-network metrics")
66
  parser.add_argument("--max-batches", type=int, default=None)
67
  parser.add_argument("--split", type=str, default=None)
68
+ parser.add_argument(
69
+ "--eval-size",
70
+ type=int,
71
+ default=cfg.get("eval_size", None),
72
+ help="If set (e.g. 256), resize eval images to eval_size×eval_size",
73
+ )
74
  args = parser.parse_args(remaining)
75
  args.config = cfg_path
76
  if "--actual-bpp" in argv:
 
82
 
83
  def build_codec_loader(args, device):
84
  split = args.split or getattr(args, "split", None) or "val2017"
85
+ eval_size = getattr(args, "eval_size", None)
86
+ tf = build_test_transform(eval_size=eval_size)
87
  root = args.dataset_path
88
  split_dir = os.path.join(root, split)
89
  if os.path.isdir(split_dir):
 
108
  if ann_rel is None:
109
  raise ValueError(f"No ann_file for task={args.task}")
110
  ann_file = ann_rel if os.path.isabs(ann_rel) else os.path.join(args.dataset_path, ann_rel)
111
+ eval_size = getattr(args, "eval_size", None)
112
  dataset = COCOEvalDataset(
113
  args.dataset_path,
114
  ann_file=ann_file,
115
  image_prefix=split,
116
+ transform=build_test_transform(eval_size=eval_size),
117
  )
118
  loader = DataLoader(
119
  dataset,
 
160
  teacher = teacher.to(device).eval()
161
  criterion = TAICCriterion(lmbda=lmbda, align_mode=align_mode)
162
  codec_loader = build_codec_loader(args, device)
163
+ eval_size = getattr(args, "eval_size", None)
164
+ size_msg = f"{eval_size}x{eval_size}" if eval_size else "original"
165
+ print(f"[codec] test set size: {len(codec_loader.dataset)} device={device} task={task} input={size_msg}")
166
 
167
  codec_result = test_taic_loader(
168
  net,
scripts/train_taic.py CHANGED
@@ -210,7 +210,7 @@ def main(argv):
210
  for epoch in range(args.epochs):
211
  logging.info(f"===== Epoch {epoch}/{args.epochs} =====")
212
  train_stats = train_one_epoch(net, teacher, train_loader, optimizer, criterion, device)
213
- if epoch % 10 == 0:
214
  val_stats = validate(net, teacher, val_loader, criterion, device)
215
  logging.info(f"train={train_stats} val={val_stats}")
216
  is_best = val_stats["loss"] < best
 
210
  for epoch in range(args.epochs):
211
  logging.info(f"===== Epoch {epoch}/{args.epochs} =====")
212
  train_stats = train_one_epoch(net, teacher, train_loader, optimizer, criterion, device)
213
+ if epoch % 2 == 0:
214
  val_stats = validate(net, teacher, val_loader, criterion, device)
215
  logging.info(f"train={train_stats} val={val_stats}")
216
  is_best = val_stats["loss"] < best