mnist 레이어 크기에 따른 테스트

동일한 레이어 갯수에서 레이어에 포함된 노드의 갯수가 어느 정도의 영향을 줄까?

레이어 갯수가 늘어나면 성능 향상이 되는 것처럼 최종 출력까지의 과정에서 레이어 크기에 따라서 성능이 달라질 거라고 생각했다. 결과를 보면 놀랍게도 별 차이가 없다.

그럼에도 불구하고 여전히 달라져야 한다고 생각했다. 레이어가 너무 작아서 그런 것이 아닐까? 밑에 레이어를 늘린 코드를 추가했다. 결과는 차이 없었다.

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

def layerTest(mnist, test_index, loop_count):

if test_index == 1: ww = [784, 512, 512, 10]
elif test_index == 2: ww = [784, 256, 256, 10]
else: ww = [784, 512, 256, 10]

bb = ww[1:]

x = tf.placeholder(tf.float32)
y = tf.placeholder(tf.float32)

# ----------------------------------------------- #

# mnist 기본 예제에서 3번째를 반복문 버전으로 수정한 코드.
# 굳이 반복문 안에 없어도 되기 때문에 바깥으로 뺐다.
r = x
for i in range(len(bb)):
row, col = ww[i], bb[i]

# 함수를 여러 번 호출하는 과정에서 변수 이름 충돌남. layer_count*10+i로 해결.
w = tf.get_variable(str(test_index*10+i), shape=[row, col], initializer=tf.contrib.layers.xavier_initializer())
b = tf.Variable(tf.zeros(col))
a = tf.add(tf.matmul(r, w), b)
r = a if i == len(bb) - 1 else tf.nn.relu(a)

activation = r
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=activation, labels=y))

learning_rate = 0.01
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)

sess = tf.Session()

# ----------------------------------------------- #

epoches, batch_size = 15, 100 # 15와 35 중에서 선택
for loop in range(loop_count):
# print('layer({}), loop({}) {}'.format(layer_count, loop, '-'*30))

sess.run(tf.global_variables_initializer())

for epoch in range(epoches):
avg_cost = 0
total_batch = mnist.train.num_examples // batch_size # 55,000 // 100 = 550

for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)

_, c = sess.run([optimizer, cost], feed_dict={x: batch_xs, y: batch_ys})
avg_cost += c / total_batch

# print('{:2} : {}'.format(epoch+1, avg_cost))

# -------------------------------- #

pred = tf.equal(tf.argmax(activation, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(pred, tf.float32))
acc = sess.run(accuracy, feed_dict={x: mnist.test.images, y: mnist.test.labels})

print('{} : accuracy {:.4f}, cost {:.4f}'.format(ww, acc, avg_cost))

sess.close()


mnist = input_data.read_data_sets('mnist', one_hot=True)

layerTest(mnist, test_index=1, loop_count=3)
layerTest(mnist, test_index=2, loop_count=3)
layerTest(mnist, test_index=3, loop_count=3)
# [출력 결과 : 첫 번째]
# [784, 512, 512, 10] : accuracy 0.9525, cost 0.1630
# [784, 512, 512, 10] : accuracy 0.9517, cost 0.1639
# [784, 512, 512, 10] : accuracy 0.9528, cost 0.1616
#
# [784, 256, 256, 10] : accuracy 0.9511, cost 0.1711
# [784, 256, 256, 10] : accuracy 0.9525, cost 0.1738
# [784, 256, 256, 10] : accuracy 0.9501, cost 0.1736
#
# [784, 512, 256, 10] : accuracy 0.9532, cost 0.1574
# [784, 512, 256, 10] : accuracy 0.9532, cost 0.1603
# [784, 512, 256, 10] : accuracy 0.9513, cost 0.1636

# [출력 결과 : 두 번째]
# [784, 512, 512, 10] : accuracy 0.9523, cost 0.1619
# [784, 512, 512, 10] : accuracy 0.9530, cost 0.1670
# [784, 512, 512, 10] : accuracy 0.9545, cost 0.1650
#
# [784, 256, 256, 10] : accuracy 0.9496, cost 0.1730
# [784, 256, 256, 10] : accuracy 0.9519, cost 0.1713
# [784, 256, 256, 10] : accuracy 0.9511, cost 0.1729
#
# [784, 512, 256, 10] : accuracy 0.9554, cost 0.1586
# [784, 512, 256, 10] : accuracy 0.9546, cost 0.1592
# [784, 512, 256, 10] : accuracy 0.9541, cost 0.1602

# [출력 결과 : 세 번째]
# [784, 512, 512, 10] : accuracy 0.9536, cost 0.1630
# [784, 512, 512, 10] : accuracy 0.9514, cost 0.1687
# [784, 512, 512, 10] : accuracy 0.9516, cost 0.1664
#
# [784, 256, 256, 10] : accuracy 0.9519, cost 0.1719
# [784, 256, 256, 10] : accuracy 0.9506, cost 0.1756
# [784, 256, 256, 10] : accuracy 0.9490, cost 0.1752
#
# [784, 512, 256, 10] : accuracy 0.9525, cost 0.1643
# [784, 512, 256, 10] : accuracy 0.9513, cost 0.1615
# [784, 512, 256, 10] : accuracy 0.9521, cost 0.1616


결과가 생각한 대로 나오지 않아서 다시 테스트했다. 그러나, 결과는 다르지 않았다. 레이어가 많아지면 수정할 수 있는 weight가 많아지기 때문에 성능이 올라가는 것처럼 보인다. 갯수를 규칙적으로 줄어들게 하는 것은 단순하게도 기분 문제일 수도 있어 보인다. 그래도 두 가지 방식에 있어 성능 차이가 없다면, 기분상 후자를 선택하는 것은 당연하겠다.

if   test_index == 1:   ww = [784, 512, 512, 512, 512, 10]
elif test_index == 2: ww = [784, 256, 256, 256, 256, 10]
elif test_index == 3: ww = [784, 640, 512, 256, 128, 10]
else: ww = [784, 512, 256, 128, 64, 10]

# ...

layerTest(mnist, test_index=1, loop_count=1)
layerTest(mnist, test_index=2, loop_count=1)
layerTest(mnist, test_index=3, loop_count=1)
layerTest(mnist, test_index=4, loop_count=1)
# [출력 결과 : 첫 번째]
# [784, 512, 512, 512, 512, 10] : accuracy 0.9660, cost 0.0990
# [784, 256, 256, 256, 256, 10] : accuracy 0.9652, cost 0.1123
# [784, 640, 512, 256, 128, 10] : accuracy 0.9677, cost 0.0929
# [784, 512, 256, 128, 64, 10] : accuracy 0.9646, cost 0.0969

# [출력 결과 : 두 번째]
# [784, 512, 512, 512, 512, 10] : accuracy 0.9666, cost 0.1014
# [784, 256, 256, 256, 256, 10] : accuracy 0.9630, cost 0.1100
# [784, 640, 512, 256, 128, 10] : accuracy 0.9686, cost 0.0902
# [784, 512, 256, 128, 64, 10] : accuracy 0.9672, cost 0.0910

# [출력 결과 : 세 번째]
# [784, 512, 512, 512, 512, 10] : accuracy 0.9653, cost 0.1028
# [784, 256, 256, 256, 256, 10] : accuracy 0.9609, cost 0.1136
# [784, 640, 512, 256, 128, 10] : accuracy 0.9684, cost 0.0931
# [784, 512, 256, 128, 64, 10] : accuracy 0.9658, cost 0.0970