텐서와 그래디언트 기반 최적화

저번에는 딥러닝이 무엇 인가에 대해 알아 보았고,

이번에는 머신러닝 기법 중 하나인 딥러닝의 차이를 나타내는

신경망(깊은 층)의 기본 구성요소에 대해 간략히 알아보고

신경망을 어떻게 최적화 시키는지 개념적으로 알아보자.

 

  1.  텐서 (Tensor)

머신 러닝의 기본 구성 요소로 데이터를 위한 그릇(Container) 역할을 한다.

일반적으로 Ptython 으로는 numpy 라는 library로 배열을 만들어 쓴다.

텐서의 종류는 배열 차원에 따라 스칼라(0D), 벡터(1D), 행렬(2D), 3D, 고차원 .. 텐서라 한다.

보통은 2D텐서부터 많이 쓰이며, 시간의 흐름에 따른 주식, 이미지, 동영상, 통계 등등에 쓰인다.

 

텐서에 대한 이해를 돕기 위해 실제 keras.datasets 에 있는 MNIST의 numpy 배열을 출력해 보면 다음과 같다.

 

참고로 print(train_images.shpae)를 하면 배열의 크기인 (60000, 28, 28) 이 출력된다. (3D 텐서)

또한 train_images는 데이터이고 train_labels는 해답이라 할 수 있다. test_images, test_labels가 또 있는 이유는,

train_images, labels로 훈련 과정을 거쳐 모델이 정확도가 올라가면 test_images와 labels로 테스트 해보기 위해서이다.

 

9번째 배열에는 (28 * 28)인 숫자 4가 들어 있다. train_images에는 6만개의 28 * 28의 이미지가 있는 것이다.

그리고 첫번째 축인 60000을 보통 샘플 축(Sample axis)이라고 한다.

이러한 텐서 데이터가 머신러닝의 기본 요소로 들어가는 것이다.

 

        2. 텐서 연산

당연히 텐서(다차원 배열) 끼리 연산이 가능하다. 덧셈, 뺄셈, 곱셈 등이 가능하다.

일반적으로 모두 행렬의 연산이라고 생각하면 편리할 거 같다.

그리고 relu라는 연산이 있는데 이는 두 텐서의 연산이 아닌 한 텐서의 연산인데

값이 0보다 크면 그대로 반환하고 0보자 작으면 0을 반환하는 연산이다.

또한 브로드캐스팅이 있는데 이는 텐서의 크기가 다를 때 작은 텐서가 큰 텐서에 맞춰서

크기를 변경하는 작업을 말한다.

예를들어 2D 텐서 k(56, 10), 1D텐서 z(10)인 크기를 가진 텐서의 덧셈을 할 때,

z(1, 10) 2D텐서로 변환 후에 56번 반복하여 더하면 결국 z(56, 10)이 된다.

 

        3. 그래디언트 기반 최적화

위 그림이 딥러닝의 핵심 구조이다. 여기서 살펴보면,

  1. 입력 데이터와 실제 값을 넣는다.
  2. 입력 데이터를 이용하여 네트워크(층)를 거치고 예측 값을 구한다. (정방향 패스)
  3. 예측값과 실제 값의 차이를 손실함수를 통해 구한다.
  4. 손실 점수에 대해 옵티마이저가 네트워크의 모든 가중치를 업데이트 한다.

1단계는 그냥 값을 넣는 것이고 2, 3단계는 텐서 연산만을 이용한 것인데 4단계는 어렵다.

현재 옵티마이저는 그래디언트(Gradient) 기반으로 해서 최적화를 하고 있다.

그래디언트는 미분 결과, 즉 텐서 연산의 변화율(경사)을 뜻한다.

가정을 해보자.

손실점수가 0.5가 나왔는데

네트워크 층 중 하나의 초기값이 0.6이라 하면 초기값을 0.55로 바꿨을 때

손실점수가 0.6으로 늘어 났으면 잘 못 바꾼 것이다.

그래서 그 초기값을 0.65로 바꿨더니 손실점수가 0.4로 줄어 들었다.

이런식으로 다른 층도 바꿔 나가면 손실점수가 최소가 되는 값을 찾을 수 있을 것이다.

하지만, 이러면 비효율 적이므로 신경망에 사용된 모든 연산이 미분 가능 하다는 장점을 사용하여

각 층의 텐서 연산을 미분하고 변화율의 방향과 조금 반대로 이동하도록 하는 것이다.

이것을 그래디언트 기반 최적화라 한다. (역방향 패스)

 

댓글 남기기