놀라움과 정보

분류 모델을 학습시킬 때 늘 줄이는 cross-entropy loss 안에도, 두 분포가 얼마나 다른지 재는 KL 발산 안에도 log가 들어 있다. KL 발산은 데이터가 실제로 따르는 분포 p(이 장에서는 「현실 p」라 부른다)와 모델이 내놓는 분포 q에 대해 KL(p‖q) = Σ pi log(pi/qi)라는 숫자를 내놓는 "비대칭 거리"다. ‖의 왼쪽에 현실 p를, 오른쪽에 모델 q를 적는데, 두 분포의 자리를 바꾼 KL(q‖p)는 대개 KL(p‖q)와 값이 다르다. 그런데 KL(p‖q)라는 숫자는 무엇을 재는가? 왜 하필 log인가? 왜 KL은 늘 0 이상인가? 실마리는 전화선으로 글자를 보내던 공학자의 물음에서 나왔다.

놀라움: 예상 밖의 일은 정보가 크다

“해가 뜨는 건 뉴스가 안 되는데 일식은 뉴스가 된다. 놀라움을 숫자로 쓸 수 있나?”

드문 일일수록 뉴스가 된다는 것은 누구나 안다. 기자들 사이에는 "개가 사람을 물면 뉴스가 안 되고, 사람이 개를 물면 뉴스가 된다"는 말이 전해진다. 하지만 "얼마나 놀라운가"는 느낌이라, 이대로는 두 소식 가운데 어느 쪽이 몇 배 놀라운지 말할 수 없다. 느낌 대신 셀 수 있는 것이 필요하다.

다음 글자 맞히기: 섀넌이 센 것

1951년 벨 연구소의 클로드 섀넌(Claude Shannon)은 「놀라움을 숫자로 잴 수 있는가」라는 물음을 실험으로 바꿨다. 사람에게 처음 보는 영어 글을 한 글자씩 맞히게 하고 글자마다 몇 번째 추측에서 맞혔는지 세었더니, MOTORCYCL 다음의 E처럼 단어 안쪽의 글자는 대개 한 번에 맞혔고 틀린 추측은 새 단어의 첫 글자에 몰렸다. 첫 추측에 맞힌 글자를 지운 줄로도, 똑같이 추측하는 쌍둥이가 곁에 있으면 원래 글을 되살릴 수 있다. 그러니 글자 하나가 알려 주는 양은 글자 자체가 아니라 받는 사람이 그 글자에 매긴 확률에 달려 있고, 앞 문맥을 충분히 아는 사람에게 영어 글자 하나는 평균 1비트 안팎이었다(알파벳 26개를 같은 확률로 보면 4.7비트).

스무고개: 답의 개수로 재기

"얼마나 맞히기 어려운가"를 숫자로 만드는 데는 스무고개가 가장 단순한 시험대다. 질문이 예/아니오뿐이라 답 하나가 셀 수 있는 한 단위가 되기 때문이다. 똑같이 그럴듯한 후보가 8개 있으면, 후보를 반씩 가르는 질문 세 번으로 답을 찾는다. 확률이 1/8인 결과를 알리는 데는 예/아니오 답 3개가 든다. 후보가 2개(확률 1/2)면 답 1개, 1,024개(확률 1/1024)면 답 10개다. 확률이 1/2k이면 답의 개수는 k = log₂(1/p) = −log₂ p다.

스무고개로 재는 소식의 크기: 후보 8개는 예/아니오 답 3개로 가려지고, 서로 무관한 소식 둘은 후보 수가 곱해지고 답의 개수가 더해진다
스무고개로 재는 소식의 크기: 후보 8개는 예/아니오 답 3개로 가려지고, 서로 무관한 소식 둘은 후보 수가 곱해지고 답의 개수가 더해진다

서로 아무 상관이 없는 소식 두 개를 한꺼번에 들으면 어떨까? 동전의 앞뒤(후보 2개)와 여덟 칸 가운데 한 칸(후보 8개)를 함께 알리면, 가능한 경우는 2 × 8 = 16가지이고 답은 1 + 3 = 4개다. 후보의 수는 곱해지는데 답의 개수는 더해진다. 확률로 말하면, 독립인 두 사건이 함께 일어날 확률은 곱해지고(P(A∩B) = P(A)·P(B)), 그 소식을 알리는 데 드는 답은 더해진다.

확률이 1/6처럼 1/2k 꼴이 아니면 −log₂ p는 2.58처럼 정수가 아닌 값이 된다. 질문은 정수 번만 할 수 있는데, 2.58 같은 −log₂ p는 무엇을 세는 것일까? 그 뜻은 아래 문제 1(자전거 자물쇠 번호)에서 질문 수와 bit를 나란히 세어 보며 따져 본다.

왜 −log인가

이제 「소식을 알리는 데 드는 예/아니오 답의 개수」를 확률 p의 함수로 쓰고 싶다. 확률이 작을수록 커져야 한다는 조건만 보면 1/p도 되고 1 − p도 될 것 같아서, 후보는 많아 보인다.

그런데 스무고개에서 본 약속, 곧 독립인 사건 두 개가 함께 일어나면 답의 개수는 더해져야 한다는 조건을 더하면 후보가 거의 다 떨어진다. 확률이 0.1인 독립 사건 두 개로 시험해 보자. 함께 일어날 확률은 0.01이다. 1/p는 따로 더하면 10 + 10 = 20인데, 함께는 1/0.01 = 100이다. 1 − p는 따로 더하면 0.9 + 0.9 = 1.8인데 함께는 0.99여서, 1/p와 1 − p 둘 다 탈락이다.

곱을 덧셈으로 바꾸는 함수가 필요하다. 확률이 작을수록 커진다는 조건 아래에서, 그런 함수는 양의 상수 c를 곱한 −c·log p 꼴뿐이며, 이 유일성은 아래 문제 2에서 증명한다.

정의

h(x)=−log⁡p(x)\textcolor{#9467bd}{h}(\textcolor{#6f8fa6}{x}) = -\log \textcolor{#d6479f}{p}(\textcolor{#6f8fa6}{x})
h(x)결과 x 의 놀라움 (정보량, 자기정보량)p(x)결과 x 가 나올 확률 (전해 듣는 사람이 매긴 확률)x일어난 결과log⁡로그. 밑이 2 면 단위는 bit, 밑이 e 면 nat\begin{array}{ll} \textcolor{#9467bd}{h}(\textcolor{#6f8fa6}{x}) & \text{결과 } x \text{ 의 놀라움 (정보량, 자기정보량)} \\ \textcolor{#d6479f}{p}(\textcolor{#6f8fa6}{x}) & \text{결과 } x \text{ 가 나올 확률 (전해 듣는 사람이 매긴 확률)} \\ \textcolor{#6f8fa6}{x} & \text{일어난 결과} \\ \log & \text{로그. 밑이 2 면 단위는 bit, 밑이 } e \text{ 면 nat} \end{array}

−log p(x)를 결과 x의 정보량이라 부르고, 흔히 놀라움(surprisal)이라고도 부른다. 거의 확실하던 일이 일어나면 놀라지 않고 드문 일이 일어나면 크게 놀란다는 느낌에서 붙은 이름이다. 하지만 이 장에서 "놀라움"은 느낌이 아니라 늘 숫자 −log p(x), 곧 결과 x를 전해 듣는 사람이 새로 받아야 하는 예/아니오 답의 개수를 가리킨다. 그리고 p는 전해 듣는 사람이 결과 x에 매긴 확률이다. MOTORCYCL 뒤의 E가 영어를 아는 사람에게는 거의 0 bit이고 영어를 모르는 사람에게는 큰 소식인 것도 그래서다. 듣는 사람이 매긴 확률이 현실과 어긋나면 어떻게 되는지는 이 장의 크로스 엔트로피 절에서 다룬다.

놀라움의 단위는 로그의 밑에 따라 붙는다. log₂를 쓰면 단위가 bit(binary digit, 예/아니오 답 하나)여서 동전 앞면(p = ½)의 놀라움이 1 bit이고, 자연로그 ln을 쓰면 단위가 nat(natural unit)이다. 이 책의 식은 수학 계산이 깔끔한 nat을 대부분 쓰는데, 두 단위는 상수배만큼 차이 난다. 1 nat = 1/ln 2 ≈ 1.443 bit, 1 bit = ln 2 ≈ 0.693 nat. numpy의 np.log는 자연로그이므로, bit가 필요하면 np.log2를 쓴다.

직접 움직여 보기

불러오는 중…

ML에서: 정답에 준 확률의 놀라움이 곧 loss

분류 모델은 사진 한 장을 보고 후보마다 확률을 내놓는다. 실제 정답 「고양이」에 0.8을 주었다면, 그 사진에서 모델이 받은 놀라움은 −ln 0.8 ≈ 0.22 nat이고, 0.01만 주었다면 −ln 0.01 ≈ 4.61 nat이다. 분류 모델을 학습시킬 때 사진 한 장마다 매기는 loss가 바로 이 놀라움이다. 현실에서 흔히 일어나는 일에 크게 놀라는 모델은 현실을 잘 모르는 모델이고, 학습은 그 놀라움을 줄여 간다. 언어 모델도 섀넌의 피험자처럼 앞 글을 보고 다음 토큰을 맞히는 놀이를 하고, 실제로 온 토큰에 준 확률의 놀라움으로 채점된다.

파이썬

import numpy as np

events = {"동전 앞면": 0.5, "주사위 6": 1/6, "생일이 오늘": 1/365, "동전 앞면 10번 연속": 0.5**10}
for name, p in events.items():
    print(f"{name}: p={p:.5f}  놀라움 {-np.log2(p):6.2f} bit  {-np.log(p):6.2f} nat")

# 독립인 두 사건: 확률은 곱해지고 놀라움은 더해진다
p1, p2 = 0.1, 0.1
for name, f in {"-log2 p": lambda p: -np.log2(p), "1/p": lambda p: 1 / p, "1-p": lambda p: 1 - p}.items():
    print(f"{name}: 따로 더하기 {f(p1) + f(p2):7.3f}   함께 {f(p1 * p2):7.3f}")
# 동전 앞면: p=0.50000  놀라움   1.00 bit    0.69 nat
# 주사위 6: p=0.16667  놀라움   2.58 bit    1.79 nat
# 생일이 오늘: p=0.00274  놀라움   8.51 bit    5.90 nat
# 동전 앞면 10번 연속: p=0.00098  놀라움  10.00 bit    6.93 nat
# -log2 p: 따로 더하기   6.644   함께   6.644
# 1/p: 따로 더하기  20.000   함께 100.000
# 1-p: 따로 더하기   1.800   함께   0.990

동전 앞면 10번 연속은 1 bit짜리 놀라움 열 개가 더해진 것이어서 정확히 10 bit다.

이 절의 결론

“놀라움 = −log(확률) = 결과를 전해 듣는 사람이 새로 받아야 하는 예/아니오 답의 개수. 곱해지는 확률을 더해지는 답의 개수로 바꾼다.”

문제 1. 자물쇠 번호는 몇 bit인가

친구가 자전거 자물쇠의 네 자리 번호를 0000부터 9999까지 모두 같은 확률로 정했다. (가) 번호를 알게 된 놀라움은 몇 bit인가? 예/아니오 질문으로 번호를 알아내려면 몇 번이면 충분한가? (나) 친구가 먼저 "첫 자리는 7이야"라고 알려 주었다. 이 소식의 놀라움과, 그 뒤에 남은 세 자리를 알게 될 때의 놀라움은 각각 몇 bit인가? 둘을 더하면 (가)와 같은가? (다) (가)와 (나)를 bit 대신 질문 수로 세어 보라. 질문 수에서는 무엇이 어긋나고, 질문 수와 bit의 차이는 무엇을 말해 주는가?

네 자리 자물쇠 번호: 아무것도 모를 때 가능한 번호 10,000가지와, 첫 자리가 7이라는 소식을 들은 뒤 남은 1,000가지
네 자리 자물쇠 번호: 아무것도 모를 때 가능한 번호 10,000가지와, 첫 자리가 7이라는 소식을 들은 뒤 남은 1,000가지

함께 풀기

김민준 M01
김민준

번호가 10,000개니까 놀라움은 log₂ 10000 ≈ 13.29 bit예요. 질문은 2¹³ = 8,192로는 모자라고 2¹⁴ = 16,384면 되니까 14번이고요.

이서연 S01
이서연

(나)는 첫 자리가 열 가지 가운데 하나니까 log₂ 10 ≈ 3.32 bit, 남은 세 자리는 log₂ 1000 ≈ 9.97 bit. 더하면 13.29 bit로 (가)와 같아.

선생님 T01
선생님

그럼 (다)요. 질문 수로 똑같이 나눠 세면요?

김민준 M01
김민준

첫 자리는 2³ = 8로는 모자라니까 4번, 남은 세 자리는 2¹⁰ = 1,024면 되니까 10번. 4 + 10 = 14로 (가)의 14번과 같네요. 어긋나는 게 없는데요.

선생님 T01
선생님

네 자리를 한 자리씩 따로 물으면요?

김민준 M04
김민준

한 자리에 4번씩이니까 16번이요. 어, 14번보다 많아요. 같은 번호인데 나눠 물으면 질문이 늘어나네요.

이서연 S01
이서연

한 자리는 3.32 bit인데 질문은 정수라서 4번으로 올려야 해. 자리마다 0.68번씩 버리는 거야. bit는 나눠도 합쳐도 13.29로 그대로인데, 질문 수는 어떻게 묶느냐에 따라 달라져.

선생님 T01
선생님

그러면 3.32 bit라는 정수가 아닌 숫자는 무엇을 세는 걸까요? 자물쇠 백 개의 첫 자리를 모아서 한꺼번에 묻는다면요?

이서연 S01
이서연

백 개를 모으면 후보가 10¹⁰⁰개니까… log₂ 10¹⁰⁰ ≈ 332.19, 질문은 333번이에요.

김민준 M01
김민준

그럼 한 자리에 3.33번꼴이네. 따로 물을 때 4번보다 훨씬 적어.

선생님 T01
선생님

더 많이 모으면 한 자리당 질문 수는 어떻게 될까요?

이서연 S07
이서연

올림으로 버리는 건 모은 전체에서 1번이 안 되니까, 많이 모을수록 한 자리당 질문 수가 3.32에 다가가요. 3.32 bit는 한 번에 묻는 질문 수가 아니라, 많이 모아 물을 때 한 자리에 드는 질문 수예요.

선생님 T01
선생님

그래요. 놀라움이 더해진다는 약속은 bit로 셀 때 늘 맞고, 한 자리당 질문 수는 모아서 물을수록 3.32에 다가가요.

김민준 M01
김민준

조별 과제에서 한 사람이 1.3시간 걸리는 일을 한 시간 단위로만 신청하게 하면 네 명이 2시간씩 8시간을 적는데, 네 명의 일 5.2시간을 모아 신청하면 6시간이면 되는 거랑 같네요.

위젯에서 확인 → 위 놀라움 위젯의 「문제 1 값 불러오기 (0.1, 0.001)」 단추로 두 소식의 확률을 불러와, 두 놀라움의 합을 견주어 볼 수 있다.

문제 2. 놀라움은 왜 −log인가 (킬러)

놀라움 h(p)가 (0, 1]에서 정의되고 다음을 만족한다고 하자. ① 가법성: 모든 p₁, p₂에 대해 h(p₁p₂) = h(p₁) + h(p₂). ② 단조성: p가 작을수록 h(p)가 크다. 가법성과 단조성 두 성질만으로 놀라움이 반드시 h(p) = −c log p (c > 0) 꼴임을 증명하라. 상수 c는 무엇을 뜻하는가?

독립인 두 사건의 확률 0.5와 0.4는 곱해져 0.2가 되고, 놀라움 h는 따로의 놀라움을 이어 붙인 길이가 되어야 한다는 가법성 조건(막대 길이는 정하지 않았다)
독립인 두 사건의 확률 0.5와 0.4는 곱해져 0.2가 되고, 놀라움 h는 따로의 놀라움을 이어 붙인 길이가 되어야 한다는 가법성 조건(막대 길이는 정하지 않았다)

함께 풀기

김민준 M01
김민준

코드로 확인했어요. h(p) = −log p에 p = 0.1, 0.2, 0.5를 넣어 보니 h(0.1 × 0.5) = h(0.1) + h(0.5)가 맞아요. 다른 조합도 다 맞고요.

선생님 T01
선생님

민준 학생이 확인한 건 어느 방향이에요?

김민준 M01
김민준

−log가 조건을 만족한다는 거요. 문제는 조건을 만족하는 게 −log밖에 없다는 거고요. 방향이 반대네요.

이서연 S01
이서연

그건 제가 해 볼게요. p = e−x로 두고 g(x) = h(e−x)라 하면 가법성이 g(x + y) = g(x) + g(y)가 돼요. 코시 방정식이요.

이서연 S01
이서연

일단 정수부터요. g(1)을 n번 더한 거니까 g(n) = n·g(1).

선생님 T01
선생님

1/n은요?

이서연 S01
이서연

g(1) = g(n·(1/n)) = n·g(1/n)이니까 g(1/n) = g(1)/n.

김민준 M01
김민준

그럼 m/n은 1/n을 m번 더한 거니까 m·g(1)/n이네.

이서연 S01
이서연

응. 합치면 모든 양의 유리수 r에서 g(r) = r·g(1)이에요. c = g(1)로 두면 g(x) = cx, 그러니까 h(p) = −c log p예요. 끝이요.

선생님 T01
선생님

x가 √2면요?

이서연 S01
이서연

√2도 유리수로 한없이 가까이 갈 수 있으니까 g(√2) = √2·c죠.

선생님 T01
선생님

그 "가까이 가면 값도 가까이 간다"는 어디서 왔어요?

이서연 S05
이서연

…연속성이요. 그런데 조건에는 연속성이 없고 단조성만 있어요. 그리고 제가 그걸 안 쓰고 넘어갔어요.

선생님 T01
선생님

단조성을 빼면 어떻게 돼요?

이서연 S01
이서연

코시 방정식은 연속성 같은 조건이 없으면 유리수 위에서만 선형이고, 실수 전체에서는 이상한 해가 있어요. 실수를 유리수 위의 벡터공간으로 보고 기저를 잡아서 만드는 해요. 그래프가 평면 어디에나 빽빽하게 퍼지는 함수라서, 어느 구간에서도 단조일 수 없어요.

선생님 T01
선생님

그러면 단조성은 그런 함수를 어떻게 막을까요? x 하나를 유리수 둘 사이에 끼워 보면요?

이서연 S01
이서연

r < x < r′로 끼우면… g가 증가함수니까 g(r) ≤ g(x) ≤ g(r′)요. 양 끝은 유리수라 아는 값이에요. cr ≤ g(x) ≤ cr′.

선생님 T01
선생님

r과 r′를 x로 조여 가면요?

이서연 S08
이서연

양 끝이 둘 다 cx로 가니까 g(x) = cx예요. 단조성이 유리수에서 실수로 건너가는 다리였어요.

김민준 M05
김민준

잠깐, 그럼 c가 음수여도 되는 거 아니에요? cx도 가법적이잖아요.

이서연 S01
이서연

단조성의 방향이 정해 줘. p가 작을수록, 곧 x가 클수록 h가 커야 하니까 c > 0.

선생님 T01
선생님

그래요. 그러면 c는 무엇을 뜻해요?

김민준 M01
김민준

−c log p = −logb p가 되게 밑을 고르는 거 아니에요?

선생님 T01
선생님

c = 1이면 무슨 단위예요? bit가 되려면 c가 얼마여야 하고요?

김민준 M08
김민준

c = 1이면 nat, c = 1/ln 2면 bit. 앞에서 본 bit와 nat의 그 상수배예요. 공리가 정할 수 없는 건 단위뿐이에요.

선생님 T13
선생님

그래요. 가법성이 log 꼴을 정하고, 단조성이 유리수에서 실수로 넘어가는 다리와 c의 부호(c > 0)를 정하고, 남은 상수는 단위예요. 민준 학생은 "만족한다"와 "그것뿐이다"를 구분했고, 서연 학생은 증명에서 조건 하나가 어디에 쓰이는지 찾았어요.

김민준 M01
김민준

보고서 쓸 때 가정 목록에 쓴 가정이 본문 어디서 쓰였는지 표시하라던 조교님 말이 이제 이해돼요. 안 쓰인 가정이 있으면 증명이 어딘가 비어 있다는 거네요.

이서연 S01
이서연

해석학 시간에 코시 방정식 괴물 해를 보여 주시면서 "연속성 한 줄이 이 괴물들을 다 쫓아낸다"고 하셨는데, 단조성도 괴물 해를 쫓아내는 일을 하네요.

문제 3. 문장 하나의 loss

언어 모델이 「나는 밥을 먹었다」를 세 토큰 「나는」「밥을」「먹었다」로 읽는다. 모델은 첫 토큰 「나는」에 0.2를, 「나는」 다음에 「밥을」이 올 확률로 0.5를, 「나는 밥을」 다음에 「먹었다」가 올 확률로 0.9를 주었다. (가) 모델이 「나는 밥을 먹었다」 문장 전체에 준 확률과 그 놀라움(nat)을 구하라. (나) 토큰마다의 놀라움을 더한 값과 비교하라. (다) 세 토큰은 서로 독립이 아닌데, 그런데도 왜 (나)가 성립하는가?

「나는」「밥을」「먹었다」 세 토큰과, 모델이 앞 토큰을 알고 각 토큰에 준 확률 0.2, 0.5, 0.9
「나는」「밥을」「먹었다」 세 토큰과, 모델이 앞 토큰을 알고 각 토큰에 준 확률 0.2, 0.5, 0.9

함께 풀기

김민준 M01
김민준

문장 확률은 0.2 × 0.5 × 0.9 = 0.09니까 놀라움은 −ln 0.09 ≈ 2.41 nat이에요. 토큰마다는 1.61, 0.69, 0.11이고, 더하면 2.41. 문제 1(자물쇠 번호)에서 첫 자리와 나머지 세 자리를 나눠 셌던 거랑 같네요.

이서연 S01
이서연

그런데 (다)가 걸려. 놀라움이 더해진다는 건 독립인 소식끼리였잖아. 「나는」 다음에 「밥을」이 올지는 「나는」에 달려 있으니까 독립이 아니야. 선생님, 그럼 더하면 안 되는 거 아니에요?

선생님 T01
선생님

모델이 두 번째 토큰에 준 0.5는 어떤 확률이었죠?

이서연 S08
이서연

「나는」이 나왔다는 걸 알고 준 확률이요. P(A∩B) = P(A)·P(B∣A)는 독립이 아니어도 늘 성립하니까, 둘째 소식을 첫 소식을 들은 뒤의 확률로 재면 −log가 그대로 더해져요. 독립이라는 조건은 P(B∣A)가 P(B)와 같아서 조건 없이 재도 된다는 뜻이었고요.

선생님 T01
선생님

그래요. 앞 소식을 이미 들은 사람에게 남은 놀라움만 더하면 돼요. 민준 학생, 토큰마다 앞을 모르는 확률로 놀라움을 재서 더하면요?

김민준 M01
김민준

「먹었다」는 앞을 모르면 훨씬 드문 말이라 놀라움이 커지겠죠. 문장의 놀라움을 부풀려 세는 거네요. 섀넌의 피험자도 앞 글을 알았으니까 MOTORCYCL 다음 E를 한 번에 맞힌 거고요.

선생님 T01
선생님

그래서 언어 모델의 loss는 앞 토큰들을 보고 준 확률의 놀라움을 토큰마다 더하고, 흔히 토큰 수로 나눠 평균을 내요. 이 문장이면 2.41 / 3 ≈ 0.80 nat이에요.

김민준 M01
김민준

연습문제 채점에서 앞 문항 답을 쓰는 문항은 앞 문항이 맞았다고 치고 채점하고, 문항마다 감점을 끝에 합치는 거랑 같네요.

이서연 S01
이서연

확률론 시간에 곱셈 규칙을 조건부 확률로 쓰면 독립 가정이 필요 없다고 배웠는데, 로그를 씌우면 그게 합으로 바뀌는 거네요.