# CERBERUS 실험 로드맵 — 무엇을, 왜, 어떤 순서로 이 문서 하나만 읽으면 **다른 서버의 에이전트도 이어서 진행할 수 있도록** 쓴다. 현황·근거·다음 명령·판단 기준을 한곳에 모은다. - 세션 복구 절차: `../../CLAUDE.md` (볼륨 루트) 또는 `session-recovery.md` - 학습 이력·설정 근거: `training-log.md` - 심사 지적과 대응: `review-2026-08-10-methodology.md` --- ## 0. 이 연구가 입증하려는 것 > **HAWK는 정적 배경을 별도 학습 대상으로 두지 않는다. 배경 전용 스트림을 추가하고 > 장면 언어로 감독하면, 배경 맥락이 중요한 이상에서 이해 성능이 향상된다.** 증명해야 하는 것은 **세 단계**이며, 뒤로 갈수록 어렵다. | 단계 | 주장 | 반증되는 조건 | |---|---|---| | S1 | 배경 스트림을 추가하면 성능이 오른다 | `flow` ≈ `zero` | | S2 | 그 향상이 **용량이 아니라 배경 내용** 때문이다 | `flow` ≈ `random_mask` | | S3 | 그 향상이 **상보 분해** 때문이다 (단순 추가가 아니라) | `flow` ≈ `duplicate` | S1만 성립하고 S2가 깨지면 "브랜치를 늘리면 좋다"는 흔한 결과로 축소된다. S2까지 성립하고 S3가 깨지면 "배경 정보를 따로 주면 좋다"까지는 주장할 수 있으나 "화소값 보존 상보 분할"(C1)의 고유성은 포기해야 한다. **설계 원칙**: 가설이 참이라면 드러나도록 최대한 유리한 조건을 만들되, 거짓일 경우에 무엇을 보고할지도 미리 정해 둔다. 어느 쪽이 나오든 쓸 수 있는 논문이 되도록 한다. --- ## 1. 현재 진행 중 — ① 통제군 4-arm **목적**: S1·S2·S3를 한 번에 판정한다. 이 실험이 논문의 생사를 가른다. ```bash cd $CERBERUS_ROOT/hawk bash scripts/run_ablation_arms.sh # flow → random_mask → duplicate → zero ``` - arm당 40 epoch(=400k 샘플), 약 1.6일. 전체 약 6.4일 - 네 arm은 **아키텍처·파라미터 수·시각 토큰 수가 동일**하고 정적 스트림의 *내용*만 다르다 - 재개 가능: 끊긴 뒤 같은 명령을 다시 실행하면 `train_run.sh`가 arm별로 이어받는다 - 진행 확인: `grep -c "Averaged stats" $CERBERUS_ROOT/runs/abl_/train.log` **주의 — 이 실험이 도는 동안 학습 경로 코드를 수정하지 말 것.** arm마다 다른 코드로 학습되면 통제가 깨진다(실제로 한 번 발생해 재시작했다). 평가·문서·분석 코드는 무관하다. **끝나면 할 일** ```bash for a in flow random_mask duplicate zero; do $CERBERUS_PY scripts/evaluate.py --ckpt $CERBERUS_ROOT/runs/abl_$a/main/checkpoint_39.pth \ --out experiments/out/eval_abl_$a.json --judge gemini-2.5-flash done $CERBERUS_PY scripts/evaluate.py --compare ``` --- ## 2. 다음 순서 (① 완료 후) 우선순위는 **"어떤 질문에 답하지 못하면 논문이 막히는가"** 기준이다. ### ② 시드 3회 — 3.2일 · 최우선 배경 스트림의 기대 이득은 이 벤치마크에서 소수점 둘째 자리 대역이다. 단일 실행 점추정으로는 "런 간 노이즈와 구별되지 않는다"는 한 문장에 무너진다. 주요 2개 arm (`flow`, 가장 강한 통제군)에 시드 3개를 돌려 평균±표준편차와 부트스트랩 CI를 보고한다. ```bash # seed 는 config 의 run.seed 를 --options 로 덮어쓴다 for s in 43 44; do bash scripts/train_run.sh configs/train_configs/ablation/stage2_flow.yaml abl_flow_s$s 0,1 2 done ``` ※ `run.seed` 오버라이드를 `train_run.sh`의 `OPTS`에 추가해야 한다(미구현). ### ③ 5번째 arm — 고친 `L_dis` — 1.6일 **답하는 질문**: "제대로 작동하는 분리 목적함수가 하류 성능을 바꾸는가." 현재 `L_dis`는 퇴화 고정점에 있어 기울기가 0이다(§4 참조). 고쳐서 재실행하려면 Stage-1부터 다시 해야 할 것 같지만, **`encoder_1`이 곁가지라 그럴 필요가 없다** — `projection.py`에서 `decoder_2`는 `encoder_0`의 출력을 받으므로, `encoder_1`만 재초기화하면 LLM 경로가 손상되지 않는다. ``` 1. L_dis 재정의: 반상관(cos→−1) → 탈상관(|cos|→0) + 배치 중심화, 샘플별 코사인(.view(1,-1) 제거), 분산 하한(VICReg식 hinge) 2. checkpoint_106 로드 후 encoder_1 만 재초기화 3. Stage-2 40 epoch (다른 arm과 동일 예산) ``` **한계**: Stage-2는 400k 샘플이라 목적함수가 작용할 기회가 Stage-1(1.6M)보다 적다. "Stage-1부터 고쳐 학습했다면 어땠을지"는 답하지 못하며, 이는 한계로 명시한다. #### ③이 되살리는 것 — 부록으로 내린 실험들의 부활 조건 **E1·E3는 폐기된 것이 아니라 보류된 것이다.** 두 실험은 애초에 `L_dis`(방향성 분리 목적함수)를 지탱하려고 설계되었고, 그 목적함수를 기여에서 내리면서 함께 부록으로 갔다. 따라서 ③에서 고친 목적함수가 효과를 보이면 **두 실험이 다시 본문 자리를 요구한다.** 그 판단을 나중에 재구성하지 않아도 되도록 의존관계를 여기 남긴다. | 실험 | 원래 목적 | 지금 위치 | 되살아나는 조건 | |---|---|---|---| | **E1** (표현 수준 진단) | `L_dis`가 실제로 표현을 분리했는지 CDS·CKA·상호정보량으로 측정 | Appendix D | ③에서 목적함수가 퇴화하지 않고, 분리도가 실제로 변할 때 | | **E3** (분리 목적함수 검정) | 손실 *방향*(+1 vs −1)이 분리를 야기하는 인과 요인임을 통제 실험으로 입증 | Appendix E | 동상. 단 축이 "방향 비교"가 아니라 **"퇴화하지 않는 목적함수 vs 없음"** 으로 이미 바뀌었다 | | **CDS** | 분리도를 재는 단일 스칼라 | Appendix C | 부호 문제(아래)를 먼저 고쳐야 함 | **되살릴 때 반드시 함께 고쳐야 하는 것 두 가지.** 그냥 부록에서 도로 꺼내면 안 된다. 1. **CDS의 부호 불변성.** linear CKA는 Gram 행렬 기반이라 부호에 불변하므로, `z_b = −c·z_m`인 상태에서 Redundancy = 1이 되어 CDS = 0이 된다. 즉 반상관을 지향하는 목적함수와 이 지표는 반대 방향을 가리킨다. ③이 목적함수를 **탈상관**(`cos → 0`)으로 바꾸면 이 모순은 자동으로 해소되지만, 그 사실을 확인하고 §4.2의 한계 서술을 갱신해야 한다. 2. **Coverage의 기준축.** 기준이 `z_a`인데 `z_a`는 `L_sim`으로 학습되므로, 목적함수가 다른 구성 간 비교에서 자[尺]가 함께 움직인다. 학습에서 자유로운 고정 표현을 기준으로 써야 한다(`complementary_disentanglement_score(..., reference=...)` 인자로 이미 지원). **되살아나지 않는 경우에도 남는 가치.** ③이 음성으로 나오면 E1·E3는 본문으로 오지 않지만, "설계했고 · 퇴화했고 · 고쳐도 달라지지 않았다"는 3단 기록이 완성된다. 이는 후속 연구가 같은 설계를 반복하지 않게 하는 정보이며, 부록에 그대로 두면 된다. **두 경우 모두 삭제하지 말 것.** --- ## 2.5 도메인 구조 — 측정으로 드러난 것과 그것이 바꾸는 설계 2026-08-11, heldout 471건의 **정답 설명**을 판정해(정적 장면 조건이 원인 설명의 일부인가) 도메인별 분포를 얻었다. 결과가 실험 설계를 바꾼다. | 데이터셋 | n(heldout) | causal | 마스크 비율 | 카메라 | 전체 규모 | |---|---|---|---|---|---| | DoTA | 296 | **43%** | 0.449 | 자기운동 → **마스크 퇴화** | 4,883 | | UBnormal | 32 | **22%** | 0.039 | 고정 → 마스크 정상 | 543 | | UCF-Crime | 112 | 9% | 0.064 | 고정 | 1,854 | | ShanghaiTech | 24 | **0%** | 0.067 | 고정 | 437 | | Ped1 / Ped2 / Avenue | 7 | **0%** | ~0.15 | 고정 | 135 | ### 이것이 A(데이터 결함)가 아니라 B(도메인 성질)인 근거 UCF-Crime의 설명은 **중위 176어절**로 DoTA(36어절)의 약 5배인데 causal은 9%뿐이다. 길이 문제가 아니다. 절도·폭행·방화의 원인은 환경이 아니라 **행위**다. ShanghaiTech의 이상 설명도 "광장에서 한 사람이 다른 보행자 진로로 갑자기 틀어 충돌을 야기"처럼 장소가 *어디서*일 뿐 *왜*가 아니다. 따라서 **고정 감시 카메라에서 이상은 행위적이고, 장면은 실제로 배경이다.** 논문의 적용 범위를 "감시 영상 일반"이 아니라 **"장면 조건이 위험도를 규정하는 도메인"** 으로 좁혀야 한다. 이는 정직한 축소이고 방어 가능하다. ### 이것이 만드는 3-패턴 검정 — 세 대안 설명을 동시에 가른다 이득이 어디서 나타나는지가 세 가설을 구별한다. 공변량(causal 비율·마스크 품질)이 **결과를 보기 전에 측정되어 있다**는 점이 핵심이다. | 도메인 | causal | 마스크 | 용량 가설 | 마스킹 정규화 가설 | **본 연구 가설** | |---|---|---|---|---|---| | UBnormal | 22% | 정상 | 이득 있음 | 이득 작음(마스크 비율 0.039) | **이득 있음** | | DoTA | 43% | 퇴화 | 이득 있음 | 이득 큼(비율 0.449) | **이득 감소** | | ShanghaiTech·Ped | 0% | 정상 | 이득 있음 | 이득 중간 | **이득 없음** | | UCF-Crime | 9% | 정상 | 이득 있음 | 이득 작음 | 이득 작음 | 용량 가설은 **균일한** 이득을 예측하고, 마스킹 정규화 가설은 **마스크 비율**을 따라가며, 본 연구 가설만이 **UBnormal 있음 / DoTA 감소 / ShanghaiTech 없음**의 비단조 패턴을 예측한다. 이 패턴은 용량이나 정규화로 만들 수 없다. ### 그래서 바뀌는 것 세 가지 1. ~~**④ ego-motion 보정을 핵심 실험으로 승격.**~~ → **실측으로 기각(④ 항목 참조).** 2D 정렬로는 DoTA 의 마스크가 줄지 않는다(0.383 → 0.398, 정렬 실패 0/320). 전진 주행의 플로우는 깊이에 따라 달라지는 3D 시차이므로 2D 변환으로 제거할 수 없다. 따라서 DoTA 의 이득 감소는 반전 수단 없이 **적용 범위의 한계로 보고**한다. 2. **UBnormal이 가장 깨끗한 검정 무대.** 고정 카메라 + 배경 인과 22%로 ego-motion 교란이 없다. 단 **두 가지 한계를 명시해야 한다** — (i) UBnormal은 **합성 영상**이므로 가장 깨끗한 증거가 합성 데이터에서 나온다는 점, (ii) heldout 내 causal 클립이 7건뿐이라 정량 검정에는 표본이 부족하다(전체 543건 중 대부분이 학습 분할). 정량은 DoTA가, 기제 예시는 UBnormal이 담당하는 분업으로 보고한다. 3. **주 종점을 도메인별로.** 풀링 수치는 DoTA 62.8% 편중이라 사실상 대시캠 성능이다 (Section 4.8 사전 등록 완료). ### 판정 방식을 텍스트로 바꾼 이유 기존 프로토콜(마스킹 영상 → 원본 영상 2단계)의 사람–LLM 일치도는 κ = 0.383이었다. 원인은 **두 판정자가 서로 다른 정보를 봤다**는 데 있다 — 사람은 전경이 지워진 저정보 영상을, LLM은 프레임을 봤다. 정답 설명 텍스트를 판정하면 둘이 같은 것을 보고, 무엇보다 **채점 기준과 일치한다**: 우리는 생성문을 정답 설명과 비교해 채점하므로, "정답이 장면 조건을 원인으로 드는가"가 이득이 나타날 수 있는 조건을 정확히 규정한다. 생성물: `experiments/bg_critical_benchmark/labels_scene_causal_llm.json` 재현: `$CERBERUS_PY scripts/label_scene_causal.py --anno --out <경로>` (471건 82초) 남은 사람 작업: `--sample 80 --dry-run`으로 뽑은 표본을 사람이 라벨하고 κ 계산. ### ④ ego-motion 보정 arm — **취소 (실측으로 기각, 2026-08-13)** §2.5에서 이 실험을 핵심으로 승격했으나, **실행 전에 효과를 측정한 결과 작동하지 않는다.** 학습 없이 확인할 수 있는 것이었고, 확인해서 2일을 아꼈다. 측정: 데이터셋당 40 클립 × 8 프레임. 앞 프레임을 특징점 대응 + RANSAC 어파인으로 현 프레임에 정렬한 뒤 플로우를 다시 계산(warp-then-flow). | 데이터셋 | 보정 전 | 양쪽 warp(통제) | 보정 후 | 보간 아티팩트 | **순효과** | 95% CI | |---|---|---|---|---|---|---| | DoTA | 0.383 | 0.381 | 0.398 | −0.002 | **+0.016** | [+0.009, +0.024] | | UCF-Crime | 0.078 | 0.079 | 0.092 | +0.001 | +0.013 | [−0.001, +0.027] | | UBnormal | 0.042 | 0.042 | 0.043 | +0.000 | +0.001 | [−0.000, +0.001] | | ShanghaiTech | 0.094 | 0.093 | 0.111 | −0.001 | +0.018 | [−0.001, +0.036] | **통제 설계.** 두 프레임을 **같은 추정 변환으로 warp** 한 조건을 통제로 둔다 — 상대 운동은 보존되고 보간만 양쪽에 동일하게 걸리므로, 원본 대비 증가분이 곧 보간 아티팩트다. 측정 결과 아티팩트는 −0.002~+0.001로 **사실상 0**이며, 관측된 증가는 보간이 아니다. *(항등 행렬 통제를 먼저 시도했으나 통제가 되지 않는다 — 정확한 항등은 정수 화소 대응이라 보간을 아예 건너뛰어 아티팩트가 0으로 나오고, 잘못된 안심을 준다. 기록으로 남긴다.)* **정렬은 전부 성공했는데 마스크가 줄지 않았고, 오히려 올랐다.** 그리고 그 상승은 **고정 카메라 도메인에서도 같은 크기로 나타난다**(ShanghaiTech +0.018, DoTA +0.016). 참 효과가 0이어야 하는 곳에서 같은 값이 나온다는 것은, 이 절차가 자기 운동을 제거하는 것이 아니라 **정렬 오차를 주입**하고 있다는 뜻이다. 원인을 추적했다. 추정된 변환의 중심 이동은 고정 카메라에서 0.02~0.10px로 사실상 항등이고 DoTA만 3.49px다 — **추정 자체는 정확하다.** 문제는 `estimateAffinePartial2D`가 회전·스케일도 추정한다는 데 있다. 중심은 거의 안 움직여도 **미세한 스케일 오차(예: 1.001배)가 화면 가장자리를 1px 가까이 밀어** 주변부를 어긋나게 한다. 중심 이동만 재던 초기 지표는 이를 놓쳤다. 따라서 결론은 유지되나 근거가 바뀐다. **2D 상사변환 정렬로는 DoTA 의 분할이 복구되지 않으며, 같은 절차가 모든 도메인에 +0.013~0.018의 정렬 오차를 주입한다.** 전진 주행의 플로우가 깊이에 따라 달라지는 3D 시차라는 해석은 여전히 유력하나, **이 측정만으로는 "시차 때문에 제거 불가"와 "이 추정기의 오차가 제거량을 상쇄"를 구별하지 못한다.** 호모그래피(8-DOF)는 평면인 노면을 정지시킬 수 있으므로 시도해 볼 가치가 있다 — 다만 그것도 노면 밖 구조물에는 같은 문제를 남긴다. **틀린 방법도 기록한다.** 처음에는 플로우 장에 어파인을 적합해 그 성분을 빼는 방식을 썼는데, DoTA 가 0.383 → **0.615 로 악화**되었다. 화소의 62% 는 이미 임계값 아래인데 전체 장에 적합된 모델이 그 정적 영역에도 운동을 예측하므로, 차이가 잔차로 남아 새로 마스크에 들어간다. 자기 운동을 제거하는 대신 정적 영역에 인공 운동을 주입하는 셈이다. 재현: `$CERBERUS_PY scripts/measure_ego_motion_effect.py --n 40` 생성물: `experiments/bg_critical_benchmark/ego_motion_effect.json` **이것이 바꾸는 것.** §2.5의 "④ 가 DoTA 의 이득 감소를 자백에서 기제 증거로 반전시킨다"는 계획은 성립하지 않는다. DoTA 에서 이득이 작게 나오더라도 저렴한 반전 수단이 없으므로, 논문은 **적용 범위의 한계로 정직하게 보고**해야 한다 — 이 방법의 분할은 고정 카메라 도메인에서 유효하고, 시차가 지배하는 주행 영상에서는 2D 정렬로 복구되지 않는다. DoTA(전체의 62%)에서 자기운동이 화면 전체를 동적으로 분류해 정적 스트림이 비는 문제 (`mask_statistics.json`). 전역 호모그래피 추정 후 잔차 플로우로 마스크를 만든다. **성능 개선이자 방법론 기여**가 될 수 있다 — 배경을 더 잘 보게 만드는 방향이므로 연구 주장과 같은 방향이다. ### ⑤ Stage-1 재학습 — 2.8일 + Stage-2 6.3일 ③의 완전판. `L_dis`를 고친 상태로 Stage-1부터 1.6M 샘플을 다시 학습한다. ③에서 유의한 효과가 보였을 때만 정당화된다. 2 GPU 기준 `max_epoch`을 107 → **133** 으로 올려야 샘플 예산(1.6M)이 유지된다(`iters_per_epoch` 1500, batch 4, 2 GPU). ### ⑥ 주 비교 full-budget run — 6.3일 Table 1을 원본 공개 수치와 나란히 놓기 위해 `flow` 구성을 원본과 같은 1.6M 샘플 (`max_epoch: 160`, batch 2, 2 GPU)로 한 번 돌린다. ①의 감축 예산 결과와는 별개다. --- ## 3. GPU 없이 병행할 것 | 작업 | 상태 | 비고 | |---|---|---| | 장면 어휘 재현율 지표 | ⏳ | **연구 주장을 직접 재는 유일한 지표** — §5 참조 | | Background-critical 주석 600건 | ⏳ | 사람 2인 이상 필요. `bg_critical_benchmark/annotation_protocol.md` | | Route B 합성 프로브 + 귀무 조건 | ◐ | `corrected_bsi()` 구현됨, 실데이터 적용 미완 | | 참고문헌 [51]–[55] 원문 대조 | ⏳ | 기억으로 작성됨 — `improved/07_references.md`에 표시 | | Figure 1 teaser | ⏳ | 실제 프레임의 `x` / `M⊙x` / `(1−M)⊙x` 3장이면 충분 | --- ## 4. 확정된 사실 (되돌리지 말 것) 측정·검증을 거친 것들이다. 다시 논의하기 전에 근거를 먼저 볼 것. **`L_dis`는 학습된 적이 없다.** `checkpoint_106` 실측: - `encoder_1.bias` 코사인 `+0.9988` / `−0.9993` (목표값에 정확히 도달) - 같은 모듈의 `decoder_2.bias`(이 손실이 안 닿는 대조군) `+0.027` / `+0.023` - `encoder_1.weight`는 초기화 대비 0.97~1.01배 — 입력 처리부는 안 움직였고 입력 무관 bias만 20~40배 팽창 - `cos = ±1`은 코사인의 정류점 → 기울기 0 → 이후 106 epoch 동안 무기여 - 결론: `t_4 = 0.1`과 `t_4 = 0`이 비트 단위로 동일하다. 어블레이션 불필요 **CDS는 `L_dis`의 최적점에서 0이 된다.** linear CKA가 부호 불변이므로 `z_b = −c·z_m`에서 Redundancy = 1 → CDS = 0. 즉 목적함수와 진단 지표가 서로 반대를 가리킨다. 비중복성이 요구하는 것은 반상관(−1)이 아니라 탈상관(0)이다. **마스크 비율은 도메인 간 10배 이상 차이 난다** (전수 7,852 클립, τ=0.2): DoTA 0.449 / Ped2 0.160 / Ped1 0.159 / Avenue 0.147 / ShanghaiTech 0.067 / UCF-Crime 0.064 / UBnormal 0.039. 고정 카메라 도메인에서 정적 스트림은 프레임의 84–96%를 보존하므로 외형 스트림과 입력이 크게 겹친다 → `duplicate` 통제군이 특히 중요. **Stage-2에는 `L_ML`·`L_BL`이 없다.** 세 스트림을 concat해 LLaMA를 1회 통과시키므로 `loss_motion = loss_background = loss`이며(`video_llama.py:806`), 실효 목적은 `1.2·L_VL + 0.1·L_sim + 0.1·L_dis`다. 따라서 `+L_BL` 어블레이션 행은 Stage-1 재사전학습을 요구한다. **Stage-1에서 `L_BL`은 정상 작동했다.** 로그의 `motionloss 2.6672` vs `backgroundloss 2.2075`가 서로 다른 값이라는 것이 증거다. 연구 주장의 핵심 부품은 붕괴하지 않았다. --- ## 5. 아직 없는 것 — 주장을 직접 재는 지표 현재 지표는 연구 주장을 **간접적으로만** 잰다. - BLEU: 문장 전체. 배경 서술이 좋아져도 희석된다 - BSI: 배경에 *민감한가*이지 *정확한가*가 아니다 - `context_critical` 정확도: 맞았나 틀렸나. 배경 서술 품질은 아니다 **장면 어휘 재현율(Scene-word Recall)** — 정답 캡션에서 뽑은 장면 어휘 (`extract_background_entities_sentence`가 뽑는 바로 그 단어들, `L_BL`의 학습 목표)를 모델 출력이 얼마나 맞히는가. 이것이 있어야 *"HAWK는 노면이 젖었다는 걸 말하지 못하는데 우리는 말한다"* 를 숫자로 쓸 수 있다. GPU 불필요. --- ## 6. 결과별 대응 (미리 정해 둔다) | ① 결과 | 해석 | 논문 방향 | |---|---|---| | `flow` > `duplicate` > `random_mask` ≈ `zero` | S1·S2·S3 전부 성립 | 원안대로. 상보 분해가 핵심 기여 | | `flow` ≈ `duplicate` > `random_mask` ≈ `zero` | S1·S2 성립, S3 실패 | C1을 "배경 정보의 명시적 분리"로 축소. 분해의 *형태*는 주장하지 않음 | | `flow` ≈ `random_mask` | S2 실패 | 이득이 용량·정규화 효과. 구조 주장 철회, 음성 결과로 정직하게 보고 | | 전부 동점 | S1 실패 | 배경 스트림 자체가 무효. ④(ego-motion)로 마스크 품질을 먼저 개선해 재시도 | 마지막 두 경우가 나와도 **버릴 실험이 아니다** — "브랜치 추가는 용량 효과였다"는 것도 이 계보에서 보고할 가치가 있는 결과이며, 통제군을 갖춘 덕분에 그렇게 말할 수 있다. --- ## 7. 백업 규약 큰 변경 후에는 양쪽 모두 밀어 다른 서버에서 재현 가능하게 한다. ```bash # 코드·문서·figure git push https://@github.com/jungseoik/hawk.git HEAD:main # 체크포인트·로그 (HF) $CERBERUS_PY scripts/upload_checkpoint.py --folder --run-dir $CERBERUS_ROOT/runs/ --latest ``` 토큰: `$CERBERUS_ROOT/.github_token`, `.hf_token`, `.gemini_token`(판정자).