공부 📖/Tensorflow 공부

TensorFlow 신경망 레이어 추가 Deep NN

아낌없이 주는 프로그래머 2019. 3. 18. 15:31
1. Deep NN
1.1 Summary
입력층(input layer)에는 각각의 입력 변수가 1:1로 매칭되는 뉴런(neuron)이 존재한다.
히든층(hidden layer)에는 입력층의 뉴런과 가중치(weight)의 결합으로 생성되는 뉴런이 존재하며, 히든층에서의 층의 개수에 따라 모형의 복잡도가 결정되고 히든층의 개수가 2개 이상이 되는 경우 deep neural network 또는 deep learning이라고 칭한다.
출력층에는 히든층에서의 뉴런과 가중치가 결합하여 생성되는 뉴런이 존재하며, 예측하고자 하는 종속변수의 형태에(numeric, binary or multinomial) 따라 출력층의 개수가 결정된다. 히든층과 출력층에 존재하는 뉴런은 이전 층에서의 입력값과 가중치를 합(summation)을 계산하는 기능과 뉴런의 가중합을 입력값으로 신호를 출력하는 활성화 함수(activation function)기능을 수행한다. 


1.2 Source Code
# 털과 날개가 있는지 없는지에 따라, 포유류인지 조류인지 분류하는 신경망 모델을 만들어봅니다.
# 신경망의 레이어를 여러개로 구성하여 말로만 듣던 딥러닝을 구성해 봅시다!
import tensorflow as tf
import numpy as np

# [털, 날개]
x_data = np.array(
    [[0, 0], [1, 0], [1, 1], [0, 0], [0, 0], [0, 1]])

# [기타, 포유류, 조류]
y_data = np.array([
    [1, 0, 0],  # 기타
    [0, 1, 0],  # 포유류
    [0, 0, 1],  # 조류
    [1, 0, 0],
    [1, 0, 0],
    [0, 0, 1]
])

#########
# 신경망 모델 구성
######
X = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)

# 첫번째 가중치의 차원은 [특성, 히든 레이어의 뉴런갯수] -> [2, 10] 으로 정합니다.
W1 = tf.Variable(tf.random_uniform([2, 10], -1., 1.))
# 두번째 가중치의 차원을 [첫번째 히든 레이어의 뉴런 갯수, 분류 갯수] -> [10, 3] 으로 정합니다.
W2 = tf.Variable(tf.random_uniform([10, 3], -1., 1.))

# 편향을 각각 각 레이어의 아웃풋 갯수로 설정합니다.
# b1 은 히든 레이어의 뉴런 갯수로, b2 는 최종 결과값 즉, 분류 갯수인 3으로 설정합니다.
b1 = tf.Variable(tf.zeros([10]))
b2 = tf.Variable(tf.zeros([3]))

# 신경망의 히든 레이어에 가중치 W1과 편향 b1을 적용합니다
L1 = tf.add(tf.matmul(X, W1), b1)
L1 = tf.nn.relu(L1)

# 최종적인 아웃풋을 계산합니다.
# 히든레이어에 두번째 가중치 W2와 편향 b2를 적용하여 3개의 출력값을 만들어냅니다.
model = tf.add(tf.matmul(L1, W2), b2)

# 텐서플로우에서 기본적으로 제공되는 크로스 엔트로피 함수를 이용해
# 복잡한 수식을 사용하지 않고도 최적화를 위한 비용 함수를 다음처럼 간단하게 적용할 수 있습니다.
cost = tf.reduce_mean(
    tf.nn.softmax_cross_entropy_with_logits_v2(labels=Y, logits=model))

optimizer = tf.train.AdamOptimizer(learning_rate=0.01)
train_op = optimizer.minimize(cost)


#########
# 신경망 모델 학습
######
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

for step in range(100):
    sess.run(train_op, feed_dict={X: x_data, Y: y_data})

    if (step + 1) % 10 == 0:
        print(step + 1, sess.run(cost, feed_dict={X: x_data, Y: y_data}))


#########
# 결과 확인
# 0: 기타 1: 포유류, 2: 조류
######
prediction = tf.argmax(model, 1)
target = tf.argmax(Y, 1)
print('예측값:', sess.run(prediction, feed_dict={X: x_data}))
print('실제값:', sess.run(target, feed_dict={Y: y_data}))

is_correct = tf.equal(prediction, target)
accuracy = tf.reduce_mean(tf.cast(is_correct, tf.float32))
print('정확도: %.2f' % sess.run(accuracy * 100, feed_dict={X: x_data, Y: y_data}))

1.4 Layer, 차원
전 내용과 다른 것은 Layer 수가 더 늘어났다는 것이다.
Layer가 많아진다는 것은 weight, bias가 늘어남을 뜻한다. 그렇기 때문에 Layer가 늘어나면 모델 정확도는 향상되지만 학습 속도는 느려진다. 그렇기 때문에 데이터의 양과 형태에 따라 Layer의 깊이를 다르게 설계해야한다.

이번 예제를 돌려보면 굉장히 정확도가 향상되었음을 알 수 있다.