Fix Ego4D target compatibility in local baselines

This commit is contained in:
Xin Wang
2026-08-28 15:03:31 +08:00
parent 4abbde4f52
commit 0f6a72cfdf
5 changed files with 134 additions and 16 deletions
+47 -6
View File
@@ -278,8 +278,18 @@ def _validate_loss_inputs(
)
def _validated_binary_activity_targets(targets: torch.Tensor) -> torch.Tensor:
"""Validate the four legal EasyCom/EgoSpeak three-label activity rows."""
def _validated_binary_activity_targets(
targets: torch.Tensor,
*,
allow_noncanonical_binary: bool = False,
) -> torch.Tensor:
"""Validate three-label activity rows.
EasyCom uses four explicit activity states. Ego4D's released target files
are consumed by EgoSpeak's MCE objective as binary/multi-positive weights,
so the compatibility path preserves any binary row instead of silently
rewriting it to an EasyCom state.
"""
if targets.ndim < 1 or targets.shape[-1] != NUM_CLASSES:
raise ValueError(
@@ -291,11 +301,22 @@ def _validated_binary_activity_targets(targets: torch.Tensor) -> torch.Tensor:
rounded = targets.round()
if not torch.allclose(targets, rounded, atol=1e-6, rtol=0.0):
raise ValueError("Activity targets must contain only binary 0/1 values")
expected_background = (rounded[..., 1:].sum(dim=-1) == 0).to(rounded.dtype)
if not torch.equal(rounded[..., 0], expected_background):
expected_background = rounded[..., 1:].sum(dim=-1) == 0
valid = rounded[..., 0].bool() == expected_background
if allow_noncanonical_binary:
return rounded
if not bool(valid.all()):
invalid = torch.unique(rounded[~valid].reshape(-1, NUM_CLASSES), dim=0)
invalid_rows = ", ".join(
str([int(value) for value in row.tolist()])
for row in invalid[:8]
)
if len(invalid) > 8:
invalid_rows += ", ..."
raise ValueError(
"Activity targets must be one of [1,0,0], [0,1,0], "
"[0,0,1], or [0,1,1]"
"[0,0,1], or [0,1,1]; observed invalid "
f"row(s): {invalid_rows}"
)
return rounded
@@ -799,7 +820,13 @@ def load_session_data(
f"{target_path}"
)
targets = torch.from_numpy(np.asarray(target_array, dtype=np.float32))
_validated_binary_activity_targets(targets)
try:
_validated_binary_activity_targets(
targets,
allow_noncanonical_binary=dataset == "ego4d",
)
except ValueError as error:
raise ValueError(f"{error}: {target_path}") from error
if len(label_indices) and int(label_indices[-1]) >= len(targets):
raise ValueError(
f"Last label index {int(label_indices[-1])} exceeds target length "
@@ -823,6 +850,20 @@ def load_session_data(
"video_sampling_grid",
)
}
expected_background = targets[:, 1:].sum(dim=-1) == 0
canonical_rows = targets[:, 0].bool() == expected_background
unique_rows, row_counts = torch.unique(
targets.to(dtype=torch.int64),
dim=0,
return_counts=True,
)
metadata["num_noncanonical_target_rows"] = int(
(~canonical_rows).sum().item()
)
metadata["target_row_pattern_counts"] = {
"".join(str(int(value)) for value in row.tolist()): int(count)
for row, count in zip(unique_rows, row_counts)
}
local = None
if local_feature_root is not None:
from local_turn_features import load_local_features