ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [PyTorchZerotoAll 내용정리] 03 Gradeint Descent
    ML&DL 이야기/Pytroch 2023. 8. 15. 15:52

    graph of gradient descent

    우리는 가중치 값에 따라서 에러를 가장 줄이는 w를 찾아보고 싶다. 이를 알기 위해서는 물론 미분을 해서 최적값을 찾아도 되지만, 우리가 앞으로 다룰, 또 대다수의 함수들은 여러가지 변수로 구성되어있기에 이런 방법으로는 최적값을 찾는 것이 불가하다.

    gradient descent algorithm

    그럼으로 적용가능한 알고리즘이 필요한데, 그 이름도 유명한 gradient desecent 알고리즘이다. 

    이 알고리즘은 산을 타면서 한 step마다 가장 가파른 방향으로 이동한다라고 생각하면 된다.

     

    왜 Gradient 방향이 가장 가파른가?

    gradient와 방향도함수의 정의를 각각 먼저 살펴보자. 

    Gradient란? 
    f(x,y,z)의 기울기 벡터 또는 gradeint는 다음과 같이 정의된다. 
    $$ \nabla f = \frac{\partial f}{\partial x} i + \frac{\partial f}{\partial y} j + \frac{\partial f}{\partial z} k$$

    즉, 스칼라 장 f가 있을 때, 각각을, x, y, z로 편미분 하여 각 방향의 단위 벡터로 표기한 것이다. 그래서 본래 스칼라였던 f가 3차원의 벡터로 바뀌게 된다. 이는 변화하는 방향이라고 생각하면 된다. 
    이 식은 결국 우리가 흔히 아는 f'(x)의 3차원 확장형이라고 생각하면 된다. 

    예시를 봐보자. 

    온도에 관한 함수 T(x,y,z)에 관한 변화률을 측정하고 싶다고 하자. 각 변수 x,y,z에 관해서 이것의 도함수가 가지는 의미는 한 점에서 다른 점 또는 방향으로 어느 정도 위치를 변경할 때 온도가 바뀌는 정도를 뜻한다. 이때 다변수함수는 일변수함수와 달리 '편미분(Partial derivative)'을 사용해야 하므로, 세 방향에 대한 온도의 변화량은

    $$ dT =  \frac{\partial f}{\partial x} dx + \frac{\partial f}{\partial y} dy + \frac{\partial f}{\partial z} dx $$

    이다. 

    그런데 변화라는 것은 변화량 뿐만 아니라 변화하는 방향까지 고려해야한다.

    따라서 온도의 변화 dT는 미소 변위 벡터 ds([dx, dy, dz])와 편미분으로 구성된 양의 내적으로 나타내어진다. 

    이때 편미분으로 구성된 식이 바로 gradient라는 것이다(변화하는 방향을 의미한다).  

     

    방향도함수

    - 방향도함수(directional derivative)

    $ D_u f(P) = lim \frac{f(P+tu)-f(P)}{h} $
    방향도함수의 정의

    방향도함수는 특정 방향(단위벡터 u)으로의 미분이다. 엄밀히는 임의의 내가 원하는 방향 벡터의 방향으로의 편도함수이다. 위의 그림에서 그 방향 u를 [a, b]라고 하면 위는 u의 방향도함수이다. 
    (h는 상수)

    기하학적 의미로는 u방향으로 함수를 자르고 그 자른 함수의 x,y 점에서의 기울기라고 생각하면된다.

    방향도함수를 그림으로 보기(https://gosamy.tistory.com/341)

     그림으로 보면 위 그림과 같다. 바닥에 깔린 초록색 단위벡터  가 방향도함수에서의 특정한 방향을 가리키는 벡터에 해당하고, 파란색 곡선에 접하는 검은색 직선의 기울기가 방향으로의 방향도함수의 미분계수가 된다. 즉 구하고자 하는 것은 검은색 직선의 기울기인 것이고, 그러기 위해서는 주어진 점에서  방향과 방향의 편도함수로 이루어진 그래디언트  를 구한 다음에, 와 내적하면 된다는 결론이 나온다(즉, gardient는 변화하는 변화방향(각 변수에 대한), u는 우리가 변화시킬 방향(가고자하는 방향)이다, 따라서 이 둘을 곱하면 당연히 전체 변화량이 나오게 된다)

     

    동시에 수식으로는

    $ f(x_1, x_2) = f(\frac{x_1+ha}{x_1+hb}) = f(x(h))$위의 경우 $x_1$ $x_2$는 상수이기에 이를 h에 관한 함수라고 할 수 있다. 
    그럼 chain rule을 이용하면
    $ \frac{df}{dh} = \frac{df}{dx_1}\frac{dx_1}{dh} + \frac{df}{dx_2}\frac{dx_2}{dh} $

    임으로 우리는 이 식을 gradient descent와 u의 내적으로 표현 가능하다. 

    즉 , 최종적으로

    $$ D_u(p) = \nabla f(p) u $$

     

    이다.

    그럼으로 아래의 정리가 나오게 된다. 

    방향도함수의 최댓값과 최솟값은 그래디언트 의 크기의 최댓값과 최솟값에 해당한다. 따라서 어떤 함수가 주어진 점에서 가장 급하게 변화하는 방향은 그래디언트 방향이고, 올라가거나 내려가거나(양/음 부호 차이) 둘 중 하나이다.

    https://www.youtube.com/watch?v=nma8R7sMuv0 

     

    Gradient Descent algorithm과 learning rate

     

    gradient descent 알고리즘 수식

    식 자체는 위에서 적힌 것과 같이 매우 간단하다. 

    최적화하고자 하는 변수를 계속 업데이트는 하는데 이를 gradient의 음수 * learning rate(α)만큼 해주는 것이다. 

    이때 주의해야할 점이 있다면 업데이트해야할 변수가 여러개라면 각각의 변수에 관해 모두 gradient descent를 적용한 다음에 다음 step으로 넘어가야한다. 

    이때 learning rate는 임의로 정할 수 있으나 그 크기가 너무 크면 

    Andrew Eng- Cousera ML lecture

    위의 그림처럼 최적값을 못찾는 경우가 생기고, 너무 작으면 converge하는데 너무 많은 시간이 든다. 

    따라서 0,001, 0.003, 0.01 → 3배씩 늘려가면서 확인 후에 범위를 좁히는 방식을 사용(엔드류응 교수의 경우)하기도 한다. 

     

    Code implementation

    실제 pytorch로는 이를 아래와 같이 구현한다. 

     

    가중치 갱신은 방금 정의했던 forward, loss, gradient 함수로 가능하다. 현재의 학습률은 0.01로 설정했다.

    epoch은 총 3번 , full batch로 진행했다.

     

    pytorch - gradient descent

    시간이 지날수록 loss가 점점 줄어드는 것을 볼 수 있고 그만큼 더 알맞은 가중치의 값으로 다가가고 있다.

    처음에는 초기 가중치 값이 임의로 설정된 1.0이었고,  4시간을 공부한다면 4.0점을 받을 것이라고 예측했지만, 100번의 학습을 한 뒤에는 7.9정도의 점수를 받을 것이라고 예측하게 되고 정답은 8이므로 맞다고 할 수 있다.

     

    https://colab.research.google.com/drive/1QB72fSRQTZihbzbp8qf7cf-jRWZFy4Ax#scrollTo=8AR3FKTrvbff

Designed by Tistory.