본문 바로가기
C.W.K.
Stream
Lesson 04 of 05 · published

로그 공간 계산: 작은 확률을 안정적으로 다루기

~8 min · log-likelihood, stability, logsumexp

Level 0수학 초심자
0 XP0/59 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete

로그값인 채로 확률을 더하려면

로그확률은 곱을 합으로 바꾸기 좋지만, 원래 확률의 합을 구하려면 꼴이 생겨. 가 아주 작으면 지수화한 값이 0으로 밑돌고, 아주 크면 넘칠 수 있어. 이때 쓰는 표준 도구가 log-sum-exp야.

가장 큰 값을 빼면 모든 지수의 입력이 0 이하가 돼서 넘침을 막고, 가장 큰 항은 정확히 이라 전부 0으로 밑도는 일도 피할 수 있어. 끝에 을 더하면 원래 크기로 돌아와.

softmax의 안정성도 같은 원리

softmax는 를 지수의 합으로 나눠. 순진하게 계산하면 큰 양의 logit에서 먼저 넘칠 위험이 커. 모든 logit에서 최댓값을 빼도 softmax 결과는 변하지 않으므로, 프레임워크는 이 이동을 이용해 안정적으로 계산해.

로그확률이 필요하다면 log(softmax(x))를 두 단계로 만들지 말고 log_softmax(x)를 써. 아주 작은 확률을 먼저 0으로 만든 뒤 로그를 취하는 실수를 피할 수 있어.

지수의 합에 로그를 씌우는 순간 logsumexp를 떠올려. 직접 구현하기보다 SciPy·PyTorch처럼 검증된 함수를 쓰는 게 안전해.

Code

`logsumexp`를 안정적으로 계산하기·python
import numpy as np
from scipy.special import logsumexp

# 수치적으로 위험: 매우 음수 로그-prob
log_probs = np.array([-1000., -1001., -1002.])

# Naive: log(sum(exp(...)))
naive = np.log(np.sum(np.exp(log_probs)))   # -inf — underflow

# 안정: logsumexp
stable = logsumexp(log_probs)
print(stable)                                # ~-999.59 — 정답

External links

Exercise

logsumexp를 직접 구현해. 로그값 배열에서 최댓값을 빼고 지수화한 뒤 합의 로그를 구하고 최댓값을 다시 더해. [-1000, -1001, -1002]에서 scipy.special.logsumexp와 비교해.
Hint
`` m = log_probs.max() stable = m + np.log(np.sum(np.exp(log_probs - m))) ``

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 2

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.
  1. Elechemist
    Elechemist

    import numpy as np from scipy.special import logsumexp

    logs = np.array([-1000, -1001, -1002])

    m = np.max(logs) shifted = logs - m exp_terms = np.exp(shifted) s = np.sum(exp_terms) manual = m + np.log(s)

    scipy_result = logsumexp(logs)

    print("manual :", manual) print("scipy :", scipy_result) print("diff :", abs(manual - scipy_result))

    출력

    manual : -999.5923940355556

    scipy : -999.5923940355556

    diff : 0.0

    언더플로우를 방지하려고 하는 기법인가보다. 에러값이 점점 작아질수록 중요한작업인듯,, 잘못하면 에러가있는데도 0으로 처리해버릴수있으니

    1. 피파
      피파· warmElechemistElechemist

      네, 정확해요. logsumexp는 “언더플로우를 피하면서 로그 확률들을 안전하게 합치는 기법”이라고 보면 돼요.

      핵심은 m = np.max(logs)로 제일 큰 값을 기준점으로 잡고, 나머지를 logs - m처럼 상대값으로 옮긴다는 점이에요. 그러면 exp(-1000)처럼 바로 0에 가까워지는 계산 대신 exp(0), exp(-1), exp(-2)처럼 안전한 범위에서 계산할 수 있거든요.

      말씀하신 것처럼 에러나 확률이 아주 작아지는 작업일수록 중요해요. 그냥 0으로 뭉개지면 “아주 작다”와 “진짜 없다”를 구분하지 못하니까요.