TensorFlow MNIST TensorBoard 예제

본 예제는 [7. TensorFlow MNIST 회귀 모델] 예제에 TensorBoard를 추가한 예제입니다.

예제를 실행하면 기본으로 제공되는 텐서보드 로그 디렉토리(/home/ncp/workspace/tensorboard)에 로그 파일이 생성됩니다. 웹 브라우저에서 [공인 IP 주소:18889]로 접속하면 TensorBoard에서 로그를 확인할 수 있습니다. 접속 환경 설정에 대한 자세한 방법은 "접속 환경 설정"을 참고하세요.

예제 코드는 TensorFlow 홈페이지에서 제공하는 TensorFlow 초보자를 위한 MNIST 기초 예제를 사용하였습니다. MNIST 데이터셋을 이용하여 Softmax 회귀 모델을 만들고 모델이 이미지 데이터를 가지고 어떤 숫자인지 예측하도록 하는 예제를 TensorBoard로 확인해 볼 것입니다.

각각의 개념이나 용어는 예제 코드를 이해하는 데 필요한 수준으로만 설명합니다. 정확한 이해를 위해서는 Machine Learning 및 Deep Learning에 대한 별도의 학습이 필요합니다.

MNIST 데이터셋 설명

MNIST 데이터셋은 아래와 같이 손으로 쓴 숫자 이미지를 벡터로 나타낸 images와 그 이미지가 의미하는 바를 나타내는 labels로 이루어져 있습니다. 아래 이미지의 라벨은 각각 5, 0, 4, 1이며, 라벨은 0~9까지 10개의 고유한 값으로 이루어져 있습니다.

MNIST 데이터셋은 또한 55,000개의 학습 데이터(mnist.train), 10,000개의 테스트 데이터(mnist.test), 5,000개의 검증용 데이터(mnist.validation)로 이루어져 있으며, 각각은 위에서 설명한 images와 labels로 다시 나뉘어 있습니다.

한 개의 이미지는 28x28(=784)픽셀로 이루어져 있기 때문에 이는 784차원의 벡터로 저장되어 있고 784차원에는 진하기의 정도에 따라 0~1 사이의 값이 들어 있습니다.

아래 코드를 통해 TensorFlow에서 제공하는 데이터를 다운로드하여 data 폴더에 저장합니다. 'one_hot=True' 옵션(one hot encoding)을 사용하여 label을 0~9 사이의 숫자값 하나로 정의하지 않고 10차원 벡터로 정의합니다. one hot encoding 데이터에 대해서는 아래에서 예제를 통해 다시 설명하도록 하겠습니다.

""" TensorFlow 패키지 import : 이후 tf로 사용하면 됩니다. """
import tensorflow as tf

""" 데이터 다운로드 및 로드
TensorFlow에서 제공하는 MNIST 데이터 파일 4개를 다운로드하여 data 폴더에 저장하고 읽어옵니다.
최초 실행 시에만 데이터를 다운로드하고, 두 번째 이후부터는 저장된 데이터를 읽어 오기만 하기 때문에 시간이 단축됩니다."""
from tensorflow.examples.tutorials.mnist import input_data
%time mnist = input_data.read_data_sets("data/", one_hot=True)  # %time을 통해 전체 실행 시간을 남길 수 있습니다.
Successfully downloaded train-images-idx3-ubyte.gz 9912422 bytes.
Extracting data/train-images-idx3-ubyte.gz
Successfully downloaded train-labels-idx1-ubyte.gz 28881 bytes.
Extracting data/train-labels-idx1-ubyte.gz
Successfully downloaded t10k-images-idx3-ubyte.gz 1648877 bytes.
Extracting data/t10k-images-idx3-ubyte.gz
Successfully downloaded t10k-labels-idx1-ubyte.gz 4542 bytes.
Extracting data/t10k-labels-idx1-ubyte.gz
CPU times: user 447 ms, sys: 454 ms, total: 901 ms
Wall time: 36.1 s

아래의 코드를 통해 데이터를 확인해 보면, images는 28x28픽셀을 나타내는 784차원 벡터로 되어 있고, labels는 'one_hot=True' 옵션(one hot encoding)을 사용하여 데이터를 읽었기 때문에 '7'이라는 라벨을 '[ 0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]'로 나타내고 있음을 확인할 수 있습니다(0은 [ 1. 0. 0. 0. 0. 0. 0. 0. 0. 0.], 1은 [ 0. 1. 0. 0. 0. 0. 0. 0. 0. 0.], 2는 [ 0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]로 나타냄).

# images/labels 데이터 구조 확인
print 'train 데이터셋(55,000건):', mnist.train.images.shape, mnist.train.labels.shape
print 'test 데이터셋(10,000건):', mnist.test.images.shape, mnist.test.labels.shape
print 'validation 데이터셋(5,000건):', mnist.validation.images.shape, mnist.validation.labels.shape

print '\n 데이터 샘플 확인(첫 번째 이미지 데이터 7)'
print 'label:', mnist.train.labels[0]
train 데이터셋(55,000건): (55000, 784) (55000, 10)
test 데이터셋(10,000건): (10000, 784) (10000, 10)
validation 데이터셋(5,000건): (5000, 784) (5000, 10)

 데이터 샘플 확인(첫 번째 이미지 데이터 7)
label: [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  1.]

회귀 모델

본 예제 코드는 TensorFlow에서 TensorFlow 초보자를 위해 제공하는 MNIST 기초 예제를 다루고 있습니다. 회귀 모델을 만들어 훈련시킨 후 label을 예측하고 모델의 정확도를 구해볼 것입니다.

Implementing the Regression

이미지와 정답 레이블을 담을 placeholder와 학습 결과인 가중치(weight)와 바이어스(bias)를 담을 Variable을 정의하고 Softmax Regression 모델을 정의합니다.

""" placeholder 정의 : 데이터가 들어 갈 곳
이미지와 정답 레이블용 2차원 tensor를 만든다.
None은 어떤 length도 가능함을 의미한다. """
# 이미지 데이터용 placeholder
with tf.name_scope("input") as scope:
    x = tf.placeholder(tf.float32, [None, 784])
# 정답 레이블용 placeholder
with tf.name_scope("y_") as scope:
    y_ = tf.placeholder(tf.float32, [None, 10])

""" Variable 정의 : 학습 결과가 저장될 가중치(weight)와 바이어스(bias) """
# 0으로 초기화 함
with tf.name_scope("weight") as scope:
    W = tf.Variable(tf.zeros([784, 10]))
with tf.name_scope("bias") as scope:
    b = tf.Variable(tf.zeros([10]))

""" 모델 정의 : Softmax Regression
10개의 값 중 가장 확률이 높은 것을 고르기 위해 Softmax 사용 """
# 모델 생성
with tf.name_scope("layer1") as scope:
    y = tf.nn.softmax(tf.matmul(x, W) + b)

w_hist = tf.summary.histogram("weight", W)
b_hist = tf.summary.histogram("bias", b)
y_hist = tf.summary.histogram("y", y)

Training

모델 훈련에 필요한 Loss 함수와 학습율(Learning Rate)을 정의하고 100개씩 샘플링하여 모델을 1000회 학습시킵니다. 샘플링 데이터 수를 늘리면 정확도가 올라갈 수는 있지만 학습 시간이 증가합니다. 랜덤 샘플링한 작은 배치로 학습하는 것을 Stochastic Training이라고 하며, 비용이 싸고 비슷한 결과를 낼 수 있어서 많이 사용됩니다.

""" 모델 훈련 """
# Loss 함수 정의
with tf.name_scope("cost") as scope:
    cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
    #tf.summary.scalar("cost",cross_entropy)
    cost_sum = tf.summary.scalar("cost",cross_entropy)
# learning rate을 0.5로 정의
with tf.name_scope("train") as scope:
    train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

# Merge all summaries into a single op
merged = tf.summary.merge_all()

# 세션 시작전에 모든 변수 초기화함
init = tf.global_variables_initializer()

sess = tf.Session()
sess.run(init)

# 기본으로 제공되는 텐서보드 로그 dir : /home/ncp/workspace/tensorboard
writer =tf.summary.FileWriter("/home/ncp/workspace/tensorboard", sess.graph)

# Training : 100개 단위로 샘플링하여 1000회 학습 진행
for i in range(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)  # 학습 데이터셋에서 무작위로 샘플링한 100개의 데이터로 구성된 'batch'를 가져옴
    summary, _ = sess.run([merged, train_step], feed_dict={x: batch_xs, y_: batch_ys})  # placeholder x, y_에 샘플링된 batch_xs, batch_ys를 공급함
    # write summary events to disk
    writer.add_summary(summary,i)

Evaluating Model

tf.argmax를 통해 가장 높은 확률의 label을 구하고 tf.equal을 통해 예측값(y)과 정답(y_)이 같은 것을 구하도록 correct_prediction과 accuracy tensor를 정의합니다.

모델을 평가하기 위해 test 데이터를 이용해서 정확도를 구합니다. 아래에서는 0.9163로 약 91%의 정확도가 나왔으며, 모델을 다시 훈련시킬 때마다 결과가 조금씩 달라질 수 있습니다.

""" 모델 평가 """
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

# 정확도
print sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels})

# 실행을 모두 마치면 Session을 닫음
writer.close()
sess.close()
0.9219

""에 대한 건이 검색되었습니다.

    ""에 대한 검색 결과가 없습니다.

    처리중...