강에서 모형이 복잡하면 분산이 크다고 했고, 강과 강에서 그 복잡도를 로 조절했습니다. 그런데 아직 안 정한 것이 있습니다.
가장 먼저 떠오르는 답은 계수의 개수입니다. 그런데 강에서 계수를 하나도 안 지우고 벌점만 걸어도 분산이 줄었습니다. 계수 개수는 안 변했는데 복잡도는 변했습니다.
이 강의는 제대로 된 눈금 네 가지를 보고, 그중 무엇이 실제로 쓸 만한지 수치로 가립니다.
문제. 복잡도의 눈금을 정합니다.
() 눈금 후보를 정리하세요.
() 모수가 같아도 복잡도가 다를 수 있음을 보이세요.
() 유효 자유도가 무엇을 뜻하는지 확인하세요.
생각의 실마리. 복잡도가 무엇인지 알려면 복잡도가 무엇을 일으키는지부터 정해야 합니다. 복잡한 모형은 학습 오차와 참 오차의 격차가 큽니다. 그 격차를 예측하는 양이 좋은 눈금입니다.
풀이. () 후보를 정리합니다.
| 눈금 후보 | 무엇을 세나 | 무엇이 문제인가 |
|---|---|---|
| 모수 개수 | 계수의 수 | 정규화를 못 셈 |
| 유효 자유도 | 실제로 쓴 자유도 | 선형 모형에만 쉬움 |
| VC 차원 | 쪼갤 수 있는 점 수 | 느슨하고 계산이 어려움 |
| 라데마허 복잡도 | 잡음을 얼마나 맞추나 | 자료에 딸림 |
| 실제로 재기 | 무작위 라벨 실험 | 비싸지만 정직함 |
() 계수 개짜리 같은 모형에 만 바꿉니다. 유효 자유도는 이렇게 셉니다.
| 모수 개수 | 유효 자유도 | 학습 오차 | |
|---|---|---|---|
모수는 개로 고정인데 유효 자유도는 에서 까지 움직입니다. 같은 모형인데 복잡도가 배 차이 납니다.
강 문제 에서 본 방향별 배율을 다 더한 것이 유효 자유도입니다. 특이값이 큰 방향은 거의 을 기여하고 작은 방향은 거의 을 기여합니다.
() 유효 자유도가 실제로 무엇을 뜻하는지 확인합니다. 참 오차에는 줄일 수 없는 잡음 분산 를 더해 학습 오차와 눈금을 맞춥니다.
| 유효 자유도 | 학습 오차 | 참 오차 | 차 나누기 자유도 |
|---|---|---|---|
마지막 열이 거의 일정합니다. 자유도가 에서 로 세 배 줄었는데도 근처를 지킵니다.
이고 잰 값이 그 근처입니다. 낙관의 크기가 잡음 분산 곱하기 자유도 나누기 표본의 두 배입니다.
강 문제 에서 본 자유도의 뜻이 여기서 수치로 확인됩니다. 자유도는 "자료를 맞추는 데 쓴 방향의 수"이고, 그만큼 낙관됩니다.
이 문제에서 배우는 것. 복잡도는 모형의 성질이 아니라 모형과 학습 방식이 함께 정하는 양입니다. 같은 계수 개도 벌점이 있으면 실제로는 개만 쓴 셈입니다.
확인 1-1. 유효 자유도의 공식을 쓰세요.
답. 특이값마다 를 더한 값입니다.
확인 1-2. 검산에서 가 과 일 때의 유효 자유도를 쓰세요.
답. 과 입니다.
확인 1-3. 검산에서 차 나누기 자유도가 어느 값 근처인지 쓰세요.
답. 근처입니다.
문제. 복잡도를 직접 잽니다.
() 무작위 라벨을 얼마나 맞추는지 재세요.
() 라데마허 복잡도를 계산하세요.
() 일반화 격차의 상계와 실제를 견주세요.
생각의 실마리. 라벨을 완전히 무작위로 두면 배울 것이 없습니다. 그래도 맞춘다면 그만큼 외울 힘이 있다는 뜻이고, 그 힘이 곧 복잡도입니다.
풀이. () 표본 에 무작위 라벨을 주고 잽니다.
| 차수 | 모수 개수 | 무작위 라벨 학습 오차 | 무작위 라벨을 얼마나 외웠나 |
|---|---|---|---|
외운 비율이 모수 개수 나누기 표본과 거의 같습니다. 이고 잰 값이 입니다.
차수 에서 학습 오차가 정확히 입니다. 표본 개를 계수 개로 다 지나갑니다. 강 문제 의 완전 분리와 같은 현상입니다.
() 라데마허 복잡도를 계산합니다. 라벨을 로 무작위로 두고 상관을 최대로 만든 값의 평균입니다.
| 차수 | 라데마허 복잡도 | 루트 모수 나누기 표본 |
|---|---|---|
오른쪽 열이 왼쪽의 상계입니다. 차수 에서는 정확히 같아지는데, 기저가 표본을 다 채우면 어떤 라벨과도 완전히 상관되기 때문입니다.
복잡도가 모수 개수의 제곱근에 비례합니다. 개수 자체가 아닙니다. 모수를 두 배 늘려도 복잡도는 배만 됩니다.
() 상계와 실제를 견줍니다.
| 표본 | 루트 나누기 의 두 배 | 실제 격차 | 상계가 몇 배 큰가 |
|---|---|---|---|
상계가 실제 격차보다 배에서 배 큽니다. 게다가 표본이 늘수록 더 벌어집니다.
이론 상계는 최악의 경우를 재므로 대체로 아주 느슨합니다. 그래도 표본이 늘면 격차가 준다는 방향은 둘 다 말합니다.
이 문제에서 배우는 것. 복잡도를 재는 가장 정직한 방법은 무작위 라벨을 줘 보는 것입니다. 이론 상계는 크기를 못 맞히고 방향만 맞힙니다. 그래서 실무에서는 상계 대신 강의 교차검증을 씁니다.
확인 2-1. 무작위 라벨 실험이 무엇을 재는지 쓰세요.
답. 모형이 잡음을 외우는 힘을 잽니다.
확인 2-2. 검산에서 차수 일 때 무작위 라벨을 얼마나 외웠는지 쓰세요.
답. 입니다.
확인 2-3. 검산에서 표본 일 때 상계가 실제 격차의 몇 배인지 쓰세요.
답. 배입니다.
문제. 분류에서 복잡도를 셉니다.
() VC 차원의 예를 정리하세요.
() 차원 직선의 VC 차원이 임을 확인하세요.
() VC 차원이 주는 상계가 쓸 만한지 보세요.
생각의 실마리. 회귀에서 자유도를 셌듯 분류에서도 세고 싶습니다. 분류의 출력은 갈래이므로 **"어떤 라벨이 와도 다 맞출 수 있는 점의 최대 개수"**를 셉니다.
풀이. () 예를 정리합니다.
| 모형 | VC 차원 | 왜 그런가 |
|---|---|---|
| 한 점 문턱 | 한 점만 나눔 | |
| 직선 (차원) | 세 점까지 아무 라벨 | |
| 초평면 (차원) | 절편을 포함 | |
| 축에 나란한 사각형 | 네 변이 각각 하나 | |
| 사인 함수 하나 | 무한 | 진동수로 다 맞춤 |
다섯째 줄이 중요합니다. 는 모수가 하나뿐인데 VC 차원이 무한입니다. 모수 개수와 복잡도가 다른 것임을 보여 주는 표준 예입니다.
() 차원 직선의 VC 차원이 임을 확인합니다. 점 개에 가능한 라벨 가지를 모두 시도합니다.
| 점 개수 | 라벨 가짓수 | 다 맞춘 가짓수 | 전부 되는가 |
|---|---|---|---|
| 예 | |||
| 예 | |||
| 예 | |||
| 아니오 |
네 점에서 가지 중 가지만 됩니다. 안 되는 두 가지가 배타적 논리합 배치입니다. 대각선끼리 같은 라벨인 경우인데, 직선 하나로는 못 나눕니다.
한 배치라도 다 되면 되고 모든 배치가 다 될 필요는 없습니다. VC 차원은 "존재하는가"를 묻지 "언제나 되는가"를 묻지 않습니다.
() VC 차원이 주는 상계가 쓸 만한지 봅니다.
| 표본 | VC 일 때 상계 | 표본 몇 배 필요한가 | 쓸 만한가 |
|---|---|---|---|
| 아니오 | |||
| 아니오 | |||
| 아니오 | |||
| 예 |
표본이 VC 차원의 배여도 상계가 로 에 가깝습니다. 배가 되어야 로 내려옵니다. 오류율의 상계가 보다 크면 아무 말도 안 한 것입니다.
실무에서 쓰는 신경망은 VC 차원이 모수 수만큼 크므로 이 상계가 무의미합니다. 모수가 억 개인 모형에 이 식을 넣으면 표본이 우주의 원자 수만큼 필요합니다.
그래서 요즘은 라데마허나 노름 기반 상계를 씁니다. 자료에 딸리는 양을 쓰면 훨씬 조입니다.
이 문제에서 배우는 것. VC 차원은 개념적으로는 정확한 눈금입니다. 학습 가능성의 필요충분조건이기도 합니다. 그런데 최악을 재므로 실무 지침으로는 못 씁니다.
확인 3-1. 차원 직선의 VC 차원과 안 되는 배치를 쓰세요.
답. 이고 네 점의 배타적 논리합 배치가 안 됩니다.
확인 3-2. 검산에서 네 점일 때 다 맞춘 가짓수를 쓰세요.
답. 가지 중 가지입니다.
확인 3-3. 검산에서 표본 일 때 VC 상계를 쓰세요.
답. 입니다.
문제. 모수를 안 줄이고 복잡도를 낮춥니다.
() 수단을 정리하세요.
() 조기 종료가 벌점과 같은 일을 하는지 보세요.
() 자료를 늘리면 복잡도가 어떻게 보이는지 재세요.
생각의 실마리. 문제 에서 만으로 유효 자유도를 에서 까지 낮췄습니다. 모수를 안 건드리고 복잡도를 낮추는 방법이 그것 말고도 있습니다.
풀이. () 정리합니다.
| 무엇 | 어떻게 조절하나 | 어디서 봤나 |
|---|---|---|
| 벌점 | 를 키움 | 강 |
| 조기 종료 | 덜 학습함 | 강 |
| 자료 늘리기 | 외우기 어렵게 | 강 |
| 잡음 넣기 | 정확히 못 맞춤 | 이 문제 |
| 계수 크기 제한 | 노름을 묶음 | 문제 |
다섯 가지가 모수를 하나도 안 줄이고 복잡도를 낮춥니다.
() 조기 종료를 봅니다. 표본 에 차수 인 모형을 에서 시작해 경사하강으로 학습합니다.
| 걸음 수 | 계수 크기 | 학습 오차 | 검증 오차 |
|---|---|---|---|
학습 오차는 에서 까지 단조로 줄어듭니다. 그런데 검증 오차는 걸음에서 으로 가장 좋고 그 뒤로 계속 나빠져 이 됩니다.
배 나빠지는 동안 학습 오차는 에서 으로 좋아졌습니다. 학습 오차만 보면 아무 문제가 없어 보입니다.
계수 크기가 에서 로 자란 것이 신호입니다. 걸음 수가 의 역수처럼 움직입니다. 조기 종료가 곧 정규화입니다.
() 자료를 늘리면 복잡도가 어떻게 보이는지 잽니다. 모형은 차수 으로 고정합니다.
| 표본 | 무작위 라벨 학습 오차 | 참 라벨 학습 오차 | 둘의 차 |
|---|---|---|---|
표본이 늘수록 무작위 라벨을 못 맞춥니다. 에서 으로 올라가는데, 이 "전혀 못 맞춤"입니다.
모형은 그대로인데 자료가 모형을 눌렀습니다. 복잡도는 모형만의 성질이 아니라 모형과 자료의 관계입니다.
강 문제 에서 자료 늘리기가 분산을 공짜로 줄인다고 한 것이 이것입니다.
이 문제에서 배우는 것. 복잡도를 낮추는 데 모수를 지울 필요가 없습니다. 덜 학습하거나, 자료를 늘리거나, 계수를 묶으면 됩니다. 그리고 조기 종료처럼 학습 오차만 보면 안 보이는 것이 있습니다.
확인 4-1. 조기 종료가 정규화와 같은 일을 하는 이유를 쓰세요.
답. 걸음 수가 계수 크기를 묶어 의 역수처럼 작동하기 때문입니다.
확인 4-2. 검산에서 검증 오차가 가장 좋은 걸음 수와 그 값을 쓰세요.
답. 걸음이고 입니다.
확인 4-3. 검산에서 표본 와 일 때 무작위 라벨 학습 오차를 쓰세요.
답. 와 입니다.
문제. 실제로 판정하고 조절합니다.
() 판정 순서를 정리하세요.
() 노름 기반 복잡도를 재세요.
() 흔한 오해를 바로잡으세요.
생각의 실마리. 문제 부터 까지의 눈금을 실무 절차로 바꿉니다. 물어야 할 것은 "복잡도가 모자란가 넘치는가" 하나입니다.
풀이. () 판정 순서를 정리합니다.
| 무엇을 보나 | 무엇을 뜻하나 | 무엇을 하나 |
|---|---|---|
| 학습 오차가 큼 | 복잡도가 모자람 | 모형을 키움 |
| 학습은 작고 검증이 큼 | 복잡도가 넘침 | 정규화 또는 자료 |
| 둘 다 크고 붙어 있음 | 잡음 한계 | 변수를 바꿈 |
| 검증이 들쭉날쭉 | 표본이 모자람 | 강 반복 교차검증 |
| 무작위 라벨도 맞춤 | 외울 힘이 넘침 | 복잡도를 줄임 |
강 문제 의 학습 곡선 판정과 같은 표입니다. 다섯째 줄만 이 강의에서 새로 추가됐습니다.
() 노름 기반 복잡도를 잽니다. 차수를 올리면서 벌점이 있을 때와 없을 때를 견줍니다.
| 차수 | 모수 | 벌점 없이 노름 | 벌점 없이 검증 | 릿지 노름 |
|---|---|---|---|---|
| 약 1.33\times 10^ |
벌점이 없으면 차수 에서 노름이 로 뛰고 검증 오차가 억이 됩니다. 차수 에서는 각각 억과 입니다.
릿지를 걸면 노름이 에서 로 퍼센트만 자랍니다. 모수는 개에서 개로 열두 배 늘었는데도 그렇습니다.
릿지 쪽 검증 오차만 따로 봅니다.
| 차수 | 릿지 검증 오차 | 차수 대비 |
|---|---|---|
릿지 검증 오차도 자라기는 합니다. 차수 의 배가 되므로 노름 하나로 다 설명되지는 않습니다. 그래도 벌점 없는 쪽의 배에 비하면 얘기가 안 됩니다.
모수 개수를 세는 것보다 노름을 재는 것이 실제에 가깝습니다.
() 흔한 오해를 바로잡습니다.
| 흔한 오해 | 실제로는 |
|---|---|
| 모수가 많으면 과적합한다 | 정규화가 있으면 아니다 |
| 학습 오차 은 나쁘다 | 강 이중 하강을 보라 |
| 복잡도는 모형의 성질이다 | 자료와 함께 정해진다 |
| VC 차원이 실무 지침이다 | 너무 느슨해 못 쓴다 |
셋째 줄이 이 강의의 결론입니다. 문제 에서 같은 모형이 표본 에서는 무작위 라벨을 퍼센트 외웠고 표본 에서는 퍼센트만 외웠습니다.
이 문제에서 배우는 것. 복잡도는 재는 것이지 세는 것이 아닙니다. 계수를 세지 말고, 무작위 라벨을 줘 보거나 노름을 재거나 교차검증으로 격차를 재야 합니다.
확인 5-1. 학습 오차가 작고 검증 오차가 클 때 무엇을 해야 하는지 쓰세요.
답. 정규화를 걸거나 자료를 늘려야 합니다.
확인 5-2. 검산에서 차수 일 때 벌점 없는 노름과 릿지 노름을 쓰세요.
답. 과 입니다.
확인 5-3. 복잡도가 모형만의 성질이 아닌 이유를 쓰세요.
답. 같은 모형도 자료가 늘면 외울 힘이 줄기 때문입니다.
| 유형 | 무엇을 묻나 | 어디를 보나 |
|---|---|---|
| 유효 자유도 | 실제로 쓴 방향의 수 | 문제 |
| 낙관의 크기 | 문제 | |
| 무작위 라벨 실험 | 외울 힘 | 문제 |
| 라데마허 복잡도 | 잡음과의 최대 상관 | 문제 |
| VC 차원 | 쪼갤 수 있는 점 수 | 문제 |
| 상계의 느슨함 | 최악을 재므로 | 문제 , |
| 조기 종료 | 걸음 수가 곧 | 문제 |
| 자료의 억제력 | 늘면 못 외움 | 문제 |
| 노름 기반 | 계수 크기로 재기 | 문제 |
| 판정 순서 | 모자란가 넘치는가 | 문제 |
눈금 넷을 한자리에 모읍니다.
| 눈금 | 자료에 딸리나 | 정규화를 세나 | 실무에 쓸 만한가 |
|---|---|---|---|
| 모수 개수 | 아니오 | 아니오 | 대충만 |
| 유효 자유도 | 예 | 예 | 선형이면 예 |
| VC 차원 | 아니오 | 아니오 | 아니오 |
| 라데마허 | 예 | 예 | 계산이 비쌈 |
| 무작위 라벨 실험 | 예 | 예 | 예 |
문제 6. 유효 자유도의 공식을 쓰세요.
답. 특이값마다 를 더한 값입니다.
문제 7. 검산에서 가 과 일 때의 유효 자유도를 쓰세요.
답. 과 입니다.
문제 8. 낙관의 크기를 자유도로 나타내는 식을 쓰세요.
답. 잡음 분산 곱하기 자유도 나누기 표본의 두 배입니다.
문제 9. 검산에서 차수 일 때 무작위 라벨을 얼마나 외웠는지 쓰세요.
답. 입니다.
문제 10. 검산에서 차수 일 때 라데마허 복잡도를 쓰세요.
답. 입니다.
문제 11. 검산에서 표본 일 때 상계가 실제 격차의 몇 배인지 쓰세요.
답. 배입니다.
문제 12. 차원 직선의 VC 차원과 안 되는 배치를 쓰세요.
답. 이고 네 점의 배타적 논리합 배치가 안 됩니다.
문제 13. 검산에서 표본 일 때 VC 상계를 쓰세요.
답. 입니다.
문제 14. 검산에서 검증 오차가 가장 좋은 걸음 수와 그 값을 쓰세요.
답. 걸음이고 입니다.
문제 15. 검산에서 걸음일 때 계수 크기와 검증 오차를 쓰세요.
답. 와 입니다.
문제 16. 검산에서 표본 와 일 때 무작위 라벨 학습 오차를 쓰세요.
답. 와 입니다.
문제 17. 검산에서 차수 일 때 벌점 없는 노름과 릿지 노름을 쓰세요.
답. 과 입니다.
문제 18. 복잡도가 모형만의 성질이 아닌 이유를 쓰세요.
답. 같은 모형도 자료가 늘면 외울 힘이 줄기 때문입니다.
심화 1. 유효 자유도가 왜 모자 행렬의 대각합인지 보이세요.
릿지의 예측은 이고 입니다. 특이값 분해로 쓰면 이렇습니다.
| 무엇 | 값 |
|---|---|
| 최소제곱 | 정사영이므로 대각합이 랭크 |
대각합이 "각 관측이 자기 예측에 얼마나 기여하는가"의 합입니다. 강의 지렛대 를 다 더한 것이고, 강 심화 의 하나씩 빼기 공식에 나오던 그 값입니다.
심화 2. 스타인의 불편 위험 추정을 정리하세요.
| 항 | 무엇 |
|---|---|
| 첫째 | 학습 잔차 |
| 둘째 | 잡음만큼 빼기 |
| 셋째 | 자유도만큼 벌하기 |
셋째 항이 문제 에서 잰 낙관입니다. 이 식의 기댓값이 참 위험과 정확히 같으므로 검증 자료 없이도 위험을 추정할 수 있습니다. AIC와 Mallows의 가 이 식의 특수한 경우이고, 를 알아야 한다는 것이 실무의 걸림돌입니다.
심화 3. 라데마허 복잡도가 왜 격차를 묶는지 설명하세요.
대칭화 논법을 씁니다. 학습 자료와 같은 분포에서 유령 표본을 하나 더 상상합니다.
| 단계 | 무엇 |
|---|---|
| 첫째 | 참 위험을 유령 표본의 경험 위험으로 바꿈 |
| 둘째 | 두 표본을 무작위로 맞바꿈 |
| 셋째 | 맞바꿈이 라벨과 같은 역할 |
셋째 단계에서 라데마허 변수가 나옵니다. 두 표본을 섞어도 분포가 같으므로 부호를 무작위로 붙인 것과 같고, 그 상태에서의 최대 상관이 곧 라데마허 복잡도입니다.
심화 4. 노름 기반 상계가 왜 신경망에 더 맞는지 설명하세요.
VC 차원은 모수 개수로 자라지만 노름 기반 상계는 가중치의 크기로 자랍니다.
| 상계 | 무엇에 딸리나 | 신경망에서 |
|---|---|---|
| VC | 모수 수 | 억이면 무의미 |
| 노름 곱 | 층마다 노름의 곱 | 훨씬 작음 |
| 여백 정규화 | 노름 나누기 여백 | 실제와 가까움 |
학습이 끝난 신경망의 가중치는 초기값에서 멀리 안 갑니다. 그래서 모수는 많아도 노름은 작고, 문제 의 조기 종료가 그 이유 중 하나입니다. 다만 노름 기반 상계도 여전히 실제 격차보다 훨씬 크다는 것이 알려져 있습니다.
심화 5. 무작위 라벨을 다 외우는데도 일반화하는 현상을 정리하세요.
| 무엇 | 어디서 |
|---|---|
| 모수가 표본보다 많음 | 문제 의 차수 |
| 무작위 라벨도 다 맞춤 | 문제 |
| 그래도 참 라벨은 일반화 | 강 이중 하강 |
세 줄이 동시에 참일 수 있습니다. VC 차원이나 라데마허 같은 최악 기반 눈금은 이것을 설명 못 합니다. 최적화가 고르는 해가 여러 해 중 노름이 가장 작은 것이기 때문이라는 설명이 유력하고, 강에서 최소 노름 해로 이중 하강을 재현한 것이 그 증거입니다.
심화 6. 복잡도 눈금을 고르는 실무 기준을 정리하세요.
| 상황 | 무엇을 쓰나 | 왜 |
|---|---|---|
| 선형 모형에 릿지 | 유효 자유도 | 닫힌 식이 있음 |
| 모형을 못 믿겠음 | 무작위 라벨 실험 | 가정이 필요 없음 |
| 후보 모형 비교 | 교차검증 | 예측 위험을 직접 |
| 이론 논의 | 라데마허 | 분포에 안 기댐 |
둘째 줄이 실무의 안전장치입니다. 라벨을 섞어 학습시켰는데 성능이 나오면 어딘가에서 자료가 새고 있습니다. 강 문제 의 변수 선택 누출을 잡는 데도 같은 실험을 씁니다.
정답.
| 기호 | 읽는 법 | 뜻 |
|---|---|---|
| 유효 자유도 | effective degrees of freedom | 실제로 쓴 방향의 수입니다 |
| 모자 행렬 | hat matrix | 관측을 예측으로 보내는 행렬입니다 |
| SURE | Stein unbiased risk estimate | 검증 없이 위험을 추정합니다 |
| VC 차원 | Vapnik-Chervonenkis dimension | 쪼갤 수 있는 점의 최대 개수입니다 |
| 쪼갬 | shattering | 어떤 라벨이 와도 다 맞춥니다 |
| 라데마허 복잡도 | Rademacher complexity | 무작위 부호와의 최대 상관입니다 |
| 대칭화 | symmetrization | 유령 표본으로 격차를 묶는 논법입니다 |
| 무작위 라벨 실험 | random label test | 외울 힘을 직접 재는 실험입니다 |
| 조기 종료 | early stopping | 덜 학습해 복잡도를 낮춥니다 |
| 암묵적 정규화 | implicit regularization | 벌점 없이 정규화처럼 작동합니다 |
다음은 215강입니다. 단원이 여기서 끝납니다. 강부터 강까지 답이 새 자료에서도 맞는가를 물었고, 그 답을 재는 눈금과 조절 손잡이를 다 만들었습니다. 단원부터는 실제 지도학습 알고리즘을 하나씩 유도합니다.
import numpy as np
rng = np.random.default_rng(20261108)
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 cheb(x, d):
# 체비쇼프 기저로 설계행렬을 만듭니다 (거듭제곱 기저는 터집니다)
T = [np.ones_like(x), x]
for _ in range(2, d + 1):
T.append(2 * x * T[-1] - T[-2])
return np.stack(T[:d + 1], axis=1)
def ridge(X, y, lam):
p = X.shape[1]
return np.linalg.solve(X.T @ X / len(y) + lam * np.eye(p),
X.T @ y / len(y))
def mse(X, y, w):
return float(np.mean((y - X @ w) ** 2))
# --- 문제 1: 모수 개수는 복잡도가 아닙니다 -------------------------------
print(" 210강에서 모형이 복잡하면 분산이 크다고 했습니다")
print(" 그러면 복잡도를 무엇으로 재야 하는지 봅니다")
print(" %s %s %s"
% (pw("눈금 후보", 22), rw("무엇을 세나", 22), rw("무엇이 문제인가", 26)))
for a, b, c in [("모수 개수", "계수의 수", "정규화를 못 셈"),
("유효 자유도", "실제로 쓴 자유도", "선형 모형에만 쉬움"),
("VC 차원", "쪼갤 수 있는 점 수", "느슨하고 계산이 어려움"),
("라데마허 복잡도", "잡음을 얼마나 맞추나", "자료에 딸림"),
("실제로 재기", "무작위 라벨 실험", "비싸지만 정직함")]:
print(" %s %s %s" % (pw(a, 22), rw(b, 22), rw(c, 26)))
print(" 아래에서 다섯째 줄을 실제로 해 봅니다")
print(" 모수가 같아도 복잡도가 다를 수 있음을 보입니다")
n1 = 60
x1 = np.linspace(-1, 1, n1)
f1 = np.sin(3 * x1)
y1 = f1 + rng.normal(0, 0.3, n1)
X1 = cheb(x1, 20)
print(" 계수 21 개짜리 같은 모형에 lambda 만 바꿉니다")
print(" %s %s %s %s"
% (pw("lambda", 12), rw("모수 개수", 14), rw("유효 자유도", 16),
rw("학습 오차", 14)))
G = X1.T @ X1 / n1
ev = np.linalg.eigvalsh(G)
for lam in [0.0, 1e-4, 1e-2, 0.1, 1.0, 100.0]:
df = float(np.sum(ev / (ev + lam)))
w = ridge(X1, y1, lam) if lam > 0 else np.linalg.pinv(X1) @ y1
print(" %s %14d %16.6f %14.6f"
% (pw("%.4f" % lam, 12), 21, df, mse(X1, y1, w)))
print(" 유효 자유도는 특이값마다 s 나누기 s 더하기 lambda 를 더한 값입니다")
print(" 모수는 21 개로 고정인데 유효 자유도는 21 에서 0.06 까지 움직입니다")
print(" 211강 문제 4 에서 본 방향별 배율을 다 더한 것이 유효 자유도입니다")
print(" 유효 자유도가 실제로 무엇을 뜻하는지 확인합니다")
print(" 학습 오차와 검증 오차의 차가 자유도에 비례하는지 봅니다")
print(" 참 오차에는 줄일 수 없는 잡음 분산 0.09 를 더해 학습 오차와 눈금을 맞춥니다")
xt = np.linspace(-1, 1, 4000)
Xt = cheb(xt, 20)
yt_mean = np.sin(3 * xt)
print(" %s %s %s %s"
% (pw("유효 자유도", 16), rw("학습 오차", 14), rw("참 오차", 14),
rw("차 나누기 자유도", 20)))
R1 = 300
for lam in [1e-4, 1e-2, 0.1, 1.0]:
df = float(np.sum(ev / (ev + lam)))
tr, te = [], []
for _ in range(R1):
ya = f1 + rng.normal(0, 0.3, n1)
w = ridge(X1, ya, lam)
tr.append(mse(X1, ya, w))
te.append(float(np.mean((yt_mean - Xt @ w) ** 2)) + 0.09)
gap = float(np.mean(te)) - float(np.mean(tr))
print(" %s %14.6f %14.6f %20.6f"
% (pw("%.6f" % df, 16), float(np.mean(tr)), float(np.mean(te)),
gap / df))
print(" 마지막 열이 거의 일정합니다. 0.3 제곱을 30 으로 나눈 값 근처입니다")
print(" 낙관의 크기가 잡음 분산 곱하기 자유도 나누기 표본의 두 배입니다")
print(" 207강 문제 1 에서 본 자유도의 뜻이 여기서 수치로 확인됩니다")
# --- 문제 2: 잡음을 얼마나 맞추는가 -------------------------------------
print(" 복잡도를 직접 재 봅니다. 무작위 라벨을 얼마나 맞추는지 셉니다")
print(" 라벨을 완전히 무작위로 두면 배울 것이 없습니다")
print(" 그래도 맞춘다면 그만큼 외울 힘이 있다는 뜻입니다")
print(" %s %s %s %s"
% (pw("차수", 10), rw("모수 개수", 14), rw("무작위 라벨 학습 오차", 24),
rw("무작위 라벨을 얼마나 외웠나", 30)))
n2 = 40
x2 = np.linspace(-1, 1, n2)
for d in [1, 3, 10, 20, 39]:
X2 = cheb(x2, d)
es = []
for _ in range(200):
yr = rng.normal(0, 1, n2)
es.append(mse(X2, yr, np.linalg.pinv(X2) @ yr))
m = float(np.mean(es))
print(" %s %14d %24.6f %30.6f"
% (pw(str(d), 10), d + 1, m, 1.0 - m))
print(" 모수가 표본에 가까워지면 무작위 라벨도 거의 다 맞춥니다")
print(" 차수 39 에서 학습 오차가 0 입니다. 표본 40 개를 40 개 계수로 지납니다")
print(" 208강 문제 4 의 완전 분리와 같은 현상입니다")
print(" 라데마허 복잡도를 직접 계산합니다")
print(" 라벨을 플러스 1 과 마이너스 1 로 무작위로 두고 상관을 최대로 만듭니다")
print(" %s %s %s"
% (pw("차수", 10), rw("라데마허 복잡도", 20), rw("루트 모수 나누기 표본", 26)))
for d in [1, 3, 10, 20, 39]:
X2 = cheb(x2, d)
Q, _ = np.linalg.qr(X2)
vs = []
for _ in range(400):
sg = rng.choice([-1.0, 1.0], n2)
vs.append(np.linalg.norm(Q.T @ sg) / n2)
print(" %s %20.6f %26.6f"
% (pw(str(d), 10), float(np.mean(vs)), np.sqrt(d + 1.0) / n2))
print(" 오른쪽 열이 왼쪽의 상계입니다. 차수 39 에서는 정확히 같아집니다")
print(" 기저가 표본을 다 채우면 어떤 라벨과도 완전히 상관되기 때문입니다")
print(" 복잡도가 모수 개수의 제곱근에 비례합니다. 개수 자체가 아닙니다")
print(" 그래서 모수를 두 배 늘려도 복잡도는 1.41 배만 됩니다")
print(" 일반화 격차의 상계를 봅니다")
print(" %s %s %s %s"
% (pw("표본", 10), rw("루트 21 나누기 n 의 두 배", 26), rw("실제 격차", 16),
rw("상계가 몇 배 큰가", 22)))
for n in [40, 100, 400, 2000]:
xa = np.linspace(-1, 1, n)
Xa = cheb(xa, 20)
fa = np.sin(3 * xa)
trs, tes = [], []
for _ in range(120):
ya = fa + rng.normal(0, 0.3, n)
w = np.linalg.pinv(Xa) @ ya
trs.append(mse(Xa, ya, w))
tes.append(float(np.mean((yt_mean - Xt @ w) ** 2)) + 0.09)
gap = float(np.mean(tes)) - float(np.mean(trs))
bd = 2.0 * np.sqrt(21.0 / n)
print(" %s %26.6f %16.6f %22.6f"
% (pw(str(n), 10), bd, gap, bd / gap))
print(" 상계가 실제 격차보다 수십 배 큽니다. 방향은 맞고 크기는 안 맞습니다")
print(" 이론 상계는 최악의 경우를 재므로 대체로 아주 느슨합니다")
print(" 그래도 표본이 늘면 격차가 준다는 것은 둘 다 말합니다")
# --- 문제 3: VC 차원 ----------------------------------------------------
print(" 분류에서 복잡도를 세는 고전적인 방법을 봅니다")
print(" 점 몇 개까지 어떤 라벨이 와도 다 맞출 수 있는지 셉니다")
print(" %s %s %s"
% (pw("모형", 26), rw("VC 차원", 14), rw("왜 그런가", 26)))
for a, b, c in [("한 점 문턱", "1", "한 점만 나눔"),
("직선 (2 차원)", "3", "세 점까지 아무 라벨"),
("초평면 (d 차원)", "d 더하기 1", "절편을 포함"),
("축에 나란한 사각형", "4", "네 변이 각각 하나"),
("사인 함수 하나", "무한", "진동수로 다 맞춤")]:
print(" %s %s %s" % (pw(a, 26), rw(b, 14), rw(c, 26)))
print(" 다섯째 줄이 중요합니다. 모수가 하나인데 VC 차원이 무한입니다")
print(" 모수 개수와 복잡도가 다른 것임을 보여 주는 표준 예입니다")
print(" 2 차원 직선의 VC 차원이 3 인 것을 확인합니다")
print(" %s %s %s %s"
% (pw("점 개수", 12), rw("라벨 가짓수", 16), rw("다 맞춘 가짓수", 18),
rw("전부 되는가", 16)))
def shatter(P):
m = len(P)
A = np.hstack([P, np.ones((m, 1))])
ok = 0
for b in range(2 ** m):
lab = np.array([1.0 if (b >> i) & 1 else -1.0 for i in range(m)])
w = np.linalg.lstsq(A * lab[:, None], np.ones(m), rcond=None)[0]
hit = np.all(lab * (A @ w) > 1e-9)
for _ in range(60):
if hit:
break
v = rng.normal(0, 1, 3)
hit = np.all(lab * (A @ v) > 0)
ok += int(hit)
return ok
for m in [1, 2, 3, 4]:
P = np.array([[np.cos(2 * np.pi * i / m + 0.3),
np.sin(2 * np.pi * i / m + 0.3)] for i in range(m)])
if m == 3:
P = np.array([[0.0, 0.0], [1.0, 0.0], [0.0, 1.0]])
if m == 4:
P = np.array([[0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [1.0, 1.0]])
ok = shatter(P)
print(" %s %16d %18d %s"
% (pw(str(m), 12), 2 ** m, ok,
rw("예" if ok == 2 ** m else "아니오", 16)))
print(" 네 점에서 배타적 논리합 배치는 직선으로 못 나눕니다")
print(" 그래서 2 차원 직선의 VC 차원이 3 입니다")
print(" 한 배치라도 다 되면 되고 모든 배치가 다 될 필요는 없습니다")
print(" VC 차원이 주는 상계를 봅니다")
print(" %s %s %s %s"
% (pw("표본", 10), rw("VC 21 일 때 상계", 20), rw("표본 몇 배 필요한가", 24),
rw("쓸 만한가", 14)))
for n in [100, 1000, 10000, 100000]:
bd = np.sqrt(8.0 * (21.0 * np.log(2 * n / 21.0 + 1) + np.log(4.0))
/ n)
print(" %s %20.6f %24.6f %s"
% (pw(str(n), 10), bd, n / 21.0,
rw("예" if bd < 0.3 else "아니오", 14)))
print(" 표본이 VC 차원의 476 배여도 상계가 0.34 로 1 에 가깝습니다")
print(" 4762 배가 되어야 0.12 로 내려옵니다")
print(" 실무에서 쓰는 신경망은 VC 차원이 모수 수만큼 크므로 이 상계가 무의미합니다")
print(" 그래서 요즘은 라데마허나 노름 기반 상계를 씁니다")
# --- 문제 4: 무엇이 진짜로 일반화를 정하는가 ----------------------------
print(" 같은 모수 개수로 복잡도를 조절하는 세 가지를 견줍니다")
print(" %s %s %s"
% (pw("무엇", 22), rw("어떻게 조절하나", 24), rw("어디서 봤나", 22)))
for a, b, c in [("벌점", "lambda 를 키움", "211강"),
("조기 종료", "덜 학습함", "197강"),
("자료 늘리기", "외우기 어렵게", "210강"),
("잡음 넣기", "정확히 못 맞춤", "이 문제"),
("계수 크기 제한", "노름을 묶음", "문제 5")]:
print(" %s %s %s" % (pw(a, 22), rw(b, 24), rw(c, 22)))
print(" 다섯 가지가 모수를 하나도 안 줄이고 복잡도를 낮춥니다")
print(" 조기 종료가 벌점과 같은 일을 하는지 봅니다")
n4 = 50
x4 = np.linspace(-1, 1, n4)
X4 = cheb(x4, 45)
f4 = np.sin(3 * x4)
y4 = f4 + rng.normal(0, 0.3, n4)
Xv4 = cheb(np.linspace(-1, 1, 4000), 45)
fv4 = np.sin(3 * np.linspace(-1, 1, 4000))
L4 = np.linalg.norm(X4, 2) ** 2 / n4
print(" %s %s %s %s"
% (pw("걸음 수", 12), rw("계수 크기", 16), rw("학습 오차", 14),
rw("검증 오차", 14)))
w4 = np.zeros(46)
snap = {}
for it in range(1, 200001):
w4 -= (1.0 / L4) * (X4.T @ (X4 @ w4 - y4) / n4)
if it in (1, 3, 10, 100, 1000, 30000, 200000):
snap[it] = w4.copy()
for it in [1, 3, 10, 100, 1000, 30000, 200000]:
w = snap[it]
print(" %s %16.6f %14.6f %14.6f"
% (pw(str(it), 12), float(np.linalg.norm(w)), mse(X4, y4, w),
float(np.mean((fv4 - Xv4 @ w) ** 2))))
print(" 걸음을 늘릴수록 계수가 커지고 학습 오차가 줄어듭니다")
print(" 검증 오차는 3 걸음에서 0.055123 으로 가장 좋고 그 뒤로 계속 나빠집니다")
print(" 걸음 수가 lambda 의 역수처럼 움직입니다. 조기 종료가 곧 정규화입니다")
print(" 자료를 늘리면 같은 모형의 복잡도가 어떻게 보이는지 봅니다")
print(" %s %s %s %s"
% (pw("표본", 10), rw("무작위 라벨 학습 오차", 24), rw("참 라벨 학습 오차", 22),
rw("둘의 차", 14)))
for n in [25, 50, 100, 400]:
xa = np.linspace(-1, 1, n)
Xa = cheb(xa, 20)
fa = np.sin(3 * xa)
er, ep = [], []
for _ in range(100):
yr = rng.normal(0, 1, n)
er.append(mse(Xa, yr, np.linalg.pinv(Xa) @ yr))
ya = fa + rng.normal(0, 0.3, n)
ep.append(mse(Xa, ya, np.linalg.pinv(Xa) @ ya))
print(" %s %24.6f %22.6f %14.6f"
% (pw(str(n), 10), float(np.mean(er)), float(np.mean(ep)),
float(np.mean(er)) - float(np.mean(ep))))
print(" 표본이 늘수록 무작위 라벨을 못 맞춥니다. 외울 힘이 상대적으로 줄어듭니다")
print(" 모형은 그대로인데 자료가 모형을 눌렀습니다")
print(" 210강 문제 3 에서 자료 늘리기가 분산을 공짜로 줄인다고 한 것입니다")
# --- 문제 5: 실무에서 복잡도 다루기 -------------------------------------
print(" 실무에서 복잡도가 문제인지 판정하는 순서를 정리합니다")
print(" %s %s %s"
% (pw("무엇을 보나", 24), rw("무엇을 뜻하나", 24), rw("무엇을 하나", 24)))
for a, b, c in [("학습 오차가 큼", "복잡도가 모자람", "모형을 키움"),
("학습은 작고 검증이 큼", "복잡도가 넘침", "정규화 또는 자료"),
("둘 다 크고 붙어 있음", "잡음 한계", "변수를 바꿈"),
("검증이 들쭉날쭉", "표본이 모자람", "212강 반복 교차검증"),
("무작위 라벨도 맞춤", "외울 힘이 넘침", "복잡도를 줄임")]:
print(" %s %s %s" % (pw(a, 24), rw(b, 24), rw(c, 24)))
print(" 210강 문제 2 의 학습 곡선 판정과 같은 표입니다")
print(" 노름 기반 복잡도를 재 봅니다")
print(" 모수 개수 대신 계수의 크기로 재면 무엇이 달라지는지 봅니다")
print(" %s %s %s %s %s"
% (pw("차수", 8), rw("모수", 8), rw("벌점 없이 노름", 18),
rw("벌점 없이 검증", 18), rw("릿지 노름", 14)))
rows = []
for d in [3, 5, 10, 20, 40, 48]:
Xa = cheb(x4, d)
Xb = cheb(np.linspace(-1, 1, 4000), d)
w0 = np.linalg.pinv(Xa) @ y4
w1 = ridge(Xa, y4, 0.05)
e0 = float(np.mean((fv4 - Xb @ w0) ** 2))
e1 = float(np.mean((fv4 - Xb @ w1) ** 2))
rows.append((d, e1))
print(" %s %8d %18.6f %18.6f %14.6f"
% (pw(str(d), 8), d + 1, float(np.linalg.norm(w0)), e0,
float(np.linalg.norm(w1))))
print(" 벌점이 없으면 모수가 늘수록 노름이 커지고 검증 오차가 함께 터집니다")
print(" 릿지를 걸면 노름이 0.86 에서 0.92 로 7 퍼센트만 자랍니다")
print(" %s %s %s"
% (pw("차수", 8), rw("릿지 검증 오차", 18), rw("차수 3 대비", 16)))
for d, e1 in rows:
print(" %s %18.6f %16.6f" % (pw(str(d), 8), e1, e1 / rows[0][1]))
print(" 릿지 검증 오차도 자라기는 합니다. 노름 하나로 다 설명되지는 않습니다")
print(" 그래도 벌점 없는 쪽에 비하면 훨씬 완만합니다")
print(" 모수 개수를 세는 것보다 노름을 재는 것이 실제에 가깝습니다")
print(" 마지막으로 흔한 오해를 정리합니다")
print(" %s %s"
% (pw("흔한 오해", 30), rw("실제로는", 36)))
for a, b in [("모수가 많으면 과적합한다", "정규화가 있으면 아니다"),
("학습 오차 0 은 나쁘다", "210강 이중 하강을 보라"),
("복잡도는 모형의 성질이다", "자료와 함께 정해진다"),
("VC 차원이 실무 지침이다", "너무 느슨해 못 쓴다")]:
print(" %s %s" % (pw(a, 30), rw(b, 36)))
print(" 214강은 복잡도를 재는 눈금을 봤습니다. 03단원이 여기서 끝납니다")
print(" 215강부터는 실제 지도학습 알고리즘을 하나씩 유도합니다")
# 210강에서 모형이 복잡하면 분산이 크다고 했습니다
# 그러면 복잡도를 무엇으로 재야 하는지 봅니다
# 눈금 후보 무엇을 세나 무엇이 문제인가
# 모수 개수 계수의 수 정규화를 못 셈
# 유효 자유도 실제로 쓴 자유도 선형 모형에만 쉬움
# VC 차원 쪼갤 수 있는 점 수 느슨하고 계산이 어려움
# 라데마허 복잡도 잡음을 얼마나 맞추나 자료에 딸림
# 실제로 재기 무작위 라벨 실험 비싸지만 정직함
# 아래에서 다섯째 줄을 실제로 해 봅니다
# 모수가 같아도 복잡도가 다를 수 있음을 보입니다
# 계수 21 개짜리 같은 모형에 lambda 만 바꿉니다
# lambda 모수 개수 유효 자유도 학습 오차
# 0.0000 21 21.000000 0.054356
# 0.0001 21 20.993596 0.054356
# 0.0100 21 20.397487 0.054526
# 0.1000 21 16.756938 0.066147
# 1.0000 21 6.862913 0.275571
# 100.0000 21 0.109994 0.642034
# 유효 자유도는 특이값마다 s 나누기 s 더하기 lambda 를 더한 값입니다
# 모수는 21 개로 고정인데 유효 자유도는 21 에서 0.06 까지 움직입니다
# 211강 문제 4 에서 본 방향별 배율을 다 더한 것이 유효 자유도입니다
# 유효 자유도가 실제로 무엇을 뜻하는지 확인합니다
# 학습 오차와 검증 오차의 차가 자유도에 비례하는지 봅니다
# 참 오차에는 줄일 수 없는 잡음 분산 0.09 를 더해 학습 오차와 눈금을 맞춥니다
# 유효 자유도 학습 오차 참 오차 차 나누기 자유도
# 20.993596 0.058548 0.122159 0.003030
# 20.397487 0.058989 0.119240 0.002954
# 16.756938 0.070338 0.120377 0.002986
# 6.862913 0.268684 0.293010 0.003545
# 마지막 열이 거의 일정합니다. 0.3 제곱을 30 으로 나눈 값 근처입니다
# 낙관의 크기가 잡음 분산 곱하기 자유도 나누기 표본의 두 배입니다
# 207강 문제 1 에서 본 자유도의 뜻이 여기서 수치로 확인됩니다
# 복잡도를 직접 재 봅니다. 무작위 라벨을 얼마나 맞추는지 셉니다
# 라벨을 완전히 무작위로 두면 배울 것이 없습니다
# 그래도 맞춘다면 그만큼 외울 힘이 있다는 뜻입니다
# 차수 모수 개수 무작위 라벨 학습 오차 무작위 라벨을 얼마나 외웠나
# 1 2 0.949434 0.050566
# 3 4 0.884730 0.115270
# 10 11 0.699721 0.300279
# 20 21 0.460557 0.539443
# 39 40 0.000000 1.000000
# 모수가 표본에 가까워지면 무작위 라벨도 거의 다 맞춥니다
# 차수 39 에서 학습 오차가 0 입니다. 표본 40 개를 40 개 계수로 지납니다
# 208강 문제 4 의 완전 분리와 같은 현상입니다
# 라데마허 복잡도를 직접 계산합니다
# 라벨을 플러스 1 과 마이너스 1 로 무작위로 두고 상관을 최대로 만듭니다
# 차수 라데마허 복잡도 루트 모수 나누기 표본
# 1 0.030922 0.035355
# 3 0.048608 0.050000
# 10 0.081748 0.082916
# 20 0.113214 0.114564
# 39 0.158114 0.158114
# 오른쪽 열이 왼쪽의 상계입니다. 차수 39 에서는 정확히 같아집니다
# 기저가 표본을 다 채우면 어떤 라벨과도 완전히 상관되기 때문입니다
# 복잡도가 모수 개수의 제곱근에 비례합니다. 개수 자체가 아닙니다
# 그래서 모수를 두 배 늘려도 복잡도는 1.41 배만 됩니다
# 일반화 격차의 상계를 봅니다
# 표본 루트 21 나누기 n 의 두 배 실제 격차 상계가 몇 배 큰가
# 40 1.449138 0.145084 9.988268
# 100 0.916515 0.035731 25.650329
# 400 0.458258 0.009497 48.251716
# 2000 0.204939 0.002305 88.898199
# 상계가 실제 격차보다 수십 배 큽니다. 방향은 맞고 크기는 안 맞습니다
# 이론 상계는 최악의 경우를 재므로 대체로 아주 느슨합니다
# 그래도 표본이 늘면 격차가 준다는 것은 둘 다 말합니다
# 분류에서 복잡도를 세는 고전적인 방법을 봅니다
# 점 몇 개까지 어떤 라벨이 와도 다 맞출 수 있는지 셉니다
# 모형 VC 차원 왜 그런가
# 한 점 문턱 1 한 점만 나눔
# 직선 (2 차원) 3 세 점까지 아무 라벨
# 초평면 (d 차원) d 더하기 1 절편을 포함
# 축에 나란한 사각형 4 네 변이 각각 하나
# 사인 함수 하나 무한 진동수로 다 맞춤
# 다섯째 줄이 중요합니다. 모수가 하나인데 VC 차원이 무한입니다
# 모수 개수와 복잡도가 다른 것임을 보여 주는 표준 예입니다
# 2 차원 직선의 VC 차원이 3 인 것을 확인합니다
# 점 개수 라벨 가짓수 다 맞춘 가짓수 전부 되는가
# 1 2 2 예
# 2 4 4 예
# 3 8 8 예
# 4 16 14 아니오
# 네 점에서 배타적 논리합 배치는 직선으로 못 나눕니다
# 그래서 2 차원 직선의 VC 차원이 3 입니다
# 한 배치라도 다 되면 되고 모든 배치가 다 될 필요는 없습니다
# VC 차원이 주는 상계를 봅니다
# 표본 VC 21 일 때 상계 표본 몇 배 필요한가 쓸 만한가
# 100 2.016189 4.761905 아니오
# 1000 0.882223 47.619048 아니오
# 10000 0.341112 476.190476 아니오
# 100000 0.124509 4761.904762 예
# 표본이 VC 차원의 476 배여도 상계가 0.34 로 1 에 가깝습니다
# 4762 배가 되어야 0.12 로 내려옵니다
# 실무에서 쓰는 신경망은 VC 차원이 모수 수만큼 크므로 이 상계가 무의미합니다
# 그래서 요즘은 라데마허나 노름 기반 상계를 씁니다
# 같은 모수 개수로 복잡도를 조절하는 세 가지를 견줍니다
# 무엇 어떻게 조절하나 어디서 봤나
# 벌점 lambda 를 키움 211강
# 조기 종료 덜 학습함 197강
# 자료 늘리기 외우기 어렵게 210강
# 잡음 넣기 정확히 못 맞춤 이 문제
# 계수 크기 제한 노름을 묶음 문제 5
# 다섯 가지가 모수를 하나도 안 줄이고 복잡도를 낮춥니다
# 조기 종료가 벌점과 같은 일을 하는지 봅니다
# 걸음 수 계수 크기 학습 오차 검증 오차
# 1 0.517168 0.144391 0.135646
# 3 0.863772 0.019825 0.055123
# 10 0.992803 0.007473 0.064504
# 100 1.001548 0.007270 0.067403
# 1000 1.014400 0.007200 0.074497
# 30000 1.256831 0.007159 0.202345
# 200000 4.537429 0.006970 4.096033
# 걸음을 늘릴수록 계수가 커지고 학습 오차가 줄어듭니다
# 검증 오차는 3 걸음에서 0.055123 으로 가장 좋고 그 뒤로 계속 나빠집니다
# 걸음 수가 lambda 의 역수처럼 움직입니다. 조기 종료가 곧 정규화입니다
# 자료를 늘리면 같은 모형의 복잡도가 어떻게 보이는지 봅니다
# 표본 무작위 라벨 학습 오차 참 라벨 학습 오차 둘의 차
# 25 0.163455 0.014932 0.148522
# 50 0.581075 0.050586 0.530488
# 100 0.806601 0.071177 0.735424
# 400 0.948540 0.085156 0.863384
# 표본이 늘수록 무작위 라벨을 못 맞춥니다. 외울 힘이 상대적으로 줄어듭니다
# 모형은 그대로인데 자료가 모형을 눌렀습니다
# 210강 문제 3 에서 자료 늘리기가 분산을 공짜로 줄인다고 한 것입니다
# 실무에서 복잡도가 문제인지 판정하는 순서를 정리합니다
# 무엇을 보나 무엇을 뜻하나 무엇을 하나
# 학습 오차가 큼 복잡도가 모자람 모형을 키움
# 학습은 작고 검증이 큼 복잡도가 넘침 정규화 또는 자료
# 둘 다 크고 붙어 있음 잡음 한계 변수를 바꿈
# 검증이 들쭉날쭉 표본이 모자람 212강 반복 교차검증
# 무작위 라벨도 맞춤 외울 힘이 넘침 복잡도를 줄임
# 210강 문제 2 의 학습 곡선 판정과 같은 표입니다
# 노름 기반 복잡도를 재 봅니다
# 모수 개수 대신 계수의 크기로 재면 무엇이 달라지는지 봅니다
# 차수 모수 벌점 없이 노름 벌점 없이 검증 릿지 노름
# 3 4 0.929680 0.008973 0.857068
# 5 6 0.931294 0.008922 0.857135
# 10 11 0.939139 0.009991 0.862879
# 20 21 0.989117 0.034824 0.884340
# 40 41 38122.240945 165775523.774689 0.916191
# 48 49 1101453075.961178 133417943890272240.000000 0.916552
# 벌점이 없으면 모수가 늘수록 노름이 커지고 검증 오차가 함께 터집니다
# 릿지를 걸면 노름이 0.86 에서 0.92 로 7 퍼센트만 자랍니다
# 차수 릿지 검증 오차 차수 3 대비
# 3 0.011112 1.000000
# 5 0.010425 0.938198
# 10 0.010977 0.987858
# 20 0.025095 2.258330
# 40 0.056975 5.127221
# 48 0.058041 5.223152
# 릿지 검증 오차도 자라기는 합니다. 노름 하나로 다 설명되지는 않습니다
# 그래도 벌점 없는 쪽에 비하면 훨씬 완만합니다
# 모수 개수를 세는 것보다 노름을 재는 것이 실제에 가깝습니다
# 마지막으로 흔한 오해를 정리합니다
# 흔한 오해 실제로는
# 모수가 많으면 과적합한다 정규화가 있으면 아니다
# 학습 오차 0 은 나쁘다 210강 이중 하강을 보라
# 복잡도는 모형의 성질이다 자료와 함께 정해진다
# VC 차원이 실무 지침이다 너무 느슨해 못 쓴다
# 214강은 복잡도를 재는 눈금을 봤습니다. 03단원이 여기서 끝납니다
# 215강부터는 실제 지도학습 알고리즘을 하나씩 유도합니다