TL;DR
- 목표: Phase B pseudo-label(noisy) → DROID GT depth/pose(clean)로 supervision 전환
- 핵심 과제: DROID Z-buffer depth(mm) + Euler XYZ pose를 Any4D relative depth + 상대 quaternion/translation 공간에 정렬
- 방식: On-the-fly alignment (preprocessing 없음) — frozen Any4D forward는 scene flow pseudo-label용으로만 유지
- 데이터:
droid_processed/ 156 에피소드 (full_processed 3162 ep 대비 소규모, 품질 ↑)
1 배경 / 목적
현재 LGMv3 Phase B는 frozen Any4D의 pseudo-label로 depth/pose/scene-flow를 학습한다. Any4D는 in-the-wild 데이터로 학습된 모델로, DROID 로봇 wrist-view에 최적화되어 있지 않아 pseudo-label에 노이즈가 상당하다.
기존 한계: pseudo-label depth/pose의 노이즈 → Phase B 수렴 품질 저하. 특히 wrist camera의 close-range geometry에서 오차 누적.
DROID droid_processed/ 데이터셋에는 156 에피소드에 대해 아래 GT가 존재한다:
- GT depth: RealSense sensor, Z-buffer depth, mm 단위
- GT camera pose: absolute Euler XYZ extrinsic [T, 6]
- GT intrinsics: per-episode calibration 데이터
이 GT를 직접 supervision signal로 사용하면 pseudo-label 노이즈 없이 Phase B 품질을 높일 수 있다. 단, LGMv3 출력은 Any4D 좌표계(relative depth, relative pose, unit-sphere rays)이므로 GT를 Any4D 공간에 맞춰야 한다.
2 Alignment 방법 설계
Depth Alignment (per-view)
Any4D depth convention은 depth_along_ray — unit-sphere ray 방향을 따른 거리, 단위 없음, relative scale. DROID GT는 Z-buffer depth(RealSense, mm 단위)다.
변환 과정:
- DROID Z-depth →
depth_along_ray 변환:
- 인트린식으로 ray direction 계산
depth_along_ray = z_depth × ‖ray_cam‖ / ray_cam_z
- Scale alignment (per-view least-squares):
s, b = argmin Σ ‖any4d_depth_i - (s × gt_dar_i + b)‖²
# valid pixels only (NaN mask, depth > 0)
- Aligned GT depth =
s × gt_depth_along_ray + b
주의: depth NaN/invalid 비율 — ego ~15%, wrist ~21%. valid pixel mask 필수. mm → m 단위 변환 후 alignment. 에피소드별 scale 다를 수 있으므로 per-view alignment 필수.
Camera Pose Alignment
DROID GT는 absolute Euler XYZ extrinsic [T, 6] (world→camera). Any4D는 상대 quaternion + translation (view 0 = reference).
- DROID absolute pose → 4×4 transform matrices:
Rotation.from_euler('xyz', euler)
- Relative:
T_rel[i] = T[ref]⁻¹ @ T[i] (ref = exo_t0)
- Quaternion (xyzw) + translation 추출
- Translation scale alignment vs Any4D (simple scale ratio)
Scene Flow
GT scene flow 없음. 처리 방식 결정:
pseudo-label 유지하되 loss weight 낮춤. frozen Any4D는 scene flow pseudo-label 용도로 여전히 필요하므로 forward call을 완전히 제거하지 않음.
3 구현 계획 (On-the-fly Alignment)
별도 preprocessing 없이 training step 내에서 real-time alignment. 추가 디스크 I/O 없이 기존 데이터 파이프라인을 최소 변경.
Training step:
1. Frozen Any4D forward → pseudo-labels (기존과 동일, scene flow용)
2. GT depth/pose 로드 (DroidDatasetV2에서 추가 필드)
3. Per-view depth alignment (tiny least-squares, <1ms/view)
4. Pose 변환 (Euler XYZ → relative quat+translation)
5. Aligned GT로 depth/pose loss 계산
Scene flow: pseudo-label 유지 (낮은 weight)
| 파일 | 변경 내용 |
DroidDatasetV2 | droid_processed/에서 ego_depth, wrist_depth, intrinsics 추가 로딩 |
train_lgm_v3.py | compute_phase_b_loss → GT depth/pose 사용, scene flow만 pseudo-label 유지 |
train_lgm_v3.sh | data_dir을 droid_processed로 변경 (156 ep) |
장점: 별도 전처리 스크립트 불필요, 코드 변경 최소화. frozen Any4D는 scene flow용으로 어차피 필요하므로 추가 overhead 없음.
트레이드오프: droid_processed 156 ep vs full_processed 3162 ep — 데이터 양 20배↓, GT 품질 ↑. 충분한 학습 수렴을 위해 epoch 수 조정 필요.
4 Takeaway
Phase B pseudo-label supervision의 근본적인 품질 한계를 GT로 대체하는 접근이다. Any4D 좌표계와 DROID GT 좌표계의 단순한 변환 공식(Z-depth → ray depth, Euler → relative quat)이 확립되어 있어 구현 리스크가 낮다.
📌 핵심 판단
GT supervision이 pseudo-label 대비 얼마나 나은지는 실제 학습으로 검증이 필요하다. Per-view least-squares alignment가 올바르게 동작하는지 초기 디버깅 시 Any4D pseudo-depth와 aligned GT depth를 시각적으로 비교하는 것이 중요하다. depth NaN 비율(ego 15%, wrist 21%)은 예상 범위이나, 특정 에피소드에서 50%+ NaN이 발생하면 해당 에피소드를 필터링해야 한다.
5 Next Steps
- DroidDatasetV2 수정: GT depth/intrinsics 필드 추가 로딩, valid pixel mask 생성
- Alignment 함수 구현:
align_depth_to_any4d(z_depth, intrinsics, any4d_depth_ref), convert_pose_to_relative(euler_abs)
- 단위 테스트: 10개 에피소드에서 aligned GT depth vs Any4D pseudo-depth 시각 비교 (outlier 에피소드 확인)
- train_lgm_v3.py 통합:
compute_phase_b_loss 내 GT supervision 분기 추가
- 미해결: translation scale alignment 방법 (Procrustes vs simple scale ratio) 선택 — 먼저 simple ratio로 시작 후 오차 큰 경우 Procrustes로 전환