Optimizer들

Optimizer. 딱히 번역은 없는 것 같지만, 최적화기 정도로 번역해볼 수 있겠다.

사실 굉장히 중요한 역할을 하는 부분이지만, 크게 중요하게 가르치는 것 같지는 않다.

한번 Optimizer의 종류와 그 optimizer를 규정하는 수식들에 대해서 알아보도록 하자.

Optimizer란?

-하기 전에 잠깐. Optimizer란 도대체 무엇인가?

인공 신경망은 기본적으로 - 수학적으로 말하면 - 행렬이다.

입력으로 들어오는 벡터를 행렬을 이용해 다른 벡터로 변환하는 과정이다.

행렬의 변환은 선형변환이므로, 중간중간 비선형 변환도 넣어준다. (이를 활성화 함수라고 부른다.)

그런데 문제는 이 행렬의 이다. 파라미터, 매개변수라고도 부른다.

이 매개변수가 최적화되어 있다면, 인공 신경망이 제 역할을 할 것이다.

어떻게든 이 매개변수를 잘 조정하는 것이 Optimizer의 역할이다.

Gradient?

자주 보게 될 말에 ‘그라디언트’가 있다.

번역은 ‘기울기’라고 하는 모양이다.

그라디언트가 무엇인지를 먼저 알아보자.

일단 수학적 정의는 대충 이렇게 되는 모양이다.

스칼라 함수 f(x)가 있을 때,

∇f = (∂f/∂x1, ∂f/∂x2, …, ∂f/∂xn)

즉, f를 이루는 매개 변수의 편미분의 열벡터이다.

이렇게 생각해보자.

3차원 공간에서 어떠한 그래프(평면)가 있고, 이를 위에서 바라봐보자.

gradient-1 gradient-2

위 이미지는 Wolfram Alpha로 만든 이미지이다.

편미분

일단 편미분(∂)이 뭘까?

위에 그려져 있는 그래프의 위에 서 있다고 생각해보자.

휴대폰을 하나 들고 있는데, 휴대폰에는 내가 지금 위치해 있는 x값과 y값, 그리고 f(x, y)값이 나온다고 생각하자.

x좌표 방향으로 살짝 움직여보자. f(x, y) 값이 변하는 것을 볼 수 있다.

내가 x좌표 방향으로 살짝 움직였을 때 f(x, y)값이 얼마나 바뀌는지를 계산하는 것을 f를 x에 대해 편미분한 것이라고 생각하면 된다.

기호로는 ∂f/∂x라고 표현한다.

계산하는 방법은 생략하자. (궁금한 사람을 위해 말해 두자면 y값을 상수 취급하고 미분을 하면 된다.)

편미분 - 더 높은 곳으로

편미분의 결과는 함수이다.

내가 서 있는 지점의 좌표를 이 함수에다가 집어넣으면, 내가 서 있는 곳의 편미분 값을 알 수 있을 것이다.

이 문단에서는 편의를 위해 ‘편미분 값’이라고 하면 ‘f의 x에 대한 편미분에 내 좌표를 대입한 값’이라고 생각하자.

내가 서 있는 곳의 편미분 값이 양수라면? +x 방향으로 움직이면 f(x, y)값이 커진다는 뜻이다.

내가 서 있는 곳의 편미분 값이 음수라면? +x 방향으로 움직이면 f(x, y)값이 작아진다는 뜻이다.

만약 내가 x축 방향만을 앞뒤로 움직일 수 있다면, f(x, y)값이 큰 곳으로 가고 싶다면 어떻게 해야 할까?

조금만 생각해보면, 편미분 값이 가르키는 대로 움직이면 f(x, y)값이 커진다는 것을 알 수 있을 것이다.

편미분 값이 음주이던 양수이던, 결국 f(x, y)값이 큰 곳을 가르킬 것이기 때문이다.

gradient-3

이해를 돕기 위해 이미지를 가져왔다. 마우스로 대충 그린 것이라 화살표를 알아보기 조금 힘들 수도 있겠다.

편미분의 열벡터

f(x, y)값이 높은 곳으로 움직이고 싶다고 할 때, 지금까지의 이동 방향을 벡터로 표시하면 다음과 같다.

(∂f/∂x, 0)

y방향으로는 이동하지 않고, x방향으로만 이동했기 때문이다.

그런데 x방향으로만 움직일 필요는 없지 않을까?

y방향도 같은 식으로 편미분을 할 수 있을 것이고, 같은 식으로 계산해서 높은 곳으로 올라가는 방향을 찾을 수 있을 것이다.

그러면 이런 식이 되지 않을까?

(∂f/∂x, ∂f/∂y)

이 방향으로 움직이면, 아마 f(x, y)값이 가장 높은 곳으로 움직일 수 있을 것이다.

gradient-4

조금 그림을 더 잘 그리면 좋겠지만 그게 안된다. 양해 부탁한다.

이 벡터가 바로 그라디언트다.

3차원 이상 그래프의 기울기라고 생각하면 된다.

혹은, ‘이 방향으로 가면 함수 값이 커짐’이라고 생각해도 될 것이다.

gradient-5

위키백과에서 이미지를 긁어왔다. 좀 더 보기 좋다. (저작권 정보 등은 원 출처를 확인하자.)

중요성?

지금까지는 3차원 상에서만 이야기를 했지만, 훨씬 더 큰 차원에서도 마찬가지로 적용된다.

그라디언트의 방향으로 움직이면 함수의 값이 커진다.

우리는 Optimizer를 만들고 싶고, Optimizer는 잘 움직여서 함수의 값을 최소로 만들고 싶어한다.

함수의 값을 최대한 작게 만드려면 어떻게 해야 할까?

Gradient의 반대 방향, 즉 -∇f 방향으로 움직이면 함수의 값이 가장 작아지지 않을까?

이게 바로 가장 기본적인 Optimizer인 ‘경사하강법’ (Gradient descent)이다.