학습 노트

[학습 노트] ForenShield 모델 원리

sybear02 2026. 8. 2. 22:57

딥페이크·위변조 모델이 보는 것

이 글은 부트캠프 최종 프로젝트 ForenShield에서 쓴 딥페이크·위변조 탐지 모듈이 각각 어떤 신호를 보는지 정리한 학습 노트다. Late Fusion으로 점수를 합치는 과정은 기술 회고로 따로 남겨 두었고, 여기서는 모듈·레인의 역할 구분에 초점을 둔다.

프로젝트와 동작 원리

ForenShield는 영상·이미지 위변조 분석과 증거 관리를 위한 딥페이크·디지털 포렌식 플랫폼이다. 나는 AI 딥페이크 탐지와 백엔드 연동을 중심으로 담당했고, 나온 점수를 Late Fusion에 넣어 서비스로 넘기는 쪽까지 작업했다. 학습·파인튜닝 파이프 전체를 혼자 돌렸다기보다, 각 모듈이 내는 점수의 의미를 맞춰 두는 일이 중요했다.

점수를 합치는 이야기만 보면 “모델이 여러 개”로 끝나기 쉽다. 실제 구조는 보는 신호가 다른 레인을 나눠 둔 쪽에 가깝다. 딥페이크 레인은 사람·얼굴·신체가 AI로 합성·교체됐는지를 묻고, 위변조 레인은 국소 편집·잘라붙이기 같은 편집 흔적이 있는지를 묻는다. 신호가 다르면 오탐 패턴도 다르기 때문에, 화면과 점수 레인도 나눴다.

딥페이크 레인은 다시 세 축으로 나뉜다. 얼굴 프레임의 공간 단서는 Xception, 클립의 시간 일관성은 TimeSformer, 프레임 쌍의 광학 흐름은 GMFlow와 그 위 점수 head다. forgery 쪽은 TruFor 등을 위변조 레인에 두는 흐름으로 이어졌다. soft-gate로 딥페이크 모듈 일부가 약해도, 위변조처럼 가능한 경로는 이어서 돌릴 수 있게 했다.

딥페이크 레인

Xception — 얼굴 단위 공간 단서

한 장의(또는 크롭한) 얼굴 프레임에서 CNN이 공간 특징을 보고 fake/real 쪽 점수를 낸다. “이 얼굴 패치가 합성·교체 분포에 가까운가”에 가깝다. 얼굴이 잘 잡히는 구간에서는 가장 직관적인 단서라, Late Fusion에서도 얼굴 단위 CNN 점수는 핵심으로 쓴다.

한계도 분명하다. 얼굴이 없거나 너무 작으면 이 모듈을 제대로 돌리기 어렵다. 그때를 soft-gate로 두고, 실패와 “일부만 돌았다”를 구분한다. 한 프레임만 보면 시간축 조작이나 움직임 이상은 놓치기 쉬워서 TimeSformer·GMFlow와 역할을 나눈다. 학습은 사전학습 가중치를 가져와 ff1k → celeb1k 순으로 파인튜닝하는 흐름이었고, Golden-200은 벤치용으로 학습에 넣지 않았다.

TimeSformer — 클립의 시간 단서

여러 프레임을 클립으로 묶어 transformer 계열로 시간축 일관성을 본다. 한 장의 텍스처보다 “이어지는 얼굴·장면이 자연스러운가”에 가깝다. 딥페이크는 프레임마다 조금씩 어색한 경우가 있어, 공간 CNN만으로는 약한 구간을 클립 단위 신호가 보완한다.

클립을 만들 만큼 얼굴·구간이 확보돼야 한다. soft-gate나 모듈 스킵이 나면 Fusion에서는 TimeSformer 쪽 가중을 줄이거나 soft discount처럼 그 점수를 언제 덜 믿을지를 규칙으로 둔다. 모델이 항상 같다가 아니라, 이번 입력에서 이 모듈이 유효한가가 점수 해석에 들어간다. Xception과 같이 사전학습 후 ff1k → celeb1k 파인튜닝 흐름을 썼다.

GMFlow — 광학 흐름과 점수 head

GMFlow 본체는 “이 영상이 fake인가”를 바로 분류하는 네트워크가 아니다. 인접 프레임 쌍에서 픽셀이 어디로 움직였는지(optical flow)를 추정하는 사전학습 모델이다. 그 위에 평균·최대·표준편차, temporal jitter, 공간 불일치 같은 flow 통계를 쌓고, 그 숫자로 fake/real 쪽 점수를 붙인다.

점수를 붙이는 방식은 두 갈래였다. 휴리스틱은 사람이 정한 규칙·기준선으로 motion_anomaly_score를 만든다. 빠른 baseline이지만 단독 판정용으로는 약했다. learned head는 같은 flow 통계를 feature로 두고, 라벨이 있는 영상으로 Random Forest 같은 얕은 분류기를 학습해 fake_score를 낸다. 여기서 learned는 GMFlow 신경망 전체를 다시 학습했다는 뜻이 아니라, flow 위에 얹은 head가 패턴을 배웠다는 뜻에 가깝다.

운영에서는 휴리스틱보다 learned head 쪽이 나았고, Optical 대표로는 RAFT·PWC-Net 등과 비교한 뒤 GMFlow를 남겼다. 그래도 Xception·TimeSformer만큼 단독으로 쓰기엔 약해서, Fusion에서는 가중을 낮게 두고 보조 신호·veto/rescue 쪽에 가깝게 썼다. 같은 딥페이크 레인이어도 Xception·TimeSformer는 분류기에 가깝게 점수를 내고, GMFlow는 움직임 이상을 숫자로 뽑은 뒤 그 위에 점수를 얹는다는 점에서 입출력 의미가 다르다.

위변조 레인

위변조(forgery)는 “이 얼굴이 AI 합성인가”보다 국소·편집·조작 흔적이 어디에 있는지에 가깝다. ForenShield에서는 TruFor 등을 위변조 레인에 두는 흐름으로 이어졌고, 사전학습 위에 비디오 forgery 데이터로 파인튜닝하는 쪽이다.

딥페이크 모듈은 신원·얼굴·신체 합성/교체에 관심이 크고 얼굴 게이트·크롭에 의존하는 편이 크다. 위변조는 잘라붙이기·국소 편집·조작 가능성 쪽에 가깝고, 얼굴이 약해도 편집 단서가 남을 수 있다. soft-gate로 딥페이크 쪽이 약해도 위변조 경로를 이어 돌리는 이유다. 점수를 하나로만 보여 주면 사용자가 “가짜”의 종류를 구분하기 어렵고, 레인을 나누면 soft-gate 이후에도 위변조 결과가 남는 이유를 설명하기 쉬워진다.

TruFor 내부 아키텍처·손실·픽셀 단위 맵의 학술 디테일은 분석 엔진 담당 쪽이 더 깊다. 학습 노트로 남기는 것은 제품 관점의 역할이다. 위변조 레인은 딥페이크 fusion의 보조 버튼이 아니라, 다른 질문을 하는 탐지 경로다.

점수로 만날 때

모듈이 낸 점수는 나중에 Late Fusion·통합 riskScore 규칙으로 만난다. 모듈 점수는 그 신호가 이번 입력에서 얼마나 수상한가이고, Fusion·Veto·Rescue는 그 점수를 최종 판정에 얼마나·언제 반영할지다. 오버레이는 fusion으로 합친 히트맵이 아니라 모듈별 단서를 토글로 보여 주는 쪽에 가깝다.

그래서 “GMFlow가 높다”와 “최종 riskScore가 높다”는 같은 문장이 아니다. 화면의 붉은 영역도 Grad-CAM처럼 전 모듈 XAI를 돌렸다는 뜻이라기보다, 탐지·로컬라이즈 결과를 시각화한 쪽에 가깝다. 가중·cap·현장 FP 튜닝의 세부 과정은 Late Fusion 기술 회고로 넘긴다.

정리

ForenShield의 탐지 쪽을 “모델이 여러 개”로만 기억하면 설명이 금방 섞인다. 딥페이크는 얼굴·시간·움직임처럼 합성/교체를 나눠 보고, 위변조는 편집 흔적을 다른 레인에서 보며, Fusion은 그 점수들을 언제 믿을지 정하는 판정 정책이다.

모델을 더 늘리는 이야기와, 지금 있는 신호가 무슨 질문의 답인지를 먼저 고정하는 이야기는 결이 다르다. 이 노트는 후자를 위한 정리였다.

관련 코드: https://github.com/owhat02/ai-forensic