학습목표:
합성곱 신경망(Convolutional Neural Network)와 이와 관련된 구성 요소 및 메서드를 소개
1. 합성곱 신경망에 대한 소개
https://libertegrace.tistory.com/entry/1-Basic-CNN
2. MNIST 분류기를 통해 배워보는 tensorflow 로 CNN구현하기 - 헬퍼함수 정의 (layers.py로 모듈화 할 수 있다.)
1) Convolutional layer
tf.nn.conv2d(x, W, strides = , padding = )
-
x: input image 또는 네트워크를 따라 이전 합성곱 계층들에서 얻어진 아래층의 feature map 데이터 (각 계층의 출력)
x의 형태) [이미지의 개수, pixel width, pixel height, color channel]로, 예를 들어, [None, 28, 28, 1] 인 경우, 이미지의 개수는 모르고, 각각은 28x28이며, 색 채널은 1개(gray)임을 나타냅니다. -
W: filter로, 합성곱 필터를 나타내는 네트워크의 학습된 가중치가 매개변수화 된 것
W의 형태) [filter width, height, dimension, filtermap 개수] 로 예를 들어, [5, 5, 1, 32] 인 경우, filter의 크기는 5x5이고, 1channel data즉, 2차원 영역에 적용되며 32개의 feature map개수로 결과적으로 합성곱계층의 가중치 집합을 여러개 가질 수 있을 때 여기서는 32개의 feature map이 있다는 의미입니다. -
stride: input된 x위에서 공간적 이동을 제어하는 값입니다. 이는 CNN개념 설명에서 잘 나와있습니다.
-
padding: ‘SAME’으로 설정하면 연산 결과의 크기가 x의 크기와 같도록 테두리에 padding이 적용됩니다.
2) 합성곱 결과에 activation function을 적용하고 싶다면
def conv_layer(input, shape):
W = weigh_variable(shape)
b = bias_variagle(shape[3])
return tf.nn.relu(conv2d(input, W) + b)
이렇게 사용할 수 있습니다.
3) pooling
tf.nn.max_pool(x, ksize = , strides = , padding = )
-
max pooling은 각 영역에서 입력값의 최대값을 출력합니다.
-
ksize : pooling의 크기를 정의
4) dropout
tf.nn.dropout(layer, keep_prob = )
-
keep_prob: 각 단계에서 학습을 계속할 뉴런의 비율. 테스트 단계에서는 dropout을 적용하지 않아서 이 값이 1.0이 되어야 하는 등 값이 수정 가능해야 하므로 tf.placeholder를 사용해야 합니다.
5) weight_variable()
: 네트워크의 fully connected layer이나 conv layer의 가중치를 지정해주는 부분입니다. 일반적으로 표준편차가 0.1인 절단정규분포를 사용하여 무작위로 초기화합니다.
def weight_variable(shape):
initial = tf.truncated_normal(shape, stddev = 0.1)
return tf.Variable(initial)
6) bias_variable()
: 완전 연결 계층이나 합성곱 계층의 편향값을 정의합니다. 여기서는 모두 0.1로 초기화됩니다.
def bias_variable(shape):
initial = tf.constant(0.1, shape = shape)
return tf.Variable(initial)
7) fully connected layer
def full_layer(input, size):
in_size = int(input.get_shape()[1])
W = weight_variavle([in_size, size])
b = bias_variable([size])
return tf.matmul(input, W)+b
지금까지의 내용을 모아보면 다음과 같습니다.
def weight_variable():
initial = tf.truncated_normal(shape, stddev = 0.1)
return tf.Variable(initial)
def bias_variable():
initial = tf.constant(0.1, shape = shape)
return tf.Variable(initial)
def conv2d(x, W):
return tf.nn.conv2d(x, W, strides= [1, 1, 1, 1], padding = ‘SAME’)
def conv_layer(input, shape):
W = weigh_variable(shape)
b = bias_variagle(shape[3])
return tf.nn.relu(conv2d(input, W) + b)
def max_pool(x):
return tf.nn.max_pool(x, ksize = [1, 2, 2, 1]., strides = [1, 2, 2, 1], padding = ‘SAME’)
def full_layer(input, size):
in_size = int(input.get_shape()[1])
W = weight_variavle([in_size, size])
b = bias_variable([size])
return tf.matmul(input, W)+b
3. MNIST 분류기를 통해 배워보는 tensorflow 로 CNN구현하기 - 모델 구성(minist_cnn.py로 모듈화 할 수 있습니다.)
1) 먼저 이미지와 정답 레이블의 placeholder를 정의합니다.
x = tf.placeholder(tf.float32, shape = [None, 784])
y = tf.placeholder(tf.float32, shape = [None, 10])
2) input image 의 크기를 정해줍니다. (원래 크기를 넣어주거나, channel 추가하거나, reshape등을 할 수 있습니다. )
x_image = tf.reshape(x, [-1, 28, 28, 1])
3) 그리고 위에서 알아보았던 여러 메소드들을 조합하여 model architecture을 만듭니다.
conv1 = conv_layer(x_image, shape = [5, 5, 1, 32]) #input size = 28x28
conv1_pool = max_pool(conv1) #input size = 14x14
conv2 = conv_layer(x_image, shape = [5, 5, 32, 64]) #input size = 14x14
conv2_pool = max_pool(conv1) #input size = 7x7
4) fully connected layer에서는 더이상 공간적 측면을 고려할 필요가 없으므로 그 전에 이미지를 vectorization 즉, flatten해 줍니다.
conv2_flat = tf.reshape(conv2_pool, [-1, 7*7*65])
5) 그리고 fully connected layer을 적용시킵니다.
full_1 = tf.nn.relu(full_layer(con2_flat, 1024)]
6) dropout
keep_prob = tf.placeholder(tf.float32)
full1_drop = tf.nn.dropout(full_1, keep_prob = keep_prob)
7) 결과
y_conv = full_layer(full1_drop, 10)
8) train_accuracy
매 batch회의 학습이 진행 될 때마다 모델의 정확도를 출력하여 모델 성능을 중간중간 확인할 수 있습니다.
8) test_accuracy
최종적으로 test한 결과도 출력할 수 있습니다.
전체 코드는 다음과 같습니다.
x = tf.placeholder(tf.float32, shape = [None, 784])
y = tf.placeholder(tf.float32, shape = [None, 10])
x_image = tf.reshape(x, [-1, 28, 28, 1])
conv1 = conv_layer(x_image, shape = [5, 5, 1, 32]) #input size = 28x28
conv1_pool = max_pool(conv1) #input size = 14x14
conv2 = conv_layer(x_image, shape = [5, 5, 32, 64]) #input size = 14x14
conv2_pool = max_pool(conv1) #input size = 7x7
conv2_flat = tf.reshape(conv2_pool, [-1, 7*7*65])
full_1 = tf.nn.relu(full_layer(con2_flat, 1024)]
keep_prob = tf.placeholder(tf.float32)
full1_drop = tf.nn.dropout(full_1, keep_prob = keep_prob)
y_conv = full_layer(full1_drop, 10)
mnist = input_data.read_data_sets(DATA__DIR, one_hot = True)
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = y_conv, labels = y))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_prediction = tf.equal(tf. argmax(y_conv, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for i in range(STEPS):
batch = mnist.train.next_batch(50)
if i%100 == 0:
train_accuracy = sess.run(accuracy, feed_dict = {x:batch[0], y:batch[1], keep_prob:1.0})
print(“step {}, training accuracy{}”. format(i, train_accuracy))
sess.run(train_step, feed_dict = {x:batch[0], y:batch[1], keep_prob:0.5})
X = mnist.test.images.reshape(10, 1000, 784)
Y = mnist.test.images.reshape(10, 1000, 10)
test_accuracy = np.mean([ssess.run(accuracy, feed_dict = {x:X[i], y:Y[i], keep_prob:1.0} for i in range(10)])
print(“test accuracy:{}.”.format(tesst_accuracy))
'Data Science > Tensorflow2.0, Pytorch' 카테고리의 다른 글
pytorch) 합성곱 신경망 (0) | 2020.06.18 |
---|---|
pytorch) 선형회귀분석 (0) | 2020.05.29 |
Learning Tensorflow) 1. 텐서플로의 기본 이해하기 (0) | 2020.04.05 |
10. Tensorflow2.0 Evaluating & Predicting (0) | 2020.03.27 |
8. Tensorflow2.0 Optimization & Training (Expert) (0) | 2020.03.27 |