|
| 1 | +# -*- coding: utf-8 -*- |
| 2 | +# 이미지 처리 분야에서 가장 유명한 신경망 모델인 CNN 을 이용하여 더 높은 인식률을 만들어봅니다. |
| 3 | + |
| 4 | +import tensorflow as tf |
| 5 | + |
| 6 | +from tensorflow.examples.tutorials.mnist import input_data |
| 7 | +mnist = input_data.read_data_sets("./mnist/data/", one_hot=True) |
| 8 | + |
| 9 | + |
| 10 | +######### |
| 11 | +# 신경망 모델 구성 |
| 12 | +###### |
| 13 | +# 기존 모델에서는 입력 값을 28x28 하나의 차원으로 구성하였으나, |
| 14 | +# CNN 모델을 사용하기 위해 2차원 평면과 특성치의 형태를 갖는 구조로 만듭니다. |
| 15 | +X = tf.placeholder(tf.float32, [None, 28, 28, 1]) |
| 16 | +Y = tf.placeholder(tf.float32, [None, 10]) |
| 17 | + |
| 18 | +# 각각의 변수와 레이어는 다음과 같은 형태로 구성됩니다. |
| 19 | +# W1 [3 3 1 32] -> [3 3]: 커널 크기, 1: 입력값 X 의 특성수, 32: 필터 갯수 |
| 20 | +# L1 Conv shape=(?, 28, 28, 32) |
| 21 | +# Pool ->(?, 14, 14, 32) |
| 22 | +W1 = tf.Variable(tf.random_normal([3, 3, 1, 32], stddev=0.01)) |
| 23 | +# tf.nn.conv2d 를 이용해 한칸씩 움직이는 컨볼루션 레이어를 쉽게 만들 수 있습니다. |
| 24 | +# padding='SAME' 은 커널 슬라이딩시 최외곽에서 한칸 밖으로 더 움직이는 옵션 |
| 25 | +L1 = tf.nn.relu(tf.nn.conv2d(X, W1, strides=[1, 1, 1, 1], padding='SAME')) |
| 26 | +# Pooling 역시 tf.nn.max_pool 을 이용하여 쉽게 구성할 수 있습니다. |
| 27 | +L1 = tf.nn.max_pool(L1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') |
| 28 | +L1 = tf.nn.dropout(L1, 0.8) |
| 29 | + |
| 30 | +# L2 Conv shape=(?, 14, 14, 64) |
| 31 | +# Pool ->(?, 7, 7, 64) |
| 32 | +# Reshape ->(?, 256) |
| 33 | +# W2 의 [3, 3, 32, 64] 에서 32 는 L1 에서 출력된 W1 의 마지막 차원, 필터의 크기 입니다. |
| 34 | +W2 = tf.Variable(tf.random_normal([3, 3, 32, 64], stddev=0.01)) |
| 35 | +L2 = tf.nn.relu(tf.nn.conv2d(L1, W2, strides=[1, 1, 1, 1], padding='SAME')) |
| 36 | +L2 = tf.nn.max_pool(L2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') |
| 37 | +# Full Connect 를 위해 차원을 줄입니다. |
| 38 | +# 직전의 Pool 사이즈인 (?, 7, 7, 64) 를 참고합니다. |
| 39 | +L2 = tf.reshape(L2, [-1, 7 * 7 * 64]) |
| 40 | +L2 = tf.nn.dropout(L2, 0.8) |
| 41 | + |
| 42 | +# FC 레이어: 입력값 7x7x64 -> 출력값 256 |
| 43 | +W3 = tf.Variable(tf.random_normal([7 * 7 * 64, 256], stddev=0.01)) |
| 44 | +L3 = tf.nn.relu(tf.matmul(L2, W3)) |
| 45 | +L3 = tf.nn.dropout(L3, 0.5) |
| 46 | + |
| 47 | +# 최종 출력값 L3 에서의 출력 256개를 입력값으로 받아서 0~9 레이블인 10개의 출력값을 만듭니다. |
| 48 | +W4 = tf.Variable(tf.random_normal([256, 10], stddev=0.01)) |
| 49 | +model = tf.matmul(L3, W4) |
| 50 | + |
| 51 | +cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(model, Y)) |
| 52 | +optimizer = tf.train.AdamOptimizer(0.001).minimize(cost) |
| 53 | +# 최적화 함수를 RMSPropOptimizer 로 바꿔서 결과를 확인해봅시다. |
| 54 | +# optimizer = tf.train.RMSPropOptimizer(0.001, 0.9).minimize(cost) |
| 55 | + |
| 56 | + |
| 57 | +######### |
| 58 | +# 신경망 모델 학습 |
| 59 | +###### |
| 60 | +init = tf.global_variables_initializer() |
| 61 | +sess = tf.Session() |
| 62 | +sess.run(init) |
| 63 | + |
| 64 | +batch_size = 100 |
| 65 | +total_batch = int(mnist.train.num_examples/batch_size) |
| 66 | + |
| 67 | +for epoch in range(15): |
| 68 | + total_cost = 0 |
| 69 | + |
| 70 | + for i in range(total_batch): |
| 71 | + batch_xs, batch_ys = mnist.train.next_batch(batch_size) |
| 72 | + # 이미지 데이터를 CNN 모델을 위한 자료형태인 [28 28 1] 의 형태로 재구성합니다. |
| 73 | + batch_xs = batch_xs.reshape(-1, 28, 28, 1) |
| 74 | + _, cost_val = sess.run([optimizer, cost], feed_dict={X: batch_xs, Y: batch_ys}) |
| 75 | + total_cost += cost_val |
| 76 | + |
| 77 | + print 'Epoch:', '%04d' % (epoch + 1), \ |
| 78 | + 'Avg. cost =', '{:.3f}'.format(total_cost / total_batch) |
| 79 | + |
| 80 | +print '최적화 완료!' |
| 81 | + |
| 82 | + |
| 83 | +######### |
| 84 | +# 결과 확인 |
| 85 | +###### |
| 86 | +check_prediction = tf.equal(tf.argmax(model, 1), tf.argmax(Y, 1)) |
| 87 | +accuracy = tf.reduce_mean(tf.cast(check_prediction, tf.float32)) |
| 88 | +print '정확도:', sess.run(accuracy, |
| 89 | + feed_dict={X: mnist.test.images.reshape(-1, 28, 28, 1), |
| 90 | + Y: mnist.test.labels}) |
0 commit comments