본 글은 학교 '머신러닝' 수업을 들으며 공부한 내용을, 저의 말로 바꿔서 남에게 설명해주듯이 쓰는 글입니다.
다시 한번 복습하는 과정에서 Coursera Andrew Ng 교수님의 강의를 일부 수강하였고, 인터넷 검색 등을 통해 내용을 보충하였습니다.
너무 쉬운 개념들은 따로 정리하지 않았습니다. 따라서 해당 글에는 적히지 않은 개념들이 일부 있을 수 있습니다.
본 글은 Andrew Ng 교수님의 'machine learning' 수업 강의 노트를 일부 사용하였습니다.
본 글에 사용된 강의노트 사진들 대부분의 저작권은 'DeepLearning.AI'에 귀속되어 있음을 밝히며,
본 글은 'DeepLearning.AI'의 'Copyright rights'에 따라 수익 창출을 하지 않고,
또한 해당 정책에 따라 '개인 공부 및 정보 전달'이라는 교육적 목적으로 글을 작성함을 밝힙니다.
다변수 선형 회귀(Linear Regression with Multiple Variable)
우리가 저번 글에서 다룬 내용은 왼쪽과 같다. 여태까지 우리는 일변수 선형 회귀를 공부했다.
즉, feature이 1개, 그리고 parameter도 최대 2개인 경우를 살펴보았다.
그러나... 당연하게도 이런 간단한 형태만 배워서는 써먹을 데가 없다.
우린 머신러닝으로 현실의 문제를 해결하는 것이 목적인데, 현실에 feature가 1개밖에 없겠는가?
그래서 우리는 우측과 같은, "다변수 선형 회귀"를 공부할 것이다.
이젠 feature가 여러개가 되었고, 우린 그 feature들을 변수 j를 통해 하나씩 가리킬 것이다.
즉 위의 사진의 경우 j = 1, 2, 3, 4 가 되며,
i의 경우 data set의 개수가 된다.
예를 들어, 우리가 지금 13번째 data set의 3번째 feature을 살펴볼 거면, 그걸 우린 x_3^(13) 이라고 표기할 수 있다.
(사실 아래첨자를 어떻게 키보드로 표기할 지는 잘 모르겠으나... 대충 여기선 나만 알아들을 수 있으면 되지 않을까? ㅎㅎ^^^)
여기서 우리가 선형대수학을 열심히 공부했던 이유가 드러나는데,
우린 features을 대표하는 feature x를, j행과 i열을 가진 행렬로 나타낼 수 있다.
여기선 i = 2이라고 지정해 준 경우, 즉 "2번째 열만 보겠다"고 지정해 준 경우이기에 열 벡터의 형태로 나타났지만,
i를 지정하지 않고 그냥 x로 표현한다면 i열의 행렬이 될 것이다.
그럼, 이제 위와 같이 h를 수정할 수 있다.
n 즉 number of features = 4인 경우는 위와 같을 것이다.
그럼, 이제 x를 각 feature을 요소로 가지는 열 벡터로,
또한 세타 또한 각 parameter들을 요소로 가지는 열 벡터로 표현이 가능하고,
각 벡터의 차원은 R+1 이다. (이때, 표기의 편의를 위해 x_0 = 1 라고 하자.)
이러면 선형대수학에서 배운 대로, 세타를 전치해 x와 행렬곱하면 그 결과가 바로 h가 나온다. (좌측 아래 식)
** 방금 설명한 게 이해가 안간다면, 이 블로그의 선형대수학 공부글을 살펴보고 오길!!!
그럼 이제, 다변수 선형 회귀도 똑같이 gradient descent를 돌리자!!!
h, parameters, J를 정리하면 위와 같고,
그에 따라 gradient descent를 돌리게 될 식은 마지막 식과 같다.
단, x나 세타를 일일이 나열하는 건 초딩표기!!!!
우린 행렬과 벡터를 배웠다! 이공계열 대학생이라면, 벡터 표기법에 익숙해지자.
(즉, J(쎄타0, 쎼타1, 쎼타2, ..., 쎄타n) 같은 걸 J(쎄타)로 표기하는 데에 익숙해져야 한다.)
좌측이 일변수 선형 회귀, 우측이 다변수 선형 회귀의 gradient descent 점화식이다.
여기서 이미 편미분된 J가 들어가있다는 것에 집중하자.
또한, j = 1인 경우, x_0^(i)가 오른쪽에 삐져나와있지만, 저 값은 어차피 1이라는 것도 확인해 두자.
피쳐 스케일링(Feature scailing)
여기서부터는 feature의 종류가 늘어나면서 생기게 되는 문제이다.
여러 feature 들 중, 어떤 한 feature만 그 값이 매우 높을 수도 있다.
예를 들어, house pricing problem에서 number of rooms값에 비해 size(feet) 값이 훨씬 더 높을 수 있다는 자명하지 않은가? (물론 price의 기준을 밀리언 달러로 놓는다던지 할 수도 있지만 일단 느낌만 가져가자.)
즉, 어떤 feature이 다른 feature에 비해 range가 과도하게 클 수 있다는 것이다.
그럼 이게 무슨 문제라는 걸까?
편의를 위해 n=2인 경우를 보면, 위 사진의 좌측 그래프처럼 J 그래프가 그려질 것이다. (J 그래프가 z축 즉 모니터를 뚫는 방향으로 그려진다고 생각하자.)
아마 옆에서 보면 넓게 퍼진 종 모양의 (즉, 분산이 매우 큰 정규분포와 비슷한 꼴의) 그래프이다.
스케일링을 해야 하는 이
근데, 여기서 간과하기 쉬운 부분이 있다.
왜 x1의 range가 x2의 range보다 훨씬 큰데 (2000 > 5)
parameter은 반대로 쎼타2의 range가 쎄타1의 range보다 더 크게 그려진 것일까??
그 이유는 수학적으로 보면 당연히 (x1, x2)의 자취가 기울기가 1보다 작은 꼴의 형태로 점이 찍힐 것이기 때문에, error가 최소화 되는 J값이 저 곳에 찍히는 건 당연하다. 또한 error들도 기울기인 쎄타1의 변화에는 민감해서 쎄타1이 조금만 변해도 확확 J값이 커지고 작아지지만, 쎄타2의 변화에는 덜 민감해서 쎄타2가 쎄타1이랑 똑같은 만큼 커진다 해도 J값은 덜 커진다.
이렇게 될 경우, 예를 들어 쎄타1 및 쎄타0 = 1인경우 즉 h = x1 + x2인 경우를 보자.
이 때, x1과 x2의 range가 아까와 같다고 하면, x1이 error값( |y - y-hat| )이 더 클 확률이 높지 않은가?
나는 의도치 않았지만 x1에 큰 weight를 준 꼴이고, x1의 값이 결과인 집값에 더 영향을 많이 끼치게 된다.
(이 결과에 영향을 더 많이 끼친다는 것이, 위에 수학적으로 설명한 '민감하다'와 일치한다.)
근데 집의 size(feet)이 크다고 무조건 비싼 집인가?? price가 무조건 높아지나??
나는 그렇게 weight를 부여할 생각이 없었다!! 그렇기에 그 weight를 없애주어야 한다!!
예를 들어, 쎼타1x1 + x2 = h(집값) 이라고 하고, x1 = 2000, x2 = 3이라 하면, 당연히 쎼타1에 1000와 같은 수로 나누던가 해서 weight를 없애려고 노력해야 한다.
그래서 우리는 그 의도치 않은 weight를 없애는 방식으로 scailing을 사용할 것이다.
어쨌든간에, 그래서 어떤 parameter가 다른 parameter들 보다 range가 더 크다고 해서 그게 뭐 대수냐?
gradient descent를 했을 때 global minimum으로 도달하기까지 더 긴 시간과 더 많은 steps를 거쳐야 할 가능성이 커지게 되기에 문제이다.
단순히 봐도 이동해야 할 거리 자체가 늘어나지 않았는가.
그래서 우리는 scailing을 해서 저 feature 들의 값의 range를 어느 정도 평탄화해줄 것이다.
(여기서 scailing을 해야 하는 이유를
1) weight 삭제,
2) gradient descent 속도 상승
이 두 가지 이유를 들어서 설명했는데, 여러 문서를 참고한 결과, 두 가지 다 주된 이유는 맞으나 1번이 좀 더 general한 이유인 것 같다.
https://en.wikipedia.org/wiki/Feature_scaling위키 참고.)
+) 확실히 하기 위해 GPT의 답변도 첨부한다.
가장 간단하게 생각해 볼 수 있는 방식으로는 각 feature의 분모를 range로 나누어 주는 것이다. 이러면 각 feature의 범위가 0부터 1로 제한되면서 parameter의 값들 또한 비슷하게 된다.
여기서 정규화와 표준화를 헷갈리지 말자!!
정규화는 데이터를 특정 범 사이의 값으로 변환하는 방법으로, 분모에 'range'가 들어간다.
표준화는 데이터를 평균이 0이고 표준편차가 1인 정규 분포 형태로 변환하는 방법으로, 분모에 '표준 편차'가 들어간다.
(스케일링은 데이터를 일정한 범위나 분포로 변환하는 과정이라고 볼 수 있는데, 여기서 '일정한 범위'가 정규화, '일정한 분포'가 표준화라고 볼 수도 있겠다.)
정규화는 상한과 하한이 0~1 또는 0 주위 값이지만,
표준화는 상한과 하한이 min과 max 값의 표준화 값에 의존한다는 것도 생각하자.
**여기서 GPT가 잘못 알려준 부분이 있다!!
데이터의 중앙값이 0이 아니라, 데이터의 평균이 0이 되게 만드는 거다.
평균 정규화를 한 후의 데이터들의 평균은 무조건 0임.
GPT를 통해 정리해 본 바는 위와 같으며, 여러 문서들로 검증했을 때 맞는 내용으로 보인다.
또한 여기서 Mean Normalization은 정규화된 후의 데이터의 범위가 꼭 -0.5~0.5는 아닌 것으로 보인다.
1, 1, 1, 1, 10 같은 사례의 경우 -0.2~0.8 같이 될 수가 있는 점 알아두자.
스케일링 실제 예시
위 두 장으로 간단한 예시를 살펴볼 수 있다.
보통 피쳐 스케일링의 결과로 각 피쳐가 대략 -1~1 사이 범위를 가지는 게 가장 좋으나,
어느 정도 허용 범위는 있다.
만약 내가 -1 ~ 1의 범위를 간주하고 스케일링을 한다고 하면,
x1나 x2정도의 범위는 수용할 만 하다 보고 스케일링을 하지 않을 수 있으나
x3, x4, x5 같은 경우는 범위가 너무 기준에서 벗어나니 스케일링 또는 리스케일링이 필요할 것이다.
여기서, Z-score standardization을 Z-score normalization이라고도 부르는 문서들이 있어서,
뭐지? 표준화가 정규화의 일종인가...? 싶었지만
GPT 답변과 여러 검색들을 통해 그냥 표기의 차이인 것 같다.
https://sebastianraschka.com/Articles/2014_about_feature_scaling.html#about-standardization
보면 위 문서의 글에서도 Z-score standardization와 Z-score normalization을 혼동해서 쓰며 똑같이 standardization을 뜻하고 있다.
근데, 어떤 문서들은 표준화(즉, Z-score normalization)를 정규화의 종류 중 하나로 보기도 하는데
뭐, 어차피 scailing의 기법들인 건 같으니까 크게 내가 신경쓸 건 없어 보인다. 이정도로 알고 넘어가자구~@~@@
배포할 때도 스케일링을 고려해야함!!
스케일링은 학습뿐만 아니라 실사용에서도 해야 한다.
예를 들어, x1은 0~2000의 range인데, 스케일링 후의 범위가 당연히 다를 것이다.
근데, (학습 이후) 내가 실제로 모델을 돌려서 사용할 건데, input에 똑같이 x1의 값 중 하나를 넣으면, ㅈㅈ!!
막 1420 이런 거 넣으면 안된다고!!
예를 들어 min-max normalization 으로 x1을 0~1 사이 값으로 만들어줬으면 내가 넣을 때도 그 사이 값을 넣어줘야지.
즉, model deploy(모델 배포) 때는 우리가 쓴 scailing에 대한 정보들도 포함해서 배포해야 한다!!
Learning rate a(alpha)에 대한 못 다한 이야기들
이 부분이 여러 정보들이 다 들어가 있어서 좀 어려울 수 있다... 잘 따라와주길 바란다.
우선, 그래프를 보면 x축 y축 변수가 뭔지 보는 건 기본!!
x축이 반복 횟수 -> 즉, x축 값이 1 커질 때마다, (batch) gradient descent를 1번 완료한 것임.
(다르게 말하면, n개의 features에 대한 j를 이용한 반복문을 끝낸 후, 다시 모든 data set을 표현한 i에 대한 반복문을 끝내면, 그제서야 x축 값이 1 커지는 거임.)
manifold graph 관점에선, x축 값이 1 커질 때마다 gradient descent의 step이 한 번 진행된, 그러니까 한 번 폴짝 움직인 것이다.
a1 > a2 > a3인 a와 와 매우 큰 값의 a에 대해, (alpha를 a라 표현하겠다.) a 값에 따라 그래프가 왜 저런 식으로 그려질까 모르겠다면, 이전 글을 참고하자!! 여기선 다 설명하진 않겠다.
다만, 반복 횟수가 일정 이상 됐을 때, a1이 a3보다 같은 반복 횟수 대비 J값이 더 크다고 무조건 단정지을 순 없다. 사실 저부분은 어떻게 그려질 지 예상하기 힘들다.
그러나 a가 어느 정도 크면 위처럼 특정 점에서 막 내려가거나 올라가거나 하는 게 아니라 일정 J값 라인에서 왔다갔다 하는 상황이 발생할 수 있어 수렴이 더 느려질 순 있다.
(그냥 참고로 알아두자 ㅎㅎ 쓸모는 딱히 없을듯? 아마두...)
어쨌거나, J값이 한 번 반복당 10^(-3) (즉, 1/1000) 보다 적은 값이 감소하면, 수렴했다고 결정한다고 한다.
다만 저번 글에서 적었다시피, 일정 값 이하가 수렴이라고 하기 보단 max iteration을 정해 주면 더 성능이 좋아지거나 할 수도 있기에, 경험에 따라 iteration의 endpoint를 모델러가 적절히 결정해야 할 것이다.
헷갈리면 안되는게, 위 그림에서 오른쪽 그래프는 (대부분의 경우) 우리가 그리지 못하는 그래프다!!
우리는 실제 측정을 통해 왼쪽 그래프만을 얻을 수 있을 뿐이다.
보면 왼쪽 그래프들은 x축이 아까와 같은 반복 횟수이고,
오른쪽 그래프는 x축이 쎄타임을 주목하자.
우리가 오른쪽 그래프를 그릴 수 있으면, 애초에 머신 러닝을 학습시킬 필요가 없다!!
그냥 J의 global minimum 콕 찍은다음에 거기 parameter값 읽으면 되지 않는가 ㅋㅋ
그걸 모르니까 왼쪽처럼 프로그래밍 해서 반복문을 돌려서 J값의 최소값을 찾는 것 아니겠나~~
다시 강조한다. 오른쪽 그래프는 일반적으로 우리가 그릴 수 없는 그래프다.
만약 우리가 그릴 수 있었다면, 애초에 머신러닝으로 풀 필요조차 없는 문제인 것이다.
여기서, a값이 많이 크면 왼쪽 위처럼 폭증할 수도 있긴 한데...
보통 저런 경우는 내가 코드 잘못짜서 버그가 일어난 경우가 대부분이다.
예를 들어 gradient descent 식에서 - 부호 대신 + 부호를 썼다던지...ㅋㅋ
어쨌거나, 왼쪽처럼 그래프가 나온다면 (버그가 없단 가정 하에) a값이 많이 큰 것이니 a값을 작게 조정해주면 될 것이다.
만약 오른쪽처럼 J의 그래프 형태를 우리가 알고 있다고 가정하면, a가 클 경우 저런 식으로 J가 overshooting 하다가 다시 수렴하다... 봉우리를 넘고 넘다보면 왼쪽 아래같은 그래프가 나올 수도 있는 것이다. 이럴 때도 a값을 줄여주면 된다.
단, a값을 너무 많이 줄일 경우 알다시피 수렴 속도가 많이 느려질 수 있다. 우리의 자원과 시간은 무한이 아니다!!
그렇기 때문에, 저번 글에서 언급했듯이 처음엔 a를 큰 값을 주고, 나중으로 갈 수록 a값을 점점 줄여나가는 방식이 선호된다 한다.
이렇게 비교해 볼 수도 있다.
(물론 꼭 a가 크다고 저렇게 된다는 것도 아니다. 상황에 따라 다른 것!!)
큰 a, 작은 a, 적당한 a????
그래, 그래, 알겠어.
a의 크기에 따라 반복문-J값 그래프가 다르게 그려질 수 있단 거 알겠어.
그래서, a가 크고 작다의 기준이 뭔데???
=> 그 기준은 대략적으로 아래와 같다.
대략적으로 저렇게 10의 마이너스 승의 수들을 사용한다.
..., 0.001, 0.01, 0.1, 1, ...
다만, 일반적으로 a가 0.1만 돼도 크다고 여기고, a에 1은 거의 안 쓴다고 한다.
대략 0.01 정도의 값이 a값의 표준 정도 되는 것 같으며
꼭 10단위로 쓰진 않고, 중간에 보다시피 3을 곱한다던지 하는 식으로 그 도메인에 특화된 a값을 넣어볼 수 있다.
(그러다 그게 맞으면 논문 나오고 그게 표준 되고 그런다함)
물론 이것도 data set의 features range나 그런 것들에 따라 달라질 수 있다!!
하지만, scailing을 통해 각 features의 range 라던지 (표준화를 할 경우) 평균이나 표준편차 라던지 같은 것들을 어느 정도 맞춰줬기 때문에,
대략적으로나마 저런 a값에 대한 기준을 잡을 수 있는 것이다.
=> 저기서 무슨 a를 먼저 넣냐 이런 것도 결국 모델러의 역량!! 경험이 중요하다. 그래서 돈주고 사람 쓰는 거 아니겠냥 ㅋㅋㅋㅋ
그래서, 만약 내가 a1 = 0.01, a2 = 0.1, a3 = 1이라는 3개의 learning mate를 갖고 똑같은 data set에 대한 gradient descent를 돌려봤을 때,
A, B, C 각각 어떤 learning mate를 사용한 결과일 확률이 높을까??
답은 순서대로 0.1, 0.01, 1이다.
왜 그런지는 각자 생각해보길 바란다. (잘 이해가 안 되면 댓글 주세요!!)
Features and polynomial regression
우리가 지금까지 대표 예시로 들먹인 house pricing 문제에서 '집 크기'는 '면적'을 feature로 썼는데, 사실 면적 이라는 하나의 feature만 써도 되지만 가로 vs 세로 이렇게 2개의 feature로 나눌 수도 있음.
뭐, 어찌됐든간에 '크기(즉, 집 면적)' 이라는 하나의 feature에 따른 h를 생각해보자. 우리가 지금까지 배운 거에 따르면 이는 h = 쎄타0 + 쎄타1*x 꼴이 나올 거임. 이건 하나의 직선인데, 실제 찍힌 점(가격)을 직선 형태로 예측하기에는 underfitting이 발생한다!! 내 h가 너무 단순함...
이 때, x를 polynomial 형태로 반복해서 쓰면 식이 2차, 3차 E와 같은 그래프를 그릴 수 있음.
여기선 2차를 쓰면 언젠가 집값이 떨어지게 예측할 텐데, 이건 실제와 맞지 않음.(면적이 커지면 집값은 작아져선 안됨.) 그래서 3차를 쓰면 면적에 비해 갑자기 집값이 빠르게 늘어남.
이 예시의 경우는, 위와 같은 h를 사용하면 h가 적당히 늘어나게 돼서 fit함.
polynomial 기법은 dimension을 높이는 게 아니라, 그냥 차수를 늘린 것임. 우리가 원래 가지고 있는 observation의 dimension을 뻥튀기하는 느낌.
dimension이 늘어나면 기본적으로 문제 해결이 쉬워짐. 예를 들어, 손과 지우개의 위치 분리 3D 모델의 경우 손과 지우개의 z축 거리라는 차원이 생긴다면, 2차원에 비해 해결이 쉽지. 가장 좋은 건 그냥 observation(dimension)을 ㅈㄴ게 늘리는 거임. ex. 온도 만으로 예측이 안되면 습도, 고도, 산소농도 등등 그냥 다 추가해버려~~~
=> but, dimension이 오르면 금액, 시간, training data가 더 많이 필요하게 됨(차원의 저주). 또한 overfitting 문제가 생길 수도 있음.
이론상으론 poly을 계속 늘려가면 error을 0으로 줄일 수 있음. 3차 해서 안되면 4차, 5차, ... data set이 100개면, 100차 h를 써버리면 error을 0으로 만들 수 있음. 근데 그럼 위의 문제와 같이 안좋아짐.
Normal equation
우리가 푸는 간단한 형태들은 gradient descent 안 쓰고도 그냥 normal equation(method 이름)으로 해결 가능함. dimension이 작고 training data 수가 적으면 N.E.가 쓸만함. 그러나, 그 반대의 경우 훨씬 느려지니 gradient descent 쓰는 게 나음.
쎄타의 값을 유사역행렬을 써서 직접 구해버리므로.
** 스도인버스 구하는 과정은 생략.
결국 아래와 같은 스도인버스 행렬이 나옴. 쎄타가 우리가 원하던 파라미터.
여기서, 우리 강의노트에는 m 크기에 따라선 뭘 선택할 지 영향을 안받도록 나와있지만, 실제로는 m이 크면 N.E. 쪽이 좀 더 불리. 사실 n(dimension)이 커지면 m 개수도 커져야하기 때문에, 결국 따라오는 문제라고 보면됨.
G.D. : m이 크던, n이 크던 좀 느려지긴 하지만 잘 작동함. 그러나 n이 작으면 비교적 느리고, starting point에 따라 random한 결과가 나올 수 있음.반복 사용.
N.E. : n이 작으면 잘 작동하나 n이 커지(고 m이 커지)면 시간이 많이 오래 걸리게 됨. 반복 사용x -> 한 cue에 결과가 나옴. 또한, 항상 같은 정해진 결과가 나옴. (사실, 실제 코드 구현에서는 dimension이 올라가면 최적의 해를 위해 iteration이 있긴 하나, 이론적으론 반복이 없다.)
현실의 머신러닝 모델들은 n이 크기 때문에 오른쪽께 현실에선 최소 100배는 느릴 거임. 근데 양자 컴퓨터 개발되면 바로 후자 가면됨 ㅎㅎ
여기서, m이 크냐 n이 크냐에 따라 좀 다른데, m > n이면 left inverse, m < n 이면 right inverse를 사용하면 좋음.
m > n인 경우는 얼굴 인식이 있을 수 있음. 인스타가서 사진만 쫙 크롤링해도 됨. data set이 ㅈㄴ 많음.
m < n인 경우는 의료 비전이 있음. 아님 tv에서 불량 해상도 탐지 같은 경우도 있음.
(현실에서 m = n인 square matrix는 거의 x)
'AI > 머신러닝(코세라)' 카테고리의 다른 글
[ML] #6 신경망(Neural Networks) (0) | 2024.10.15 |
---|---|
[ML] #5 정규화(Regularization) (0) | 2024.10.15 |
[ML] #4 로지스틱 회귀(Logistic Regression) (0) | 2024.10.14 |
[ML] #2 일변수 선형 회귀(Linear Regression with One Variable) (0) | 2024.09.19 |
[ML] #1 머신러닝 개론(Introduction to Machine Learning) (0) | 2024.09.19 |