Be Brave, Be Humble

Logistic_XOR_Regression 본문

AI/Computer Vision

Logistic_XOR_Regression

해쨔니 2022. 7. 25. 21:12

numerical_derivative, sigmoid 함수 정의

In [ ]:
import numpy as np
from datetime import datetime

np.random.seed(66)

def numerical_derivative(f, x):
    delta_x = 1e-4 # 0.0001
    grad = np.zeros_like(x) # x랑 같은 차원으로 0행렬 생성

    it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite']) 
    # np.nditer : 다차원 배열의 각 요소 (= 스칼라)에 접근 가능하게 하는 함수. 
    # https://transferhwang.tistory.com/278 참고

    while not it.finished:
        idx = it.multi_index
        tmp_val = x[idx]
        x[idx] = float(tmp_val) + delta_x
        fx1 = f(x) # f(x+delta_x)

        x[idx] = float(tmp_val) - delta_x
        fx2 = f(x) # f(x-delta_x)
        grad[idx] = (fx1 - fx2) / (2*delta_x)

        x[idx] = tmp_val
        it.iternext()

    return grad
In [ ]:
# 최종 출력은 y = sigmoid(Wx+b)이며, 손실함수는 cross-entropy로 나타냄

def sigmoid(z):
    return 1 / (1 + np.exp(-z) )

data definition

In [ ]:
x_XOR = np.array([ [0,0], [0,1], [1,0], [1,1] ])
t_XOR = np.array([0, 1, 1, 0]).reshape(4,1)

print("x_XOR.shape = ", x_XOR.shape, "t_XOR.shape", t_XOR.shape)
x_XOR.shape =  (4, 2) t_XOR.shape (4, 1)

initialize weights and bias

In [ ]:
W = np.random.rand(2, 1) # 피처가 2차원으로 증가하였으니 가중치도 2차원
b = np.random.rand(1)

print("W = ", W, ", W.shape = ", W.shape, ", b = ", b, ", b.shape = ", b.shape)
W =  [[0.15428758]
 [0.13369956]] , W.shape =  (2, 1) , b =  [0.36268547] , b.shape =  (1,)

define loss function and output, y

In [ ]:
def loss_func(x, t):

    delta = 1e-7 # log 무한대 발산 방지

    z = np.dot(x, W) + b
    y = sigmoid(z)

    # cross-entropy
    return -np.sum( t*np.log(y + delta) + (1-t)*np.log( (1-y)+delta ) )
    # 이론상 시그모이드값인 y는 1이 될 수 없지만, 변수 저장공간 때문에 8byte로 표현해야 해서
    # 0.9999가 올림되어 1이되는 경우가 있음. 따라서 log 무한대 발산 방지위해 delta 더해줌

XOR learning

In [ ]:
learning_rate = 1e-5

f = lambda x : loss_func(x_XOR, t_XOR)

print("Initial error value = ", loss_func(x_XOR, t_XOR) )

start_time = datetime.now()

for step in range(200001):

    W -= learning_rate * numerical_derivative(f, W)

    b -= learning_rate * numerical_derivative(f, b)

    if (step % 5000 == 0):
      print("step = ", step, "error value = ", loss_func(x_XOR, t_XOR))

end_time = datetime.now()

print()
print("Elapsed Time => ", end_time - start_time)
Initial error value =  2.7730781385876213
step =  0 error value =  2.77307813033545
step =  5000 error value =  2.773039709898957
step =  10000 error value =  2.773006410086216
step =  15000 error value =  2.772977485577135
step =  20000 error value =  2.772952300635761
step =  25000 error value =  2.7729303129837746
step =  30000 error value =  2.772911060046327
step =  35000 error value =  2.772894147221561
step =  40000 error value =  2.7728792378762943
step =  45000 error value =  2.7728660448140214
step =  50000 error value =  2.772854322998673
step =  55000 error value =  2.7728438633493804
step =  60000 error value =  2.7728344874486766
step =  65000 error value =  2.7728260430296823
step =  70000 error value =  2.772818400127661
step =  75000 error value =  2.772811447798134
step =  80000 error value =  2.7728050913181663
step =  85000 error value =  2.7727992497996956
step =  90000 error value =  2.772793854154239
step =  95000 error value =  2.772788845357254
step =  100000 error value =  2.77278417296803
step =  105000 error value =  2.7727797938674943
step =  110000 error value =  2.772775671181839
step =  115000 error value =  2.772771773364617
step =  120000 error value =  2.772768073413965
step =  125000 error value =  2.7727645482050742
step =  130000 error value =  2.772761177920909
step =  135000 error value =  2.7727579455667506
step =  140000 error value =  2.7727548365561705
step =  145000 error value =  2.7727518383579657
step =  150000 error value =  2.772748940195048
step =  155000 error value =  2.7727461327876464
step =  160000 error value =  2.7727434081343
step =  165000 error value =  2.7727407593250786
step =  170000 error value =  2.772738180382277
step =  175000 error value =  2.7727356661245457
step =  180000 error value =  2.7727332120510075
step =  185000 error value =  2.772730814242413
step =  190000 error value =  2.772728469276826
step =  195000 error value =  2.772726174157709
step =  200000 error value =  2.7727239262525667

Elapsed Time =>  0:00:41.748182

200000번 돌렸을 때 loss가 크게 줄어들고 있진 않음 =>

  1. epoch 증가 시켜봄.
  2. 하이퍼파라미터(러닝레이트 변경) -> 그래도 값이 크게 바뀌지 않는다면
  3. 혹시 2.78이 최소인가? 의문 가지기.

2.7이 최소값인지 확인해보려면 predict 해보면 됨. 제대로 예측하는지!!

그런데 밑에 실행시켜보면 잘 예측해내지 못함. 문제는 데이터에 있음.

and는 0 0 0, 0 1 0, 1 0 0

xor은 0 0 0, 0 1 1, 1 0 1 이런 패턴임

기하학적으로 생각해보면 and는 1 1 1일 때만 1이 나오면 됨. 즉 1개의 직선으로 classification이 가능함.

그런데 xor은 데이터의 패턴을 표시하기 위해서 선이 2개가 있어야 함.

0 0 0, 1 1 0/ 0 1 1, 1 0 1을 분리해내는 선 => 즉 곡선이 필요함. 이 간단한 xor 데이터도 분류를 못해내더라 => XOR problem

ML로 풀 수 없는 문제를 Deep learning으로 풀 수 있다!!! => ML에서 DL로 넘어가는 계기

ML 알고리즘으로 XOR을 풀 수 없다는 것을 증명해낸 것이 마빈민스키. 퍼셉트론이라는 책에서 증명함. => 이것이 1차 AI 암흑기

evaluate and predict

In [ ]:
# 학습 마친 후, 임의의 데이터에 대해 미래 값 예측 함수
# 입력변수 test_data : numpy type

def predict(test_data):

    z = np.dot(test_data, W) + b
    y = sigmoid(z)

    if y > 0.5:
      pred_val = 1
    else:
      pred_val = 0
    
    return y, pred_val
In [ ]:
test_data = np.array([ [0,0], [0,1], [1,0], [1,1] ])

for input_data in test_data:

  print(predict(input_data))
(array([0.50672412]), 1)
(array([0.50029826]), 1)
(array([0.50220144]), 1)
(array([0.49577529]), 0)
In [ ]:
In [ ]:
In [ ]:
In [ ]:
 

'AI > Computer Vision' 카테고리의 다른 글

Keras_Simple_Linear_Regression_Exercise_Sequential  (0) 2022.08.01
multi_variable_linear_regression  (0) 2022.08.01
LogisticRegression_Example  (0) 2022.07.25
LinearRegression_Example  (0) 2022.07.25
NumericalDerivative_Example  (0) 2022.07.25
Comments