hello, robot

신경망에서 값이 흐르는 길은 둘이에요. 입력을 넣어 결과를 받아오는 순전파와, 그 결과의 오차를 거꾸로 되돌리며 가중치를 고치는 역전파예요. 학습이 실제로 일어나는 쪽은 역전파인데, 이게 성립하려면 조건이 하나 붙어요. 활성화 함수를 미분할 수 있어야 해요.

가중치를 고치는 한 줄

뉴런 하나짜리 예제로 보면 역전파는 코드 한 줄로 줄어들어요.

self.w = self.w - a * (self.output - target) * self.getActGrad(self.output) * self.input

학습률 a를 빼면 곱해진 항이 셋이에요.

무엇0이 되면
output - target오차 함수를 출력으로 미분한 값 (MSE면 정확히 이 형태)오차가 없으니 갱신 없음 (정상)
getActGrad활성화 함수의 기울기오차가 아무리 커도 갱신 0
input그 가중치에 들어온 입력값기여가 없었으니 갱신 없음 (정상)

세 항의 곱이 곧 체인룰이고, 손실에서 가중치까지 가는 길에 놓인 미분값을 순서대로 곱하는 구조예요. 층이 깊어져도 원리는 같아요. 층마다 이 곱셈이 한 번씩 더 붙을 뿐이에요.

곱셈이라는 점이 중요해요. 세 항 중 하나라도 0이면 갱신량 전체가 0이 돼요.

계단 함수로는 배울 수 없어요

함수와 도함수를 같이 봐야 해요
계단은 임계점을 뺀 모든 구간에서 기울기가 0이고, 정작 임계점에서는 미분이 정의되지 않아요.
계단함수도함수항상 0기울기 0 — 한 발짝도 못 움직여요시그모이드함수도함수최대 0.25최대 0.25 — 층마다 곱해지면 줄어요ReLU함수도함수양수에서 1양수 구간 1 — 몇 번 곱해도 1활성화 함수를 고르는 기준은 값을 어떤 범위로 눌러줄지가 아니라, 그 기울기가 층을 지나며 살아남는지예요.출력층은 사정이 달라 여전히 시그모이드나 소프트맥스를 써요. 거기는 확률을 내놓는 자리라 뒤로 더 전달할 층이 없거든요.

퍼셉트론이 원래 쓰던 계단 함수는 분류기로서는 자연스럽지만, 위의 세 항 중 가운데가 0이 되니 가중치가 한 발짝도 안 움직여요. 계단 함수를 쓰면서 다층 신경망을 학습시킬 수 없었던 이유가 여기 있어요.

시그모이드는 이 문제를 푸는 함수예요. 계단 함수와 모양은 비슷하게 0과 1 사이를 오가는데, 각진 곳 없이 S자로 부드럽게 이어져서 어디서든 미분이 돼요. 미분 가능한 형태로 계단을 흉내 냈다고 보면 정확해요.

0.25가 층마다 곱해지면

그런데 시그모이드는 다른 문제를 가져와요. 도함수가 σ(x)(1 − σ(x))인데 값이 가장 클 때가 x = 0이고 그때가 0.25예요.

가장 좋은 조건으로만 계산해도
체인룰이 층마다 기울기를 곱해가니 이 값이 층 수만큼 곱해져요.
0.250.0250.00250.000251층0.252층0.06254층0.0039066층0.000244지나온 층 수 (로그 축척)가장 좋은 조건인0.25로만 계산해도 이래요.여섯 층이면 갱신량이만분의 이 수준이에요.출력층 근처는 그럭저럭 학습되는데입력층 쪽은 사실상 멈춰 있어요.체인룰은 층마다 기울기를 곱해가는 구조예요. 시그모이드 도함수의 최댓값이 x=0에서 0.25이고, x=4에서는 0.0177까지 떨어져요.기울기 소실은 함수 자체의 결함이라기보다 깊이와 맞물려 생기는 문제예요. [2,2,1] 같은 얕은 망에서는 느려질 뿐 멈추지 않아요.

출력층 근처는 그럭저럭 학습되는데 입력층 쪽 가중치는 사실상 멈춰 있게 돼요. 이게 기울기 소실이고, 층을 깊게 쌓으면 오히려 학습이 안 되던 실질적인 원인이었어요.

ReLU가 한 일

ReLU는 음수를 0으로 자르고 양수는 그대로 통과시키는 함수예요. 생김새는 시그모이드보다 훨씬 단순한데, 양수 구간의 기울기가 1로 일정하다는 점이 결정적이에요. 1은 몇 번을 곱해도 1이라 층이 깊어져도 신호가 줄지 않아요.

계산 비용도 비교 한 번이면 끝나서 지수 함수를 계산하는 시그모이드보다 훨씬 빨라요. 지금 합성곱 신경망의 중간 층이 거의 전부 ReLU를 쓰는 이유예요.

여기서 활성화 함수를 고르는 기준이 하나 정리돼요. 값을 어떤 범위로 눌러줄지가 아니라, 그 함수의 기울기가 층을 지나며 살아남는지를 봐야 해요.

얕으면 시그모이드로도 돌아가요

그렇다고 시그모이드가 못 쓰는 함수라는 뜻은 아니에요. XOR을 푸는 예제 신경망은 층 구성이 [2, 2, 1]이라 곱셈이 두어 번밖에 안 붙어요. 0.25가 두 번 곱해지는 정도면 학습이 느려질 뿐 멈추지는 않아서, 에포크를 1,000회쯤 돌리면 수렴해요.

기울기 소실은 함수 자체의 결함이라기보다 깊이와 맞물려 생기는 문제라는 얘기예요. 얕은 신경망에서 잘 돌아가던 구성을 그대로 깊게 쌓았을 때 갑자기 학습이 안 되면, 코드보다 활성화 함수를 먼저 의심하는 게 맞아요.

전처리 쪽에서 비슷하게 조용히 틀리는 경우는 MNIST 학습은 됐는데 직접 쓴 숫자만 틀리는 전처리 불일치에 따로 정리했어요.