# Softmax Classifier
import tensorflow as tf
import numpy as np
tf.set_random_seed(777)
# 파일로부터 데이터 불러오기
xy = np.loadtxt('data-zoo.csv', delimiter=',', dtype=np.float32)
# x_data, y_data 생성하기
x_data = xy[:, 0:-1] # 모든 줄과, 0부터 끝에서 -1위치 까지의 데이터
y_data = xy[:, [-1]] # 모든 줄과 맨 마지막 데이터
nb_classes = 7 # 0 ~ 6까지 7가지
print(x_data.shape, y_data.shape)
X = tf.placeholder(tf.float32, [None, 16]) # 입력의 갯수
Y = tf.placeholder(tf.int32, [None, 1]) # 결과의 갯수
# Y값을 one hot 형식식로 변경하기 [3] --> [[0001000]] 형태로
Y_one_hot = tf.one_hot(Y, nb_classes) # shape=(?, 1, 7) 한차원 더 만들어 처리 하기
print("one_hot:", Y_one_hot) # 1차원이면 2차원으로 변경
# reshape [[0001000]] 형태를 [0001000] 형태로 변환
Y_one_hot = tf.reshape(Y_one_hot, [-1, nb_classes]) # -1은 모든것을 의미
print("reshape one_hot:", Y_one_hot) # shape=(?, 7)
W = tf.Variable(tf.random_normal([16, nb_classes]), name="weight") # [입력값, 출력값]
b = tf.Variable(tf.random_normal([nb_classes]), name="bias") # [출력값]
# # 가설 - softmax 이용
# # softmax = exp(logits) / reduce_sum(exp(logits), dim)
logits = tf.matmul(X, W) + b
hypothesis = tf.nn.softmax(logits)
# Cross entropy cost
# cost = tf.reduce_mean(-tf.reduce_sum(Y * tf.log(hypothesis), axis = 1))를 사용하지 않음
cost_i = tf.nn.softmax_cross_entropy_with_logits(logits = logits, labels=Y_one_hot)
cost = tf.reduce_mean(cost_i)
# 기존의 optimzer 그대로 사용
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
train = optimizer.minimize(cost)
# 예측값 처리
prediction = tf.argmax(hypothesis, 1)
correct_predication = tf.equal(prediction, tf.argmax(Y_one_hot, 1))
accuracy = tf.reduce_mean(tf.cast(correct_predication, tf.float32))
# 실행
with tf.Session() as sess:
sess.run(tf.global_variables_initializer()) # 초기화
for step in range(2001):
_, cost_val, acc_val = sess.run([train, cost, accuracy], feed_dict={X: x_data, Y: y_data})
if step % 100 == 0:
print("Step: {:5}\tCost: {:.3f}\tAcc: {:.2%}".format(step, cost_val, acc_val))
pred = sess.run(prediction, feed_dict={X: x_data})
# flatten 기존의 [[1],[0]]의 형태를 [1, 0] 형태로 변환
for p, y in zip(pred, y_data.flatten()):
print("[{}] Prediction: {} True Y: {}".format(p == int(y), p, int(y)))