SGD = Stochastic Gradient Descent

신경망 학습에서 '확률적으로 무작위로 골라낸 데이터'에 대해 수행하는 경사 하강법.
신경망 학습에서는 데이터를 미니배치로 무작위로 선정해서 학습하므로, SGD라 지칭함.
  • 경사법 = Gradient Method
  • 현 위치에서 기울어진 방향으로 일정 거리만큼 이동함. 그 뒤 이동한 부분에서 다시 기울기를 구하고, 또 그 기울어진 방향으로 이동을 반복함.
    이런 방법으로 함수의 값을 줄여나가거나(경사 하강법) 늘려나가며(경사 상승법) 기울기가 0인 지점을 찾음.
    이 방법의 경우, 복잡한 함수일 때 고원 = plateau 이라는 평평한 곳으로 파고들며 학습이 진행되지 않는 정체기에 빠질 수 있음.
    또한 기울기가 0인 곳은 최솟값이나 최댓값 뿐만 아니라 극솟값/극댓값/안장점 이 될 수도 있음.
  • 경사 하강법 = Gradient Descent Method
  • 경사법 중 최솟값을 찾는 방법. 일반적으로 신경망 분야에서는 경사법이 경사 하강법으로 등장함(손실 함수의 최솟값을 찾아야 하므로)
    매개변수의 갱신과정은 아래와 같음.($h$,$b$ : 가중치, 편향과 같은 매개변수, $\eta$ : 학습률 = learning rate, $f$ : 손실 함수) $$ w = w - \eta\frac{\partial f}{\partial w} \\ b = h - \eta\frac{\partial f}{\partial b} $$ 여기서 학습률이란 갱신하는 양으로, 한 번의 학습으로 얼마만큼 학습해야 하는지를 정함. 일반적으로 0.01, 0.001과 같이 미리 특정 값으로 정함.
    이 학습률이 너무 크거나 작으면 목표하고자 하는 곳에 도달할 수 없음.
    1. 파이썬 구현
    2. 수치 미분 구현(numerical_gradient 함수)은 이곳 참조.
      def gradient_descent(f, init_x, lr=0.01, step_num=100):
          x = init_x
          x_history = [] # 학습에 따른 변화 정도를 보기위해 값 저장
      
          for i in range(step_num):
              x_history.append( x.copy() )
      
              grad = numerical_gradient(f, x)
              x -= lr * grad
      
          return x, np.array(x_history)
      
      실제 경사하강법에 의해 함수(신경망에서는 손실 함수가 될)의 최솟값을 어떻게 찾는지 확인하기 위해 $f(x_0,x_1) = x_0^2 + x_1^2$의 최솟값을 찾아보자.
      def function_2(x):
          return x[0]**2 + x[1]**2
      
      init_x = np.array([-3.0, 4.0])    
      
      lr = 0.1
      step_num = 100
      x, x_history = gradient_descent(function_2, init_x, lr=lr, step_num=step_num)
      
      plt.plot( [-5, 5], [0,0], '--b')
      plt.plot( [0,0], [-5, 5], '--b')
      plt.plot(x_history[:,0], x_history[:,1], 'o')
      
      plt.xlim(-3.5, 3.5)
      plt.ylim(-4.5, 4.5)
      plt.xlabel("X0")
      plt.ylabel("X1")
      plt.show()
      
      
      결과는 다음과 같다.

      학습률에 따른 차이를 알아보기 위해 위 소스의 lr값을 0.005로 바꾸면 다음과 같다.

      위에서 확인 할 수 있듯이, 학습률이 낮으면 100번 반복해도(step_num 값) 최솟값인 ($x_0$,$x_1$) = (0,0)에 다가가지 못한다.
      이번엔 반대로 학습률을 높여보자.(lr을 1과 0.9로 설정)

      1의 경우가 주황색이고, 0.9가 파란색이다. 그림에서 볼 수 있듯이, 0.9는 결과적으로는 찾아갔지만 1은 두 점만 반복하며 못 찾는 것을 볼 수 있다.
      실제로 x_history의 변수를 보면 아래와 같다.
      # lr = 0.9
      x_history
      array([[ -3.00000000e+00,   4.00000000e+00],
             [  2.40000000e+00,  -3.20000000e+00],
             [ -1.92000000e+00,   2.56000000e+00],
             ..., 
             [  1.19357577e-09,  -1.59143436e-09],
             [ -9.54860614e-10,   1.27314749e-09],
             [  7.63888491e-10,  -1.01851799e-09]])
      
      # lr = 1
      x_history
      array([[-3.,  4.],
             [ 3., -4.],
             [-3.,  4.],
             ..., 
             [ 3., -4.],
             [-3.,  4.],
             [ 3., -4.]])
      
      따라서 학습률의 설정은 중요하고, 이와 같은 매개변수를 하이퍼파라미터 = hyper parameter 로 지칭한다.
    3. SGD의 단점
    4. 비등방성 = anisotropy 함수(방향에 따라 성질=기울기 가 달라지는 함수.)에서는 탐색 경로가 비효율적이다.
      예를 들어 $f(x,y) = \frac{1}{20}x^2 + y^2$과 같은 함수의 탐색경로를 아래와 같이 찾는다.(시작 위치 : (-7,2))
      위와 같이 탐색하는 이유는 SGD가 무작정 기울어진 방향으로 탐색하기 때문이고, 이 방향이 본래의 최솟값과는 다른 방향을 가리키기 때문이다.
      이러한 단점을 개선해주는 모델로 Momentum, AdaGrad, Adam 등이 있다.

댓글

이 블로그의 인기 게시물

Loss Function

Backpropagation