본문으로 바로가기

최근 저는 텐서플로우로 간단한 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폴더를 텐서보드에서 읽으면

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

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


댓글을 달아 주세요

  1. BlogIcon *저녁노을* 2018.02.09 07:29 신고

    잘 보고가요

    즐거운 주말되세요

  2. BlogIcon 핑구야 날자 2018.02.09 13:01 신고

    어려운 부분이 있지만 ㅋㅋ 잘 배우고 갑니다.

  3. BlogIcon Bliss :) 2018.02.09 13:31 신고

    제가 헬로우 월드에서 멈춰 있는 것은 이렇게 테스트해보고 경우의 수를 바꿔가는 노력이 없어서 그런 것 같아요. 몇 번 하다가 블로그 통째로 뱌뱌 할 뻔 해서 @.@ 시범 블로그에 해보면 되는데 자꾸 미루고 말이지요. 정보가 넘치는 시대에 무지에는 다 이유가 있는 듯합니다^^;; 물론 PinkWink님처럼 멋진 지식이 없다는 것도요ㅎㅎ 따스한 오후 되세요^^

  4. BlogIcon luvholic 2018.02.09 13:59 신고

    과정을 잘 모르지만 결과로 출력된 그래프를 보니 넘 신기해요~^^

  5. BlogIcon 『방쌤』 2018.02.09 15:16 신고

    오늘은 날씨가 정말 많이 풀렸네요~
    이 날씨만 쭉~~~유지가 되었으면 좋겠습니다.^^

  6. BlogIcon 휴식같은 친구 2018.02.09 15:35 신고

    프로그래밍의 재미에 푹 빠지신 것 같네요...ㅎㅎ
    하면 재밌을 것 같네요.
    공감하고 갑니다.

  7. BlogIcon 공수래공수거 2018.02.10 08:00 신고

    필요로 하시는분들에게 도움이 되겠습니다
    즐거운 주말 되시기 바랍니다^^

  8. BlogIcon peterjun 2018.02.11 01:12 신고

    제 눈이 까막눈인 것 같았어요. ㅠㅠ
    주말 행복하게 잘 보내세요~~~

  9. pitbulls 2018.02.13 15:44 신고

    안녕하세요. '파이썬 데이터 주무르기' 책으로 열심히 공부중인 독자 입니다. 먼저 너무 좋은 책 잘 써 주셔서 감사합니다. 그 간에 읽던 책들은 비전문가인 제가 입문서로 쓰기엔 너무 복잡하고 원론적인 이야기가 많아서 독파가 힘들었는데, 이 책은 예제 위주이고 일단 문법 모르더라도 데이터를 다루는 큰 그림을 이해할 수 있어서 재밌게 공부하고 있습니다. 감사드리는 마음에 인쇄 오류가 있어서 좀 알려드리려고 합니다. 벌써 알고 계실 수 있겠지만 그래도 혹시 놓치셨을까봐요. 83paeg In[7] 맨 마지막 'print'문이 들여쓰기가 잘못된거 같구요. 159page In[2]예제 내용에 'urlopen'이 빠진 것 같습니다. (제가 잘못 안 것이라도 너그러이...)
    다시 한번 좋은 책 써주셔서 감사드립니다. 꾸벅. 블로그에서도 좋은 내용 많이 배워가도록 하겠습니다. ^^