이번 시간 학습 목표는
🥕 경사하강법 알고리즘 이해하기
입니다!!
새롭게 해결해야 할 문제는 앞으로 계속 머신러닝 모델을 학습할 샘플 데이터들이 추가될거고 모든 생선이 도착할 때까지 기다릴 수는 없는 상황입니다. 데이터가 점점 늘어나면서 늘어나는 데이터를 반영해서 매일 모델을 학습 시키는 것은 서버 등 학습 자원에 대한 부담이 커집니다.
이를 해결하기 위해 앞서 훈련한 모델을 버리지 않으면서 새로운 데이터에 대해서 조금씩 더 훈련하는 훈련 방식을 점진적 학습 혹은 온라인 학습 이라고 합니다.
대표적인 점진적 학습 알고리즘은 확률적 경사하강법 입니다.
경사 하강법은 경사를 따라 내려가는 방법을 말합니다. 훈련 세트를 사용해 모델을 훈련할 때, 경사 하강법으로 가장 가파른 길을 찾으면서 전체 샘플이 아닌 랜덤하게 샘플을 고른다는 점에서 확률적 이라는 표현을 씁니다.
확률적 경사 하강법은 훈련 세트에서 랜덤하게 하나의 샘플을 선택하여 가파른 경사를 조금 내려갑니다. 전체 샘플을 모두 사용할 때까지 이 과정을 계속합니다. 만약 모든 샘플을 다 사용해도 경사를 다 내려오지 못한 경우에는 처음부터 다시 시작합니다. 이렇듯 확률적 경사 하강법에서 훈련 세트를 한 번 모두 사용하는 과정을 에포크라고 부릅니다.
확률적 경사 하강법
- 훈련 세트에서 샘플 하나씩 꺼내 손실 함수의 경사를 따라 최적의 모델을 찾는 알고리즘
- 미니배치 경사 하강법: 샘플을 하나씩 사용하지 않고 여러 개를 사용
- 배치 경사 하강법: 한번에 전체 샘플을 사용
샘플을 한개씩 사용하지 않고 여러개씩 선택해서 경사를 내려가는 것을 미니배치 경사 하강법이라고 합니다. 그리고 극단적으로 한번 경사로를 이동하기 위해 전체 샘플을 사용하는 것을 배치 경사 하강법이라고 합니다. 하지만 전체 데이터를 사용하면 그만큼 컴퓨터 자원을 만힝 사용하기 때문에, 데이터가 너무 많은 경우에는 한번에 처리하기 어려울 수 있습니다.
에포크:
- 확률적 경사 하강법에서 전체 샘플을 모두 사용하는 한 번의 반복을 의미
- 일반적으로 경사 하강법 알고리즘은 수십에서 수백 번의 에포크를 반복
확률적 경사 하강법에서 가장 빠른 길을 찾아 내려가는 것은 손실 함수를 대상으로 합니다. 손실 함수는 모델이 얼마나 틀렸는지를 의미합니다.
손실 함수
- 확률적 경사 하강법이 최적화할 대상
- 이진 분류에는 로지스틱 회귀(또는 이진 크로스엔트로피) 손실 함수 사용
- 다중 분류에는 크로스엔트로피 손실함수 사용
- 회귀 문제에는 평균 제곱 오차 손실 함수를 사용
경사 하강법이 조금씩 내려와야 하기 때문에 손실 함수는 미분 가능, 즉 연속적이어야 합니다.
손실함수를 만들기 위해 샘플 4개의 예측 확률이 0.9, 0.3, 0.2, 0.8 이라고 가정해보겠습니다. 첫 번째 샘플부터 하나씩 어떻게 손실 함수를 만들 수 있는지 살펴볼게요.
첫 번째 샘플의 예측은 0.9이므로 양성 클래스의 타깃인 1과 곱한 다음 음수를 취하면 -0.9 입니다. 예측이 1에 가까울 수록 좋은 모델이며 예측값이 커질수록 손실함수는 작아지기 때문에 손실함수로 적절해 보입니다.
두 번째 샘플의 예측은 0.3이고 타깃은 1입니다. 마찬가지로 타깃을 곱하고 음수로 바꾸면 -0.3입니다. 첫번째 샘플보다 높은 손실이며 실제로 두번째 샘플은 예측이 틀렸기 때문에 알맞게 구해진 것 같습니다.
세 번째 샘플은 타깃이 음성 클래스라 0입니다. 하지만 예측 확률과 곱하면 무조건 0이 되기 때문에 이 때는 타깃을 마치 양성 클래스처럼 바꾸어 1로 만들고 대신 예측값도 양성 클래스에 대한 예측으로 바꿉니다. 즉 1-0.2 = 0.8로 만든 후, 첫 번째나 두 번째 샘플처럼 곱하고 음수로 바꾸어 줍니다.
네 번째도 이런 방식으로 계산하면 연속적인 손실 함수를 얻을 수 있을 듯합니다.
예측 확률에 로그 함수를 적용해보겠습니다. 예측 확률의 범위는 0~1 사이인데 로그 함수는 이 사이에서 음수가 되므로 최종 손실 값은 양수가 됩니다. 로그 함수는 0에 가까울수록 아주 큰 음수가 되기 때문에 손실을 아주 크게 만들어 모델에 큰 영향을 미칠 수 있습니다.
타깃 = 1 일때,
타깃 = 0 일때,
이렇게 정의된 손실함수를 로지스틱 손실함수 또는 이진 크로스엔트로피 손실 함수 라고 합니다.
다중분류에서도 비슷한 손실 함수를 사용하는데, 크로스엔트로피 손실 함수라고 부릅니다.
손실함수
- 이진분류: 로지스틱 손실 함수
- 다중분류: 크로스엔트로피 함수
- 회귀: 평균 제곱 오차(mean squared error)
사이킷런에서 확률적 경사 하강법을 제공하는 대표적인 분류용 클래스인 SGDClassifier로 모델 학습을 해보겠습니다.
우선 훈련세트와 테스트 세트를 만들고 표준화 전처리를 수행합니다.
꼭 훈련 세트에서 학습한 통계값으로 테스트 세트도 변환해야 합니다.
SGDClassifier 객체를 만들 때 2개의 매개변수를 지정합니다. loss는 손실 함수의 종류를 지정하고 max_iter는 수행할 에포크 횟수를 지정합니다.
loss='log', max_iter=10 으로 지정해서 학습해보겠습니다.
모델 정확도가 낮은 이유는 반복 횟수 10회가 부족한 것으로 보입니다.
확률적 경사하강법은 점진적 학습이 가능하기 때문에 훈련한 모델 sc를 추가로 더 훈련해볼게요. 모델을 이어서 훈련할 때는 partial_fit( ) 매서드를 사용합니다. 이 매서드는 호출할 때마다 1 에포크씩 이어서 훈련합니다.
정확도가 향상되긴했지만 더 훈련을 하면 좋을 것 같습니다. 그렇다면 얼마나 더 훈련을 해야할까요?
확률적 경사 하강법을 사용한 모델은 에포크 횟수에 따라 과소적합이나 과대적합이 될 수 있습니다.
에포크 횟수가 적으면 모델이 훈련세트를 덜 학습해서 과소적합이되고 에포크 횟수가 충분히 많으면 훈련 세트를 완전히 학습합니다. 하지만 에포크 횟수가 너무 많으면 모델은 훈련 세트에 너무 맞아 테스트 세트에는 점수가 나쁜 과대적합 모델이 될 가능성이 있습니다.
훈련 세트 점수는 에포크가 진행될수록 꾸준히 증가하지만 테스트 세트 점수는 어느 순간 감소하기 시작합니다. 이 지점이 모델이 과대적합되기 시작하는 지점입니다. 과대적합이 시작하기 전에 모델 학습을 종료하는 것을 조기 종료라고 합니다.
그렇다면 실제로 에포크별 훈련세트와 테스트 세트의 정확도를 나타내는 위 그래프를 그려보겠습니다.
훈련세트와 테스트 세트의 점수를 기록할 리스트를 만들어줍니다. 그리고 fit( ) 매서드가 아닌 partial_fit( ) 매서드만 사용할건데요, 이 메서드는 훈련 세트에 있는 전체 클래스의 레이블을 전달해줘야 합니다. train_target의 7개 생선 목록을 np.unique( ) 함수를 사용해서 만들어줍니다.
에포크 300번 동안 훈련을 반복해서 진행합니다.
100번째 에포크 이후에는 훈련 세트와 테스트 세트의 점수가 조금씩 벌어지고 있습니다. 이 모델은 100번째 에포크가 적절한 반복 횟수인 것 같네요.
반복 횟수를 100에 맞추고 다시 모델을 훈련해보겠습니다.
SGDClassifier는 일정 에포크 동안 성능이 향상되지 않으면 자동으로 훈련을 멈추는 기능이 있습니다. tol 매개변수에서 향상될 최솟값을 지정합니다.
SGDClassifier loss 매개변수
- hinge: loss 매개변수의 기본값으로 힌지 손실은 서포트 벡터 머신이라 불리는 또 다른 머신러닝 알고리즘을 위한 손실 함수
마지막으로 힌지 손실을 사용해서 같은 에포크 동안 모델을 훈련해보겠습니다.
출처: 한빛미디어