brunch

매거진 딥러닝 101

You can make anything
by writing

C.S.Lewis

by TUGU Jan 09. 2019

벡터화된 알고리즘으로 For loop를 없애자

딥러닝 101_Chapter 12

For loop는 무겁다. 벡터화는 가볍다.


딥러닝을 구현하기 위해서는 수많은  데이터와, 수많은 반복적인 수식을 통한 알고리즘이 구현이 되어야 한다. ' 수많은'이라는 알고리즘은 코딩으로는 일반적으로 For loop를 통해서 구현이 가능하다. For loop를 통해서 반복시켜야 할 데이터와 알고리즘이 몇 개 되지 않는다면 여전히 For loop는 직관적으로 쉽게 이해가 가능한 형태이므로 충분히 써먹을 수 있는 알고리즘이다. 하지만 딥러닝의 시대에서는 For loop는 더 이상 효율적인 알고리즘이 되기 어렵다. 무슨 말인지 살펴보자.


파이썬을 비롯하여 대다수 코딩 라이브러리의 경우, 데이터를 기본적으로는 열벡터(Column Vector)로 인식을 하게 된다. 예를 들어, W 와 X 그리고 b 가 각각 n 개의 요소로 이루어져 있다고 할 때 각각 n 차원의 열벡터로 데이터 형식을 정의할 수 있다. 

파이썬은 데이터를 기본적으로 열벡터로 인식한다


그렇다면 실제로  Z=WX + b는 어떻게 구현이 되는지  코딩의 벡터화 여부에 따라 각각 살펴보도록 하자.




코딩이 벡터화되지 않은 경우

슬라이드의 왼쪽에서 보듯이 인풋 데이터 X와 연결된 W가 n 개일 때 Z = wx + b를 구현하려면, 우선 그리고 w와 x는 각각 n 차원의 열벡터이므로 수학적으로 element-wise 곱을 나타내려면 W를  전치행렬 ( W Transpose)로 변환시키고 곱해야 한다. 그리고  z=0으로 초기화 시킨 후 For loop를 통해 반복적으로 계산을 해 주어야 한다. 



코딩이  벡터화된 경우

슬라이드의 오른쪽을 보자. 우리의 목적은 z = WX + b를 벡터화 시켜서 구현하는 것이다.

이 경우, 두 개의 열벡터 간의 곱은 어떻게 나타낼 수 있을까? 다행히 친절하게도 파이썬의 라이브러리에서는 np.dot(w, x)로 코딩해주면  element-wise의 열벡터 간의 곱을 나타내는 알고리즘이 쉽게 구현이 된다. 더하기는 그 자체로 element-wise 방식으로 계산이 되므로 그냥 +b로 구현이 가능하다. 즉, z=np.dot(W, X) + b로 나타낼 수 있다.


벡터화는 가볍다


어떤가? 지금 딱 한 눈으로 봐도 벡터화된 경우의 코드는 1줄이면 끝났고, 여기에 어떠한 반복적인 처리를 하는 For loop와 같은  코드가 없다. 똑같은 아웃풋을 내는 알고리즘인데 오른쪽과 같이 기존 파이썬에 내장된 함수를 통해 처리를 하면 훨씬 더 빠르고 가볍고 효율적인 알고리즘이 되는 것이다. (GPU와 CPU 모두 이러한 벡터화를 지원을 한다)

특히 딥러닝과 같은 무거운 알고리즘,  즉 무수히 많은 레이어와 노드로 구성이 된 알고리즘을 빠르고 효율적으로 구현하기 위해서는 For-loop 와 같은 알고리즘은 최대한 피하는 것이 좋다.



다른 예로 아래와 같이 n 차원의 열벡터 데이터 v에 exponential 을 취하는 경우를 생각해 보았을 때, 파이썬의 수학 라이브러리 numpy 가 제공하는 함수를 쓰면, for loop를 쓰지 않고 벡터화된 알고리즘을 간단히 구현할 수 있는 것이다. 




Summary 

파이썬 프로그래밍에 있어서 데이터는 벡터/매트릭스(행렬)로 인식이 되며, 특히 사용되는 데이터가 무수히 많은 딥러닝 알고리즘 구현에 있어서는 빠르고 효율적인 알고리즘을 위해 반드시 numpy 라이브러리를 사용하여 벡터화된 알고리즘을 구현하도록 해야 한다.



자료 출처 : https://www.youtube.com/watch?v=qsIrQi0fzbY&list=PLkDaE6sCZn6Ec-XTbcX1uRg2_u4xOEky0&index=17




매거진의 이전글 m개의 데이터에 대한 Gradient Descent
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari