1. 텐서플로우 기본다지기 – First Contact with TensorFlow

tensorflowbookcover-1024x7122x이 글은 스페인 카탈루냐 공과대학의 Jordi Torres 교수가 텐서플로우를 소개하는 책 ‘First Contack with TensorFlow‘을 번역한 것 입니다. 이 글은 원 도서의 라이센스(CC BY-NC-SA 3.0)와 동일한 라이센스를 따릅니다.

목록으로가기

 

이 장에서는 텐서플로우의 코드와 프로그래밍 모델이 어떤지 간략히 소개합니다. 후반부에 가면 독자는 자기 컴퓨터에 텐서플로우를 설치할 수 있을 겁니다.

오픈소스 패키지

머신러닝은 수십년간 학계가 주도를 해왔지만 최근 수년간 기업에서도 연구활동이 활발해 졌습니다. 아마도 기업이 보유한 대량의 데이터와 전례없는 최신 컴퓨터 성능 덕택일 것입니다.

이런 맥락에서 알파벳의 자회사인 구글이 머신러닝 기술을 자사의 프로토타입과 제품에 핵심 역할로 사용하는 가장 큰 회사 중에 하나임에 틀림 없습니다.

지난 10월 알파벳이 구글의 매출과 이익이 크게 늘어난 분기 실적을 발표할 때 선다 피차이 CEO는 “머신러닝은 우리가 하는 모든 일에 대해 다시 생각케 만드는 핵심적이고 변화무쌍한 도구입니다”라고 분명하게 말했습니다.

기술적으로 보면 우리는 격변의 시기를 마주하고 있습니다. 여기에는 구글 뿐만이 아니라 마이크로소프트, 페이스북, 아마존, 애플 같은 테크기반의 회사들이 이 분야에 집중적으로 투자하고 있습니다.

이런 맥락에서 몇달전 구글은 텐서플로우 엔진을 오픈소스 라이센스(Apache 2.0)로 공개했습니다. 구글이 지메일, 구글 포토스, 검색, 음성인식 같은 상용 제품에 텐서플로우를 사용한 것 처럼 자신의 프로젝트나 제품에 머신러닝을 적용하고 싶은 개발자나 연구원들이 텐서플로우를 사용할 수 있게 되었습니다.

텐서플로우는 원래 머신러닝과 딥 뉴럴 네트워크(deep neural network) 연구를 수행하는 구글 브레인 팀에서 개발했지만 일반적인 머신러닝 문제에도 폭 넓게 적용하기에 충분합니다.

제가 엔지니어고 또 엔지니어에게 말하는 것이기 때문에 이 책에서는 어떻게 알고리즘이 데이터 플로우 그래프(data flow graph)로 표현되는지 자세히 알아 보겠습니다. 텐서플로우는 데이터 플로우 그래프를 사용해서 수치 연산을 하는 라이브러리로 볼 수 있습니다. 그래프의 노드(node)는 수학적 연산을 나타내고 노드를 연결하는 그래프의 엣지(edge)는 다차원 데이터 배열(array)을 나타냅니다.

텐서플로우는 수치연산을 기호로 표현한 그래프 구조를 만들고 처리한다는 기본 아이디어를 바탕으로 구현되었습니다. 그래서 텐서플로우는 CPU, GPU의 장점을 모두 이용할 수 있고 안드로이드나 iOS 같은 모바일 플랫폼은 물론 맥 OS X와 같은 64비트 리눅스에서 바로 사용될 수 있습니다.

텐서플로우의 또 하나의 강점은 알고리즘이 어떻게 돌아가고 있는지 알려주기 위해 많은 정보를 모니터링하고 디스플레이 해주는 텐서보드 모듈입니다. 좀 더 좋은 모델을 만들기 위해서 알고리즘의 동작을 조사해서 디스플레이 하는 것이 매우 중요합니다. 종종 시행착오를 통해 약간 불분명한 프로세스로 많은 모델을 만들고 있는데 이건 당연히 리소스 특히 시간 낭비입니다.

텐서플로우 서빙(Serving)

최근에 구글에서는 텐서플로우의 머신러닝 모델을 운영 환경으로 배포하는 것을 도와주는 텐서플로우 서빙을 런칭했습니다.(심지어 다른 패키지의 모델까지로도 확장할 수 있습니다.) 텐서플로우 서빙은 아파치 2.0 라이센스로 깃허브에 올려져 있는 오픈소스이며 C++로 작성되어 있습니다.

텐서플로우와 텐서플로우 서빙의 차이점은 뭘까요? 텐서플로우가 입력된 데이터를 가지고 머신러닝 알고리즘을 만들고 모델을 훈련시키는 걸 도와주는 것이라면 텐서플로우 서빙은 이 모델을 운영환경에서 사용할 수 있도록 도와줍니다. 모델은 텐서플로우를 이용해 훈련시키고 사용자로부터 들어오는 입력 데이터를 반영하기 위해 텐서플로우 서빙 API를 이용할 수 있습니다.

개발자들은 실제 환경의 데이터로 시스템의 구조와 API를 안정적으로 유지하면서 대규모의 모델들을 바꿔가면서 테스트할 수 있습니다.

전형적인 작업 파이프라인(pipeline)은 학습기에 훈련 데이터를 공급하고 모델을 만든 다음 검증 절차를 거쳐서 텐서플로우 서빙 시스템에 배포하는 것입니다. 보통 모델이 런칭되고 새로운 데이터가 생기거나 모델을 개선하기 위해 위와 같은 작업은 반복적으로 일어납니다. 실제 구글이 블로그에서 밝힌 것 처럼 많은 작업 파이프라인들이 끊임 없이 돌아가고 있으며 새로운 데이터가 입수될 때 마다 새로운 모델을 만들어 내고 있습니다.

tensorflowserving

구글에서 오픈소스로 공개한 고성능 RPC 프레임워크인 gRPC를 이용해 텐서플로우 서빙 시스템은 프론트 엔드 시스템과 통신합니다. 텐서플로우 서빙에 대해 더 알고 싶다면 서빙 아키텍처 개요를 참고하고 환경설정을 한 뒤에 기본 튜토리얼을 따라 해 보시길 추천해 드립니다.

텐서플로우 설치

이제 직접 해 볼 시간입니다. 지금부터는 책을 읽으면서 실습을 해 보시길 권합니다.

텐서플로우의 파이썬 API(C/C++ API도 있습니다)를 사용하려면 파이썬 2.7 버전을 설치해야 합니다.(이 책을 읽는 엔지니어라면 어떻게 설치하는 지 알고 있으리라 생각합니다.) (역주: 특별한 이유가 없다면 3.5.x 버전 이상의 파이썬을 사용하는 것이 좋습니다.)

일반적으로 파이썬으로 작업을 할 때는 virtualenv라는 가상환경을 사용해야 합니다. Virtualenv는 한 컴퓨터에서 여러 프로젝트를 작업할 때 파이썬 패키지의 의존성이 충돌하지 않도록 관리해주는 툴 입니다. 즉 virtualenv를 사용하여 텐서플로우를 설치하면 의존성 때문에 같이 설치 되는 패키지들이 다른 프로젝트에서 설치한 같은 패키지들을 덮어쓰지 않게 됩니다. (역주. anaconda 패키지를 설치하신 경우라면 conda 명령을 이용해서도 가상환경을 관리할 수 있습니다.)

우선 pipvirtualenv를 아래 명령으로 설치합니다.

# Ubuntu/Linux 64-bit
$ sudo apt-get install python-pip python-dev python-virtualenv 

# Mac OS X 
$ sudo easy_install pip
$ sudo pip install --upgrade virtualenv

~/tensorflow 디렉토리에 virtualenv 환경을 만듭니다.

$ virtualenv --system-site-packages ~/tensorflow

다음은 아래처럼 virtualenv를 활성화시키는 것입니다.

$ source ~/tensorflow/bin/activate #  with bash 
$ source ~/tensorflow/bin/activate.csh #  with csh
tensorflow)$

활성화된 후에는 명령줄 시작 부분에 현재 작업하고 있는 virtualenv 이름이 나타나게 됩니다. virtualenv가 활성화 되었으므로 pip를 이용해 텐서플로우를 설치합니다. (역주. 최신버전의 텐서플로우 설치는 여기를 참고해 주세요.)

# Ubuntu/Linux 64-bit, CPU only:
(tensorflow)$ sudo pip install --upgrade https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.7.1-cp27-none-linux_x86_64.whl 

# Mac OS X, CPU only:
(tensorflow)$ sudo easy_install --upgrade six
(tensorflow)$ sudo pip install --upgrade https://storage.googleapis.com/tensorflow/mac/tensorflow-0.7.1-cp27-none-any.whl

최신 버전을 설치하려면 공신 설치 문서인 여기를 참고하세요.

사용하고 있는 플랫폼이 GPU를 가지고 있으면 설치해야 할 패키지가 다릅니다. 공식 문서를 참고해서 시스템의 GPU가 텐서플로우가 지원하는 스펙에 부합되는 것인지 확인하세요. 텐서플로우 GPU 버전을 이용하려면 추가적인 소프트웨어를 설치해야 합니다. 텐서플로우 다운로드와 설치 웹 페이지를 참고해 주세요. GPU를 이용하는 자세한 내용은 6장을 참고하세요.

마지막으로 작업을 마쳤을 때는 버추얼 환경을 빠져나와야 합니다.

(tensorflow)$ deactivate

이 책은 입문서로 쓰여 졌기에 텐서플로우를 설치하는 다른 방법에 대해서는 공식 문서를 참고해 주세요.

첫번째 텐서플로우 코드

서두에 이야기했듯이 텐서플로우라는 행성을 탐험하기 위해 이론은 조금만 다루고 실습을 많이 하겠습니다. 렛츠고!

지금부터는 텍스트 편집기를 사용해서 파이썬 코드를 작성하고 .py 확장자로 저장하는 것이 좋습니다.(예, text.py)

텐서플로우 프로그램이 어떤지 처음 맛보기 위해 간단한 곱셈 프로그램을 만들어 보겠습니다. 코드는 아래와 같습니다.

import tensorflow as tf

a = tf.placeholder("float")
b = tf.placeholder("float")

y = tf.mul(a, b)

sess = tf.Session()

print sess.run(y, feed_dict={a: 3, b: 3})

이 코드에서 텐서플로우 파이썬 모듈을 임포트한 후 프로그램 실행 중에 값을 변경할 수 있는 placeholder라 부르는 심볼릭 변수들을 정의합니다. 그리고 나서 텐서플로우에서 제공하는 곱셈 함수를 호출할 때 이 두 변수를 파라메타로 넘깁니다. tf.mul은 텐서(tensor)를 조작하기 위해 텐서플로우가 제공하는 많은 수학 연산 함수 중 하나입니다. 여기서 텐서는 동적 사이즈를 갖는 다차원 데이터 배열이라고 생각하면 됩니다.

주요한 함수는 아래와 같습니다. (역주: 텐서플로우에는 이외에도 많은 기본적인 수학함수를 제공하고 있습니다. 상세한 내용은 API 문서를 참고해 주세요.)

함수 설명
tf.add 덧셈
tf.sub 뺄셈
tf.mul 곱셈
tf.div 나눗셈의 몫
tf.mod 나눗셈의 나머지
tf.abs 절대값을 리턴합니다.
tf.neg 음수를 리턴합니다.
tf.sign 부호를 리턴합니다.(역주: 음수는 -1, 양수는 1, 0 일땐 0을 리턴합니다)
tf.inv 역수를 리턴합니다.(역주: 3의 역수는 1/3 입니다)
tf.square 제곱을 계산합니다.
tf.round 반올림 값을 리턴합니다.
tf.sqrt 제곱근을 계산합니다.
tf.pow 거듭제곱 값을 계산합니다.
tf.exp 지수 값을 계산합니다.
tf.log 로그 값을 계산합니다.
tf.maximum 최대값을 리턴합니다.
tf.minimum 최소값을 리턴합니다.
tf.cos 코사인 함수 값을 계산합니다.
tf.sin 사인 함수 값을 계산합니다.

텐서플로우는 행렬 연산을 위해서도 여러가지 함수를 제공합니다. 아래 몇가지를 적었습니다.(역주: 텐서플로우에는 이외에도 많은 행렬 함수를 제공하고 있습니다. 상세한 내용은 API 문서를 참고해 주세요.)

함수 설명
tf.diag 대각행렬을 리턴합니다.
tf.transpose 전치행렬을 리턴합니다.
tf.matmul 두 텐서를 행렬곱셈하여 결과 텐서를 리턴합니다.
tf.matrix_determinant 정방행렬의 행렬식 값을 리턴합니다.
tf.matrix_inverse 정방행렬의 역행렬을 리턴합니다.

그 다음 가장 중요한 것 하나는 심볼릭 표현으로 된 수식을 계산하기 위해 세션을 생성하는 것입니다. 사실 여기까지는 아무것도 실행되지 않습니다. 저는 텐서플로우가 머신러닝 알고리즘을 표현하는 인터페이스적인 측면과 알고리즘을 실행시키는 프로그램으로서의 측면을 모두 가지고 있다는 것을 강조하고 싶습니다.

Session() 함수를 통해 세션을 생성함으로써 프로그램이 텐서플로우 라이브러리와 상호작용하게 됩니다. 즉 세션을 생성하여 run() 메소드를 호출할 때 비로서 심볼릭 코드가 실제 실행됩니다. 예제에서 run() 메소드에 feed_dict 인자로 변수의 값을 넘겼습니다. 입력된 수식이 계산되면 곱의 결과 9를 프린트하고 종료됩니다.

간단한 이 예제에서 볼수 있듯이 텐서플로우 프로그램의 일반적인 구조는 전체 알고리즘을 먼저 기술하고 세션을 생성하여 연산을 실행시키는 것입니다.

그러나 때로는 프로그램을 구성할 때 코드의 일부분만 계산을 수행하면서 그래프 구조를 만들어 가고 싶을 때가 있습니다. 이런 경우는 iPython 같은 대화식 환경을 사용할 경우입니다. 텐서플로우는 이런 용도로 tf.interactiveSession() 클래스를 제공합니다.

이런 프로그래밍 모델의 배경에 대해 설명하는 것은 이 책의 범위를 넘어섭니다. 그러나 다음 장을 계속 진행하기 위해 꼭 알아둬야 할 것은 연산과 데이터에 대한 모든 정보는 그래프 구조안에 저장된다는 점 입니다.

그래프 구조는 수학 계산을 표현합니다. 노드는 수학 연산를 나타내고 데이터 입력과 출력의 위치를 나타내거나 저장된 변수를 읽거나 씁니다. 엣지는 입력 값과 출력 값으로 연결된 노드 사이의 관계를 표현하고 그와 동시에 텐서플로우의 기본 데이터 구조인 텐서를 운반합니다.

텐서플로우는 그래프 구조로 표현된 정보를 이용해서 트랜잭션 간의 의존성을 인식하고 노드에 입력 데이터로 들어 올 텐서가 준비될 때 디바이스(역주: CPU 또는 GPU)에 비동기적으로 그리고 병렬적으로 연산을 할당합니다.

병렬처리 덕택에 계산 비용이 많이 드는 복잡한 알고리즘을 빠르게 실행시킬 수 있습니다. 또 텐서플로우가 복잡한 연산에 대해 효율적으로 구현되어 있기 때문입니다. 거기에 더해서 GPU 같은 특별한 디바이스에 맞도록 연산 처리를 구현한 커널(역주: 커널은 디바이스 별로 연산 로직을 구현한 코드입니다)을 가지고 있습니다. 아래 테이블은 가장 중요한 연산(커널)을 요약했습니다.

연산 카테고리 연산 예
Maths Add. Sub, Mul, Div, Exp, Log, Greater, Less ,Equal
Array Concat, Slice, Split, Constant, Rank, Shape, Shuffle
Matrix MatMul, MatrixInverse, MatrixDeterminant
Neuronal Network SoftMax, Sigmoid, ReLU, Convolution2D, MaxPool
Checkpointing Save, Restore
Queues and syncronizations Enqueue, Dequeue, MutexAcquire, MutexRelease
Flow control Merge, Switch, Enter, Leave, NextIteration

디스플레이 패널 텐서보드

더 범용적인 툴로 만들기 위해 텐서플로우는 시각화 툴인 텐서보드에 프로그램을 최적화하고 디버깅하는 기능을 포함시켰습니다. 텐서보드에서는 도식화한 그래프의 각 부분의 상세 정보와 파라메타들에 대한 여러 통계 데이터를 볼 수 있습니다.

텐서보드에 나타나는 데이터는 summary 연산으로 취득할 수 있는 데이터로서 텐서플로우가 실행되는 동안 생성되며 추적 파일에 저장됩니다. 텐서플로우의 도큐먼트 페이지에서 파이썬 API의 자세한 설명을 참고하세요.

텐서보드를 실행하는 것은 간단합니다. 커맨드라인에서 추적 정보가 담겨있는 파일을 인자로 지정하여 실행시키면 됩니다.

(tensorflow)$ tensorboard --logdir=<trace file>

그리고 간단하게 브라우저에서 http://localhost:6006/ 으로 접속하면 됩니다.

텐서보드에 대한 자세한 설명은 이 책의 범위를 벗어납니다. 텐서보드가 어떻게 동작하는지에 대한 자세한 설명은 텐서플로우 튜토리얼 페이지의 텐서보드 그래프 시각화 섹션을 참고하세요.

목록으로가기