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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
|