텐서플로우로 보는 딥러닝 기초
Neural Nets (XOR) 예제로 알아보기
창창호
2023. 2. 16. 23:18
K(x) = sigmoid(XW1 + B1)
Y' = H(X) = sigmoid(K(x)W2 + B2)
2차원 배열이 x_data를 2차원 공간에 표현하여 x1, x2를 기준으로 y_data를 0 또는 1로 구분하는 예제
- 라이브러리 선언
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline # 그림 등을 바로 볼 수 있게 해주는 라이브러리 선언
import tensorflow as tf
- 붉은색 과 푸른색으로 0, 1 표현하는 기본 틀 생성
x_data = [[0, 0],
[0, 1],
[1, 0],
[1, 1]]
y_data = [[0],
[1],
[1],
[0]]
plt.scatter(x_data[0][0],x_data[0][1], c='red' , marker='^')
plt.scatter(x_data[3][0],x_data[3][1], c='red' , marker='^')
plt.scatter(x_data[1][0],x_data[1][1], c='blue' , marker='^')
plt.scatter(x_data[2][0],x_data[2][1], c='blue' , marker='^')
plt.xlabel("x1")
plt.ylabel("x2")
plt.show()
- tensorflow data API로 학습시킬 값 담고 preprocess function으로 학습에 쓰일 Data 연산을 위해 Type을 맞춰줌
dataset = tf.data.Dataset.from_tensor_slices((x_data, y_data)).batch(len(x_data))
def preprocess_data(features, labels):
features = tf.cast(features, tf.float32)
labels = tf.cast(labels, tf.float32)
return features, labels
- W, b값 설정
W = tf.Variable(tf.zeros((2,1)), name='weight')
b = tf.Variable(tf.zeros((1,)), name='bias')
print("W = {}, B = {}".format(W.numpy(), b.numpy()))
W = [[0.]
[0.]], B = [0.]
- Sigmoid 함수를 가설로 선언
def logistic_regression(features):
hypothesis = tf.divide(1., 1. + tf.exp(tf.matmul(features, W) + b))
return hypothesis
- 가설 검증을 위한 Cost 함수 정의
def loss_fn(hypothesis, features, labels):
cost = -tf.reduce_mean(labels * tf.math.log(logistic_regression(features)) + (1 - labels) * tf.math.log(1 - hypothesis))
return cost
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
- Sigmoid 함수를 통해 예측값이 0.5보다 크면 1을 반환, 0.5보다 작으면 0으로 반환하는 과정
def accuracy_fn(hypothesis, labels):
predicted = tf.cast(hypothesis > 0.5, dtype=tf.float32)
accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, labels), dtype=tf.float32))
return accuracy
- GradientTape를 이용해 경사 값 계산
def grad(hypothesis, features, labels):
with tf.GradientTape() as tape:
loss_value = loss_fn(logistic_regression(features),features,labels)
return tape.gradient(loss_value, [W,b])
- 위의 Data를 Cost함수를 통해 학습시킨 후 모델을 생성
EPOCHS = 1001
for step in range(EPOCHS):
for features, labels in dataset:
features, labels = preprocess_data(features, labels)
grads = grad(logistic_regression(features), features, labels)
optimizer.apply_gradients(grads_and_vars=zip(grads,[W,b]))
if step % 100 == 0:
print("Iter: {}, Loss: {:.4f}".format(step, loss_fn(logistic_regression(features),features,labels)))
print("W = {}, B = {}".format(W.numpy(), b.numpy()))
x_data, y_data = preprocess_data(x_data, y_data)
test_acc = accuracy_fn(logistic_regression(x_data),y_data)
print("Testset Accuracy: {:.4f}".format(test_acc))
Iter: 0, Loss: 0.6931
Iter: 100, Loss: 0.6931
Iter: 200, Loss: 0.6931
Iter: 300, Loss: 0.6931
Iter: 400, Loss: 0.6931
Iter: 500, Loss: 0.6931
Iter: 600, Loss: 0.6931
Iter: 700, Loss: 0.6931
Iter: 800, Loss: 0.6931
Iter: 900, Loss: 0.6931
Iter: 1000, Loss: 0.6931
W = [[0.]
[0.]], B = [0.]
Testset Accuracy: 0.5000
실제 값은 Loss 가 계속 떨어지면서 Testset Accuracy : 1이 나와야하지만
Logistic function에선 Loss 가 동일하고 Testset Accuracy : 0.5가 나오는 걸 봐서 50%정도의 정확도를 가지고 있다고 말할 수 있다.