[기본기 0-4] 딥러닝을 위한 확률/통계 최소셋 (베이즈 관점)
딥러닝 학습의 본질은 "데이터가 주어졌을 때 어떤 파라미터가 가장 그럴듯한가"를 찾는 것이다. 이 문서는 그 질문을 확률 언어로 바꾸는 가장 기본적인 흐름을 설명한다.
베이즈 관점이 좋은 이유는 딥러닝 학습을 단순한 최적화 문제가 아니라 "믿음이 어떻게 업데이트되는가"라는 이야기로 바꿔주기 때문이다. 데이터를 보기 전에는 어떤 파라미터가 좋을지 막연하지만, 데이터를 본 뒤에는 어떤 파라미터가 더 그럴듯한지 말할 수 있다.
초심자 입장에서는 기호가 많아 보이지만 질문은 하나뿐이다. "데이터를 보고 나서 어떤 모델을 더 믿게 되는가?" 이 질문에 답하는 틀이 베이즈 정리다. 이후 MLE, MAP, variational inference도 모두 이 구조의 변형으로 이해할 수 있다.
시각 자료로 먼저 보기
왜 베이즈 관점이 중요한가
\theta: 모델 가설(파라미터)D: 관측 데이터p(\theta|D): 데이터를 본 뒤의 믿음(사후확률)
즉 데이터가 들어오면 모델에 대한 믿음이 업데이트된다. 베이즈 관점은 이 업데이트를 수식으로 적는 방법이다.
이 관점이 중요한 이유는, 같은 학습 과정을 더 풍부하게 해석하게 해주기 때문이다. 단순히 loss를 줄인다고만 말하면 계산 절차만 보이지만, posterior 관점으로 보면 "데이터가 기존 믿음을 어떻게 밀어냈는가"까지 설명할 수 있다.
1) 베이즈 정리
p(\theta|D): 사후확률 (posterior)p(D|\theta): 우도 (likelihood)p(\theta): 사전확률 (prior)p(D): 정규화 상수. "전체 확률을 1로 맞추는 역할"이라고 생각하면 된다.
이 식은 "원래 믿고 있던 것(prior)"과 "데이터가 얼마나 잘 설명되는가(likelihood)"를 합쳐서 "업데이트된 믿음(posterior)"을 만드는 공식이다.
이 문장을 붙잡고 있으면 수식이 덜 추상적으로 느껴진다. prior는 시작점이고, likelihood는 데이터가 주는 증거이며, posterior는 둘을 결합한 최종 판단이다. 즉 데이터 설명력과 기존 믿음이 함께 작동한다.
각 항의 의미를 표로 다시 보면 다음과 같다.
| 기호 | 의미 |
|---|---|
p(\theta|D) | 데이터를 본 뒤 파라미터에 대한 믿음, 즉 사후확률 |
p(D|\theta) | 주어진 파라미터가 데이터를 얼마나 잘 설명하는지 나타내는 우도 |
p(\theta) | 데이터를 보기 전 파라미터에 대한 초기 믿음, 즉 사전확률 |
p(D) | 데이터 자체가 관측될 확률로, 정규화 상수 역할을 한다 |
직관적으로 보면 posterior = likelihood × prior 구조다. 즉 데이터 설명력과 기존 믿음이 결합되어 최종적인 모델 믿음이 정해진다.
왜 딥러닝에서는 prior를 자주 생략할까
실무 딥러닝에서는 대규모 신경망에 대해 prior를 명시적으로 설계하고 계산하는 일이 어렵다. 그래서 자주 아래처럼 단순화한다.
여기서 prior를 거의 상수처럼 취급하면, 결국 "우도를 가장 크게 만드는 파라미터"를 찾는 문제가 된다.
이것이 Maximum Likelihood Estimation, 즉 MLE다. 딥러닝 학습을 "데이터 확률을 최대화하는 파라미터 찾기"라고 설명하는 이유가 여기 있다.
MLE와 MAP는 무엇이 다른가
둘 다 좋은 파라미터를 찾는 방법이지만, 무엇을 최적화하느냐가 다르다.
MLE는 오직 데이터가 얼마나 잘 설명되는지만 본다. 반면 MAP는 prior까지 고려해서, "원래 그럴듯하다고 생각한 파라미터 범위"를 더 선호한다.
직관적으로는 다음처럼 이해하면 된다.
- MLE: 데이터만 보고 최대한 잘 맞추기
- MAP: 데이터도 보되, 너무 이상한 파라미터는 prior로 억제하기
그래서 MAP는 regularization과도 연결된다. 예를 들어 가우시안 prior를 두면, 결과적으로 큰 가중치를 억제하는 형태가 되어 L2 regularization과 비슷한 효과가 나온다.
실무 딥러닝에서는 보통 MLE 관점으로 설명을 시작하지만, weight decay나 Bayesian learning을 이해하려면 MAP 관점이 훨씬 자연스럽다.
2) 우도 (Likelihood)
우도는 p(D|\theta)다. 의미는 "파라미터 \theta가 주어졌을 때, 지금 관측한 데이터 D가 나올 확률"이다.
예를 들어 \theta_1은 고양이 이미지를 잘 분류하고, \theta_2는 잘 분류하지 못한다면 보통 p(D|\theta_1) > p(D|\theta_2)로 해석할 수 있다.
그래서 가장 좋은 파라미터는 우도를 가장 크게 만드는 값으로 잡는다.
주의: 우도는 데이터를 고정하고 파라미터에 대해 비교하는 관점이라서, \theta에 대한 일반적인 확률분포와 완전히 같은 방식으로 읽으면 안 된다.
3) 로그우도 (Log Likelihood)
실제 데이터셋은 보통 하나의 샘플이 아니라 여러 샘플로 이루어진다.
각 데이터가 독립적으로 생성되었다고 가정하면 전체 데이터의 우도는 각 샘플 우도의 곱으로 쓸 수 있다.
- 곱셈을 덧셈으로 바꿔 계산이 쉬워짐
- 수치 안정성 개선(아주 작은 값 언더플로우 완화)
즉 전체 데이터 확률은 각 데이터 확률의 곱이고, 로그를 취하면 각 샘플의 로그 확률을 더하는 형태가 된다.
왜 로그를 쓰는지가 중요하다. 확률은 보통 매우 작은 값이라서 여러 개를 곱하면 금방 0에 가까워진다. 예를 들어 0.001 × 0.002 × 0.0003 같은 값은 컴퓨터에서 다루기 불편하다.
하지만 로그를 취하면 아주 작은 값도 다루기 쉬운 숫자로 바뀐다. 예를 들어 10^{-30}은 로그를 취하면 -30 수준으로 바뀐다.
또한 \log(a \times b \times c) = \log a + \log b + \log c 이므로, 복잡한 곱 계산을 단순한 합 계산으로 바꿀 수 있다. 그래서 딥러닝에서는 로그우도를 기본 도구처럼 사용한다.
그래서 최종 목표는 다음처럼 쓸 수 있다.
이 식의 의미는 단순하다. 각 데이터 샘플 x_i를 모델이 얼마나 잘 설명하는지 로그확률로 계산하고, 그 값을 모두 더한 뒤, 그 합이 가장 커지도록 파라미터 \theta를 찾는 것이다. 이것을 log likelihood 최대화라고 한다.
4) Loss가 등장하는 이유: NLL
우리는 본질적으로 maximize log likelihood, 즉 로그우도를 최대화하고 싶다. 하지만 딥러닝 프레임워크는 대개 loss를 최소화하는 인터페이스로 설계되어 있다.
그래서 부호를 반대로 바꿔 다음처럼 쓴다.
이것이 바로 Negative Log Likelihood, 즉 NLL이다. 이름 그대로 로그우도 앞에 마이너스를 붙인 값이다.
그래서 아래 세 문장은 모두 같은 뜻이다.
- log likelihood를 최대화한다.
- negative log likelihood를 최소화한다.
- loss를 최소화한다.
즉 log likelihood 최대화 = NLL 최소화다. 부호만 바뀌었을 뿐, 모델이 데이터를 더 잘 설명하게 만든다는 본질은 달라지지 않는다.
5) Cross Entropy와 연결
분류 문제에서는 보통 정답 라벨 y가 주어졌을 때, 모델이 그 정답을 얼마나 높은 확률로 맞히는지를 본다.
이 형태가 바로 분류에서 자주 쓰는 CrossEntropyLoss와 연결된다.
원-핫 라벨 분류에서는 실제 정답이 한 클래스에만 1을 주기 때문에, 결국 모델이 정답 클래스에 부여한 확률이 핵심이 된다.
- 모델이 정답 클래스에 높은 확률을 주면 loss가 작다.
- 모델이 정답 클래스에 낮은 확률을 주면 loss가 크다.
예를 들어 정답이 cat일 때
p(cat|x)=0.9이면 loss는 작다.p(cat|x)=0.1이면 loss는 매우 커진다.
즉 Cross Entropy는 "정답에 얼마나 확신을 줬는가"를 벌점 형태로 측정하는 함수다.
원-핫 라벨 설정에서는 Cross Entropy를 최소화하는 것이 Negative Log Likelihood를 최소화하는 것과 사실상 같은 의미다. 그래서 분류 문제에서는 CrossEntropyLoss를 쓰는 것이 곧 정답 로그확률을 최대화하는 것과 연결된다.
즉 아래 흐름으로 이해하면 된다.
6) 기댓값 (Expectation)
딥러닝의 loss는 보통 데이터 분포에 대한 평균으로 해석됩니다.
E[L(x)]는 "샘플 하나하나의 loss를 장기적으로 평균내면 어떤 값이 되는가"를 뜻한다.
직관적으로 말하면 expectation은 확률 가중 평균이다. 실제 딥러닝에서는 전체 데이터 분포를 알 수 없으므로, 샘플 평균으로 이 기댓값을 근사한다.
코드에서 자주 보는 loss.mean()은 바로 이 기댓값 근사와 연결된다.
7) 분산 (Variance)
Var(X)=\mathbb{E}[(X-\mu)^2]
여기서 \mu = \mathbb{E}[X]다. 즉 분산은 값이 평균에서 얼마나 퍼져 있는지를 나타낸다.
분산은 불확실성이나 퍼짐 정도를 나타내며, 딥러닝에서는 정규화(BatchNorm), 초기화 안정성, gradient 해석과 직접 연결된다.
특히 SGD에서는 gradient가 사실상 확률 변수처럼 움직인다.
미니배치가 바뀔 때마다 gradient 값도 달라지므로 gradient variance가 존재한다. 이 분산이 너무 크면 학습이 흔들리고, loss가 진동하며, 수렴 속도가 느려질 수 있다.
그래서 실전에서는 BatchNorm, Adam, larger batch size, gradient clipping 같은 기법으로 분산과 학습 안정성을 함께 관리한다.
우도 vs 사후확률 (핵심 차이)
| 개념 | 수식 | 의미 |
|---|---|---|
| 우도 | p(D|\theta) | 파라미터가 주어졌을 때 데이터 확률 |
| 사후확률 | p(\theta|D) | 데이터가 주어졌을 때 파라미터 확률 |
코드-수식 연결
| 수식 | PyTorch 코드 | 설명 |
|---|---|---|
p(D|\theta) | model(x) | 모델의 데이터 설명력 |
\log p(x) | torch.log(p) | 로그 확률 |
\sum \log p(x) | log_prob.sum() | 로그우도 누적 |
\mathbb{E}[L] | loss.mean() | 평균 loss |
딥러닝 코드와 수식의 대응 관계
실제 딥러닝 코드는 복잡해 보여도, 핵심 구조는 확률 모델의 수식을 구현한 형태로 볼 수 있다.
| 수식 | PyTorch 코드 | 의미 |
|---|---|---|
p(D|\theta) | model(x) | 현재 파라미터가 데이터를 얼마나 잘 설명하는지 |
\log p(x) | torch.log(p) | 로그 확률 |
\sum \log p(x) | log_prob.sum() | 전체 데이터에 대한 로그우도 누적 |
\mathbb{E}[L] | loss.mean() | 배치 기준 평균 loss |
전체 흐름: 딥러닝 학습의 수식 구조
딥러닝 학습은 구현 세부가 다양해 보여도, 큰 흐름은 거의 항상 아래 순서를 따른다.
- 데이터 관측
D = \{x_1, x_2, ...\} - 모델 확률 계산
p(x|\theta) - 로그우도 계산
\log p(D|\theta) - NLL loss로 변환
L = -\log p(D|\theta) - 평균 loss 계산
\mathbb{E}[L]또는 미니배치 평균loss.mean() - 파라미터 업데이트
gradient descent로\theta를 조정
이 흐름을 한 문장으로 요약하면, 딥러닝은 데이터를 잘 설명하는 확률 모델을 학습하는 과정이다.
자주 하는 오해 5개
- 우도와 확률을 완전히 동일하게 생각한다
- prior를 항상 명시적으로 넣어야만 학습 가능하다고 생각한다
- 로그우도를 단순 계산 트릭으로만 본다
- 기댓값이 실제 샘플 평균과 항상 정확히 같다고 생각한다
- 베이즈 관점은 실무 딥러닝과 무관하다고 생각한다
체크리스트
- 베이즈 정리가 무엇을 업데이트하는 공식인지 설명 가능한가?
- 우도와 사후확률 질문의 방향 차이를 설명 가능한가?
- 왜 로그우도를 쓰는지 수치 관점으로 설명 가능한가?
- 기댓값과 평균 loss의 연결을 설명 가능한가?
- 분산이 학습 안정성과 어떤 관련이 있는지 설명 가능한가?