[Python] Convolutional Neural Network – MNIST 예재

MNIST데이터 CNN

데이터 준비

  • 28*28픽셀의 이미지, 그레이 스케일로된 이미지
  • 각 이미지는 0~9까지의 숫자로 총 10개 라벨값이 있음
In [1]:
# 데이터 준비
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
import numpy as np
  
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
trX, trY, teX, teY = mnist.train.images, mnist.train.labels, mnist.test.images, mnist.test.labels
trX = trX.reshape(-1, 28, 28, 1)  # 28x28x1 input img
teX = teX.reshape(-1, 28, 28, 1)  # 28x28x1 input img
Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz

플레이스 홀더, 가중치 변수 생성

In [2]:
# 데이터 플레이스홀더 생성  
X = tf.placeholder("float", [None, 28, 28, 1])
Y = tf.placeholder("float", [None, 10])

# 컨볼루션레이어 가중치, 바이어스
w = tf.Variable(tf.random_normal([3,3,1,32], stddev=0.01))    # 컨볼루션 필터사이즈 3*3크기 필터로 32개 컨볼루션 레이어만들기
w2 = tf.Variable(tf.random_normal([3,3,32,64], stddev=0.01))  # 컨볼루션 필터사이즈 3*3크기, 32개 필터로 64개 컨볼루션 레이어만들기
w3 = tf.Variable(tf.random_normal([3,3,64,128], stddev=0.01)) # 컨볼루션 필터사이즈 3*3크기, 64개 필터로 128개 컨볼루션 레이어만들기

# 풀리 커넥티드레이어 생성을 위한 가중치
w4 = tf.Variable(tf.random_normal([128*4*4, 625], stddev=0.01)) # 128*4*4 인풋, 625개 아웃풋
w_o = tf.Variable(tf.random_normal([625, 10], stddev=0.01))     # 625개 인풋, 10개 아웃풋(라벨)

# 드랍아웃 파라미터 플레이스 홀더 
p_keep_conv = tf.placeholder("float")
p_keep_hidden = tf.placeholder("float")

모델 만들기

  • 컨볼루션-렐루-맥스풀링-드랍아웃-풀리커넥티드
In [3]:
# 컨볼루션 모델 생성
l1a = tf.nn.relu(tf.nn.conv2d(X, w, [1,1,1,1], 'SAME'))     # 28*28 컨볼루션에 relu 활성화함수 적용 / [N,28,28,32]
l1 = tf.nn.max_pool(l1a, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')  # 2*2사이즈 맥스풀링 적용 / 아웃풋 [N,14,14,32]
l1 = tf.nn.dropout(l1, p_keep_conv)

l2a = tf.nn.relu(tf.nn.conv2d(l1, w2, [1,1,1,1], 'SAME'))   # relu 활성화함수 적용 / [N,14,14, 64]
l2 = tf.nn.max_pool(l2a, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')  # 2*2사이즈 맥스풀링 적용  / [N, 7, 7, 64]
l2 = tf.nn.dropout(l2, p_keep_conv)

l3a = tf.nn.relu(tf.nn.conv2d(l2, w3, [1,1,1,1], 'SAME'))   # relu 활성화함수 적용 / [N, 7, 7, 128]
l3 = tf.nn.max_pool(l3a, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')  # 2*2사이즈 맥스풀링 적용 / [N, 4, 4, 128]

l3 = tf.reshape(l3, [-1, w4.get_shape().as_list()[0]]) #풀리커넥티드 인풋 형태로 바꿈
l3 = tf.nn.dropout(l3, p_keep_conv)

# 풀리 커넥티드 레이어
l4 = tf.nn.relu(tf.matmul(l3, w4))
l4 = tf.nn.dropout(l4, p_keep_conv)

pyx = tf.matmul(l4, w_o)

코스트함수, 최적화함수 정의

In [4]:
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pyx, Y))
train_op = tf.train.RMSPropOptimizer(0.001, 0.9).minimize(cost)
predict_op = tf.argmax(pyx, 1)

뉴럴넷 학습

In [5]:
with tf.Session() as sess:
    tf.initialize_all_variables().run()
    
    for i in range(100):
        for start, end in zip(range(0, len(trX), 128), range(128, len(trX), 128)): # 0~128개 / 128~256개 즉 128개씩 뽑아서 학습 
            sess.run(train_op, feed_dict={X:trX[start:end], Y:trY[start:end],
                                          p_keep_conv:0.8, p_keep_hidden:0.5})
        
        test_indices = np.arange(len(teX)) # 테스트 데이터 배치
        np.random.shuffle(test_indices)
        test_indices = test_indices[0:256]
        
        print i, np.mean(np.argmax(teY[test_indices], axis=1) == sess.run(predict_op, feed_dict={X: teX[test_indices],
                                                                                                 Y: teY[test_indices],
                                                                                                 p_keep_conv: 1.0,
                                                                                                 p_keep_hidden: 1.0}))
0 0.96484375
1 0.98046875
2 0.98828125
3 0.98828125
4 0.99609375
5 0.98828125
6 1.0
7 0.98828125
8 0.99609375
9 0.9921875
10 0.99609375
11 0.99609375
12 0.99609375
13 0.9921875
14 0.9921875
15 0.98046875
16 0.9921875
17 0.9921875
18 0.99609375
19 0.98828125
20 1.0
21 0.9921875
22 0.9921875
23 0.99609375
24 0.98828125
25 0.9921875
26 0.984375
27 0.99609375
28 0.9921875
29 0.9921875
30 0.984375
31 0.984375
32 0.9921875
33 1.0
34 0.99609375
35 0.99609375
36 0.99609375
37 1.0
38 0.9921875
39 0.984375
40 1.0
41 0.99609375
42 0.98828125
43 0.99609375
44 1.0
45 0.99609375
46 1.0
47 0.9921875
48 0.9921875
49 1.0
50 0.99609375
51 0.99609375
52 1.0
53 0.9921875
54 1.0
55 0.99609375
56 0.9921875
57 1.0
58 0.984375
59 0.9921875
60 1.0
61 1.0
62 0.99609375
63 0.984375
64 0.99609375
65 0.99609375
66 1.0
67 0.9921875
68 0.98828125
69 1.0
70 0.984375
71 1.0
72 1.0
73 0.99609375
74 0.98046875
75 1.0
76 0.9921875
77 0.98828125
78 0.9921875
79 0.9921875
80 0.9921875
81 1.0
82 0.99609375
83 0.99609375
84 0.99609375
85 1.0
86 0.9921875
87 0.98828125
88 1.0
89 1.0
90 0.98046875
91 0.98828125
92 0.9921875
93 0.9921875
94 0.984375
95 0.99609375
96 0.99609375
97 0.9921875
98 0.99609375
99 0.99609375

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다