머신러닝

5G 시대의 개막: 구글 Colaboratory에 의한 GPU 머신 러닝

coding art 2019. 6. 1. 16:30
728x90


머신 러닝을 위한 환경으로서 윈도우즈에 아나콘다를 설치하여 사용하고 있으나 또 다른 방법론이 있는바 구글의 컬래버러터리(“Colaboratory”) 이다. 머신 러닝을 실행시킬 수 있는 구글 NDRIVE 속의 특이한 Backend로서 쥬피터 노트북으로 보면 될 것이다.

노트북 스타일의 소프트웨어로는 이미 잘 알려져 있던 매쓰매티가가 있으며 MSDOS에서 벗어나 WIN 3.1이 발표되었던 95년경에 마이크로소프트 WORD와 함께 바인딩하여 노트북처럼 쓸 수 있었다. 노트북 스타일의 장점은 텍스트와 코드가 섞인 논문이나 기술 보고서를 작성하기에 편리해 보인다.




1년 반 전에 머신 러닝을 위한 아나콘다를 성공적으로 설치 후 필자의 블로그에서 인공지능 향학열이 높아 보이는 간절한 독자의 요청에 지극 받아 쥬피터 노트북을 설치하게 되었다. 설치와 아울러 몇 개의 예제를 실행 해 본 후 사실 상 쥬피터 사용은 손을 놓았었다. 하지만 다시 찾게 된 계기는 얼마 전에 LeCUN AI 랩 리더로 있는 Facebook에서 제공하는 PyTorch를 아나콘다에 설치하고 다소 컴퓨팅 부담이 큰 개미와 벌” Image 인식 예제가 쥬피터 노트북으로 코딩 되어 있어 다시 사용해 보았다.

 

그간에 지금까지 손댔던 머신 러닝 예제들의 크기가 작아 아나콘다 스파이더3 편집기를 벗어나야 할 필요성을 거의 느껴 보지 못했으나 앞서 언급했던 Image 인식 문제라든지, 또는 앞으로 해보고자 하는 전이학습(Transfer Learning)과 같이 고속의 대용량 컴퓨팅 파워 지원이 필요할 수도 있는 예제들이 나타나기 시작하는 듯하다.

 

구글의 컬래버러터리(“Colaboratory”)가 그렇게 매력적인지는 아직 모르겠으나 GPU를 무상으로 지원한다는 점을 지적하고자 한다. 개인적으로도 2018년 말에 졸저를 출판하였지만 그 이전서부터 GPU 코딩까지 지원하는 내용을 다루어 보고자 하는 동기가 있었던 것이 사실이지만 가격을 조사해보니 비트코인 및 채굴 열풍까지 더해 내가 사용하는 컴퓨터 가격의 수배 이상을 호가했었다. 그렇다고 구글이나 아마존의 유료 클라우드 서비스를 이용하기에는 부담스러웠는데 최근 언젠가 슬며시 무료 서비스로 제공되고 있음을 알게되어 무척 기쁘게 느껴진다.

 

제 아무리 부자라고해도 공짜라면 사죽을 못 쓰는게 인간의 본성인 듯하다. 얼릉 익혀서 사용해 보기로 한다. 구글 유튜브, 문서와 이메일을 비롯한 본인이 즐겨 사용하는 앱들이 나타나 있다. 구글에 로그인 되어 있는 상태에서 구글의 NDRIVE 속으로 들어가 보자.



NDIRIVE 속은 잡다한 사물들이 잔뜩 들어 있는데 + 연결할 앱 더보기를 선택 클릭하자.




드라이브 앱 연결이 뜨는데 엄청 많으므로 검색을 이용하도록 하자. “colaboatory”를 입력 검색한다.




Colaboratory 앱 아이콘이 뜨면 연결 버튼을 누르자.


연결 버튼 누른 후 기본 앱 설정 요구가 나오면

예스로 통과 후 평가하기 창이 뜨는데 끈 후 다시 앞으로 돌아가서 Colaboratory가 메뉴에 등록되었는지 살펴보고 있으면 클릭해서 시작하자.



대박! 클라우드형 쥬피터 노트북이 뜨는데 바로 코딩해서 실행시키면 될 것 같다.



아나콘다에서 실행되던 코드를 하나 복사하여 아래와 같이 셀 하나에 집어넣고 수정해서 실행해 보자. 파일을 저장하면 구글시트, 구글문서와 함께 NDRIVE에 저장된다. GPU device를 확인하는 명령을 넣어 두도록 하자. 아울러 CPU 만 사용할 때와 GPU 사용할 때의 실행 시간을 비교해 보기로 보자.


런타임 메뉴에서 유형을 GPU로 선택 변경하고 편집기 왼쪽의 버튼을 눌러 코드를 실행 시킨다.


편집기 위 RAM 디스크 부위를 클릭해 보면 GPU 처리 메세지를 볼 수 있다. 즉 컴퓨팅 과제물을 GPU에 입력 후 결과가 나올 때까지 대기하는 모양이다.



CPU GPU 실행을 비교해 보면 30% 실행 속도가 빨라져 있음을 알 수 있다.




10배 정도로 가속될까봐 조마조마 했는데 전혀 그런 걱정을 할 필요는 없을 듯하다. 하지만 컴퓨팅 타임이 정말로 크다면 GPU 접속을 위한 입출력은 1회이므로 모르긴 해도 수배에 이르는 가속효과를 볼 수 있을 듯하다.

 

구글이나 아마존 왜 GPU를 무료로 개방하는 것일까? 그 것은 이미 5G 통신시대가 시작되었기 때문이다. 퀄컴의 855 칩 스펙을 보면 그 작은 5G 스마트폰에 머신 러닝 지원을 위한 GPU 하드웨어가 이미 설치되었으며 컴퓨팅 속도가 장난이 아닌 듯 싶다. 아마도 머신 러닝이 5G 스마트폰을 디바이스로 하여 많이 발전하리라 보인다. 굳이 구글이 클라우드 GPU를 무료로 제공하지 않아도 아쉬울 것은 없을 것이다. 그럼에도 불구하고 구글이 클라우드 GPU 서비스를 유료로 묶어 둔다면 그 느려터진 구글 클라우드 서비스를 누가 사용하겠는가? 때 늦은 감이 있는 듯하지만 어쨌든 공짜이니 필요한 만큼 사용해 보기로 하겠다.

 

아래에 첨부된 파이선 텐서플로우 코드는 이미 필자의 졸저 3-12장과 3-13장에서 2차 다항식 형태의 hypothesis를 사용하여 XOR 로직문제를 처리하기 위해 사요했던 적이 있는 바 MNIST 문제의 인식율을 노여 보기 위해 입력 데이터를 covariance 처리하여 뉴럴 네트워크에 적용하여 보았더니 98%에 근접하는 상당히 높은 인식률을 보여준다. 그 상세한 이론적 배경은 여름철에 출판하게될 2권에 수록할 예정이다.

 

#mnist_nn_covariance_01.py

#MNIST_NN
import tensorflow as tf
import random
import time
#import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data

start_time = time.time()
tf.set_random_seed(777)  #reproducibility

mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

#parameters
learning_rate = 0.001
training_epochs = 1
batch_size = 100

#input place holders
X = tf.placeholder(tf.float32, [None, 784])
Y = tf.placeholder(tf.float32, [None, 10])

#weights & bias for nn layers
W1 = tf.Variable(tf.random_normal([784, 128], stddev=0.01))
b1 = tf.Variable(tf.random_normal([128], stddev=0.01))
W2 = tf.Variable(tf.random_normal([784, 128], stddev=0.01))
b2 = tf.Variable(tf.random_normal([128], stddev=0.01))
L1 = tf.nn.relu((tf.matmul(X, W2) + b2)*(tf.matmul(X, W1) + b1))
W3 = tf.Variable(tf.random_normal([128, 64], stddev=0.01))
b3 = tf.Variable(tf.random_normal([64], stddev=0.01))
L2 = tf.nn.relu(tf.matmul(L1, W3) + b3)
W4 = tf.Variable(tf.random_normal([64, 10], stddev=0.01))
b4 = tf.Variable(tf.random_normal([10], stddev=0.01))
hypothesis = tf.matmul(L2, W4) + b4

#define cost/loss & optimizer
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(
    logits=hypothesis, labels=Y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)

#initialize
sess = tf.Session()
sess.run(tf.global_variables_initializer())

#train my model
for epoch in range(training_epochs):
    avg_cost = 0
    total_batch = 20000
    #total_batch = int(mnist.train.num_examples / batch_size)

    for i in range(total_batch):
        batch_xs, batch_ys = mnist.train.next_batch(batch_size)
        feed_dict = {X: batch_xs, Y: batch_ys}
        c, _ = sess.run([cost, optimizer], feed_dict=feed_dict)
        avg_cost += c / total_batch

    print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.9f}'.format(avg_cost))

print('Learning Finished!')

#Test model and check accuracy
correct_prediction = tf.equal(tf.argmax(hypothesis, 1), tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print('Accuracy:', sess.run(accuracy, feed_dict={
      X: mnist.test.images, Y: mnist.test.labels}))

#Get one and predict
r = random.randint(0, mnist.test.num_examples - 1)
print("Label: ", sess.run(tf.argmax(mnist.test.labels[r:r + 1], 1)))
print("Prediction: ", sess.run(
    tf.argmax(hypothesis, 1), feed_dict={X: mnist.test.images[r:r + 1]}))

end_time = time.time()

print( "Completed in ", end_time - start_time , " seconds")