콘볼루션층 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)
'인공지능 AI' 카테고리의 다른 글
[인공지능/AI] Hyperparameter Tuning (Optimization) 하이퍼파라미터 튜닝 (최적화) (0) | 2021.04.13 |
---|---|
[인공지능/AI] Cross Entropy 크로스 엔트로피 (0) | 2021.04.08 |
[인공지능/딥러닝/AI] 합성곱 신경망 CNN(Convolutional Neural Network) (0) | 2020.08.26 |
[인공지능/AI]텐서플로를 이용한 MNIST 딥러닝학습 (0) | 2020.08.26 |
Tensorflow(텐서플로우) 설치와 기초 (0) | 2020.08.23 |