인공지능 AI

[인공지능/딥러닝/AI] CNN 아키텍처기반의 MNIST 수행하기

콘볼루션층 3개와 완전연결층 1개로 구성된 CNN 아키텍처로 MNIST 검증을 해보도록 하겠습니다.

 

CNN 아키텍처 구현을 위한 텐서플로 API는 다음과 같습니다

 

콘볼루션(convolution) 연산 수행 API

tf.nn.conv2d(input, filter, strides, padding)

input: 입력 데이터이며 [batch, in_height, in_width, in_channels] 의 모양입니다.

예를 들어 100개의 배치로 묶은 28x28 크기의 흑백 이미지를 입력으로 넣은 경우,

[100, 28, 28, 1] 형태입니다.

 

filter: 콘볼루션 연산에 적용하는 필터이며 [filter_height, filter_width, in_channels, out_channels] 모양입니다.

필터크기가 3x3이며 입력채널개수가 1개, 적용필터가 32개라면

[3, 3, 1, 32] 입니다.

 

strides: 필터 이동 간격을 나타내는 파라미터입니다. 

예를 들어 [1, 1, 1, 1] 형태라면 필터를 왼쪽위부터 오른쪽아래까지 1칸씩 이동시킨다는 말입니다.

 

padding: 'SAME' 또는 'VALID' 값을 가지는 파라미터입니다.

padding='VALID' 로 초기화하면 패딩을 적용하지 않는 다는 의미이고

padding='SAME' 로 초기화하면 입력데이터와 출력데이터가 같도록 주변을 0으로 채운는 패딩을 수행한다는 의미입니다.

 

풀링(pooling)연산 수행 API

tf.nn.max_pool(value, ksize, strides, padding)

value: [batch, height, width, channels] 형태이며 콘볼루션층의 relu를 통과한 출력 결과를 나타냅니다.

 

ksize: [1, height, width, 1] 형태입니다. 

 

 

파이썬코드로 구현한 코드입니다.

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import numpy as np

mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

print("\ntrain image shape = ", np.shape(mnist.train.images))
print("train label shape = ", np.shape(mnist.train.labels))
print("test image shape = ", np.shape(mnist.test.images))
print("test label shape = ", np.shape(mnist.test.labels))

#setting CNN hyper parameter
learning_rate = 0.001
epochs = 30
batch_size = 100

#placeholder 정의
X = tf.placeholder(tf.float32, [None, 784])
T = tf.placeholder(tf.float32, [None, 10])

A1 = X_img = tf.reshape(X, [-1, 28, 28, 1])

#convolutional layer 1
#3x3 크기의 32개의 필터
F2 = tf.Variable(tf.random_normal([3, 3, 1, 32], stddev=0.01))
b2 = tf.Variable(tf.constant(0.1, shape=[32]))

#convolution 연산
C2 = tf.nn.conv2d(A1, F2, strides=[1,1,1,1], padding='SAME')

#relu 출력
Z2 = tf.nn.relu(C2+b2)

A2 = tf.nn.max_pool(Z2, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')

#convolutional layer 2
#3x3 크기의 64개의 필터
F3 = tf.Variable(tf.random_normal([3, 3, 32, 64], stddev=0.01))
b3 = tf.Variable(tf.constant(0.1, shape=[64]))

C3 = tf.nn.conv2d(A2,F3,strides=[1,1,1,1],padding='SAME')

#relu 출력
Z3 = tf.nn.relu(C3+b3)

A3 = tf.nn.max_pool(Z3, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')

#convolutional layer 3
#3x3 크기의 128개의 필터
F4 = tf.Variable(tf.random_normal([3,3,64,128], stddev=0.01))
b4 = tf.Variable(tf.constant(0.1, shape=[128]))

C4 = tf.nn.conv2d(A3, F4, strides=[1,1,1,1], padding='SAME')

Z4 = tf.nn.relu(C4+b4)

A4 = tf.nn.max_pool(Z4, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')


#완전연결층 연산정의
#4x4 크기의 128개의 activation map을 flatten
A4_flat = P4_flat = tf.reshape(A4, [-1, 128*4*4])

#출력층
W5 = tf.Variable(tf.random_normal([128*4*4, 10], stddev=0.01))
b5 = tf.Variable(tf.random_normal([10]))

#출력층 선형회귀 값, 즉 softmax들어가는 입력값
Z5 = logits = tf.matmul(A4_flat, W5)+b5

y = A5 = tf.nn.softmax(Z5)

#가중치, 바이어스 업데이트
cross_entropy = tf.nn.softmax_cross_entropy_with_logits_v2(logits=Z5, labels=T)

loss = tf.reduce_mean(cross_entropy)

optimizer = tf.train.AdamOptimizer(learning_rate)

train = optimizer.minimize(loss)

#정확도 검증 노드
predicted_val = tf.equal(tf.argmax(A5, 1), tf.argmax(T,1))
accuracy = tf.reduce_mean(tf.cast(predicted_val, dtype=tf.float32))

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    for i in range(epochs):
        total_batch = int(mnist.train.num_examples/ batch_size)

        for step in range(total_batch):
            batch_x, batch_t = mnist.train.next_batch(batch_size)

            loss_val, _ = sess.run([loss, train], feed_dict={X: batch_x, T: batch_t})

            if step % 100 == 0:
                print("step = ", step, ", loss_val = ", loss_val)

            #checking Accuracy
            test_x_data = mnist.test.images
            test_t_data = mnist.test.labels
            accuracy_val = sess.run(accuracy, feed_dict={X: test_x_data, T: test_t_data})

            print("\nAccuracy = ", accuracy_val)

결과