단원에서 그래디언트를 정확하게 얻는 법을 세웠습니다. 그런데 실제 학습은 그 정확한 그래디언트를 안 씁니다.
강의 경사하강은 자료 전체의 그래디언트를 요구했습니다. 표본이 백만 개면 한 걸음에 백만 번 계산해야 합니다.
답은 편향이 없다는 것입니다. 미니배치 그래디언트는 전체 그래디언트를 평균적으로 맞히고, 틀리는 것은 분산뿐입니다. 이 강의는 그 분산이 무엇을 하는지 봅니다.
문제. 미니배치의 성질을 봅니다.
() 세 방식을 정리하세요.
() 편향이 없음을 확인하세요.
() 분산이 배치 크기에 반비례하는지 보세요.
생각의 실마리. 손실이 표본별 손실의 평균입니다. 그러면 그래디언트도 평균이고, 평균의 추정은 표본평균입니다. 강에서 이미 다룬 구조입니다.
풀이. () 정리합니다.
| 방식 | 몇 개를 보나 | 무엇이 문제인가 |
|---|---|---|
| 전체 배치 | 개 전부 | 정확하지만 한 걸음이 비쌈 |
| 미니배치 | 개 | 가운데 |
| 한 개씩 | 개 | 잡음이 크지만 빠름 |
한 걸음의 비용이 에 비례하고 한 걸음의 질도 가 정합니다. 그래서 어느 가 좋은지는 저절로 안 정해집니다.
() 편향이 없음을 확인합니다. 표본 방문 수를 으로 맞춰 공정하게 견줍니다.
| 배치 크기 | 반복 수 | 평균과 참값의 최대 차 | 한 번 뽑았을 때 최대 차 |
|---|---|---|---|
표본 방문 수를 맞추면 평균이 배치 크기와 무관하게 참값에 붙습니다. 셋째 열이 모두 근처입니다.
한 번 뽑은 값은 크게 벗어납니다. 배치 에서 이나 틀립니다.
편향은 없고 분산만 다릅니다. 그것이 확률적 최적화의 출발점입니다.
() 분산을 잽니다.
| 배치 크기 | 그래디언트 분산의 합 | 개일 때 대비 | 배치 크기의 역수 |
|---|---|---|---|
셋째 열과 넷째 열이 거의 같습니다.
분산이 배치 크기에 반비례하고 표준편차는 제곱근에 반비례합니다. 강의 표본평균 분산 공식이 그대로 쓰입니다.
이 문제에서 배우는 것. 미니배치는 근사가 아니라 추정입니다. 틀린 방향으로 가는 것이 아니라 평균적으로 맞는 방향에 잡음이 얹힌 것이고, 잡음의 크기가 로 정해집니다.
확인 1-1. 미니배치 그래디언트의 기댓값이 무엇인지 쓰세요.
답. 전체 그래디언트입니다.
확인 1-2. 검산에서 배치 일 때 한 번 뽑은 값의 최대 차를 쓰세요.
답. 입니다.
확인 1-3. 검산에서 배치 의 개 대비 분산 비를 쓰세요.
답. 입니다.
문제. 학습에 무엇이 일어나는지 봅니다.
() 무엇이 달라지는지 정리하세요.
() 최적점에서 그래디언트를 재세요.
() 정말 맴도는지 학습시키세요.
() 학습률을 줄여 보세요.
생각의 실마리. 전체 배치에서는 최적점에서 그래디언트가 정확히 입니다. 그러면 걸음이 멈춥니다. 미니배치는 어떨까요.
풀이. () 정리합니다.
| 무엇 | 어떻게 | 결과 |
|---|---|---|
| 방향 | 평균은 맞음 | 한 번은 틀릴 수 있음 |
| 최적점 근처 | 그래디언트가 이 아님 | 떨림이 남음 |
| 학습률 | 떨림 크기를 정함 | 줄여야 수렴함 |
| 탈출 | 안장점과 얕은 골 | 잡음이 도움 |
() 정규방정식으로 최적점을 구하고 거기서 그래디언트를 잽니다.
| 무엇 | 그래디언트 노름 |
|---|---|
| 전체 배치 | |
| 배치 | |
| 배치 | |
| 배치 |
전체 배치에서는 정확히 인데 미니배치에서는 이 아닙니다.
배치 에서 로 여덟 배 키우면 노름이 에서 로 줄어듭니다. 약 배이고, 문제 의 법칙과 맞습니다.
그래서 학습률을 그대로 두면 최적점 둘레를 계속 맴돕니다.
() 정말 맴도는지 학습시킵니다. 학습률 로 걸음 갑니다.
| 배치 크기 | 최적점과의 거리 | 전체 손실 | 최적 손실 대비 |
|---|---|---|---|
최적 손실은 입니다.
배치가 작을수록 최적점에서 멀리 떨어진 자리를 맴돕니다. 배치 는 거리 인데 전체 배치는 입니다.
() 학습률을 줄여 봅니다. 배치를 로 고정합니다.
| 학습률 | 최적점과의 거리 | 최적 손실 대비 |
|---|---|---|
학습률을 줄이면 떨림이 줄어듭니다. 거리가 에서 로 열 배 줄었습니다.
다만 너무 줄이면 걸음 안에 도착을 못 합니다. 강에서 이 맞바꿈을 수렴 조건으로 적습니다.
이 문제에서 배우는 것. 확률적 경사하강은 고정 학습률로는 수렴하지 않습니다. 최적점 둘레의 한 영역까지만 가고 거기서 맴돌며, 그 영역의 크기가 학습률과 배치 크기로 정해집니다.
확인 2-1. 최적점에서 미니배치 그래디언트가 이 아닌 이유를 쓰세요.
답. 표본마다의 그래디언트가 서로 다르고 그 합만 이기 때문입니다.
확인 2-2. 검산에서 배치 과 배치 의 최적점 그래디언트 노름을 쓰세요.
답. 와 입니다.
확인 2-3. 검산에서 학습률 와 의 최적점과의 거리를 쓰세요.
답. 과 입니다.
문제. 어느 배치가 좋은지 봅니다.
() 무엇을 견줄지 정리하세요.
() 같은 걸음 수로 견주세요.
() 같은 표본 방문 수로 견주세요.
() 학습률도 함께 키워 보세요.
생각의 실마리. "배치가 클수록 좋다"와 "작을수록 좋다"가 둘 다 맞는 말일 수 있습니다. 무엇을 고정하고 재느냐가 다르기 때문입니다.
풀이. () 정리합니다.
| 무엇으로 재나 | 어느 쪽이 유리 | 왜 |
|---|---|---|
| 걸음 수 기준 | 배치가 클수록 좋음 | 한 걸음이 정확해짐 |
| 표본 방문 수 기준 | 배치가 작을수록 좋음 | 같은 계산으로 더 많은 걸음 |
| 실제 시간 기준 | 가운데가 좋음 | 병렬 처리가 있기 때문 |
같은 것을 세 가지로 재면 답이 다릅니다. 무엇을 아끼려는지 먼저 정해야 합니다.
() 같은 걸음 수로 견줍니다. 걸음, 학습률 입니다.
| 배치 크기 | 본 표본 수 | 최적 손실 대비 |
|---|---|---|
배치가 클수록 좋습니다. 다만 본 표본 수도 함께 커집니다. 공정한 비교가 아닙니다.
() 같은 표본 방문 수로 견줍니다. 번으로 맞춥니다.
| 배치 크기 | 걸음 수 | 최적 손실 대비 |
|---|---|---|
학습률을 고정하면 같은 예산에서도 큰 배치가 낫습니다.
배치 는 걸음을 배 더 갔는데도 로 가장 나쁩니다. 걸음이 많아도 떨림이 그 이득을 지웁니다.
그러면 작은 배치를 쓸 이유가 없어 보입니다. 학습률을 함께 바꾸면 이야기가 달라집니다.
() 배치를 배 하면 학습률도 배 합니다.
| 배치 크기 | 학습률 | 걸음 수 | 최적 손실 대비 |
|---|---|---|---|
앞의 세 줄이 에서 로 사실상 같습니다. 배치가 배 차이나는데 결과가 같습니다.
넷째 줄만 나빠집니다. 학습률 이 너무 커서 규칙이 깨졌습니다.
학습률에는 상한이 있어 끝없이 못 키웁니다. 강에서 그 상한이 어디서 오는지 봅니다.
이 문제에서 배우는 것. 배치 크기와 학습률은 따로 정하는 손잡이가 아닙니다. 하나를 바꾸면 다른 하나도 바꿔야 하고, 그 규칙이 선형 스케일링입니다.
확인 3-1. 배치 크기 비교에서 무엇을 고정해야 공정한지 쓰세요.
답. 무엇을 아끼려는지 정하고 그것을 고정해야 합니다.
확인 3-2. 검산에서 표본 방문 수를 맞췄을 때 배치 와 의 최적 손실 대비를 쓰세요.
답. 와 입니다.
확인 3-3. 검산에서 선형 스케일링을 적용한 배치 와 의 최적 손실 대비를 쓰세요.
답. 과 입니다.
문제. 어떻게 뽑을지 정합니다.
() 방법들을 정리하세요.
() 복원 추출과 비복원 섞기를 견주세요.
() 안 섞으면 어떻게 되는지 보세요.
() 배치 안의 상관을 보세요.
생각의 실마리. 문제 의 분산 공식은 표본이 독립이라는 가정 위에 있습니다. 그 가정이 깨지면 어떻게 될까요.
풀이. () 정리합니다.
| 방법 | 무엇을 하나 | 무엇이 특징인가 |
|---|---|---|
| 복원 추출 | 매번 무작위로 뽑음 | 이론이 깔끔함 |
| 비복원 섞기 | 한 판을 섞어 순서대로 | 실무의 기본 |
| 고정 순서 | 안 섞음 | 쓰면 안 됨 |
| 중요도 표집 | 어려운 것을 자주 | 가중을 되돌려야 함 |
() 복원 추출과 비복원 섞기를 견줍니다. 판을 돕니다.
| 배치 크기 | 복원 추출 | 비복원 섞기 | 어느 쪽이 나은가 |
|---|---|---|---|
| 비복원 | |||
| 비복원 | |||
| 비복원 |
세 경우 모두 비복원 섞기가 낫습니다. 배치 에서는 아홉 배 가까이 차이 납니다.
한 판 안에서 모든 표본을 정확히 한 번씩 보기 때문입니다. 복원 추출은 어떤 표본을 두 번 보고 어떤 것은 못 봅니다.
() 안 섞으면 어떻게 되는지 봅니다. 목표값 순으로 정렬된 자료를 씁니다.
| 어떻게 돌았나 | 최적 손실 대비 | 최적점과의 거리 |
|---|---|---|
| 안 섞음 | ||
| 섞음 |
안 섞으면 손실이 다섯 배 넘게 나쁩니다.
배치마다 목표값이 한쪽으로 몰립니다. 그래디언트가 판 안에서 한 방향으로 치우쳤다가 반대로 치우칩니다.
섞기는 선택이 아니라 필수입니다. 그리고 자료가 정렬돼 있는지는 대개 모르고 시작합니다.
() 배치 안의 상관을 봅니다.
| 어떻게 뽑았나 | 배치 그래디언트 분산 | 독립일 때의 예측 |
|---|---|---|
| 무작위로 개 | ||
| 정렬된 자료에서 연속 |
무작위로 뽑으면 독립 가정의 예측과 거의 같습니다. 대 입니다.
정렬된 자료에서 연속으로 뽑으면 분산이 배 큽니다.
배치 안 표본이 서로 닮아 유효 표본 수가 줄었기 때문입니다. 강의 유효 표본 크기가 여기서 다시 나옵니다. 개를 뽑았는데 실제로는 열 개쯤 뽑은 셈입니다.
이 문제에서 배우는 것. 분산 공식의 는 표본이 독립일 때만 성립합니다. 배치 안에 상관이 있으면 같은 로도 잡음이 훨씬 큽니다. 섞기는 그 상관을 없애는 가장 싼 방법입니다.
확인 4-1. 비복원 섞기가 복원 추출보다 나은 이유를 쓰세요.
답. 한 판 안에서 모든 표본을 정확히 한 번씩 보기 때문입니다.
확인 4-2. 검산에서 안 섞었을 때와 섞었을 때의 최적 손실 대비를 쓰세요.
답. 와 입니다.
확인 4-3. 검산에서 정렬된 자료에서 연속으로 뽑은 배치 그래디언트 분산을 쓰세요.
답. 입니다.
문제. 실제로 정합니다.
() 배치 크기를 어떻게 정하는지 정리하세요.
() 작은 배치가 언제 발산하는지 보세요.
() 잡음 크기를 재는 법을 보세요.
() 이 강의를 한 장으로 모으세요.
생각의 실마리. 문제 에서 배치와 학습률을 함께 키웠습니다. 그러면 반대 방향은 어떨까요. 배치를 줄이면 무엇이 먼저 무너질까요.
풀이. () 정리합니다.
| 무엇 | 왜 | 덧붙임 |
|---|---|---|
| 메모리에 맞게 | 가장 큰 제약 | 먼저 정해집니다 |
| 의 거듭제곱 | 하드웨어 정렬 | 관례입니다 |
| 작으면 정규화 효과 | 잡음이 일반화를 도움 | 강 참고 |
| 크면 병렬이 유리 | 같은 시간에 더 많이 | 강 참고 |
| 학습률과 함께 | 따로 정하면 안 됨 | 문제 참고 |
() 작은 배치가 언제 발산하는지 봅니다. 학습률을 올려 갑니다.
| 학습률 | 배치 | 배치 | 배치 | 배치 |
|---|---|---|---|---|
| 발산 | ||||
| 발산 |
학습률 에서 배치 만 발산합니다. 나머지 셋은 멀쩡합니다.
같은 학습률인데 배치가 작을수록 먼저 터집니다. 한 걸음의 잡음이 크면 가끔 아주 큰 걸음이 나오기 때문입니다.
그래서 배치를 줄이면 학습률도 함께 줄여야 합니다. 문제 의 선형 스케일링과 같은 이야기를 반대 방향에서 본 것입니다.
() 잡음 크기를 재는 법을 봅니다.
| 배치 크기 | 신호 노름 제곱 | 잡음 흔적 | 잡음 나누기 신호 |
|---|---|---|---|
잡음 나누기 신호가 을 넘으면 배치를 키울 값이 있습니다. 배치 에서 입니다.
보다 훨씬 작으면 배치를 더 키워도 걸음의 질이 거의 안 좋아집니다. 배치 에서 이므로, 로 키워도 얻는 것이 거의 없습니다.
이 비가 임계 배치 크기를 정합니다. 강에서 다시 봅니다.
() 이 강의를 한 장으로 모읍니다.
| 무엇 | 한 줄로 |
|---|---|
| 미니배치 그래디언트는 | 편향이 없고 분산만 있습니다 |
| 분산은 | 배치 크기에 반비례합니다 |
| 최적점에서 | 미니배치 그래디언트는 이 아닙니다 |
| 그래서 | 학습률을 안 줄이면 맴돕니다 |
| 학습률을 고정하면 | 같은 계산 예산에서 큰 배치가 낫습니다 |
| 배치를 키우면 | 학습률도 함께 키워야 결과가 비슷합니다 |
| 섞기는 | 선택이 아니라 필수입니다 |
| 작은 배치는 | 같은 학습률에서 먼저 발산합니다 |
| 잡음 나누기 신호가 | 배치를 더 키울 값이 있는지 말해 줍니다 |
이 문제에서 배우는 것. 배치 크기는 혼자 정할 수 없는 손잡이입니다. 학습률과 묶여 있고, 잡음 대 신호 비가 어디까지 키울 값이 있는지를 말해 줍니다.
확인 5-1. 배치를 줄이면 학습률을 어떻게 해야 하는지 쓰세요.
답. 함께 줄여야 합니다.
확인 5-2. 검산에서 학습률 일 때 어느 배치가 발산하는지 쓰세요.
답. 배치 입니다.
확인 5-3. 검산에서 배치 과 의 잡음 나누기 신호를 쓰세요.
답. 과 입니다.
| 유형 | 무엇을 묻나 | 어디를 보나 |
|---|---|---|
| 편향 없음 | 기댓값이 전체 그래디언트 | 문제 |
| 분산 | 배치 크기에 반비례 | 문제 |
| 최적점의 잡음 | 이 아님 | 문제 |
| 맴돎 | 학습률이 영역 크기를 정함 | 문제 |
| 무엇을 고정하나 | 답이 달라짐 | 문제 |
| 선형 스케일링 | 배치와 학습률을 함께 | 문제 |
| 섞기 | 안 섞으면 다섯 배 나쁨 | 문제 |
| 배치 안 상관 | 유효 표본이 줄음 | 문제 |
| 발산 | 작은 배치가 먼저 | 문제 |
| 잡음 대 신호 | 임계 배치 크기 | 문제 |
핵심 식을 한자리에 모읍니다.
| 무엇을 바꾸면 | 무엇이 달라지나 |
|---|---|
| 를 배 | 분산이 배 |
| 를 배 | 한 걸음 비용이 배 |
| 와 학습률을 함께 배 | 결과가 비슷함 |
| 학습률을 배 | 떨림이 줄고 도착이 늦음 |
문제 6. 미니배치 그래디언트의 기댓값이 무엇인지 쓰세요.
답. 전체 그래디언트입니다.
문제 7. 검산에서 배치 일 때 한 번 뽑은 값의 최대 차를 쓰세요.
답. 입니다.
문제 8. 검산에서 배치 의 개 대비 분산 비를 쓰세요.
답. 입니다.
문제 9. 최적점에서 미니배치 그래디언트가 이 아닌 이유를 쓰세요.
답. 표본마다의 그래디언트가 서로 다르고 그 합만 이기 때문입니다.
문제 10. 검산에서 배치 과 배치 의 최적점 그래디언트 노름을 쓰세요.
답. 와 입니다.
문제 11. 검산에서 학습률 와 의 최적점과의 거리를 쓰세요.
답. 과 입니다.
문제 12. 배치 크기 비교에서 무엇을 고정해야 공정한지 쓰세요.
답. 무엇을 아끼려는지 정하고 그것을 고정해야 합니다.
문제 13. 검산에서 표본 방문 수를 맞췄을 때 배치 와 의 최적 손실 대비를 쓰세요.
답. 와 입니다.
문제 14. 검산에서 선형 스케일링을 적용한 배치 와 의 최적 손실 대비를 쓰세요.
답. 과 입니다.
문제 15. 비복원 섞기가 복원 추출보다 나은 이유를 쓰세요.
답. 한 판 안에서 모든 표본을 정확히 한 번씩 보기 때문입니다.
문제 16. 검산에서 안 섞었을 때와 섞었을 때의 최적 손실 대비를 쓰세요.
답. 와 입니다.
문제 17. 검산에서 정렬된 자료에서 연속으로 뽑은 배치 그래디언트 분산을 쓰세요.
답. 입니다.
문제 18. 검산에서 배치 과 의 잡음 나누기 신호를 쓰세요.
답. 과 입니다.
심화 1. 분산 공식을 유도하세요.
표본 의 그래디언트를 라 하면 미니배치 그래디언트는 평균입니다.
| 단계 | 무엇 |
|---|---|
| 기댓값 | 각 의 기댓값이 이므로 |
| 분산 | 독립이면 분산이 더해지고 이 곱해짐 |
| 결과 |
강의 표본평균과 완전히 같은 계산입니다. 다른 것은 가 스칼라가 아니라 벡터라는 것뿐이고, 그러면 분산이 공분산 행렬이 됩니다.
문제 에서 잰 것은 그 행렬의 대각합입니다.
심화 2. 유한 모집단 보정을 정리하세요.
비복원으로 개 중 개를 뽑으면 분산에 인자가 붙습니다.
| 보정 인자 | 뜻 | |
|---|---|---|
| 거의 | 복원과 같음 | |
| 전체 배치라 잡음이 없음 |
둘째 줄이 문제 의 전체 배치입니다. 전부 뽑으면 무작위성이 사라집니다.
문제 에서 비복원이 나았던 이유가 이 인자입니다.
심화 3. 확률적 근사 조건을 미리 봅니다.
| 조건 | 무엇을 막나 |
|---|---|
| 첫째 | 너무 빨리 줄어 도착 못 하는 것 |
| 둘째 | 잡음이 안 사라지는 것 |
가 둘 다 만족합니다. 는 첫째만 만족하고 둘째는 안 됩니다.
문제 의 ()에서 고정 학습률로는 떨림이 안 사라졌습니다. 강이 이 조건을 정면으로 다룹니다.
심화 4. 중요도 표집을 정리하세요.
어려운 표본을 자주 뽑되 가중으로 되돌립니다.
| 무엇 | 어떻게 |
|---|---|
| 뽑을 확률 | 그래디언트 노름에 비례 |
| 가중 | 확률의 역수 |
| 얻는 것 | 분산 감소 |
| 치르는 것 | 노름을 매번 계산 |
넷째 줄이 실무의 걸림돌입니다. 노름을 알려면 그래디언트를 계산해야 하는데, 그러면 아낀 것이 없습니다.
강에서 이 문제를 어떻게 우회하는지 봅니다.
심화 5. 그래디언트 잡음이 어떤 분포인지 정리하세요.
| 상황 | 어떤 분포 |
|---|---|
| 가 크면 | 중심극한정리로 정규분포에 가까움 |
| 가 작으면 | 꼬리가 두꺼울 수 있음 |
| 이상점이 있으면 | 아주 두꺼움 |
둘째와 셋째 줄이 문제 의 발산을 설명합니다. 정규분포라면 학습률 에서 배치 가 터질 일이 드문데, 꼬리가 두꺼우면 가끔 아주 큰 걸음이 나옵니다.
강 심화 의 그래디언트 자르기가 이 꼬리를 잘라 냅니다.
심화 6. 이 강의가 다음 강의로 어떻게 이어지는지 정리하세요.
| 이 강의에서 | 다음에서 |
|---|---|
| 고정 학습률로는 맴돎 | 강 수렴 조건 |
| 선형 스케일링과 상한 | 강 배치와 학습률 |
| 잡음 대 신호 비 | 강 임계 배치 크기 |
| 분산을 줄이고 싶음 | 강 분산 감소 |
| 배치 안 상관 | 강 배치 정규화 |
강은 이 강의의 문제 를 정리로 만듭니다. 학습률을 어떻게 줄여야 정말 최적점에 닿는지가 그 물음입니다.
정답.
| 기호 | 읽는 법 | 뜻 |
|---|---|---|
| 미니배치 | mini-batch | 한 걸음에 쓰는 표본 묶음입니다 |
| 확률적 경사하강 | stochastic gradient descent | 미니배치 그래디언트로 걸음을 딛습니다 |
| 편향 없는 추정 | unbiased estimator | 기댓값이 참값과 같습니다 |
| 판 | epoch | 자료 전체를 한 번 도는 것입니다 |
| 비복원 섞기 | shuffling without replacement | 판마다 섞어 한 번씩 봅니다 |
| 선형 스케일링 | linear scaling rule | 배치를 배 하면 학습률도 배 합니다 |
| 잡음 대 신호 비 | noise-to-signal ratio | 그래디언트 분산을 노름 제곱으로 나눈 값입니다 |
| 임계 배치 크기 | critical batch size | 더 키워도 이득이 없어지는 크기입니다 |
| 유효 표본 크기 | effective sample size | 상관을 고려한 실질 표본 수입니다 |
| 중요도 표집 | importance sampling | 다른 분포로 뽑고 가중으로 되돌립니다 |
다음은 236강 SGD의 수렴 조건입니다. 이 강의의 문제 에서 고정 학습률로는 최적점에 안 닿는다는 것을 봤습니다. 다음 강의는 어떻게 줄여야 닿는지를 조건으로 적습니다.
import numpy as np
def pw(s):
return sum(2 if ord(c) > 0x1100 else 1 for c in str(s))
def rw(s, w):
return str(s) + ' ' * max(0, w - pw(s))
def rl(s, w):
return ' ' * max(0, w - pw(s)) + str(s)
def ridge_grad(X, y, b, lam=0.0):
r = X @ b - y
return X.T @ r / len(y) + lam * b
def full_loss(X, y, b):
r = X @ b - y
return float((r ** 2).mean() / 2)
print("=" * 78)
print("235강 미니배치 그래디언트의 분산 코드 검산")
print("=" * 78)
print()
print("문제 1. 왜 일부만 보는가")
print()
print(" (1) 세 방식을 정리합니다")
rows = [
("전체 배치", "n 개 전부", "정확하지만 한 걸음이 비쌈"),
("미니배치", "B 개", "가운데"),
("한 개씩", "1 개", "잡음이 크지만 빠름"),
]
w = [max(pw(r[i]) for r in rows + [("방식", "몇 개를 보나", "무엇이 문제인가")]) for i in range(3)]
print(" " + rw("방식", w[0]) + " " + rw("몇 개를 보나", w[1]) + " " + "무엇이 문제인가")
for r in rows:
print(" " + rw(r[0], w[0]) + " " + rw(r[1], w[1]) + " " + r[2])
print(" 한 걸음의 비용이 B 에 비례하고 한 걸음의 질도 B 가 정합니다")
print(" 그래서 어느 B 가 좋은지는 저절로 안 정해집니다")
print()
print(" (2) 미니배치 그래디언트가 편향 없는 추정임을 확인합니다")
rng = np.random.default_rng(20235)
n, p = 2000, 12
X = rng.normal(0, 1, (n, p))
beta = rng.normal(0, 1, p)
y = X @ beta + rng.normal(0, 1.0, n)
b0 = rng.normal(0, 0.5, p)
g_full = ridge_grad(X, y, b0)
print(" 전체 그래디언트를 참값으로 놓고 미니배치를 여러 번 뽑습니다")
print(" 표본 방문 수를 %d 로 맞춰 공정하게 견줍니다" % 512000)
print(" " + rl("배치 크기", 12) + " " + rl("반복 수", 10) + " " + rl("평균과 참값의 최대 차", 24) + " " + rl("한 번 뽑았을 때 최대 차", 26))
for B in [1, 8, 64, 512]:
reps = 512000 // B
est = []
for _ in range(reps):
idx = rng.integers(0, n, B)
est.append(ridge_grad(X[idx], y[idx], b0))
est = np.array(est)
m = est.mean(axis=0)
print(" " + rl("%d" % B, 12) + " " + rl("%d" % reps, 10) + " " + rl("%.6f" % float(np.abs(m - g_full).max()), 24) + " " + rl("%.6f" % float(np.abs(est[0] - g_full).max()), 26))
print(" 표본 방문 수를 맞추면 평균이 배치 크기와 무관하게 참값에 붙습니다")
print(" 한 번 뽑은 값은 배치가 작을수록 크게 벗어납니다")
print(" 편향은 없고 분산만 다릅니다. 그것이 확률적 최적화의 출발점입니다")
print()
print(" (3) 분산이 배치 크기에 반비례하는지 봅니다")
print(" " + rl("배치 크기", 12) + " " + rl("그래디언트 분산의 합", 22) + " " + rl("1 개일 때 대비", 18) + " " + rl("배치 크기의 역수", 18))
base_var = None
for B in [1, 2, 4, 8, 16, 32, 64]:
est = []
for _ in range(4000):
idx = rng.integers(0, n, B)
est.append(ridge_grad(X[idx], y[idx], b0))
est = np.array(est)
v = float(est.var(axis=0).sum())
if base_var is None:
base_var = v
print(" " + rl("%d" % B, 12) + " " + rl("%.6f" % v, 22) + " " + rl("%.6f" % (v / base_var), 18) + " " + rl("%.6f" % (1.0 / B), 18))
print(" 셋째 열과 넷째 열이 거의 같습니다")
print(" 분산이 배치 크기에 반비례합니다. 표준편차는 제곱근에 반비례합니다")
print(" 163강의 표본평균 분산 공식이 그대로 쓰입니다")
print()
print("문제 2. 잡음이 걸음에 무엇을 하는가")
print()
print(" (1) 무엇이 달라지는지 정리합니다")
rows = [
("방향", "평균은 맞음", "한 번은 틀릴 수 있음"),
("최적점 근처", "그래디언트가 0 이 아님", "떨림이 남음"),
("학습률", "떨림 크기를 정함", "줄여야 수렴함"),
("탈출", "안장점과 얕은 골", "잡음이 도움"),
]
w = [max(pw(r[i]) for r in rows + [("무엇", "어떻게", "결과")]) for i in range(3)]
print(" " + rw("무엇", w[0]) + " " + rw("어떻게", w[1]) + " " + "결과")
for r in rows:
print(" " + rw(r[0], w[0]) + " " + rw(r[1], w[1]) + " " + r[2])
print()
print(" (2) 최적점에서 그래디언트가 0 이 아닌 것을 봅니다")
bstar = np.linalg.solve(X.T @ X, X.T @ y)
print(" 정규방정식으로 최적점을 구합니다")
print(" " + rw("무엇", 22) + " " + rl("그래디언트 노름", 18))
print(" " + rw("전체 배치", 22) + " " + rl("%.10f" % float(np.linalg.norm(ridge_grad(X, y, bstar))), 18))
for B in [8, 64, 512]:
nr = []
for _ in range(2000):
idx = rng.integers(0, n, B)
nr.append(float(np.linalg.norm(ridge_grad(X[idx], y[idx], bstar))))
print(" " + rw("배치 %d" % B, 22) + " " + rl("%.10f" % float(np.mean(nr)), 18))
print(" 전체 배치에서는 정확히 0 입니다")
print(" 미니배치에서는 0 이 아니고 배치가 작을수록 큽니다")
print(" 그래서 학습률을 그대로 두면 최적점 둘레를 계속 맴돕니다")
print()
print(" (3) 정말 맴도는지 학습시켜 봅니다")
def run_sgd(B, lr, steps, rr, decay=False, b_init=None):
b = (b_init if b_init is not None else np.zeros(p)).copy()
hist = []
for t in range(1, steps + 1):
idx = rr.integers(0, n, B)
step = lr / (1.0 + 0.01 * t) if decay else lr
b -= step * ridge_grad(X[idx], y[idx], b)
if t % (steps // 5) == 0:
hist.append((t, float(np.linalg.norm(b - bstar)), full_loss(X, y, b)))
return b, hist
print(" 학습률을 0.05 로 고정하고 배치를 바꿔 2000 걸음 갑니다")
print(" " + rl("배치 크기", 12) + " " + rl("최적점과의 거리", 18) + " " + rl("전체 손실", 16) + " " + rl("최적 손실 대비", 18))
opt_loss = full_loss(X, y, bstar)
for B in [4, 32, 256, 2000]:
bb, _ = run_sgd(B, 0.05, 2000, np.random.default_rng(101))
print(" " + rl("%d" % B, 12) + " " + rl("%.6f" % float(np.linalg.norm(bb - bstar)), 18) + " " + rl("%.6f" % full_loss(X, y, bb), 16) + " " + rl("%.6f" % (full_loss(X, y, bb) - opt_loss), 18))
print(" 최적 손실은 %.6f 입니다" % opt_loss)
print(" 배치가 작을수록 최적점에서 멀리 떨어진 자리를 맴돕니다")
print(" 전체 배치는 정확히 최적점에 붙습니다")
print()
print(" (4) 학습률을 줄이면 어떻게 되는지 봅니다")
print(" 배치를 8 로 두고 학습률만 바꿉니다")
print(" " + rl("학습률", 12) + " " + rl("최적점과의 거리", 18) + " " + rl("최적 손실 대비", 18))
for lr in [0.2, 0.05, 0.01, 0.002]:
bb, _ = run_sgd(8, lr, 3000, np.random.default_rng(202))
print(" " + rl("%.4f" % lr, 12) + " " + rl("%.6f" % float(np.linalg.norm(bb - bstar)), 18) + " " + rl("%.6f" % (full_loss(X, y, bb) - opt_loss), 18))
print(" 학습률을 줄이면 떨림이 줄어듭니다")
print(" 다만 너무 줄이면 3000 걸음 안에 도착을 못 합니다")
print(" 236강에서 이 맞바꿈을 수렴 조건으로 적습니다")
print()
print("문제 3. 배치 크기와 걸음 수")
print()
print(" (1) 무엇을 견줄지 정리합니다")
rows = [
("걸음 수 기준", "배치가 클수록 좋음", "한 걸음이 정확해짐"),
("표본 방문 수 기준", "배치가 작을수록 좋음", "같은 계산으로 더 많은 걸음"),
("실제 시간 기준", "가운데가 좋음", "병렬 처리가 있기 때문"),
]
w = [max(pw(r[i]) for r in rows + [("무엇으로 재나", "어느 쪽이 유리", "왜")]) for i in range(3)]
print(" " + rw("무엇으로 재나", w[0]) + " " + rw("어느 쪽이 유리", w[1]) + " " + "왜")
for r in rows:
print(" " + rw(r[0], w[0]) + " " + rw(r[1], w[1]) + " " + r[2])
print(" 같은 것을 세 가지로 재면 답이 다릅니다. 무엇을 아끼려는지 먼저 정해야 합니다")
print()
print(" (2) 같은 걸음 수로 견줍니다")
print(" 2000 걸음을 똑같이 갑니다. 학습률은 0.05 입니다")
print(" " + rl("배치 크기", 12) + " " + rl("본 표본 수", 14) + " " + rl("최적 손실 대비", 18))
for B in [4, 16, 64, 256]:
bb, _ = run_sgd(B, 0.05, 2000, np.random.default_rng(303))
print(" " + rl("%d" % B, 12) + " " + rl("%d" % (B * 2000), 14) + " " + rl("%.6f" % (full_loss(X, y, bb) - opt_loss), 18))
print(" 배치가 클수록 좋습니다. 다만 본 표본 수도 함께 커집니다")
print()
print(" (3) 같은 표본 방문 수로 견줍니다")
budget = 128000
print(" 표본 방문을 %d 번으로 맞추고 배치를 바꿉니다" % budget)
print(" " + rl("배치 크기", 12) + " " + rl("걸음 수", 12) + " " + rl("최적 손실 대비", 18))
for B in [4, 16, 64, 256]:
steps = budget // B
bb, _ = run_sgd(B, 0.05, steps, np.random.default_rng(404))
print(" " + rl("%d" % B, 12) + " " + rl("%d" % steps, 12) + " " + rl("%.6f" % (full_loss(X, y, bb) - opt_loss), 18))
print(" 학습률을 고정하면 같은 예산에서도 큰 배치가 낫습니다")
print(" 걸음이 8 배 많아도 떨림이 그 이득을 지웁니다")
print(" 그러면 작은 배치를 쓸 이유가 없어 보입니다. 다음에서 그것을 봅니다")
print()
print(" (4) 배치를 키우면서 학습률도 함께 키워 봅니다")
print(" 배치를 k 배 하면 학습률도 k 배 하는 규칙을 씁니다")
print(" " + rl("배치 크기", 12) + " " + rl("학습률", 12) + " " + rl("걸음 수", 10) + " " + rl("최적 손실 대비", 18))
for B, lr in [(4, 0.02), (16, 0.08), (64, 0.32), (256, 1.28)]:
steps = budget // B
bb, _ = run_sgd(B, lr, steps, np.random.default_rng(505))
val = full_loss(X, y, bb) - opt_loss
txt = "%.6f" % val if np.isfinite(val) else "발산"
print(" " + rl("%d" % B, 12) + " " + rl("%.4f" % lr, 12) + " " + rl("%d" % steps, 10) + " " + rl(txt, 18))
print(" 배치를 키운 만큼 학습률을 키우면 결과가 비슷해집니다")
print(" 다만 학습률에는 상한이 있어 끝없이 못 키웁니다")
print(" 237강에서 그 상한이 어디서 오는지 봅니다")
print()
print("문제 4. 표집 방법")
print()
print(" (1) 방법들을 정리합니다")
rows = [
("복원 추출", "매번 무작위로 뽑음", "이론이 깔끔함"),
("비복원 섞기", "한 판을 섞어 순서대로", "실무의 기본"),
("고정 순서", "안 섞음", "쓰면 안 됨"),
("중요도 표집", "어려운 것을 자주", "가중을 되돌려야 함"),
]
w = [max(pw(r[i]) for r in rows + [("방법", "무엇을 하나", "무엇이 특징인가")]) for i in range(3)]
print(" " + rw("방법", w[0]) + " " + rw("무엇을 하나", w[1]) + " " + "무엇이 특징인가")
for r in rows:
print(" " + rw(r[0], w[0]) + " " + rw(r[1], w[1]) + " " + r[2])
print()
print(" (2) 복원 추출과 비복원 섞기를 견줍니다")
def run_shuffle(B, lr, epochs, rr):
b = np.zeros(p)
for _ in range(epochs):
perm = rr.permutation(n)
for s in range(0, n, B):
idx = perm[s:s + B]
b -= lr * ridge_grad(X[idx], y[idx], b)
return b
def run_replace(B, lr, epochs, rr):
b = np.zeros(p)
for _ in range(epochs * (n // B)):
idx = rr.integers(0, n, B)
b -= lr * ridge_grad(X[idx], y[idx], b)
return b
print(" 같은 걸음 수가 되게 맞추고 20 판을 돕니다")
print(" " + rl("배치 크기", 12) + " " + rl("복원 추출", 16) + " " + rl("비복원 섞기", 16) + " " + rl("어느 쪽이 나은가", 20))
for B in [8, 32, 128]:
b1 = run_replace(B, 0.05, 20, np.random.default_rng(606))
b2 = run_shuffle(B, 0.05, 20, np.random.default_rng(606))
l1 = full_loss(X, y, b1) - opt_loss
l2 = full_loss(X, y, b2) - opt_loss
print(" " + rl("%d" % B, 12) + " " + rl("%.8f" % l1, 16) + " " + rl("%.8f" % l2, 16) + " " + rl("비복원" if l2 < l1 else "복원", 20))
print(" 비복원 섞기가 대체로 낫습니다")
print(" 한 판 안에서 모든 표본을 정확히 한 번씩 보기 때문입니다")
print(" 복원 추출은 어떤 표본을 두 번 보고 어떤 것은 못 봅니다")
print()
print(" (3) 안 섞으면 어떻게 되는지 봅니다")
order_y = np.argsort(y)
Xs = X[order_y]
ys = y[order_y]
def run_fixed(B, lr, epochs, shuffle, rr):
b = np.zeros(p)
for _ in range(epochs):
perm = rr.permutation(n) if shuffle else np.arange(n)
for s in range(0, n, B):
idx = perm[s:s + B]
b -= lr * ridge_grad(Xs[idx], ys[idx], b)
return b
bstar_s = np.linalg.solve(Xs.T @ Xs, Xs.T @ ys)
opt_s = full_loss(Xs, ys, bstar_s)
print(" 목표값 순으로 정렬된 자료를 씁니다. 실무에서 흔한 상황입니다")
print(" " + rw("어떻게 돌았나", 18) + " " + rl("최적 손실 대비", 18) + " " + rl("최적점과의 거리", 18))
for nm, sh in [("안 섞음", False), ("섞음", True)]:
bb = run_fixed(32, 0.05, 20, sh, np.random.default_rng(707))
print(" " + rw(nm, 18) + " " + rl("%.8f" % (full_loss(Xs, ys, bb) - opt_s), 18) + " " + rl("%.6f" % float(np.linalg.norm(bb - bstar_s)), 18))
print(" 안 섞으면 배치마다 목표값이 한쪽으로 몰립니다")
print(" 그래디언트가 판 안에서 한 방향으로 치우쳤다가 반대로 치우칩니다")
print(" 섞기는 선택이 아니라 필수입니다")
print()
print(" (4) 배치 안의 상관을 봅니다")
print(" 한 배치 안 표본들의 그래디언트가 서로 얼마나 닮았는지 봅니다")
print(" " + rw("어떻게 뽑았나", 20) + " " + rl("배치 그래디언트 분산", 22) + " " + rl("독립일 때의 예측", 20))
gi = np.array([ridge_grad(X[i:i + 1], y[i:i + 1], b0) for i in range(n)])
v1 = float(gi.var(axis=0).sum())
B = 32
rand_var = []
sort_var = []
for _ in range(2000):
idx = rng.integers(0, n, B)
rand_var.append(ridge_grad(X[idx], y[idx], b0))
s0 = int(rng.integers(0, n - B))
sort_var.append(ridge_grad(Xs[s0:s0 + B], ys[s0:s0 + B], b0))
rv = float(np.array(rand_var).var(axis=0).sum())
sv = float(np.array(sort_var).var(axis=0).sum())
print(" " + rw("무작위로 %d 개" % B, 20) + " " + rl("%.6f" % rv, 22) + " " + rl("%.6f" % (v1 / B), 20))
print(" " + rw("정렬된 자료에서 연속", 20) + " " + rl("%.6f" % sv, 22) + " " + rl("%.6f" % (v1 / B), 20))
print(" 무작위로 뽑으면 독립 가정의 예측과 거의 같습니다")
print(" 정렬된 자료에서 연속으로 뽑으면 분산이 %.2f 배 큽니다" % (sv / rv))
print(" 배치 안 표본이 서로 닮아 유효 표본 수가 줄었기 때문입니다")
print()
print("문제 5. 실무에서 쓰기")
print()
print(" (1) 배치 크기를 어떻게 정하는지 정리합니다")
rows = [
("메모리에 맞게", "가장 큰 제약", "먼저 정해집니다"),
("2 의 거듭제곱", "하드웨어 정렬", "관례입니다"),
("작으면 정규화 효과", "잡음이 일반화를 도움", "230강 참고"),
("크면 병렬이 유리", "같은 시간에 더 많이", "317강 참고"),
("학습률과 함께", "따로 정하면 안 됨", "문제 3 참고"),
]
w = [max(pw(r[i]) for r in rows + [("무엇", "왜", "덧붙임")]) for i in range(3)]
print(" " + rw("무엇", w[0]) + " " + rw("왜", w[1]) + " " + "덧붙임")
for r in rows:
print(" " + rw(r[0], w[0]) + " " + rw(r[1], w[1]) + " " + r[2])
print()
print(" (2) 작은 배치가 언제 발산하는지 봅니다")
r2g = np.random.default_rng(30235)
ntr, pp = 60, 40
Xtr = r2g.normal(0, 1, (ntr, pp))
bt = np.zeros(pp)
bt[:5] = np.array([1.5, -1.2, 0.9, -0.7, 0.5])
ytr = Xtr @ bt + r2g.normal(0, 0.5, ntr)
def run_small(B, lr, steps, rr):
b = np.zeros(pp)
for _ in range(steps):
idx = rr.integers(0, ntr, B)
b -= lr * (Xtr[idx].T @ (Xtr[idx] @ b - ytr[idx]) / B)
return b
print(" 표본 %d 개에 변수 %d 개인 자료로 학습률을 올려 갑니다" % (ntr, pp))
print(" " + rl("학습률", 10) + " " + rl("배치 2", 16) + " " + rl("배치 8", 16) + " " + rl("배치 30", 16) + " " + rl("배치 60", 16))
old = np.seterr(over='ignore', invalid='ignore')
for lr in [0.02, 0.06, 0.12, 0.20]:
cells = []
for B in [2, 8, 30, 60]:
bb = run_small(B, lr, 2000, np.random.default_rng(808))
v = float(((Xtr @ bb - ytr) ** 2).mean() / 2)
cells.append("%.6f" % v if np.isfinite(v) and v < 1e6 else "발산")
print(" " + rl("%.4f" % lr, 10) + " " + rl(cells[0], 16) + " " + rl(cells[1], 16) + " " + rl(cells[2], 16) + " " + rl(cells[3], 16))
np.seterr(**old)
print(" 학습률 0.12 에서 배치 2 만 발산합니다")
print(" 같은 학습률인데 배치가 작을수록 먼저 터집니다")
print(" 한 걸음의 잡음이 크면 가끔 아주 큰 걸음이 나오기 때문입니다")
print(" 그래서 배치를 줄이면 학습률도 함께 줄여야 합니다. 문제 3 의 규칙과 같은 이야기입니다")
print()
print(" (3) 그래디언트 잡음 크기를 재는 법을 봅니다")
print(" 두 배치의 그래디언트를 견주면 잡음을 잴 수 있습니다")
print(" " + rl("배치 크기", 12) + " " + rl("신호 노름 제곱", 18) + " " + rl("잡음 흔적", 16) + " " + rl("잡음 나누기 신호", 20))
sig2 = float((g_full ** 2).sum())
for B in [8, 32, 128, 512]:
tr = []
for _ in range(2000):
idx = rng.integers(0, n, B)
tr.append(ridge_grad(X[idx], y[idx], b0))
tr = np.array(tr)
noise = float(tr.var(axis=0).sum())
print(" " + rl("%d" % B, 12) + " " + rl("%.6f" % sig2, 18) + " " + rl("%.6f" % noise, 16) + " " + rl("%.6f" % (noise / sig2), 20))
print(" 잡음 나누기 신호가 1 을 넘으면 배치를 키울 값이 있습니다")
print(" 1 보다 훨씬 작으면 배치를 더 키워도 걸음의 질이 거의 안 좋아집니다")
print(" 이 비가 임계 배치 크기를 정합니다. 237강에서 다시 봅니다")
print()
print(" (4) 이 강의를 한 장으로 모읍니다")
rows = [
("미니배치 그래디언트는", "편향이 없고 분산만 있습니다"),
("분산은", "배치 크기에 반비례합니다"),
("최적점에서", "미니배치 그래디언트는 0 이 아닙니다"),
("그래서", "학습률을 안 줄이면 맴돕니다"),
("학습률을 고정하면", "같은 계산 예산에서 큰 배치가 낫습니다"),
("배치를 키우면", "학습률도 함께 키워야 결과가 비슷합니다"),
("섞기는", "선택이 아니라 필수입니다"),
("작은 배치는", "같은 학습률에서 먼저 발산합니다"),
("잡음 나누기 신호가", "배치를 더 키울 값이 있는지 말해 줍니다"),
]
w = [max(pw(r[i]) for r in rows + [("무엇", "한 줄로")]) for i in range(2)]
print(" " + rw("무엇", w[0]) + " " + "한 줄로")
for r in rows:
print(" " + rw(r[0], w[0]) + " " + r[1])
print(" 236강은 맴도는 것을 멈추게 하는 조건을 적습니다")
print()
print("=" * 78)
print("검산 끝")
print("=" * 78)
# ==============================================================================
# 235강 미니배치 그래디언트의 분산 코드 검산
# ==============================================================================
#
# 문제 1. 왜 일부만 보는가
#
# (1) 세 방식을 정리합니다
# 방식 몇 개를 보나 무엇이 문제인가
# 전체 배치 n 개 전부 정확하지만 한 걸음이 비쌈
# 미니배치 B 개 가운데
# 한 개씩 1 개 잡음이 크지만 빠름
# 한 걸음의 비용이 B 에 비례하고 한 걸음의 질도 B 가 정합니다
# 그래서 어느 B 가 좋은지는 저절로 안 정해집니다
#
# (2) 미니배치 그래디언트가 편향 없는 추정임을 확인합니다
# 전체 그래디언트를 참값으로 놓고 미니배치를 여러 번 뽑습니다
# 표본 방문 수를 512000 로 맞춰 공정하게 견줍니다
# 배치 크기 반복 수 평균과 참값의 최대 차 한 번 뽑았을 때 최대 차
# 1 512000 0.012807 3.909673
# 8 64000 0.013638 4.707070
# 64 8000 0.013057 0.517990
# 512 1000 0.006572 0.328767
# 표본 방문 수를 맞추면 평균이 배치 크기와 무관하게 참값에 붙습니다
# 한 번 뽑은 값은 배치가 작을수록 크게 벗어납니다
# 편향은 없고 분산만 다릅니다. 그것이 확률적 최적화의 출발점입니다
#
# (3) 분산이 배치 크기에 반비례하는지 봅니다
# 배치 크기 그래디언트 분산의 합 1 개일 때 대비 배치 크기의 역수
# 1 237.860205 1.000000 1.000000
# 2 119.081467 0.500636 0.500000
# 4 60.109848 0.252711 0.250000
# 8 30.233607 0.127107 0.125000
# 16 15.101435 0.063489 0.062500
# 32 7.569362 0.031823 0.031250
# 64 3.774150 0.015867 0.015625
# 셋째 열과 넷째 열이 거의 같습니다
# 분산이 배치 크기에 반비례합니다. 표준편차는 제곱근에 반비례합니다
# 163강의 표본평균 분산 공식이 그대로 쓰입니다
#
# 문제 2. 잡음이 걸음에 무엇을 하는가
#
# (1) 무엇이 달라지는지 정리합니다
# 무엇 어떻게 결과
# 방향 평균은 맞음 한 번은 틀릴 수 있음
# 최적점 근처 그래디언트가 0 이 아님 떨림이 남음
# 학습률 떨림 크기를 정함 줄여야 수렴함
# 탈출 안장점과 얕은 골 잡음이 도움
#
# (2) 최적점에서 그래디언트가 0 이 아닌 것을 봅니다
# 정규방정식으로 최적점을 구합니다
# 무엇 그래디언트 노름
# 전체 배치 0.0000000000
# 배치 8 1.1490909372
# 배치 64 0.4165001801
# 배치 512 0.1478179001
# 전체 배치에서는 정확히 0 입니다
# 미니배치에서는 0 이 아니고 배치가 작을수록 큽니다
# 그래서 학습률을 그대로 두면 최적점 둘레를 계속 맴돕니다
#
# (3) 정말 맴도는지 학습시켜 봅니다
# 학습률을 0.05 로 고정하고 배치를 바꿔 2000 걸음 갑니다
# 배치 크기 최적점과의 거리 전체 손실 최적 손실 대비
# 4 0.332282 0.557491 0.057783
# 32 0.074233 0.502475 0.002768
# 256 0.044541 0.500681 0.000974
# 2000 0.014044 0.499804 0.000096
# 최적 손실은 0.499708 입니다
# 배치가 작을수록 최적점에서 멀리 떨어진 자리를 맴돕니다
# 전체 배치는 정확히 최적점에 붙습니다
#
# (4) 학습률을 줄이면 어떻게 되는지 봅니다
# 배치를 8 로 두고 학습률만 바꿉니다
# 학습률 최적점과의 거리 최적 손실 대비
# 0.2000 0.403280 0.081213
# 0.0500 0.148782 0.010672
# 0.0100 0.066315 0.002108
# 0.0020 0.039111 0.000740
# 학습률을 줄이면 떨림이 줄어듭니다
# 다만 너무 줄이면 3000 걸음 안에 도착을 못 합니다
# 236강에서 이 맞바꿈을 수렴 조건으로 적습니다
#
# 문제 3. 배치 크기와 걸음 수
#
# (1) 무엇을 견줄지 정리합니다
# 무엇으로 재나 어느 쪽이 유리 왜
# 걸음 수 기준 배치가 클수록 좋음 한 걸음이 정확해짐
# 표본 방문 수 기준 배치가 작을수록 좋음 같은 계산으로 더 많은 걸음
# 실제 시간 기준 가운데가 좋음 병렬 처리가 있기 때문
# 같은 것을 세 가지로 재면 답이 다릅니다. 무엇을 아끼려는지 먼저 정해야 합니다
#
# (2) 같은 걸음 수로 견줍니다
# 2000 걸음을 똑같이 갑니다. 학습률은 0.05 입니다
# 배치 크기 본 표본 수 최적 손실 대비
# 4 8000 0.032369
# 16 32000 0.008245
# 64 128000 0.002288
# 256 512000 0.000919
# 배치가 클수록 좋습니다. 다만 본 표본 수도 함께 커집니다
#
# (3) 같은 표본 방문 수로 견줍니다
# 표본 방문을 128000 번으로 맞추고 배치를 바꿉니다
# 배치 크기 걸음 수 최적 손실 대비
# 4 32000 0.056355
# 16 8000 0.005447
# 64 2000 0.001557
# 256 500 0.000676
# 학습률을 고정하면 같은 예산에서도 큰 배치가 낫습니다
# 걸음이 8 배 많아도 떨림이 그 이득을 지웁니다
# 그러면 작은 배치를 쓸 이유가 없어 보입니다. 다음에서 그것을 봅니다
#
# (4) 배치를 키우면서 학습률도 함께 키워 봅니다
# 배치를 k 배 하면 학습률도 k 배 하는 규칙을 씁니다
# 배치 크기 학습률 걸음 수 최적 손실 대비
# 4 0.0200 32000 0.016651
# 16 0.0800 8000 0.016674
# 64 0.3200 2000 0.016282
# 256 1.2800 500 0.040946
# 배치를 키운 만큼 학습률을 키우면 결과가 비슷해집니다
# 다만 학습률에는 상한이 있어 끝없이 못 키웁니다
# 237강에서 그 상한이 어디서 오는지 봅니다
#
# 문제 4. 표집 방법
#
# (1) 방법들을 정리합니다
# 방법 무엇을 하나 무엇이 특징인가
# 복원 추출 매번 무작위로 뽑음 이론이 깔끔함
# 비복원 섞기 한 판을 섞어 순서대로 실무의 기본
# 고정 순서 안 섞음 쓰면 안 됨
# 중요도 표집 어려운 것을 자주 가중을 되돌려야 함
#
# (2) 복원 추출과 비복원 섞기를 견줍니다
# 같은 걸음 수가 되게 맞추고 20 판을 돕니다
# 배치 크기 복원 추출 비복원 섞기 어느 쪽이 나은가
# 8 0.02186830 0.01646480 비복원
# 32 0.00476873 0.00245933 비복원
# 128 0.00103011 0.00011760 비복원
# 비복원 섞기가 대체로 낫습니다
# 한 판 안에서 모든 표본을 정확히 한 번씩 보기 때문입니다
# 복원 추출은 어떤 표본을 두 번 보고 어떤 것은 못 봅니다
#
# (3) 안 섞으면 어떻게 되는지 봅니다
# 목표값 순으로 정렬된 자료를 씁니다. 실무에서 흔한 상황입니다
# 어떻게 돌았나 최적 손실 대비 최적점과의 거리
# 안 섞음 0.00966792 0.138632
# 섞음 0.00176172 0.060102
# 안 섞으면 배치마다 목표값이 한쪽으로 몰립니다
# 그래디언트가 판 안에서 한 방향으로 치우쳤다가 반대로 치우칩니다
# 섞기는 선택이 아니라 필수입니다
#
# (4) 배치 안의 상관을 봅니다
# 한 배치 안 표본들의 그래디언트가 서로 얼마나 닮았는지 봅니다
# 어떻게 뽑았나 배치 그래디언트 분산 독립일 때의 예측
# 무작위로 32 개 7.590194 7.524127
# 정렬된 자료에서 연속 24.339953 7.524127
# 무작위로 뽑으면 독립 가정의 예측과 거의 같습니다
# 정렬된 자료에서 연속으로 뽑으면 분산이 3.21 배 큽니다
# 배치 안 표본이 서로 닮아 유효 표본 수가 줄었기 때문입니다
#
# 문제 5. 실무에서 쓰기
#
# (1) 배치 크기를 어떻게 정하는지 정리합니다
# 무엇 왜 덧붙임
# 메모리에 맞게 가장 큰 제약 먼저 정해집니다
# 2 의 거듭제곱 하드웨어 정렬 관례입니다
# 작으면 정규화 효과 잡음이 일반화를 도움 230강 참고
# 크면 병렬이 유리 같은 시간에 더 많이 317강 참고
# 학습률과 함께 따로 정하면 안 됨 문제 3 참고
#
# (2) 작은 배치가 언제 발산하는지 봅니다
# 표본 60 개에 변수 40 개인 자료로 학습률을 올려 갑니다
# 학습률 배치 2 배치 8 배치 30 배치 60
# 0.0200 0.057654 0.043132 0.042066 0.041734
# 0.0600 0.113115 0.048269 0.042931 0.042391
# 0.1200 발산 0.062312 0.044537 0.043524
# 0.2000 발산 0.092982 0.047295 0.045264
# 학습률 0.12 에서 배치 2 만 발산합니다
# 같은 학습률인데 배치가 작을수록 먼저 터집니다
# 한 걸음의 잡음이 크면 가끔 아주 큰 걸음이 나오기 때문입니다
# 그래서 배치를 줄이면 학습률도 함께 줄여야 합니다. 문제 3 의 규칙과 같은 이야기입니다
#
# (3) 그래디언트 잡음 크기를 재는 법을 봅니다
# 두 배치의 그래디언트를 견주면 잡음을 잴 수 있습니다
# 배치 크기 신호 노름 제곱 잡음 흔적 잡음 나누기 신호
# 8 18.198200 30.295457 1.664750
# 32 18.198200 7.391092 0.406144
# 128 18.198200 1.880223 0.103319
# 512 18.198200 0.467306 0.025679
# 잡음 나누기 신호가 1 을 넘으면 배치를 키울 값이 있습니다
# 1 보다 훨씬 작으면 배치를 더 키워도 걸음의 질이 거의 안 좋아집니다
# 이 비가 임계 배치 크기를 정합니다. 237강에서 다시 봅니다
#
# (4) 이 강의를 한 장으로 모읍니다
# 무엇 한 줄로
# 미니배치 그래디언트는 편향이 없고 분산만 있습니다
# 분산은 배치 크기에 반비례합니다
# 최적점에서 미니배치 그래디언트는 0 이 아닙니다
# 그래서 학습률을 안 줄이면 맴돕니다
# 학습률을 고정하면 같은 계산 예산에서 큰 배치가 낫습니다
# 배치를 키우면 학습률도 함께 키워야 결과가 비슷합니다
# 섞기는 선택이 아니라 필수입니다
# 작은 배치는 같은 학습률에서 먼저 발산합니다
# 잡음 나누기 신호가 배치를 더 키울 값이 있는지 말해 줍니다
# 236강은 맴도는 것을 멈추게 하는 조건을 적습니다
#
# ==============================================================================
# 검산 끝
# ==============================================================================