아직 우리는 인공신경망에서 가중치를 어떻게 업데이트해야 하는가의 핵심적인 질문에 답하지 않았습니다. 지금가지의 고정은 이에 대한 답을 하기 위한 과정이었으며 이제 거의 다 왔습니다. 이 비밀을 풀기 위해 반드시 이해해야 할 핵심 아이디어 한 가지만 더 이해하면 됩니다!
지금까지는 네트워크의 각 계층에 걸쳐 역전파되는 오차를 구해봤습니다. 이처럼 오차를 구하는 이유는 인공 신경망이 보다 나은 답을 출력하게 하기 위해 가중치를 조정해가는 데 지침 역할 을 하는 것이 오차이기 때문입니다. 이러한 과정은 이 책의 앞 부분에 나왔던 선형 분류자 예제에서부터 우리가 보아왔던 것입니다.
하지만 신경망에서 노드는 단순한 선형 분류자가 아닙니다. 노드는 입력되는 신호에 가중치를 적용한 후 이의 합을 구하고 다시 여기에 시그모이드 활성화 함수를 적용하는 식으로 좀 더 복잡한 구조를 가집니다. 그렇다면 이처럼 정교한 노드 사이를 연결하는 연결 노드의 가중치를 어떻게 업데이트해야 할까요? 우리는 왜 어떤 끝내주는 대수학공식을 이용해 가중치를 단번에 구해낼 수 없는 것일까요?
- 가중치 계산
신경망에는 너무나도 많은 가중치의 조합이 존재합니다. 또한 신호가 여러 개의 계층을 타고 전파되어나갈 때 한 계층을 거칠 때마다 직전 계층의 출력 값이 다음 계층의 입력값이 되므로 함수의 함수,ㅡ 함수의 함수의 함수...같은 식으로 수많은 함수의 조합이 필요하게 됩니다. 따라서 수학 연산의 과정이 너무 복잡하게 되므로 가중치를 한 방에 풀어주는 대수학을 활용할 수 없는 것입니다.
2018년 4월 1일 일요일
CHAPTER 13 행렬곱을 이용한 오차의 연전파
우리는 앞 장에서 실제 숫자를 대입해 역전파를 이해하고자 했습니다. 하지만 실제 역전파는 매우 복잡하겠죠? 그렇다면 우리는 역전파에도 행렬곱을 이용할 수 있을까요? 기억하겠지만 우리는 이미 9장에서 앞쪽으로 전파법에 대해 행렬곱으로 계산한 바 있습니다.
이번에는 오차의 역전파를 행렬곱으로 간결하게 만들 수 있는지 보기 위해서 단계별 기호를 이용해 적어보겠습니다. 이렇게 행렬곱으로 표현하는 방식을 벡터화한다(vectorize)라고 합니다.
수많은 연산을 행렬의 형태로 표현하게 되면 우리가 손으로 쓰기에도 편하지만 무엇보다도 컴퓨터가 반복적인 유사한 연산을 순식간에 처리할 수 있게 되므로 훨씬 더 효율적으로 작업을 수행할 수 있다는 장점을 가지게 됩니다.
최종 출력 계층으로 부터 나오는 오차로부터 시작해보겠습니다. 출력 계층에 2개의 노등가 있는 예제를 보고 있었으니 여기에서의 오차는 다음과 같이 표현할 수 있습니다.
error(output) = ( e1, e2)
다음으로는 은닉계층의 오차를 행렬로 구성해보겠습니다. 어렵게 느껴질 수 있으니 단계별로 차근차근 보겠습니다. 우선 은닉 계층의 첫 번째 노드부터 보겠습니다. 앞장의 그림을 다시 보면 은닉 계층의 첫 번째 노드의 오차에 영향을 주는 것은 출력 계층으로 부터의 2개의 경로임을 확인할 수 있습니다. 이 2개의 경로를 통해 전달되는 오차 신호는 각각 e1 * w11 /(w11 + w21)과 e2 * w12/(w12 + w22)입니다. 은닉 계층의 두 번째 노드는 마찬가지로 각각 e1 * w21 /(w21 + w11)과 e2 * w22 /(w22 + w12)가 됩니다. 만약 이 식이 혼동이 되는 분은 반드시 12장을 다시 한번 학습하고 돌아오기 바랍니다.
그렇다면 이제 은닉 계층의 오류를 다음과 같이 행렬로 표현할 수 있습니다.
이 행렬을 보다 간결하게 행렬곱으로 다시 쓸 수 있다면 좋을 것 같ㅅ브니다. 마치 전파법에서 봤던 것 처럼 말입니다.
하지만 안타깝게도 전파법에서 봤던 수준으로 간결하게 이 행렬을 다시 쓸 수는 없습니다. 위의 복잡한 수식을 풀어내기가 쉽지는 않기 때문입니다. 그렇다면 어떻게 해야 할까요? 정말 간결하게 쓰고 싶기는 한데 말입니다.
위의 수식을 다시 봅시다. 이 수식에서 핵심은 출력 오차인 en과 가중치 wij의 곱셈 연산입니다. 가중치가 크면 클수록 더 많은 출력 오차가 은닉계층으로 돌아오게 됩니다. 이것이 핵심입니다. 분수에서 분모 부분은 일정의 정규화 인자(nomalizing factor)라고 할 수 있습니다. 만약 정규화 인자를 무시한다고 해도 우리는 되돌아오는 오창의 일정 비율 정도를 잃을 뿐입니다. 따라서 e1 * w11/(w11+w21)을 간단하게 e1 * w11로 표현해도 되는 것입니다.
가중치 행렬은 우리가 8장에서 만들었던 행렬과 유사해 보이지만 자세히 보면 대각선 방향으로 원소가 뒤바뀐 것을 알 수 있습니다. 즉 우측 상단의 가중치와 좌측 하단의가중치가 바뀌어 있습니다. 이처럼 핻렬릐 행과 열을 바꾸는 것을 전치(transpose)한다고 부르며, 행렬 w의 전치 행렬을 기호로는 wt라고 표기합니다.
다음 그림에서 전치 행렬의 두 가지 예를 보겠습니다. 전치 행렬은 행과 열의 개수가 다른 경우에도 가능함을 이해하기 바랍니다.
이제 다음과 같이 오차의 역전파를 행렬로 간결하게 표현할 수 있게 되었습니다.
error(hidden) = wt(hidden_output) * error(output)
간결하게 표현해서 좋기는 하지만 정규화 인자를 생략했다는 점이 마음에 걸립니다. 이렇게 생각해 버려도 괜찮은 것일까요? 결론부터 말하면 이처럼 오차 신호의 피드백을 단순화하더라도 정규화 인자가 있을 때와 마찬가지로 잘 동작한다는 사실이 밝혀져 있습니다. 오차를 역전파하는 몇 가지 방ㅂ버을 비굑한 결과를 블로그에 올렸으니 관심 있는 분들은 참고하기 바랍니다(http://bit.ly/2m2z2YY). 간결한 방식이 문제 없이 작동한다면. 더 어려운 방법을 쓸 필요는 없겠죠!
이점에 대해 조금 더 말하면, 설령 다소 크거나 작은 오차가 역전파되었다고 하더라도 우리의 인공 신경망은 다음 학습 단계에서 이를 스스로 바로 잡아갑니다.
오차에 대한 책임을 분산시키는 데 지침이 되는 것은 가중치의 크기이므로 역전파되는 오차가 연결 노드의 가중치의 크기를 중시한다는 점이 핵심입니다.
지금까지 정말 많은 것을 학습하느라 고생 많으셨습니다. 이론과 관련한 마지막 장이 될 다음 장으로 넘어가기 전에 잠깐 쉬어도 좋을 것 같습니다. 다음 장은 정말 멋지지만 살짝 골치 아픈 내용을 다루기 때문입니다.
핵심 정리
- 오차의 역전파를 행렬곱으로 표현할 수 있습니다.
- 오차의 역전파를 행렬곱으로 표현함으로써 우리는 네트워크의 크기에 상관없이 이를 간결하게 표현할 수 있으며, 컴퓨터를 통해 보다 효율적이고 빠르게 업무를 처리하게 할 수 있습니다.
- 이제 우리는 전파법과 역전파 모두 행렬곱을 통해 효율적으로 처리할 수 있다는 사실을 알게 되었습니다.
이번에는 오차의 역전파를 행렬곱으로 간결하게 만들 수 있는지 보기 위해서 단계별 기호를 이용해 적어보겠습니다. 이렇게 행렬곱으로 표현하는 방식을 벡터화한다(vectorize)라고 합니다.
수많은 연산을 행렬의 형태로 표현하게 되면 우리가 손으로 쓰기에도 편하지만 무엇보다도 컴퓨터가 반복적인 유사한 연산을 순식간에 처리할 수 있게 되므로 훨씬 더 효율적으로 작업을 수행할 수 있다는 장점을 가지게 됩니다.
최종 출력 계층으로 부터 나오는 오차로부터 시작해보겠습니다. 출력 계층에 2개의 노등가 있는 예제를 보고 있었으니 여기에서의 오차는 다음과 같이 표현할 수 있습니다.
error(output) = ( e1, e2)
다음으로는 은닉계층의 오차를 행렬로 구성해보겠습니다. 어렵게 느껴질 수 있으니 단계별로 차근차근 보겠습니다. 우선 은닉 계층의 첫 번째 노드부터 보겠습니다. 앞장의 그림을 다시 보면 은닉 계층의 첫 번째 노드의 오차에 영향을 주는 것은 출력 계층으로 부터의 2개의 경로임을 확인할 수 있습니다. 이 2개의 경로를 통해 전달되는 오차 신호는 각각 e1 * w11 /(w11 + w21)과 e2 * w12/(w12 + w22)입니다. 은닉 계층의 두 번째 노드는 마찬가지로 각각 e1 * w21 /(w21 + w11)과 e2 * w22 /(w22 + w12)가 됩니다. 만약 이 식이 혼동이 되는 분은 반드시 12장을 다시 한번 학습하고 돌아오기 바랍니다.
그렇다면 이제 은닉 계층의 오류를 다음과 같이 행렬로 표현할 수 있습니다.
이 행렬을 보다 간결하게 행렬곱으로 다시 쓸 수 있다면 좋을 것 같ㅅ브니다. 마치 전파법에서 봤던 것 처럼 말입니다.
하지만 안타깝게도 전파법에서 봤던 수준으로 간결하게 이 행렬을 다시 쓸 수는 없습니다. 위의 복잡한 수식을 풀어내기가 쉽지는 않기 때문입니다. 그렇다면 어떻게 해야 할까요? 정말 간결하게 쓰고 싶기는 한데 말입니다.
위의 수식을 다시 봅시다. 이 수식에서 핵심은 출력 오차인 en과 가중치 wij의 곱셈 연산입니다. 가중치가 크면 클수록 더 많은 출력 오차가 은닉계층으로 돌아오게 됩니다. 이것이 핵심입니다. 분수에서 분모 부분은 일정의 정규화 인자(nomalizing factor)라고 할 수 있습니다. 만약 정규화 인자를 무시한다고 해도 우리는 되돌아오는 오창의 일정 비율 정도를 잃을 뿐입니다. 따라서 e1 * w11/(w11+w21)을 간단하게 e1 * w11로 표현해도 되는 것입니다.
가중치 행렬은 우리가 8장에서 만들었던 행렬과 유사해 보이지만 자세히 보면 대각선 방향으로 원소가 뒤바뀐 것을 알 수 있습니다. 즉 우측 상단의 가중치와 좌측 하단의가중치가 바뀌어 있습니다. 이처럼 핻렬릐 행과 열을 바꾸는 것을 전치(transpose)한다고 부르며, 행렬 w의 전치 행렬을 기호로는 wt라고 표기합니다.
다음 그림에서 전치 행렬의 두 가지 예를 보겠습니다. 전치 행렬은 행과 열의 개수가 다른 경우에도 가능함을 이해하기 바랍니다.
이제 다음과 같이 오차의 역전파를 행렬로 간결하게 표현할 수 있게 되었습니다.
error(hidden) = wt(hidden_output) * error(output)
간결하게 표현해서 좋기는 하지만 정규화 인자를 생략했다는 점이 마음에 걸립니다. 이렇게 생각해 버려도 괜찮은 것일까요? 결론부터 말하면 이처럼 오차 신호의 피드백을 단순화하더라도 정규화 인자가 있을 때와 마찬가지로 잘 동작한다는 사실이 밝혀져 있습니다. 오차를 역전파하는 몇 가지 방ㅂ버을 비굑한 결과를 블로그에 올렸으니 관심 있는 분들은 참고하기 바랍니다(http://bit.ly/2m2z2YY). 간결한 방식이 문제 없이 작동한다면. 더 어려운 방법을 쓸 필요는 없겠죠!
이점에 대해 조금 더 말하면, 설령 다소 크거나 작은 오차가 역전파되었다고 하더라도 우리의 인공 신경망은 다음 학습 단계에서 이를 스스로 바로 잡아갑니다.
오차에 대한 책임을 분산시키는 데 지침이 되는 것은 가중치의 크기이므로 역전파되는 오차가 연결 노드의 가중치의 크기를 중시한다는 점이 핵심입니다.
지금까지 정말 많은 것을 학습하느라 고생 많으셨습니다. 이론과 관련한 마지막 장이 될 다음 장으로 넘어가기 전에 잠깐 쉬어도 좋을 것 같습니다. 다음 장은 정말 멋지지만 살짝 골치 아픈 내용을 다루기 때문입니다.
핵심 정리
- 오차의 역전파를 행렬곱으로 표현할 수 있습니다.
- 오차의 역전파를 행렬곱으로 표현함으로써 우리는 네트워크의 크기에 상관없이 이를 간결하게 표현할 수 있으며, 컴퓨터를 통해 보다 효율적이고 빠르게 업무를 처리하게 할 수 있습니다.
- 이제 우리는 전파법과 역전파 모두 행렬곱을 통해 효율적으로 처리할 수 있다는 사실을 알게 되었습니다.
2018년 3월 27일 화요일
laradock on mac
mysql bash -> hostname -I
.env DB_HOST SETTING
php artisan make:auth
php artisan migrate
CHAPTER12 다중 계층에서의 오차의 역전파
다음은 3개 계층(입력 계층, 은닉 계층, 출력 계층)으로 구성된 간단한 신경망입니다.
입력 입력계층 은닉계층 출력계층 출력
---> (1) ---> (1) ------> (1) ---->
오른쪽 끝의 최종 출력 계층부터 보겠습니다. 출력 계층의 오차를 이용해 출력 계층의 연결된 노드들의 가중치를 업데이트하게 됩니다. 이를 조금 더 일반화해보면 출력 계층의 오차는 e(output)으로, 여기에서는 가중치 who로 표현할 수 있습니다. 물론 e(output)은 가중치 비율에 따라 나뉘어 전달될 것입니다.
이렇게 시각화해봄으로써우리는 새로 추가된 계층에 대해 어떻게 하면 좋을지 감을 잡을 수 있을 것 같습니다. 즉 은닉 계층의 노드으 ㅣ출력 값과 관련된 오차를 e(hidden)이라고 하고 이 오차를 입력 계층과 은닉계층을 연결하는 가중치 wih에 대해 그 비율에 맞게 나누어 주면 되는 것입니다. 다음 그림에 이를 표현햅습니다.
만약 계층이 더 많이 있다면 이처럼 최종 출력 꼐층으로부터 역방향으로 동일한 과정을 반복하면 될 것입니다. 이처럼 오차 관련 정보가 뒤쪽으로 계속해서 전파되므로 역전파라고 부르는 것입니다.
출력 계층의 경우에는 출력 계층의 노드의 결과 값의 오차인 e(output)을 사용했지만, 은닉 계층의 노드에서 e(hidden)은 어떤 오차 값으 ㄹ사용하면 될까요? 만약 이런 의문이 들었다면 지금까지의 내용을 제대로 이해하고 있는 것이라고 보룻 었을 것 같습니다. 중간에 위치하는 은닉 계층은 사실 명백한 오차를 가지고 있지 않기 때문입니다. 앞에서 배웠던 내요을 다시 상기해볼까요? 은닉 계층의 각각의 노드는 직전 계층으로부터 입력을 받아 적절한 출력값을 다음 계층으로 전달하게 됩니다. 이때 이 출력 값이란 직전 계층의 입력 값에 가중치를 적용한 다음이를 모두 더한 값에 활성화 함수를 적용한 값입니다. 그럼 도대체 어떻게 오차를 구해낼 수 있는 것일까요?
은닉 노드에 대해서는 목표로 하는 출력 값이 없습니다. 오직 최종 출려 ㄱ계층의 노드만이 학습데이터로부터 얻은 실제값, 즉 목표로 하는 출력 값을 가지고 있다는 것이죠. 앞으로 그림을 보면 다시 한번 생각해보기 바랍니다. 은닉 계층의 첫 번째 노드는 2개의 연결 노드를 가지는데 이들은 출력 계층의 2개의 노드로 각각 연결됩니다. 그리고 우리는 출력 계층의 노드에서의 오차를 이 연결 노드에 나누어줄 수 있다는 점을 알고 있습니다. 이 말은 결국 중간의 은닉 계층의 노드로부터 오는 2개의 연결 노드 각각에 대해 어떤 오차가 존재한다느 말입니다. 우리는 이러한 2개의 연결노드의 오차를 재조합함으로써 은닉 계층의 노드의 에러로 사용할 수 있습니다. 즉 중간 계층의 노드는 목표로 하는 출력 값을 가지지 않기 때문에 이처럼 차선의 방법을 사용하는 것입니다. 이와 같은 아이디어를 다음 그림에 표현해봤습니다.
그림을 보면 좀 더 명확해질 것입니다. 우리에게 필요한 것은 은닉 계층의 노드들에 대한 오차입니다. 이 오차를 이용해 직전 계층과의 연결 노드에 존재하는 가중치를 업데이트할 것이기 때문입니다. 은닉 계층의 노드의 오차를 e(hidden)이라고 하겠습니다. 아직까지 우리는 실제 이 오차의 값이 얼마인지에 대한 답을 가지고 있지 않습니다. 그 이유는 (반복해서 말하지만) 학습 데이터로부터 얻을 수 있는 목표 값은 (으닉 계층이 아니라) 오직 최종 출력 계층의 노드에 대한 것이므로, 으닉 계층에서의 오차를 목표 값과 실제 값 간의 차이라고 정의할 수 없기 때문입니다.
학습 데이터들은 최종 노드의 결과 값이 가져야 할 목표 값에 대해서만 말해줍니다. 이 외의 노드들의 결과 값에 대해서는 아무것도 말해주지 않습니다. 이것이 이 퍼즐의 핵심입니다.
우리는 앞에서 본 대로 오직의 역전파를 이용해 연결 노드에 대해 나뉜 오차를 재조합해야 합니다. 따라서 은닉계층의 첫 번째 노드의 오차는 이 은닉계층에서 다음 계층으로 연결되는 모든 연결 노드에 있는 나뉜 오차들의 합이 됩니다. 앞의 그림에서 보면 e(output.1)은 w11과 연결되어 있으면 e(output2)는 w12와 연결되어 있습니다. 이를 수식으로 써보면 다음과 같습니다.
e(hidden1) = 연결 노드 w11, w12로 나뉘어 전달되는 오차의 합
= e(output1) * w11 /(w11 + w21) + e(output2) * w12/(w12 + w22)
수식으로만 보면 이해가 어려울 수 있으니 실제 숫자를 대입해서 보겠습니다. 다음 그림은 오차가 역전파하는 과정을 실제 숫자와 함께 표현한 것입니다.
앞의 그림에서 출력 계층의 첫 번째 노드의 오차 0.8은 이와 연결된 2개의 가중치 2.0과 3.0에 비례해 각각 0.32와 0.48로 나뉘어 전달된다는 것을 확인할 수 있습니다. 출력 계층의 두 번째 노드의 오차 0.5는 연결된 2개의 가중치 1.0과 4.0에 비례해 각각 0.1과 0.4로 나뉩니다. 따라서 은닉 계층의 첫 번째 노드의 오차는 0.32와 0.1의 합인 0.42가 되고 두번 째 노드의 오차는 0.48과 0.4의 합인 0.88이 되는 것입니다.
다음 그림은 한 단계 더 나아가 은닉 계층의 오차 값을 이용해 입력 계층이 오차를 구하는 것을 보여줍니다.
핵심정리
- 인공 신경망에서 학습이란 연결 노드의 가중치를 업데이트하는 과정을 의미합니다. 가중치의 업데이트는 오차에 의해 주도되는데, 오차는 학습데이터로부터 주어진 정답과 출력값 간의 차이를 의미합니다.
- 출력 노드의 오차는 실제 값(정답)과 출력 값 사이의 차이를 의미합니다.
- 중간 계층의 존재하는 노드들의 오차는 명백하지 않습니다. 한 가지 접근 방법은 출력 계층의 노드들의 오차를 이와 연결된 가중치의 크기에 비례해 누눠서 역전파하고 이를 재조합하는 방법입니다.
입력 입력계층 은닉계층 출력계층 출력
---> (1) ---> (1) ------> (1) ---->
오른쪽 끝의 최종 출력 계층부터 보겠습니다. 출력 계층의 오차를 이용해 출력 계층의 연결된 노드들의 가중치를 업데이트하게 됩니다. 이를 조금 더 일반화해보면 출력 계층의 오차는 e(output)으로, 여기에서는 가중치 who로 표현할 수 있습니다. 물론 e(output)은 가중치 비율에 따라 나뉘어 전달될 것입니다.
이렇게 시각화해봄으로써우리는 새로 추가된 계층에 대해 어떻게 하면 좋을지 감을 잡을 수 있을 것 같습니다. 즉 은닉 계층의 노드으 ㅣ출력 값과 관련된 오차를 e(hidden)이라고 하고 이 오차를 입력 계층과 은닉계층을 연결하는 가중치 wih에 대해 그 비율에 맞게 나누어 주면 되는 것입니다. 다음 그림에 이를 표현햅습니다.
만약 계층이 더 많이 있다면 이처럼 최종 출력 꼐층으로부터 역방향으로 동일한 과정을 반복하면 될 것입니다. 이처럼 오차 관련 정보가 뒤쪽으로 계속해서 전파되므로 역전파라고 부르는 것입니다.
출력 계층의 경우에는 출력 계층의 노드의 결과 값의 오차인 e(output)을 사용했지만, 은닉 계층의 노드에서 e(hidden)은 어떤 오차 값으 ㄹ사용하면 될까요? 만약 이런 의문이 들었다면 지금까지의 내용을 제대로 이해하고 있는 것이라고 보룻 었을 것 같습니다. 중간에 위치하는 은닉 계층은 사실 명백한 오차를 가지고 있지 않기 때문입니다. 앞에서 배웠던 내요을 다시 상기해볼까요? 은닉 계층의 각각의 노드는 직전 계층으로부터 입력을 받아 적절한 출력값을 다음 계층으로 전달하게 됩니다. 이때 이 출력 값이란 직전 계층의 입력 값에 가중치를 적용한 다음이를 모두 더한 값에 활성화 함수를 적용한 값입니다. 그럼 도대체 어떻게 오차를 구해낼 수 있는 것일까요?
은닉 노드에 대해서는 목표로 하는 출력 값이 없습니다. 오직 최종 출려 ㄱ계층의 노드만이 학습데이터로부터 얻은 실제값, 즉 목표로 하는 출력 값을 가지고 있다는 것이죠. 앞으로 그림을 보면 다시 한번 생각해보기 바랍니다. 은닉 계층의 첫 번째 노드는 2개의 연결 노드를 가지는데 이들은 출력 계층의 2개의 노드로 각각 연결됩니다. 그리고 우리는 출력 계층의 노드에서의 오차를 이 연결 노드에 나누어줄 수 있다는 점을 알고 있습니다. 이 말은 결국 중간의 은닉 계층의 노드로부터 오는 2개의 연결 노드 각각에 대해 어떤 오차가 존재한다느 말입니다. 우리는 이러한 2개의 연결노드의 오차를 재조합함으로써 은닉 계층의 노드의 에러로 사용할 수 있습니다. 즉 중간 계층의 노드는 목표로 하는 출력 값을 가지지 않기 때문에 이처럼 차선의 방법을 사용하는 것입니다. 이와 같은 아이디어를 다음 그림에 표현해봤습니다.
그림을 보면 좀 더 명확해질 것입니다. 우리에게 필요한 것은 은닉 계층의 노드들에 대한 오차입니다. 이 오차를 이용해 직전 계층과의 연결 노드에 존재하는 가중치를 업데이트할 것이기 때문입니다. 은닉 계층의 노드의 오차를 e(hidden)이라고 하겠습니다. 아직까지 우리는 실제 이 오차의 값이 얼마인지에 대한 답을 가지고 있지 않습니다. 그 이유는 (반복해서 말하지만) 학습 데이터로부터 얻을 수 있는 목표 값은 (으닉 계층이 아니라) 오직 최종 출력 계층의 노드에 대한 것이므로, 으닉 계층에서의 오차를 목표 값과 실제 값 간의 차이라고 정의할 수 없기 때문입니다.
학습 데이터들은 최종 노드의 결과 값이 가져야 할 목표 값에 대해서만 말해줍니다. 이 외의 노드들의 결과 값에 대해서는 아무것도 말해주지 않습니다. 이것이 이 퍼즐의 핵심입니다.
우리는 앞에서 본 대로 오직의 역전파를 이용해 연결 노드에 대해 나뉜 오차를 재조합해야 합니다. 따라서 은닉계층의 첫 번째 노드의 오차는 이 은닉계층에서 다음 계층으로 연결되는 모든 연결 노드에 있는 나뉜 오차들의 합이 됩니다. 앞의 그림에서 보면 e(output.1)은 w11과 연결되어 있으면 e(output2)는 w12와 연결되어 있습니다. 이를 수식으로 써보면 다음과 같습니다.
e(hidden1) = 연결 노드 w11, w12로 나뉘어 전달되는 오차의 합
= e(output1) * w11 /(w11 + w21) + e(output2) * w12/(w12 + w22)
수식으로만 보면 이해가 어려울 수 있으니 실제 숫자를 대입해서 보겠습니다. 다음 그림은 오차가 역전파하는 과정을 실제 숫자와 함께 표현한 것입니다.
앞의 그림에서 출력 계층의 첫 번째 노드의 오차 0.8은 이와 연결된 2개의 가중치 2.0과 3.0에 비례해 각각 0.32와 0.48로 나뉘어 전달된다는 것을 확인할 수 있습니다. 출력 계층의 두 번째 노드의 오차 0.5는 연결된 2개의 가중치 1.0과 4.0에 비례해 각각 0.1과 0.4로 나뉩니다. 따라서 은닉 계층의 첫 번째 노드의 오차는 0.32와 0.1의 합인 0.42가 되고 두번 째 노드의 오차는 0.48과 0.4의 합인 0.88이 되는 것입니다.
다음 그림은 한 단계 더 나아가 은닉 계층의 오차 값을 이용해 입력 계층이 오차를 구하는 것을 보여줍니다.
핵심정리
- 인공 신경망에서 학습이란 연결 노드의 가중치를 업데이트하는 과정을 의미합니다. 가중치의 업데이트는 오차에 의해 주도되는데, 오차는 학습데이터로부터 주어진 정답과 출력값 간의 차이를 의미합니다.
- 출력 노드의 오차는 실제 값(정답)과 출력 값 사이의 차이를 의미합니다.
- 중간 계층의 존재하는 노드들의 오차는 명백하지 않습니다. 한 가지 접근 방법은 출력 계층의 노드들의 오차를 이와 연결된 가중치의 크기에 비례해 누눠서 역전파하고 이를 재조합하는 방법입니다.
2018년 3월 26일 월요일
CHAPTER 11 여러 노드에서의 오차의 역전파
이번에는 2개의 출력 노드를 가지는 그림을 보겠습니다.
결과값의 오차
i1 -> 계층1(1) -> (w1.1)-> 계층2(1) -> o1 e1
-> (w1.2)
-> (w1.2)
i2 -> 계층1(2) -> (w2.2) -> 계층2(2) ->o2 e2
2개의 출력 노드 모두 오차를 가질 수 있습니다. 특히 우리가 아직 네트워크를 학습시키지 않은 경우에는 거으 ㅣ무조건 오차를 가지고 있겠죠. 그러므로 2개의 오차 모두 가중치를 어떻게 업데이트해야 할지에 대한 정보를 줘야 합니다. 우리는 앞에서 했던 대로 출력 노드의오차를 앞 단의 각 가중치에 비례해 나누어 주는 접근 방법을 활용할 수 있습니다.
출력노드가 여러 개라고 해서 변하는 것은 아무것도 없습니다. 그저 첫 번째 출력 노드에서 했던 작업을 두 번째 출력 노드에서 동일하게 반복하면 되는 것입니ㅏㄷ. 어떻게 이렇게 간단할 수 있냐고요? 그 이유는 하나의 출력 노드로의 연결은 다른 출력 노드로의 연결과 완전 별개이기 때문입니다. 각각의 연결 간에 는 전혀 의존 관계가 존재하지 않는다느 ㄴ말입니다.
앞의 그림을 다시 한번 보면 첫 번째 출력 노드의 오차를 e1이라고 표기했습니다. 이 초차는 학습데이터 t1에 의해 제공된 실제 값과 우리가 계산한 ㅜㅊㄹ력 값 o1사이의 차이를 의미합니다. 다시 말해 e1 = t1 -01입니다. 그리고 두 번째 출력 노드에서의 오차는 e2라고 표기해습니다.
그림을 자세히 보면 e1은 w11과 w21의 가중치의 값에 비례해서 나눠어 연결된 노드로 전달됩니다. 이와 유사하게 e2는 w12와 w22의 값에 비례해 나뉩니다.
좀 더 이해가 쉽도록 이를 수식으로 표현해 보겠습니다. 오차 e1은 w11과 w21의 업데이트에 영향을 주게 됩니다. 그러므로 w11을 업데이트 하기 위해 사용되는 e1의 일부는 다음과 같이 표현 가능합니다.
w11 / (w11 + w21)
그리고 w21을 업데이트 하기 위해 사용되는 e1의 일부는 다음과 같이 표현할 수 있습니다.
w21 /( w21 + w11)
이러한 수식의 의미는 결국 무엇일까요? 오차 e1은 나뉘어 전달될 때, 작은 가중치를 가지는 연결 노드보다 큰 가중치를 가지는 연결 노드에 더 많이 전달된다는 것입니다.
만약 w11 = 6이고 w21 = 3이라는 값을 가진다고 하면 w11은 w21보다2배 큽니다. 이때 w11을 업데이트하기 위해 전달되는 오차 e1의 일부는 6 / (6 +3) =6 /9 = 2/3 가 됩니다. 그럼 1/3이 남는데요. 실제로 오차 e1에서 w21을 업데이트 하기 위해 전달되는 부분은 3/ (6 +3) = 3/ 9 = 1/3입니다.
만약 가중치가 같다면 1/2씩 전달되게 될 것입니다. 예를 들어 w11 = 4, w21 = 4라면 약쪽으로 나눠어 전달되는 오차는 2개 모두 4 /( 4+4) = 4/8 = 1/2이 될 것 입니다.
지금까지 공부한 내용을 정리해보겠ㅅ브니다. 우리는 오차를 이용해서 네트워크 내의 매개변수들의 값(가중치)을 조정해나간다는 사실을 알게 되었습니다. 최종 출력 계층으로부터 그 직전 계층으로 가는 연결 노드으 ㅣ가중치를 업데이트하는 방식을 살펴봤는데 여러개의 출력 노드가 있는 경우에도 그 각각으 ㅣ출력노드를 개별적으로 처리하면 될 뿐, 복잡해질 것이 전혀 없다는 사실을 알게 되었습니다.
그렇다면 2개 보다 더 많은 꼐층을 가지는 신경망에서는 어떻게 하면 될까요? 다시 말해 최종 출력 계층에 인접하는 계층이 아니라, 멀리 떨어져 있는 꼐층과 관련된 가중치는 어떻게 업데이트를 해야 할 까요? 이데 대해서는 다음장에서 살펴보겠습니다.
결과값의 오차
i1 -> 계층1(1) -> (w1.1)-> 계층2(1) -> o1 e1
-> (w1.2)
-> (w1.2)
i2 -> 계층1(2) -> (w2.2) -> 계층2(2) ->o2 e2
2개의 출력 노드 모두 오차를 가질 수 있습니다. 특히 우리가 아직 네트워크를 학습시키지 않은 경우에는 거으 ㅣ무조건 오차를 가지고 있겠죠. 그러므로 2개의 오차 모두 가중치를 어떻게 업데이트해야 할지에 대한 정보를 줘야 합니다. 우리는 앞에서 했던 대로 출력 노드의오차를 앞 단의 각 가중치에 비례해 나누어 주는 접근 방법을 활용할 수 있습니다.
출력노드가 여러 개라고 해서 변하는 것은 아무것도 없습니다. 그저 첫 번째 출력 노드에서 했던 작업을 두 번째 출력 노드에서 동일하게 반복하면 되는 것입니ㅏㄷ. 어떻게 이렇게 간단할 수 있냐고요? 그 이유는 하나의 출력 노드로의 연결은 다른 출력 노드로의 연결과 완전 별개이기 때문입니다. 각각의 연결 간에 는 전혀 의존 관계가 존재하지 않는다느 ㄴ말입니다.
앞의 그림을 다시 한번 보면 첫 번째 출력 노드의 오차를 e1이라고 표기했습니다. 이 초차는 학습데이터 t1에 의해 제공된 실제 값과 우리가 계산한 ㅜㅊㄹ력 값 o1사이의 차이를 의미합니다. 다시 말해 e1 = t1 -01입니다. 그리고 두 번째 출력 노드에서의 오차는 e2라고 표기해습니다.
그림을 자세히 보면 e1은 w11과 w21의 가중치의 값에 비례해서 나눠어 연결된 노드로 전달됩니다. 이와 유사하게 e2는 w12와 w22의 값에 비례해 나뉩니다.
좀 더 이해가 쉽도록 이를 수식으로 표현해 보겠습니다. 오차 e1은 w11과 w21의 업데이트에 영향을 주게 됩니다. 그러므로 w11을 업데이트 하기 위해 사용되는 e1의 일부는 다음과 같이 표현 가능합니다.
w11 / (w11 + w21)
그리고 w21을 업데이트 하기 위해 사용되는 e1의 일부는 다음과 같이 표현할 수 있습니다.
w21 /( w21 + w11)
이러한 수식의 의미는 결국 무엇일까요? 오차 e1은 나뉘어 전달될 때, 작은 가중치를 가지는 연결 노드보다 큰 가중치를 가지는 연결 노드에 더 많이 전달된다는 것입니다.
만약 w11 = 6이고 w21 = 3이라는 값을 가진다고 하면 w11은 w21보다2배 큽니다. 이때 w11을 업데이트하기 위해 전달되는 오차 e1의 일부는 6 / (6 +3) =6 /9 = 2/3 가 됩니다. 그럼 1/3이 남는데요. 실제로 오차 e1에서 w21을 업데이트 하기 위해 전달되는 부분은 3/ (6 +3) = 3/ 9 = 1/3입니다.
만약 가중치가 같다면 1/2씩 전달되게 될 것입니다. 예를 들어 w11 = 4, w21 = 4라면 약쪽으로 나눠어 전달되는 오차는 2개 모두 4 /( 4+4) = 4/8 = 1/2이 될 것 입니다.
지금까지 공부한 내용을 정리해보겠ㅅ브니다. 우리는 오차를 이용해서 네트워크 내의 매개변수들의 값(가중치)을 조정해나간다는 사실을 알게 되었습니다. 최종 출력 계층으로부터 그 직전 계층으로 가는 연결 노드으 ㅣ가중치를 업데이트하는 방식을 살펴봤는데 여러개의 출력 노드가 있는 경우에도 그 각각으 ㅣ출력노드를 개별적으로 처리하면 될 뿐, 복잡해질 것이 전혀 없다는 사실을 알게 되었습니다.
그렇다면 2개 보다 더 많은 꼐층을 가지는 신경망에서는 어떻게 하면 될까요? 다시 말해 최종 출력 계층에 인접하는 계층이 아니라, 멀리 떨어져 있는 꼐층과 관련된 가중치는 어떻게 업데이트를 해야 할 까요? 이데 대해서는 다음장에서 살펴보겠습니다.
CHAPTER 10 여러 노드에서 가중치 학습하기
이 책 앞부분에서 선형함수의 매개변수인 기울기의 값을 조정해감으로써 선형분류자를 업데이트해나갔던 것을 기억할 겁니다. 그때 오차라는 개념을 공부한 바 있습니다.
오차는 예측 값고 ㅏ실제 값(정담)과의 차이를 의미하는데, 우리는 이 오차에 기반을 두고선형 분류자를 정교화해나갔습니다. 오차와 기울기의 관계가 매우 단순했기 때문에 이를 조정해가는 ㅓㄳ은 별로 어려운 과정은 아니였습니ㅏㄷ.
그렇다면 여러 개의 노드가 결과 값과 오차에 영향을 주는 경우에는 가중치를 어떻게 업데이트해야 할까요? 이를 그림으로 표현하면 다음과 같습니다.
<---- p="">(1) ->W1.1(3.0)-> (1) -> 결과 값의 오차
(2) -> W2.1(1.0) ->
<---- p="">
결과 노드에 영향을 주는 노드가 한 개인 경우에는 월씬 간단했지만, 이와 같이 2개의 노드를 가지는 경우에는 결과 값의 오차를 어떻게 활용해야 할까요?
오차를 하나의 가중치 업데이트에만 사용하는 것은 합리적이지 못합니다. 나머지 하나의 가중치를 무시하는 것이기 때문이죠. 오차가 발생하는데에는 이 다른 연결 노드분도 공헌을 했다는 사실을 무시할 수 없다는 말입니다.
물론 수많으 연결 중에 단 하나의 연결만 해당 오차의 발생에 영향을 미치느느 경우가 있을 수는 있겠지만, 이런 가능성은 매우 낮습니다. 설령 우리가 이리미 정확한 값을 가지게 된 가중치의 값을 변경해 상황을 악화시키게 된다고 하더라도 이런상황은 다음번의 업데이트를 통해 개선될 것입니다.
한가지 방법은 다음 그리과 같이 모든 연결된 노드에 대해 오차를 균일하게 나누어 분배하는 것입니다.
<----1 p="">(1) ->W1.1(3.0)-> (1) -> 결과 값의 오차
(2) -> W2.1(1.0) ->
<----1 p="">
또 다른 방법은 오차를 나누어 분배하지만 차별을 두는 것인데, 더 큰 가중치를 가지는 연결에 더 큰 오차를 분배하는 것입니다. 더 큰 가중치를 가진다는 것은 그만큼 오차의 형성에 더 큰 영향을 줬다는 의미이기 때문입니다. 이를 그림으로 표현하면 다음과 같습니다.
<----3 p="">(1) ->W1.1(3.0)-> (1) -> 결과 값의 오차
(2) -> W2.1(1.0) ->
<----1 p="">
이 그림에서 2개의 노드는 한 노드에 서로 다른 가눙치로 영햐응ㄹ 줬습니다. 각 연결의 가중치는 3.0과 1.0 입니다. 만약 오차르 ㄹ이들 가중치에 비례해 나눠준다면 오차의 3/4이 위쪽 가중치를 업데이트하는 데에 사용되고 나머지 1/4이 아래쪽으 ㅣ가중치를 업데이트하는데에 사용될 것입니다.
이방법은 노드가 더 많아지더라도 동일하게 적용 가능합니다. 만약 100개의 노드가 다음 계층의 노드에 연결되어 있다고 한다면 우리는 오차를 100개의 연결에 나누어주되 그 값은 각각의 가중치에 따라, 즉 각각의 견결이 오차에 영향을 주는 정도에 비례해서 전달하면 되는 것입니다.
따라서 우리는 가중치를 두 가지 방법을 ㅗ활용한다는 점을 확인할 수 있습니다. 우선 앞에서 여러 사례를 살펴본 바오 ㅏ같이 신호를 하나의 계층에서 다음 계층으로 전파하는데에 가중치를 이용합니다. 두 번째로 오차를 하나의 계층에서 직전 계층으로, 즉 역으로 전파하는 데에도 가중치를 이요합니다. 첫 번째 방식은 앞에서 이비본 전파법이고 두 번째 방법을 역전파(backprogagation)라고 부릅니다.
만약 출력 계층의 2개의 노드를 가진다면 우리는 두 번째 노드에서 대해서도 동일한 작업을 하게 됩니다. 두 번째 노드의 결과 값 역시 그 자체의 오차를 가지므로 연결되는 노드에 대해 이 오차를 분배해주면 되는 것입니다. 다음 장에서 이에 대해 상세히 살펴보게습니다.
----1>----3>----1>----1>---->---->
오차는 예측 값고 ㅏ실제 값(정담)과의 차이를 의미하는데, 우리는 이 오차에 기반을 두고선형 분류자를 정교화해나갔습니다. 오차와 기울기의 관계가 매우 단순했기 때문에 이를 조정해가는 ㅓㄳ은 별로 어려운 과정은 아니였습니ㅏㄷ.
그렇다면 여러 개의 노드가 결과 값과 오차에 영향을 주는 경우에는 가중치를 어떻게 업데이트해야 할까요? 이를 그림으로 표현하면 다음과 같습니다.
<---- p="">(1) ->W1.1(3.0)-> (1) -> 결과 값의 오차
(2) -> W2.1(1.0) ->
<---- p="">
결과 노드에 영향을 주는 노드가 한 개인 경우에는 월씬 간단했지만, 이와 같이 2개의 노드를 가지는 경우에는 결과 값의 오차를 어떻게 활용해야 할까요?
오차를 하나의 가중치 업데이트에만 사용하는 것은 합리적이지 못합니다. 나머지 하나의 가중치를 무시하는 것이기 때문이죠. 오차가 발생하는데에는 이 다른 연결 노드분도 공헌을 했다는 사실을 무시할 수 없다는 말입니다.
물론 수많으 연결 중에 단 하나의 연결만 해당 오차의 발생에 영향을 미치느느 경우가 있을 수는 있겠지만, 이런 가능성은 매우 낮습니다. 설령 우리가 이리미 정확한 값을 가지게 된 가중치의 값을 변경해 상황을 악화시키게 된다고 하더라도 이런상황은 다음번의 업데이트를 통해 개선될 것입니다.
한가지 방법은 다음 그리과 같이 모든 연결된 노드에 대해 오차를 균일하게 나누어 분배하는 것입니다.
<----1 p="">(1) ->W1.1(3.0)-> (1) -> 결과 값의 오차
(2) -> W2.1(1.0) ->
<----1 p="">
또 다른 방법은 오차를 나누어 분배하지만 차별을 두는 것인데, 더 큰 가중치를 가지는 연결에 더 큰 오차를 분배하는 것입니다. 더 큰 가중치를 가진다는 것은 그만큼 오차의 형성에 더 큰 영향을 줬다는 의미이기 때문입니다. 이를 그림으로 표현하면 다음과 같습니다.
<----3 p="">(1) ->W1.1(3.0)-> (1) -> 결과 값의 오차
(2) -> W2.1(1.0) ->
<----1 p="">
이 그림에서 2개의 노드는 한 노드에 서로 다른 가눙치로 영햐응ㄹ 줬습니다. 각 연결의 가중치는 3.0과 1.0 입니다. 만약 오차르 ㄹ이들 가중치에 비례해 나눠준다면 오차의 3/4이 위쪽 가중치를 업데이트하는 데에 사용되고 나머지 1/4이 아래쪽으 ㅣ가중치를 업데이트하는데에 사용될 것입니다.
이방법은 노드가 더 많아지더라도 동일하게 적용 가능합니다. 만약 100개의 노드가 다음 계층의 노드에 연결되어 있다고 한다면 우리는 오차를 100개의 연결에 나누어주되 그 값은 각각의 가중치에 따라, 즉 각각의 견결이 오차에 영향을 주는 정도에 비례해서 전달하면 되는 것입니다.
따라서 우리는 가중치를 두 가지 방법을 ㅗ활용한다는 점을 확인할 수 있습니다. 우선 앞에서 여러 사례를 살펴본 바오 ㅏ같이 신호를 하나의 계층에서 다음 계층으로 전파하는데에 가중치를 이용합니다. 두 번째로 오차를 하나의 계층에서 직전 계층으로, 즉 역으로 전파하는 데에도 가중치를 이요합니다. 첫 번째 방식은 앞에서 이비본 전파법이고 두 번째 방법을 역전파(backprogagation)라고 부릅니다.
만약 출력 계층의 2개의 노드를 가진다면 우리는 두 번째 노드에서 대해서도 동일한 작업을 하게 됩니다. 두 번째 노드의 결과 값 역시 그 자체의 오차를 가지므로 연결되는 노드에 대해 이 오차를 분배해주면 되는 것입니다. 다음 장에서 이에 대해 상세히 살펴보게습니다.
----1>----3>----1>----1>---->---->
CHAPTER 8 머신러닝의 다양한 문제점 해결하기
이 장에서는 머신러닝 시스템의 성능이 잘 나오지 않을 때 고려할 만한 사항을 살펴보겠습니다. 머신러닝으로 문제를 해결한다는 것은 데이터에 맞는 모델, 적립한 손실함수, 최적화 방법, 평가 방버을 찾는 과정입니다. 처음에서 성능이 잘 나오지 않더라도 너무 실망히지 마시고 개선 방안을 찾아내면 됩니다.
8.1 모델 문제
지금부터 8.2절 '데이터 문제'에서 다룰 데이터 처리, 8.3절 '속도 문제 '에서 다룰 속도 향상 외에 모델 자체에서 비롯된 문제를 해결해서 모텔의 성능을 향상하는 방법을 크게 둘로 나눠 설명합니다. 첫 번째는 학습할 때는 잘 동작했는데 실제로 사용하니 성능이 생각보다 잘 나오지 않는 과학습(오버피팅, 과적합, 과적응) 문제를 해결하는 방안을 알아보고, 두 번째는 데이터에 적합한 모델을 효과적으로 찾는 방법에 대해 알아보겠습니다.
8.1.1 과학습
머신러닝 시스템 시스템을 기존 데이터로 학습시킨 후 평가했을 때는 좋은 성능이 나와 학습이 잘되었다고 판단했는데, 새로운 데이터에서 예상대로 성능이 나오지 않는 경우의 원인은 대부분 과 학습 때문입니다. 과학습은 말 그대로 모델이 과하게 학습 데이터에 집중한 나머지 필요 이상으로 패턴을 학습한 경우입니다. 다음 그림과 같은 경우를 들 수 있습니다.
그림 8-1 과학습의 예. 거시적으로는 선형 패턴(점선으로 표시)을 가지는 데이터인데 필요 이상으로 복잡하게 학습한 경우(실선으로 표시)
[그림 8-1]은 과학습의 한 예입니다. 그래프에서 x로 표시된 점은 관착된 데이터입니다. 얼핏 봐도 데이터가 왼쪽 아래부터 오른쪽 위까지의 선형 패턴을 가집니다. 이 데이터를 기반으로 X값이 7일 때의 Y 값을 예측한다면 11 정도가 될 겁니다. 그런데 전체적인 패턴을 무시한 채 학습 데이터를 완벽하게 예측하는 것에만 중점을 두어 모든 점을 지나는 선을 모델로 만들게 되었습니다. 그 결과 실선과 같은 과학습된 모델을 가지게되고 X값이 7일 때의 Y값을 제대로 예측할 수 없게 된 겁니다.
그렇다면 이문제를 어떻게 해결해야 할까요? 그리고 이런 현상이 일어날지 어떻게 미리 알 수 있을까요? 2.1.5.2절 '정규화'와 2.4.1절 '모델의 일반화 특성 평가'에서 이론상으로 다룬 바 있습니다. 이제부터 과학습을 해결하는 실용적인 방법을 알아보겠습니다.
8.1.1.1 학습- 평가 데이터 나누기
과학습 문제를 발견하는 가장 효과적인 방법은 전체 데이터의 일부분만으로 모델을 학습시키고 나머지 데이터를 이용해 모델을 평가해서 얼마나 데이터의 일반적인 패턴을 잘 학습하는지 판단 하는 겁니다. 일반적인 패턴을 잘 파악하지 못하는 모델은 그렇지 않은 모델에 비해 학습용 데이터에서는 좋은 성능을 보이지만, 평가용 데이터에서는 성능이 잘 나오지 않는 현상을 보이게 됩니다. 자세한 내용은 2.4.1절 '모델의 일반화 특성 평가'를 참조하세요
8.1.1.2 정규화
모델의 정규화는 바로 이런 과학습 문제를 해결하기위해 등장했습니다. 정규화는 데이터를 설명할 수 있는 가장 간단한 가정만을 사용한다는 '오컴의 면도날 가정'을 이용하여 과학습을 막습니다. [그림 8-1]을 보면 데이터의 패턴을 설명하기에는 점선이 실선으로 표시된 복잡한 모델보다 더 간단합니다. 이렇게 데이터의 패턴을 복수의 가정으로 설명할 때는 데이터의 패턴에서 심하게 벗어나지 않으면 되도록 간단한 가정을 사용하는 것이 좋습니다.
2.1.5.2절 '정규화'에서 설명했듯이 '데이터의 패턴에서 너무 벗어나지 않는 것'과 '더 간단한 모델을 사용하는 것'의 균형은 정규화 파라미터로 결정합니다. 그렇다면 그 파라미터를 어떻게 결정해야 할 까요? 2.4.1절 '모델의 일반화 특성 평가'에서 설명한 것과 같이 정규화 파라미터를 결정하는 데이터셋을 따로 빼놓고 학습하는 방법을 많이 사용합니다.
정규화 파라미터가 실제로 어떻게 영향을 미치는지 간단한 예제를 통해 알아보겠습니다. 사이킷런의 linear_model.Ridge 클래스는 정규화 파라미터를 지원하는 선형 회귀 클래스입니다. 클래스의 원형은 다음과 같습니다.
class sklearn.linear_model.Ridge(alpha=1.0, fit_intercept=True, normalize=False, copy_X=True, max_iter=None, tol=0.001, solver='auto', random_State=None)
여기서 정규화와 관련된 파라미터는 alpha인테, 값이 클수록 정규화의 강도가 더욱 강해집니다.
실제로 어떻게 문제가 발생하는지 시각적으로 보여드리기 위해 2차 함수를 따르는 데이터를 만든 후 10차 함수 형태의 모델을 사용하는 경우를 알아보겠습니다(현샐에서는 데이터가 몇 차원 함수를 따르는지 알 수 없으므로 임의로 높은 차원을 가정합니다). 여기서는 구현보다는 어떻게 되는지 설명에 집중하기 위해 자세한 코드는 생략하도록 하겠습니다.
데이터는 다음과 같은 가우스 분포도 생성되었습니다.
y = x*x -2x -1 + 노이즈
그리고 우리 모델은 10차 함수 형태까지 학습할 수 있는 능력을 가진 10차 다항함수를 사용했습니다. 수식으로 나타내면 학습과정에서 상수 부분까지 모두 11개의 파라미터(w10, w9,...w0)를 학습하게 됩니다.
모델이 표현할 수 있는 한계(10차 함수)가 실제 데이터(2차 함수)보다 훨씬 높죠? 이런 경우에 과학습이 심하게 발생할 수 있습니다. 과학습이 나타나는 현상을 실제로 ㄹㄴ덤한 데이터를 만들고 학습해서 시각화해보겠습니다. 먼저 정규화 없이 그냥 모델을 단순하게 학습시킨 결과를 살펴보겠습니다.
[그림 8-2]를 보면 단순히 오목하게 생긴 2차 함수의 패턴을 학습하면 되는데 모델이 필요 이상으로 복잡해서 굉장히 구불구불한 모양으로 학습된 것을 볼 수 있습니다. 똑같은 데이터에 정규화 파라미터 alpha값을 증가시켜 보겠습니다.
그림 8-3 정규화가 있을 때(alpha=0.1)의 변화
[그림 8-2]에 비해 곡선이 훨씬 부드러워졌습니다. 다시 말해, 모델이 표현 가능한 범위보다 좀더 간단한 모델을 사용하도록 강제된 것을 확인할 수 있습니다.
그림 8-4 정규화가 좀 더 강할 때(alpha =1)
[그림 8-4]는 [그림 8-3]보다 더욱 강하게 정규화 값을 설정한 경우입니다. 곡선이 좀 더 부르러워져서 더 간단한 모델이 되었습니다.
이렇게 정규화 파라미터를 조절하면서 필요 이상으로 복잡한 패턴을 학습하지 않도록 머신러닝 모델을 조절할 수 있습니다. 그렇다면 적절한 파라미터 값은 어떻게 찾을 수 있을까요?
그림 8-5 검증용 데이터를 나누어 정규화 파라미터 정하기
1. 데이터를 학습 및 검증용(A)과 테스트(B)으로 나눕니다.
2. A를 다시 학습용(C)와 검증용(V)로 나눕니다.
3. 학습용 데이터에 대해 정당한 정규화 파라미터로 학습을 수행한 후 검증용 데이터를 사용해 성능을 측정합니다. 반봅해서 V에서 가장 성능이 좋은 정규화 파라미터를 찾습니다.
4. 과정 3에서 찾은 정규화 파라미터를 이용해서 A에 대해 학습을 수행합니다.
5. 모델 자체에 대한 평가는 B로 하면 됩니다.
과정 2부터 4까지는 교차 검증을 이용해도 됩니다. 교차검증은 2.4.1.2절 '교차검증'을 참조하기 바랍니다.
8.1.1.3 학습을 일찍 끝내기
정규화와 비슷하지만 훨씬 더 간단한 방식이 있습니다. 이 방식은 딥러닝에서 주로 사용되지만, 그 외의 분야에서도 많이 쓰이고 있습니다. 우선 아래 그래프에서 과학습이 되는 시점에 주안점을 두어 살펴보고 이야기를 더 진행하겠습니다.
그림 8-6 머신러닝 모델을 학습할 때 일반적으로 보게 되는 학습 데이터와 테스트 데이터에서의 손실 곡선
[그림 8-6]은 머신러닝 모델을 학습할 때 보게 되는 일반적인 손실 그래프입니다. 위에 있는 고선이 테스트 데이터에서의 손실, 아래 있는 곡선이 학습 데이터에서의 손실입니다. 학습 데이터에서의 손실은 학습을 진행할수록 줄어드는데, 테스트 데이터에서의 손실은 학습데이터에 모델이 과하게 최적화된 이후 오히려 늘어나게 됩니다. 손실이 늘어나기 시작하는 지점이 바로 과학습의 시작점입니다. 이 지점 이전까지는 학습 효과가 좋았으므로 과학습이 나타나는 시점까지만 학습하면 과학습을 예방할 수 있게 됩니다. 물론 '어느 시점'에 그만둘지 결정하는 것은 쉬운 일이아닙니다. 하지만 정규화가 쉽게 되지 ㅏㅇㄶ는 모델에는 이 방식을 더 유욯하게 사용할 수 있습니다.
딥러닝으로 유명한 힌튼 교수는 '일찍 끝내기(early stopping)는 아름다운 공짜 점심'이라고 표현했습니다. 아주 쉽고 거의 공짜로 이득을 본다는 뜻이죠. 실제로 현업에서도 학습을 완전히 수행하기보다는 최대 몇 번까지 반복한다고(예를 들어 100번) 적당히 정해놓고 학습을 하는 식으로 많이 사용합니다.
8.1.1.4 드롭-아웃(딥러닝 기법)
딥러닝에는 뉴렐넷의 과학습을 예방하는 방법으로 드롭-아웃(drop-out)을 널리 사용합니ㅏㄷ. 본 개념을 먼저 살표고벴습니다.
드롭-아웃은 딥러닝 모델으 ㄹ학습할 때 레이어와 레이어를 잇는 연결 중에서 일정한 확률 p로 몇 가지 연결을 무작위로 끊은 채 학습합니다. 즉, 학습이 진행될 때(파라미터를 업데이트 할 때) 마다 연결이 조금씩 달라진 상태로 딥러닝 모델을 학습하게 됩니다.
1. 아래와 같은 딥러닝 모델이 있다고 합시다. 동그라미는 레이어고, 선은 그것을 잇는 가중치 연결입니다.
2. 학습중 일부 업데이트는 아래와 같이 확률 p에 따라 레이어 연결을 임의로 몇 개 누락시키고 업데이트합니다.
3. 또 다른 업데이트는 다른 패턴으로 임의로 몇 개 누락시키고 업데이트 합니다.
4. 학습이 모두 끝난 후 모델을 실제로 사용할 때는 모든 연결을 사용하지만 p 만큼 연결의 강도를 약화시켜서 사용합니다.
드롭-아웃을 이용한 딥러닝 모델 학습이나 학습된 모델을 사용하는 방법 자체는 앞에서 설명한 것처럼 상당히 간단합니다. 연결을 무작위로 끊으면서 학습하고, 학습된 모델을 사용할 때는 연결 강도를 조절하면 됩니다. 또한 텐서플로에서 라이브러리로 제공하므로 그냥 가져다 쓰면 됩니다. 하지만 왜 이렇게 하는 것이 정규화에 도움이 되는지 이해하기 쉽지 않을 겁니다. 그 이유를 순서에 입각하여 살펴보면 다음과 같습니다.
1. 학습 시 연결을 임의로 몇 개를 끊으면 모델이 더 '간단하게'됩니다.
2. 간단한 모델로 학습하면 원래 모델보다 조금 제한된 모델로 학습이 이루어지게 되고 결과적으로 필요 이상으로 모델이 데이터의 복잡한 패턴을 학습하는 것을 방지하는 효과를 발휘하게 됩니다.
3. 이 과정을 반복하면 간단한 모델들의 밈의 조합을 이용해서 데이터를 설명하려는 시도를하게됩니다.
4. 그 결과 모델은 피처와 레이어 사이의 연결 가능한 모든 레이어 간의 조합에 대해 학습을 수행하는 것이 아니라 적은 연결로 전체를 설명하는 방향으로 학습하게 됩니다.
이 과정은 앞에서 설명한 정규화와 비슷하게 모델을 단순화시키는 효과를 볼 수 있습니다. 드롭-아웃은 구현이 쉬우면서도 딥러닝 모델의 성능을 늘리는데 매유 효과적입니다. 만일 딥러닝기법을 사용한다면 도입을 꼭 고려해보기 바랍니다. 참고로 텐서플로에서는 이 기능을 깁본으로 지원합니다.
8.1.2 좋은 모델을 좀 더 수월하게 찾는 방법
머신러닝은 모델에 따라 성능이 크게 좌우됩니다. 딥러닝이 발전하고 데이터양이 증가하면서 모델 자체에 대한 고민은 예전보다 적어진 듯 보이지만, 그럼에도 더 좋은 성능을 얻으려면 더 데이터에 적합한 모델을 이용하여 학습해야 합니다. 따라서 모델의 중요성은 아무리 강조해도 지나치지 않습니다.
이절에서는 데이터에 적합한 모델을 효과적으로 찾는 방법에 대해 알아보겠습니다. 1장과 2장에서도 잠깐 어급했지만'머신러닝을 적용한다'는 것은 '데이터에 적합한 모델과 학습 방법을 차즌ㄴ 일련의 과정을 적용한다'는 뜻입니다. 특히 적합한 모델을 찾는 것은 핵심입니다.
그렇다면 어떻게 하면 적합한 모델을 쉽게 찾을 수 있을 까요? 다음과 같은 방법을 생각할 수 있습니다.
- 간단한 모델부터 적용하기
- 데이터와 모델 시각화 하기
- 모델의 최대 성능 가늠하기
8.1.2.1 간단한 모델부터 적용하기
가장 중요한 원칙은 처음부터 복잡한 모델을 곧바로 적용하는 것이 아니라 간단한 모델을 적용시켜서 성능을 확인해보는 것입니다. 어차피 복잡한 모델이 더 좋은 성능을 낼 확률이 높은데 왜 굳이 시간을 낭비하는지 의문이 들 수도 있을 겁니다. 간단한 모델 부터 테스트해보는 데는 다음과같은 이유가 있습니다.
간단한 모델은 구현이쉽고 학습도 쉽습니다.
대부분의 머신러닝 라이브러리는 선형 휘귀, 로지스틱 휘귀, 레이어가 1개인 뉴런넷 모델 등 간단한 모델을 제공하고 있어 손쉽게 시도할 수 있고 학습도 굉장히 빠릅니다. 또한 적은 학습과 정 튜닝으로 최대의 성능을 쉽게 확인할 수 있습니다. 복잡한 모델은 구현, 학습, 그리고 파라미터 튜닝에 오랜 시간이 걸립니다.
간단한 모델의 성능은 다른 모델이 얼마나 잘 동작하는지에 대한 지표가 됩니다.
간단한 모델을 실제 시스템에 사용하지 않더라도 그 성능을 더 복잡합 모델의 성능 지표로 삼을 수 있습니다. 복잡한 모델의 1차 구현물이 간단한 모델의 성능보다 월등히 좋지 않다면 뭔가 개선 방법을 찾아야 합니다. 반대로 간단한 모델보다 성능이 좋다면 모델이 잘 작동한다고 판단하고 튜닝에 돌입하면 됩니다.
간단한 모델은 원인을 파악하기가 상대적으로 쉽습니다.
모델의 성능이 떨어지는 원인은 다양합니다. 데이터 처리 버그, 모델의 학습방법, 아니면 그냥 문제 자체가 예측이 어려운 경우일 수도 있습니다. 이유가 뭐든 간단한 모델일 때보다 복잡한 모델에서 문제의원인을 찾기가 상대저그로 어렵다는 건 두말할 필요 없을 겁니다. 먼저 간단한 모델을 사용해서 전체가 잘 동작하는지 검증한 후 복잡한 모델을 적용하기 바랍니다.
8.1.2.2 데이터와 모델 시각화하기
데이터를 시각화해보는 것도 적합한 모델을 찾는데 도움이 됩니다. 하지만 추가 노력이 들기 때문에 생략하는 경우도 적지 않습니다. 전체 데이터를 완전히 시각화하지 않더라도 패턴을 살펴볼 수 있는 수준이면 도움이 됩니다. 그 이유는 다음과 같습니다.
데이터 이상 파악
예를 들어 일반적인 선형 회귀를 해보려고 생각하고 있었는데, 데이터를 시각화해보니 데이터가 선형적인 양상이 아니라 로그 스케일을 따른다든가, 소수점 단위를 예상하고 있었는데 음수가 나온다든가, 혹은 기본값이 특이하게 들어 있는 경우를 생각할 수 있습니다. 실숫값을 기대하고 있었는데 정숫값만 존재하거나 카테고리 ID가 들어오는 경우처럼 데이터 자체에 대한 가정에 문제가 잇는지 등도 파악하기 좋습니다.
데이터 특성 파악
데이터를 분석할 때 가장 기본적인 것은 데이터가 정규 분포를 따른다고 가정하느 것입니다. 대부분의 경우에는 큰 무리가 없지만, 가끔 데이터가 정규분포를 크게 벗어난느 경우가 있습니다. 예를 들어[그림8-7]과 같이 데이터가 한개 의 정규분포(가우스분포)를 따르지 않는 경우입니다. 이 경우에는 2개의 정규분포를 포함하는 머신러닝 기법이 적합합니다.
모델 동작 방식 이해
데이터를 시각화 하는 것과 함께 모델의동작 결과를 시각화하는 것도 많은 도움이 됩니다. 예를 들어 분류 모델의 경우에는 모델이 각 데이터 포인트를 어떻게 분류하는지, 희귀모델의 경우에는 모델이 출력하는 결괏값이 어떻게 분포된느지 시각화하면 모델이 어떤 방시긍로 동작하는지 이해하는 데 도움이 됩니다.
시각화는 이책의 여러붑ㄴ에서 쓰였는데, 8.2.3.2 절'데이터의 값이 치우쳐 있을 때'에서는 데이터를 시각화에서 데이터의 편중 정도를 파악하고, 8.1.1.2절 '정규화'에서는 모델을 시각화해서 실제로 정규화가 모델에 어떻게 영향을 미치는지 살펴 보았습니다.
아래 URL에 방문하면 사이킷런에서 사용할 수 있는 다양한 시각화 예제를 확인할 수 있습니다.
http://scikit-learn.org/stable/suto_examples/
|2차원 이상의 데이터 시각화하기|
2차원 이상의 데이터를 시각화하는 일은 쉽지 않습니다. 데이터들의 상관관계를 이용해서 2차원으로 관곌르 재정의해서 그리는 방법이 있는데, 데이터의 절대좌표를 직접 입력하는 것이 아니라 한 데이터의 위치가 다른 데이터와 얼마나 다른지 상대거리를 이용해서 시각화하게 됩니다. 그리고 데이터의 절대거리보다는 근처에 있는 점들과의 관계를 보존하는 방법으로 시각화합니다. 이런 경우에 t-SNE 같은 방법이 특히 많이 이용됩니다. 예를 들어 텐서플로 튜터리얼에서 t-SNE를 사용하여 단어 벡터들을 시각화한 예를 착을 수 있습니다. 더 자세한 사항은 해당 튜터리엉ㄹ을 참고하세요. 대표적으로 Isomap, L.I.E, MIDS와 같은 방법이 있습니다. 자체한 사항은 사이킷런 홈페이지를 참고하세요.
8.1.2.3 모델의 최대성능 가늠하기
구현한 모델이 99.99% 정확도를 보인다면 더할 나위 없겠죠, 반대로 성능이 너무 좋지 않나면 더 적극적으로 새로운 모델을 찾아봐야 할 겁니다. 그러면 과연 성능이 얼마나 좋은지 어떻게 판단 할 수 있을까요? 지금 얻은 성능의 수치는 낮지만 사실 엄청나게 잘하고 있는것 아닐까요? 단순히 성능 수치만으로는 애매한 부분이 있기 때문에 가능한 한 최고 성능르 가늠해보고 현재 어느 정도 수준인지 판단하는 것이 중요합니다.
물론 최고 선을을 가늠하는 것은 쉽지 않은 일입니다. 대에 따라 다르겠지만 다음과 같은 시나리오를 생각할 수 있습니다.
머신러닝 시스템과 사람의 성능 비교
사람의 직접 해당 일을 수행했을 때 얻을 수 있는 정확도 등의 예측 성능은 좋은 지표가 됩니다. 예를 들어 몇 명의 수동으로 이미지에 보이는 몰체를 태깅하거나 분류한 다음 평균 성능을 평가하여 머신러닝 시스템이 얼마나 잘 동작하는지 가늠해보는 겁니다. 예를 들어 아마존 메커니컬 피크는 수많은 사람에게 태깅을 부탁하고 소액을 지불하는 크라우드 소싱을 이용합니다. 만일 사람조차도 공통 의견을 만들기가 쉽지 않다면 머신러닝 시스템도 좋은 성능을 내기 쉽지 않을 겁니다.
이론상 성능의 한계나 보장된 값이 존재할 때
데이터에 따라 다소 제한적이긴 하지만 보장된 성능이 존재하는 경유가 있습니다. 예를 들어 제품의 불량률이 정해져 있고, 센서가 얻을 수 있는 불량에 대한 정보에 한계치가 있다면, 이 두요소에 의존하여 불량을 판볻하는 시스템의 성능에는 한계가 있겠죠. 이와 같은 정보를 미리 알면 현재 머신러닝 시스템이 얼마나 잘 동작하는지 알 수 있습니다.
8.2 데이터 분제
학습 데이터가 어떻게 구성되어 있는지에 따라 학습 성능이 크게 달라집니다. 이 장에서는 데이터가 너무 많거나 너무 적거나, 아니면(가장 일반적인) 치우침이 심할 때 어떻게 하면좋을지 살펴보겠습니다. 참고로 8.1.2.2절 '데이터와 모델 시각화하기'에서 언급한 데이터 시각화도 이런 데이터의 특성을 이해하는데 도움이 됩니다.
8.2.1 데이터가 너무 많을때
앞서 머신러닝에서 데이터가 많을 수록 좋다고 언급했습니다. 이론상으로는 데이터가 많을 수록 성능이 좋은 모델을 얻을 수 있지만, 데이터가 많으면 처리 시간이 오래 걸리기 때문에 문제가 될 수 있습니다. 특히 같거나 비슷한 데이터가 많이 들어오는 경우를 생각해 봅시다. 예를 들어 1분마다 물체의 움직임을 감지하여 데이터를 송신하는 센서를 이용하여 물체의 이동 곙로를 학습하는 모델을 만들려고 할 때 물체가 거의 정지해 있다면 대부붕의 데이터가 움직임 없음(0)으로 채워질 겁니다. 또 다른 경우는 특정 분류 항목의 데이터가 너무 많아서 전체 적으로 학습이 오래 걸리는데 그렇지 않은 항목은 적은 경우가 있습니다. 예를 들어 사진 데이터에서 하늘이나 구름 사진은 어첨 많은데 휘귀한 동뭀진은 적은 경우가 있습니다. 이를 해결하기 위해 다음과 같은 방법을 생각해 볼 수 있습니다.
과소표집
과소표집(언더샘플링)은 전체 데이터셋에서 데이터를 무작휘 확률로 선택해서 선택된 데이터로 이우러진 작아진 데이터셋을 사용하는 방식입니다. 데이터를 무작위로 선택하는 방법은 다양하지만, 가장 중요한점은 데이터의 특성과 상관없이 뽑아야 한다는 것입니다. 예를 들어 사용자 구매 이력 데이터에서 50%확률로 데이터를 뽑는것은 괜찮지만, 사용자 이름 가나다순으로 정렬된 데이터셋의 앞부분 절반만 사용하는 것은 데이터으 ㅣ특성을 바꿀 수 있기 때문에 안됩니다.
중요도 표집
중요도 표짐(중요도 샘플링)은 데이터의 중요도에 따라 선택 확률을 변도하여 샘플링하는 기법이다. 무작위 확률로 선택하다 보면 특정 경우에 해당하는 데이터가 거의 없어지는 문제가 발생할 수 있습니다. 예를 들어 이미지 분류 문제를 푼다고 가정합시다. 학습용 데이터에서 '하늘'에 해당하는 이미지는 엄청 많은데 '오리너구리'에 해당하는 이미지는 적다고 합시다. 이런 경우 이미지를 무작위로 선택하면 오리너구리 이미지는 정말로 적은 수만 남게 됩니다. 그러면 오리너구리에 대한 학습이 제대로 이루어지지 못하겠죠. 이런 경우에는 데이터의 중요도에 따라 선택확률을 변동시키는 방법이 더 적합합니다. 예를 들어 하늘에 해당하는 사진은 10%의 확률로 뽑고 오리너구리 사진은 너무 개수가 적으니 80%의 확률로 뽑는 방법을 고려 할 수 있습니다.
피처 선택
'피처 선택'은 중요한 피처만 선택해서 전체 학습률과 성능을 증가시키는 방법입니다. 피처가 많으면 학습에 사용하는 데이터가 많아 학습률이 느려지고, 모델이 복잡해져서 과학습을 할 우려가 있습니다. 피처를 고르는 방법으로 '카이제곱 피처 선택법', '상호-정보 피처 선택법', '검증셋에서의 성능'이 주로 사용됩니다. 어떤 방법을 사용하든 성능에 도움이 되는 피처는 고르고 그렇지 않은 피처는 삭제하는 방향으로 진행됩니다.
1. 카이제곱 피처 선택법(이하 카이제곱 선택법): 피처와 성능 간의 통계학적 독립성을 테스트하는 방법입니다. 성능과 연관이 많은 피처는 나두고 그렇지 않은 피처는 제거합니다.
2. 상호-정보 피처 선택법(이사 상호 정보 선택법):중요한 피처만 선택하는 것은 카이제곱 선택법과 같지만, 실제로 계산하는 방법과 의미는 약간 다릅니다. 카이제곱 선택법이 각 피처가 모델의 성능에 얼마나 통계적으로 유의미한 기여를 하느냐를 검토한다면, 상호-정보 선택법은 선택한 피처 한 쌍이 서로 예측하는 데 얼마나 도움이 되느냐를 검토합니다. 결과적으로 상호-정보 선택법은 카이제곱 선택법보다 좀 더 자주 나오는 피처를 선택합니다.
3. 검증셋에서의 성능: 학습용 데이터에서 검증용 데이터를 따로 분리하여 피처의 일부만을 사용해서 모델을 학습한 후 검증셋에서의 성능 평가를통해 어떤 피처가 좋을지 측정합니다.
앞의 방법을 통해 전체 피처 셋에서 피츠를 하나씩 제외하거나, 아니면 아무것도 없는 상태에서 가장 많이 도움 되는 피처를 하나씩 추가하는 식으로 사용할 피처를 결정합니다.
8.2.2 데이터가 너무 적을때
데이터가 적을 때 할 수 있는 일은 그렇게 많지 않습니다. 다음과 같은 방법을 통해 약간이나마 개선해볼 수는 있습니다.
8.2.2.1 레이블된 데이터는 별로 없지만 일반적인 데이터가 많은 경우(표현형 학습)
이런 경우에는 먼저 데이터의 일반적인 특성을 배우는 학습을 휴행하여 얻어진 정보를 이용해서 추가로 학습하ㅕㄴ 어느 정도 효과를 볼 수 있습니다.
예를 들어 제품 리뷰를 받는 사이트에서 제품에 대한 리뷰가 호의적이거나 적대적인지 판단하는 모델을 만든다고 가정해 봅시다. 이 모델을 학습시키면 각 리뷰에 대해 '호의적' 또는 '적대적' 레이블이 붙어 있어야 합니다. 사용자가 리뷰를 작성할 때는 호의적 또는 적대적이라고 명시하지 않으므로 이런 데이터셋을 만들려면 사람이 수작업으로 각 리뷰가 어떤 성격인지 일일이 체크해야 합니다(별점 데이터가 있다면 4점 이상이면 호의적, 2점 이하면 적대적이라고 레이블하기도 하지만, 이 경웅에도 문장 단위의 호의적 또는 적대적 레이블은 어렵습니다). 이런 수작업 레이블이 없는 이뷰는 손쉽게 많은 양을 얻을 수 있습니다. 그렇다면 이러한 리뷰를 통해 리뷰의 일반적인 패턴(예를 들면 어떤 단어가 많이 나오는지 파악해서 단어의 의미를 추론)을 먼저 추출해서 리뷰를 잘 표현할 수 있는 간명한 표현ㅅ형을 만든 다음, 실제 레이블을 가진 리뷰를 표현형으로 변환한 뒤 이를 이용해 분류를 합니다. 이렇게 데이터 자체에 대해 알고 있는 정보의 도움을 받아서 성능을 향상할 수도 있습니다.
이러한 과정을 딥러닝에서는 표현형학습 혹은 비지도 선행학습 등의 분야에서 다룹니다. 유명한 방식으로는 오토인코더나 토픽 모델링이 있습니다. 이 중 토픽 모델링은 5.2절 '토픽 모델링'에서 다뤘습니다.
8.2.2.2 전이학습
전이학습은 성격이 다른 데이터셋(예를 들면 이미지와 텍스트 데이터)을 이용해서 학습시킨 모델을 현재 데이터셋에 적용하는 방법입니다. 넓은 의미로는 다른 데이터셋에서 얻은 정보를 이용해서 현재 문제의 성능을 향상시키는 방법도 포함합니다. 앞서 다룬 방법에서는 데이터 성격이 모두 같았지만, 전이 학습에서는 데이터 성격이 다릅니다. 예를 들어 리뷰 데이터 분석을 하는 경우 백과사전이나 제품의 이미지 등을 이용해 모델을 학습시킨 후, 그 모델을 이용해 리뷰가 호의적인지 적대적인지 예측하는 겁니다.
이렇게 다른 성격의 데이터를 이용하여 학습시킨 모델을 활용하는 방법은 생각보다 쉽지 않습니다. 다행이 딥러닝에서는 중간 레잉어를 공유하는 방식으로 생각보다 쉽게 이런 정보를 이용할 수 있습니다. 더 자세한 내용은 이 책의 범위를 벗어나므로 이런 정보가 있다는 정도만 알아두기 바랍니다.
8.1 모델 문제
지금부터 8.2절 '데이터 문제'에서 다룰 데이터 처리, 8.3절 '속도 문제 '에서 다룰 속도 향상 외에 모델 자체에서 비롯된 문제를 해결해서 모텔의 성능을 향상하는 방법을 크게 둘로 나눠 설명합니다. 첫 번째는 학습할 때는 잘 동작했는데 실제로 사용하니 성능이 생각보다 잘 나오지 않는 과학습(오버피팅, 과적합, 과적응) 문제를 해결하는 방안을 알아보고, 두 번째는 데이터에 적합한 모델을 효과적으로 찾는 방법에 대해 알아보겠습니다.
8.1.1 과학습
머신러닝 시스템 시스템을 기존 데이터로 학습시킨 후 평가했을 때는 좋은 성능이 나와 학습이 잘되었다고 판단했는데, 새로운 데이터에서 예상대로 성능이 나오지 않는 경우의 원인은 대부분 과 학습 때문입니다. 과학습은 말 그대로 모델이 과하게 학습 데이터에 집중한 나머지 필요 이상으로 패턴을 학습한 경우입니다. 다음 그림과 같은 경우를 들 수 있습니다.
그림 8-1 과학습의 예. 거시적으로는 선형 패턴(점선으로 표시)을 가지는 데이터인데 필요 이상으로 복잡하게 학습한 경우(실선으로 표시)
[그림 8-1]은 과학습의 한 예입니다. 그래프에서 x로 표시된 점은 관착된 데이터입니다. 얼핏 봐도 데이터가 왼쪽 아래부터 오른쪽 위까지의 선형 패턴을 가집니다. 이 데이터를 기반으로 X값이 7일 때의 Y 값을 예측한다면 11 정도가 될 겁니다. 그런데 전체적인 패턴을 무시한 채 학습 데이터를 완벽하게 예측하는 것에만 중점을 두어 모든 점을 지나는 선을 모델로 만들게 되었습니다. 그 결과 실선과 같은 과학습된 모델을 가지게되고 X값이 7일 때의 Y값을 제대로 예측할 수 없게 된 겁니다.
그렇다면 이문제를 어떻게 해결해야 할까요? 그리고 이런 현상이 일어날지 어떻게 미리 알 수 있을까요? 2.1.5.2절 '정규화'와 2.4.1절 '모델의 일반화 특성 평가'에서 이론상으로 다룬 바 있습니다. 이제부터 과학습을 해결하는 실용적인 방법을 알아보겠습니다.
8.1.1.1 학습- 평가 데이터 나누기
과학습 문제를 발견하는 가장 효과적인 방법은 전체 데이터의 일부분만으로 모델을 학습시키고 나머지 데이터를 이용해 모델을 평가해서 얼마나 데이터의 일반적인 패턴을 잘 학습하는지 판단 하는 겁니다. 일반적인 패턴을 잘 파악하지 못하는 모델은 그렇지 않은 모델에 비해 학습용 데이터에서는 좋은 성능을 보이지만, 평가용 데이터에서는 성능이 잘 나오지 않는 현상을 보이게 됩니다. 자세한 내용은 2.4.1절 '모델의 일반화 특성 평가'를 참조하세요
8.1.1.2 정규화
모델의 정규화는 바로 이런 과학습 문제를 해결하기위해 등장했습니다. 정규화는 데이터를 설명할 수 있는 가장 간단한 가정만을 사용한다는 '오컴의 면도날 가정'을 이용하여 과학습을 막습니다. [그림 8-1]을 보면 데이터의 패턴을 설명하기에는 점선이 실선으로 표시된 복잡한 모델보다 더 간단합니다. 이렇게 데이터의 패턴을 복수의 가정으로 설명할 때는 데이터의 패턴에서 심하게 벗어나지 않으면 되도록 간단한 가정을 사용하는 것이 좋습니다.
2.1.5.2절 '정규화'에서 설명했듯이 '데이터의 패턴에서 너무 벗어나지 않는 것'과 '더 간단한 모델을 사용하는 것'의 균형은 정규화 파라미터로 결정합니다. 그렇다면 그 파라미터를 어떻게 결정해야 할 까요? 2.4.1절 '모델의 일반화 특성 평가'에서 설명한 것과 같이 정규화 파라미터를 결정하는 데이터셋을 따로 빼놓고 학습하는 방법을 많이 사용합니다.
정규화 파라미터가 실제로 어떻게 영향을 미치는지 간단한 예제를 통해 알아보겠습니다. 사이킷런의 linear_model.Ridge 클래스는 정규화 파라미터를 지원하는 선형 회귀 클래스입니다. 클래스의 원형은 다음과 같습니다.
class sklearn.linear_model.Ridge(alpha=1.0, fit_intercept=True, normalize=False, copy_X=True, max_iter=None, tol=0.001, solver='auto', random_State=None)
여기서 정규화와 관련된 파라미터는 alpha인테, 값이 클수록 정규화의 강도가 더욱 강해집니다.
실제로 어떻게 문제가 발생하는지 시각적으로 보여드리기 위해 2차 함수를 따르는 데이터를 만든 후 10차 함수 형태의 모델을 사용하는 경우를 알아보겠습니다(현샐에서는 데이터가 몇 차원 함수를 따르는지 알 수 없으므로 임의로 높은 차원을 가정합니다). 여기서는 구현보다는 어떻게 되는지 설명에 집중하기 위해 자세한 코드는 생략하도록 하겠습니다.
데이터는 다음과 같은 가우스 분포도 생성되었습니다.
y = x*x -2x -1 + 노이즈
그리고 우리 모델은 10차 함수 형태까지 학습할 수 있는 능력을 가진 10차 다항함수를 사용했습니다. 수식으로 나타내면 학습과정에서 상수 부분까지 모두 11개의 파라미터(w10, w9,...w0)를 학습하게 됩니다.
모델이 표현할 수 있는 한계(10차 함수)가 실제 데이터(2차 함수)보다 훨씬 높죠? 이런 경우에 과학습이 심하게 발생할 수 있습니다. 과학습이 나타나는 현상을 실제로 ㄹㄴ덤한 데이터를 만들고 학습해서 시각화해보겠습니다. 먼저 정규화 없이 그냥 모델을 단순하게 학습시킨 결과를 살펴보겠습니다.
[그림 8-2]를 보면 단순히 오목하게 생긴 2차 함수의 패턴을 학습하면 되는데 모델이 필요 이상으로 복잡해서 굉장히 구불구불한 모양으로 학습된 것을 볼 수 있습니다. 똑같은 데이터에 정규화 파라미터 alpha값을 증가시켜 보겠습니다.
그림 8-3 정규화가 있을 때(alpha=0.1)의 변화
[그림 8-2]에 비해 곡선이 훨씬 부드러워졌습니다. 다시 말해, 모델이 표현 가능한 범위보다 좀더 간단한 모델을 사용하도록 강제된 것을 확인할 수 있습니다.
그림 8-4 정규화가 좀 더 강할 때(alpha =1)
[그림 8-4]는 [그림 8-3]보다 더욱 강하게 정규화 값을 설정한 경우입니다. 곡선이 좀 더 부르러워져서 더 간단한 모델이 되었습니다.
이렇게 정규화 파라미터를 조절하면서 필요 이상으로 복잡한 패턴을 학습하지 않도록 머신러닝 모델을 조절할 수 있습니다. 그렇다면 적절한 파라미터 값은 어떻게 찾을 수 있을까요?
그림 8-5 검증용 데이터를 나누어 정규화 파라미터 정하기
1. 데이터를 학습 및 검증용(A)과 테스트(B)으로 나눕니다.
2. A를 다시 학습용(C)와 검증용(V)로 나눕니다.
3. 학습용 데이터에 대해 정당한 정규화 파라미터로 학습을 수행한 후 검증용 데이터를 사용해 성능을 측정합니다. 반봅해서 V에서 가장 성능이 좋은 정규화 파라미터를 찾습니다.
4. 과정 3에서 찾은 정규화 파라미터를 이용해서 A에 대해 학습을 수행합니다.
5. 모델 자체에 대한 평가는 B로 하면 됩니다.
과정 2부터 4까지는 교차 검증을 이용해도 됩니다. 교차검증은 2.4.1.2절 '교차검증'을 참조하기 바랍니다.
8.1.1.3 학습을 일찍 끝내기
정규화와 비슷하지만 훨씬 더 간단한 방식이 있습니다. 이 방식은 딥러닝에서 주로 사용되지만, 그 외의 분야에서도 많이 쓰이고 있습니다. 우선 아래 그래프에서 과학습이 되는 시점에 주안점을 두어 살펴보고 이야기를 더 진행하겠습니다.
그림 8-6 머신러닝 모델을 학습할 때 일반적으로 보게 되는 학습 데이터와 테스트 데이터에서의 손실 곡선
[그림 8-6]은 머신러닝 모델을 학습할 때 보게 되는 일반적인 손실 그래프입니다. 위에 있는 고선이 테스트 데이터에서의 손실, 아래 있는 곡선이 학습 데이터에서의 손실입니다. 학습 데이터에서의 손실은 학습을 진행할수록 줄어드는데, 테스트 데이터에서의 손실은 학습데이터에 모델이 과하게 최적화된 이후 오히려 늘어나게 됩니다. 손실이 늘어나기 시작하는 지점이 바로 과학습의 시작점입니다. 이 지점 이전까지는 학습 효과가 좋았으므로 과학습이 나타나는 시점까지만 학습하면 과학습을 예방할 수 있게 됩니다. 물론 '어느 시점'에 그만둘지 결정하는 것은 쉬운 일이아닙니다. 하지만 정규화가 쉽게 되지 ㅏㅇㄶ는 모델에는 이 방식을 더 유욯하게 사용할 수 있습니다.
딥러닝으로 유명한 힌튼 교수는 '일찍 끝내기(early stopping)는 아름다운 공짜 점심'이라고 표현했습니다. 아주 쉽고 거의 공짜로 이득을 본다는 뜻이죠. 실제로 현업에서도 학습을 완전히 수행하기보다는 최대 몇 번까지 반복한다고(예를 들어 100번) 적당히 정해놓고 학습을 하는 식으로 많이 사용합니다.
8.1.1.4 드롭-아웃(딥러닝 기법)
딥러닝에는 뉴렐넷의 과학습을 예방하는 방법으로 드롭-아웃(drop-out)을 널리 사용합니ㅏㄷ. 본 개념을 먼저 살표고벴습니다.
드롭-아웃은 딥러닝 모델으 ㄹ학습할 때 레이어와 레이어를 잇는 연결 중에서 일정한 확률 p로 몇 가지 연결을 무작위로 끊은 채 학습합니다. 즉, 학습이 진행될 때(파라미터를 업데이트 할 때) 마다 연결이 조금씩 달라진 상태로 딥러닝 모델을 학습하게 됩니다.
1. 아래와 같은 딥러닝 모델이 있다고 합시다. 동그라미는 레이어고, 선은 그것을 잇는 가중치 연결입니다.
2. 학습중 일부 업데이트는 아래와 같이 확률 p에 따라 레이어 연결을 임의로 몇 개 누락시키고 업데이트합니다.
3. 또 다른 업데이트는 다른 패턴으로 임의로 몇 개 누락시키고 업데이트 합니다.
4. 학습이 모두 끝난 후 모델을 실제로 사용할 때는 모든 연결을 사용하지만 p 만큼 연결의 강도를 약화시켜서 사용합니다.
드롭-아웃을 이용한 딥러닝 모델 학습이나 학습된 모델을 사용하는 방법 자체는 앞에서 설명한 것처럼 상당히 간단합니다. 연결을 무작위로 끊으면서 학습하고, 학습된 모델을 사용할 때는 연결 강도를 조절하면 됩니다. 또한 텐서플로에서 라이브러리로 제공하므로 그냥 가져다 쓰면 됩니다. 하지만 왜 이렇게 하는 것이 정규화에 도움이 되는지 이해하기 쉽지 않을 겁니다. 그 이유를 순서에 입각하여 살펴보면 다음과 같습니다.
1. 학습 시 연결을 임의로 몇 개를 끊으면 모델이 더 '간단하게'됩니다.
2. 간단한 모델로 학습하면 원래 모델보다 조금 제한된 모델로 학습이 이루어지게 되고 결과적으로 필요 이상으로 모델이 데이터의 복잡한 패턴을 학습하는 것을 방지하는 효과를 발휘하게 됩니다.
3. 이 과정을 반복하면 간단한 모델들의 밈의 조합을 이용해서 데이터를 설명하려는 시도를하게됩니다.
4. 그 결과 모델은 피처와 레이어 사이의 연결 가능한 모든 레이어 간의 조합에 대해 학습을 수행하는 것이 아니라 적은 연결로 전체를 설명하는 방향으로 학습하게 됩니다.
이 과정은 앞에서 설명한 정규화와 비슷하게 모델을 단순화시키는 효과를 볼 수 있습니다. 드롭-아웃은 구현이 쉬우면서도 딥러닝 모델의 성능을 늘리는데 매유 효과적입니다. 만일 딥러닝기법을 사용한다면 도입을 꼭 고려해보기 바랍니다. 참고로 텐서플로에서는 이 기능을 깁본으로 지원합니다.
8.1.2 좋은 모델을 좀 더 수월하게 찾는 방법
머신러닝은 모델에 따라 성능이 크게 좌우됩니다. 딥러닝이 발전하고 데이터양이 증가하면서 모델 자체에 대한 고민은 예전보다 적어진 듯 보이지만, 그럼에도 더 좋은 성능을 얻으려면 더 데이터에 적합한 모델을 이용하여 학습해야 합니다. 따라서 모델의 중요성은 아무리 강조해도 지나치지 않습니다.
이절에서는 데이터에 적합한 모델을 효과적으로 찾는 방법에 대해 알아보겠습니다. 1장과 2장에서도 잠깐 어급했지만'머신러닝을 적용한다'는 것은 '데이터에 적합한 모델과 학습 방법을 차즌ㄴ 일련의 과정을 적용한다'는 뜻입니다. 특히 적합한 모델을 찾는 것은 핵심입니다.
그렇다면 어떻게 하면 적합한 모델을 쉽게 찾을 수 있을 까요? 다음과 같은 방법을 생각할 수 있습니다.
- 간단한 모델부터 적용하기
- 데이터와 모델 시각화 하기
- 모델의 최대 성능 가늠하기
8.1.2.1 간단한 모델부터 적용하기
가장 중요한 원칙은 처음부터 복잡한 모델을 곧바로 적용하는 것이 아니라 간단한 모델을 적용시켜서 성능을 확인해보는 것입니다. 어차피 복잡한 모델이 더 좋은 성능을 낼 확률이 높은데 왜 굳이 시간을 낭비하는지 의문이 들 수도 있을 겁니다. 간단한 모델 부터 테스트해보는 데는 다음과같은 이유가 있습니다.
간단한 모델은 구현이쉽고 학습도 쉽습니다.
대부분의 머신러닝 라이브러리는 선형 휘귀, 로지스틱 휘귀, 레이어가 1개인 뉴런넷 모델 등 간단한 모델을 제공하고 있어 손쉽게 시도할 수 있고 학습도 굉장히 빠릅니다. 또한 적은 학습과 정 튜닝으로 최대의 성능을 쉽게 확인할 수 있습니다. 복잡한 모델은 구현, 학습, 그리고 파라미터 튜닝에 오랜 시간이 걸립니다.
간단한 모델의 성능은 다른 모델이 얼마나 잘 동작하는지에 대한 지표가 됩니다.
간단한 모델을 실제 시스템에 사용하지 않더라도 그 성능을 더 복잡합 모델의 성능 지표로 삼을 수 있습니다. 복잡한 모델의 1차 구현물이 간단한 모델의 성능보다 월등히 좋지 않다면 뭔가 개선 방법을 찾아야 합니다. 반대로 간단한 모델보다 성능이 좋다면 모델이 잘 작동한다고 판단하고 튜닝에 돌입하면 됩니다.
간단한 모델은 원인을 파악하기가 상대적으로 쉽습니다.
모델의 성능이 떨어지는 원인은 다양합니다. 데이터 처리 버그, 모델의 학습방법, 아니면 그냥 문제 자체가 예측이 어려운 경우일 수도 있습니다. 이유가 뭐든 간단한 모델일 때보다 복잡한 모델에서 문제의원인을 찾기가 상대저그로 어렵다는 건 두말할 필요 없을 겁니다. 먼저 간단한 모델을 사용해서 전체가 잘 동작하는지 검증한 후 복잡한 모델을 적용하기 바랍니다.
8.1.2.2 데이터와 모델 시각화하기
데이터를 시각화해보는 것도 적합한 모델을 찾는데 도움이 됩니다. 하지만 추가 노력이 들기 때문에 생략하는 경우도 적지 않습니다. 전체 데이터를 완전히 시각화하지 않더라도 패턴을 살펴볼 수 있는 수준이면 도움이 됩니다. 그 이유는 다음과 같습니다.
데이터 이상 파악
예를 들어 일반적인 선형 회귀를 해보려고 생각하고 있었는데, 데이터를 시각화해보니 데이터가 선형적인 양상이 아니라 로그 스케일을 따른다든가, 소수점 단위를 예상하고 있었는데 음수가 나온다든가, 혹은 기본값이 특이하게 들어 있는 경우를 생각할 수 있습니다. 실숫값을 기대하고 있었는데 정숫값만 존재하거나 카테고리 ID가 들어오는 경우처럼 데이터 자체에 대한 가정에 문제가 잇는지 등도 파악하기 좋습니다.
데이터 특성 파악
데이터를 분석할 때 가장 기본적인 것은 데이터가 정규 분포를 따른다고 가정하느 것입니다. 대부분의 경우에는 큰 무리가 없지만, 가끔 데이터가 정규분포를 크게 벗어난느 경우가 있습니다. 예를 들어[그림8-7]과 같이 데이터가 한개 의 정규분포(가우스분포)를 따르지 않는 경우입니다. 이 경우에는 2개의 정규분포를 포함하는 머신러닝 기법이 적합합니다.
모델 동작 방식 이해
데이터를 시각화 하는 것과 함께 모델의동작 결과를 시각화하는 것도 많은 도움이 됩니다. 예를 들어 분류 모델의 경우에는 모델이 각 데이터 포인트를 어떻게 분류하는지, 희귀모델의 경우에는 모델이 출력하는 결괏값이 어떻게 분포된느지 시각화하면 모델이 어떤 방시긍로 동작하는지 이해하는 데 도움이 됩니다.
시각화는 이책의 여러붑ㄴ에서 쓰였는데, 8.2.3.2 절'데이터의 값이 치우쳐 있을 때'에서는 데이터를 시각화에서 데이터의 편중 정도를 파악하고, 8.1.1.2절 '정규화'에서는 모델을 시각화해서 실제로 정규화가 모델에 어떻게 영향을 미치는지 살펴 보았습니다.
아래 URL에 방문하면 사이킷런에서 사용할 수 있는 다양한 시각화 예제를 확인할 수 있습니다.
http://scikit-learn.org/stable/suto_examples/
|2차원 이상의 데이터 시각화하기|
2차원 이상의 데이터를 시각화하는 일은 쉽지 않습니다. 데이터들의 상관관계를 이용해서 2차원으로 관곌르 재정의해서 그리는 방법이 있는데, 데이터의 절대좌표를 직접 입력하는 것이 아니라 한 데이터의 위치가 다른 데이터와 얼마나 다른지 상대거리를 이용해서 시각화하게 됩니다. 그리고 데이터의 절대거리보다는 근처에 있는 점들과의 관계를 보존하는 방법으로 시각화합니다. 이런 경우에 t-SNE 같은 방법이 특히 많이 이용됩니다. 예를 들어 텐서플로 튜터리얼에서 t-SNE를 사용하여 단어 벡터들을 시각화한 예를 착을 수 있습니다. 더 자세한 사항은 해당 튜터리엉ㄹ을 참고하세요. 대표적으로 Isomap, L.I.E, MIDS와 같은 방법이 있습니다. 자체한 사항은 사이킷런 홈페이지를 참고하세요.
8.1.2.3 모델의 최대성능 가늠하기
구현한 모델이 99.99% 정확도를 보인다면 더할 나위 없겠죠, 반대로 성능이 너무 좋지 않나면 더 적극적으로 새로운 모델을 찾아봐야 할 겁니다. 그러면 과연 성능이 얼마나 좋은지 어떻게 판단 할 수 있을까요? 지금 얻은 성능의 수치는 낮지만 사실 엄청나게 잘하고 있는것 아닐까요? 단순히 성능 수치만으로는 애매한 부분이 있기 때문에 가능한 한 최고 성능르 가늠해보고 현재 어느 정도 수준인지 판단하는 것이 중요합니다.
물론 최고 선을을 가늠하는 것은 쉽지 않은 일입니다. 대에 따라 다르겠지만 다음과 같은 시나리오를 생각할 수 있습니다.
머신러닝 시스템과 사람의 성능 비교
사람의 직접 해당 일을 수행했을 때 얻을 수 있는 정확도 등의 예측 성능은 좋은 지표가 됩니다. 예를 들어 몇 명의 수동으로 이미지에 보이는 몰체를 태깅하거나 분류한 다음 평균 성능을 평가하여 머신러닝 시스템이 얼마나 잘 동작하는지 가늠해보는 겁니다. 예를 들어 아마존 메커니컬 피크는 수많은 사람에게 태깅을 부탁하고 소액을 지불하는 크라우드 소싱을 이용합니다. 만일 사람조차도 공통 의견을 만들기가 쉽지 않다면 머신러닝 시스템도 좋은 성능을 내기 쉽지 않을 겁니다.
이론상 성능의 한계나 보장된 값이 존재할 때
데이터에 따라 다소 제한적이긴 하지만 보장된 성능이 존재하는 경유가 있습니다. 예를 들어 제품의 불량률이 정해져 있고, 센서가 얻을 수 있는 불량에 대한 정보에 한계치가 있다면, 이 두요소에 의존하여 불량을 판볻하는 시스템의 성능에는 한계가 있겠죠. 이와 같은 정보를 미리 알면 현재 머신러닝 시스템이 얼마나 잘 동작하는지 알 수 있습니다.
8.2 데이터 분제
학습 데이터가 어떻게 구성되어 있는지에 따라 학습 성능이 크게 달라집니다. 이 장에서는 데이터가 너무 많거나 너무 적거나, 아니면(가장 일반적인) 치우침이 심할 때 어떻게 하면좋을지 살펴보겠습니다. 참고로 8.1.2.2절 '데이터와 모델 시각화하기'에서 언급한 데이터 시각화도 이런 데이터의 특성을 이해하는데 도움이 됩니다.
8.2.1 데이터가 너무 많을때
앞서 머신러닝에서 데이터가 많을 수록 좋다고 언급했습니다. 이론상으로는 데이터가 많을 수록 성능이 좋은 모델을 얻을 수 있지만, 데이터가 많으면 처리 시간이 오래 걸리기 때문에 문제가 될 수 있습니다. 특히 같거나 비슷한 데이터가 많이 들어오는 경우를 생각해 봅시다. 예를 들어 1분마다 물체의 움직임을 감지하여 데이터를 송신하는 센서를 이용하여 물체의 이동 곙로를 학습하는 모델을 만들려고 할 때 물체가 거의 정지해 있다면 대부붕의 데이터가 움직임 없음(0)으로 채워질 겁니다. 또 다른 경우는 특정 분류 항목의 데이터가 너무 많아서 전체 적으로 학습이 오래 걸리는데 그렇지 않은 항목은 적은 경우가 있습니다. 예를 들어 사진 데이터에서 하늘이나 구름 사진은 어첨 많은데 휘귀한 동뭀진은 적은 경우가 있습니다. 이를 해결하기 위해 다음과 같은 방법을 생각해 볼 수 있습니다.
과소표집
과소표집(언더샘플링)은 전체 데이터셋에서 데이터를 무작휘 확률로 선택해서 선택된 데이터로 이우러진 작아진 데이터셋을 사용하는 방식입니다. 데이터를 무작위로 선택하는 방법은 다양하지만, 가장 중요한점은 데이터의 특성과 상관없이 뽑아야 한다는 것입니다. 예를 들어 사용자 구매 이력 데이터에서 50%확률로 데이터를 뽑는것은 괜찮지만, 사용자 이름 가나다순으로 정렬된 데이터셋의 앞부분 절반만 사용하는 것은 데이터으 ㅣ특성을 바꿀 수 있기 때문에 안됩니다.
중요도 표집
중요도 표짐(중요도 샘플링)은 데이터의 중요도에 따라 선택 확률을 변도하여 샘플링하는 기법이다. 무작위 확률로 선택하다 보면 특정 경우에 해당하는 데이터가 거의 없어지는 문제가 발생할 수 있습니다. 예를 들어 이미지 분류 문제를 푼다고 가정합시다. 학습용 데이터에서 '하늘'에 해당하는 이미지는 엄청 많은데 '오리너구리'에 해당하는 이미지는 적다고 합시다. 이런 경우 이미지를 무작위로 선택하면 오리너구리 이미지는 정말로 적은 수만 남게 됩니다. 그러면 오리너구리에 대한 학습이 제대로 이루어지지 못하겠죠. 이런 경우에는 데이터의 중요도에 따라 선택확률을 변동시키는 방법이 더 적합합니다. 예를 들어 하늘에 해당하는 사진은 10%의 확률로 뽑고 오리너구리 사진은 너무 개수가 적으니 80%의 확률로 뽑는 방법을 고려 할 수 있습니다.
피처 선택
'피처 선택'은 중요한 피처만 선택해서 전체 학습률과 성능을 증가시키는 방법입니다. 피처가 많으면 학습에 사용하는 데이터가 많아 학습률이 느려지고, 모델이 복잡해져서 과학습을 할 우려가 있습니다. 피처를 고르는 방법으로 '카이제곱 피처 선택법', '상호-정보 피처 선택법', '검증셋에서의 성능'이 주로 사용됩니다. 어떤 방법을 사용하든 성능에 도움이 되는 피처는 고르고 그렇지 않은 피처는 삭제하는 방향으로 진행됩니다.
1. 카이제곱 피처 선택법(이하 카이제곱 선택법): 피처와 성능 간의 통계학적 독립성을 테스트하는 방법입니다. 성능과 연관이 많은 피처는 나두고 그렇지 않은 피처는 제거합니다.
2. 상호-정보 피처 선택법(이사 상호 정보 선택법):중요한 피처만 선택하는 것은 카이제곱 선택법과 같지만, 실제로 계산하는 방법과 의미는 약간 다릅니다. 카이제곱 선택법이 각 피처가 모델의 성능에 얼마나 통계적으로 유의미한 기여를 하느냐를 검토한다면, 상호-정보 선택법은 선택한 피처 한 쌍이 서로 예측하는 데 얼마나 도움이 되느냐를 검토합니다. 결과적으로 상호-정보 선택법은 카이제곱 선택법보다 좀 더 자주 나오는 피처를 선택합니다.
3. 검증셋에서의 성능: 학습용 데이터에서 검증용 데이터를 따로 분리하여 피처의 일부만을 사용해서 모델을 학습한 후 검증셋에서의 성능 평가를통해 어떤 피처가 좋을지 측정합니다.
앞의 방법을 통해 전체 피처 셋에서 피츠를 하나씩 제외하거나, 아니면 아무것도 없는 상태에서 가장 많이 도움 되는 피처를 하나씩 추가하는 식으로 사용할 피처를 결정합니다.
8.2.2 데이터가 너무 적을때
데이터가 적을 때 할 수 있는 일은 그렇게 많지 않습니다. 다음과 같은 방법을 통해 약간이나마 개선해볼 수는 있습니다.
8.2.2.1 레이블된 데이터는 별로 없지만 일반적인 데이터가 많은 경우(표현형 학습)
이런 경우에는 먼저 데이터의 일반적인 특성을 배우는 학습을 휴행하여 얻어진 정보를 이용해서 추가로 학습하ㅕㄴ 어느 정도 효과를 볼 수 있습니다.
예를 들어 제품 리뷰를 받는 사이트에서 제품에 대한 리뷰가 호의적이거나 적대적인지 판단하는 모델을 만든다고 가정해 봅시다. 이 모델을 학습시키면 각 리뷰에 대해 '호의적' 또는 '적대적' 레이블이 붙어 있어야 합니다. 사용자가 리뷰를 작성할 때는 호의적 또는 적대적이라고 명시하지 않으므로 이런 데이터셋을 만들려면 사람이 수작업으로 각 리뷰가 어떤 성격인지 일일이 체크해야 합니다(별점 데이터가 있다면 4점 이상이면 호의적, 2점 이하면 적대적이라고 레이블하기도 하지만, 이 경웅에도 문장 단위의 호의적 또는 적대적 레이블은 어렵습니다). 이런 수작업 레이블이 없는 이뷰는 손쉽게 많은 양을 얻을 수 있습니다. 그렇다면 이러한 리뷰를 통해 리뷰의 일반적인 패턴(예를 들면 어떤 단어가 많이 나오는지 파악해서 단어의 의미를 추론)을 먼저 추출해서 리뷰를 잘 표현할 수 있는 간명한 표현ㅅ형을 만든 다음, 실제 레이블을 가진 리뷰를 표현형으로 변환한 뒤 이를 이용해 분류를 합니다. 이렇게 데이터 자체에 대해 알고 있는 정보의 도움을 받아서 성능을 향상할 수도 있습니다.
이러한 과정을 딥러닝에서는 표현형학습 혹은 비지도 선행학습 등의 분야에서 다룹니다. 유명한 방식으로는 오토인코더나 토픽 모델링이 있습니다. 이 중 토픽 모델링은 5.2절 '토픽 모델링'에서 다뤘습니다.
8.2.2.2 전이학습
전이학습은 성격이 다른 데이터셋(예를 들면 이미지와 텍스트 데이터)을 이용해서 학습시킨 모델을 현재 데이터셋에 적용하는 방법입니다. 넓은 의미로는 다른 데이터셋에서 얻은 정보를 이용해서 현재 문제의 성능을 향상시키는 방법도 포함합니다. 앞서 다룬 방법에서는 데이터 성격이 모두 같았지만, 전이 학습에서는 데이터 성격이 다릅니다. 예를 들어 리뷰 데이터 분석을 하는 경우 백과사전이나 제품의 이미지 등을 이용해 모델을 학습시킨 후, 그 모델을 이용해 리뷰가 호의적인지 적대적인지 예측하는 겁니다.
이렇게 다른 성격의 데이터를 이용하여 학습시킨 모델을 활용하는 방법은 생각보다 쉽지 않습니다. 다행이 딥러닝에서는 중간 레잉어를 공유하는 방식으로 생각보다 쉽게 이런 정보를 이용할 수 있습니다. 더 자세한 내용은 이 책의 범위를 벗어나므로 이런 정보가 있다는 정도만 알아두기 바랍니다.
피드 구독하기:
글 (Atom)