콘텐츠로 이동

실험4: FedAvg + FT 학습 파이프라인 정합성 감사

날짜: 2026-04-14 대상: v5 FL 실험 전체 파이프라인 (Phase 2 + Phase 3) 리뷰어: exp-critic 선행 리뷰: report/version5/exp-critic/v5_0413_FL_critic_review.md 수정 상태: 전건 수정 완료 (2026-04-14)


요약

v5 FL 실험의 학습 파이프라인 전체를 데이터 누수, 기간 정합성, 파인튜닝 프로세스, 연합학습 라운드 구성 관점에서 비판적 분석을 수행했다. CRITICAL 3건, MAJOR 5건, MINOR 3건의 이슈를 발견했으며, 이 중 CRITICAL 이슈는 실험 결론의 신뢰성에 직접 영향을 미친다.

[2026-04-14 수정 완료] 아래 전체 11건(C1-C3, M1-M5, m1-m3) 코드 수정 및 테스트 통과 완료. 상세 변경 이력은 todos/track-b_ver6_fl_advanced.md 참조.


1. CRITICAL 이슈

C1. Phase 2 FT에 Validation/Early Stopping 미적용 — ✅ 수정 완료

파일: experiments/federated/v5_0413_fed_train.py:219-224, src/fed_learning/trainer.py:_local_train()

# fed_train.py:219-224
if args.ft_epochs > 0:
    ft_models = {}
    for apt_name in EVAL_HOUSEHOLDS:
        ft_model = copy.deepcopy(trainer.global_model)
        trainer._local_train(
            ft_model, trainer._loaders[apt_name][0], args.ft_epochs
        )

문제: Phase 2의 핵심 결과인 F3(FedAvg+FT)에서 _local_train()이 validation 없이 고정 에폭만큼 무조건 학습한다. 동일 실험의 train_local_only()는 patience=10 early stopping을 적용하므로 비교 조건이 불공정하다.

영향: "F3: FedAvg+FT가 PAPE 기준 최선(42.02%)"이라는 결론이 FT 에폭 수 선택의 임의성에 종속된다. 10 에폭이 최적인지, 과적합이 발생했는지 판단 불가.

개선: _local_train()에 val_loader를 인자로 받아 early stopping 적용, 또는 FT 전용 함수 별도 구현.

수정: _local_train()에 val_loader/patience 파라미터 추가, FT 호출부 수정 (21 tests passed)


C2. cold_start_evaluate()에 Early Stopping 미적용 — ✅ 수정 완료

파일: src/fed_learning/trainer.py:332-348

if ft_epochs > 0:
    for _epoch in range(ft_epochs):
        for x, y in train_l:
            ...  # early stopping 없음

문제: 이전 리뷰(v5_0413 #3)에서 이미 지적된 사항. val_l을 생성하지만 FT 루프에서 한 번도 사용하지 않는다. 여전히 미수정 상태.

영향: FT-50의 과적합이 과장되었을 가능성. "Fine-tuning은 해롭다"는 결론이 약화될 수 있음.

수정: 인라인 FT 루프 → _local_train() 재사용으로 교체 (23 tests passed)


C3. Phase 2에서 EVAL_HOUSEHOLDS가 Federation에 참여 — ✅ 수정 완료

파일: experiments/federated/v5_0413_fed_train.py:177-186

fed_households = get_federation_households(
    num_households=args.num_households, seed=args.seed,
)
for apt in EVAL_HOUSEHOLDS:
    if apt not in fed_households:
        fed_households.append(apt)  # 평가 가구를 강제 포함

문제: EVAL_HOUSEHOLDS(Apt6, Apt15, Apt30, Apt51, Apt88)가 연합 학습 라운드에 학습 참여자로 포함된다. 글로벌 모델이 평가 대상 가구의 train 데이터로 학습된 weight를 포함하게 되어, "글로벌 모델이 미지의 가구에 일반화 가능한가?"를 측정하는 목적과 충돌한다.

반면 Phase 3(v5_0413_fed_cold_start.py:188)에서는 exclude=EVAL_HOUSEHOLDS로 올바르게 제외한다.

영향: Phase 2 FedAvg+FT의 좋은 성능이 글로벌 모델이 이미 해당 가구 패턴을 학습했기 때문일 수 있으며, FedAvg의 일반화 능력을 과대 평가할 위험이 있다.

개선: Phase 2에서도 EVAL_HOUSEHOLDS를 federation에서 제외하거나, "참여 가구 eval"과 "비참여 가구 eval"을 분리 보고.

수정: --include-eval-in-fed 플래그 추가, 기본 제외 (27 tests passed)


2. MAJOR 이슈

M1. Few-Shot data_fraction에서 Normalization 정보 누수 — ✅ 수정 완료

파일: src/fed_learning/data_utils.py:61-73

# line 61-66: mean/std 계산 (전체 train_data 기준)
mean = float(np.mean(train_data))
std = float(np.std(train_data))
train_data = (train_data - mean) / std

# line 71-73: data_fraction 적용 (mean/std 계산 이후)
if data_fraction < 1.0:
    n_train = max(seq_len + pred_len + 1, int(len(train_data) * data_fraction))
    train_data = train_data[:n_train]

문제: data_fraction 적용 전에 전체 train_data로 mean/std를 계산한다. frac=0.1일 때 모델은 전체 학습 기간의 통계를 알고 있지만 실제로는 10%의 데이터만 학습한다. 신규 가구가 자신의 전체 데이터 통계를 알 수 없는 현실 시나리오와 불일치한다.

영향: Few-shot 시나리오에서 정규화를 통한 정보 누수. Cold-start 실험 결론의 신뢰성 저하.

개선: data_fraction 적용 후에 mean/std를 계산하도록 순서 변경.

수정: data_fraction 적용 후 mean/std 계산으로 순서 변경 (8 tests passed)


M2. Few-Shot 시계열 앞부분 절단으로 인한 계절 편향 — ✅ 수정 완료

파일: src/fed_learning/data_utils.py:71-73

train_data = train_data[:n_train]  # 항상 시계열 앞부분만 사용

문제: Few-shot(frac=0.1)에서 학습 데이터를 시계열의 앞부분에서만 잘라낸다. 에너지 소비 데이터는 계절성이 강하므로, 초기 구간(예: 1~2월)만 학습하면 테스트 기간(11~12월경)의 계절적 특성을 반영하지 못한다.

영향: "데이터가 적어서 성능이 나쁜" 효과와 "계절 불일치로 성능이 나쁜" 효과를 분리할 수 없다.

개선: 테스트 직전 구간(recent-first) 방식과의 비교 실험 추가.

수정: few_shot_strategy 파라미터 추가: "earliest" (기본) / "recent" (15 tests passed)


M3. 가구 간 시계열 길이 차이로 Test 기간 불일치 가능성 — ✅ 검증 완료 (정상)

파일: src/fed_learning/data_utils.py:49, src/peak_analysis/community.py:load_apartment_hourly()

문제: 각 가구별 CSV를 독립 로드 후 70/10/20 비율 분할한다. 가구마다 데이터 시작/종료 시점이 다르면 동일한 "test set"이라 해도 실제 평가 기간이 가구마다 달라진다.

영향: 가구 간 성능 비교의 공정성 훼손. 특히 계절성이 있는 데이터에서 test 구간의 계절 분포가 달라지면 PAPE 비교가 왜곡된다.

개선: 공통 시간 구간(common time intersection) 확보 후 분할, 또는 절대 날짜 기준 분할.

검증 결과: EVAL 5가구 test 기간 동일 (2016-10-06~12-15), 6가구(패턴B)만 11일 차이 — 현재 실험 무영향


M4. Per-Household Normalization과 글로벌 모델의 의미적 충돌 — ✅ 서술 완료

파일: src/fed_learning/data_utils.py:61-66, src/fed_learning/trainer.py:114

문제: 각 가구별 독립 Z-score 정규화 후 글로벌 모델에 FedAvg 가중치 평균을 수행한다. 가구 A(mean=2.0, std=1.0)와 가구 B(mean=8.0, std=3.0)가 서로 다른 스케일을 동일 범위로 매핑하므로, 글로벌 모델 weight의 물리적 의미가 가구마다 달라진다.

영향: 연합학습의 feature heterogeneity 문제. 논문에서 인지하고 Limitation으로 서술해야 한다.

개선: 보고서에 한계 명시. 선택적으로 global normalization 실험 추가.

수정: report/version6/exp-expert/v6_0414_normalization_limitation.md 작성, 논문 FL 섹션 추가 시 통합


M5. PAPE 정의와 ESS 실용적 피크의 괴리 — ✅ 수정 완료

파일: src/peak_analysis/metrics.py:239-240

peak_true = np.max(y_true, axis=-1)   # 24시간 윈도우별 max
peak_pred = np.max(y_pred, axis=-1)

문제: PAPE가 매일의 일별 피크를 동일 가중치로 평균한다. ESS/BESS 제어에서 중요한 것은 월별 최대 피크(demand charge 기준)이지, 평범한 날의 피크가 아니다.

영향: 실험1(PAPE-전력비용 관계 증명)의 설계에 직접 영향. 현재 PAPE로는 ESS 제어 실효성을 정확히 측정하기 어렵다.

개선: Monthly PAPE(월별 최대 피크 기준) 또는 Top-K PAPE(상위 K개 피크일 기준) 별도 보고.

수정: compute_monthly_pape(), compute_hr() 추가, trainer 결과 dict에 반영 (16 tests passed)


3. MINOR 이슈

m1. FedDF Distillation Loader 편향 — ✅ 수정 완료

이전 리뷰(v5_0413 #4)에서 지적됨. trainer.py:204에서 첫 번째 가구의 train_loader만 사용. ~~여전히 미수정 상태.~~

수정: ConcatDataset + RandomSampler로 전체 가구 혼합 distillation loader 구성

m2. FT Learning Rate가 로컬 학습과 동일 — ✅ 수정 완료

파일: trainer.py:337

Fine-tuning은 수렴된 글로벌 모델에서 시작하므로 LR=1e-3이 과도할 수 있다. Pre-trained 모델 FT에서는 통상 10x~100x 낮은 LR을 사용한다.

수정: --ft_lr CLI 인자 추가 (fed_train.py, fed_cold_start.py), 기본값 None (기존 동작 유지)

m3. FedProx용 global_model 복사가 FedAvg에서도 실행 — ✅ 수정 완료

파일: trainer.py:138-143

FedProx의 proximal term 계산용 deepcopy가 FedAvg 사용 시에도 매번 실행된다. FedAvg의 modify_local_loss()는 loss를 그대로 반환하므로 불필요한 오버헤드.

수정: isinstance(aggregator, FedProxAggregator) 조건 분기로 FedAvg 시 불필요 복사 제거


4. 정상 확인 항목

항목 결과
Train/Val/Test 시간적 분할 (seq_len overlap) 표준 관행, 누수 아님
정규화 기준 Phase 2/3 일관성 각 가구별 독립 계산으로 일관됨
Test set 평가 범위 data_fraction과 무관하게 전체 사용 (의도된 설계, 보고서 명시 필요)

5. 종합 판정

최종 상태: 전건 수정 완료 (2026-04-14) — 수정된 코드로 통합 재실험 필요

항목 판정 수정 상태
Phase 2 FT early stopping Critical ✅ 완료
Phase 3 cold-start FT early stopping Critical ✅ 완료
Phase 2 EVAL_HOUSEHOLDS 참여 Critical ✅ 완료
Few-shot normalization 순서 Major ✅ 완료
Few-shot 계절 편향 Major ✅ 완료
가구 간 test 기간 불일치 Major ✅ 정상 확인
Per-household normalization 한계 Major ✅ 서술 완료
PAPE 정의 괴리 Major ✅ 완료
FedDF loader 편향 Minor ✅ 완료
FT learning rate 분리 Minor ✅ 완료
FedProx 조건 복사 Minor ✅ 완료

다음 단계

코드 수정은 모두 완료됨. 남은 작업: 1. 수정된 코드로 Phase 2 + Phase 3 통합 재실험 (실험5와 연계) 2. 재실험 결과에 Monthly PAPE, HR 지표 동시 적용 3. 재실험 결과에 대한 exp-critic 재검토

이전 리뷰 대비 변화

  • v5_0413 리뷰의 #1(PAPE 해석 방향) → 이미 수정 반영됨
  • v5_0413 리뷰의 #3(Early Stopping) → 범위 확대: Phase 2 FT에도 동일 문제 발견 (C1) → ✅ 수정됨
  • v5_0413 리뷰의 #5(Phase 2-3 비대칭) → 구체화: EVAL_HOUSEHOLDS 참여가 성능 과대추정의 구체적 메커니즘으로 규명 (C3) → ✅ 수정됨
  • 신규 발견 6건: M1(normalization 누수), M2(계절 편향), M3(test 기간 불일치), M4(이종 스케일 집계), M5(PAPE 정의 괴리), m3(불필요 복사) → ✅ 전건 수정/검증됨