MXNet 시작하기 (1) – NDArrays API

이 시리즈는 AWS 테크 에반젤리스트인 Julien Simon이 연재한 MXNet 관련 글 모음의 번역 편집본으로 최근 각광 받고 있는 Deep Learning 라이브러리인 Apache MXnet  을 개괄적으로 설명하려고 합니다.

이 글은 간단한 코드를 이해하는 개발자라면 기계 학습과 인공 지능을 잘 알지 못하는 분이라도 쉽게 따라올 수 있도록 했습니다. 너무 겁먹지 않으셔도 됩니다.

우선 몇 차례에 걸쳐 Apache MXNet의 주요 기능과 관련된 API를 예제 코드 위주로 살펴 보겠습니다.

MXNet의 이론적 근거와 아키텍처에 대해 더 자세히 알고 싶다면 “MXNet : 이기종 분산 시스템을위한 유연하고 효율적인 기계 학습 라이브러리“라는 논문를 읽어 보시길 추천합니다. 하지만, 어려운 논문을 살펴 보는 건 이 시리즈의 목적이 아니고, 개발자를 위해 기존 개념을 다루면서도 코드를 직접 사용하여 보다 이해하기 쉽게 ​​접근 할 예정입니다.

여러분은 천천히 따라오면서 필요한 만큼의 최소한의 수학과 어려운 용어를 조금씩 익힐 수 있습니다. 저도 여러분과 같이 아직 전문가가 아니며, 우리가 만드는 애플리케이션에 인공 지능 기능을  어떻게 추가 할 수 있는지에 대해서만 집중하려고 합니다.

MXNet 설치 및 실행하기
우선 먼저 MXNet을 설치하십시오. 여기에서 공식 가이드를 찾을 수 있지만, 여기에서 간단히 설치할 수 있는 방법을 알려드립니다.

MXNet의 주요 기능 중 하나는 CPU와 GPU에서 동일하게 실행될 수 있다는 것입니다. 즉, 컴퓨터에 NVIDIA GPU (MacBook과 동일)가 없더라도 나중에 AWS에서 제공하는 GPU 기반 가상 클라우드 인스턴스에서 사용 가능한 MXNet 코드를 작성하고 실행할 수 있습니다.

여러분 PC에 GPU가 있으면 CUDAcuDNN툴킷을 설치해야합니다. 그런데, 이 도구를 설치하는 것이 초보자 입장에서 매우 까다롭고 MXNet 바이너리와 Nvidea 도구 사이의 비 호환성으로 인해 설정이 깨져서 작업하기가 어려울 수 있습니다.

이러한 이유로 MXNet 웹 사이트에서 제공되는 Docker 이미지 (CPU 환경 용, GPU 환경 용) (nvidia-docker가 필요함)를 사용하는 것이 좋습니다. 이 이미지에는 필요한 모든 것을 사전 설치하여, 몇 분 안에 시작할 수 있습니다.

sudo -H pip install mxnet --upgrade
 python
 >>> import mxnet as mx
 >>> mx.__version__
 '0.9.3a3'

Docker 이미지는 ‘pip’를 통해 사용할 수 있는 Python 패키지보다 최신 버전 인 것 같습니다.

docker run -it  mxnet/python
 root@88a5fe9c8def:/# python
 >>> import mxnet as mx
 >>> mx.__version__
 '0.9.5'

AWS에서 MXNet 실행하기

AWS는 Linux 및 Ubuntu에서 사용할 수있는 Deep Learning AMI(Amazon Liunx Deep Learning AMIUbuntu Deep Learnin AMI)를 제공합니다. 본 AMI에는 모든 Nvidia 도구와 그 밖의 많은 딥러닝 프레임 워크 (MXNet 포함)가 사전 설치되어 제공됩니다.

====================================================================
 __|  __|_  )
 _|  (     /   Deep Learning AMI for Amazon Linux
 ___|\___|___|
 ====================================================================

[ec2-user@ip-172-31-42-173 ~]$ nvidia-smi -L
 GPU 0: GRID K520 (UUID: GPU-d470337d-b59b-ca2a-fe6d-718f0faf2153)

[ec2-user@ip-172-31-42-173 ~]$ python
 >>> import mxnet as mx
 >>> mx.__version__
 '0.9.3'

본 AMI는 일반 Amazon EC2 인스턴스 또는 GPU 인스턴스에서 실행할 수 있습니다. 컴퓨터에 Nvidia GPU가없는 경우 나중에 네트워크 교육을 시작할 때 유용 할 수 있습니다. 가장 저렴한 옵션은 g2.2xlarge 인스턴스를 시간당 0.65 달러로 사용하는 것입니다.

우선은 공부를 위한 것이니 만큼 당분간 CPU 만 있으면됩니다! 이제 시작해 보겠습니다.

NDArrays가 중요한 이유
MXNet API에서 살펴볼 첫 번째 부분은 NDArrays입니다.  NDArray는 동일한 유형 및 크기 항목 (32 비트 부동 소수점, 32 비트 정수 등)을 포함하는 n차원 배열입니다. 이 배열이 중요한 이유는  딥러닝 학습 및 실행에 필요한 많은 수학 연산을 통한 데이터 저장을 할 수 있는 다차원 배열이기 때문입니다. 입력 데이터, 가중치 및 출력 데이터는 벡터 및 행렬에 저장되므로 이러한 종류의 데이터 구조를 사용해야 합니다.

간단한 예를 들어 봅시다. 아래 이미지는 손으로 쓴 ‘8’이라는 이미지를  18×18 픽셀로 나누었습니다.


숫자 8, 18×18 픽셀

이 이미지는 18×18 매트릭스와 동일한 이미지로서 각 셀은 해당 픽셀의 그레이 스케일 값을 저장합니다. 흰색은 ‘0’, 검정은 ‘255’, 그레이 스케일은 ‘254’입니다. 이 행렬 표현은 신경망을 통해 0에서 9까지 숫자를 범주화하여 학습을 진행합니다.


그레이 스케일 값을 유지하는 18×18 매트릭스

이제 그레이 스케일 이미지 대신 컬러 이미지를 사용한다고 상상해봅시다. 각 이미지는 각 색상에 하나씩 3 개의 행렬을 사용하기 때문에 입력 데이터는 이제 약간 더 복잡해졌습니다.

한 단계 더 들어가서, 자동차 자율 주행을 위해 실시간 이미지 인식을 하고 있다고 가정 해보죠. 카메라에 찍히는 사물 데이터를 인지하기 위해 초당 30 프레임의 1000 x 1000 픽셀 RGB 이미지를 사용하고 있습니다. 매초마다 90 개의 1000 x 1000 매트릭스 (30 프레임 x 3 색)를 처리해야 합니다. 각 픽셀을 32 비트 값으로 표현하면 90 x 1000 x 1000 x 4 바이트, 그 이상 또는 이하의 343 메가 바이트가됩니다. 여러 대의 카메라를 가지고 있다면 더 복잡해 집니다.

이러한 정도의 데이터 크기가 신경망을 통해 전달하는 사이즈입니다. 최대 성능 (즉, 최소 대기 시간)을 위해 GPU는 이미지를 하나씩 처리하지 않고 일괄 적으로 처리합니다. 배치(Batch) 크기를 8로 설정하면 신경망은 입력 데이터를 1000 x 1000 x 24의 단위(chunk)로 처리합니다. 즉 3 개의 색상으로 8 1000 x 1000 이미지를 보유하는 3 차원 배열을 처리합니다.

요점:  NDArrays는 신경망 학습에 있어서 기본이고, 모든 데이터를 저장하는 방법이라 첫번째로 꼭 알아두셔야 합니다.

NDArray API 사용해 보기
이제 실제로 NDArray가 어떻게 작동하는지 살펴 보겠습니다. 여러분이 Python 기반 numpy 라이브러리를 사용해 보셨다면, NDArrays는 이와 매우 유사하며 NDArray API의 대부분을 바로 이해하실 수 있습니다.

하지만 걱정하지 마세요! 기초부터 시작하겠습니다. 🙂

>>> a = mx.nd.array([[1,2,3], [4,5,6]])
 >>> a.size
 6
 >>> a.shape
 (2L, 3L)
 >>> a.dtype
 <type 'numpy.float32'>

기본적으로 NDArray에는 32 비트 부동 소수점이 있지만 사용자 정의 할 수 있습니다.

>>> import numpy as np
 >>> b = mx.nd.array([[1,2,3], [2,3,4]], dtype=np.int32)
 >>> b.dtype

NDArray 출력도 간단합니다.

>>> b.asnumpy()
 array([[1, 2, 3],
 [2, 3, 4]], dtype=int32)

원하는 수학 연산자를 모두 사용할 수 있습니다. 행렬 곱셈을 시도해 봅시다.

>>> a = mx.nd.array([[1,2,3], [4,5,6]])
 >>> b = a*a
 >>> b.asnumpy()
 array([[  1.,   4.,   9.],
 [ 16.,  25.,  36.]], dtype=float32)

행렬 곱셈 (dot product)은 다음과 같습니다.

>>> a = mx.nd.array([[1,2,3], [4,5,6]])
 >>> a.shape
 (2L, 3L)
 >>> a.asnumpy()
 array([[ 1.,  2.,  3.],
 [ 4.,  5.,  6.]], dtype=float32)

>>> b = a.T
 >>> b.shape
 (3L, 2L)
 >>> b.asnumpy()
 array([[ 1.,  4.],
 [ 2.,  5.],
 [ 3.,  6.]], dtype=float32)

>>> c = mx.nd.dot(a,b)
 >>> c.shape
 (2L, 2L)
 >>> c.asnumpy()
 array([[ 14.,  32.],
 [ 32.,  77.]], dtype=float32)

조금 더 복잡한 것을 시도해 봅시다.

  • 균일 분포로 1000×1000 매트릭스를 초기화하고, GPU #0에 저장합니다 (여기서 g2 인스턴스를 사용합니다.)
  • GPU #0에서도 일반 분포 (평균 1과 표준 편차 2)를 갖는 또 다른 1000×1000 매트릭스를 초기화합니다.
>>> c = mx.nd.uniform(low=0, high=1, shape=(1000,1000), ctx="gpu(0)")
 >>> d = mx.nd.normal(loc=1, scale=2, shape=(1000,1000), ctx="gpu(0)")
 >>> e = mx.nd.dot(c,d)

MXNet은 CPU와 GPU에서 동일하게 실행될 수 있습니다. 실례로 “gpu(0)”을 “cpu(0)”로 바꾸면 행렬 곱셈이 CPU에서 실행됩니다.

정말 간단하게 NDArrays를 알아보았습니다. 신경망 구축을 위한 상위 기능(FullyConnected 등)은 나중에 실제 신경망을 알아볼 때 더 배워 보도록 하겠습니다. 다음 글에서는 데이터 흐름을 정의 할 수있는 Symbol API를 살펴볼 것입니다.

다음 글: MXNet 시작하기 (2) – Symbol API

연재 순서

Julien Simon은 파리에서 개발자들의 클라우드 활용을 돕는 AWS Principal Technical Evangelist로 일하고 있습니다. 선마이크로시스템에서 임베디드 개발자로 시작하여, 6천5백만명이 사용하는 Viadeo라는 스타트업을 비롯 Aldebaran Robotics, Criteo, Pixmania 등의 회사에서 CTO 역할을 수행하였습니다. 본 블로그에서는 Julien이 최근 기고하는 MXNet 관련 블로그 글을 한국어로 소개해 드릴 예정입니다.

여러분의 생각

Copyright(c) 1996-2016, Channy Yun All rights reserved.