1, 빅데이터 시대의 인공지능 문동선 v2 from Dongsun Moon

'Deep Learning > 이론' 카테고리의 다른 글

Deep learning 발표자료 2015  (0) 2015.12.30
Posted by 21세기 유목민
0, 0

  TensorFlow computation graph는 강력하지만 조금 복잡해하다. 그래프 시각화는 이해와 디버깅에 도움이 될 것이다.

Visualization of a TensorFlow graph

  내가 만든 그래프를 보려면, 우선 로그 디렉토리를 지정하여 TensorBoard를 실행해야 한다. 자세한 방법은 다음 글을 참고 하면 된다. 

http://dsmoon.tistory.com/entry/TensorBoard-Visualizing-Learning


Name scoping and nodes

  TensorFlow 그래프들은 보통 수천개의 노드들을 갖기 때문에 한번에 쉽게 보기도 어렵고, 보통 그래프 툴로도 보기가 어렵다. 변수 이름들은 scope되고 시각화 작업이 이 정보를 이용해서 그래프의 노드들을 계층적으로 보여준다. 기본적으로는 최상위 계층이 보여진다. 아래와 같은 예제가 있다고 하자


import tensorflow as tf

with tf.name_scope('hidden') as scope:
    a = tf.constant(5, name = 'alpha')
    W = tf.Variable(tf.random_uniform([1, 2], -1.0, 1.0), name = 'weights')
    b = tf.Variable(tf.zeros([1]), name = 'biases')

  세노드는 scope로 인해 접두어가 붙어, hidden/alpha, hidden/wtight, hidden/biases 네이밍 된다.

  기본적으로 시각화에서 3개 노드는 hidden 레이블이 붙은 한 노드로 합쳐질 것이다. 추가적인 디테일들을 사라진다. 더블 클릭 하거나 오렌지색 "+" 부분을 클릭하여 노드를 확장할 수 있다. 그러면 alpha, weights, biases subnode들을 볼 수 있다.


Unexpanded name scopeExpanded name scope

기본적인 모습. 더블 클릭하거나 , "+" 부분을 클릭하여 확장 가능.

확장된 모습. 더블 클릭하거나 , "-" 부분을 클릭하여 원래 모습으로 작게 만들 수 

   노드들을 이름 스코프로 묶는 것은 보기 좋은 그래프를 만들기 위해 필수적이다. 이름 스코프 작업에 공을 들일 수록 더 좋은 시각화가 가능해질 것이다.

  위 그림은 시각화의 두가지 측면을 보여준다. TensorFlow 그래프는 두가지 종류의 연결을 가진다. 바로, 데이터 의존성과 제어 의존성이다. 데이터 의존성은 두 op 사이의 텐서의 흐름을 보여주고, 실선 화살표로 보여진다. 반면 제어 의존성은 점선으로 표시된다. 위 우측 그림을 보면 모두 실선으로 데이터 흐름을 보여주는데, CheckNumerics와 control_dependency 사이만 점선으로 표시되어 있다.

  레이아웃을 단순하게 하는 두번째 트릭이 있다. 대부분의 TensorFlow 그래프들은 연결이 매우 많은 노드를 몇개 갖는다. 예를 들어 많은 노드들이 초기화 스텝에서 제어 의존성을 갖는다. 초기화 노드들 사이의 모든 의존성들을 그리게 되면 매우 보기 힘들고 어수선한 그림이 될 것이다.

  불필요하게 지저분해지는 것을 줄이기 위해, high-degree 노드들은 우측의 남는 공간에 따로 그려진다. 선을 그리는 대신, 연결을 나타내는 작은 아이콘들을 그린다. 이렇게 부수적인 노드들을 별도로 분리하는 작업이 중요한 데이터를 훼손하진 않는다. 이러한 노드들은 대부분 기록과 관련이 있기 때문이다.

conv_1 is part of the main graphsave is extracted as auxiliary node

  conv_1 노드는 save 노드에 연결되어 있다. 오른쪽에 작게 save 노드가 표시되어 있다.

save 는 고차원 노드라서 오른쪽 여분 공간에 표시된다. conv_1과의 연결이 노드 왼쪽에 작게 표시된다. 간결성을 위해 처음 5개만 보여주고 12개는 축약되어 있음을 볼 수 있다.

  우측의 여분 공간이라고 하면 이해가 안 될 수도 있을 것 같아, 전체적인 그림을 아래 첨부한다. 그림 전제에 서로 연결된 노드들의 그래프가 보여지고 우측 상단에 고차원 노드들이 몇개 표시된 것을 볼 수 있다. 저 노드들의 연결이 모두 표시 되었다면, 중요한 정보들이 부가적인 정보에 묻혀서 보기 힘들어지고, 일부 노드만 따로 선택해서 보는 지루하고 힘든 작업을 매번 해야 했을 것이다.



  구조 단순화를 위한 마지막 트릭은 series collapsing이다. 노드의 이름이 끝에 숫자만 다르고 isomorphic한 것들은 단일 스택으로 보여준다. 매우 긴 시퀀스가 있다면 매우 많이 단순화를 해준다. 이 경우도 더블 클릭으로 확장해서 볼 수 있다.

Sequence of nodesExpanded sequence of nodes
축약된 모습

더블 클릭으로 확장된 모습

 마지막으로, 가독성을 위한 것이 하나 더 있는데, constant와 summary node들을 위한 특별한 아이콘들을 사용한다는 것이다. 아래 테이블을 참고하자.

SymbolMeaning
Name scopeHigh-level node representing a name scope. Double-click to expand a high-level node.
Sequence of unconnected nodesSequence of numbered nodes that are not connected to each other.
Sequence of connected nodesSequence of numbered nodes that are connected to each other.
Operation nodeAn individual operation node.
Constant nodeA constant.
Summary nodeA summary node.
Data flow edgeEdge showing the data flow between operations.
Control dependency edgeEdge showing the control dependency between operations.
Reference edgeA reference edge showing that the outgoing operation node can mutate the incoming tensor.

Interaction

  확대를 해볼수도 있고 패닝을 해볼 수도 있다. 이동하기 위해 클릭하고 드래그할 수 있고, 스크롤하여 확대도 할 수 있다. 더블클릭하거나 "+" 네임 스코프를 펼쳐볼 수 도 있다. 편의를 위해 우측 하단에 미니맵도 표시된다.

  열려진 노드를 닫기 위해서 다시 더블 클릭하거나 "-" 버튼을 클릭한다. 클릭을 한 번만 하면 노드가 선택된다. 선택된 노드는 어두운 색으로 바뀌고 아래와 같은 정보 카드가 표시된다. 여기에는 노드에 대한 자세한 정보와 이에 연결된 노드들이 표시된다.

Info card of a name scopeInfo card of operation node

conv2 네임 스콥에 관한 자세한 정보 카드.

입력과 출력별로 보여짐.

네임 스콥에 관한 속성 정보는 없음.

인포카드가 DecodeRaw 연산 노드에 대한 자세한 정보를 보여준다.

입력과 출력 정보와 속성 정보도 표시됨.

  노드를 선택하는 것은 고차원 노드들을 이해하는데 유용하다. 고차원 노드를 선택하면 이와 연결된 노드들도 선택된다. 어떠한 노느들이 저장되고, 안되고 있는지 확인을 쉽게할 수 있다.

  인포카드에서 노드 이름을 클릭하면 그것을 선택하는 것과 같다. 따라서 시점이 자동으로 해당 노드가 보이게 이동하게 된다.

  색인 위에 있는 컬러 메뉴를 통해 두가지 color scheme 중에 하나를 고를 수 있다. 기본 구조 뷰에서는 두 레벨 노드가 같은 구조를 가지고, 같은 색이 된다. 유일한 구조를 가진 노드는 회색이 된다. 다른 뷰에서는 어떤 디바이스가 어떤 노드를 실행했는지 보여준다. 네임 스콥은 실행된 비율에 따라 적절히 색칠된다.

Color by structureColor by device

Structure view

고유한 구조를 가진 것들은 회색.

conv1,2 는 같은 구조를 가지고 있어서 빨간 색.

Device view
보라색은 GPU, 녹색은 CPU에서 실행된 비율.


Reference

https://www.tensorflow.org/versions/master/how_tos/graph_viz/index.html





'Deep Learning > TensorFlow' 카테고리의 다른 글

TensorBoard: Graph Visualization  (0) 2015.12.19
TensorBoard: Visualizing Learning  (0) 2015.12.17
[TensorFlow tutorial] Convolutional Neural Networks  (0) 2015.12.17
TensorFlow 101 - part2  (0) 2015.12.14
TensorFlow 101 - part1  (0) 2015.12.11
TensorFlow Variables 사용법  (0) 2015.12.07
Posted by 21세기 유목민
0, 0

  텐서플로우에서 사용하는 거대한 딥뉴럴네트워크 계산들은 매우 복잡하고 혼란스러울 수도 있다. 이해와 디버깅, 최적화를 돕기 위해,  TensorBoard라는 시각화 툴이 있다. TensorBoard를 TensorFlow 그래프를 시각화하기 위해 사용할 수도 있고, 그래프 수행의 정량적인 메트릭들을 그려볼 수도 있다. TensorBoard를 세팅해서 띄우면 아래와 같은 모습이다.


데이터 직렬화하기


  TensorBoard는 TensorFlow 이벤트 파일을 읽음으로써 동작한다. 여기에는 TensorFlow를 실행하면서 발생된 요약 데이터가 담겨있다. 이어서 요약 데이터에 대한, TensorBoard의 일반적인 생명주기를 다룬다.

  우선, 요약 데이터를 수집하기 원하는 TensorFlow 그래프를 만들고, 요약 연산을 할 노드를 결정한다.

  예를 들어, MNIST를 위한 CNN을 학습한다고 하자. 시간에 따른 학습률과 목적함수의 변화를 기록하고 싶을 것이다. 데이터를 수집하기 위해 scalar_summary op을 학습률 노드, 손실 노드에 각각 추가하라. 그리고 scalar_summary 각각에  'learning rate'이나 'loss function' 같이 의미 있는 태그를 달아줘라.

  아마도 특정 레이어의 활성도, 그래디언트, 웨이트 등의 분포를 보고 싶을 수 있다. 그래디언트 출력이나 웨이트 변수 등에 각각 histogram_summary op을 붙여 이러하한 데이터를 수집할 수 있다.

  TensorFlow안의 연산들은 당신이 그들이나 그들의 출력에 종속적인 op을 실행(run)할 때까지 아무것도 하지 않는다. 그리고 우리가 만든 요약 노드들은 부가적인 것일뿐, 당신이 실행중인 어떠한 op도 그것들에 종속적이지 않다. 따라서, 요약을 만들려면 요약 노드 모두를 실행해야 한다. 그것들을 일일이 손으로 관리한다는 것은 피곤한 일이다. 따라서 이들을 모든 요약 데이터를 생산하는 단일 op으로 묶기 위해 tf.merge_all_summaries를 사용하자.

  그러면 이제 합쳐진 요약 op을 실행할 수 있다. 이 op은 당신의 모든 요약 데이터에 대한, 직렬화된 Summary protobuf 객체를 정해진 step에 만들어 낼 것이다. 마지막으로, 요약 데이터를 디스크에 저장하기 위해, 요약 protobuf를 tr.train.SummaryWriter에 넘겨주어야 한다.

  SummaryWriter 는 생성자에 logdir를 필요로 한다. 여기에서 logdir은 좀 중요한데, 모든 이벤트들을 기록할 디렉토리의 위치이기 때문이다. 게다가, SummaryWriter는 생성자에서 옵션으로 GraphDef를 받을 수도 있다. 만약 그렇다면, TensorBoard 는 그래프도 시각화 해줄 것이다.

  자 이제 당신의 그래프를 수정하고 SummaryWriter를 실행해보자. 원한다면, 모든 step마다 합쳐진 요약 op을 실행할 수도 있고, 상당한 양의 훈련 데이터를 기록할 수도 있다. 당신이 원하는 것보다도 많은 것이 있을 수도 있다. 대신 n 스탭마다 실행하는 것을 고려해보자.

  아래 코드 예제는 MNIST 튜토리얼을 조금 수정한 것이다. 요약 op 을 추가했고, 매 10스텝마다 수행한다. 만약 이를 실행하고  tensorboard --logdir=/tmp/mnist_logs 를 실행하면, 훈련동안의 웨이트와 정확도 같은 통계값들을 시각화해서 볼 수 있을 것이다. 아래 코드는 일부분이고 풀버젼은 따로 참고하길 바란다.


# Create the model
x = tf.placeholder("float", [None, 784], name="x-input")
W = tf.Variable(tf.zeros([784,10]), name="weights")
b = tf.Variable(tf.zeros([10], name="bias"))

# use a name scope to organize nodes in the graph visualizer
with tf.name_scope("Wx_b") as scope:
  y = tf.nn.softmax(tf.matmul(x,W) + b)

# Add summary ops to collect data
w_hist = tf.histogram_summary("weights", W)
b_hist = tf.histogram_summary("biases", b)
y_hist = tf.histogram_summary("y", y)

# Define loss and optimizer
y_ = tf.placeholder("float", [None,10], name="y-input")
# More name scopes will clean up the graph representation
with tf.name_scope("xent") as scope:
  cross_entropy = -tf.reduce_sum(y_*tf.log(y))
  ce_summ = tf.scalar_summary("cross entropy", cross_entropy)
with tf.name_scope("train") as scope:
  train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

with tf.name_scope("test") as scope:
  correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
  accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
  accuracy_summary = tf.scalar_summary("accuracy", accuracy)

# Merge all the summaries and write them out to /tmp/mnist_logs
merged = tf.merge_all_summaries()
writer = tf.train.SummaryWriter("/tmp/mnist_logs", sess.graph_def)
tf.initialize_all_variables().run()

# Train the model, and feed in test data and record summaries every 10 steps

for i in range(1000):
  if i % 10 == 0:  # Record summary data, and the accuracy
    feed = {x: mnist.test.images, y_: mnist.test.labels}
    result = sess.run([merged, accuracy], feed_dict=feed)
    summary_str = result[0]
    acc = result[1]
    writer.add_summary(summary_str, i)
    print("Accuracy at step %s: %s" % (i, acc))
  else:
    batch_xs, batch_ys = mnist.train.next_batch(100)
    feed = {x: batch_xs, y_: batch_ys}
    sess.run(train_step, feed_dict=feed)

print(accuracy.eval({x: mnist.test.images, y_: mnist.test.labels}))


  이제 TensorBoard를 이용해 데이터를 시각화할 준비가 다 되었다.

Launching TensorBoard


  TensorBoard를 다음과 같이 실행해보자.


$ python tensorflow/tensorboard/tensorboard.py --logdir=path/to/log-directory

  "logdir" 는 SummaryWriter가 데이터를 직렬화하여 저장한 디렉토리를 가리킨다. 만약 "logdir" 디렉토리가 별도로 실행한 직렬화 파일을 가진 서브디렉토리를 가진다면 TensorBoard는 그 역시도 시각화해준다. TensorBoard를 실행하면, 웹브라우져로 localhost:6006에 접속하여 화면을 볼 수 있다.


  만약 pip로 설치된 TensorFlow라면, tensorboard는 system path에 설치 되었을 것이고, 더 간단한 명령으로 실행 할 수도 있다.



$ tensorboard --logdir=/path/to/log-directory

  TensorBoard를 보면, 우측상단에 네비게이션 탭이 보일 것이다. 각 탭은 시각화 할 수 있는직렬화된 데이터들의 집합을 나타낸다. TensorBoard에서 보이는 로그에 탭과 관련된 데이터가 없다면, 해당 테이터를 직렬화하는 방법에 대한 메세지가 표시될 것이다.


Reference

https://www.tensorflow.org/versions/master/how_tos/summaries_and_tensorboard/index.html

'Deep Learning > TensorFlow' 카테고리의 다른 글

TensorBoard: Graph Visualization  (0) 2015.12.19
TensorBoard: Visualizing Learning  (0) 2015.12.17
[TensorFlow tutorial] Convolutional Neural Networks  (0) 2015.12.17
TensorFlow 101 - part2  (0) 2015.12.14
TensorFlow 101 - part1  (0) 2015.12.11
TensorFlow Variables 사용법  (0) 2015.12.07
Posted by 21세기 유목민
0, 0