[딥러닝] 오차 역전파 (Error Back propagation) ,기울기 소실(vanishing gradient) 문제, 고급 경사 하강법
신경망 내부의 가중치는 오차 역전파 방법을 이용해 수정한다.
- 경사하강법의 확장 개념
임의의 가중치를 선언하고 결괏값을 이용해 오차를 구한 뒤 이 오차가 최소인 지점으로 계속해서 조금씩 이동시킨다.
오차가 최소가 되는 점(미분했을 때 기울기가 0이 되는 지점) 찾기
계산 방향이 출력층에서 시작해 앞으로 진행. 이러한 다층 퍼셉트론에서의 최적화 과정을 오차 역전파라고 한다.
= 출력층으로부터 하나씩 앞으로 되돌아가며 각 층의 가중치를 수정하는 방법
오차역전파 구동 방식
1 . 임의의 초기 가중치(W)를 준 뒤 결과(y out)를 계산한다.
2 . 계산 결과와 우리가 원하는 값 사이의 오차를 구한다.
3 . 경사 하강법을 이용해 바로 앞 가중치를 오차가 작아지는 방향으로 업데이트한다.
4 . 위 과정을 더이상 오차가 줄어들지 않을 때까지 반복한다. (가중치 - 기울기 , 가중치의 변화가 없는 상태)
OR 문제를 이러한 오차 역전파 방식으로 해결하려면 어떻게 코딩해야 할까요?
앞서 XOR 문제를 코딩으로 확인할 때는 가중치를 미리 알고 접근했었습니다.
오차 역전파는 이를 몰라도 문제를 해결하기 위해 개발된 방법입니다.
입력된 실제 값과 다층 퍼셉트론의 계산 결과를 비교하여 가중치를 역전파 방식으로 수정해 가는 코딩은 다음과 같은 순서로 구현합니다.
1 | 환경 변수 지정: 환경 변수에는 입력 값과 타깃 결괏값이 포함된 데이터셋, 학습률 등이 포함됩니다. 또한, 활성화 함수와 가중치 등도 선언되어야 합니다.
2 | 신경망 실행: 초깃값을 입력하여 활성화 함수와 가중치를 거쳐 결괏값이 나오게 합니다.
3 | 결과를 실제 값과 비교: 오차를 측정합니다.
4 | 역전파 실행: 출력층과 은닉층의 가중치를 수정합니다.
5 | 결과 출력
다층 퍼셉트론 , 오차 역전파 -> 신경망 -> XOR문제 해결
오차 역전파의 기울기 소실(vanishing gradient) 문제
- 층이 늘어나면서 역전파를 통해 전달되는 이 기울기의 값이 점점 작아져 맨 처음 층까지 전달되지 않는다
이유는 활성화 함수로 사용된 시그모이드 함수의 특성 때문입니다. 시그모이드 함수를 미분하면 최대치는 0.3, 1보다 작으므로 계속 곱하다 보면 0에 가까워진다. 따라서 여러 층을 거칠수록 기울기가 사라져 가중치를 수정하기가 어려워진다.
해결 : 활성화 함수를 시그모이드가 아닌 여러 함수로 대체
렐루 함수 : 현재 가장 많이 사용되는 활성화 함수
경사하강법으로 가중치 업데이트 -- 전체 데이터를 미분해야 하므로 계산량이 많다 --> 보안책: 고급 경사 하강법
- 확률적 경사 하강법(Stochastic Gradient Descent, SGD)
전체 데이터를 사용하는 것이 아니라, 랜덤하게 추출한 일부 데이터를 사용하므로 더 빨리 그리고 자주 업데이트 가능
- 모멘텀(momentum)
경사 하강법에 탄력을 더해 주는 것. 다시 말해서, 경사 하강법과 마찬가지로 매번 기울기를 구하지만, 이를 통해 오차를 수정하기 전 바로 앞 수정 값과 방향(+, -)을 참고하여 같은 방향으로 일정한 비율만 수정되게 하는 방법.
따라서 수정 방향이 양수(+) 방향으로 한 번, 음수(-) 방향으로 한 번 지그재그로 일어나는 현상이 줄어들고, 이전 이동 값을 고려하여 일정 비율만큼만 다음 값을 결정하므로 관성의 효과
고급 경사 하강법 |
개요 |
효과 |
케라스 사용법 |
확률적 경사 하강법(SGD) |
랜덤하게 추출한 일부 데이터를 사용해 더 빨리, 자주 업데이트를 하게 하는 것 |
속도 개선 |
keras.optimizers.SGD(lr = 0.1) 케라스 최적화 함수를 이용합니다. |
모멘텀 (Momentum) |
관성의 방향을 고려해 진동과 폭을 줄이는 효과 |
정확도 개선 |
keras.optimizers.SGD(lr = 0.1, momentum = 0.9) 모멘텀 계수를 추가합니다. |
네스테로프 모멘텀(NAG) |
모멘텀이 이동시킬 방향으로 미리 이동해서 그레이디언트를 계산. 불필요한 이동을 줄이는 효과 |
정확도 개선 |
keras.optimizers.SGD(lr = 0.1, momentum = 0.9, nesterov = True) 네스테로프 옵션을 추가합니다. |
아다그라드 (Adagrad) |
변수의 업데이트가 잦으면 학습률을 적게 하여 이동 보폭을 조절하는 방법 |
보폭 크기 개선 |
keras.optimizers.Adagrad(lr = 0.01, epsilon = 1e - 6) 아다그라드 함수를 사용합니다. ※ 참고: 여기서 epsilon, rho, decay 같은 파라미터는 바꾸지 않고 그대로 사용하기를 권장하고 있습니다. 따라서 lr, 즉 learning rate(학습률) 값만 적절히 조절하면 됩니다. |
알엠에스프롭 (RMSProp) |
아다그라드의 보폭 민감도를 보완한 방법 |
보폭 크기 개선 |
keras.optimizers.RMSprop(lr = 0.001,rho = 0.9, epsilon = 1e - 08, decay = 0.0) 알엠에스프롭 함수를 사용합니다. |
아담(Adam) |
모멘텀과 알엠에스프롭 방법을 합친 방법 |
정확도와 보폭 크기 개선 |
keras.optimizers.Adam(lr = 0.001, beta_1 = 0.9, beta_2 = 0.999, epsilon = 1e - 08, decay = 0.0) 아담 함수를 사용합니다. |
아담(Adam) = 현재 가장 많이 사용되는 고급 경사 하강법