2019. 6. 5. 21:00ㆍmachine learning
2019/06/04 - [machine learning] - [골빈해커의 3분 딥러닝] 04_01_classification
[골빈해커의 3분 딥러닝] 04_01_classification
골빈 해커님이 쓰신 3분 딥러닝을 코드 위주로 설명한 포스팅. 4장 01에서는 2개의 특징 데이터(털, 날개)를 가지고 [기타, 포유류, 조류]를 분류하는 모델을 설명하고 있으며, 전체 코드는 아래와 같다. step by..
yujuwon.tistory.com
이전 포스팅에 이어 이번에는 layer를 2개를 만들어서 (Deep) 모델을 구현한 예제를 살펴보자.
이전 포스팅과의 차이라면 layer 개수와 loss 함수를 tf에서 제공하는 함수를 썼다는 정도이다.
전체 코드는 아래와 같다.
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을 적용합니다 | |
# (1x2) * (2x10) + (1x10) | |
L1 = tf.add(tf.matmul(X, W1), b1) | |
L1 = tf.nn.relu(L1) | |
# 최종적인 아웃풋을 계산합니다. | |
# 히든레이어에 두번째 가중치 W2와 편향 b2를 적용하여 3개의 출력값을 만들어냅니다. | |
# (1x10) * (10x3) + (1x3) = 1x3 | |
model = tf.add(tf.matmul(L1, W2), b2) | |
# 텐서플로우에서 기본적으로 제공되는 크로스 엔트로피 함수를 이용해 | |
# 복잡한 수식을 사용하지 않고도 최적화를 위한 비용 함수를 다음처럼 간단하게 적용할 수 있습니다. | |
# tf.nn.softmax_cross_entropy_with_logits_v2 : softmax 함수와 크로스 엔트로피*Cross-Entropy 손실함수를 구현한 API. | |
# softmax 계산까지 함께 해주기 때문에 소프트맥스 함수(tf.nn.softmax)를 씌운 normalize된 출력값이 아닌 소프트맥스 함수를 씌우기 전의 출력값인 logits를 인자로 넣어주어야 함. | |
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})) |
이전 포스팅과 차이점만 살펴보자.
W1 = tf.Variable(tf.random_uniform([2, 10], -1., 1.))
W2 = tf.Variable(tf.random_uniform([10, 3], -1., 1.))
b1 = tf.Variable(tf.zeros([10]))
b2 = tf.Variable(tf.zeros([3]))
이전 포스팅과 다르게 이번에는 weight1,2, bias1,2를 각각 선언하였다.
L1 = tf.add(tf.matmul(X, W1), b1)
L1 = tf.nn.relu(L1)
model = tf.add(tf.matmul(L1, W2), b2)
그리고 layer도 2개로 만들었다. [1x2]의 인풋이 들어오면 w1,b1과 계산하는 layer1, layer1의 output과 w2,b2와 계산하는 layer2.. 이렇게 두 개의 layer가 존재하게 된다.
ex) 1번 layer : [1x2] * [2*10] + [1x10] = [1x10]
2번 layer : [1x10] * [10x3] + [1x3] = [1x3]
cost = tf.reduce_mean( tf.nn.softmax_cross_entropy_with_logits_v2(labels=Y, logits=model))
이전에는 cross_entropy 계산하는 로직을 직접 구현하였는데, 이번에는 tf에 존재하는 함수를 사용해서 loss를 구하고 있다. 주의할 점은 softmax까지 한꺼번에 계산해주기 때문에 softmax가 적용된 normalize된 출력값을 logit에 넣어주면 안된다. softmax가 적용되기 전의 logit값을 넣어주어야 한다.
optimizer = tf.train.AdamOptimizer(learning_rate=0.01)
이전 포스팅에서는 gragient decent optimizer를 사용했는데, 이번에는 adamoptimizer를 사용하고 있다.
나머지 예측을 위한 코드는 이전 포스팅과 동일하며, 결과 정확도는 약 83%를 나타낸다.
이전 33%에 비하면 정말 놀라운 성능 향상이라고 할 수 있겠다.