Convolution Neural Network (CNN) 은 이미지 분석에 사용되는 인공신경망의 한 종류이므로 이를 MNIST 데이터 분류에도 사용할 수 있습니다.
먼저 다음과 같이 데이터를 불러오고, 파라미터를 설정합니다.
1 2 3 4 5 6 7 8 9 10 | import tensorflow as tf import random mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) # hyper parameters learning_rate = 0.001 training_epochs = 15 batch_size = 100 total_batch = int(mnist.train.num_examples / batch_size) | cs |
학습은 총 15 epoch 동안 진행되며, 효율적인 학습을 위해 batch_size = 100으로 설정합니다. (MNIST 데이터 갯수는 784)
이제 데이터를 담을 변수 X, Y를 설정합니다.
1 2 3 4 5 | X = tf.placeholder(tf.float32, [None, 784]) X_img = tf.reshape(X, [-1, 28, 28, 1]) # img 28x28x1 (black/white) Y = tf.placeholder(tf.float32, [None, 10]) | cs |
이미지 데이터 X는 X_img처럼 CNN에서 사용할 수 있는 형태로 reshape합니다. 이 shape는 모든 이미지가 28X28X1의 구조를 가진 데이터를 의미합니다.
Y의 출력데이터는 1~ 9 이므로 10이 됩니다.
이제 FCLayer (Full Connected Layer)에 연결하기 전에 Convolution Layer와 Pool Layer를 생성, 연결합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # L1 ImgIn shape=(?, 28, 28, 1) W1 = tf.Variable(tf.random_normal([3, 3, 1, 32], stddev=0.01)) # Conv -> (?, 28, 28, 32) # Pool -> (?, 14, 14, 32) L1 = tf.nn.conv2d(X_img, W1, strides=[1, 1, 1, 1], padding='SAME') L1 = tf.nn.relu(L1) L1 = tf.nn.max_pool(L1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') # L2 ImgIn shape=(?, 14, 14, 32) W2 = tf.Variable(tf.random_normal([3, 3, 32, 64], stddev=0.01)) # Conv ->(?, 14, 14, 64) # Pool ->(?, 7, 7, 64) L2 = tf.nn.conv2d(L1, W2, strides=[1, 1, 1, 1], padding='SAME') L2 = tf.nn.relu(L2) L2 = tf.nn.max_pool(L2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') L2_flat = tf.reshape(L2, [-1, 7 * 7 * 64]) # -> 3136 | cs |
W1은 3X3X1 의 구조를 가진 필터 32개를 의미합니다. stride는 1X1, padding은 SAME으로 설정되어있으므로 output 크기는 원본 크기와 같은 28X28이 됩니다.
이제 max_pool을 진행하는데, strides가 2X2 이고 padding이 same으로 설정되어있으므로 output 크기는 ksize(커널 사이즈)를 고려하면 공식에 의해 원본의 절반 크기인 14X14가 됩니다.
공식 : ((N - F) / strides) + 1
이제 완성된 레이어를 다음 레이어에 연결합니다. W2는 3X3X32 ( 32 = 이전 필터의 갯수 ) 구조의 필터를 64개 사용합니다.
따라서 최종적으로 완성된 output의 구조는 7X7X64입니다.
이제 완성된 레이어를 FCLayer에 연결하면 되는데, 그 전에 값을 이용할 수 있게끔 모든 데이터를 펼치는 작업이 필요합니다. 이것은 위와 같이 reshape 메소드를 이용해 쉽게 구현할 수 있습니다.
이제 FCLayer에 연결하기 위한 3136개의 데이터를 가진 N (-1) 개의 데이터셋이 완성되었습니다. 이것은 다음과 같이 FCLayer에 연결 및 학습할 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # Final FC 7x7x64 inputs -> 10 outputs W3 = tf.get_variable("W3", shape=[7 * 7 * 64, 10], initializer=tf.contrib.layers.xavier_initializer()) b = tf.Variable(tf.random_normal([10])) logits = tf.matmul(L2_flat, W3) + b # define cost/loss & optimizer cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits( logits=logits, labels=Y)) optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost) # initialize sess = tf.Session() sess.run(tf.global_variables_initializer()) # train my model print('Learning started. It takes sometime.') for epoch in range(training_epochs): avg_cost = 0 for i in range(total_batch): batch_xs, batch_ys = mnist.train.next_batch(batch_size) feed_dict = {X: batch_xs, Y: batch_ys} c, _ = sess.run([cost, optimizer], feed_dict=feed_dict) avg_cost += c / total_batch print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.9f}'.format(avg_cost)) | cs |
테스트 및 정확도 체크는 아래의 코드를 참고하세요.
1 2 3 4 5 | # Test model and check accuracy correct_prediction = tf.equal(tf.argmax(logits, 1), tf.argmax(Y, 1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) print('Accuracy:', sess.run(accuracy, feed_dict={ X: mnist.test.images, Y: mnist.test.labels})) | cs |
전체 소스코드는 여기에서 볼 수 있습니다.
'파이썬 > 머신러닝' 카테고리의 다른 글
[#E20] Recurrent Neural Network (RNN - PART 2/3) (0) | 2018.12.18 |
---|---|
[#E19] Recurrent Neural Network (RNN - PART 1/3) (0) | 2018.12.16 |
[#E17] Convolution Neural Network (CNN - 실전편) (0) | 2018.12.14 |
[#E16] Convolution Neural Network (CNN - 준비편) (0) | 2018.12.14 |
[#E15] MNIST 데이터란? (0) | 2018.12.14 |