MNIST 데이터셋을 신경망으로 학습시키며 딥러닝에 대한 맛을 보자.
인공지능에 관심이 있는 분이라면 MNIST를 처음 듣는 사람은 없을 것이다. 하지만 인공지능 분야에 첫걸음을 때는 사람을 위해 간략히 MNIST에 대해 설명하고 넘어가도록 하자.
MNIST는 손으로 쓴 숫자들의 이미지를 모아놓은 데이터 셋으로 0~9까지의 수를 28 * 28픽셀 크기의 이미지로 구성해 놓은 것이다.
MNIST 학습은 머신러닝을 공부하는 사람이라면 누구가 거쳐 가는 프로그래밍에 Hello World라고도 불리운다.
지금부터 텐서플로에 내장된 MNIST 데이터를 기반으로 학습하는 과정을 살펴보자.
1. 데이터 가져오기
가장 먼저 텐서플로를 임포트하고 텐서플로에 대장된 tensorflow.example.tutorials.mnist.input_data 모듈을 임포트 한다.
import tensorflow as tf
form tensorflow.examples.turorials.mnist import input_data
mnist = input_data.read_data_sets("./mnist/data/", one_hot = True)
마지막 줄을 보면 MNIST 데이터를 내려받고 레이블을 원 - 핫 인코딩 방식으로 읽어 드린다.
이 세줄로 MNIST 데이터셋을 사용하기 위한 준비가 끝났다.
데이터 정제 작업은 생각보다 쉽지 않다. 이와 같이 우리의 학습을 위해 힘써주신 텐서플로님에게 다시한번 감사의 인사를 올린다.
2. 신경망 모델 구성
-이제 신경망 모델을 만들어 보자.
MNIST 이미지는 28 * 28 픽셀로 이뤄져 있다. 이것은 784개의 특징으로 이뤄져 있다고 말할 수 있다. 그리고 레이블은 0~9이므로 10가지로 분류하면된다.
이것을 입력과 출력 변수 X,Y로 정의하면 아래와 같이 할 수 있다.
X = tf.placeholder(tf.float32, [None, 784])
Y = tf.placeholder(tf.float32, [None, 10])
위 None으로 정의되어 있는 첫번째 차원은 한번에 학습 시킬 이미지의 개수를 지정하는 값이 들어가는 부분이다.
즉, 이 부분은 배치 크기를 지정하는 자리이다.
None은 n개로 특정한 수를 정의하지 않고 사용자가 입력한 갯수대로 받겠다는 의미이다.
이와 같이 정의하면 한 번에 학습할 개수를 계속 변형하면서 사용할 수 있다.
*미니배치(minibatch)란?
이미지를 하나씩 학습하는 것보다 여러개를 한번에 학습 시키는 것이 효율적이다.
하지만 그만큼 많은 메모리와 높은 컴퓨팅 능력이 필요하다.
그러므로 무식하게 한번에 모든 학습 데이터를 학습 시키거나 비효율적으로 하나씩 학습시키기 보다는 적당한 크기로 잘라서 학습을 시키는 것이 좋으며 이것을 미니 배치라 한다.
-이제 2개의 은닉층이 다음과 같이 구성된 신경망을 만들어 보자.
784(입력, 특징 개수) -> 256 (1 은닉층 뉴런 개수) -> 256(2 은닉층 뉴런 개수) -> 10 (결과값)
이와 같은 신경망을 코드로 구성하면 아래와 같다.
W1 = tf.Variable(tf.random_normal([784, 256], stdev=0.01))
L1 = tf.nn.relu(tf.matmul(X, W1))
W2 = tf.Variable(tf.random_normal([256,256], stdev=0.01))
L2 = tf.nn.relu(tf.matmul(L2, W2))
W3 = tf.Variable(tf.random_normal([256,10], stddev=0.01))
model = tf.matmul(L2, W3)
위 내용은 편향이 제외된 가중치에 대한 내용만 담고 있다.
위 코드에 tf.random_normal([256,10], stdev=0.01)의 내용은 표준편차가 0.01인 정규 분포를 가지는 임의의 값으로 뉴런을 초기화 한다는 의미이다.
마지막 라인을 보면 행렬곱을 하기 위해 matmul 함수를 이용하였으며 행렬곱을 통해 각 계층으로 들어오는 입력값에 각각의 가중치를 곱한다.
활성화 함수로는 relu를 사용한 것을 확인 할 수 있다.
마지막 W3을 보면 출력값을 10으로 정의 한 것을 볼 수 있다.
그리고 출력층에는 보통 활성화 함수를 사용하지 않는다.
- 각 이미지에 대한 손실값과 미니배치의 평균 손실값을 구하고 손실값을 최소화하는 최적화를 수행하는 부분을 살펴보자.
이미지에 대한 손실값은 실제값과 예측값의 차이를 말한다. 이것을 구하기 위해서는 tf.nn.softmax_cross_entropy_with_logits 함수를 사용하면 된다.
미니 배치의 평균 손실값을 구하기 위해서는 tf.reduce_mean함수를 사용하면 된다.
이 손실값을 최소화하는 최적화를 수행하는 것은 tf.train.AdamOptimizer함수를 사용하면 된다.
위 내용을 코드로 살펴보면 아래와 같다.
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=model, labels = Y))
optimizer = tf.train.AdamOptimizer(0.001).minimize(cost)
3. 앞에서 정의된 신경망 모델을 초기화 및 학습 진행할 세션을 시작.
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
4. 학습을 실제로 진행하는 코드 알아보기.
batch_size = 100
total_batch = int(mnist.train.num_examples / batch_size)
앞서 말한바와 같이 MNIST는 데이터가 수만개로 매우 크므로 미니 배치를 이용하는 것이며 미니 배치의 크기를 100으로 설정한 것이다.
total_batch는 전체 데이터에 batch_size를 나누어 총 몇개의 미니 배치가 있는지를 의미한다.
그리고 MNIST 데이터 전체를 학습하는 일은 15회 반복하도록 하자.
그리고 이어서 미니배치의 총 개수만큼 반복하여 학습한다.
• Epoch이란? 학습 데이터 전체를 한 바퀴 도는 것을 Epoch이라고 함. 위 내용은 15 Epoch을 하도록 함을 뜻함.
for epoch in range(15):
total_cost = 0
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
_, cost_val = sess.run([optimizer, cost], feed_dict={X: batch_xs, Y: batch_ys})
위 내용을 보면 mnist.train.next_batch함수를 이용해 batch_size만큼 학습할 데이터를 가져오는 것을 볼 수 있다.
이어서 sess.run을 이용하여 최적화 시키고 손실값을 가져와서 저장한다.
이 때 fedd_dict 매개 변수에 입력값 X와 예측을 평가할 실제 레이블값 Y에 사용할 데이터를 넣어준다.
그리고 손실값을 저장한 다음, 한 Epoch의 학습이 끝나면 학습한 평균 손실값을 출력한다.
total_cost += cost_val
print('Epoch:', '%04d' % (epoch + 1), 'Avg. cost=', '{:3f}'.format(total_cost / total_batch))
여기까지가 전체 학습 코드에 대한 내용이다.
아주 간결하다는 것을 느낄 수 있을 것이다.
5. 학습이 잘되었는지 알아보자.
is_correct = tf.equal(tf.argmax(model, 1), tf.argmax(Y,1))
위 내용은 예측 결과인 model의 값과 실제 레이블인 Y의 값을 비교하는 것이다.
이와 같이 구해진 is_correct를 0 or 1로 변환하고 변환한 값들의 평균을 내면 바로 정확도가 된다.
accuracy = tf.reduce_mean(tf.cast(is_correct, tf.float32))
print('accuracy : ", sess.run(accuracy, feed_dict = {X : mnist.test.images, Y: mnist.test.labels}) )
[출처 : 골빈해커의 3분 딥러닝 텐서플로우 맛]
'인공지능 > Tensorflow' 카테고리의 다른 글
[Tensorflow] TF-Slim 알아보자 (0) | 2018.11.29 |
---|---|
[Tensorflow]TFRecord 파일 생성 방법(텐서플로우 데이타 포맷) (0) | 2018.11.29 |
[Tensorflow] 텐서보드 사용하기 (0) | 2018.09.11 |
[Tensorflow] 학습 모델 저장하고 재사용하기 (0) | 2018.09.10 |