안녕하세요.


이번에는 Docker를 이용해 구축한 TensorFlow(이하 텐서플로우)의 학습된 정보 (training)를 Tensorboard(이하 텐서보드)로 시각화는 방법을 다뤄 보겠습니다.


앞서 소개한 바 있는 Docker로 Windows에서 텐서플로우 수행하기 포스트에서 생성한 도커 컨테이너에서는 버그로 인해 텐서보드가 수행되지 않지 않는 현상이 있어 불가피하게 새로운 컨테이너를 만들어야 합니다.

귀찮겠지만 다음과 같이 새로운 컨테이너를 만들도록 합시다.   


1. 0.9 버전의 텐서플로우 컨테이너 만들기


Docker Quickstart Terminal를 실행한 후 현재 실행 중인 컨테이너 정보를 확인합시다.


$ docker ps -a


기존에 설치한 컨테이너가 수행 중이라면 정지하고 새로운 이미지를 다운로드 받아 설치합니다.


$ docker stop {수행중인 컨테이너 이름} $ docker run -p 8888:8888 -p 6006:6006 -it b.gcr.io/tensorflow/tensorflow:r0.9-devel

b.gcr.io/tensorflow/tensorflow 다음 콜론(:) 구분자 다음은 태그를 지칭하고 여기서 r0.9-devel 은 0.9 개발자 버전을 의미합니다.

(글을 작성하는 시점에서 텐서플로우는 활발히 개발 중인 프로젝트임으로 다음 링크에서 최신 버전에 대한 태그를 확인하기 바랍니다.)


또한 -d 옵션은 포트 포워딩을 의미하는데 jupyter가 사용하는 기본 포트인 8888과 텐서보드가 사용하는 포트인 6006를 전달해서 외부(즉, windows) 상에서 접속할 수 있게 해 줍니다.


다운로드가 완료되면 새로운 컨테이너가 생성되고 기본 값으로 bash 가 실행됩니다.


2. jupyter 실행하기


root@{컨테이너 아이디}:/# cd /


루트 폴더로 이동하면 jupyter를 실행할 수 있는 shell script 가 준비되어 있습니다. 이전 이미지는 컨테이너 생성 후 바로 이 스크립트를 수행하도록 지정되어 있으나 이 개발자 버전에서는 사용자가 직접 이 스크립트를 수행해 주어야 합니다.

bash가 종료되더라도 jupyter가 종료되지 않도록 nohup 으로 수행하고 새로운 process로 띄우기 위해 & 옵션을 줍시다.


root@{컨테이너 아이디}:/# nohup ./run_jupyter.sh


이제 windows에서 브라우저로 다음 경로에 접속해 jupyter를 실행합니다: 

http://192.168.99.100:8888/


3. 텐서보드 실행하기


텐서보드는 jupyter처럼 웹서비스로 동작합니다. 따라서 이를 실행하기 위해 run_jupyter.sh 와 같은 run_tensorboard.sh 스크립트를 만들어 보도록 하겠습니다.


root@{컨테이너 아이디}:/# nohup tensorboard --logdir=/logs --port 6006 &


여기서 logdir은 텐서플로우 프로그램에서 지정하는 로그 경로를 의미하고 port 는 사용할 포트를 의미합니다.

이제, windows 의 브라우저로 텐서보드를 접속해봅시다: 

http://192.168.99.100:6006/


아직 텐서플로우로 학습한 바가 없어서 아무런 기록이 없습니다.

4. 샘플코드 수행하기

jupyter에서 새로운 ipython 파일을 생성하고 샘플코드를 입력합시다.


import tensorflow as tf

# reset everything to rerun in jupyter
tf.reset_default_graph()

# config
batch_size = 100
learning_rate = 0.5
training_epochs = 5
logs_path = "/logs"

# load mnist data set
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)

# input images
with tf.name_scope('input'):
    # None -> batch size can be any size, 784 -> flattened mnist image
    x = tf.placeholder(tf.float32, shape=[None, 784], name="x-input") 
    # target 10 output classes
    y_ = tf.placeholder(tf.float32, shape=[None, 10], name="y-input")

# model parameters will change during training so we use tf.Variable
with tf.name_scope("weights"):
    W = tf.Variable(tf.zeros([784, 10]))

# bias
with tf.name_scope("biases"):
    b = tf.Variable(tf.zeros([10]))

# implement model
with tf.name_scope("softmax"):
    # y is our prediction
    y = tf.nn.softmax(tf.matmul(x,W) + b)

# specify cost function
with tf.name_scope('cross_entropy'):
    # this is our cost
    cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))

# specify optimizer
with tf.name_scope('train'):
    # optimizer is an "operation" which we can execute in a session
    train_op = tf.train.GradientDescentOptimizer(learning_rate).minimize(cross_entropy)

with tf.name_scope('Accuracy'):
    # Accuracy
    correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    
# create a summary for our cost and accuracy
tf.scalar_summary("cost", cross_entropy)
tf.scalar_summary("accuracy", accuracy)

# merge all summaries into a single "operation" which we can execute in a session 
summary_op = tf.merge_all_summaries()

with tf.Session() as sess:
    # variables need to be initialized before we can use them
    sess.run(tf.initialize_all_variables())

    # create log writer object
    writer = tf.train.SummaryWriter(logs_path, graph=tf.get_default_graph())
        
    # perform training cycles
    for epoch in range(training_epochs):
        
        # number of batches in one epoch
        batch_count = int(mnist.train.num_examples/batch_size)
        
        for i in range(batch_count):
            batch_x, batch_y = mnist.train.next_batch(batch_size)
            
            # perform the operations we defined earlier on batch
            _, summary = sess.run([train_op, summary_op], feed_dict={x: batch_x, y_: batch_y})
            
            # write log
            writer.add_summary(summary, epoch * batch_count + i)
            
        if epoch % 5 == 0: 
            print "Epoch: ", epoch 
    print "Accuracy: ", accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels})
    print "done"

MNIST 데이터셋(수기로 작성한 숫자를 모아 구분하는 데이터셋)을 이용해 간단한 소프트맥스 로지스틱스 회기 분류로 학습 후 평가하는 모델을 수행해 봅니다.

이때, 텐서보드를 위해 추가되는 코드는 다음과 같습니다.


  • logs_path = "/logs" : 텐서보드가 참조할 로그 정보가 저장될 경로를 지정
  • tf.scalar_summary("cost", cross_entropy)
    tf.scalar_summary("accuracy", accuracy)
    summary_op = tf.merge_all_summaries()

    : EVENTS 항목에 표시할 요약 정보로 cost와 accuracy를 지정
  • writer = tf.train.SummaryWriter(logs_path, graph=tf.get_default_graph())
    : SummaryWriter 개체를 생성해 로그 경로에 현재 그래프를 지정
  • _, summary = sess.run([train_op, summary_op], feed_dict={x: batch_x, y_: batch_y})
    : training과 summary operation을 수행
  • writer.add_summary(summary, epoch * batch_count + i)
    : minibatch 수행 시마다 결과 요약 저장

5. 텐서보드에서 결과 확인

텐서보드는 events, images, audios, graphs, histograms 항목으로 구성되어 있습니다.

이번 샘플 코드에서는 events 와 graphs 에 관한 정보만 저장됩니다.




events 항목에서 학습으로 인해 accuracy가 증가되면서 cost 가 주는 모습을 보여주는 도식을 볼 수 있으며, graphs 항목에서는 모델의 형태와 텐서의 흐름을 역동적으로 볼 수 있습니다.


5. 참고자료



안녕하세요.

TensorFlow docker image 를 윈도우즈에 설치하기

지난 포스트에서  docker의 마법을 활용해 (심지어 윈도우즈에다TensorFlow를 한 방에 설치해서 바로 활용하는 법을 정리한 바 있습니다.

이번에는 생성한 컨테이너를 다시 실행하거나 업데이트 하는 방법을 소개하고자 합니다. 이번 내용은 다음 도커 가이드에서 발췌하여 적용한 사례에 관한 부분입니다.


Docker 기본 사용법


앞서 docker에 대한 개념은 이해할 필요가 있는데 상위 링크에 자세한 설명이 있으니 참고하시기 바랍니다.


1. 컨테이너 시작


가상 머신을 수행하는 기기가 종료되면 (당연히) 여기서 (몰래) 돌고 있던 jupyter with TensorFlow server 역시 종료되게 됩니다. 따라서 Docker Quickstart Terminal를 다시 수행해야 합니다.


이때 설치된 컨테이너를 확인하기 위해 다음 명령을 수행합니다.


$ docker ps -a


상기 명령의 결과로 출력된 컨테이너 리스트 중에서 STATUS 항목으로 현재 수행 여부를 NAMES 에서 지정된 이름을 알 수 있습니다. 컨테이너가 수행 중이지 않다면 아래 명령과 더불어 NAMES 에 지정된 이름으로 해당 컨테이너를 실행시킬 수 있습니다.


$ docker start {컨테이너 이름}


 

2. 컨테이너 업데이트 하기


기본 사용법에 따르면 docker attach {컨테이터 이름} 을 통해 컨테이너에 접속할 수 있으나 활용 중인 TensorFlow container는 접속 시 console 없이 jupyter log 메시지만 출력하고 있는 관계로 아무런 명령을 수행할 수 없습니다. 따라서, 다음과 같이 외부에서 컨테이너에 명령을 수행할 수 있는 인터페이스를 활용하고자합니다.


docker exec {컨테이너 이름} {명령어 ... }


명령어는 bash shell에서 동작하는 대부분이 전달되는 것으로 보입니다. 

확인 차원에서 jupyter 의 확장 기능인 IPython Clusters 를 설치해 보았습니다.

자세한 설치 방법은 ipyparallel github guide를 참조했습니다.


$ docker ps

CONTAINER ID        IMAGE                            COMMAND             CREATED
             STATUS              PORTS                              NAMES
8eb60a8f3211        b.gcr.io/tensorflow/tensorflow   "/run_jupyter.sh"   5 weeks
 ago         Up 29 minutes       6006/tcp, 0.0.0.0:8888->8888/tcp   focused_yonath
$ docker exec focused_yonath pip ipyparallel


이와 같은 방식으로 컨테이너 외부에서도 추가 모듈을 설치하거나 업데이트할 수 있습니다.



안녕하세요. "생각의웹"입니다.


docker를 활용해 윈도우즈에서 TensorFlow가 설치된 iPython Jupiter를 설치해 활용하는 법 정리합니다.


먼저 원문은 다음과 같습니다: 

http://www.netinstructions.com/how-to-install-and-run-tensorflow-on-a-windows-pc/



원문을 따라서 수행하다보면 다음과 같은 문제점들이 발생합니다.

1) 계정 정보가 한글 ID인 경우, 경로 이상 문제 발생

2) TensorFlow docker image 설치 후 python 이 아닌 ipython server가 수행되고 shell이 뜨지 않음


이 현상들을 해결하고 다음과 같이 설치 및 활용 절차를 재정리합니다.


  1. Docker toolbox for Windows 설치: docker toolbox 설치 후 바탕화면에 등장하는 Docker Quickstart Terminal 을 실행합니다.
  2. default docker machine이 자동으로 생성됩니다. 다음 명령어로 생성된 docker machine을 확인합니다
    docker-machine ls
  3. TensorFlow가 preset 되어 있는 docker image를 cloning 하고 port forwarding 해서 수행합니다. 이때 8888 포트는 jupyter를 위해 6006 포트는 tensorboard를 위해 사용됩니다.
  4. docker run -p 8888:8888 -p 6006:6006 -it b.gcr.io/tensorflow/tensorflow
  5. 정상적으로 동작하면 다음과 같은 메세지가 표시됩니다.

  6. ...
    The Jupyter Notebook is running at : http:..[all ip addresses on your system]:8888/
    
  7. tensorboard를 사용하기 위해 다음과 같이 tensorboard를 활성화합니다.
     
  8. docker machine의 IP address를 확인합니다. 여기의 적힌 IP address가 접근 가능한 서버 주소가 됩니다.
  9. docker-machine ip default
  10. 만일 ip address가 192.168.99.100 이라면 browser를 열어 다음과 같이 tensorflow가 설치된 jupyter server에 접근할 수 있습니다.

  11. 192.168.99.100:8888

참고로 여기에 설치되어 있는 TensorFlow는 non-GPU 버전에 0.8입니다. 

GPU 사용 버전을 활용하시려면 github 가이드를 확인하시기 바랍니다.



이상입니다.

이제부터 tensorflow 공부를 제대로 해봐야 겠네요. 


+ Recent posts