BonanDing commited on
Commit
f10b281
·
1 Parent(s): f53385e

Restore revisit local context exclusion

Browse files
datasets/video/memory_selection.py CHANGED
@@ -32,6 +32,17 @@ def _memory_candidate_frames(num_frames, target_positions, cfg, split, min_candi
32
  return np.arange(min_candidate_frame, stop, dtype=np.int64)
33
 
34
 
 
 
 
 
 
 
 
 
 
 
 
35
  def _as_pose_array(poses) -> np.ndarray:
36
  poses = np.asarray(poses, dtype=np.float32)
37
  if poses.ndim != 2 or poses.shape[1] < 5:
@@ -795,6 +806,10 @@ def _select_revisit(
795
  if len(candidates) == 0:
796
  return np.empty((0,), dtype=np.int64)
797
 
 
 
 
 
798
  if len(excluded) > 0:
799
  candidates = candidates[~np.isin(candidates, excluded)]
800
  if len(candidates) == 0:
@@ -828,7 +843,7 @@ def select_memory_indices(
828
  anchor_candidate_stop=None,
829
  dynamic_stream=None,
830
  ):
831
- """Select causal memory indices and masks for [anchor][dynamic][revisit]."""
832
 
833
  poses = _as_pose_array(poses)
834
  target_positions = np.asarray(target_positions, dtype=np.int64)
 
32
  return np.arange(min_candidate_frame, stop, dtype=np.int64)
33
 
34
 
35
+ def _exclude_revisit_local_context(candidates: np.ndarray, target_positions: np.ndarray, cfg) -> np.ndarray:
36
+ exclusion = max(0, int(cfg_get(cfg, "local_context_exclusion_frames", 8)))
37
+ if exclusion <= 0 or len(candidates) == 0 or len(target_positions) == 0:
38
+ return candidates
39
+
40
+ target_start = int(target_positions[0])
41
+ target_stop = int(target_positions[-1]) + 1
42
+ local_start = max(0, target_start - exclusion)
43
+ return candidates[(candidates < local_start) | (candidates >= target_stop)]
44
+
45
+
46
  def _as_pose_array(poses) -> np.ndarray:
47
  poses = np.asarray(poses, dtype=np.float32)
48
  if poses.ndim != 2 or poses.shape[1] < 5:
 
806
  if len(candidates) == 0:
807
  return np.empty((0,), dtype=np.int64)
808
 
809
+ candidates = _exclude_revisit_local_context(candidates, target_positions, cfg)
810
+ if len(candidates) == 0:
811
+ return np.empty((0,), dtype=np.int64)
812
+
813
  if len(excluded) > 0:
814
  candidates = candidates[~np.isin(candidates, excluded)]
815
  if len(candidates) == 0:
 
843
  anchor_candidate_stop=None,
844
  dynamic_stream=None,
845
  ):
846
+ """Select memory indices and masks for [anchor][dynamic][revisit]."""
847
 
848
  poses = _as_pose_array(poses)
849
  target_positions = np.asarray(target_positions, dtype=np.int64)
tests/test_dememwm_latent_dataset.py CHANGED
@@ -141,6 +141,30 @@ class MemorySelectionTests(unittest.TestCase):
141
 
142
  self.assertEqual(candidates.tolist(), [1, 2])
143
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  def test_dememwm_latent_config_has_dataset_side_memory_causal_default(self):
145
  config_path = Path(__file__).resolve().parents[1] / "configurations" / "dataset" / "video_minecraft_dememwm_latent.yaml"
146
 
@@ -279,11 +303,12 @@ class MemorySelectionTests(unittest.TestCase):
279
  selected = indices["revisit"][masks["revisit"]]
280
  self.assertIn(6, selected.tolist())
281
 
282
- def test_training_noncausal_revisit_can_select_target_window_frame(self):
283
  poses = np.zeros((8, 5), dtype=np.float32)
284
  poses[:, 0] = 100.0
285
  poses[:, 4] = 180.0
286
  poses[4] = np.asarray([0, 0, 0, 0, 0], dtype=np.float32)
 
287
  cfg = _selection_cfg(
288
  causal=False,
289
  max_anchor_frames=0,
@@ -300,7 +325,7 @@ class MemorySelectionTests(unittest.TestCase):
300
  rng=np.random.default_rng(0),
301
  )
302
 
303
- self.assertEqual(indices["revisit"].tolist(), [4])
304
  self.assertEqual(masks["revisit"].tolist(), [True])
305
 
306
  def test_validation_and_test_noncausal_revisit_stays_past_only(self):
@@ -324,8 +349,8 @@ class MemorySelectionTests(unittest.TestCase):
324
  with self.subTest(split=split), mock.patch.object(memory_selection, "_select_by_point_union", side_effect=fake_point_union):
325
  indices, masks = select_memory_indices(poses, np.array([4]), cfg, split=split)
326
 
327
- self.assertEqual([candidates.tolist() for candidates in seen_candidates], [[0, 1, 2, 3]])
328
- self.assertEqual(indices["revisit"].tolist(), [3])
329
  self.assertEqual(masks["revisit"].tolist(), [True])
330
 
331
  def test_revisit_can_duplicate_anchor_and_dynamic_when_scored_best(self):
@@ -340,6 +365,7 @@ class MemorySelectionTests(unittest.TestCase):
340
  max_dynamic_frames=1,
341
  max_revisit_frames=2,
342
  pose_similarity_threshold=0.95,
 
343
  )
344
 
345
  indices, masks = select_memory_indices(
 
141
 
142
  self.assertEqual(candidates.tolist(), [1, 2])
143
 
144
+ def test_revisit_excludes_local_context_and_target_window_but_keeps_future(self):
145
+ import datasets.video.memory_selection as memory_selection
146
+
147
+ poses = _poses(12)
148
+ cfg = _selection_cfg(
149
+ causal=False,
150
+ max_anchor_frames=0,
151
+ max_dynamic_frames=0,
152
+ max_revisit_frames=2,
153
+ local_context_exclusion_frames=2,
154
+ )
155
+ seen_candidates = []
156
+
157
+ def fake_pose_similarity(poses_arg, candidates, target_positions, cfg_arg, count, rng=None):
158
+ seen_candidates.append(candidates.copy())
159
+ return np.asarray([1, 8], dtype=np.int64)
160
+
161
+ with mock.patch.object(memory_selection, "_select_by_pose_similarity", side_effect=fake_pose_similarity):
162
+ indices, masks = select_memory_indices(poses, np.array([4, 5, 6, 7]), cfg, split="training")
163
+
164
+ self.assertEqual([candidates.tolist() for candidates in seen_candidates], [[0, 1, 8, 9, 10, 11]])
165
+ self.assertEqual(indices["revisit"].tolist(), [1, 8])
166
+ self.assertEqual(masks["revisit"].tolist(), [True, True])
167
+
168
  def test_dememwm_latent_config_has_dataset_side_memory_causal_default(self):
169
  config_path = Path(__file__).resolve().parents[1] / "configurations" / "dataset" / "video_minecraft_dememwm_latent.yaml"
170
 
 
303
  selected = indices["revisit"][masks["revisit"]]
304
  self.assertIn(6, selected.tolist())
305
 
306
+ def test_training_noncausal_revisit_excludes_target_window_frame(self):
307
  poses = np.zeros((8, 5), dtype=np.float32)
308
  poses[:, 0] = 100.0
309
  poses[:, 4] = 180.0
310
  poses[4] = np.asarray([0, 0, 0, 0, 0], dtype=np.float32)
311
+ poses[6] = np.asarray([0, 0, 0, 0, 0], dtype=np.float32)
312
  cfg = _selection_cfg(
313
  causal=False,
314
  max_anchor_frames=0,
 
325
  rng=np.random.default_rng(0),
326
  )
327
 
328
+ self.assertEqual(indices["revisit"].tolist(), [6])
329
  self.assertEqual(masks["revisit"].tolist(), [True])
330
 
331
  def test_validation_and_test_noncausal_revisit_stays_past_only(self):
 
349
  with self.subTest(split=split), mock.patch.object(memory_selection, "_select_by_point_union", side_effect=fake_point_union):
350
  indices, masks = select_memory_indices(poses, np.array([4]), cfg, split=split)
351
 
352
+ self.assertEqual([candidates.tolist() for candidates in seen_candidates], [[0, 1]])
353
+ self.assertEqual(indices["revisit"].tolist(), [1])
354
  self.assertEqual(masks["revisit"].tolist(), [True])
355
 
356
  def test_revisit_can_duplicate_anchor_and_dynamic_when_scored_best(self):
 
365
  max_dynamic_frames=1,
366
  max_revisit_frames=2,
367
  pose_similarity_threshold=0.95,
368
+ local_context_exclusion_frames=0,
369
  )
370
 
371
  indices, masks = select_memory_indices(