์ฌ๋ฌ ์์ธก ๊ฒฐ๊ณผ๋ฌผ์ ๋์ถํด๋ด๊ธฐ ์ํ ๋ฐฉ๋ฒ์ผ๋ก Softmax Classification์ ์ฌ์ฉํ๋ค. ์ ๋ฒ ๊ธ์์๋ ๊ธฐ์ด์ ์ธ ์ฌ๋ฌ ๊ณต์๋ค์ ์ฐ๋ฆฌ๊ฐ ์ง์ ๊ตฌํํด๋์ง๋ง, ์ฌ์ค ๊ตฌ๊ธ์ด ์ด๋ฏธ ๋ค ํ ์ค์ ์ฝ๋๋ก ๋ง๋ค์ด๋จ๋ค. ๊ณต๋ถ๋ฅผ ํ๋ ์
์ฅ์์ ์๋ ์๋ฆฌ๋ฅผ ์๋ ๊ฒ์ด ์ค์ํ๊ธฐ ๋๋ฌธ์ ๊ธฐ์ด๋ถํฐ ๋ฐฐ์ฐ๋ ๊ฒ์ด ์ค์ํ์ง๋ง, ์ค๋ฌด์์๋ ๊ฐ๋จํ๊ฒ ์ฌ์ฉํ ์ ์๋ค๋ ์๋ฏธ๋ค. ์ด๋ฒ์๋ ๋ Fancyํ๊ฒ Softmax Classification์ ๊ตฌํํด๋ณด์.
logits = tf.matmul(X, W) + b
hypothesis = tf.nn.softmax(logits)
# Cross entropy cost/loss
cost = tf.reduce_mean(-tf.reduce_sum(Y * tf.log(hypothesis), axis=1))
์ด์ ๊ธ์์ ๊ตฌํํ๋ ๊ธฐ๋ณธ์ ์ธ ์ฝ๋๋ ์์ ๊ฐ๋ค. logits๋ผ๋ node๋ฅผ ์ ์ํ ํ ์ด๋ฅผ ํ์ฉํด hypothesis๋ฅผ Softmax๋ก ๋ง๋ค์๋ค. cost์ญ์ ์ํ ๊ณต์์ ํ๋ํ๋ ์ฝ๋๋ก ๊ตฌํํด ๋ง๋ค์ด ๋์๋ค.
# Cross entropy cost/loss
cost_i = tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=Y_one_hot)
cost = tf.reduce_mean(cost_i)
ํ์ง๋ง softmax_cross_entropy_with_logits๋ผ๋ ํ ์ค์ ์ฝ๋๋ฅผ ๊ตฌ๊ธ์ด ์ด๋ฏธ ๋ง๋ค์ด๋จ๋ค. logits๊ณผ one-hot-encoding์ผ๋ก ํํํ Y ๊ฐ์ ์ง์ ํ๋ฉด ๋๋ค. ์ค์ ๋ฐ์ดํฐ๋ฅผ ๋ถ์ํด๋ณด์.
import numpy as np
# Predicting animal type based on various features
xy = np.loadtxt('data-04-zoo.csv', delimiter=',', dtype=np.float32)
x = xy[:, 0:-1]
y = xy[:, [-1]]
์ด 16๊ฐ์ง์ ํน์ง์ ํ์ฉํด ๊ฐ ๋๋ฌผ์ด ์ด๋ค ์ข
์ผ๋ก ๋ถ๋ฅ๋๋์ง ์ ๋ฆฌํ ๋ฐ์ดํฐ๋ฅผ ๋ถ์ํด๋ณด์. numpy์ loadtxt๋ฅผ ํ์ฉํด ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์ค๊ณ ๊ฐ๊ฐ feature์ธ x์ ๊ฒฐ๊ณผ๊ฐ์ธ y๋ก ๋๋๋ค.
nb_classes = 7 # 0 ~ 6
X = tf.placeholder(tf.float32, [None, 16])
Y = tf.placeholder(tf.int32, [None, 1]) # 0 ~ 6, shape=(?, 1)
Y_one_hot = tf.one_hot(Y, nb_classes) # one-hot shape =(?, 1, 7)
Y_one_hot = tf.reshape(Y_one_hot, [-1, nb_classes]) # shape=(?, 7)
W = tf.Variable(tf.random_normal([16, nb_classes]), name = 'weight')
b = tf.Variable(tf.random_normal([nb_classes]), name = 'bias')
์ด ๊ฒฐ๊ณผ๊ฐ์ 0 ~ 6์ 7๊ฐ์ง๋ก ํํ๋๋ค. X์ Y ๊ฐ๊ฐ์ ํํ์ ๋ง๊ฒ placeholder๋ฅผ ์ง์ ํด์ฃผ๊ณ , ํนํ Y๋ one-hot-encoding์ผ๋ก ๋ฐ๊ฟ์ค๋ค. ์ด๋ ์ฌ์ฉํ๋ ๋ฉ์๋๊ฐ tf.one_hot์ด๋ค. Y๋ผ๋ ๋ฐ์ดํฐ๋ฅผ ์ด 7๊ฐ๋ก ํํ๋๋ one-hot-encoding์ผ๋ก ๋ง๋ค๋ผ๋ ์๋ฏธ๋ค. ๊ทธ๋ฆฌ๊ณ double-brackets๋ก ๋์ถ๋๋ ๊ฒฐ๊ณผ๊ฐ์ ๋ค์ ํ๋์ ๋ฆฌ์คํธ ํํ๋ก ๋ฐ๊ฟ์ฃผ๊ธฐ ์ํด tf.reshape ๋ฉ์๋๋ฅผ ์ ์ฉํ๋ค. W์ b ์ญ์ ๊ฐ๊ฐ์ ํํ์ ๋ง๊ฒ Variable์ ์ง์ ํ๋ค.
# tf.nn.softmax computes softmax activation
# softmax = exp(logits) / reduce_sum(exp(logits), dim)
logits = tf.matmul(X, W) + b
hypothesis = tf.nn.softmax(logits)
# Cross entropy cost/loss
cost_i = tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=Y_one_hot)
cost = tf.reduce_mean(cost_i)
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(cost)
์ด์ ๋ค์ ์ฒ์์ ๋ด์ฉ์ผ๋ก ๋์์ ๊ตฌ๊ธ์์ ๋ง๋ค์ด๋ Softmax Classification์ ์ ์ฉํ๋ฉด ๋๋ค. ์ง๊ธ๊น์ง ์งฐ๋ ์ฝ๋์ ํ๋ฆ๊ณผ ํฌ๊ฒ ๋ค๋ฅด์ง ์๋ค.
prediction = tf.argmax(hypothesis, 1)
correct_prediction = tf.equal(prediction, tf.argmax(Y_one_hot, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
one-hot-encoding์ผ๋ก ํํ๋ Y ๊ฐ ์ค์์ ์ฐ๋ฆฌ๊ฐ ์์๋ณด๊ธฐ ์ฝ๋๋ก tf.argmax๋ฅผ ์ฌ์ฉํด ๋ค์ 0 ~ 6 ์ฌ์ด์ ํน์ ํ ํ๋์ ๊ฐ์ผ๋ก ๋ฐ๊ฟ์ค๋ค. ์ฐ๋ฆฌ๊ฐ ์์ธกํ ๊ฐ๊ณผ ์ค์ Y์ ๊ฐ์ด ์ผ์นํ๋์ง tf.equal ๋ฉ์๋๋ก ํ๋ณ์ ํ๊ณ accuracy๋ ๊ณ์ฐํ ์ ์๋ค.
# Launch graph
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for step in range(2000):
sess.run(optimizer, feed_dict={X: x, Y: y})
if step % 200 == 0:
loss, acc = sess.run([cost, accuracy], feed_dict={X: x, Y: y})
print('Step: {:5}\tLoss: {:.3f}\tAcc: {:.2%}'.format(step, loss, acc))
# Let's see if we can predict
pred = sess.run(prediction, feed_dict={X: x})
# y_data: (N, 1) = flatten => (N, ) matches pred.shape
for p, y in zip(pred, y.flatten()):
print('[{}] Prediction: {} True Y: {}'.format(p == int(y), p, int(y)))
์ด์ ๊ทธ๋ํ๋ฅผ ๊ทธ๋ ค์ ํ์ต์ ์์ผ๋ณธ๋ค. ์ฐ๋ฆฌ๊ฐ ์ต์ข
์ ์ผ๋ก ์๊ณ ์ถ์ ๊ฒ์ ํ์ต ํ์ฐจ๊ฐ ์งํ๋ ์๋ก cost์ accurcy๊ฐ ์ด๋ป๊ฒ ๊ฐ์ ๋๋์ง๋ค. ์ดํ ๊ฐ ๊ฐ์ฒด๋น ์ค์ ๊ฒฐ๊ณผ๊ฐ์ด ์ผ์นํ๋์ง๋ ํ์ธํ ์ ์๋ค.
Step: 0 Loss: 5.991 Acc: 5.94%
Step: 200 Loss: 0.533 Acc: 85.15%
Step: 400 Loss: 0.334 Acc: 91.09%
Step: 600 Loss: 0.237 Acc: 93.07%
Step: 800 Loss: 0.180 Acc: 94.06%
Step: 1000 Loss: 0.143 Acc: 95.05%
Step: 1200 Loss: 0.117 Acc: 100.00%
Step: 1400 Loss: 0.099 Acc: 100.00%
Step: 1600 Loss: 0.085 Acc: 100.00%
Step: 1800 Loss: 0.075 Acc: 100.00%
[True] Prediction: 0 True Y: 0
[True] Prediction: 0 True Y: 0
[True] Prediction: 3 True Y: 3
[True] Prediction: 0 True Y: 0
[True] Prediction: 0 True Y: 0
[True] Prediction: 0 True Y: 0
...
[True] Prediction: 1 True Y: 1
[True] Prediction: 0 True Y: 0
[True] Prediction: 5 True Y: 5
[True] Prediction: 0 True Y: 0
[True] Prediction: 6 True Y: 6
[True] Prediction: 1 True Y: 1
ํ์ต ํ์ฐจ๊ฐ ์งํ๋ ์๋ก cost๋ ์ค์ด๋ค๊ณ accuracy๋ 100%์ ๋๋ฌํ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค. ๊ฐ ๊ฐ์ฒด๋ณ๋ก ๋๋ ๋ดค์ ๋๋ ์ค์ ๊ฒฐ๊ณผ๊ฐ๊ณผ ์ฐ๋ฆฌ๊ฐ ์์ธกํ ๊ฐ์ด ์ผ์นํ๋ค. ์ด์ ์ฐ๋ฆฌ๋ Fancyํ๊ฒ Softmax Classification์ ์ฌ์ฉํ ์ ์๋ค.