208강은 갈래가 둘인 문제를 풀었습니다. 이제 셋 이상으로 넓힙니다.
갈래마다 로짓을 하나씩 두고 소프트맥스로 확률을 만듭니다.
시그모이드는 이것의 특수한 경우이고, 강에서 본 기울기가 그대로 유지됩니다. 새로 배울 것은 많지 않습니다.
대신 새로 생기는 문제가 둘입니다. 자유도가 하나 남고, 갈래가 아주 많으면 분모를 계산하는 것 자체가 비싸집니다.
문제. 소프트맥스를 세웁니다.
(1) 갈래가 둘일 때 시그모이드가 되는지 확인하세요.
(2) 자유도가 남는 것을 보세요.
(3) 한 갈래를 고정해 보세요.
생각의 실마리. 분자와 분모에 같은 것을 곱해도 값이 안 변합니다. 거기서 자유도가 나옵니다.
풀이. (1) 갈래가 둘일 때를 봅니다.
| 로짓 차이 | 시그모이드 | 소프트맥스 첫 칸 | 차이 |
|---|---|---|---|
완전히 같습니다. 소프트맥스가 시그모이드의 일반화입니다.
갈래가 둘일 때 두 로짓의 차이만 뜻이 있습니다.
(2) 자유도가 남는 것을 봅니다.
| 무엇을 더하나 | 첫 표본의 확률 |
|---|---|
모든 갈래의 로짓에 같은 값을 더해도 확률이 안 바뀝니다.
갈래가 개면 자유 모수가 개분입니다. 강 문제 의 더미변수 함정과 같은 구조입니다.
(3) 한 갈래를 고정해 봅니다.
| 어떻게 맞추나 | 교차엔트로피 | 계수의 크기 | 첫 갈래 계수 합 |
|---|---|---|---|
| 모두 자유 | |||
| 첫 갈래를 으로 |
두 방식의 교차엔트로피가 로 똑같습니다. 같은 확률을 냅니다.
첫 갈래 계수 합이 와 으로 다릅니다. 계수는 다른데 확률은 같으며, 자유도 하나가 남는다는 뜻입니다.
계수의 크기는 과 으로 자유로운 쪽이 조금 작습니다. 에서 시작해 경사하강으로 갔기 때문이며, 자연히 작은 해로 갑니다.
정규화를 걸면 모두 자유로운 쪽도 답이 하나로 정해집니다.
이 문제에서 배우는 것. 자유도가 남는 것을 그냥 두는 것이 실무의 표준입니다. 통계 소프트웨어는 한 갈래를 기준으로 고정해 계수를 해석 가능하게 만들지만, 딥러닝 프레임워크는 모두 자유롭게 두고 정규화로 정합니다. 후자가 되는 이유는 강의 더미변수 함정과 달리 확률에는 영향이 없기 때문이며, 계수를 해석할 일이 없으면 문제가 되지 않습니다. 다만 계수를 보고할 때는 어느 갈래를 기준으로 뒀는지 반드시 밝혀야 합니다.
바로 확인 1.
확인 1-1. 소프트맥스에 상수를 더하면 어떻게 되는지 쓰세요.
답. 확률이 안 바뀌며 자유 모수가 개분입니다.
확인 1-2. 검산에서 로짓 차이 일 때 두 값을 쓰세요.
답. 으로 같습니다.
확인 1-3. 검산에서 두 맞추기 방식의 교차엔트로피와 계수 크기를 쓰세요.
답. 둘 다 이고 계수는 과 입니다.
문제. 기울기를 유도합니다.
(1) 이진과 같은 모양인지 확인하세요.
(2) 야코비 행렬을 보세요.
(3) 뉴턴의 비용을 재세요.
생각의 실마리. 강 심화 에서 미리 본 가 여기서 나옵니다.
풀이. (1) 확인합니다.
| 무엇 | 기울기 |
|---|---|
| 이진 교차엔트로피 | 예측 확률 관측 |
| 소프트맥스 교차엔트로피 | 예측 확률 벡터 원핫 |
| 가중치에 대해서는 | 위에 를 곱함 |
| 무엇 | 값 | 판정 |
|---|---|---|
| 해석 기울기와의 최대 차 | 같음 |
소수점 아래 아홉 자리까지 같습니다. 유도가 맞습니다.
(2) 야코비 행렬을 봅니다.
| 무엇 | 값 | 이론값 |
|---|---|---|
| 행의 합 | ||
| 대칭인가 | ||
| 가장 작은 고유값 | ||
| 대각합 |
행의 합이 입니다. 확률의 합이 로 고정이기 때문입니다.
가장 작은 고유값이 입니다. 그것이 자유도 하나가 남는다는 뜻입니다.
(3) 뉴턴의 비용을 잽니다.
| 변수 | 갈래 | 헤세의 크기 | 이진 대비 |
|---|---|---|---|
갈래가 이면 헤세가 이진의 만 배 가까이 됩니다.
그래서 다중분류는 대개 경사하강으로 풉니다. 강 문제 의 손익분기가 갈래 수만큼 앞당겨집니다.
이 문제에서 배우는 것. 야코비의 고유값 이 문제 의 자유도와 같은 사실입니다. 확률 벡터가 단체 위에 갇혀 있으므로 그 방향으로는 아무 변화도 못 만들고, 그래서 헤세도 특이행렬이 됩니다. 뉴턴을 쓰려면 한 갈래를 빼거나 정규화를 더해야 하며, 이것이 다중분류에서 뉴턴이 덜 쓰이는 또 하나의 이유입니다. 한 사실이 확률·계수·헤세 세 곳에서 같은 모습으로 나타납니다.
바로 확인 2.
확인 2-1. 소프트맥스 교차엔트로피의 로짓에 대한 기울기를 쓰세요.
답. 예측 확률 벡터에서 원핫을 뺀 것입니다.
확인 2-2. 검산에서 야코비의 행의 합과 가장 작은 고유값을 쓰세요.
답. 둘 다 입니다.
확인 2-3. 검산에서 변수 에 갈래 일 때 헤세가 이진의 몇 배인지 쓰세요.
답. 배입니다.
문제. 이진 분류기를 여러 개 씁니다.
(1) 방법을 정리하세요.
(2) 세 방법을 견주세요.
(3) 갈래가 아주 많을 때를 보세요.
생각의 실마리. 소프트맥스 말고 이진 분류기를 조합하는 길도 있습니다.
풀이. (1) 정리합니다.
| 방법 | 분류기 개수 | 한 개가 보는 자료 | 무엇이 문제 |
|---|---|---|---|
| 소프트맥스 | 개 | 전부 | 갈래가 많으면 분모가 비쌈 |
| 하나 대 나머지 | 개 | 전부 | 확률의 합이 이 아님 |
| 하나 대 하나 | 개 | 두 갈래분 | 개수가 제곱으로 늚 |
| 오류 정정 부호 | 정하기 나름 | 부분집합 | 설계가 어려움 |
둘째 줄이 흔히 쓰이는데 확률로 읽으려면 다시 정규화해야 합니다.
(2) 세 방법을 같은 자료로 견줍니다.
| 방법 | 검증 정확도 | 확률 합의 평균 | 검증 교차엔트로피 |
|---|---|---|---|
| 소프트맥스 | |||
| 하나 대 나머지 | |||
| 하나 대 하나 |
정확도는 셋이 근처로 비슷합니다. 참 구조가 소프트맥스라 첫 줄이 조금 낫습니다.
하나 대 나머지는 확률의 합이 입니다. 다시 나눠야 합니다.
하나 대 하나는 합이 인데 그것이 쌍의 개수입니다. 표를 세는 것이라 확률 해석이 더 약하고, 교차엔트로피가 로 가장 나쁩니다.
(3) 갈래가 아주 많을 때를 봅니다.
| 갈래 수 | 분모의 항 수 | 한 표본당 곱셈 |
|---|---|---|
단어가 만 개면 표본 하나에 억 번 곱합니다.
계층 소프트맥스나 잡음 대조 추정으로 줄입니다. S의 언어모형에서 이 문제를 다시 만납니다.
이 문제에서 배우는 것. 분모가 전체 갈래를 훑는다는 것이 소프트맥스의 유일한 약점입니다. 확률을 제대로 주고 기울기가 깔끔한데도 어휘가 만이면 못 쓰며, 그래서 언어모형은 오랫동안 이 분모를 우회하는 방법을 찾아 왔습니다. 계층으로 나눠 번만 계산하거나, 잡음 표본 몇 개와만 견주는 방식이 그것입니다. 알고리즘의 한계가 수학이 아니라 계산량에서 오는 대표적인 예입니다.
바로 확인 3.
확인 3-1. 하나 대 나머지의 문제를 쓰세요.
답. 확률의 합이 이 아니라 다시 정규화해야 합니다.
확인 3-2. 검산에서 세 방법의 검증 교차엔트로피를 쓰세요.
답. , , 입니다.
확인 3-3. 검산에서 갈래가 만일 때 표본당 곱셈 횟수를 쓰세요.
답. 번입니다.
문제. 보정을 확인합니다.
(1) 갈래마다 성립하는지 보세요.
(2) 구간별로 보세요.
(3) 하나 대 나머지와 견주세요.
생각의 실마리. 강 문제 의 보증이 갈래 수만큼 여러 개로 늘어납니다.
풀이. (1) 갈래마다 봅니다.
| 갈래 | 예측 확률 평균 | 실제 비율 | 차이 |
|---|---|---|---|
갈래마다 정확히 맞습니다. 절편이 그것을 강제합니다.
강의 보증이 갈래 수만큼 여러 개로 늘어난 것입니다.
(2) 구간별로 봅니다.
| 예측 확률 구간 | 표본 수 | 평균 예측 | 실제 비율 |
|---|---|---|---|
| 에서 | |||
| 에서 | |||
| 에서 | |||
| 에서 | |||
| 에서 |
구간마다도 평균 예측과 실제 비율이 붙습니다.
학습 자료에서 그렇다는 것입니다. 새 자료는 따로 봐야 합니다.
(3) 하나 대 나머지와 견줍니다.
| 무엇 | 확률 합의 평균 | 최솟값 | 최댓값 |
|---|---|---|---|
| 다시 나누기 전 | |||
| 다시 나눈 뒤 |
평균은 정확히 입니다. 절편이 갈래마다 비율을 맞추고 그 비율들의 합이 이기 때문입니다.
그런데 표본마다는 에서 까지 흩어집니다.
나누면 이 되지만 그렇게 만든 값이 확률이라는 보장은 없습니다. 확률이 필요하면 소프트맥스를 쓰는 것이 낫습니다.
이 문제에서 배우는 것. 평균이 맞는 것과 표본마다 맞는 것은 다릅니다. 하나 대 나머지의 확률 합이 평균으로는 정확히 인데 개별 표본에서는 에서 까지 흔들렸습니다. 그런데 보고서에는 대개 평균만 실리므로 "보정이 잘 됐다"는 결론이 쉽게 나옵니다. 강의 보정 곡선이 구간별로 보는 이유가 이것이고, 그마저도 평균끼리 견주는 것이라 개별 표본의 흔들림은 안 보입니다.
바로 확인 4.
확인 4-1. 검산에서 갈래 의 예측 확률 평균과 실제 비율을 쓰세요.
답. 둘 다 입니다.
확인 4-2. 검산에서 하나 대 나머지의 확률 합 최솟값과 최댓값을 쓰세요.
답. 과 입니다.
확인 4-3. 다시 나눈 값이 확률인지 쓰세요.
답. 합은 이 되지만 확률이라는 보장은 없습니다.
문제. 실무 문제를 다룹니다.
(1) 확인할 것을 정리하세요.
(2) 갈래가 불균형할 때를 보세요.
(3) 문턱을 조정해 보세요.
생각의 실마리. 갈래가 여럿이면 갈래마다 사정이 다릅니다.
풀이. (1) 정리합니다.
| 무엇 | 왜 |
|---|---|
| 갈래가 몇 개인가 | 분모 비용과 방법 선택 |
| 갈래가 불균형한가 | 드문 갈래를 못 배움 |
| 갈래에 순서가 있는가 | 순서형 모형이 나음 |
| 갈래가 계층인가 | 계층 구조를 쓸 수 있음 |
| 여러 갈래가 동시에 참인가 | 다중 라벨 문제 |
마지막 줄은 소프트맥스가 아니라 갈래마다 시그모이드를 씁니다.
(2) 갈래가 불균형할 때를 봅니다.
| 갈래 | 실제 비율 | 예측된 비율 | 그 갈래의 재현율 |
|---|---|---|---|
드문 갈래는 한 번도 예측되지 않습니다. 예측된 비율이 입니다.
확률은 맞는데 최댓값을 고르면 언제나 흔한 갈래가 이깁니다. 강에서 이 문제를 정면으로 다룹니다.
(3) 문턱을 조정해 봅니다.
| 어떻게 고르나 | 전체 정확도 | 가장 드문 갈래 재현율 | 거시 평균 재현율 |
|---|---|---|---|
| 가장 큰 확률 | |||
| 사전확률로 나눠 | |||
| 균등 사전으로 바꿈 |
사전확률로 나누면 가장 드문 갈래의 재현율이 에서 으로 오릅니다.
대신 전체 정확도가 에서 로 내려갑니다. 무엇을 원하는지가 정합니다.
둘째와 셋째가 같습니다. 상수를 곱해도 argmax가 안 바뀌기 때문입니다.
정리하면 단원은 다음과 같습니다.
| 강의 | 무엇을 세웠나 |
|---|---|
| 무엇을 최소화할지의 틀 | |
| 손실이 어디서 오는지 | |
| 닫힌 해와 수치 안정성 | |
| 닫힌 해가 없을 때의 반복 | |
| 여러 갈래로의 확장 |
이 문제에서 배우는 것. 문턱 조정은 학습을 다시 하지 않고도 되는 유일한 조절 손잡이입니다. 위 표에서 같은 모형의 확률을 그대로 두고 고르는 규칙만 바꿨는데 거시 평균 재현율이 에서 가 됐습니다. 강 문제 의 클래스 가중치는 학습을 다시 해야 하고 확률의 보정도 깨뜨리는데, 문턱 조정은 확률을 온전히 남긴 채 결정만 바꿉니다. 그래서 실무의 순서는 확률을 잘 맞춘 뒤 문턱을 목적에 맞춰 고르는 것이며, 강과 강이 그 절차를 세웁니다.
바로 확인 5.
확인 5-1. 검산에서 드문 두 갈래의 예측된 비율을 쓰세요.
답. 둘 다 입니다.
확인 5-2. 검산에서 사전확률로 나눴을 때의 정확도와 거시 평균 재현율을 쓰세요.
답. 과 입니다.
확인 5-3. 사전확률로 나누는 것과 균등 사전으로 바꾸는 것이 왜 같은지 쓰세요.
답. 상수를 곱해도 argmax가 안 바뀌기 때문입니다.
| 무엇 | 식 |
|---|---|
| 소프트맥스 | |
| 교차엔트로피 | -\sum_{k}t_{k}\log q_ |
| 로짓 기울기 | |
| 가중치 기울기 | x(q-t)^ |
| 야코비 | \text{diag}(q)-qq^ |
| 넓히는 방법 | 분류기 수 | 확률이 나오나 |
|---|---|---|
| 소프트맥스 | 예 | |
| 하나 대 나머지 | 다시 나눠야 | |
| 하나 대 하나 | 아니오 |
| 불균형 대응 | 무엇을 바꾸나 |
|---|---|
| 클래스 가중치 | 손실과 확률 |
| 문턱 조정 | 결정만 |
| 재표본 | 자료 분포 |
| 자주 하는 실수 | 바로잡기 |
|---|---|
| 자유도를 안 고려합니다 | 계수 해석이 안 됩니다 |
| 하나 대 나머지 출력을 확률로 씁니다 | 합이 이 아닙니다 |
| 갈래가 많은데 소프트맥스를 그냥 씁니다 | 분모가 비쌉니다 |
| 최댓값만 골라 드문 갈래를 놓칩니다 | 문턱을 조정합니다 |
| 다중 라벨에 소프트맥스를 씁니다 | 갈래마다 시그모이드를 씁니다 |
문제 6. 소프트맥스에 상수를 더하면 어떻게 되는지 쓰세요.
답. 확률이 안 바뀌며 자유 모수가 개분입니다.
문제 7. 검산에서 로짓 차이 일 때 시그모이드와 소프트맥스 값을 쓰세요.
답. 둘 다 입니다.
문제 8. 검산에서 두 맞추기 방식의 교차엔트로피와 계수 크기를 쓰세요.
답. 둘 다 이고 계수는 과 입니다.
문제 9. 소프트맥스 교차엔트로피의 로짓에 대한 기울기를 쓰세요.
답. 예측 확률 벡터에서 원핫을 뺀 것입니다.
문제 10. 검산에서 야코비의 행의 합과 가장 작은 고유값을 쓰세요.
답. 둘 다 입니다.
문제 11. 검산에서 변수 에 갈래 일 때 헤세가 이진의 몇 배인지 쓰세요.
답. 배입니다.
문제 12. 검산에서 세 방법의 검증 교차엔트로피를 쓰세요.
답. , , 입니다.
문제 13. 검산에서 갈래가 만일 때 표본당 곱셈 횟수를 쓰세요.
답. 번입니다.
문제 14. 검산에서 갈래 의 예측 확률 평균과 실제 비율을 쓰세요.
답. 둘 다 입니다.
문제 15. 검산에서 하나 대 나머지의 확률 합 최솟값과 최댓값을 쓰세요.
답. 과 입니다.
문제 16. 검산에서 드문 두 갈래의 예측된 비율을 쓰세요.
답. 둘 다 입니다.
문제 17. 검산에서 사전확률로 나눴을 때의 정확도와 거시 평균 재현율을 쓰세요.
답. 과 입니다.
문제 18. 사전확률로 나누는 것과 균등 사전으로 바꾸는 것이 왜 같은지 쓰세요.
답. 상수를 곱해도 argmax가 안 바뀌기 때문입니다.
심화 1. 순서형 분류를 정리하세요.
갈래에 순서가 있으면 그 정보를 쓸 수 있습니다.
| 무엇 | 어떻게 |
|---|---|
| 비례 오즈 모형 | 문턱을 여러 개 두고 기울기는 하나 |
| 누적 확률 | 를 모형화 |
| 모수 개수 | 개 |
소프트맥스는 개가 필요한데 이쪽은 훨씬 적습니다.
"매우 나쁨에서 매우 좋음"처럼 순서가 있으면 이것이 맞습니다.
비례 오즈 가정이 깨지면 문턱마다 기울기를 따로 둡니다. 그러면 모수가 다시 늘어납니다.
심화 2. 다중 라벨 문제를 정리하세요.
| 무엇 | 소프트맥스 | 갈래마다 시그모이드 |
|---|---|---|
| 확률의 합 | 제약 없음 | |
| 언제 | 하나만 참 | 여럿이 참일 수 있음 |
| 손실 | 교차엔트로피 하나 | 이진 교차엔트로피 개 |
사진에 개와 고양이가 함께 있으면 소프트맥스가 틀립니다.
갈래끼리 상관이 있으면 독립 시그모이드도 최적이 아닙니다. 그 상관을 담는 모형이 따로 있습니다.
평가지표도 달라집니다. 정확도 대신 갈래별 F의 평균을 봅니다.
심화 3. 계층 소프트맥스를 정리하세요.
| 무엇 | 보통 | 계층 |
|---|---|---|
| 계산량 | ||
| 만 갈래 | 10^ | 약 |
| 트리 모양 | 없음 | 성능에 영향 |
셋째 줄이 문제입니다. 자주 나오는 갈래를 얕은 자리에 두면 빠릅니다.
허프만 트리를 쓰는 것이 강 문제 와 이어집니다.
대안은 잡음 대조 추정입니다. 정답과 잡음 표본 몇 개만 견줍니다.
심화 4. 온도와 지식 증류를 정리하세요.
| 무엇이 되나 | |
|---|---|
| 최댓값에 | |
| 보통 소프트맥스 | |
| 균등 |
강 문제 에서 값으로 확인했습니다.
증류에서 교사와 학생 모두 같은 로 부드럽게 만듭니다. 그러면 "어느 갈래와 헷갈리는지"가 전달됩니다.
기울기가 의 제곱에 반비례해 작아지므로 손실에 을 곱합니다.
심화 5. 다중분류 평가지표를 정리하세요.
| 무엇 | 어떻게 평균 |
|---|---|
| 미시 평균 | 전체 표본을 모아 계산 |
| 거시 평균 | 갈래마다 계산해 평균 |
| 가중 평균 | 갈래 크기로 가중 |
미시 평균은 흔한 갈래가 지배합니다. 정확도와 거의 같습니다.
거시 평균은 갈래마다 같은 무게입니다. 문제 에서 이것을 봤습니다.
불균형 문제에서는 거시 평균을 봐야 드문 갈래의 실패가 보입니다. 강에서 다시 다룹니다.
심화 6. 단원을 정리하세요.
| 무엇을 정하면 | 무엇이 정해지나 |
|---|---|
| 분포 가정 | 손실함수 |
| 손실과 모형 | 볼록한지 |
| 볼록성과 크기 | 어떤 방법으로 풀지 |
| 갈래 수 | 분모 비용과 방법 |
넷을 정하면 알고리즘이 정해집니다. 새로운 문제를 만나도 이 순서로 물으면 됩니다.
그런데 아직 답하지 않은 것이 있습니다. 그 답이 새 자료에서도 맞는가입니다.
강 문제 에서 경험적 위험과 참 위험의 차이를 봤는데, 그 차이가 무엇에 달렸는지가 강부터의 물음입니다.
정답.
| 기호 | 읽는 법 | 뜻 |
|---|---|---|
| 소프트맥스 | softmax | 로짓 벡터를 확률 벡터로 바꿉니다 |
| 원핫 | one-hot | 정답 자리만 인 벡터입니다 |
| 야코비 | Jacobian | 벡터 함수의 일계 도함수 행렬입니다 |
| 하나 대 나머지 | one-vs-rest | 갈래마다 이진 분류기를 둡니다 |
| 하나 대 하나 | one-vs-one | 갈래 쌍마다 분류기를 둡니다 |
| 계층 소프트맥스 | hierarchical softmax | 트리로 분모를 줄입니다 |
| 잡음 대조 추정 | NCE | 잡음 표본과만 견줍니다 |
| 순서형 분류 | ordinal | 갈래에 순서가 있습니다 |
| 다중 라벨 | multi-label | 여러 갈래가 동시에 참입니다 |
| 거시 평균 | macro average | 갈래마다 같은 무게로 평균합니다 |
여기서 단원 학습을 최적화로 쓰기를 마칩니다. 강부터 강까지가 하나의 줄기였습니다.
다음은 강 편향과 분산의 분해입니다. 단원이 **"답을 어떻게 찾는가"**를 다뤘다면, 단원은 **"그 답이 새 자료에서도 맞는가"**를 묻습니다. 강 문제 에서 표본 일 때 경험적 위험 과 참 위험 의 간극을 봤는데, 그 간극이 무엇으로 이루어져 있는지가 강의 주제입니다.
import numpy as np
rng = np.random.default_rng(20261016)
def pw(s, n):
k = n - sum(2 if ord(c) > 0x2FFF else 1 for c in str(s))
return str(s) + " " * max(k, 0)
def rw(s, n):
k = n - sum(2 if ord(c) > 0x2FFF else 1 for c in str(s))
return " " * max(k, 0) + str(s)
def sig(z):
return 1.0 / (1.0 + np.exp(-np.clip(z, -500, 500)))
def softmax(Z):
Z = Z - Z.max(axis=1, keepdims=True)
E = np.exp(Z)
return E / E.sum(axis=1, keepdims=True)
def ce(X, Y, W):
Z = X @ W
Z = Z - Z.max(axis=1, keepdims=True)
return float(np.mean(np.log(np.exp(Z).sum(axis=1)) - (Z * Y).sum(axis=1)))
# --- 문제 1: 시그모이드를 넓힙니다 --------------------------------------
print(" 208강은 갈래가 둘인 문제를 풀었습니다. 이제 셋 이상으로 넓힙니다")
print(" 갈래마다 로짓을 하나씩 두고 소프트맥스로 확률을 만듭니다")
print(" 갈래가 둘이면 소프트맥스가 시그모이드가 되는지 확인합니다")
zs = np.array([-3.0, -1.0, 0.0, 1.0, 3.0])
print(" %s %s %s %s"
% (pw("로짓 차이", 14), rw("시그모이드", 18), rw("소프트맥스 첫 칸", 20),
rw("차이", 16)))
for z in zs:
a = float(sig(z))
b = float(softmax(np.array([[z, 0.0]]))[0, 0])
print(" %s %18.10f %20.10f %16.4e"
% (pw("%.1f" % z, 14), a, b, abs(a - b)))
print(" 완전히 같습니다. 소프트맥스가 시그모이드의 일반화입니다")
print(" 갈래가 둘일 때 두 로짓의 차이만 뜻이 있습니다")
print(" 자유도가 하나 남습니다")
W0 = rng.normal(0, 1, (3, 4))
X0 = rng.normal(0, 1, (5, 3))
print(" 모든 갈래의 로짓에 같은 값을 더해도 확률이 안 바뀝니다")
print(" %s %s"
% (pw("무엇을 더하나", 22), rw("첫 표본의 확률", 48)))
for c in [0.0, 5.0, -20.0]:
Wc = W0 + c
q = softmax(X0 @ Wc)
print(" %s %s"
% (pw("%.1f" % c, 22),
rw(" ".join("%.8f" % v for v in q[0]), 48)))
print(" 갈래가 K 개면 자유 모수가 K 빼기 1 개분입니다")
print(" 186강 문제 1 의 더미변수 함정과 같은 구조입니다")
print(" 한 갈래를 기준으로 고정해 봅니다")
n1 = 4000
K1 = 3
X1 = np.concatenate([np.ones((n1, 1)), rng.normal(0, 1, (n1, 2))], axis=1)
Wt = np.array([[0.0, 0.5, -0.4], [0.0, 1.2, -0.8], [0.0, -0.6, 1.0]])
P1 = softmax(X1 @ Wt)
lab = np.array([rng.choice(K1, p=q) for q in P1])
Y1 = np.zeros((n1, K1))
Y1[np.arange(n1), lab] = 1.0
def fit_soft(X, Y, steps=4000, lr=0.5, fix_first=False):
W = np.zeros((X.shape[1], Y.shape[1]))
for _ in range(steps):
G = X.T @ (softmax(X @ W) - Y) / len(Y)
if fix_first:
G[:, 0] = 0.0
W -= lr * G
return W
W_free = fit_soft(X1, Y1)
W_fix = fit_soft(X1, Y1, fix_first=True)
print(" %s %s %s %s"
% (pw("어떻게 맞추나", 22), rw("교차엔트로피", 20),
rw("계수의 크기", 16), rw("첫 갈래 계수 합", 20)))
for nm, W in [("모두 자유", W_free), ("첫 갈래를 0 으로", W_fix)]:
print(" %s %20.10f %16.6f %20.6f"
% (pw(nm, 22), ce(X1, Y1, W), float(np.linalg.norm(W)),
float(np.abs(W[:, 0]).sum())))
print(" 두 방식의 교차엔트로피가 0.7823864447 로 똑같습니다. 같은 확률을 냅니다")
print(" 첫 갈래 계수 합이 0.373779 와 0.000000 으로 다릅니다")
print(" 계수는 다른데 확률은 같습니다. 자유도 하나가 남는다는 뜻입니다")
print(" 계수의 크기는 1.937830 과 1.980840 으로 자유로운 쪽이 조금 작습니다")
print(" 0 에서 시작해 경사하강으로 갔기 때문입니다. 자연히 작은 해로 갑니다")
print(" 정규화를 걸면 모두 자유로운 쪽도 답이 하나로 정해집니다")
# --- 문제 2: 기울기가 그대로입니다 --------------------------------------
print(" 기울기가 이진과 같은 모양입니다")
print(" 로짓에 대한 기울기가 예측 확률 빼기 목표 분포입니다")
print(" %s %s"
% (pw("무엇", 24), rw("기울기", 34)))
for a, b in [("이진 교차엔트로피", "예측 확률 빼기 관측"),
("소프트맥스 교차엔트로피", "예측 확률 벡터 빼기 원핫"),
("가중치에 대해서는", "위에 x 를 곱함")]:
print(" %s %s" % (pw(a, 24), rw(b, 34)))
print(" 수치 미분과 견줘 확인합니다")
Wr = rng.normal(0, 0.3, (3, K1))
G_an = X1.T @ (softmax(X1 @ Wr) - Y1) / n1
h = 1e-6
G_nu = np.zeros_like(Wr)
for i in range(3):
for j in range(K1):
Wp = Wr.copy()
Wm = Wr.copy()
Wp[i, j] += h
Wm[i, j] -= h
G_nu[i, j] = (ce(X1, Y1, Wp) - ce(X1, Y1, Wm)) / (2 * h)
print(" %s %s %s"
% (pw("무엇", 26), rw("값", 20), rw("판정", 14)))
print(" %s %20.4e %s"
% (pw("해석 기울기와의 최대 차", 26),
float(np.abs(G_an - G_nu).max()), rw("같음", 14)))
print(" 소수점 아래 아홉 자리까지 같습니다. 유도가 맞습니다")
print(" 야코비 행렬을 봅니다")
q = softmax(np.array([[1.0, 0.3, -0.5]]))[0]
J = np.diag(q) - np.outer(q, q)
print(" 소프트맥스의 야코비는 대각 q 에서 q q 전치를 뺀 것입니다")
print(" %s %s %s"
% (pw("무엇", 26), rw("값", 20), rw("이론값", 16)))
for nm, v, t in [("행의 합", float(J.sum(axis=1).max()), 0.0),
("대칭인가", float(np.abs(J - J.T).max()), 0.0),
("가장 작은 고유값", float(np.linalg.eigvalsh(J).min()), 0.0),
("대각합", float(np.trace(J)),
float(1.0 - np.sum(q ** 2)))]:
print(" %s %20.10f %16.6f"
% (pw(nm, 26), v if abs(v) > 1e-12 else 0.0, t))
print(" 행의 합이 0 입니다. 확률의 합이 1 로 고정이기 때문입니다")
print(" 가장 작은 고유값이 0 입니다. 그것이 자유도 하나가 남는다는 뜻입니다")
print(" 뉴턴을 쓰려면 헤세가 커집니다")
print(" %s %s %s %s"
% (pw("변수", 10), rw("갈래", 10), rw("헤세의 크기", 18),
rw("이진 대비", 14)))
for p, K in [(10, 2), (10, 10), (100, 10), (100, 100)]:
size = (p * (K - 1)) ** 2
base = (p * 1) ** 2
print(" %s %10d %18d %14.1f"
% (pw("%d" % p, 10), K, size, size / base))
print(" 갈래가 100 이면 헤세가 이진의 만 배 가까이 됩니다")
print(" 그래서 다중분류는 대개 경사하강으로 풉니다")
print(" 208강 문제 2 의 손익분기가 갈래 수만큼 앞당겨집니다")
# --- 문제 3: 여러 갈래로 넓히는 다른 방법 -------------------------------
print(" 이진 분류기를 여러 개 써서 넓힐 수도 있습니다")
print(" %s %s %s %s"
% (pw("방법", 20), rw("분류기 개수", 14), rw("한 개가 보는 자료", 22),
rw("무엇이 문제", 20)))
for a, b, c, d in [("소프트맥스", "1 개", "전부", "갈래가 많으면 분모가 비쌈"),
("하나 대 나머지", "K 개", "전부", "확률의 합이 1 이 아님"),
("하나 대 하나", "K(K-1)/2 개", "두 갈래분", "개수가 제곱으로 늚"),
("오류 정정 부호", "정하기 나름", "부분집합", "설계가 어려움")]:
print(" %s %s %s %s" % (pw(a, 20), rw(b, 14), rw(c, 22), rw(d, 20)))
print(" 둘째 줄이 흔히 쓰이는데 확률로 읽으려면 다시 정규화해야 합니다")
print(" 세 방법을 같은 자료로 견줍니다")
n3 = 3000
K3 = 4
X3 = np.concatenate([np.ones((n3, 1)), rng.normal(0, 1, (n3, 3))], axis=1)
W3 = rng.normal(0, 1.0, (4, K3))
W3[:, 0] = 0.0
P3 = softmax(X3 @ W3)
lab3 = np.array([rng.choice(K3, p=qq) for qq in P3])
Y3 = np.zeros((n3, K3))
Y3[np.arange(n3), lab3] = 1.0
Xv = np.concatenate([np.ones((3000, 1)), rng.normal(0, 1, (3000, 3))], axis=1)
Pv = softmax(Xv @ W3)
labv = np.array([rng.choice(K3, p=qq) for qq in Pv])
def fit_logit(X, y, steps=3000, lr=0.5):
w = np.zeros(X.shape[1])
for _ in range(steps):
w -= lr * (X.T @ (sig(X @ w) - y)) / len(y)
return w
Ws = fit_soft(X3, Y3)
ovr = np.stack([fit_logit(X3, (lab3 == k).astype(float)) for k in range(K3)],
axis=1)
ovo = {}
for a in range(K3):
for b in range(a + 1, K3):
m = (lab3 == a) | (lab3 == b)
ovo[(a, b)] = fit_logit(X3[m], (lab3[m] == a).astype(float))
print(" %s %s %s %s"
% (pw("방법", 20), rw("검증 정확도", 16), rw("확률 합의 평균", 20),
rw("검증 교차엔트로피", 22)))
qs = softmax(Xv @ Ws)
acc_s = float((qs.argmax(axis=1) == labv).mean())
ce_s = float(-np.mean(np.log(np.clip(qs[np.arange(3000), labv], 1e-12, 1))))
print(" %s %16.6f %20.6f %22.6f"
% (pw("소프트맥스", 20), acc_s, float(qs.sum(axis=1).mean()), ce_s))
raw = sig(Xv @ ovr)
acc_o = float((raw.argmax(axis=1) == labv).mean())
norm = raw / raw.sum(axis=1, keepdims=True)
ce_o = float(-np.mean(np.log(np.clip(norm[np.arange(3000), labv], 1e-12, 1))))
print(" %s %16.6f %20.6f %22.6f"
% (pw("하나 대 나머지", 20), acc_o, float(raw.sum(axis=1).mean()), ce_o))
votes = np.zeros((3000, K3))
for (a, b), wv in ovo.items():
pa = sig(Xv @ wv)
votes[:, a] += pa
votes[:, b] += 1.0 - pa
acc_v = float((votes.argmax(axis=1) == labv).mean())
nv = votes / votes.sum(axis=1, keepdims=True)
ce_v = float(-np.mean(np.log(np.clip(nv[np.arange(3000), labv], 1e-12, 1))))
print(" %s %16.6f %20.6f %22.6f"
% (pw("하나 대 하나", 20), acc_v, float(votes.sum(axis=1).mean()), ce_v))
print(" 정확도는 셋이 비슷합니다. 참 구조가 소프트맥스라 첫 줄이 조금 낫습니다")
print(" 하나 대 나머지는 확률의 합이 1 이 아닙니다. 다시 나눠야 합니다")
print(" 하나 대 하나는 표를 세는 것이라 확률 해석이 더 약합니다")
print(" 갈래가 아주 많으면 분모가 문제입니다")
print(" %s %s %s"
% (pw("갈래 수", 14), rw("분모의 항 수", 18), rw("한 표본당 곱셈", 20)))
for K in [10, 1000, 100000, 1000000]:
print(" %s %18d %20d" % (pw("%d" % K, 14), K, K * 300))
print(" 단어가 100 만 개면 표본 하나에 3 억 번 곱합니다")
print(" 계층 소프트맥스나 잡음 대조 추정으로 줄입니다")
print(" S8 의 언어모형에서 이 문제를 다시 만납니다")
# --- 문제 4: 확률이 맞는지 ----------------------------------------------
print(" 다중분류에서도 보정을 봐야 합니다")
print(" 206강 문제 5 의 보증이 갈래마다 성립하는지 확인합니다")
print(" %s %s %s %s"
% (pw("갈래", 10), rw("예측 확률 평균", 20), rw("실제 비율", 16),
rw("차이", 16)))
q_tr = softmax(X3 @ Ws)
for k in range(K3):
print(" %s %20.8f %16.8f %16.4e"
% (pw("%d" % k, 10), float(q_tr[:, k].mean()),
float((lab3 == k).mean()),
abs(float(q_tr[:, k].mean()) - float((lab3 == k).mean()))))
print(" 갈래마다 정확히 맞습니다. 절편이 그것을 강제합니다")
print(" 206강의 보증이 갈래 수만큼 여러 개로 늘어난 것입니다")
print(" 구간별로 보면 어떤지 봅니다")
print(" %s %s %s %s"
% (pw("예측 확률 구간", 20), rw("표본 수", 12), rw("평균 예측", 16),
rw("실제 비율", 16)))
flat_q = q_tr.ravel()
flat_y = Y3.ravel()
for lo, hi in [(0.0, 0.1), (0.1, 0.3), (0.3, 0.5), (0.5, 0.8), (0.8, 1.0)]:
m = (flat_q >= lo) & (flat_q < hi if hi < 1.0 else flat_q <= hi)
if m.sum() > 30:
print(" %s %12d %16.6f %16.6f"
% (pw("%.1f 에서 %.1f" % (lo, hi), 20), int(m.sum()),
float(flat_q[m].mean()), float(flat_y[m].mean())))
print(" 구간마다도 평균 예측과 실제 비율이 붙습니다")
print(" 학습 자료에서 그렇다는 것입니다. 새 자료는 따로 봐야 합니다")
print(" 하나 대 나머지는 어떤지 봅니다")
raw_tr = sig(X3 @ ovr)
print(" %s %s %s %s"
% (pw("무엇", 24), rw("확률 합의 평균", 20), rw("최솟값", 16),
rw("최댓값", 16)))
ssum = raw_tr.sum(axis=1)
print(" %s %20.6f %16.6f %16.6f"
% (pw("다시 나누기 전", 24), float(ssum.mean()),
float(ssum.min()), float(ssum.max())))
nn = raw_tr / ssum[:, None]
print(" %s %20.6f %16.6f %16.6f"
% (pw("다시 나눈 뒤", 24), float(nn.sum(axis=1).mean()),
float(nn.sum(axis=1).min()), float(nn.sum(axis=1).max())))
print(" 평균은 정확히 1.000000 입니다. 절편이 갈래마다 비율을 맞추기 때문입니다")
print(" 그런데 표본마다는 0.802481 에서 1.849152 까지 흩어집니다")
print(" 나누면 1 이 되지만 그렇게 만든 값이 확률이라는 보장은 없습니다")
print(" 확률이 필요하면 소프트맥스를 쓰는 것이 낫습니다")
# --- 문제 5: 실무의 다중분류 --------------------------------------------
print(" 실무에서 확인할 것을 정리합니다")
print(" %s %s"
% (pw("무엇", 26), rw("왜", 30)))
for a, b in [("갈래가 몇 개인가", "분모 비용과 방법 선택"),
("갈래가 불균형한가", "드문 갈래를 못 배움"),
("갈래에 순서가 있는가", "순서형 모형이 나음"),
("갈래가 계층인가", "계층 구조를 쓸 수 있음"),
("여러 갈래가 동시에 참인가", "다중 라벨 문제")]:
print(" %s %s" % (pw(a, 26), rw(b, 30)))
print(" 마지막 줄은 소프트맥스가 아니라 갈래마다 시그모이드를 씁니다")
print(" 갈래가 불균형하면 어떻게 되는지 봅니다")
n5 = 6000
K5 = 4
X5 = np.concatenate([np.ones((n5, 1)), rng.normal(0, 1, (n5, 2))], axis=1)
prior = np.array([0.85, 0.10, 0.04, 0.01])
W5 = np.zeros((3, K5))
W5[1:, :] = rng.normal(0, 1.0, (2, K5))
W5[0, :] = np.log(prior)
P5 = softmax(X5 @ W5)
lab5 = np.array([rng.choice(K5, p=qq) for qq in P5])
Y5 = np.zeros((n5, K5))
Y5[np.arange(n5), lab5] = 1.0
W5h = fit_soft(X5, Y5, steps=5000)
q5 = softmax(X5 @ W5h)
pred5 = q5.argmax(axis=1)
print(" %s %s %s %s"
% (pw("갈래", 10), rw("실제 비율", 14), rw("예측된 비율", 16),
rw("그 갈래의 재현율", 20)))
for k in range(K5):
m = lab5 == k
rec = float((pred5[m] == k).mean()) if m.sum() > 0 else 0.0
print(" %s %14.6f %16.6f %20.6f"
% (pw("%d" % k, 10), float(m.mean()), float((pred5 == k).mean()), rec))
print(" 드문 갈래는 한 번도 예측되지 않습니다")
print(" 확률은 맞는데 최댓값을 고르면 언제나 흔한 갈래가 이깁니다")
print(" 227강에서 이 문제를 정면으로 다룹니다")
print(" 문턱을 갈래마다 바꿔 봅니다")
print(" %s %s %s %s"
% (pw("어떻게 고르나", 26), rw("전체 정확도", 16),
rw("가장 드문 갈래 재현율", 24), rw("거시 평균 재현율", 20)))
rows = []
rows.append(("가장 큰 확률", pred5))
adj = q5 / prior[None, :]
rows.append(("사전확률로 나눠", adj.argmax(axis=1)))
rows.append(("균등 사전으로 바꿈",
(q5 / prior[None, :] * (1.0 / K5)).argmax(axis=1)))
for nm, pr in rows:
acc = float((pr == lab5).mean())
recs = [float((pr[lab5 == k] == k).mean()) for k in range(K5)]
print(" %s %16.6f %24.6f %20.6f"
% (pw(nm, 26), acc, recs[3], float(np.mean(recs))))
print(" 사전확률로 나누면 드문 갈래의 재현율이 크게 오릅니다")
print(" 대신 전체 정확도가 내려갑니다. 무엇을 원하는지가 정합니다")
print(" 둘째와 셋째가 같습니다. 상수를 곱해도 argmax 가 안 바뀝니다")
print(" 02 단원을 정리합니다")
print(" %s %s"
% (pw("강의", 14), rw("무엇을 세웠나", 34)))
for a, b in [("205", "무엇을 최소화할지의 틀"),
("206", "손실이 어디서 오는지"),
("207", "닫힌 해와 수치 안정성"),
("208", "닫힌 해가 없을 때의 반복"),
("209", "여러 갈래로의 확장")]:
print(" %s %s" % (pw(a, 14), rw(b, 34)))
print(" 다섯 강이 학습을 최적화 문제 하나로 적는 과정이었습니다")
print(" 03 단원은 그 답이 새 자료에서도 맞는지를 묻습니다")
# 208강은 갈래가 둘인 문제를 풀었습니다. 이제 셋 이상으로 넓힙니다
# 갈래마다 로짓을 하나씩 두고 소프트맥스로 확률을 만듭니다
# 갈래가 둘이면 소프트맥스가 시그모이드가 되는지 확인합니다
# 로짓 차이 시그모이드 소프트맥스 첫 칸 차이
# -3.0 0.0474258732 0.0474258732 6.9389e-18
# -1.0 0.2689414214 0.2689414214 0.0000e+00
# 0.0 0.5000000000 0.5000000000 0.0000e+00
# 1.0 0.7310585786 0.7310585786 0.0000e+00
# 3.0 0.9525741268 0.9525741268 0.0000e+00
# 완전히 같습니다. 소프트맥스가 시그모이드의 일반화입니다
# 갈래가 둘일 때 두 로짓의 차이만 뜻이 있습니다
# 자유도가 하나 남습니다
# 모든 갈래의 로짓에 같은 값을 더해도 확률이 안 바뀝니다
# 무엇을 더하나 첫 표본의 확률
# 0.0 0.26799613 0.40689187 0.31114313 0.01396886
# 5.0 0.26799613 0.40689187 0.31114313 0.01396886
# -20.0 0.26799613 0.40689187 0.31114313 0.01396886
# 갈래가 K 개면 자유 모수가 K 빼기 1 개분입니다
# 186강 문제 1 의 더미변수 함정과 같은 구조입니다
# 한 갈래를 기준으로 고정해 봅니다
# 어떻게 맞추나 교차엔트로피 계수의 크기 첫 갈래 계수 합
# 모두 자유 0.7823864447 1.937830 0.373779
# 첫 갈래를 0 으로 0.7823864447 1.980840 0.000000
# 두 방식의 교차엔트로피가 0.7823864447 로 똑같습니다. 같은 확률을 냅니다
# 첫 갈래 계수 합이 0.373779 와 0.000000 으로 다릅니다
# 계수는 다른데 확률은 같습니다. 자유도 하나가 남는다는 뜻입니다
# 계수의 크기는 1.937830 과 1.980840 으로 자유로운 쪽이 조금 작습니다
# 0 에서 시작해 경사하강으로 갔기 때문입니다. 자연히 작은 해로 갑니다
# 정규화를 걸면 모두 자유로운 쪽도 답이 하나로 정해집니다
# 기울기가 이진과 같은 모양입니다
# 로짓에 대한 기울기가 예측 확률 빼기 목표 분포입니다
# 무엇 기울기
# 이진 교차엔트로피 예측 확률 빼기 관측
# 소프트맥스 교차엔트로피 예측 확률 벡터 빼기 원핫
# 가중치에 대해서는 위에 x 를 곱함
# 수치 미분과 견줘 확인합니다
# 무엇 값 판정
# 해석 기울기와의 최대 차 1.2622e-10 같음
# 소수점 아래 아홉 자리까지 같습니다. 유도가 맞습니다
# 야코비 행렬을 봅니다
# 소프트맥스의 야코비는 대각 q 에서 q q 전치를 뺀 것입니다
# 무엇 값 이론값
# 행의 합 0.0000000000 0.000000
# 대칭인가 0.0000000000 0.000000
# 가장 작은 고유값 0.0000000000 0.000000
# 대각합 0.5616505357 0.561651
# 행의 합이 0 입니다. 확률의 합이 1 로 고정이기 때문입니다
# 가장 작은 고유값이 0 입니다. 그것이 자유도 하나가 남는다는 뜻입니다
# 뉴턴을 쓰려면 헤세가 커집니다
# 변수 갈래 헤세의 크기 이진 대비
# 10 2 100 1.0
# 10 10 8100 81.0
# 100 10 810000 81.0
# 100 100 98010000 9801.0
# 갈래가 100 이면 헤세가 이진의 만 배 가까이 됩니다
# 그래서 다중분류는 대개 경사하강으로 풉니다
# 208강 문제 2 의 손익분기가 갈래 수만큼 앞당겨집니다
# 이진 분류기를 여러 개 써서 넓힐 수도 있습니다
# 방법 분류기 개수 한 개가 보는 자료 무엇이 문제
# 소프트맥스 1 개 전부 갈래가 많으면 분모가 비쌈
# 하나 대 나머지 K 개 전부 확률의 합이 1 이 아님
# 하나 대 하나 K(K-1)/2 개 두 갈래분 개수가 제곱으로 늚
# 오류 정정 부호 정하기 나름 부분집합 설계가 어려움
# 둘째 줄이 흔히 쓰이는데 확률로 읽으려면 다시 정규화해야 합니다
# 세 방법을 같은 자료로 견줍니다
# 방법 검증 정확도 확률 합의 평균 검증 교차엔트로피
# 소프트맥스 0.644667 1.000000 0.899010
# 하나 대 나머지 0.643000 1.007647 0.914752
# 하나 대 하나 0.645000 6.000000 1.063491
# 정확도는 셋이 비슷합니다. 참 구조가 소프트맥스라 첫 줄이 조금 낫습니다
# 하나 대 나머지는 확률의 합이 1 이 아닙니다. 다시 나눠야 합니다
# 하나 대 하나는 표를 세는 것이라 확률 해석이 더 약합니다
# 갈래가 아주 많으면 분모가 문제입니다
# 갈래 수 분모의 항 수 한 표본당 곱셈
# 10 10 3000
# 1000 1000 300000
# 100000 100000 30000000
# 1000000 1000000 300000000
# 단어가 100 만 개면 표본 하나에 3 억 번 곱합니다
# 계층 소프트맥스나 잡음 대조 추정으로 줄입니다
# S8 의 언어모형에서 이 문제를 다시 만납니다
# 다중분류에서도 보정을 봐야 합니다
# 206강 문제 5 의 보증이 갈래마다 성립하는지 확인합니다
# 갈래 예측 확률 평균 실제 비율 차이
# 0 0.15700000 0.15700000 0.0000e+00
# 1 0.15500000 0.15500000 8.3267e-17
# 2 0.53600000 0.53600000 1.1102e-16
# 3 0.15200000 0.15200000 2.7756e-17
# 갈래마다 정확히 맞습니다. 절편이 그것을 강제합니다
# 206강의 보증이 갈래 수만큼 여러 개로 늘어난 것입니다
# 구간별로 보면 어떤지 봅니다
# 예측 확률 구간 표본 수 평균 예측 실제 비율
# 0.0 에서 0.1 4320 0.041498 0.044213
# 0.1 에서 0.3 4443 0.187390 0.186135
# 0.3 에서 0.5 1125 0.393376 0.387556
# 0.5 에서 0.8 1360 0.644479 0.644118
# 0.8 에서 1.0 752 0.889781 0.890957
# 구간마다도 평균 예측과 실제 비율이 붙습니다
# 학습 자료에서 그렇다는 것입니다. 새 자료는 따로 봐야 합니다
# 하나 대 나머지는 어떤지 봅니다
# 무엇 확률 합의 평균 최솟값 최댓값
# 다시 나누기 전 1.000000 0.802481 1.849152
# 다시 나눈 뒤 1.000000 1.000000 1.000000
# 평균은 정확히 1.000000 입니다. 절편이 갈래마다 비율을 맞추기 때문입니다
# 그런데 표본마다는 0.802481 에서 1.849152 까지 흩어집니다
# 나누면 1 이 되지만 그렇게 만든 값이 확률이라는 보장은 없습니다
# 확률이 필요하면 소프트맥스를 쓰는 것이 낫습니다
# 실무에서 확인할 것을 정리합니다
# 무엇 왜
# 갈래가 몇 개인가 분모 비용과 방법 선택
# 갈래가 불균형한가 드문 갈래를 못 배움
# 갈래에 순서가 있는가 순서형 모형이 나음
# 갈래가 계층인가 계층 구조를 쓸 수 있음
# 여러 갈래가 동시에 참인가 다중 라벨 문제
# 마지막 줄은 소프트맥스가 아니라 갈래마다 시그모이드를 씁니다
# 갈래가 불균형하면 어떻게 되는지 봅니다
# 갈래 실제 비율 예측된 비율 그 갈래의 재현율
# 0 0.662000 0.722667 0.923968
# 1 0.291167 0.277333 0.761878
# 2 0.035333 0.000000 0.000000
# 3 0.011500 0.000000 0.000000
# 드문 갈래는 한 번도 예측되지 않습니다
# 확률은 맞는데 최댓값을 고르면 언제나 흔한 갈래가 이깁니다
# 227강에서 이 문제를 정면으로 다룹니다
# 문턱을 갈래마다 바꿔 봅니다
# 어떻게 고르나 전체 정확도 가장 드문 갈래 재현율 거시 평균 재현율
# 가장 큰 확률 0.833500 0.000000 0.421461
# 사전확률로 나눠 0.440167 0.579710 0.544850
# 균등 사전으로 바꿈 0.440167 0.579710 0.544850
# 사전확률로 나누면 드문 갈래의 재현율이 크게 오릅니다
# 대신 전체 정확도가 내려갑니다. 무엇을 원하는지가 정합니다
# 둘째와 셋째가 같습니다. 상수를 곱해도 argmax 가 안 바뀝니다
# 02 단원을 정리합니다
# 강의 무엇을 세웠나
# 205 무엇을 최소화할지의 틀
# 206 손실이 어디서 오는지
# 207 닫힌 해와 수치 안정성
# 208 닫힌 해가 없을 때의 반복
# 209 여러 갈래로의 확장
# 다섯 강이 학습을 최적화 문제 하나로 적는 과정이었습니다
# 03 단원은 그 답이 새 자료에서도 맞는지를 묻습니다