본문 바로가기

Theory/DeepLearning

[Tensor Flow] 텐서보드 Tensorboard 사용해보기

최근 저는 텐서플로우로 간단한 Hello World 수준의 예제를 한 번 다뤄보고[바로가기], 그 후에 변수의 히스토리를 Python list형으로 저장해서 학습이 완료된 후에 확인해보는 것[바로가기]을 다루고난 후, 입력 변수가 2개, 출력 변수가 1개인 경우의 선형회귀(Linear Regression) 문제를 텐서플로우로 확인하는 예제[바로가기]도 다루어 보았습니다. 이제 텐서플로우에서 참 유용하게 사용하는 텐서보드(Tensor Board)를 소개하려고 합니다. 이전에 정말 초급모드로 다룬적[바로가기]이 있습니다만, 그 때는 저 자신도 그게 뭔지도 모르고 그냥 이렇게 하니 되네요~~하고 이야기했던 거라 다시 다뤄보고 싶었습니다.

언제나 Python을 공부하다 보면 참 고마운 분들이 많습니다. 너무 많은 분들이 좋은 내용을 공유하고 계시죠. 이번 글도 김성훈 교수님의 유명한 딥러닝과 텐서플로우 공개 강좌[바로가기], 그 외에 엣지있게 설명한 텐서플로우[바로가기], 딥러닝 첫걸음[바로가기], 처음 배우는 머신러닝[바로가기]을 정말 단순히 따라가는 수준입니다.

이제... 텐서보드를 사용하기 위해 어떻게 해야하는지 보도록 하겠습니다. 예제는 AND를 학습하겠다는 정말 기초적인 첫 예제[바로가기]를 살짝 바꾸는 걸로 하겠습니다.

import tensorflow as tf
import numpy as np
from tqdm import tqdm_notebook
import matplotlib.pyplot as plt
%matplotlib inline

# AND
x_data = np.array([[0, 0],
                  [0, 1],
                  [1, 0],
                  [1, 1]], dtype=np.float32)
y_data = np.array([[0],
                  [0],
                  [0],
                  [1]], dtype=np.float32)

X = tf.placeholder(tf.float32, [None, 2], name='x-input')
Y = tf.placeholder(tf.float32, [None, 1], name='y-input')

먼저 당시 그 예제와 동일하게 설정을 진행하구요...

with tf.name_scope("layer") as scope:    
    W = tf.Variable(tf.random_normal([2, 1]), name='weight')
    b = tf.Variable(tf.random_normal([1]), name='bias')

    hypothesis = tf.sigmoid(tf.matmul(X, W) + b)
    
    w_hist = tf.summary.histogram("weight", W)
    b_hist = tf.summary.histogram("bias", b)
    hypothesis_hist = tf.summary.histogram("hypothesis", hypothesis)

저렇게... with 구문으로 tf.name_scope를 사용하면 나중에 위 코드 안에 있는 W, b, hypothesis를 하나로 묶어서 보여주기 때문에 이쁘게 보입니다. 그리고 histogram으로 보고 싶은 변수는 tf.summary.histogram으로 변수를 잡아 주면 됩니다.

with tf.name_scope("cost") as scope:
    cost = -tf.reduce_mean(Y * tf.log(hypothesis) + (1 - Y) * tf.log(1 - hypothesis))
    cost_summ = tf.summary.scalar("cost", cost)

with tf.name_scope("train") as scope:
    train = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(cost)

그리고... scalarcost를 보고 싶다면 tf.summary.scalar로 잡으면 됩니다. 그냥 보기 좋게 tf.name_scopewith만 잡으면 되구요.

# Accuracy computation
# True if hypothesis>0.5 else False
predicted = tf.cast(hypothesis > 0.5, dtype=tf.float32)
accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, Y), dtype=tf.float32))
accuracy_summ = tf.summary.scalar("accuracy", accuracy)

이제... predictedaccuracy는 원래 하던대로 잡았고, accuracy만 scalar로 보고 싶어서 tf.summary.scalar로 잡아 주었습니다.

# Launch graph
with tf.Session() as sess:
    # tensorboard --logdir=./logs
    merged_summary = tf.summary.merge_all()
    writer = tf.summary.FileWriter("./logs/hello_tf_180115-1")
    writer.add_graph(sess.graph)  # Show the graph
    
    # Initialize TensorFlow variables
    sess.run(tf.global_variables_initializer())

    for step in tqdm_notebook(range(10001)):
        summary, _ = sess.run([merged_summary, train], feed_dict={X: x_data, Y: y_data})
        writer.add_summary(summary, global_step=step)

    # Accuracy report
    h, c, a = sess.run([hypothesis, predicted, accuracy], feed_dict={X: x_data, Y: y_data})
    print("\nHypothesis: ", h, "\nCorrect: ", c, "\nAccuracy: ", a)

그래프를 launch하는 부분에서는... tf.summary.merge_all()명령으로 변수를 잡아서 그걸 sess.run으로 train을 돌릴때 같이 돌려주면 됩니다. 그리고, tf.summary.FileWriter를 이용해서 log를 기록할 폴더를 지정해 주면 됩니다. 그리고 중간중간 accuracy를 print하는 것 보다 [바로가기]에서 이야기한 TQDM을 사용해서 progress bar를 보게 해도 되지요^^ 위 블럭을 실행할때는...

저렇게 떠서... 남은 시간을 예상해볼 수도 있구요...

또 다 실행되고 나서는 저 코드를 실행하기 위해 들어간 시간등을 확인해 볼 수도 있지요^^ 아까 그래프를 실행할 때 사용한 FileWriter에서 지정한 폴더로 터미널을 이용해서 이동합니다.

그리고 tensorboard --logdir=./hello_tf_180115-1/이라고 입력하면 위에 나타나듯이 6006이라고 포트넘버가 나타납니다.

이제.. localhost:6006이라고 웹 브라우저에서 입력하면 이쁘게 잘 저 화면이 나타납니다.^^

전체 그래프의 구조도 확인할 수 있구요... tf.name_scope로 묶은 train, cost와 layer도 하나의 블럭처럼 이쁘게 보이네요.

layer를 열어보니, weight(2*1)와 bias와 함께 hypothesis가 표현되어 있음을 알 수 있습니다.

또한... weight와 bias의 히스토리를 히스토그램으로도 확인할 수 있습니다.

만약.. 한 폴더에 비교하고 싶은 결과를 저렇게 따로 저장해두고, 위 그림처럼 XOR폴더를 텐서보드에서 읽으면

다수의 결과를 동시에 비교해 볼 수 있습니다.

이런 기능을 사용할 수 있다는 것이 텐서플로우의 큰 장점인것 같습니다.^^

반응형