본문 바로가기
Tensorflow

18. Tensorflow 시작하기 - Convolutional Neural Networks (이미지 프로세싱)

by 대소니 2016. 11. 20.


이번에는 이미지를 인식하기 위해서 많이 사용되는 CNN 모델에 대해서 살펴보겠습니다.


Deep CNN 튜토리얼 링크는 다음과 같습니다

(https://www.tensorflow.org/versions/master/tutorials/deep_cnn/index.html#convolutional-neural-networks)

튜토리얼 문서에서 'tensorflow/models/image/cifar10' 로 되어 있는 링크에서 최신본의 전체 소스를 다운로드 할 수 있습니다.


다운로드 받으신 파일들중에서 'cifar10_train.py' 파일을 실행하면 기초 데이터를 다운받고 학습을 진행하게 됩니다. 이번에는 많은 이미지들을 학습해야 하기 때문에 서버 사양에 따라 빠르면 4~5시간에서 많게는 몇일이 걸릴수도 있으니 참고하셔서 돌려보시길 바랍니다.


튜토리얼 문서에서 사용되는 서버 사양은 Tesla K40c 그래픽카드(약 1,500만원) GPU로 돌려서 아래와 같이 각 batch 마다 약 0.3초 정도의 속도가 나오는가 봅니다. 이 정도 성능으로 돌리면 약 4~5시간이면 학습이 완료가 된다고 합니다.


2015-11-04 11:45:49.133065: step 10, loss = 4.66 (533.8 examples/sec; 0.240 sec/batch)

2015-11-04 11:45:51.397710: step 20, loss = 4.64 (597.4 examples/sec; 0.214 sec/batch)

2015-11-04 11:45:54.446850: step 30, loss = 4.62 (391.0 examples/sec; 0.327 sec/batch)

2015-11-04 11:45:57.152676: step 40, loss = 4.61 (430.2 examples/sec; 0.298 sec/batch)

2015-11-04 11:46:00.437717: step 50, loss = 4.59 (406.4 examples/sec; 0.315 sec/batch)

...


그에 반에 저는 무료 AWS에서 기본 CPU로 돌려보니 아래와 같이 각 batch 마다 약 1.6초 정도의 속도로 5배이상 차이가 납니다. 더욱이 우울한 것은 기본 서버 메모리가 full이 되는 시점이 되면 12초로 더 심각해진다는 것입니다. 쿠쿠

역시 고사양의 연산장치와 충분한 크기의 메모리, 그로인한 많은 자본금이 필요합니다.^^


2016-11-20 14:38:15.294355: step 10, loss = 4.64 (80.0 examples/sec; 1.600 sec/batch)

2016-11-20 14:38:31.421066: step 20, loss = 4.39 (79.6 examples/sec; 1.609 sec/batch)

2016-11-20 14:38:47.497850: step 30, loss = 4.39 (79.8 examples/sec; 1.604 sec/batch)

2016-11-20 14:39:03.651877: step 40, loss = 4.31 (80.0 examples/sec; 1.600 sec/batch)

...

2016-11-20 18:28:40.319457: step 6130, loss = 0.86 (9.9 examples/sec; 12.952 sec/batch)

2016-11-20 18:30:49.119361: step 6140, loss = 0.88 (9.9 examples/sec; 12.916 sec/batch)



CIFAR-10


이번에 사용하게 될 데이터는 CIFAR-10 입니다.

이 데이터셋은 RGB 칼라로 되어 있는 32x32 사이즈의 이미지들입니다. 10개의 classes로 구성이 되어 있고 각각의 class는 6000개의 이미지로 구성되어 있어 총 60,000개의 이미지로 이루어진 데이터셋입니다.

(CIFAR-10 : http://www.cs.toronto.edu/~kriz/cifar.html)


이 데이터셋을 학습하여 어떤 이미지가 주어지면 10개의 분류중에 하나로 예측하는 알고리즘을 CNN 모델로 만들게 되겠습니다. 이 소스상에는 기본적인 모델 구현외에도 많은 다른 아이디어들이 포함이 되어 있어서 이미지 관련 시스템을 만들때에 참고하면 좋은 내용들이 많이 있습니다. (튜토리얼 문서에 Highlights 내용을 참고)



Train


전체적인 흐름을 알수 있게 아주 잘 만들어진 소스를 살펴보겠습니다.

'cifar10_train.py' 파일의 train() 함수를 보면,

가장 먼저 디폴트 Graph를 지정해주고 step을 사용하기 위한 global_step을 정의해줍니다.



def train():
"""Train CIFAR-10 for a number of steps."""
with tf.Graph().as_default():
global_step = tf.Variable(0, trainable=False)


그리고 'cifar10.py' 파일에 정의가 되어 있는 Training을 위한 이미지 데이터들을 불러옵니다.

'cifar10.py' 파일에는 CNN을 구성하기 위한 모델부터 loss등을 계산하기 위한 핵심 로직들이 함수로 구현이 되어 있습니다. 따라가보면 이미지 데이터셋을 로딩하는 것 뿐만아니라 이미지를 crop하고 flip하고 distort 하는 과정들이 포함 되어 있고 이러한 로직들은 그대로 재사용 할 수 있을만큼 잘 함수로 만들어 두었습니다.

이렇게 학습에 사용할 이미지와 label 정보들을 불러오게 됩니다.



# Get images and labels for CIFAR-10.
images, labels = cifar10.distorted_inputs()


그 다음으로는 핵심 두뇌 역활을 하게 되는 CNN 모델을 구성하는 inference() 함수를 실행합니다.

이 함수에서 구현하고 있는 모델은 총 5개의 layer로 되어 있으며, 2개의 max pooling Layer와 2개의 fully connected Layer와 1개의 softmax layer로 구성이 되어 있습니다. 그리고 relu, weight decay, lrn등의 아이디어들도 사용이 됩니다.


관련하여 자세한 내용을 보고 싶으시면 아래의 링크된 논문 내용을 참고해주세요

(http://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks)


이렇게 하여 모델이 구성이 됩니다.



# Build a Graph that computes the logits predictions from the
# inference model.
logits = cifar10.inference(images)


그리고 loss 를 계산합니다.

예측된 결과값과 실제 label과의 cross entropy 연산을 통해서 cost를 구하게 됩니다.



# Calculate loss.
loss = cifar10.loss(logits, labels)


그리고 train_op을 생성합니다.

데이터들을 학습하기 위해서 learning rate을 조정해주고, gradient descent 알고리즘을 사용하며, moving averages 를 통해서 보다 빠른 학습을 위한 내용들이 구현이 되어 있습니다.



# Build a Graph that trains the model with one batch of examples and
# updates the model parameters.
train_op = cifar10.train(loss, global_step)


이제 중요한 핵심 로직들이 모두 만들어졌습니다.

이어지는 내용들은 세션을 생성하고 변수들을 초기화하고 데이터들을 파일저장하기 위한 기본적인 내용들을 해줍니다.



# Create a saver.
saver = tf.train.Saver(tf.all_variables())

# Build the summary operation based on the TF collection of Summaries.
summary_op = tf.merge_all_summaries()

# Build an initialization operation to run below.
init = tf.initialize_all_variables()

# Start running operations on the Graph.
sess = tf.Session(config=tf.ConfigProto(
log_device_placement=FLAGS.log_device_placement))
sess.run(init)

# Start the queue runners.
tf.train.start_queue_runners(sess=sess)

summary_writer = tf.train.SummaryWriter(FLAGS.train_dir, sess.graph)


그리고 본격적인 실제 학습을 실행하는 내용과 로깅과 모니터링을 위한 내용들이 이어집니다.

각 10 step 마다 loss와 속도 체크를 위한 내용들을 출력해줍니다.

각 100 step 마다는 학습되는 데이터들 파일로 저장해주며,

각 1000 step 마다는 checkpoint 를 기록해 저장해줍니다.



for step in xrange(FLAGS.max_steps):
start_time = time.time()
_, loss_value = sess.run([train_op, loss])
duration = time.time() - start_time

assert not np.isnan(loss_value), 'Model diverged with loss = NaN'

if step % 10 == 0:
num_examples_per_step = FLAGS.batch_size
examples_per_sec = num_examples_per_step / duration
sec_per_batch = float(duration)

format_str = ('%s: step %d, loss = %.2f (%.1f examples/sec; %.3f '
'sec/batch)')
print (format_str % (datetime.now(), step, loss_value,
examples_per_sec, sec_per_batch))

if step % 100 == 0:
summary_str = sess.run(summary_op)
summary_writer.add_summary(summary_str, step)

# Save the model checkpoint periodically.
if step % 1000 == 0 or (step + 1) == FLAGS.max_steps:
checkpoint_path = os.path.join(FLAGS.train_dir, 'model.ckpt')
saver.save(sess, checkpoint_path, global_step=step)


이렇게 하여 간단하게 소스들을 살펴보았습니다.



중간 결과


저는 한 5시간 정도 실행을 해보고 텐서보드에서 보니 튜토리얼에서 보여지는 그래프는 볼 수가 없네요. 아직 절반도 학습이 되지 않은 상태로만 나타납니다. 후후

튜토리얼상의 그래프로도 알 수 있듯이 loss가 1인 구간에서 크게 진전이 없게 나타나는 것만 볼 수 있었습니다.




댓글