|
|
내부 연산
없다. 데이터셋에서 쌍으로 꺼내오는 단계다.
출력
(x, c) 쌍이 인코더로 전달된다.
전문 설명
여기서 짚어둘 것은 ACT 기준으로 x가 "정답 action"이라는 점이다. 학습 시점에는 정답이 존재하므로 인코더가 그것을 참조하여 정확한 잠재변수를 추정할 수 있다. 반면 추론 시점에는 정답이 존재하지 않으므로 인코더 자체를 사용할 수 없다. 이 비대칭성이 이후 모든 블록의 설계에 영향을 미친다.
쉽게 다시 말하면
시험공부를 할 때는 문제집과 정답지를 둘 다 펴놓고 본다. 학습 시의 $x$가 그 정답지다. 실전 시험(추론)에서는 정답지가 없다. 그래서 학습 때 쓰던 부품 하나를 추론 때는 통째로 떼어내야 한다.
1-2. 블록 2 — 인코더 (mu, sigma 산출)
입력 : x, c
내부 연산
입력을 신경망에 통과시켜 저차원으로 압축한다. ACT의 경우 transformer 인코더를 사용하며, 시퀀스 맨 앞에 배치된 CLS 토큰이 self-attention을 거치며 시퀀스 전체의 정보를 누적하여 "전체 요약 슬롯" 역할을 수행한다. 그 요약 표현으로부터 최종적으로 두 개의 값을 산출한다.
출력
전문 설명
일반 오토인코더가 압축값 하나를 출력하는 것과 달리, VAE 계열은 확률분포의 파라미터를 출력한다. 이것이 "변분(Variational)"이라는 명칭의 근거다.
sigma의 의미는 다음과 같이 해석된다.
또한 중요한 사실로, 인코더는 학습 시에만 동작한다. 따라서 그 출력물인 mu, sigma 역시 학습 시에만 산출된다. 추론 파이프라인에는 이 블록 자체가 등장하지 않는다.
여기서 처음 접할 때 직관적으로 이상하게 느껴질 수 있는 지점이 있다. "값 하나면 될 것을 왜 평균과 분산 두 개로 출력하는가"라는 의문이다. 답은 이 모델의 목적이 "압축"이 아니라 "생성"이기 때문이다. 압축만이 목적이라면 값 하나로 충분하다. 그러나 나중에 인코더 없이 디코더만으로 새로운 샘플을 만들어내려면, 잠재공간이 구멍 없이 연속적으로 채워져 있어야 한다. 각 데이터를 점 하나가 아니라 일정한 넓이를 가진 영역으로 매핑해야 그 조건이 충족되며, 그 넓이를 정하는 것이 sigma다.
쉽게 다시 말하면
인코더는 감정사다. 물건을 보고 "이건 대략 이 정도 가치(mu)이고 오차 범위는 이 정도(sigma)입니다"라는 감정서를 써준다. 확실한 물건이면 오차 범위를 좁게 쓰고 애매한 물건이면 넓게 쓴다.
그리고 오차 범위를 굳이 적어두는 이유는, 나중에 감정사 없이 감정서만 보고 물건을 역으로 만들어내야 하기 때문이다. 점 하나만 찍혀 있으면 그 점을 벗어난 순간 아무 정보도 없지만, 범위가 적혀 있으면 그 범위 안 어디를 짚어도 말이 되는 물건이 나온다.
1-3. 블록 3 — Reparameterization Trick (z 샘플링)
Reparameterization trick이 위치하는 지점은 정확히 여기다. 인코더 직후, 디코더 직전.
입력
mu, sigma (인코더 출력)
내부 연산
ACT 기준으로 $z$는 32차원 연속 벡터다.
출력
잠재변수 z 하나
전문 설명
원래 수행하려는 연산은 N(mu, sigma^2) 분포에서 z를 하나 샘플링하는 것이다. 그러나 샘플링 연산은 미분 불가능하다. 미분이 불가능하면 역전파 경로가 그 지점에서 단절되고, 인코더의 가중치는 영원히 갱신되지 않는다.
이 문제를 해결하기 위해 무작위성을 계산 경로 바깥으로 분리한다. epsilon은 표준정규분포에서 독립적으로 뽑아온 상수 취급이 되고, mu와 sigma는 곱셈과 덧셈이라는 결정론적 연산으로만 관여한다. 그 결과 mu와 sigma에 대한 편미분이 성립하므로 gradient가 인코더까지 온전히 전달된다.
여기서 헷갈리기 쉬운 지점이 있다. hidden state와 latent variable을 같은 것으로 이해하는 경우다. 둘은 다르다. hidden state는 토큰마다 산출되는 결정론적 중간 표현이고, latent variable z는 시퀀스 전체를 확률적으로 압축한 단일 벡터다.
또 하나 혼동되기 쉬운 것은 epsilon의 정체다. epsilon은 학습을 통해 조절되는 값이 아니며, 어떤 의미를 담고 있지도 않다. 매번 새로 뽑히는 순수한 난수이고, 그것이 이 설계의 요점이다. 의미를 담은 부분(mu, sigma)과 무작위인 부분(epsilon)을 완전히 분리했기 때문에 학습이 가능해진 것이다.
쉽게 다시 말하면
주사위를 굴려 나온 눈만큼 걸어가야 하는 게임이 있다고 하자. "주사위 굴리기"는 내가 통제할 수 없으니 미세조정도 불가능하다.
그런데 주사위는 미리 굴려놓고(epsilon), 그 결과에 "내 보폭"(sigma)을 곱하고 "출발 지점"(mu)을 더하는 방식으로 바꾸면 어떻게 되는가. 주사위 값은 이미 주어진 숫자가 되고, 내가 조절하는 것은 보폭과 출발점뿐이다. 이 둘은 얼마든지 미세조정할 수 있다. 무작위성은 그대로 살아있는데 학습은 가능해진 것이다.
1-4. 블록 4 — 디코더
입력
z + 조건 c
내부 연산
z와 c를 받아 원본 형태로 복원한다. ACT의 경우 ResNet-18로 추출한 시각 feature, 로봇 상태, 그리고 z를 transformer 디코더에 입력하여 미래 K스텝의 action을 병렬로 일괄 출력한다.
출력
hat{x} — 복원된 데이터. ACT의 경우 action chunk.
전문 설명
원본 Transformer가 한 토큰씩 순차 생성(autoregressive)하는 것과 달리, ACT의 디코더는 action chunk 전체를 동시에 산출한다. 이는 누적 오차(compounding error)를 줄이기 위한 설계다.
이 디코더가 곧 정책(policy)이다. 실제로 로봇을 구동하는 부분이 이 블록이며, 그래서 "CVAE 디코더 = action decoder"라는 등식이 성립한다.
쉽게 다시 말하면
디코더는 몽타주 화가다. "이런 느낌의 사람이었다"는 압축된 인상(z)과 "성별은 남자, 나이는 30대"라는 조건(c)만 듣고 얼굴 전체를 한 번에 그려낸다. 목격자 진술을 한 글자씩 순서대로 받아 적는 방식이 아니라, 전체 인상을 받아 한 장으로 뽑아내는 방식이다.
1-5. 블록 5 — 손실 함수 (Reconstruction + KL)
입력
hat{x} (디코더 출력), x (정답), mu, sigma (인코더 출력)
내부 연산 ① — Reconstruction Loss
복원 결과가 원본과 얼마나 일치하는지를 측정한다. 통상 MSE(L2)를 사용한다. 이 항은 $\sigma$를 축소시키는 방향의 압력으로 작용한다. 불확실성이 작아야 $z$가 정밀한 위치에 놓이고, 그래야 정확한 복원이 가능하기 때문이다.
내부 연산 ② — KL Divergence Loss
KL divergence가 위치하는 지점은 정확히 여기다. 인코더 출력에 직접 부과된다.
역할은 인코더가 산출한 분포를 표준정규분포 N(0,1) 방향으로 압박하는 것이며, mu -> 0, sigma -> 1 방향으로 밀어붙인다. 다만 그 값으로 완전히 고정시키는 것이 아니라 과도한 이탈을 규제하는 성격이다.
최종 손실
출력
스칼라 하나
전문 설명 — KL을 부과하는 이유
인코더가 아무런 제약 없이 mu, sigma를 산출하면 잠재공간이 임의로 분산되어 곳곳에 공백이 생긴다. 그 상태에서 디코더만 분리하여 임의의 z를 입력하면 학습된 적 없는 영역에 대응하는 무의미한 출력이 나온다. 사전에 "z는 대체로 표준정규분포를 따른다"는 제약을 강제해두면, 추론 시 그 분포에서 임의로 샘플링해도 유효한 출력이 보장된다.
ACT에서 추론 시 z = 0으로 고정할 수 있는 근거가 정확히 이것이다. 학습 과정 내내 분포의 중심을 0 근처로 몰아두었기 때문에, 그 중심값을 사용해도 자연스러운 출력이 산출된다.
전문 설명 — 두 손실의 길항 작용과 sigma 변화
고양이와 강아지로 학습된 모델에 표범을 입력하면 sigma가 커지는 방향이 맞다. 다만 그 원인은 KL loss의 압박이 아니라 두 손실의 균형점 이동이다.
이 현상은 실제 부작용으로 이어진다. 잠재공간을 지도로 간주하면 "고양이 영역"과 "강아지 영역" 사이에 경계가 흐릿하게 퍼진 표범/늑대 영역이 형성된다. 추론 시 고양이 영역 근처에서 샘플링하더라도 이 흐릿한 영역으로 넘어갈 수 있고, 그 경우 "고양이 같으나 어딘가 이상한" 결과가 산출된다.
VAE 결과물이 GAN 대비 흐릿(blurry)하다고 알려진 원인 중 하나가 이것이다. reconstruction loss(MSE)가 여러 가능성의 평균을 취하는 성질을 갖는데, 잠재공간의 클러스터 경계까지 흐릿하게 섞이면 디코더가 "이것도 저것도 아닌 평균적 형태"를 산출하게 된다.
여기서 오해하기 쉬운 지점을 하나 정리해둔다. "sigma가 크다"는 것이 곧 "학습이 잘못되었다"는 의미는 아니다. 애매한 입력에 대해 sigma가 커지는 것은 인코더가 상황을 정확히 반영하고 있다는 신호에 가깝다. 문제가 되는 것은 sigma 자체가 아니라, 그 넓어진 영역이 다른 클러스터와 겹칠 때 생성 결과가 오염된다는 부수적 효과다.
쉽게 다시 말하면
두 사람이 밧줄을 양쪽에서 당기고 있다. 한쪽(reconstruction)은 "정확히 복원해야 하니 범위를 좁혀라"라고 당기고, 다른 쪽(KL)은 "잠재공간이 고르게 퍼져야 하니 표준 규격에 맞춰라"라고 당긴다.
전형적인 고양이 사진은 복원 쪽이 쉽게 이겨서 sigma가 좁아진다. 표범처럼 애매한 입력은 복원 쪽이 힘을 쓰지 못해 sigma가 넓게 남는다. 그리고 그 넓은 영역이 옆 동네와 겹치면, 뽑기를 했을 때 가끔 국경 지대의 이상한 물건이 나오게 된다.
1-6. 블록 6 — 역전파 및 가중치 갱신
입력
스칼라 손실 L
내부 연산
chain rule로 gradient를 계산하여 인코더와 디코더 양쪽 모두의 가중치를 갱신한다. 블록 3에서 reparameterization trick을 적용했기 때문에 z를 경유하여 인코더까지 gradient가 전달된다.
ACT 기준으로 학습 대상 가중치는 ResNet-18(이미지 백본), CVAE 인코더, CVAE 디코더 전체이며, model.safetensors에 저장된다.
출력
갱신된 가중치
쉽게 다시 말하면
채점 결과 하나를 받아들고, 그 결과를 만들어낸 모든 부품에게 "너는 이만큼 이 방향으로 바뀌어야 한다"고 통보하는 단계다. 앞에서 주사위를 바깥으로 빼둔 덕분에 이 통보가 인코더까지 무사히 도달한다.
2. CVAE 추론 시 파이프라인
학습 시와 구조가 크게 달라진다. 인코더가 통째로 제거된다.
2-1. 블록 1 — z 준비
입력
없음 (또는 표준정규분포)
내부 연산
두 가지 방식이 있다.
출력
z 벡터 하나
전문 설명
인코더를 사용하지 않는 이유는 명확하다. 인코더 입력에는 "정답 x"가 필요한데, 추론 시점에는 그것이 존재하지 않는다. 정답을 이미 알고 있다면 애초에 생성할 이유가 없다.
여기서 처음에 혼동하기 쉬운 지점이 있다. ACT의 z = 0은 "표준정규분포에서 샘플링한 값이 우연히 0이 된 것"이 아니라 고정 상수로 지정한 것이다. 즉 확률적 요소를 의도적으로 제거한 선택이며, 그 결과 같은 관측에 대해서는 항상 같은 action이 산출된다. 로봇 제어에서는 재현성이 다양성보다 중요하므로 타당한 설계다.
쉽게 다시 말하면
학습 때는 정답지를 보고 "이 사람은 이런 스타일로 푸는구나"를 요약했지만, 실전에서는 정답지가 없으므로 "가장 무난한 표준 스타일"(z=0)로 푼다. 매번 다른 스타일로 풀면 로봇이 같은 상황에서 다르게 움직이게 되는데, 그것은 제어 관점에서 바람직하지 않다.
2-2. 블록 2 — 디코더
입력
z + 조건 c (현재 카메라 이미지, 로봇 관절 상태)
내부 연산
학습 시와 완전히 동일한 forward pass다. 가중치가 고정되어 있다는 점만 다르다.
출력
생성된 데이터. ACT의 경우 미래 K스텝의 action chunk.
2-3. 블록 3 — Temporal Ensembling (ACT 한정 후처리)
입력
시점마다 중첩되어 예측된 복수의 action chunk
내부 연산
동일 시점에 대해 여러 chunk가 각각 예측한 값들을 가중평균으로 결합한다.
출력
연속적으로 이어지는 action
전문 설명
chunk 단위로 불연속하게 예측하면 chunk 경계에서 동작이 급변한다. 중첩 예측 후 결합하면 그 이음매가 평활화된다.
쉽게 다시 말하면
여러 예보관이 각자 내일 날씨를 예측했을 때 한 명만 믿지 않고 평균을 내는 것과 같다. 튀는 예측이 눌리면서 안정적인 결과가 나온다.
3. Diffusion 학습 시 파이프라인
전문 설명 — 핵심 아이디어
CVAE와 달리 diffusion에는 인코더라는 개념 자체가 없다. 저차원으로 압축된 잠재변수도 없다. 대신 원본과 동일한 shape을 가진 상태 x_t가 여러 timestep에 걸쳐 존재하며, 단일 네트워크를 반복 재사용한다.
깨끗한 데이터에 노이즈를 섞어둔 뒤, "여기 섞인 노이즈가 무엇이었는가"를 신경망에게 맞히도록 훈련시킨다. 이후 순수 노이즈에서 출발하여 예측된 노이즈를 조금씩 제거해 나가면 데이터가 생성된다.
쉽게 다시 말하면
원본 사진에 일부러 잡티를 뿌려놓고, "방금 뿌린 잡티가 정확히 뭐였게?"를 계속 맞히게 훈련시키는 것이다. 이걸 잘하게 되면, 나중에 잡티뿐인 화면을 주고도 "여기 낀 잡티는 이거일 것이다"라고 찍어서 지워나갈 수 있게 된다. 그 지우기를 수백 번 반복하면 아무것도 없던 자리에서 그림이 떠오른다.
3-1. 블록 0 — 입력 3개
학습 시 입력은 정확히 세 개다.
① 실제 데이터 x_0
② 랜덤 노이즈 epsilon
③ 랜덤 timestep t
쉽게 다시 말하면
x_0는 요리 재료, epsilon은 뿌릴 후추, t는 얼마나 뿌릴지 정하는 다이얼이다. 그리고 후추는 뿌리는 데도 쓰이지만 나중에 채점할 때 "정답 후추량"으로도 다시 등장한다. 이 이중 역할을 놓치면 뒤에서 헷갈린다.
3-2. 블록 1 — 노이즈 추가 (Forward Process)
이 블록에는 학습되는 가중치가 존재하지 않는다. 고정된 공식일 뿐이다.
입력
x_0, epsilon, t
내부 연산
각 입력의 역할은 다음과 같다.
출력
x_t — 원본과 노이즈가 t에 대응하는 비율로 혼합된 텐서. shape은 x_0와 완전히 동일하다.
전문 설명 — 분산 보존(variance-preserving) 설계
두 계수는 (sqrt{bar_a_t})^2 + (sqrt{1-\bar_a_t})^2 = 1을 만족한다. 이 상보 관계가 분산 보존 성질을 만든다. 이러한 가중평균 형태로 혼합하면 t가 어떤 값이든 x_t의 분산이 일정하게 유지된다. 이 성질이 없으면 t가 커질수록 값이 발산하거나 0으로 수렴하여 신경망이 학습할 수 없는 스케일이 된다.
전문 설명 — 반드시 정정해야 할 오해
원래 정의는 매 스텝 다음과 같다.
b_t는 해당 스텝에서 주입할 미소한 노이즈량(0.0001~0.02 수준), z_t는 그 스텝에서 새로 추출한 노이즈다. 여기서도 기존 신호를 축소시키고 그 빈자리를 새 노이즈로 채우는 방식이 적용된다. 단순 덧셈이었다면 1000회 반복 시 값이 계속 증가하여 표준 가우시안으로 수렴하지 못하고 학습도 불안정해진다. 따라서 항상 제곱합이 1인 두 조각으로 분할하여 혼합하는 것이다.
이 반복을 실제로 전개하면(가우시안의 합이 다시 가우시안이 되는 성질에 의해) 한 번에 도달하는 폐형식이 도출된다. 여기서
즉 1번 스텝부터 t번 스텝까지의 잔존 비율을 전부 누적곱한 값이다.
쉽게 다시 말하면
t는 믹서기의 비율 다이얼이고, x_0와 epsilon은 섞이는 두 재료다. 다이얼을 돌리면 그 비율대로 섞인 결과가 나온다.
그리고 다이얼을 500까지 돌린다고 해서 실제로 500번 갈지는 않는다. "500번 갈았다면 이렇게 되었을 것"을 바로 계산해서 내놓는다. 하는 일은 같은데 연산만 최적화한 것이며, 이것이 diffusion 학습이 실제로 빠르게 도는 핵심 요령이다.
3-3. 블록 2 — 노이즈 예측 네트워크 (U-Net)
이 파이프라인에서 학습 가능한 가중치 theta를 보유한 유일한 블록이다.
입력
epsilon은 여기 입력되지 않는다. epsilon은 손실 함수에서 정답으로만 사용된다. 이 지점을 혼동하기 쉽다.
t를 네트워크에도 재투입하는 이유
x_t만으로는 네트워크가 노이즈 혼입 정도를 판별하기 어렵다. t=10의 미미하게 오염된 상태와 t=900의 거의 순수 노이즈 상태는 픽셀 패턴 자체가 상이하다. t를 명시적으로 제공해야 "현재 노이즈가 이 정도 수준이므로 예측할 노이즈도 그 강도로 잡아야 한다"는 자기 보정이 가능하다.
timestep embedding이 위치하는 지점이 정확히 여기다.
정수 하나를 그대로 투입하는 것이 아니라, transformer의 positional encoding과 마찬가지로 sinusoidal embedding으로 변환한 뒤 네트워크 내부로 주입한다. 주입 방식은 U-Net의 각 residual block마다 해당 임베딩으로 feature map의 scale과 shift를 조정하는 것이며, 통상 FiLM이라 불리는 방식이다. 그 결과 동일한 네트워크가 t=10일 때와 t=900일 때 다르게 동작한다.
내부 연산 — U-Net 구조
이것과 CNN의 차이점
골격은 CNN이 맞다. 다만 순수 CNN 분류기(ResNet 등)와 세 가지가 다르다.
ⓐ decoder가 대칭으로 결합되어 있고(그래서 "U"자 형태) ⓑ timestep embedding이 주입되며 ⓒ bottleneck에 attention이 혼재한다. 정확히는 CNN + attention 하이브리드다.
출력
epsilon_theta(x_t, t) 하나. x_t와 정확히 동일한 shape.
의미는 "이 안에 혼입되어 있던 노이즈는 이러한 형태였을 것"이라는 예측값이다. 이미지가 아니라 노이즈 형태의 텐서다.
3-3-1. 보충 — 노이즈가 낀 입력에서 어떻게 특징을 추출하는가
전문 설명
이 의문은 diffusion 이해의 핵심을 관통한다.
우선 x_t는 순수 노이즈가 아니다. t가 아무리 커도 bar_a_t가 0에 근접할 뿐 정확히 0이 되지는 않는다. 따라서 x_0의 흔적이 미약하게나마 잔존한다.
육안으로 식별되지 않는 패턴을 신경망이 포착하는 근거는 학습을 통해 자연 이미지의 통계적 규칙성을 습득했기 때문이다. 인간도 자연 이미지 통계에 익숙하기 때문에(하늘은 평활하고 엣지는 연속적이라는 등) 약간 이상한 픽셀만 보아도 이질감을 감지한다. 신경망도 같은 원리다.
전문 설명 — "2단계가 아니라 1단계"라는 표현의 정확한 범위
여기서 표현을 정밀하게 규정할 필요가 있다.
"먼저 자연물이 어떠해야 하는지 파악하고, 그 다음 그것을 기준으로 비교한다"는 식으로 명시적으로 분리된 서브루틴은 존재하지 않는다. 신경망 가중치 안에 "자연 이미지 지식 모듈"이 독립 저장되어 있는 것이 아니라, 자연 이미지 통계 지식과 노이즈 검출 능력이 하나의 가중치 함수 안에 뒤엉켜서(entangled) 학습된다.
입력에서 출력으로 단일 매핑이 이루어진다.
다만 이 "1단계"라는 프레이밍은 오해될 소지가 있으므로 범위를 한정한다. 물론 네트워크 내부에는 encoder→decoder라는 구조적 단계는 있다. 여기서 '1단계'라는 것은 '지식 습득'과 '비교 판단'이 각각 독립된 모듈로 분리되어 순차 실행되는 게 아니라는 뜻이다. 즉 U-Net에는 특징을 추출하는 encoder 경로와 그것을 노이즈 형태로 재구성하는 decoder 경로라는 구조적 구분이 분명히 존재한다. "2단계가 아니다"라는 진술은 그 구조적 단계 구분을 부정하는 것이 아니라, "자연물 지식을 먼저 조회하고 그 다음 별도의 비교 모듈이 판정한다"는 식의 기능적 서브루틴 분리가 없다는 것을 가리킨다. 네트워크 내부에 아무런 단계 구분도 없다는 의미가 아니다.
쉽게 다시 말하면
체스 그랜드마스터가 보드를 보고 즉시 "이 수가 좋다"고 판단하는 것과 같다. "1단계로 정석 이론을 떠올리고 2단계로 현 상황과 대조한다"는 의식적 절차를 밟는 것이 아니라, 수만 번의 경험이 뇌에 녹아들어 보는 즉시 좋은 수가 떠오른다.
다만 이 비유가 "그랜드마스터의 뇌에는 아무 구조도 없다"는 뜻은 아니다. 시각 피질이 있고 기억을 담당하는 영역이 있듯, U-Net에도 encoder와 decoder라는 물리적 구조는 엄연히 존재한다. 없는 것은 "지식 조회 담당 부서"와 "비교 판정 담당 부서"가 따로 있어서 서류를 주고받는 식의 분업이다.
전문 설명 — 여기서 파생되는 실제 현상
노이즈 자체는 균일하게 살포되지만, 원본 신호의 복잡도에 따라 영역별 추정 난이도가 달라진다. 그 결과 단순한 영역(하늘, 벽면)은 잘 복원되고 복잡한 영역(손가락, 텍스트)은 뭉개지거나 왜곡된다. 생성 이미지에서 손가락이 자주 부자연스러운 원인이 여기에 있다.
3-4. 블록 3 — 손실 함수 (MSE)
입력
epsilon_theta (예측), epsilon (정답 — 블록 0에서 추출한 그 노이즈)
내부 연산
두 텐서의 차분을 제곱하여 전체 평균을 취하면 스칼라 하나가 산출된다.
출력
스칼라 손실
전문 설명 — L1과 L2의 차이
쉽게 다시 말하면
채점이다. 제출한 답안(epsilon_theta)과 정답지(epsilon)를 픽셀 단위로 대조하여 "총 얼마나 틀렸는지"를 숫자 하나로 압축한다. L2는 큰 실수 하나를 크게 감점하고, L1은 실수 개수만큼 공평하게 감점하는 채점 기준이라고 보면 된다.
3-5. 블록 4 — 역전파 및 가중치 갱신
입력
스칼라 손실 L
내부 연산
1. loss를 역전파 → U-Net 전체 가중치에 대한 gradient 계산 2. optimizer(통상 Adam)가 그 gradient 방향으로 가중치를 미소하게 갱신 3. 이를 수백만 회 반복 (매회 다른 데이터, 다른 t, 다른 노이즈)
출력
갱신된 U-Net 가중치
전문 설명
diffusion이라 하여 역전파가 특수한 것은 아니다. 일반 CNN에서 사용하는 chain rule 기반 backprop과 원리가 완전히 동일하다. 모든 conv 커널의 모든 가중치 값 각각에 대해 개별적으로 gradient가 산출된다. 다만 이것이 하나씩 순차 계산되는 것이 아니라 레이어 단위 행렬 연산으로 일괄 처리되며, 그래서 GPU 가속이 유효하다.
차이가 있다면 gradient 전파 경로가 다소 복잡하다는 점뿐이다. skip connection을 통해 우회 경로로도 흐르고, timestep embedding 쪽으로도 전파된다. 계산 원리 자체는 동일하다.
학습 전체 루프 정리
① x₀, ε, t 추출 ② x_t = √ᾱt·x₀ + √(1−ᾱt)·ε (노이즈 추가, 학습 가중치 없음) ③ ε_θ = U-Net(x_t, t) (여기만 학습 대상) ④ L = ‖ε − ε_θ‖² ⑤ 역전파 → Adam으로 갱신 ⑥ 수백만 회 반복
쉽게 다시 말하면
"채점 결과가 이만큼 나왔으니 부품들은 각자 이 방향으로 조금씩 바꿔라"를 수백만 번 반복하는 것이다. 특별할 것 없이 일반 CNN과 똑같은 방식이며, 다만 지름길(skip connection)과 옆길(timestep embedding)이 있어서 통보가 오가는 길이 조금 복잡할 뿐이다.
4. Diffusion 추론 시 파이프라인
전문 설명 — 학습과의 결정적 차이
학습은 "예측하고 종료"였으나, 추론은 그 예측을 활용하여 실제로 데이터를 개선하는 단계가 세 개 추가된다. 목적이 다르기 때문이다.
쉽게 다시 말하면
학습은 "이 문제 보고 정답 맞혀봐, 채점만 하겠다"였고, 추론은 "정답 맞혀봐(1단계). 이제 그 답으로 실제 문제지를 고쳐 쓰고 다음 문제로 넘어가라(2~4단계)"인 것이다.
4-1. 블록 0 — 초기화
입력
없음
내부 연산
표준 가우시안 N(0,I)에서 완전 무작위 샘플링. 원본도, 학습 데이터도, 어떠한 조건도 필요하지 않다. "평균 0, 분산 1인 정규분포에서 추출한 난수"를 목표 shape만큼 채우는 것이다. 학습 시 epsilon을 추출하던 방식과 완전히 동일하다.
출력
x_T — 순수 노이즈
4-2. 블록 1 — 노이즈 예측 (① 단계)
입력
x_t, t
내부 연산
학습이 완료되어 가중치가 고정된 U-Net에 통과시킨다. 학습 시와 완전히 동일한 연산이다. 동일한 conv, 동일한 downsampling/upsampling, 동일한 timestep embedding 주입 방식이 적용된다. 유일한 차이는 학습 시에는 출력의 오차를 근거로 가중치를 갱신했으나, 추론 시에는 갱신 없이 출력값만 사용한다는 점이다.
출력
epsilon_theta(x_t, t)
전문 설명 — 가장 혼동되기 쉬운 지점
이 시점에서는 "이미지가 선명해진다"는 변화가 전혀 발생하지 않는다. "이 안에 혼입된 노이즈의 정체가 무엇인가"를 추정한 것에 불과하다. 실제 제거 연산은 다음 블록에서 수행된다.
또한 "순수 노이즈에서 진짜 노이즈만 골라낸다"는 표현도 정밀하지 않다. t=T에서 입력은 사실상 전부 노이즈이므로, 두 성분 중 노이즈만 분리해내는 상황이 아니다. 정확히는 **"이 상태 전체를 관측하여, 만약 이것이 어떤 실제 데이터에 씌워진 노이즈라면 그 노이즈가 어떤 값이었을지를 추정"**하는 것이다.
쉽게 다시 말하면
탐정이 현장을 보고 "범인은 이런 인상착의였을 것"이라고 몽타주를 그리는 단계다. 아직 아무도 체포하지 않았다. 몽타주만 그렸을 뿐이다.
4-3. 블록 2 — 평균 계산 (② 단계)
입력
x_t, epsilon_theta
내부 연산
세 조각으로 분해하면 다음과 같다.
① — 예측 노이즈에 계수 적용
epsilon_theta를 그대로 감산하는 것이 아니라, t에 따라 결정된 계수를 곱한 뒤 감산한다. 혼합 시에도 비율로 혼합했으므로 감산 시에도 그 비율에 대응하는 양만큼 제거해야 수학적 정합성이 성립한다. 비율을 무시하고 단순 감산하면 원본도 노이즈도 아닌 왜곡된 값이 산출된다.
② x_t - (①) — 실제 감산 연산
실제로 노이즈를 제거하는 지점이다.
③ frac{1}{sqrt{a_t}} times (②) — 스케일 보정
②에서 감산했으나 값의 전체 스케일이 어긋나 있으므로 원래 스케일로 복원한다. 분산 보존 성질을 유지하기 위한 조치다.
출력
mu_theta — 최종 x_{t-1}이 아니라 **다음 상태 분포의 평균(중심값)**이다.
각주 — a_t와 bar_a_t는 서로 다른 값이다
표기가 유사하여 혼동하기 쉬우나 두 계수는 다르다.
1번 스텝부터 t번 스텝까지 누적곱한 계수
즉 a_t는 "이번 한 스텝에서 신호가 얼마나 살아남는가"이고, bar_a_t는 "처음부터 지금까지 누적으로 얼마나 살아남았는가"다. 위 mu_theta 공식에서 스케일 보정 계수 frac{1}{sqrt{a_t}}는 한 스텝 단위의 보정이고, 노이즈 계수에 들어가는 sqrt{1-bar_a_t}는 누적 기준의 값이다. 다른 자료와 대조할 때 이 둘을 뒤바꾸면 공식이 성립하지 않으므로 주의를 요한다.
전문 설명 — 스케일 보정의 원리
숫자로 단순화하여 보면 다음과 같다. (실제로는 두 계수의 제곱합이 1이 되도록 정해지지만, 여기선 스케일 보정의 원리만 보여주기 위해 편의상 아무 숫자나 골랐다. 아래 2와 3은 분산 보존 조건을 만족하지 않는 임의의 값이다.)
x_t = 2x_0 + 3\epsilon 형태로 혼합되었다고 가정하면, x_0를 복원하려면
x_0 = \frac{x_t - 3\epsilon}{2}
감산을 수행한 뒤, 그 결과를 원래 크기로 복원하기 위해 2로 나누는 절차가 필요하다. 이것이 스케일 보정이다. 실제 공식의 $\frac{1}{sqrt{a_t}}가 정확히 이 역할을 수행한다.
전문 설명 — t가 개입하는 두 지점
전문 설명 — "평균"이라 부르는 이유
다음 단계에서 여기에 확률적 요소를 가산하여 최종 x_{t-1}을 확정하기 때문이다. mu_theta는 그 분포의 중심 역할을 한다.
쉽게 다시 말하면
몽타주(예측 노이즈)를 받아들고 실제로 용의자 명단에서 그 사람을 지우는 단계다. 다만 명단의 배율이 이상하게 조정된 상태라, 지운 뒤에 배율을 원래대로 되돌리는 작업까지 마쳐야 제대로 된 명단이 나온다.
4-4. 블록 3~4 — 확률적 노이즈 가산 및 최종 샘플링 (③④ 단계)
입력
mu_theta
내부 연산
출력
x_{t-1} — 다음 상태 확정
전문 설명 — 노이즈를 제거하면서 다시 가산하는 이유
DDPM은 reverse process도 forward process와 동일하게 확률적(stochastic) 과정이 되도록 설계되었다. forward process 자체가 매 스텝 새 난수를 추출하여 혼합하는 확률 과정이었다. 즉 "정해진 단일 경로"가 아니라 "가능한 여러 경로 중 하나"였다. reverse도 대칭적으로 그렇게 구성한 것이다.
z를 가산하지 않으면 동일한 x_T에서 출발할 경우 항상 완전히 동일한 결과만 산출된다(완전 결정론적). z를 매 스텝 주입하면 최종 결과에 다양성이 발생한다.
전문 설명 — 반드시 정정해야 할 오해
mu_theta 계산 자체가 이미 해당 시점에서 적정한 양만큼 정확히 제거하도록 설계되어 있다. 과잉 제거나 과소 제거를 z가 교정하는 것이 아니다. mu_theta는 "가장 그럴듯한 단일 평균값"이며, 실제 x_{t-1}이 될 수 있는 값은 그 평균 주변에 분포로 산포되어 있다. z의 가산은 그 여러 가능성 중 하나를 선택하는 선택 행위다.
전문 설명 — sigma_t의 정체
해당 스텝에서 허용할 무작위성의 크기를 결정하는 계수다. b_t 스케줄표에 사전 정의된 고정값이며, t가 클 때(초반) 크고 작아질수록(후반) 감소한다. 초반에는 자유롭게 변동하다가 후반으로 갈수록 확정적으로 수렴하는 구조다.
전문 설명 — t=1에서 z를 가산하지 않는 이유
최종 스텝은 결과를 확정하는 단계이므로, 여기서까지 무작위성을 주입하면 불필요한 잡음이 결과물에 잔존한다. 따라서 최종 스텝만 예외적으로 mu_theta를 그대로 사용한다.
쉽게 다시 말하면
조각가가 "이 부분은 정확히 이만큼 깎아야 한다"는 계획(mu_theta)을 세웠다. 그러나 실제로 손으로 깎을 때는 미세한 손 떨림이나 나뭇결의 차이 때문에 매번 조금씩 다른 결과가 나온다. z는 그 자연스러운 미세 변주를 의도적으로 재현하여 주입하는 것이다. "너무 깎였으니 되돌린다"가 아니라 "완전히 동일하게만 나오지 않도록 자연스러운 다양성을 만든다"는 의미다.
4-5. 블록 5 — 반복 및 최종 출력
내부 연산
블록 1~4를 t=T부터 t=1까지 반복한다. 매 반복마다 동일한 U-Net을 그대로 재사용한다. 변경되는 것은 입력 x_t와 t뿐이다. "동일한 함수를 T회 다른 입력으로 호출한다"는 표현이 정확하다.
출력
x_0 — 최종 생성 결과
전문 설명
이것이 diffusion의 속도가 느린 원인이기도 하다. GAN은 단일 forward pass로 종료되나, diffusion은 연산량이 큰 U-Net을 T회(통상 1000회) 반복 호출해야 한다. DDIM 등 고속 샘플러는 이 스텝 수를 20~50회로 축소하는 방향으로 개발되었다.
전체를 요약하면 "노이즈를 예측하여 제거하는 절차의 반복"이 diffusion 추론의 본질이며, 여기에 매 스텝 미세한 무작위성이 부가된다. t가 클 때(초반)는 개략적 구조만 형성되고, t가 작아질수록(후반) 점진적으로 정교화된다.
쉽게 다시 말하면
큰 돌덩이(순수 노이즈)에서 출발하여 "여기 필요 없는 부분이 무엇인가"를 계속 판단하며 깎아내다 보면 원하는 형상이 드러나는 조각 과정이다.
5. 두 모델의 비교
5-1. 구조 비교
전문 설명 — "무작위성 위치" 행에 대한 보충
이 행은 얼핏 "CVAE는 무작위가 한 번만 들어가고 diffusion은 매 스텝 들어간다"는 비대칭으로 읽힐 수 있으나, 기준 단위를 맞추면 실제로는 대칭적이다.
즉 양쪽 모두 "각자의 반복 단위(학습 스텝 / 추론 스텝) 안에서는 한 번씩" 무작위성이 주입된다. 차이는 무작위성 주입 횟수의 절대량이 아니라, 하나의 결과물을 만들어내는 데 몇 번의 반복 단위가 필요한가에 있다.
5-2. 관련 기술의 위치 명세
쉽게 다시 말하면
CVAE는 작은 메모지 한 장(z)에 요약해두고 그걸로 한 번에 그림을 그리는 방식이다. 빠르지만 요약 과정에서 디테일이 뭉개지기 쉽다.
Diffusion은 원본과 같은 크기의 캔버스를 계속 손보는 방식이다. 압축을 안 하니 디테일이 살지만, 같은 붓질을 천 번 해야 해서 느리다.
6. 마무리
전문 설명
ACT는 전자를, Diffusion Policy는 후자를 action decoder로 채택한다.
쉽게 다시 말하면
한 문장씩으로 정리하면, CVAE는 "요약해두고 한 방에 그린다"이고 diffusion은 "잡티에서 시작해 천 번 다듬는다"이다.
다음 단계로 "왜 diffusion이 CVAE보다 multimodal action을 더 잘 표현하는가"를 살펴보면, 이 두 구조의 차이가 실제 로봇 성능에서 어떻게 갈리는지 이어서 확인할 수 있을 것이다.
|
|
첫댓글 잘 정리했네요 이제 이론도 알았으니 잘안되는 문제를 분석하고 개선해보길 바랍니다.