Amazon Web Services 한국 블로그

AWS로 딥 러닝을 위한 프레임워크 MxNet 활용하기

머신 러닝에 대한 관심이 폭발적으로 증가했습니다. 특히, 국내에서는 올해 알파고로 인해 딥러닝(Deep Learning)에 대한 관심이 크게 증가하였습니다. 인공 신경망을 이용한 딥 러닝 기법은 하드웨어 성능의 비약적인 개선과 신경망 알고리즘의 개선으로 인해 실제 활용 가능한 수준으로 빠르게 변화하였습니다.

이러한 관심으로 인해 분산 딥 러닝 프레임워크(distributed deep-learning framework)가 많이 개발되어 오픈소스 형식으로 공개되고 있는 상황입니다. 게임 서비스 영역에서도 차츰 딥 러닝을 활용한 서비스들이 지속적으로 나타나고 있습니다. 인공 지능 연구 및 서비스 개발자의 요구 사항, 지원 언어 및 하드웨어 따라 여러 종류의 딥 러닝 프레임워크가 개발되어 공개되었습니다. 대표적인 것이 MXNet,   Caffe , Theano , TensorFlow™, Torch  등이 있습니다.

딥러닝 프레임워크 소개
DeepLearning 4J에서 비교한 딥러닝 프레임워크 비교 기사를 보면 아래와 같은 장단점을 나열할 수 있습니다. (본 자료는 AWS의 공식적인 자료가 아니며, DeepLearning 4J의 의견입니다.)

프레임워크 장점 단점
Theano
  • Python 지원
  • Wrapper 를 통한 높은 추상화로 사용성 편리
  • 여러 에코시스템이 존재
  •  연구용으로 많이 사용됨
  • Theano자체는 로우레벨 라이브러리
  • 큰 규모 모델에 많은 컴파일 시간
  • torch에 비해 매우 큰 라이브러리
  • 에러메시지가 부정확
Torch
  • 모듈화된 라이브러리로 상호 연계가 쉬움
  • GPU지원, 본인 레이어 타입 작성이 편리
  • 선훈련된 모델들이 많음
  • Lua 기반
  • 회귀 뉴럴 네트워크에 적합하지 않음
  • 문서화 부실
TensorFlow
  • Python + Numpy
  • 컴퓨팅 그래프 추상화
  • Theano보다 빠른 컴파일
  • 시각화를 위한 TensorBoard
  • 데이터와 모델의 병렬화
  • 다른 프레임워크보다 느림
  • Torch보다 훨씬 큰 라이브러리
  • 선 훈련된 모델이 적음
  • 계산 그래프가 Python으로 되어 있어서 느림
  • 도구로서의 기능이 약함
Caffe
  • 이미지 프로세싱에 적합
  • 잘 튜닝된 네트워크
  • 코드 작성없이 모델 트레이닝 가능
  • Python인터페이스가 유용
  • GPU를 위해서는 C++/CUDA작성 필요
  • 회귀 네트워크에는 부적합
  • 큰 네트워크에는 부적절
  • 확장성이 떨어짐
MxNet
  • 혼합 패러다임 지원(symbolic/imperative)
  • 자동 미분화
  • GPU, mobile에서도 동작
  • 여러 언어 지원(C++, Python, R, Scala, Julia, Matlab and Javascript)
  • 최적화된 C++ 엔진으로 좋은 성능
  • 로우 레벨 텐서 연산자가 적음
  • 흐름 제어 연산자 지원하지 않음
  • 컴파일 세팅에 따라 결과가 달라짐.
  • 자신의 커스컴 레이어 생성을 위해서는 어느정도 백엔드 텐서 라이브러리 이해가 필요

아마존의 CTO인 Werner Vogels 박사께서는 최근 MXNet – Deep Learning Framework of Choice at AWS라는 글에서 확장 능력, 개발 속도, 이동성 등의 다양한 요인을 비추어 볼 때, MXNet이 가장 좋은 딥러닝 프레임웍이라고 판단하고, 이를 기반한 딥러닝 서비스 개발 지원 및 오픈 소스 지원에 대한 의지를 피력한 바 있습니다.

MxNet은 오픈소스로 여러 언어를 지원하고 모바일부터 서버까지 다양한 디바이스를 지원하는 딥 러닝 프레임워크 입니다. CPU와 GPU 연산을 지원하고, 심볼릭과 명령적(imperative) 프로그래밍의 혼합 방식 까지 지원하며 최적화된 엔진을 사용해서 성능이 뛰어납니다.

또한 실무적으로 많이 사용하는 Python, C++, R, Scala, Julia, Matlab, and JavaScript을 지원하는 등 산업계에서 응용하기에 매우 적합한 딥 러닝 프레임워크입니다.

아래 그림에서 보시다시피, Inception v3 (MXNet 및 P2 인스턴스 사용)를 통해 GPU 숫자를 증가시켰을 때, 다른 라이브러리 보다 빠른 처리량을 가짐과 동시에 GPU 숫자가 증가하는 확장 상황에서도 처리량의 효율이 85%에 달할 정도로 뛰어난 성능을 보여 주고 있습니다.

컴퓨팅 처리량 및 효율 뿐만 아니라 메모리 사용량도 중요합니다. MXNet은 1,000개의 신경망 레이어를 사용할 때 4GB 이하의 메모리를 사용하고, 이식성 면에서도 다양한 플랫폼을 지원합니다. 안드로이드나 iOS에서도 활용 가능하고, 심지어 자바스크립트 확장 기능으로 웹 브라우저에서도 실행 할 수 있습니다.

DeepLearning AMI를 통해 MXNet 실행하기
이 글에서는 Amazon EC2의 신규 GPU 기반 P2 인스턴스 및 G2 인스턴스를 통해 딥러닝 API를 기반으로 MXNet을 간단히 실행해 보겠습니다. (P2 및 G2 인스턴스는 시간당 가격이 다른 인스턴스에 비해 높으므로, 짧은 시간 테스트를 위해서는 스팟 인스턴스를 이용해 보는 것도 권장합니다.)

2016-11-mxnet-1

먼저 AWS 마켓 플레이스에서 제공하는 Amazon Deep Learning AMI을 기반으로 인스턴스를 실행합니다. 본 AMI에 설치된 딥 러닝 프레임워크는 Caffe, MxNet, TensorFlow, Theano, Torch 입니다. 우리는 여기서 MxNet을 사용해 보겠습니다. SSH로 접속해서 인스턴스의 src 디렉토리에 있습니다.

2016-11-mxnet-2

인스턴스의 src/mxnet/example 디렉토리를 보면 많은 예제들이 존재합니다. 이와 관련된 튜토리얼은 http://mxnet.io/tutorials/index.html 링크를 참조하면 됩니다.

우리가 실행을 해볼 것은 숫자 이미지를 트레이닝 해서 특정 이미지 내 숫자 데이터가 어떤 것인지 찾아내는 예제입니다. 간단한 Python 코드를 통해 해 볼 수 있습니다. (http://mxnet.io/tutorials/python/mnist.html.)

다만 여기서 플롯팅의 경우 현재 실행 중인 인스턴스에서 구동이 되지 않기 때문에 플롯(plot)을 이미지로 출력하는 부분은 제외하고 실행을 해야 합니다. 문서에는 단계별로 수행을 하게 되어 있습니다만 소스 부분을 고쳐서 한번에 실행하게 수정을 한 것이 다음 Python 소스 입니다.

import mxnet as mx

def to4d(img):
    return img.reshape(img.shape[0], 1, 28, 28).astype(np.float32)/255

batch_size = 100
train_iter = mx.io.NDArrayIter(to4d(train_img), train_lbl, batch_size, shuffle=True)
val_iter = mx.io.NDArrayIter(to4d(val_img), val_lbl, batch_size)


# Create a place holder variable for the input data
data = mx.sym.Variable('data')
# Flatten the data from 4-D shape (batch_size, num_channel, width, height) 
# into 2-D (batch_size, num_channel*width*height)
data = mx.sym.Flatten(data=data)

# The first fully-connected layer
fc1  = mx.sym.FullyConnected(data=data, name='fc1', num_hidden=128)
# Apply relu to the output of the first fully-connnected layer
act1 = mx.sym.Activation(data=fc1, name='relu1', act_type="relu")

# The second fully-connected layer and the according activation function
fc2  = mx.sym.FullyConnected(data=act1, name='fc2', num_hidden = 64)
act2 = mx.sym.Activation(data=fc2, name='relu2', act_type="relu")

# The thrid fully-connected layer, note that the hidden size should be 10, which is the number of unique digits
fc3  = mx.sym.FullyConnected(data=act2, name='fc3', num_hidden=10)
# The softmax and loss layer
mlp  = mx.sym.SoftmaxOutput(data=fc3, name='softmax')

# We visualize the network structure with output size (the batch_size is ignored.)
shape = {"data" : (batch_size, 1, 28, 28)}
mx.viz.plot_network(symbol=mlp, shape=shape)


import logging
logging.getLogger().setLevel(logging.DEBUG)

model = mx.model.FeedForward(
    symbol = mlp,       # network structure
    num_epoch = 10,     # number of data passes for training 
    learning_rate = 0.1 # learning rate of SGD 
)
model.fit(
    X=train_iter,       # training data
    eval_data=val_iter, # validation data
    batch_end_callback = mx.callback.Speedometer(batch_size, 200) # output progress for each 200 data batches
)

prob = model.predict(val_img[0:1].astype(np.float32)/255)[0]
print 'Classified as %d with probability %f' % (prob.argmax(), max(prob))

위의 코드를 실행하면 다음과 같이 모델을 훈련하게 되고, 그 다음에 숫자 7 이미지를 판단해서 결과를 출력합니다.

2016-11-mxnet-3

MxNet 의 Github 레포지터리의 example을 보면 이 외에도 아주 다양한 샘플 코드가 존재합니다.

딥 러닝은 이제 많은 분야에서 빠르게 응용되고 있습니다. 게임 개발자 분들도 이러한 딥 러닝 기법을 활용한 다양한 게임 AI를 만드셔서 활용하시기 바랍니다. 만약 실제 서비스를 위해 클러스터를 구성해야 한다면, AWS CloudFormation를 통해 AWS 자원을 손쉽게 만들고 운영할 수 있는 방식을 통해 딥러닝 클러스터를 만들 수 있는 MXNet의 CF 템플릿을 소개합니다.

이 템플릿을 이용하여 Amazon Deep Learning AMIAmazon EC2의 신규 GPU P2 인스턴스에 구성하여, 자동 스케일링을 지원하는 분산 딥러닝 클러스터를 만들어 운영할 수 있게 됩니다. (자세한 것은 AWS를 통한 분산 딥러닝(Deep Learning) 구성하기를 참고하세요.)

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 박선용 솔루션즈 아키텍트께서 작성해주셨습니다.