이 포스트는 Github 접속 제약이 있을 경우를 위한 것이며, 아래와 동일 내용을 실행 결과와 함께 Jupyter notebook으로도 보실 수 있습니다.
You can also see the following as Jupyter notebook along with execution result screens if you have no trouble connecting to the Github.
4-1. Train Data 확인 및 가중치 설정
import tensorflow as tf
import numpy as np
tf.random.set_seed(1234) # for reproducibility
x_data = [[1, 2, 1, 1],
[2, 1, 3, 2],
[3, 1, 3, 4],
[4, 1, 5, 5],
[1, 7, 5, 5],
[1, 2, 5, 6],
[1, 6, 6, 6],
[1, 7, 7, 7]]
y_data = [[0, 0, 1],
[0, 0, 1],
[0, 0, 1],
[0, 1, 0],
[0, 1, 0],
[0, 1, 0],
[1, 0, 0],
[1, 0, 0]]
# convert into numpy and float format
x_data = np.asarray(x_data, dtype=np.float32)
y_data = np.asarray(y_data, dtype=np.float32)
nb_classes = 3 #class의 개수
print(x_data.shape)
print(y_data.shape)
# Weight and bias setting
W = tf.Variable(tf.random.normal((4, nb_classes)), name='weight')
b = tf.Variable(tf.random.normal((nb_classes,)), name='bias')
variables = [W, b]
print(W,b)
4-2. Modeling
# tf.nn.softmax computes softmax activations
# softmax = exp(logits) / reduce_sum(exp(logits), dim)
def hypothesis(X):
return tf.nn.softmax(tf.matmul(X, W) + b)
print(hypothesis(x_data))
4-3. Cost function
def cost_fn(X, Y):
logits = hypothesis(X)
cost = -tf.reduce_sum(Y * tf.math.log(logits), axis=1)
cost_mean = tf.reduce_mean(cost)
#print('cost: ', cost)
return cost_mean
print('cost_mean: ', cost_fn(x_data, y_data))
4-4. GradientTape 기능
x = tf.constant(3.0)
with tf.GradientTape() as g:
g.watch(x)
y = x * x # x^2
dy_dx = g.gradient(y, x) # Will compute to 6.0
print(dy_dx)
def grad_fn(X, Y):
with tf.GradientTape() as tape:
loss = cost_fn(X, Y)
grads = tape.gradient(loss, variables)
return grads
print(grad_fn(x_data, y_data)) # 가중치 각 원소들의 grad 계산
# variables = [W, b]
print(variables)
# zip 기능 확인
grads = grad_fn(x_data, y_data)
for pair in zip(grads, variables):
print(pair)
4-5. 학습 및 가중치 최적화
def fit(X, Y, epochs=2000, verbose=100):
optimizer = tf.keras.optimizers.SGD(learning_rate=0.1)
for i in range(epochs):
grads = grad_fn(X, Y)
optimizer.apply_gradients(zip(grads, variables))
if (i==0) | ((i+1)%verbose==0):
print('Loss at epoch %d: %f' %(i+1, cost_fn(X, Y).numpy()))
fit(x_data, y_data)
4-6. Prediction Check
sample_data = [[2,1,3,2]] # answer_label [[0,0,1]]
sample_data = np.asarray(sample_data, dtype=np.float32)
a = hypothesis(sample_data)
print(a)
print(tf.argmax(a, 1)) #index: 2
b = hypothesis(x_data)
print(b)
print(tf.argmax(b, 1))
print(tf.argmax(y_data, 1)) # matches with y_data
4-7. Convert as Class
class softmax_classifer(tf.keras.Model):
def __init__(self, nb_classes):
super(softmax_classifer, self).__init__()
self.W = tf.Variable(tf.random.normal((4, nb_classes)), name='weight')
self.b = tf.Variable(tf.random.normal((nb_classes,)), name='bias')
def softmax_regression(self, X):
return tf.nn.softmax(tf.matmul(X, self.W) + self.b)
def cost_fn(self, X, Y):
logits = self.softmax_regression(X)
cost = tf.reduce_mean(-tf.reduce_sum(Y * tf.math.log(logits), axis=1))
return cost
def grad_fn(self, X, Y):
with tf.GradientTape() as tape:
cost = self.cost_fn(x_data, y_data)
grads = tape.gradient(cost, self.variables)
return grads
def fit(self, X, Y, epochs=2000, verbose=500):
optimizer = tf.keras.optimizers.SGD(learning_rate=0.1)
for i in range(epochs):
grads = self.grad_fn(X, Y)
optimizer.apply_gradients(zip(grads, self.variables))
if (i==0) | ((i+1)%verbose==0):
print('Loss at epoch %d: %f' %(i+1, self.cost_fn(X, Y).numpy()))
model = softmax_classifer(nb_classes)
model.fit(x_data, y_data)
4-8. Example : Zoo classifier
xy = np.loadtxt('zoo.txt', delimiter=',', dtype=np.float32)
x_data = xy[:, 0:-1]
y_data = xy[:, -1]
nb_classes = 7 # 0 ~ 6
y_data.astype(np.int32) # 데이터 형태 변환 (converting data type)
# Make Y data as onehot shape
Y_one_hot = tf.one_hot(y_data.astype(np.int32), nb_classes)
print(x_data.shape, Y_one_hot.shape)
# Weight and bias setting
W = tf.Variable(tf.random.normal((16, nb_classes)), name='weight')
b = tf.Variable(tf.random.normal((nb_classes,)), name='bias')
variables = [W, b]
# tf.nn.softmax computes softmax activations
# softmax = exp(logits) / reduce_sum(exp(logits), dim)
def logit_fn(X):
return tf.matmul(X, W) + b
def hypothesis(X):
return tf.nn.softmax(logit_fn(X))
def cost_fn(X, Y):
logits = logit_fn(X)
cost_i = tf.keras.losses.categorical_crossentropy(y_true=Y, y_pred=logits,
from_logits=True)
cost = tf.reduce_mean(cost_i)
return cost
def grad_fn(X, Y):
with tf.GradientTape() as tape:
loss = cost_fn(X, Y)
grads = tape.gradient(loss, variables)
return grads
def prediction(X, Y):
pred = tf.argmax(hypothesis(X), 1)
correct_prediction = tf.equal(pred, tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
return accuracy
def fit(X, Y, epochs=1000, verbose=100):
optimizer = tf.keras.optimizers.SGD(learning_rate=0.1)
for i in range(epochs):
grads = grad_fn(X, Y)
optimizer.apply_gradients(zip(grads, variables))
if (i==0) | ((i+1)%verbose==0):
# print('Loss at epoch %d: %f' %(i+1, cost_fn(X, Y).numpy()))
acc = prediction(X, Y).numpy()
loss = cost_fn(X, Y).numpy()
print('Steps: {} Loss: {}, Acc: {}'.format(i+1, loss, acc))
fit(x_data, Y_one_hot)