donut

Logistic_XOR 구현

Tensorflow/DNN

 

 

 

 

NN(Neural Network)_XOR

NN(인공신경망)을 통해 컴퓨터가 사람의 뇌처럼
복잡한 계산을 할 수있게 한다.

대표적으로 XOR 알고리즘이 그 예다.
XOR은 아래 처럼, 주어진 두 수가 같은 경우에 1, 다를경우는 0을 출력한다. 즉 OR과 반대다.

XOR알고리즘을 풀기위해선 여러번의 여러번의 계산이 필요하다.
분류 함수로 한번에 할 수 없고, 분류 함수를 단계별로 진행해야 풀이가 가능하다.

이번 포스팅에서는 한번의 분류함수로 xor을 풀이해 보겠습니다.

In [3]:
x = [[0, 0],
     [0, 1],
     [1, 0],
     [1, 1]]
y = [[0],
     [1],
     [1],
     [0]]
 

XOR알고리즘을 tf코드로 모델 만들기

In [4]:
import numpy as np
import tensorflow as tf
print(tf.__version__)
 
2.1.0
In [5]:
#학습시킬 dataset 세팅
#배치값 미지정
dataset= tf.data.Dataset.from_tensor_slices((x,y))
In [6]:
#dataset값 확인
elem = [i for i in dataset]
print(elem)
print(len(elem))
 
[(<tf.Tensor: shape=(2,), dtype=int32, numpy=array([0, 0], dtype=int32)>, <tf.Tensor: shape=(1,), dtype=int32, numpy=array([0], dtype=int32)>), (<tf.Tensor: shape=(2,), dtype=int32, numpy=array([0, 1], dtype=int32)>, <tf.Tensor: shape=(1,), dtype=int32, numpy=array([1], dtype=int32)>), (<tf.Tensor: shape=(2,), dtype=int32, numpy=array([1, 0], dtype=int32)>, <tf.Tensor: shape=(1,), dtype=int32, numpy=array([1], dtype=int32)>), (<tf.Tensor: shape=(2,), dtype=int32, numpy=array([1, 1], dtype=int32)>, <tf.Tensor: shape=(1,), dtype=int32, numpy=array([0], dtype=int32)>)]
4
In [7]:
#학습시킬 dataset 세팅
#배치값 x의 길이로 설정
#배치는 한번에 학습시킬 size임
dataset= tf.data.Dataset.from_tensor_slices((x,y)).batch(len(x))
In [8]:
#dataset값 확인
elem = [i for i in dataset]
print(elem)
print(len(elem))
 
[(<tf.Tensor: shape=(4, 2), dtype=int32, numpy=
array([[0, 0],
       [0, 1],
       [1, 0],
       [1, 1]], dtype=int32)>, <tf.Tensor: shape=(4, 1), dtype=int32, numpy=
array([[0],
       [1],
       [1],
       [0]], dtype=int32)>)]
1
 

전처리 함수(데이터 타입 맞추기)

In [10]:
def preprocess_data(features, labels):
    features = tf.cast(features, tf.float32)
    labels = tf.cast(labels, tf.float32)
    return features, labels
 

W, b 설정

In [11]:
#W,b의 초기값은 0이나 랜덤으로 으로 정해주면된다
#W = tf.Variable(tf.random.normal((2,1)))
#b = tf.Variable(tf.random.normal((1,)))
W = tf.Variable(tf.zeros((2,1)), name= 'weight')
b = tf.Variable(tf.zeros((1,)), name= 'bias')
print(W.numpy(), b.numpy())
 
[[0.]
 [0.]] [0.]
 

시그모이드 선언

In [12]:
def logistic_regression(features):
    hypothesis = tf.divide(1., 1. + tf.exp(tf.matmul(features, W) + b))
    return hypothesis
 

코스트 함수 선언

In [13]:
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)
 

결과값 도출 함수 구현

시그모이드 함수로 도출된 hypothesis를 0 or 1로 cast해준다.

tf.cast => 조건이 참일경우 1, 거짓일 경우 0출력
tf.equal => 주어인 값이 같은경우 True, 다를경우 False
아래는 cast와 equal를 이해하기 쉽도록 예시를 작성 하였습니다.

In [14]:
test1 = 0.3
test2 = tf.cast(test1 > 0.5,dtype = tf.float32)
test2.numpy()
Out[14]:
0.0
In [15]:
test1 = 0.6
test2 = tf.cast(test1 > 0.5,dtype = tf.float32)
test2.numpy()
Out[15]:
1.0
In [16]:
test1 = 0.6
test2 = 0.6
test3 = tf.equal(test1,test2)
test3.numpy()
Out[16]:
True
In [17]:
test7 = tf.cast(tf.equal(test1,test2),dtype = tf.float32)
test7.numpy()
Out[17]:
1.0
In [18]:
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
 

경사하강법

In [19]:
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])
 

실행

로지스틱 함수로 xor알고리즘을 완벽하게 구현하지 못했다.
loss값이 더이상 감소하지 않는 것을 확인 할 수 있었다.

In [23]:
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()))
 
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.]
 

이 포스팅은 부스트코스 강의, 모두를위한 딥러닝 강의를 참고하였습니다.

In [ ]:
 

'Tensorflow > DNN' 카테고리의 다른 글

DNN_XOR구현  (0) 2020.08.12
NN_XOR 구현  (0) 2020.08.08