201강에서 엔트로피가 압축의 하한이라고 했습니다. 그 하한은 참 분포를 알 때의 이야기입니다.
그 "더 쓴 양"이 KL 발산입니다.
두 분포가 얼마나 어긋나 있는지를 재는 자이며, 202강의 상호정보량이 그 특수한 경우이고 204강의 손실함수가 그것을 그대로 씁니다.
그런데 거리가 아닙니다. 대칭이 아니고 삼각부등식도 안 되며, 어느 방향으로 재느냐가 근사의 모양을 바꿉니다.
문제. KL을 정의합니다.
(1) 더 쓴 비트를 재세요.
(2) 비음성을 확인하세요.
(3) 거리가 아닌 이유를 보이세요.
생각의 실마리. 201강 문제 2에서 확률이 의 거듭제곱이면 부호 길이가 였습니다. 그 가 틀린 값이면 어떻게 될까요.
풀이. (1) 더 쓴 비트를 잽니다.
| 어떤 분포로 부호를 만드나 | 평균 길이 | 참 엔트로피 | 더 쓴 양 | KL |
|---|---|---|---|---|
| 참 분포와 같음 | ||||
| 조금 다름 | ||||
| 많이 다름 | ||||
| 균등이라고 봄 |
더 쓴 양이 정확히 KL 발산입니다. 그것이 이 양의 뜻입니다.
참 분포를 쓸 때만 이고 나머지는 모두 양수입니다.
(2) 비음성을 확인합니다. 만 쌍을 무작위로 만들어 계산합니다.
| 무엇 | 값 | 판정 |
|---|---|---|
| 음수가 나온 횟수 | 없음 | |
| 가장 작은 값 | 이상 |
132강의 젠센 부등식으로 증명됩니다. 로그가 오목하기 때문입니다.
(3) 거리가 아닌 이유를 봅니다.
| 어떤 성질 | 거리라면 | KL은 | 성립 |
|---|---|---|---|
| 자기 자신과는 | 예 | ||
| 대칭 | 아니오 | ||
| 삼각부등식 | 이하여야 | 아니오 |
대칭이 아니므로 거리가 아닙니다. 그래서 발산이라 부릅니다.
삼각부등식도 위 예에서 이미 깨졌습니다. 만큼 넘어섭니다.
만 번 중 번 삼각부등식이 깨졌습니다. 우연이 아니라 분의 꼴로 일어납니다.
이 문제에서 배우는 것. "두 분포가 얼마나 다른가"라는 물음이 하나의 답을 갖지 않습니다. KL이 답이 되는 물음은 정확히 **"로 부호를 만들어 에서 온 자료를 적으면 얼마나 손해인가"**이고, 그 물음이 비대칭이므로 답도 비대칭입니다. 를 로 근사하는 손해와 를 로 근사하는 손해는 애초에 다른 상황입니다. 문제 4에서 대칭인 자들을 보지만, 대칭으로 만들면 우도와의 연결이 끊어집니다.
바로 확인 1.
확인 1-1. KL 발산이 무엇을 재는지 한 문장으로 쓰세요.
답. 틀린 분포로 부호를 만들었을 때 더 쓰는 비트 수입니다.
확인 1-2. 검산에서 네 분포의 KL을 쓰세요.
답. , , , 입니다.
확인 1-3. 검산에서 삼각부등식이 깨진 횟수를 쓰세요.
답. 만 번 중 번입니다.
문제. 두 방향을 견줍니다.
(1) 두 봉우리를 하나로 근사해 보세요.
(2) 벌이 어디서 나오는지 보세요.
(3) 어느 방향을 쓰는지 정리하세요.
생각의 실마리. 와 가 다른 답을 냅니다. 어떻게 다른지 봅니다.
풀이. (1) 봉우리가 둘인 참 분포를 봉우리 하나로 근사합니다.
| 어느 방향으로 재나 | 최적 평균 | 최적 표준편차 | 그때의 값 | 어떤 모양 |
|---|---|---|---|---|
| 넓게 덮음 | ||||
| 한쪽에 붙음 |
앞쪽은 평균 에 표준편차 로 두 봉우리를 다 덮습니다.
뒤쪽은 평균 에 표준편차 로 한 봉우리에 정확히 붙습니다. 참 봉우리의 표준편차가 이므로 그 봉우리를 그대로 베낀 것입니다.
(2) 왜 그런지 봅니다.
| 어떤 자리 | ||
|---|---|---|
| 참은 큰데 근사가 에 가까움 | 무한대로 커짐 | 거의 벌 없음 |
| 근사는 큰데 참이 에 가까움 | 거의 벌 없음 | 무한대로 커짐 |
| 둘 다 에 가까움 | 벌 없음 | 벌 없음 |
앞쪽은 참이 있는 곳에 근사가 없으면 큰 벌을 받습니다. 그래서 두 봉우리를 다 덮으려고 넓게 퍼집니다.
뒤쪽은 근사가 있는 곳에 참이 없으면 벌을 받습니다. 그래서 한 봉우리에 좁게 붙습니다.
한쪽이 인데 다른 쪽이 양수면 값이 무한이 됩니다.
| 무엇 | 값 |
|---|---|
| 이 있는 쪽 없는 쪽 | |
| 없는 쪽 이 있는 쪽 | 무한대 |
실무에서 이것 때문에 확률에 아주 작은 값을 더해 둡니다.
(3) 어느 방향을 쓰는지 정리합니다.
| 어디서 | 어느 방향 | 왜 |
|---|---|---|
| 최대우도 학습 | 자료를 다 덮어야 | |
| 변분추론 | 계산이 되는 쪽 | |
| 지식 증류 | 교사를 다 배워야 | |
| 정책 최적화 | 너무 멀리 안 가게 |
둘째 줄이 봉우리 하나에 붙는 성질 때문에 문제가 되기도 합니다.
이 문제에서 배우는 것. 생성모형이 흐릿한 결과를 내는 이유가 첫째 줄에 있습니다. 최대우도는 을 줄이므로 자료가 있는 모든 곳을 덮으려 하고, 그래서 실제로는 없는 중간 영역에도 확률을 줍니다. 얼굴 생성에서 흐릿한 평균 얼굴이 나오는 것이 그 결과입니다. 반대로 뒤쪽 방향을 쓰면 선명하지만 다양성을 잃습니다. 어느 쪽도 공짜가 아니며, S11의 생성모형이 이 맞바꿈을 정면으로 다룹니다.
바로 확인 2.
확인 2-1. 검산에서 두 방향의 최적 평균과 표준편차를 쓰세요.
답. 과 , 과 입니다.
확인 2-2. 두 방향이 각각 어떤 자리에서 큰 벌을 받는지 쓰세요.
답. 앞쪽은 참이 있는데 근사가 없을 때, 뒤쪽은 근사가 있는데 참이 없을 때입니다.
확인 2-3. 검산에서 이 있는 쪽을 앞에 둘 때와 뒤에 둘 때의 값을 쓰세요.
답. 과 무한대입니다.
문제. 학습과 잇습니다.
(1) 로그우도와 교차엔트로피를 견주세요.
(2) 표본이 늘면 어디로 가는지 보세요.
(3) 모형이 틀리면 어디로 가는지 보세요.
생각의 실마리. 자료로 모형을 맞추는 것이 곧 KL을 줄이는 것입니다.
풀이. (1) 정규분포의 평균을 여러 값으로 두고 봅니다. 참 평균은 이고 표본은 개입니다.
| 가정한 평균 | 평균 로그우도 | 교차엔트로피 | 합 |
|---|---|---|---|
교차엔트로피가 평균 로그우도의 부호를 바꾼 것과 같습니다.
우도를 최대로 하는 것이 교차엔트로피를 최소로 하는 것입니다.
참 엔트로피는 모형과 무관한 상수이므로 KL을 최소로 하는 것과 같습니다.
(2) 표본이 늘면 어디로 가는지 봅니다.
| 표본 크기 | 최대우도 평균 | 참값 | 교차엔트로피 |
|---|---|---|---|
표본이 늘면 참값으로 갑니다. 149강 문제 3의 일치성입니다.
교차엔트로피는 참 엔트로피 로 수렴합니다.
다만 표본 에서 으로 참값보다 작습니다. 자기 자료에 맞춘 평균으로 잰 값이라 낙관됩니다. 189강 문제 1과 같습니다.
(3) 모형이 틀리면 어디로 가는지 봅니다. 참은 두 봉우리인데 정규 하나로 맞춥니다.
| 무엇 | 값 | 무엇을 뜻하나 |
|---|---|---|
| 최대우도 평균 | 두 봉우리의 가운데 | |
| 최대우도 표준편차 | 봉우리 사이 거리까지 담음 | |
| 참 봉우리의 표준편차 | 각 봉우리 안의 퍼짐 |
모형이 틀려도 최대우도는 KL을 가장 작게 하는 자리로 갑니다.
그 자리가 참과 같지는 않습니다. 가장 가까운 근사일 뿐입니다.
문제 2의 앞쪽 방향과 같은 답입니다. 표준편차 이 문제 2의 와 거의 같습니다.
이 문제에서 배우는 것. "최대우도가 참값을 찾는다"는 말에 조건이 붙습니다. 참 분포가 모형 안에 있어야 하며, 없으면 KL을 가장 작게 하는 자리로 갈 뿐입니다. 그 자리를 유사참값이라 하고, 위 표에서 과 이 그것입니다. 그런데 자료의 어느 봉우리도 그 자리에 없으므로 예측이 모든 관측에서 나쁩니다. 189강 문제 2의 모형 선택이 필요한 이유이고, 잔차를 보면 이 결함이 드러납니다.
바로 확인 3.
확인 3-1. 최대우도와 교차엔트로피의 관계를 쓰세요.
답. 평균 로그우도의 부호를 바꾼 것이 교차엔트로피이며 최대화와 최소화가 같은 일입니다.
확인 3-2. 검산에서 표본 과 의 최대우도 평균을 쓰세요.
답. 과 입니다.
확인 3-3. 검산에서 모형이 틀릴 때의 최대우도 표준편차와 참 봉우리의 표준편차를 쓰세요.
답. 과 입니다.
문제. 다른 자와 견줍니다.
(1) 네 자를 정리하세요.
(2) 같은 쌍을 네 자로 재세요.
(3) 겹치지 않을 때를 보세요.
생각의 실마리. KL이 무한이 되는 자리가 있고 대칭이 아닙니다. 그 둘을 고친 자들이 있습니다.
풀이. (1) 정리합니다.
| 이름 | 대칭인가 | 무엇이 좋은가 |
|---|---|---|
| KL 발산 | 아니오 | 우도와 바로 이어짐 |
| 젠센-섀넌 | 예 | 언제나 유한하고 제곱근이 거리 |
| 전변동거리 | 예 | 확률 차이의 최대 |
| 헬링거 거리 | 예 | 제곱근을 쓰면 안정적 |
| 바서슈타인 | 예 | 값의 위치를 반영 |
(2) 같은 쌍을 네 자로 잽니다.
| 두 분포 | KL | 젠센-섀넌 | 전변동 | 헬링거 |
|---|---|---|---|---|
| 거의 같음 | ||||
| 꽤 다름 | ||||
| 한쪽이 | ||||
| 반대로 | 무한대 |
마지막 줄에서 KL만 무한대가 됩니다. 나머지 셋은 유한하고, 셋째 줄과 같은 값입니다.
젠센-섀넌은 두 분포의 평균을 가운데 두므로 언제나 유한합니다.
그것이 생성모형에서 이 자를 쓰는 이유입니다.
(3) 겹치지 않을 때를 봅니다. 두 점 분포를 떨어뜨려 갑니다.
| 떨어진 거리 | KL | 젠센-섀넌 | 전변동 | 바서슈타인 |
|---|---|---|---|---|
| 무한대 | ||||
| 무한대 | ||||
| 무한대 |
겹치지 않으면 앞의 셋이 거리와 무관하게 같은 값을 냅니다. 만큼 떨어진 것과 만큼 떨어진 것을 구분하지 못합니다.
바서슈타인만 거리를 반영합니다. 그래서 기울기가 살아 있습니다.
생성모형 학습에서 이 성질이 중요합니다. 초기의 생성 분포가 자료와 전혀 안 겹치면 앞의 셋으로는 어느 쪽으로 움직여야 할지 알 수 없습니다.
이 문제에서 배우는 것. 자를 고르는 것이 학습이 되느냐 마느냐를 정합니다. 위 표의 셋째 열이 상수이면 그 자로 만든 손실함수의 기울기가 이고, 최적화가 아예 시작되지 않습니다. 이것이 초기 생성적 적대 신경망이 학습에 실패하던 이유이고, 바서슈타인을 쓴 변형이 나온 배경입니다. "두 분포가 다르다"는 사실만으로는 부족하고 "어느 쪽으로 얼마나 다른가"가 필요합니다.
바로 확인 4.
확인 4-1. 젠센-섀넌이 언제나 유한한 이유를 쓰세요.
답. 두 분포의 평균을 가운데 두므로 한쪽이 인 자리가 안 생기기 때문입니다.
확인 4-2. 검산에서 "반대로 "인 쌍의 네 값을 쓰세요.
답. 무한대, , , 입니다.
확인 4-3. 겹치지 않는 두 분포에서 어느 자만 거리를 반영하는지 쓰세요.
답. 바서슈타인이며 , , 을 그대로 냅니다.
문제. 운영에 씁니다.
(1) 쓰이는 자리를 정리하세요.
(2) 자료 이동을 감시하세요.
(3) 문턱과 칸 개수를 정하세요.
생각의 실마리. 학습 때의 분포와 지금 들어오는 분포가 달라지면 모형이 무너집니다. 그 차이를 재는 자가 필요합니다.
풀이. (1) 쓰이는 자리를 정리합니다.
| 어디 | 무엇을 재나 |
|---|---|
| 분류 손실 | 라벨과 예측 확률의 어긋남 |
| 변분 오토인코더 | 잠재 분포와 사전분포의 어긋남 |
| 지식 증류 | 교사와 학생 출력의 어긋남 |
| 정책 경사 | 새 정책과 옛 정책의 어긋남 |
| 자료 이동 감시 | 학습 때와 지금 분포의 어긋남 |
마지막 줄이 운영에서 가장 자주 쓰입니다.
(2) 자료 이동을 감시합니다. 학습 때 분포를 열 칸으로 나누고 지금 자료와 견줍니다.
| 지금 자료 | KL | 젠센-섀넌 | 판정 |
|---|---|---|---|
| 그대로 | 정상 | ||
| 평균이 옮겨감 | 이동 의심 | ||
| 평균이 옮겨감 | 이동 의심 | ||
| 퍼짐이 배 | 이동 의심 |
평균이 만 옮겨가도 이 으로 열일곱 배가 됩니다.
문턱을 정하려면 정상일 때의 흔들림을 먼저 재야 합니다.
(3) 정상일 때의 흔들림을 잽니다.
| 표본 크기 | KL 평균 | KL의 분위 | 참값 |
|---|---|---|---|
표본이 작으면 아무 일이 없어도 KL이 큽니다. 표본 의 분위 가 위 표의 "평균이 옮겨감"보다는 작지만 " 옮겨감"보다 큽니다.
201강 문제 5의 치우침이 여기서도 그대로입니다.
앞 표에서 쓴 문턱 은 표본 의 분위 보다 넉넉합니다.
칸을 나누는 방식도 값을 바꿉니다.
| 칸 개수 | 평균 이동 | 정상일 때 분위 | 신호 대 잡음 |
|---|---|---|---|
칸을 늘리면 신호가 에서 로 조금 커집니다.
그런데 잡음은 에서 로 훨씬 크게 커집니다.
마지막 열이 계속 줄어듭니다. 여기서는 칸을 적게 쓰는 쪽이 낫고, 칸 개수는 그 비가 가장 큰 자리로 고릅니다.
이 문제에서 배우는 것. 자료 이동 감시는 검정이지 지표가 아닙니다. "KL이 이니 이동했다"는 판정이 성립하려면 정상일 때 그 값이 얼마나 나오는지를 알아야 하고, 그것은 표본 크기와 칸 개수에 함께 달렸습니다. 178강 문제 4의 귀무분포를 여기서 시뮬레이션으로 만든 셈이며, 실무에서는 최근 정상 구간을 여러 번 잘라 기준선 분포를 만들어 두고 그 분위를 문턱으로 씁니다. 문턱을 고정 상수로 박아 두면 트래픽이 줄어드는 밤 시간에 거짓 경보가 쏟아집니다.
바로 확인 5.
확인 5-1. 검산에서 평균이 옮겨갔을 때와 그대로일 때의 KL을 쓰세요.
답. 과 입니다.
확인 5-2. 검산에서 표본 과 의 분위를 쓰세요.
답. 와 입니다.
확인 5-3. 검산에서 칸 개와 개의 신호 대 잡음을 쓰세요.
답. 과 입니다.
| 무엇 | 식 |
|---|---|
| KL 발산 | |
| 교차엔트로피 | |
| 관계 | 교차엔트로피 엔트로피 KL |
| 젠센-섀넌 | 평균과의 KL을 반씩 |
| 전변동 | 확률 차이 절댓값의 절반 |
| 성질 | KL |
|---|---|
| 비음성 | 예 |
| 자기 자신과 | 예 |
| 대칭 | 아니오 |
| 삼각부등식 | 아니오 |
| 유한 | 아니오 |
| 방향 | 근사의 모양 |
|---|---|
| 넓게 덮음 | |
| 한쪽에 붙음 |
| 자주 하는 실수 | 바로잡기 |
|---|---|
| KL을 거리라고 부릅니다 | 대칭도 삼각부등식도 안 됩니다 |
| 방향을 아무렇게나 씁니다 | 근사의 모양이 달라집니다 |
| 인 칸을 그냥 둡니다 | 무한이 됩니다 |
| 문턱을 고정 상수로 둡니다 | 표본 크기에 따라 달라집니다 |
| 칸을 많이 나눕니다 | 잡음이 더 빨리 커집니다 |
문제 6. KL 발산이 무엇을 재는지 한 문장으로 쓰세요.
답. 틀린 분포로 부호를 만들었을 때 더 쓰는 비트 수입니다.
문제 7. 검산에서 네 분포의 KL을 쓰세요.
답. , , , 입니다.
문제 8. 교차엔트로피와 엔트로피와 KL의 관계를 쓰세요.
답. 교차엔트로피가 엔트로피와 KL의 합입니다.
문제 9. 검산에서 삼각부등식이 깨진 횟수를 쓰세요.
답. 만 번 중 번입니다.
문제 10. 검산에서 두 방향의 최적 평균과 표준편차를 쓰세요.
답. 과 , 과 입니다.
문제 11. 두 방향이 각각 어떤 자리에서 큰 벌을 받는지 쓰세요.
답. 앞쪽은 참이 있는데 근사가 없을 때, 뒤쪽은 근사가 있는데 참이 없을 때입니다.
문제 12. 최대우도와 교차엔트로피의 관계를 쓰세요.
답. 평균 로그우도의 부호를 바꾼 것이 교차엔트로피입니다.
문제 13. 검산에서 표본 과 의 최대우도 평균을 쓰세요.
답. 과 입니다.
문제 14. 검산에서 모형이 틀릴 때의 최대우도 표준편차를 쓰세요.
답. 이며 참 봉우리는 입니다.
문제 15. 검산에서 "반대로 "인 쌍의 네 값을 쓰세요.
답. 무한대, , , 입니다.
문제 16. 겹치지 않는 두 분포에서 어느 자만 거리를 반영하는지 쓰세요.
답. 바서슈타인입니다.
문제 17. 검산에서 표본 과 의 분위를 쓰세요.
답. 와 입니다.
문제 18. 검산에서 칸 개와 개의 신호 대 잡음을 쓰세요.
답. 과 입니다.
심화 1. 상호정보량이 KL의 특수한 경우임을 정리하세요.
| 무엇 | 무엇에 대응 |
|---|---|
| 참 분포 | 실제 결합분포 |
| 근사 분포 | 독립이라면 이랬을 분포 |
| KL | 상호정보량 |
202강 문제 1의 비음성이 여기서 따라 나옵니다. KL이 이상이므로 상호정보량도 이상입니다.
이 되는 조건도 같습니다. 두 분포가 같을 때, 곧 독립일 때입니다.
조건부 상호정보량도 같은 식으로 조건부 KL이 됩니다.
심화 2. 피셔 정보와의 관계를 정리하세요.
두 분포가 아주 가까울 때 KL이 이차식이 됩니다.
| 무엇 | 뜻 |
|---|---|
| 피셔 정보 행렬 | |
| 일차항 | |
| 이차항 | 피셔 정보의 절반 |
KL이 모수 공간의 국소적인 거리를 정의합니다. 유클리드 거리가 아니라 분포가 얼마나 달라지느냐로 재는 거리입니다.
자연 그래디언트가 이 거리를 씁니다. 모수를 같은 크기로 움직여도 분포 변화가 다르므로, 분포 변화 기준으로 걸음을 정합니다.
152강의 피셔 정보와 109강의 헤세 행렬이 여기서 만납니다.
심화 3. 변분 하한을 정리하세요.
| 항 | 뜻 |
|---|---|
| 왼쪽 | 알고 싶은 로그 증거 |
| \mathcal | 계산 가능한 하한 |
| KL | 근사의 어긋남 |
KL이 이상이므로 이 하한입니다.
하한을 올리는 것이 곧 KL을 줄이는 것입니다. 왼쪽이 와 무관한 상수이기 때문입니다.
문제 2의 뒤쪽 방향이 여기서 쓰입니다. 참 사후분포를 모르는데도 계산이 되는 쪽이 그쪽뿐입니다.
그 대가가 봉우리 하나에 붙는 성질입니다. 사후분포가 여러 봉우리면 하나만 잡습니다.
심화 4. 라벨 평활을 정리하세요.
정답 라벨을 대신 로 두는 기법입니다.
| 무엇 | 왜 |
|---|---|
| 원핫 라벨 | 확신을 무한히 키우려 함 |
| 평활한 라벨 | 확신에 상한을 둠 |
| 결과 | 과확신이 줄고 보정이 나아짐 |
원핫 라벨은 확률 을 목표로 하므로 로짓이 무한대로 갑니다.
평활하면 최적 로짓이 유한해집니다. 그것이 정규화로 작동합니다.
201강 심화 5의 출력 엔트로피 벌점과 비슷하지만 다릅니다. 이쪽은 목표 분포를 바꾸고 저쪽은 손실에 항을 더합니다.
심화 5. KL을 추정하는 법을 정리하세요.
| 방법 | 언제 |
|---|---|
| 칸으로 나누기 | 저차원이고 표본이 많을 때 |
| 최근접이웃 | 연속 다차원 |
| 밀도비 추정 | 분류기로 비를 추정 |
| 변분 하한 | 신경망으로 하한 최대화 |
셋째 줄이 실무에서 널리 쓰입니다. 두 표본을 구분하는 분류기를 학습하면 그 출력에서 밀도비가 나옵니다.
분류기가 두 표본을 잘 구분할수록 KL이 큽니다. 자료 이동 감시를 분류 문제로 바꾸는 방법입니다.
193강 문제 5의 AUC와 이어집니다. 다만 그쪽에서는 AUC가 높은 것이 나쁜 신호였고 여기서는 이동의 신호입니다.
심화 6. 이 강의가 남긴 문제를 정리하세요.
두 분포의 어긋남을 쟀는데 그것을 손실함수로 쓰는 것은 아직입니다.
| 무엇을 못 했나 | 어디서 |
|---|---|
| 분류 손실의 유도 | 강 |
| 로지스틱과 소프트맥스의 연결 | 강 |
| 회귀 손실이 왜 제곱인가 | 강 |
"제곱오차를 쓴다"거나 "교차엔트로피를 쓴다"는 것이 선택이 아니라 유도의 결과임을 보입니다. 분포를 무엇으로 가정하느냐가 손실을 정하며, 그 다리가 이 강의의 문제 3입니다.
정답.
| 기호 | 읽는 법 | 뜻 |
|---|---|---|
| KL 발산 | 로 를 적을 때 더 쓰는 양입니다 | |
| 교차엔트로피 | cross entropy | 엔트로피와 KL의 합입니다 |
| 젠센-섀넌 | Jensen-Shannon | 대칭이고 언제나 유한합니다 |
| 전변동거리 | total variation | 확률 차이 절댓값의 절반입니다 |
| 헬링거 거리 | Hellinger | 제곱근의 차이로 잽니다 |
| 바서슈타인 | Wasserstein | 옮기는 비용으로 잽니다 |
| 유사참값 | pseudo-true value | 모형이 틀릴 때 도달하는 자리입니다 |
| 변분 하한 | ELBO | 로그 증거의 계산 가능한 하한입니다 |
| 자료 이동 | data drift | 학습 때와 분포가 달라진 것입니다 |
| 라벨 평활 | label smoothing | 목표 확률을 보다 작게 둡니다 |
다음은 204강 교차엔트로피와 손실함수의 유도입니다. 이 강의가 두 분포의 어긋남을 쟀습니다.
문제 3에서 최대우도가 KL을 줄이는 것과 같음을 봤습니다. 204강은 그 다리를 건너 분포 가정이 손실함수를 정한다는 것을 보입니다. 정규를 가정하면 제곱오차, 베르누이를 가정하면 이진 교차엔트로피, 다항을 가정하면 소프트맥스 교차엔트로피가 유도되어 나옵니다.
import numpy as np
rng = np.random.default_rng(20261010)
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 H(p, base=2.0):
p = np.asarray(p, dtype=float).ravel()
p = p[p > 0]
return float(-(p * (np.log(p) / np.log(base))).sum()) + 0.0
def KL(p, q, base=2.0):
p = np.asarray(p, dtype=float).ravel()
q = np.asarray(q, dtype=float).ravel()
m = p > 0
if np.any(q[m] <= 0):
return float("inf")
return float((p[m] * (np.log(p[m] / q[m]) / np.log(base))).sum()) + 0.0
def CE(p, q, base=2.0):
p = np.asarray(p, dtype=float).ravel()
q = np.asarray(q, dtype=float).ravel()
m = p > 0
if np.any(q[m] <= 0):
return float("inf")
return float(-(p[m] * (np.log(q[m]) / np.log(base))).sum()) + 0.0
# --- 문제 1: 틀린 분포로 부호를 만들면 -------------------------------
print(" 201강에서 엔트로피가 압축의 하한이라고 했습니다")
print(" 그 하한은 참 분포를 알 때의 이야기입니다")
print(" 틀린 분포로 부호를 만들면 몇 비트를 더 쓰는지 재 봅니다")
p = np.array([0.5, 0.25, 0.125, 0.125])
qs = [("참 분포와 같음", np.array([0.5, 0.25, 0.125, 0.125])),
("조금 다름", np.array([0.4, 0.3, 0.2, 0.1])),
("많이 다름", np.array([0.1, 0.2, 0.3, 0.4])),
("균등이라고 봄", np.array([0.25, 0.25, 0.25, 0.25]))]
print(" %s %s %s %s %s"
% (pw("어떤 분포로 부호를 만드나", 28), rw("평균 길이", 14),
rw("참 엔트로피", 14), rw("더 쓴 양", 12), rw("KL", 12)))
for nm, q in qs:
print(" %s %14.6f %14.6f %12.6f %12.6f"
% (pw(nm, 28), CE(p, q), H(p), CE(p, q) - H(p), KL(p, q)))
print(" 더 쓴 양이 정확히 KL 발산입니다. 그것이 이 양의 뜻입니다")
print(" 교차엔트로피 = 엔트로피 + KL 입니다")
print(" 참 분포를 쓸 때만 0 이고 나머지는 모두 양수입니다")
print(" 비음성을 무작위로 확인합니다")
neg = 0
mn = None
for _ in range(300000):
a = rng.random(5)
b = rng.random(5)
a, b = a / a.sum(), b / b.sum()
v = KL(a, b)
if v < 0:
neg += 1
if mn is None or v < mn:
mn = v
print(" 30 만 쌍을 무작위로 만들어 KL 을 계산했습니다")
print(" %s %s %s"
% (pw("무엇", 26), rw("값", 18), rw("판정", 14)))
print(" %s %18d %s" % (pw("음수가 나온 횟수", 26), neg, rw("없음", 14)))
print(" %s %18.10f %s" % (pw("가장 작은 값", 26), mn, rw("0 이상", 14)))
print(" 132강의 젠센 부등식으로 증명됩니다. 로그가 오목하기 때문입니다")
print(" 거리가 아닌 이유를 봅니다")
print(" %s %s %s %s"
% (pw("어떤 성질", 24), rw("거리라면", 20), rw("KL 은", 20),
rw("성립", 10)))
a1 = np.array([0.7, 0.2, 0.1])
b1 = np.array([0.2, 0.5, 0.3])
c1 = np.array([0.4, 0.4, 0.2])
print(" %s %s %20.6f %s"
% (pw("자기 자신과는 0", 24), rw("0", 20), KL(a1, a1), rw("예", 10)))
print(" %s %s %20.6f %s"
% (pw("대칭", 24), rw("%.6f" % KL(a1, b1), 20), KL(b1, a1),
rw("아니오", 10)))
tri = KL(a1, b1) - KL(a1, c1) - KL(c1, b1)
print(" %s %s %20.6f %s"
% (pw("삼각부등식", 24), rw("0 이하여야", 20), tri,
rw("예" if tri <= 0 else "아니오", 10)))
print(" 대칭이 아니므로 거리가 아닙니다. 그래서 발산이라 부릅니다")
print(" 삼각부등식도 위 예에서 이미 깨졌습니다. 0.422882 만큼 넘어섭니다")
bad = 0
for _ in range(200000):
x, y, z = rng.random(3), rng.random(3), rng.random(3)
x, y, z = x / x.sum(), y / y.sum(), z / z.sum()
if KL(x, y) > KL(x, z) + KL(z, y) + 1e-12:
bad += 1
print(" 20 만 번 중 %d 번 삼각부등식이 깨졌습니다" % bad)
# --- 문제 2: 방향이 결과를 바꿉니다 ------------------------------------
print(" 두 방향이 서로 다른 답을 냅니다")
print(" 봉우리가 둘인 참 분포를 봉우리 하나로 근사해 봅니다")
grid = np.linspace(-8, 8, 4001)
d = grid[1] - grid[0]
def norm(mu, sd, x):
return np.exp(-(x - mu) ** 2 / (2 * sd * sd)) / (sd * np.sqrt(2 * np.pi))
ptrue = 0.5 * norm(-2.5, 0.7, grid) + 0.5 * norm(2.5, 0.7, grid)
ptrue = ptrue / ptrue.sum()
def fit(direction):
best = None
for mu in np.linspace(-4, 4, 161):
for sd in np.linspace(0.2, 5.0, 241):
q = norm(mu, sd, grid)
q = q / q.sum()
v = KL(ptrue, q, np.e) if direction == "forward" else \
KL(q, ptrue, np.e)
if best is None or v < best[0]:
best = (v, mu, sd)
return best
fw = fit("forward")
rv = fit("reverse")
print(" %s %s %s %s %s"
% (pw("어느 방향으로 재나", 24), rw("최적 평균", 14), rw("최적 표준편차", 16),
rw("그때의 값", 14), rw("어떤 모양", 16)))
print(" %s %14.4f %16.4f %14.6f %s"
% (pw("KL(참, 근사)", 24), fw[1], fw[2], fw[0], rw("넓게 덮음", 16)))
print(" %s %14.4f %16.4f %14.6f %s"
% (pw("KL(근사, 참)", 24), rv[1], rv[2], rv[0], rw("한쪽에 붙음", 16)))
print(" 앞쪽은 참이 있는 곳에 근사가 없으면 큰 벌을 받습니다")
print(" 그래서 두 봉우리를 다 덮으려고 넓게 퍼집니다")
print(" 뒤쪽은 근사가 있는 곳에 참이 없으면 벌을 받습니다")
print(" 그래서 한 봉우리에 좁게 붙습니다")
print(" 두 방향의 벌이 어디서 나오는지 봅니다")
print(" %s %s %s"
% (pw("어떤 자리", 30), rw("KL(참, 근사)", 18), rw("KL(근사, 참)", 18)))
for a, b, c in [("참은 큰데 근사가 0 에 가까움", "무한대로 커짐", "거의 벌 없음"),
("근사는 큰데 참이 0 에 가까움", "거의 벌 없음", "무한대로 커짐"),
("둘 다 0 에 가까움", "벌 없음", "벌 없음")]:
print(" %s %s %s" % (pw(a, 30), rw(b, 18), rw(c, 18)))
print(" 한쪽이 0 인데 다른 쪽이 양수면 값이 무한이 됩니다")
pz = np.array([0.5, 0.5, 0.0])
qz = np.array([0.4, 0.3, 0.3])
print(" %s %s" % (pw("KL(0 이 있는 쪽, 없는 쪽)", 30), rw("%.6f" % KL(pz, qz), 18)))
print(" %s %s" % (pw("KL(없는 쪽, 0 이 있는 쪽)", 30), rw("무한대", 18)))
print(" 실무에서 이것 때문에 확률에 아주 작은 값을 더해 둡니다")
print(" 어느 방향을 쓰는지 정리합니다")
print(" %s %s %s"
% (pw("어디서", 24), rw("어느 방향", 22), rw("왜", 24)))
for a, b, c in [("최대우도 학습", "KL(자료, 모형)", "자료를 다 덮어야"),
("변분추론", "KL(근사, 참)", "계산이 되는 쪽"),
("지식 증류", "KL(교사, 학생)", "교사를 다 배워야"),
("정책 최적화", "KL(새 정책, 옛 정책)", "너무 멀리 안 가게")]:
print(" %s %s %s" % (pw(a, 24), rw(b, 22), rw(c, 24)))
print(" 둘째 줄이 봉우리 하나에 붙는 성질 때문에 문제가 되기도 합니다")
# --- 문제 3: 최대우도와의 관계 -----------------------------------------
print(" 자료로 모형을 맞추는 것이 곧 KL 을 줄이는 것입니다")
print(" 정규분포의 평균을 여러 값으로 두고 두 양을 함께 봅니다")
n3 = 4000
xs = rng.normal(1.5, 1.0, n3)
print(" 참 평균은 1.5 이고 표본은 4000 개입니다")
print(" %s %s %s %s"
% (pw("가정한 평균", 14), rw("평균 로그우도", 18), rw("교차엔트로피", 18),
rw("합", 14)))
for mu in [0.0, 1.0, 1.5, 2.0, 3.0]:
ll = float(np.mean(-0.5 * (xs - mu) ** 2 - 0.5 * np.log(2 * np.pi)))
print(" %s %18.6f %18.6f %14.6f"
% (pw("%.1f" % mu, 14), ll, -ll, ll + (-ll)))
print(" 교차엔트로피가 평균 로그우도의 부호를 바꾼 것과 같습니다")
print(" 우도를 최대로 하는 것이 교차엔트로피를 최소로 하는 것입니다")
print(" 참 엔트로피는 모형과 무관한 상수이므로 KL 을 최소로 하는 것과 같습니다")
print(" 표본이 늘면 어디로 가는지 봅니다")
print(" %s %s %s %s"
% (pw("표본 크기", 12), rw("최대우도 평균", 18), rw("참값", 10),
rw("교차엔트로피", 16)))
for n in [20, 100, 1000, 100000]:
z = rng.normal(1.5, 1.0, n)
mh = float(z.mean())
ce = float(np.mean(0.5 * (z - mh) ** 2 + 0.5 * np.log(2 * np.pi)))
print(" %s %18.6f %10.1f %16.6f"
% (pw("%d" % n, 12), mh, 1.5, ce))
print(" 표본이 늘면 참값으로 갑니다. 149강 문제 3 의 일치성입니다")
print(" 교차엔트로피는 참 엔트로피 1.418939 로 수렴합니다")
print(" 다만 표본 100 에서 1.406596 으로 참값보다 작습니다")
print(" 자기 자료에 맞춘 평균으로 잰 값이라 낙관됩니다. 189강 문제 1 과 같습니다")
print(" 모형이 틀리면 어디로 가는지 봅니다")
print(" 참은 두 봉우리인데 정규 하나로 맞춥니다")
n4 = 200000
mix = np.where(rng.random(n4) < 0.5, -2.5, 2.5) + rng.normal(0, 0.7, n4)
mh = float(mix.mean())
sh = float(mix.std())
print(" %s %s %s"
% (pw("무엇", 26), rw("값", 16), rw("무엇을 뜻하나", 22)))
for nm, v, w in [("최대우도 평균", mh, "두 봉우리의 가운데"),
("최대우도 표준편차", sh, "봉우리 사이 거리까지 담음"),
("참 봉우리의 표준편차", 0.7, "각 봉우리 안의 퍼짐")]:
print(" %s %16.6f %s" % (pw(nm, 26), v, rw(w, 22)))
print(" 모형이 틀려도 최대우도는 KL 을 가장 작게 하는 자리로 갑니다")
print(" 그 자리가 참과 같지는 않습니다. 가장 가까운 근사일 뿐입니다")
print(" 문제 2 의 앞쪽 방향과 같은 답입니다. 자료를 다 덮으려 합니다")
# --- 문제 4: 얼마나 다른지 재는 다른 자들 ------------------------------
print(" 두 분포의 차이를 재는 자가 여럿입니다")
print(" %s %s %s"
% (pw("이름", 20), rw("대칭인가", 12), rw("무엇이 좋은가", 30)))
for a, b, c in [("KL 발산", "아니오", "우도와 바로 이어짐"),
("젠센-섀넌", "예", "언제나 유한하고 제곱근이 거리"),
("전변동거리", "예", "확률 차이의 최대"),
("헬링거 거리", "예", "제곱근을 쓰면 안정적"),
("바서슈타인", "예", "값의 위치를 반영")]:
print(" %s %s %s" % (pw(a, 20), rw(b, 12), rw(c, 30)))
def JS(p, q):
m = (np.asarray(p, float) + np.asarray(q, float)) / 2.0
return 0.5 * KL(p, m) + 0.5 * KL(q, m)
def TV(p, q):
return float(0.5 * np.abs(np.asarray(p, float) - np.asarray(q, float)).sum())
def HE(p, q):
return float(np.sqrt(0.5 * ((np.sqrt(np.asarray(p, float))
- np.sqrt(np.asarray(q, float))) ** 2).sum()))
print(" 네 자로 같은 쌍들을 재 봅니다")
print(" %s %s %s %s %s"
% (pw("두 분포", 26), rw("KL", 12), rw("젠센-섀넌", 14),
rw("전변동", 12), rw("헬링거", 12)))
pairs = [("거의 같음", np.array([0.5, 0.3, 0.2]), np.array([0.48, 0.31, 0.21])),
("꽤 다름", np.array([0.5, 0.3, 0.2]), np.array([0.2, 0.3, 0.5])),
("한쪽이 0", np.array([0.5, 0.5, 0.0]), np.array([0.4, 0.3, 0.3])),
("반대로 0", np.array([0.4, 0.3, 0.3]), np.array([0.5, 0.5, 0.0]))]
for nm, a, b in pairs:
v = KL(a, b)
print(" %s %12s %14.6f %12.6f %12.6f"
% (pw(nm, 26), rw("무한대" if np.isinf(v) else "%.6f" % v, 12),
JS(a, b), TV(a, b), HE(a, b)))
print(" 마지막 줄에서 KL 만 무한대가 됩니다. 나머지 셋은 유한합니다")
print(" 젠센-섀넌은 두 분포의 평균을 가운데 두므로 언제나 유한합니다")
print(" 그것이 생성모형에서 이 자를 쓰는 이유입니다")
print(" 겹치지 않는 두 분포에서 무엇이 달라지는지 봅니다")
print(" 두 점 분포를 떨어뜨려 가며 네 자를 봅니다")
print(" %s %s %s %s %s"
% (pw("떨어진 거리", 14), rw("KL", 12), rw("젠센-섀넌", 14),
rw("전변동", 12), rw("바서슈타인", 14)))
for gap in [0.0, 0.5, 1.0, 4.0]:
xs2 = np.array([0.0, gap])
if gap == 0.0:
a = np.array([1.0, 0.0])
b = np.array([1.0, 0.0])
else:
a = np.array([1.0, 0.0])
b = np.array([0.0, 1.0])
v = KL(a, b)
print(" %s %12s %14.6f %12.6f %14.6f"
% (pw("%.1f" % gap, 14),
rw("무한대" if np.isinf(v) else "%.6f" % v, 12),
JS(a, b), TV(a, b), gap))
print(" 겹치지 않으면 앞의 셋이 거리와 무관하게 같은 값을 냅니다")
print(" 바서슈타인만 거리를 반영합니다. 그래서 기울기가 살아 있습니다")
print(" 생성모형 학습에서 이 성질이 중요합니다")
# --- 문제 5: 실무의 KL ---------------------------------------------------
print(" 실무에서 KL 이 나오는 자리를 봅니다")
print(" %s %s"
% (pw("어디", 26), rw("무엇을 재나", 30)))
for a, b in [("분류 손실", "라벨과 예측 확률의 어긋남"),
("변분 오토인코더", "잠재 분포와 사전분포의 어긋남"),
("지식 증류", "교사와 학생 출력의 어긋남"),
("정책 경사", "새 정책과 옛 정책의 어긋남"),
("자료 이동 감시", "학습 때와 지금 분포의 어긋남")]:
print(" %s %s" % (pw(a, 26), rw(b, 30)))
print(" 마지막 줄이 운영에서 가장 자주 쓰입니다")
print(" 자료 이동을 KL 로 감시해 봅니다")
n5 = 5000
base = rng.normal(0, 1, 200000)
edges = np.quantile(base, np.linspace(0, 1, 11))
edges[0], edges[-1] = -np.inf, np.inf
def binned(x):
b = np.clip(np.searchsorted(edges, x, side="right") - 1, 0, 9)
c = np.bincount(b, minlength=10).astype(float)
return (c + 0.5) / (c + 0.5).sum()
ref = binned(base)
print(" 학습 때 분포를 열 칸으로 나누고 지금 자료와 견줍니다")
print(" %s %s %s %s"
% (pw("지금 자료", 26), rw("KL", 14), rw("젠센-섀넌", 14), rw("판정", 14)))
for nm, cur in [("그대로", rng.normal(0, 1, n5)),
("평균이 0.2 옮겨감", rng.normal(0.2, 1, n5)),
("평균이 0.5 옮겨감", rng.normal(0.5, 1, n5)),
("퍼짐이 1.5 배", rng.normal(0, 1.5, n5))]:
q = binned(cur)
k = KL(ref, q)
print(" %s %14.6f %14.6f %s"
% (pw(nm, 26), k, JS(ref, q),
rw("정상" if k < 0.01 else "이동 의심", 14)))
print(" 평균이 조금만 옮겨가도 값이 크게 커집니다")
print(" 문턱을 정하려면 정상일 때의 흔들림을 먼저 재야 합니다")
print(" 정상일 때의 흔들림을 재 봅니다")
print(" %s %s %s %s"
% (pw("표본 크기", 12), rw("KL 평균", 14), rw("KL 의 95 분위", 16),
rw("참값", 10)))
for n in [200, 1000, 5000, 20000]:
ks = []
for _ in range(500):
q = binned(rng.normal(0, 1, n))
ks.append(KL(ref, q))
print(" %s %14.6f %16.6f %10.1f"
% (pw("%d" % n, 12), float(np.mean(ks)),
float(np.quantile(ks, 0.95)), 0.0))
print(" 표본이 작으면 아무 일이 없어도 KL 이 큽니다")
print(" 201강 문제 5 의 치우침이 여기서도 그대로입니다")
print(" 앞 표에서 쓴 문턱 0.01 은 표본 5000 의 95 분위 0.002522 보다 넉넉합니다")
print(" 그래서 문턱은 같은 표본 크기의 95 분위를 기준으로 잡습니다")
print(" 칸을 나누는 방식이 값을 바꿉니다")
print(" %s %s %s %s"
% (pw("칸 개수", 14), rw("평균 0.2 이동", 18), rw("정상일 때 95 분위", 22),
rw("신호 대 잡음", 16)))
for K in [5, 10, 30, 100]:
e2 = np.quantile(base, np.linspace(0, 1, K + 1))
e2[0], e2[-1] = -np.inf, np.inf
def b2(x):
b = np.clip(np.searchsorted(e2, x, side="right") - 1, 0, K - 1)
c = np.bincount(b, minlength=K).astype(float)
return (c + 0.5) / (c + 0.5).sum()
r2 = b2(base)
shifted = KL(r2, b2(rng.normal(0.2, 1, n5)))
ks = [KL(r2, b2(rng.normal(0, 1, n5))) for _ in range(300)]
q95 = float(np.quantile(ks, 0.95))
print(" %s %18.6f %22.6f %16.4f"
% (pw("%d" % K, 14), shifted, q95, shifted / q95))
print(" 칸을 늘리면 신호가 0.0263 에서 0.0389 로 조금 커집니다")
print(" 그런데 잡음은 0.0014 에서 0.0188 로 훨씬 크게 커집니다")
print(" 마지막 열이 계속 줄어듭니다. 여기서는 칸을 적게 쓰는 쪽이 낫습니다")
print(" 칸 개수는 그 비가 가장 큰 자리로 고릅니다")
print(" 203강은 두 분포의 어긋남을 쟀습니다. 204강은 그것을 손실함수로 씁니다")
# 201강에서 엔트로피가 압축의 하한이라고 했습니다
# 그 하한은 참 분포를 알 때의 이야기입니다
# 틀린 분포로 부호를 만들면 몇 비트를 더 쓰는지 재 봅니다
# 어떤 분포로 부호를 만드나 평균 길이 참 엔트로피 더 쓴 양 KL
# 참 분포와 같음 1.750000 1.750000 0.000000 0.000000
# 조금 다름 1.800687 1.750000 0.050687 0.050687
# 많이 다름 2.623808 1.750000 0.873808 0.873808
# 균등이라고 봄 2.000000 1.750000 0.250000 0.250000
# 더 쓴 양이 정확히 KL 발산입니다. 그것이 이 양의 뜻입니다
# 교차엔트로피 = 엔트로피 + KL 입니다
# 참 분포를 쓸 때만 0 이고 나머지는 모두 양수입니다
# 비음성을 무작위로 확인합니다
# 30 만 쌍을 무작위로 만들어 KL 을 계산했습니다
# 무엇 값 판정
# 음수가 나온 횟수 0 없음
# 가장 작은 값 0.0003976835 0 이상
# 132강의 젠센 부등식으로 증명됩니다. 로그가 오목하기 때문입니다
# 거리가 아닌 이유를 봅니다
# 어떤 성질 거리라면 KL 은 성립
# 자기 자신과는 0 0 0.000000 예
# 대칭 0.842267 0.774982 아니오
# 삼각부등식 0 이하여야 0.422882 아니오
# 대칭이 아니므로 거리가 아닙니다. 그래서 발산이라 부릅니다
# 삼각부등식도 위 예에서 이미 깨졌습니다. 0.422882 만큼 넘어섭니다
# 20 만 번 중 51258 번 삼각부등식이 깨졌습니다
# 두 방향이 서로 다른 답을 냅니다
# 봉우리가 둘인 참 분포를 봉우리 하나로 근사해 봅니다
# 어느 방향으로 재나 최적 평균 최적 표준편차 그때의 값 어떤 모양
# KL(참, 근사) 0.0000 2.6200 0.615899 넓게 덮음
# KL(근사, 참) -2.5000 0.7000 0.692629 한쪽에 붙음
# 앞쪽은 참이 있는 곳에 근사가 없으면 큰 벌을 받습니다
# 그래서 두 봉우리를 다 덮으려고 넓게 퍼집니다
# 뒤쪽은 근사가 있는 곳에 참이 없으면 벌을 받습니다
# 그래서 한 봉우리에 좁게 붙습니다
# 두 방향의 벌이 어디서 나오는지 봅니다
# 어떤 자리 KL(참, 근사) KL(근사, 참)
# 참은 큰데 근사가 0 에 가까움 무한대로 커짐 거의 벌 없음
# 근사는 큰데 참이 0 에 가까움 거의 벌 없음 무한대로 커짐
# 둘 다 0 에 가까움 벌 없음 벌 없음
# 한쪽이 0 인데 다른 쪽이 양수면 값이 무한이 됩니다
# KL(0 이 있는 쪽, 없는 쪽) 0.529447
# KL(없는 쪽, 0 이 있는 쪽) 무한대
# 실무에서 이것 때문에 확률에 아주 작은 값을 더해 둡니다
# 어느 방향을 쓰는지 정리합니다
# 어디서 어느 방향 왜
# 최대우도 학습 KL(자료, 모형) 자료를 다 덮어야
# 변분추론 KL(근사, 참) 계산이 되는 쪽
# 지식 증류 KL(교사, 학생) 교사를 다 배워야
# 정책 최적화 KL(새 정책, 옛 정책) 너무 멀리 안 가게
# 둘째 줄이 봉우리 하나에 붙는 성질 때문에 문제가 되기도 합니다
# 자료로 모형을 맞추는 것이 곧 KL 을 줄이는 것입니다
# 정규분포의 평균을 여러 값으로 두고 두 양을 함께 봅니다
# 참 평균은 1.5 이고 표본은 4000 개입니다
# 가정한 평균 평균 로그우도 교차엔트로피 합
# 0.0 -2.554544 2.554544 0.000000
# 1.0 -1.545465 1.545465 0.000000
# 1.5 -1.415925 1.415925 0.000000
# 2.0 -1.536386 1.536386 0.000000
# 3.0 -2.527307 2.527307 0.000000
# 교차엔트로피가 평균 로그우도의 부호를 바꾼 것과 같습니다
# 우도를 최대로 하는 것이 교차엔트로피를 최소로 하는 것입니다
# 참 엔트로피는 모형과 무관한 상수이므로 KL 을 최소로 하는 것과 같습니다
# 표본이 늘면 어디로 가는지 봅니다
# 표본 크기 최대우도 평균 참값 교차엔트로피
# 20 1.358668 1.5 1.523372
# 100 1.520953 1.5 1.406596
# 1000 1.515618 1.5 1.430397
# 100000 1.502759 1.5 1.423888
# 표본이 늘면 참값으로 갑니다. 149강 문제 3 의 일치성입니다
# 교차엔트로피는 참 엔트로피 1.418939 로 수렴합니다
# 다만 표본 100 에서 1.406596 으로 참값보다 작습니다
# 자기 자료에 맞춘 평균으로 잰 값이라 낙관됩니다. 189강 문제 1 과 같습니다
# 모형이 틀리면 어디로 가는지 봅니다
# 참은 두 봉우리인데 정규 하나로 맞춥니다
# 무엇 값 무엇을 뜻하나
# 최대우도 평균 -0.008273 두 봉우리의 가운데
# 최대우도 표준편차 2.596507 봉우리 사이 거리까지 담음
# 참 봉우리의 표준편차 0.700000 각 봉우리 안의 퍼짐
# 모형이 틀려도 최대우도는 KL 을 가장 작게 하는 자리로 갑니다
# 그 자리가 참과 같지는 않습니다. 가장 가까운 근사일 뿐입니다
# 문제 2 의 앞쪽 방향과 같은 답입니다. 자료를 다 덮으려 합니다
# 두 분포의 차이를 재는 자가 여럿입니다
# 이름 대칭인가 무엇이 좋은가
# KL 발산 아니오 우도와 바로 이어짐
# 젠센-섀넌 예 언제나 유한하고 제곱근이 거리
# 전변동거리 예 확률 차이의 최대
# 헬링거 거리 예 제곱근을 쓰면 안정적
# 바서슈타인 예 값의 위치를 반영
# 네 자로 같은 쌍들을 재 봅니다
# 두 분포 KL 젠센-섀넌 전변동 헬링거
# 거의 같음 0.001177 0.000294 0.020000 0.014284
# 꽤 다름 0.396578 0.095816 0.300000 0.259893
# 한쪽이 0 0.529447 0.172242 0.300000 0.406802
# 반대로 0 무한대 0.172242 0.300000 0.406802
# 마지막 줄에서 KL 만 무한대가 됩니다. 나머지 셋은 유한합니다
# 젠센-섀넌은 두 분포의 평균을 가운데 두므로 언제나 유한합니다
# 그것이 생성모형에서 이 자를 쓰는 이유입니다
# 겹치지 않는 두 분포에서 무엇이 달라지는지 봅니다
# 두 점 분포를 떨어뜨려 가며 네 자를 봅니다
# 떨어진 거리 KL 젠센-섀넌 전변동 바서슈타인
# 0.0 0.000000 0.000000 0.000000 0.000000
# 0.5 무한대 1.000000 1.000000 0.500000
# 1.0 무한대 1.000000 1.000000 1.000000
# 4.0 무한대 1.000000 1.000000 4.000000
# 겹치지 않으면 앞의 셋이 거리와 무관하게 같은 값을 냅니다
# 바서슈타인만 거리를 반영합니다. 그래서 기울기가 살아 있습니다
# 생성모형 학습에서 이 성질이 중요합니다
# 실무에서 KL 이 나오는 자리를 봅니다
# 어디 무엇을 재나
# 분류 손실 라벨과 예측 확률의 어긋남
# 변분 오토인코더 잠재 분포와 사전분포의 어긋남
# 지식 증류 교사와 학생 출력의 어긋남
# 정책 경사 새 정책과 옛 정책의 어긋남
# 자료 이동 감시 학습 때와 지금 분포의 어긋남
# 마지막 줄이 운영에서 가장 자주 쓰입니다
# 자료 이동을 KL 로 감시해 봅니다
# 학습 때 분포를 열 칸으로 나누고 지금 자료와 견줍니다
# 지금 자료 KL 젠센-섀넌 판정
# 그대로 0.001408 0.000353 정상
# 평균이 0.2 옮겨감 0.024486 0.006045 이동 의심
# 평균이 0.5 옮겨감 0.189188 0.045247 이동 의심
# 퍼짐이 1.5 배 0.134849 0.034964 이동 의심
# 평균이 조금만 옮겨가도 값이 크게 커집니다
# 문턱을 정하려면 정상일 때의 흔들림을 먼저 재야 합니다
# 정상일 때의 흔들림을 재 봅니다
# 표본 크기 KL 평균 KL 의 95 분위 참값
# 200 0.031562 0.059035 0.0
# 1000 0.006304 0.011262 0.0
# 5000 0.001362 0.002522 0.0
# 20000 0.000362 0.000677 0.0
# 표본이 작으면 아무 일이 없어도 KL 이 큽니다
# 201강 문제 5 의 치우침이 여기서도 그대로입니다
# 앞 표에서 쓴 문턱 0.01 은 표본 5000 의 95 분위 0.002522 보다 넉넉합니다
# 그래서 문턱은 같은 표본 크기의 95 분위를 기준으로 잡습니다
# 칸을 나누는 방식이 값을 바꿉니다
# 칸 개수 평균 0.2 이동 정상일 때 95 분위 신호 대 잡음
# 5 0.026345 0.001405 18.7468
# 10 0.028234 0.002444 11.5510
# 30 0.032767 0.006833 4.7953
# 100 0.038870 0.018791 2.0685
# 칸을 늘리면 신호가 0.0263 에서 0.0389 로 조금 커집니다
# 그런데 잡음은 0.0014 에서 0.0188 로 훨씬 크게 커집니다
# 마지막 열이 계속 줄어듭니다. 여기서는 칸을 적게 쓰는 쪽이 낫습니다
# 칸 개수는 그 비가 가장 큰 자리로 고릅니다
# 203강은 두 분포의 어긋남을 쟀습니다. 204강은 그것을 손실함수로 씁니다