cross-entropy 손실함수 완전 정복 — 심화 학습서

05. 통합 walkthrough — 한 예제로 전 과정을 끊김 없이

목차

앞 장들은 cross-entropy를 조각으로 나눠 배웠다. 정보이론의 뿌리(01), 로짓을 확률과 손실로 바꾸는 길(02), gradient qyq-y(03), 실전 안정·스무딩(04)이 각각의 장이었다. 이 장은 그 조각을 하나의 예제에 끼워 처음부터 끝까지 이어 본다.

예제는 단 하나, 로짓 z=(2.0,1.0,0.1)z=(2.0,\,1.0,\,0.1)이다. 이 로짓을 softmax로 확률로 바꾸고, cross-entropy로 손실을 재고, gradient qyq-y를 구하고, 학습률 0.1로 한 스텝 업데이트해 손실이 정말 줄어드는지 숫자로 확인한다. 새 식은 없다. 앞 장의 식들을 한 흐름에서 차례로 보는 것이 전부다.

전체 여정은 다음과 같다.

logits z=(2.0,1.0,0.1)

softmax
q=(.659,.242,.099)

cross-entropy
L = -log q_c

gradient q - y
=(.659,-.758,.099)

one step
z' = z - 0.1(q - y)

new loss L' = 1.317 < 1.417
(loss decreased)

로짓에서 출발해 한 스텝 뒤 줄어든 손실까지 가는 길이다.

설정을 정해 두자. 3-클래스 분류이고 로짓은 z=(2.0,1.0,0.1)z=(2.0,\,1.0,\,0.1)이다. 정답은 중간 로짓 클래스(0-based 인덱스 1)다. one-hot 라벨로는 y=(0,1,0)y=(0,1,0)이고, 학습률은 η=0.1\eta=0.1이다. 정답이 가장 큰 로짓이 아니라는 점이 중요하다. 모델이 아직 정답을 1등으로 꼽지 못한, 틀리기 직전의 상태다. 학습이 할 일이 가장 많은 출발점이라 흐름을 보기에 좋다.


5.1 단계 ① — 로짓을 softmax로

softmax 정의 qi=ezi/jezjq_i = e^{z_i}/\sum_j e^{z_j}를 그대로 적용한다(02 §2.1). 먼저 분모를 구한다.

S=e2.0+e1.0+e0.1=7.389056+2.718282+1.105171=11.212509.S = e^{2.0}+e^{1.0}+e^{0.1} = 7.389056 + 2.718282 + 1.105171 = 11.212509.

각 확률은 분자 ezke^{z_k}SS로 나눈 값이다.

kk (0-based) 클래스 zkz_k ezke^{z_k} qk=ezk/Sq_k = e^{z_k}/S
0 1 2.0 7.389056 0.659001
1 2 (정답) 1.0 2.718282 0.242433
2 3 0.1 1.105171 0.098566
11.212509 1.000000 ✓

확률 합이 정확히 1이다. softmax가 항상 보장하는 성질이다. 모델은 가장 큰 로짓을 가진 클래스 1에 0.659로 가장 높은 확률을 줬다. 그런데 정답은 클래스 2다. 모델이 정답에 준 확률은 0.242뿐이다. 이 차이를 메우는 일이 학습이다.

같은 결과를 더 안전하게 구하는 방법도 있다. maxz=2.0\max z=2.0을 모든 로짓에서 빼고 지수를 취하는 것이다(02 §2.1 성질 4). 이때 지수값은 ez2=(1.0,0.367879,0.149569)e^{z-2}=(1.0,\,0.367879,\,0.149569), 그 합은 1.5174481.517448이고, 나눈 qq는 위 표와 똑같다. 여기서는 로짓이 작아 빼지 않아도 안전하지만, 큰 로짓에서 overflow(자릿수 넘침)를 막는 습관이라 들여 두면 좋다.

광고 · Advertisements

5.2 단계 ② — cross-entropy 손실

라벨이 one-hot이라 손실 합에서 정답 항만 살아남는다(01 §1.4). 그래서 CE=logqc\text{CE}=-\log q_c 한 줄로 줄어든다. 정답이 클래스 2(인덱스 1)이므로 그 자리 확률을 넣는다.

L=logq2=log(0.242433)=1.417030 nat.L = -\log q_2 = -\log(0.242433) = \mathbf{1.417030}\ \text{nat}.

정답을 바꿔 보면 손실이 왜 이 값인지 또렷해진다. 만약 정답이 클래스 1(인덱스 0, 모델이 확신한 쪽)이었다면 log0.659001=0.417030-\log 0.659001 = 0.417030으로 훨씬 작았을 것이다. 같은 예측이라도 정답이 무엇이냐에 따라 손실이 다르다. CE는 정답에 준 확률 하나만 보기 때문이다.

여기서 깔끔한 패턴 하나가 보인다(02 §2.2). 세 정답 경우의 CE는 0.417,1.417,2.3170.417,\,1.417,\,2.317인데, 그 간격이 로짓 간격(2.01.02.0{-}1.0, 1.00.11.0{-}0.1)과 정확히 같다. 이유는 CE=zc+logjezj\text{CE}=-z_c+\log\sum_j e^{z_j}에서 나온다. 둘째 항 logjezj=2.417030\log\sum_j e^{z_j}=2.417030은 정답과 무관한 상수다. 그래서 정답을 바꾸면 CE가 zc-z_c만큼만 평행이동한다.

5.3 단계 ③ — gradient qyq-y

03장에서 유도한 결과 zL=qy\nabla_z L = q - y를 쓴다(03 §3.2). one-hot y=(0,1,0)y=(0,1,0)이라, 정답 성분에서만 1을 빼면 된다.

qy=(0.6590010,    0.2424331,    0.0985660)=(0.659001,    0.757567,    0.098566).q - y = (0.659001 - 0,\;\; 0.242433 - 1,\;\; 0.098566 - 0) = (\,0.659001,\;\; -0.757567,\;\; 0.098566\,).

각 성분이 업데이트를 어느 방향으로 끄는지 보자.

성분 클래스 qkykq_k - y_k 부호 업데이트 효과
0 1 +0.659001+0.659001 양수 z1z_1 내림 → 오답 확률 ↓
1 2 (정답) 0.757567-0.757567 음수 z2z_2 올림 → 정답 확률 ↑
2 3 +0.098566+0.098566 양수 z3z_3 내림 → 오답 확률 ↓

정답 성분만 음수다. 경사하강 zzη(qy)z\leftarrow z-\eta(q-y)은 음수 성분의 로짓을 올리고 양수 성분의 로짓을 내린다. 그래서 정답 로짓이 올라가고 나머지가 내려간다. "틀린 방향으로, 틀린 만큼만"이라는 qyq-y의 성질이 그대로 작동한다.

광고 · Advertisements

5.4 단계 ④ — 한 스텝 업데이트

이제 zzη(qy)z\leftarrow z - \eta(q-y)η=0.1\eta=0.1로 한 번 적용한다(03 §3.5). 각 성분을 따로 계산한다.

z1=2.00.1×0.659001=2.00.0659001=1.934100,z2=1.00.1×(0.757567)=1.0+0.0757567=1.075757,z3=0.10.1×0.098566=0.10.0098566=0.090143.\begin{aligned} z_1' &= 2.0 - 0.1\times 0.659001 = 2.0 - 0.0659001 = 1.934100,\\ z_2' &= 1.0 - 0.1\times(-0.757567) = 1.0 + 0.0757567 = 1.075757,\\ z_3' &= 0.1 - 0.1\times 0.098566 = 0.1 - 0.0098566 = 0.090143. \end{aligned}

새 로짓은 z=(1.934100,  1.075757,  0.090143)z' = (1.934100,\;1.075757,\;0.090143)이다. 정답 로짓 z2z_2만 올라갔고(1.01.0761.0\to1.076), 나머지는 내려갔다(2.01.9342.0\to1.934, 0.10.0900.1\to0.090). 앞 표가 예고한 그대로다.

5.5 단계 ⑤ — 손실이 줄었는지 확인

새 로짓으로 softmax를 다시 돌린다. 새 분모는 S=e1.934100+e1.075757+e0.090143=6.918+2.932+1.094S' = e^{1.934100}+e^{1.075757}+e^{0.090143} = 6.918\ldots+2.932\ldots+1.094\ldots이고, 나눠서 정리하면 새 확률이 나온다.

q=(0.632090,    0.267920,    0.099990).q' = (0.632090,\;\; 0.267920,\;\; 0.099990).

새 손실은 정답 자리 확률의 음로그다.

L=logq2=log(0.267920)=1.317067 nat.L' = -\log q'_2 = -\log(0.267920) = \mathbf{1.317067}\ \text{nat}.

업데이트 전후를 나란히 두면 변화가 한눈에 보인다.

업데이트 전 업데이트 후 변화
정답 확률 q2q_2 0.242433 0.267920 +0.025+0.025
손실 LL 1.417030 1.317067 ΔL=0.099963\Delta L = -0.099963

단 한 스텝에 정답 확률이 0.242에서 0.268로 올랐고, 손실이 1.417에서 1.317로 내렸다. qyq-y gradient가 의도한 방향으로 작동함을 숫자로 확인한 셈이다. 이 과정을 수천 번 반복하면 정답 확률이 1에 가까워지고, 손실이 0(one-hot 하한)에 다가간다(01 §1.5).

z=(2.0,1.0,0.1)
true=class2
q_2=0.2424

L=1.41703

grad q - y
=(.659,-.758,.099)

z' = z - 0.1(q - y)
=(1.934,1.076,0.090)

q'_2=0.2679
L'=1.31707 (down)

손실 1.41703에서 한 스텝 뒤 1.31707로 내려가는 같은 흐름을 숫자로 다시 보여 준다.


5.6 보너스 — 같은 예측에 label smoothing 끼우기

지금까지는 one-hot 라벨이었다. 같은 모델 예측에 04장의 label smoothing(정답을 1까지 밀지 않도록 라벨을 살짝 푸는 기법)을 적용하면 손실이 어떻게 달라지는지 한 번 더 따라가 본다(04 §4.2). 04장의 분해 검산이 손으로도 맞아떨어지는지 직접 확인하는 것이 목적이다.

여기서는 04장 §4.2와 같은 설정을 쓴다. 확률은 q=(0.2,0.3,0.5)q=(0.2,0.3,0.5)이고 정답은 인덱스 2다. 스무딩 강도 ε=0.1\varepsilon=0.1, 클래스 수 K=3K=3이면 스무딩 타깃은 다음과 같다.

yLS=(10.1)(0,0,1)+0.13(1,1,1)=(0.0333,0.0333,0.9333).y^{LS} = (1-0.1)\,(0,0,1) + \tfrac{0.1}{3}(1,1,1) = (0.0333,\,0.0333,\,0.9333).

먼저 정의 그대로 직접 합산한다.

softCE=[0.0333ln0.2+0.0333ln0.3+0.9333ln0.5]=0.7407.\text{softCE} = -[0.0333\ln 0.2 + 0.0333\ln 0.3 + 0.9333\ln 0.5] = \mathbf{0.7407}.

이제 분해식으로 검산한다. softCE는 두 부분의 가중 합으로 쪼개진다.

softCE=(1ε)CEhard+εCEuniform.\text{softCE} = (1-\varepsilon)\,\text{CE}_{\text{hard}} + \varepsilon\,\text{CE}_{\text{uniform}}.

두 부분을 각각 구한다.

  • CEhard=logqt=log0.5=0.6931\text{CE}_{\text{hard}} = -\log q_t = -\log 0.5 = 0.6931. 정답 클래스 확률 하나만 본 값이다.
  • CEuniform=13(ln0.2+ln0.3+ln0.5)=13(3.5066)=1.1689\text{CE}_{\text{uniform}} = -\tfrac13(\ln 0.2 + \ln 0.3 + \ln 0.5) = -\tfrac13(-3.5066) = \mathbf{1.1689}. 정답뿐 아니라 모든 클래스의 음로그를 평균낸 값이라는 점에 주의한다.

두 값을 가중치 0.90.90.10.1로 더한다.

0.9×0.6931+0.1×1.1689=0.62379+0.11689=0.7407 0.9 \times 0.6931 + 0.1 \times 1.1689 = 0.62379 + 0.11689 = \mathbf{0.7407}\ \checkmark

직접 합산값과 분해값이 정확히 일치한다. 중간 항 CEuniform=1.1689\text{CE}_{\text{uniform}}=1.1689를 정확히 넣어야 합이 0.7407로 떨어진다. 이 항을 잘못 적으면 합이 0.7407이 안 되고 검산이 깨진다. one-hot CE인 0.6931보다 약간 커진 0.7407은, 모델이 정답을 1까지가 아니라 0.93 부근까지만 밀도록 과확신을 누른 결과다.


한 예제로 logits → softmax(qq) → cross-entropy(L=1.41703L=1.41703) → gradient(qyq-y) → 한 스텝(η=0.1\eta=0.1) → 줄어든 손실(L=1.31707L'=1.31707)까지 끊김 없이 달렸고, label smoothing 분해(0.7407)까지 손으로 검산했다. cross-entropy의 핵심 동작이 모두 이 한 흐름 안에 있다. 다음 06장은 이 책 전체를 치트시트 한 장 카드, 결정표, 함정 체크리스트로 압축한다.

Sources

  • 본 장의 모든 수치는 형제 장 02·03·04의 1차 검산과 같은 값이며, Python으로 직접 재계산해 일치를 확인했다(softmax q=(0.659001,0.242433,0.098566)q=(0.659001,0.242433,0.098566), L=1.417030L=1.417030, qyq-y, z=(1.934100,1.075757,0.090143)z'=(1.934100,1.075757,0.090143), q=(0.632090,0.267920,0.099990)q'=(0.632090,0.267920,0.099990), L=1.317067L'=1.317067, label smoothing softCE =0.7407=0.7407).
  • softmax 정의·평행이동 불변(safe softmax) — 02장 §2.1.
  • one-hot CE = logqc-\log q_c로의 환원, 정답을 바꿀 때의 평행이동 패턴 — 01장 §1.4, 02장 §2.2.
  • gradient zL=qy\nabla_z L = q - y 유도와 부호 해석 — 03장 §3.2.
  • 한 스텝 경사하강 worked example(η=0.1\eta=0.1) — 03장 §3.5.
  • CE 손실의 하한 0(one-hot) — 01장 §1.5.
  • label smoothing 정의·분해 검산((1ε)CEhard+εCEuniform(1-\varepsilon)\,\text{CE}_{\text{hard}} + \varepsilon\,\text{CE}_{\text{uniform}}) — 04장 §4.2.