페이지

2022년 7월 22일 금요일

2.4 신경망의 엔진: 그래디언트 기반 최적화

 이전 절에서 보았듯이 첫 번째 신경망 예제에 있는 각 층은 입력 데이터를 다음과 같이 변환합니다.

output = relu(dot(W, input) + b)

이 식에서 턴서 W와 b는 층의 속성 처럼 볼 수 있습니다. 가중치(weight)또는 훈련되는 파라미터(trainable parameter)라고 부릅니다(각각 커널(kernel)과 편향(bias)이라고 부르기도 합니다). 이런 가중치에는 훈련 데이터를 신경망에 노출시켜서 학습된 정보가 담겨 있습니다.

초기에는 가중치 행렬이 작은 난수로 채워져 있습니다.(무작위 초기화(random initialization)단계라고 부릅니다). 물론 W와  b가 난수일 때 relu(dot(W, input) + b)가 유용한 어떤 표현을 만들 것이라고 기대할 수는 없습니다. 즉 의미 없는 표현이 만들어집니다. 하지만 이는 시작 단계일뿐입니다. 그 다음에는 피드백 신호에 기초하여 가중치가 점진적으로 저정될 것입니다. 이런 점진적인 조정 또는 훈련(trainintg)이 머신 러닝 학습의 핵심입니다.

훈련은 다음과 같은 훈련 반복 루프(training loop)안에서 일어납니다. 필요한 만큼 반복 푸프안에서 이런 단계가 반복됩니다.

1. 훈련 샘플 x와 이에 상응하는 타깃 y의 배치를 추출합니다.

2. x를 사용하여 네트워크를 실행하고(정방향 패스(forward pass) 단계), 예측 y_pred를 구합니다.

3. y_pred와 y의 차이를 측정하여 이배치에 대한 네트워크의 손실을 계산합니다.

4. 배치에 대한 손신이 조금 감소되도록 네트워크의 모든 가중치를 업데이트 합니다.

결국 훈련 데이터에서 네트워크의 손실, 즉 예측 y_pred와 타깃 y의 오차가 매우 작아질 것입니다. 이 네트워크는 입력에 정확한 타깃을 매핑하는 것을 학습했습니다. 전체적으로 보면 마술처럼 보이지만 개별적인 단계로 쪼개서 보면 단순합니다.

1단계는 그먕 입출력 코드이므로 매우 쉽습니다. 2단계와 3단계는 몇 개의 텐서 연산을 적용한 것뿐이므로 이전 절에서 배웠던 연산을 사용하여 이 단계를 구현할 수 있습니다. 어려운 부분은 네트워크의 가중치를 업데이트하는 4단계입니다. 개별적인 가중치 값이 있을 때 값이 증가해야 할지 감소해야 할지, 또 얼마큼 업데이트해야 할지 어떻게ㅐ 알 수 있을까요?

한 가지 간단한 방법은 네트워크 가중치 행렬의 원소를 모두 고정하고 관심 있는 하나만 다른 값을 적용해 보는 것입니다. 이 가중체의 초깃값이 0.3이라고 가정합니다. 배치 데이터를 정방향 패스에 통과시킨 후 네트워크의 손실이 0.5가 나왔습니다. 이 가증치 값을 0.35로 변경하고 다시 정방향 패스를 실행했더니 손실이 0.6으로 증가했습니다. 반대로 0.25로 줄이면 손실이 0.4로 감소했습니다. 이경우에 가중치를 0.05만큼 업데이트한 것이 손실을 줄이는데 기여한 것으로 보입니다. 이런 식으로 네트워크의 모든 가중치에 반복합니다.

이런 접근 방식은 모든 가중치 행렬의 원소마다 두 번의 (비용이 큰) 정방향 패스를 계산해야 하므로 엄청나게 비효율적입니다(보통 수천에서 경우에 따라 수백만 개의 많은 가중치가 있습니다). 신경망에 사용된 모든 연산이 미분 가능(differentiable)하다는 장점을 사용하여 네트워크 가중치에 대한 손실의 그래디언트(gradient)를 계산하는 것이 훨씬 더 좋은 방법입니다. 그래디언트의 반대 방향으로 가중치를 이동하면 손실이 감소됩니다.

미분 가능하다는 것과 그래디언트가 무엇인지 이미 알고 있다면 2.4.3절로 건너 뛰어도 좋습니다. 그렇지 않으면 다음 두 절이 이해하는데 도움이 될 것입니다.

댓글 없음: