BonanDing commited on
Commit
9913a60
·
1 Parent(s): 199b3f1

Add DeMemWM image-space validation metrics

Browse files
algorithms/dememwm/df_video.py CHANGED
@@ -1156,6 +1156,34 @@ class DeMemWMMinecraft(DiffusionForcingBase):
1156
  latent_loss = xs_pred.new_tensor(0.0)
1157
 
1158
  self.log(f"{namespace}/latent_mse", latent_loss.detach())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1159
  return latent_loss
1160
 
1161
  def test_step(self, batch, batch_idx) -> STEP_OUTPUT:
 
1156
  latent_loss = xs_pred.new_tensor(0.0)
1157
 
1158
  self.log(f"{namespace}/latent_mse", latent_loss.detach())
1159
+ if eval_start < target_length:
1160
+ xs_pred_decode = self.decode(xs_pred[eval_start:target_length].to(target_poses.device))
1161
+ xs_decode = self.decode(xs[eval_start:target_length].to(target_poses.device))
1162
+
1163
+ if self.logger and self.log_video:
1164
+ log_video(
1165
+ xs_pred_decode,
1166
+ xs_decode,
1167
+ step=batch_idx,
1168
+ namespace=namespace + "_vis",
1169
+ context_frames=self.context_frames,
1170
+ logger=self.logger.experiment,
1171
+ save_local=self.save_local,
1172
+ local_save_dir=self.local_save_dir,
1173
+ )
1174
+
1175
+ if target_mask is None:
1176
+ self._update_metric_accumulators(xs_pred_decode, xs_decode)
1177
+ else:
1178
+ valid_mask = rearrange(
1179
+ target_mask[:, eval_start:target_length].to(device=xs_pred_decode.device),
1180
+ "b t -> t b",
1181
+ )
1182
+ if valid_mask.any():
1183
+ self._update_metric_accumulators(
1184
+ xs_pred_decode[valid_mask].unsqueeze(1),
1185
+ xs_decode[valid_mask].unsqueeze(1),
1186
+ )
1187
  return latent_loss
1188
 
1189
  def test_step(self, batch, batch_idx) -> STEP_OUTPUT:
tests/test_dememwm_latent_dataset.py CHANGED
@@ -538,6 +538,12 @@ class DeMemWMLatentDatasetTests(unittest.TestCase):
538
  self.diffusion_model = FakeDiffusion()
539
  self.logged = []
540
  self.horizons = []
 
 
 
 
 
 
541
 
542
  def _preprocess_batch(self, batch):
543
  return _preprocess_dememwm_latent_batch(batch)
@@ -553,7 +559,11 @@ class DeMemWMLatentDatasetTests(unittest.TestCase):
553
  raise AssertionError("latent dict validation must not VAE-encode inputs")
554
 
555
  def decode(self, xs):
556
- raise AssertionError("latent dict validation must not decode for the latent metric")
 
 
 
 
557
 
558
  def log(self, name, value):
559
  self.logged.append((name, value))
@@ -569,7 +579,14 @@ class DeMemWMLatentDatasetTests(unittest.TestCase):
569
  }
570
  harness = Harness()
571
 
572
- with mock.patch.object(df_video, "select_memory_indices", side_effect=fake_select_memory_indices):
 
 
 
 
 
 
 
573
  loss = DeMemWMMinecraft.validation_step(harness, batch, 0, namespace="test")
574
  calls = harness.diffusion_model.calls
575
  required_kwargs = {"reference_length", "frame_memory_segments", "frame_memory_masks", "frame_memory_pose", "frame_idx", "image_hw"}
@@ -595,6 +612,17 @@ class DeMemWMLatentDatasetTests(unittest.TestCase):
595
  self.assertEqual(calls[0]["kwargs"]["frame_memory_masks"]["revisit"].tolist(), [[False]])
596
  self.assertEqual(calls[2]["kwargs"]["frame_memory_masks"]["revisit"].tolist(), [[True]])
597
  self.assertAlmostEqual(float(loss), 1.0 / 3.0)
 
 
 
 
 
 
 
 
 
 
 
598
 
599
  def test_interactive_generation_fails_until_packed_memory_path_exists(self):
600
  from algorithms.dememwm.df_video import DeMemWMMinecraft
 
538
  self.diffusion_model = FakeDiffusion()
539
  self.logged = []
540
  self.horizons = []
541
+ self.decoded_inputs = []
542
+ self.metric_updates = []
543
+ self.logger = type("Logger", (), {"experiment": object()})()
544
+ self.log_video = True
545
+ self.save_local = False
546
+ self.local_save_dir = None
547
 
548
  def _preprocess_batch(self, batch):
549
  return _preprocess_dememwm_latent_batch(batch)
 
559
  raise AssertionError("latent dict validation must not VAE-encode inputs")
560
 
561
  def decode(self, xs):
562
+ self.decoded_inputs.append(xs.detach().clone())
563
+ return xs + 10.0
564
+
565
+ def _update_metric_accumulators(self, xs_pred, xs_gt):
566
+ self.metric_updates.append((xs_pred.detach().clone(), xs_gt.detach().clone()))
567
 
568
  def log(self, name, value):
569
  self.logged.append((name, value))
 
579
  }
580
  harness = Harness()
581
 
582
+ video_calls = []
583
+
584
+ def fake_log_video(*args, **kwargs):
585
+ video_calls.append((args, kwargs))
586
+
587
+ with mock.patch.object(
588
+ df_video, "select_memory_indices", side_effect=fake_select_memory_indices
589
+ ), mock.patch.object(df_video, "log_video", side_effect=fake_log_video):
590
  loss = DeMemWMMinecraft.validation_step(harness, batch, 0, namespace="test")
591
  calls = harness.diffusion_model.calls
592
  required_kwargs = {"reference_length", "frame_memory_segments", "frame_memory_masks", "frame_memory_pose", "frame_idx", "image_hw"}
 
612
  self.assertEqual(calls[0]["kwargs"]["frame_memory_masks"]["revisit"].tolist(), [[False]])
613
  self.assertEqual(calls[2]["kwargs"]["frame_memory_masks"]["revisit"].tolist(), [[True]])
614
  self.assertAlmostEqual(float(loss), 1.0 / 3.0)
615
+ self.assertEqual([name for name, _ in harness.logged], ["test/latent_mse"])
616
+ self.assertEqual(len(harness.decoded_inputs), 2)
617
+ self.assertEqual(harness.decoded_inputs[0][:, 0, 0, 0, 0].tolist(), [2.0, 2.0, 4.0])
618
+ self.assertEqual(harness.decoded_inputs[1][:, 0, 0, 0, 0].tolist(), [2.0, 3.0, 4.0])
619
+ self.assertEqual(len(harness.metric_updates), 1)
620
+ metric_pred, metric_gt = harness.metric_updates[0]
621
+ self.assertEqual(metric_pred[:, 0, 0, 0, 0].tolist(), [12.0, 12.0, 14.0])
622
+ self.assertEqual(metric_gt[:, 0, 0, 0, 0].tolist(), [12.0, 13.0, 14.0])
623
+ self.assertEqual(len(video_calls), 1)
624
+ self.assertEqual(video_calls[0][1]["namespace"], "test_vis")
625
+ self.assertEqual(video_calls[0][1]["step"], 0)
626
 
627
  def test_interactive_generation_fails_until_packed_memory_path_exists(self):
628
  from algorithms.dememwm.df_video import DeMemWMMinecraft