핵심 키워드
- #확률적 경사 하강법 #손실 함수 #에포크
- 경사 하강법 알고리즘을 이해하고 대량의 데이터에서 분류 모델을 훈련하는 방법을 배우자
점진적인 학습
- 럭키 백 대박!
럭키백 이벤트가 대박이 나서 각지에서 한빛 마켓에 수산물을 공급하겠다고 함
하지만 어민이 주는 샘플인 훈련 데이터가 한 번에 준비되는 것이 아니라 조금씩 전달된다는 것과
도착하는 대로 생선을 판매해야 하므로 데이터가 쌓일 때까지 무작정 기다릴 수 없다는 문제가 발생
그렇다면 기존의 훈련 데이터에 새로운 데이터를 추가하여 모델을 매일매일 다시 훈련한다면
매일 추가되는 새로운 데이터를 활용해 모델을 훈련할 수 있으나 시간이 자날수록 데이터가 늘어가는 문제 발생
또 다른 방법으로는 새로운 데이터를 추가할 때 이전 데이터를 버림으로써 훈련 데이터 크기를 일정하게 유지하는 것인데
이렇게 하면 데이터셋의 크기가 너무 커지지 않지만 데이터를 버릴 때 다른 데이터에 없는 중요한 생선 데이터가 포함된다면 큰일
그러므로 앞서 훈련한 모델을 버리지 않고(기존 모델의 가중치와 절편을 유지하면서)
새로운 데이터에 대해서만 조금씩 더 훈련하는 방법(업데이트만)이 필요
이런 식의 훈련 방식을 점진적 학습 또는 모델을 서비스하는 도중에 업데이트하므로 온라인 학습이라고 부르며
대표적인 점진적 학습 알고리즘은 확률적 경사 하강법 (Stochatic Grdient Descent, SGD)
+) 확률적 경사 하강법은 머신러닝 알고리즘이 아닌, 머신러닝 혹은 딥러닝 알고리즘을 훈련하는 방법 (최적화하는 방법) - 확률적 경사 하강법
확률적이라는 말은 '무작위하게' 혹은 '랜덤하게'의 기술적인 표현이며 경사는 '기울기'를, 하강법은 '내려가는 방법'을 뜻함
다시 말해 경사 하강법은 무작위하게 경사를 따라 내려가는 방법이며, 가장 빠른 길은 경사가 가장 가파른 길이므로
가장 가파른 경사를 따라 원하는 지점에 도달하는 것이 경사 하강법의 목표
이 때 만약 한 번에 걸음이 너무 크면 경사를 따라 내려가지 못하고 오히려 올라갈 수 있음
그러므로 가상 가파른 길을 찾아 내려오지만 조금씩 내려오는 것이 중요하며, 내려오는 과정이 경사 하강법 모델을 훈련하는 것
확률적 경사 하강법은 훈련 세트에서 랜덤하게 하나의 샘플을 선택하여 가파른 경사를 조금씩 내려가고
그다음 훈련 세트에서 랜덤하게 또 다른 샘플을 하나 선택해서 경사를 조금 내려가며 전체 샘플을 모두 사용할 때까지 계속 반복
전체 샘플을 모두 사용할 경우 1 에포크 완료라고 하며, 그래도 산을 다 내려오지 못했으면 훈련 세트에 모든 샘플을 다시 채우고
다시 처음부터 시작하여 랜덤하게 하나의 샴플을 선택해 이어서 경사를 내려감
이렇게 만족할만한 위치(최적점)에 도달할 때까지 계속 내려가면 됨
일반적으로 경사 하강법은 훈련 세트를 1번 이상 사용, 에포크를 수십, 수백 번 이상 여러 번 반복하는 것이 기본
무작위로 몇 개의 샘플을 선택해서 경사를 내려가기 위해서 여러 개의 샘플을 사용해 경사 하강법을 수행하는 방식은
미니배치 경사 하강법이라고 하며 미니배치의 개수는 하이퍼파라미터
극단적으로 한 번 경사로를 따라 이동하기 위해 전체 샘플을 사용하는 것은 배치 경사 하강법이라고 하며
사실 전체 데이터를 사용하기 때문에 가장 안정적인 방법이 될 수 있으나 데이터가 너무 많아 컴퓨터 자원을 많이 사용하게 됨
이처럼 훈련 세트를 사용해 산 아래에 있는 최적의 장소로 조금씩 이동하는 알고리즘을 확률적 경사 하강법이라고 하며
이 때문에 훈련 데이터가 모두 준비되어 있지 않고 매일매일 업데이트되어도 학습을 계속 이어나갈 수 있으므로
다시 산꼭대기에서부터 시작할 필요가 없는 것임
여기서 가장 빠른 길을 찾아 내려가려고 하는 이 산을 바로 손실 함수라고 부름
- 손실 함수
손실 함수는 머신러닝 알고리즘이 얼마나 엉터리인지 측정하는 기준이므로 손실 함수의 값이 작을수록 좋음
하지만 어떤 값이 최솟값인지 알지 못하므로 이 값을 찾아서 조금씩 이동하려면 확률적 경사 하강법이 적합
분류에서 손실은 정답을 맞추지 못하는 것으로 아주 확실함
예) 도미와 빙어를 구분하는 이진 분류 문제에서 도미는 양성 클래스(1), 빙어는 음성 클래스(0) 일 때
정확도는 4개의 예측 중에서 2개만 맞았으므로 0.5인데 4개의 샘플만 있다면 가능한 정확도는 0, 0.25, 0.5, 0.75, 1
다섯 가지 뿐이기 때문에 듬성듬성하여 연속적이지 않으며 미분 가능하지 않으므로 경사 하강법을 이용해 조금씩 움직일 수 없음
그러므로 정확도는 손실 함수로 사용할 수 없는 측정 방식 중 하나가 되게 됨
그러므로 연속적인 손실 함수를 만들기 위해서는 확률이 0 ~ 1 사이의 어떤 값도 될 수 있는 연속적인 로지스틱 회귀 모델을 이용
+) 회귀의 경우, 평균절대값오차, 평균제곱오차가 미분이 가능하므로 손실함수와 측정 지표가 동일
분류의 경우, 정확도는 단지 모델의 성능을 보는 측정 지표이며, 최적화는 로지스틱 손실 함수를 가지고 최적화
- 로지스틱 손실 함수
아래 샘플 4개의 예측 확률을 각각 0.9, 0.3, 0.2, 0.8이라 가정한 후 첫 번째 샘플부터 어떻게 손실 함수를 만들 수 있는지 살펴봄
첫 번째 샘플의 예측은 0.9이므로 양성 클래스의 타깃인 1과 곱한 다음 음수로 바꿀 수 있음 (-0.9)
예측이 1에 가까울수록 예측과 타깃의 곱의 음수는 점점 작아지는데, 정답과 가까운 수를 더 낮은 값으로 바꾸기 위해 음수 사용
두 번째 샘플의 예측은 0.3이므로 타깃이 양성 클래스이므로 예측과 타깃을 곱해 음수로 바꿈 (-0.3)
이 값은 -0.3이 되기 때문에 첫 번째 샘플보다 높은 손실이 됨
세 번째 샘플의 타깃은 음성 클래스이므로 0을 0.2와 그대로 곱하면 무조건 0이 되므로 타깃을 양성 클래스처럼 바꾸어 사용
이를 위해 대신 예측값도 양성 클랫에 대한 예측으로 바꾸도록 하여 1 - 0.2 = 0.8로 사용한 후 곱하고 음수로 바꿈 (-0.8)
세 번째 샘플은 음성 클래스인 타깃을 맞추었으므로 낮은 손실이 되며 결과가 낮으므로 정답에 가까운 것을 알 수 있음
네 번째 샘플의 타깃은 음성 클래스이므로 타깃을 1로 바꾸고 예측 확률에서 1에서 뺀 다음 곱해서 음수로 바꿈 (-0.2)
예측 확률을 사용해 이런 방식으로 계산하면 연속적인 손실 함수를 얻을 수 있을 거 같은데 이 예측 확률에 로그 함수를 적용하면
예측 확률의 범위는 0 ~ 1 사이인데 로그 함수는 이 사이에서 음수가 되므로 최종 손실 값은 양수가 되는 것을 볼 수 있으며
손실이 양수가 되면 이해하기 더 쉬워짐
양성 클래스(타깃 = 1)일 때 손실은 -log(예측 확률)로 계산하므로 확률이 1에서 멀어질수록 손실은 아주 큰 양수가 됨
음성 클래스(타깃 = 0)일 때 손실은 -log(1 - 예측 확률)로 계싼하므로 확률이 0에서 멀어질수록 손실이 아주 큰 양수가 됨
예1) 타깃이 = 1이며, 예측이 0.8과 0.2일 때는 -log(예측확률)
0.8 → -log0.8 → -(-log0.8) → log0.8 이므로 → + 작은 양수
0.2 → -log0.2 → -(-log0.2) → log0.2 이므로 → + 아주 큰 양수
예2) 타깃이 = 0이며, 예측이 0.2과 0.8일 때는 -log(1 - 예측확률)
0.2 → -log0.8 → -(-log0.8) → log0.8 이므로 → + 작은 양수
0.8 → -log0.2 → -(-log0.2) → log0.2 이므로 → + 아주 큰 양수
이렇게 정의한 손실 함수를 로지스틱 손실 함수라고 부르거나 이진 크로스엔트로피 손실 함수라고도 부름
SGDClassifier
- 데이터 전처리
fish_csv_data 파일에서 판다스 데이터 프레임을 만든 후
Species 열을 제외한 나머지 5개는 입력 데이터로 사용 그리고 Species 열을 타깃 데이터로 사용
이 후 train_test_split()를 사용해 데이터를 훈련 세트와 테스트 세트로 나누고 훈련 세트와 테스트 세트의 특성을 표준화 전처리
가장 가파른 경사를 따라 내려가기 위해서는 각각의 특성이나 스케일이 같아야 경사를 공평하게 예측할 수 있어 표준화 필요
- SGDClassifier
사이킷런에서 확률적 경사 하강법을 제공하는 대표적인 분류용 클래스는 SGDClassifier이며
SGDClassifier의 객체를 만들 때 2개의 매개변수인 loss와 max_iter를 지정함
loss는 손실 함수의 종류를 지정하여 SGDClassifier가 어떤 함수를 최적화할지 지정하도록 함
여기서는 log로 지정하고 로지스틱 손실 함수를 지정
max_iter는 수행할 에포크 횟수를 지정하며 10으로 지정하여 전체 훈련 세트를 10회 반복하도록 함
그 후 훈련 세트와 테스트 세트에서 정확도 점수를 출력
출력된 훈련 세트와 테스트 세트의 정확도가 낮으므로 지정한 반복 횟수를 높여야 하는 것으로 보임
확률적 경사 하강법은 점진적 학습이 가능하므로 모델을 이어서 훈련하기 위해 partial_fit() 메소드를 사용
fit() 메소드의 경우 이전에 학습했던 것(가중치, 절편 등)을 모두 버리고 새로 학습하지만, partial_fit() 메소드는 이어서 훈련
그러므로 호출할 때마다 1 에포크씩 이어서 훈련할 수 있으므로 훈련 후 다시 점수를 확인해보면
아직 점수가 낮지만 에포크를 한 번 더 실행하니 정확도가 향상된 것을 볼 수 있음
그러므로 얼마나 훈련해야 할지에 대한 기준이 필요
+) SGDClassifier 객체에 한 번에 훈련 세트 전체를 전달했지만
이 알고리즘은 전달한 훈련 세트에서 1개씩 샘플 꺼내어 경사 하강 단계를 수행하며
미니배치 경사 하강법이나 배치 하강법을 제공하지 않으며 이들은 나중에 배울 케라스가 제공
에포크와 과대/과소적합
- 에포크와 과대/과소적합
확률적 경사 하강법을 사용한 모델을 에포크 횟수에 따라 과소적합이나 과대적합이 될 수 있음
에포크 횟수가 적으면 모델이 훈련 세트를 덜 학습하며, 횟수가 충분히 많으면 훈련 세트를 완전히 학습하므로
적은 에포크 횟수 동안에 훈련한 모델은 훈련 세트와 테스트 세트에 잘 맞지 않는 과소적합 모델이 될 수 있으며
반대로 많은 에포크 횟수 동안 훈련한 모델은 훈련 세트에 너무 잘 맞아 테스트 세트에서 점수가 나쁜 과대적합 모델이 될 수 있음
- 조기 종료
에포크가 진행됨에 따라 모델의 정확도를 나타내면 훈련 세트 점수는 에포크가 진행될수록 꾸준히 증가하지만
테스트 세트는 어느 순간 감소하기 시작하며 바로 이 지점이 모델이 과대적합되기 시작하는 곳이며
과대적합이 시작하기 전에 훈련을 멈추는 것을 조기 종료라고 함
아래와 같이 에포크가 진행됨에 따라 모델의 정확도 그래프를 그리기 위한 모델 훈련에서는 partial_fit() 메소드를 사용
이때 partial_fit() 메소드만 사용하려면 훈련 세트에 있는 전체 클래스의 레이블(7개의 생선 목록)을 전달해주어야 함
그러므로 이를 위해 np.unique() 함수로 train_target에 있는 7개 생선의 목록을 만들어 classes로 저장
또한 에포크마다 훈련 세트와 테스트 세트에 대한 점수를 기록하기 위해 train_score, test_score라는 2개의 리스트를 준비
그리고 300번의 에포크 동안 훈련을 반복하며 훈련 세트와 테스트 세트의 점수를 계산하여 리스트에 저장한 후 그래프로 그림
그래프를 보면 백 번째 에포크 이후에는 훈련 세트와 테스트 세트의 점수가 조금씩 벌어지고 있으며
에포크 초기에는 과소적합되어 훈련 세트와 테스트 세트의 점수가 낮은 것을 볼 수 있음
그러므로 이 모델의 경우 백 번째 에포크가 적절한 반복 횟수로 보여지므로 SGDClassifier 반복 횟수를 100으로 변경 후 재훈련
그리고 훈련 세트와 테스트 세트의 점수를 출력하면 훈련 세트와 테스트 세트에서의 정확도 점수가 비교적 높게 나오게 됨
+) SGDClassifier의 loss 매개변수의 기본값은 'hinge'이며
힌지 손실은 서포트 벡터 머신이라 불리는 또 다른 머신러닝 알고리즘을 위한 손실 함수임
'ML > 혼자 공부하는 머신러닝 + 딥러닝' 카테고리의 다른 글
[혼공머신] 05. 트리 알고리즘 - 교차 검증과 그리드 서치 (0) | 2022.06.01 |
---|---|
[혼공머신] 05. 트리 알고리즘 - 결정 트리 (0) | 2022.05.30 |
[혼공머신] 04. 다양한 분류 알고리즘 - 로지스틱 회귀 (0) | 2022.05.24 |
[혼공머신] 03. 회귀 알고리즘과 모델 규제 - 특성 공학과 규제 (0) | 2022.05.17 |
[혼공머신] 03. 회귀 알고리즘과 모델 규제 - 선형 회귀 (0) | 2022.05.16 |