ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • AI Multi layer (XOR 문제)
    인공지능 2020. 5. 29. 02:29
    728x90

    지금까지 공부했던 Logistic regression 으로는 XOR 문제를 풀 수 없는데 오늘은 그것에 대해 알아볼게요

     

    기본 구현

    Sigmoid(), numerical_derivation() 함수 준비

    # 시그모이드 함수
    # 입력 x에 대해서 결과가 1이 나올 확률을 의미
    def sigmoid(x):
        return 1 / (1 + np.exp(-x))
    
    
    def numerical_derivation(f, input_data):
        delta_x = 1e-4
        it = np.nditer(input_data, flags=['multi_index'])
        ret = np.zeros_like(input_data)
    
        while not it.finished:
            idx = it.multi_index
            tmp = input_data[idx]
    
            input_data[idx] = float(tmp) + delta_x
            fx1 = f(input_data)
    
            input_data[idx] = float(tmp) - delta_x
            fx2 = f(input_data)
            ret[idx] = (fx1 - fx2) / (2 * delta_x)
    
            input_data[idx] = tmp
            it.iternext()
    
        return ret

     

    Logic Gate 클래스 준비

    class LogicGate:
        def __init__(self, gate_name, xdata, tdata):
            # 임의의 W, b 준비
            self.__W = np.random.rand(2, 1)
            self.__b = np.random.rand(1)
    
            self.name = gate_name
            self.__xdata = xdata.reshape(4, 2)
            self.__tdata = tdata.reshape(4, 1)
    
        def __loss_func(self):
            delta = 1e-7
            z = np.dot(self.__xdata, self.__W) + self.__b
    
            # 각각의 입력에 대해 결과가 1이 나올 확률을 구해줌
            y = sigmoid(z)
    
            # 정답이 1일 때는 1이 나올 확률인 시그모이드를 그대로 활용
            # 정답이 0 일 때는 1이 나올 확률을 역전시켜 0이 나올 확률로 만든 뒤 활용함
            return -np.sum(self.__tdata * np.log(y + delta) + (1 - self.__tdata) * np.log(1 - y + delta))
    
        def error_val(self):
            return self.__loss_func()
    
        def train(self):
            f = lambda x: self.__loss_func()
            learning_rate = 1e-2
    
            print('Init error_val = ', self.error_val(), 'W = ', self.__W, 'b = ', self.__b)
            for step in range(8001):
                self.__W -= learning_rate * numerical_derivation(f, self.__W)
                self.__b -= learning_rate * numerical_derivation(f, self.__b)
    
                if step % 400 == 0:
                    print('step = ', step, 'error_val = ', self.error_val(), 'W = ', self.__W, 'b = ', self.__b)
    
        def predict(self, xdata):
            y = sigmoid(np.dot(xdata, self.__W) + self.__b)
            if y < 0.5:
                result = 0
            else:
                result = 1
            return y, result

    OR

    학습 데이터 준비

    # 학습 데이터 준비
    # OR 데이터
    xdata = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
    tdata = np.array([0, 1, 1, 1])

    학습 및 결과

    OR_obj = LogicGate("OR_GATE", xdata, tdata)
    OR_obj.train()
    
    print(OR_obj.predict([0, 0]))
    print(OR_obj.predict([0, 1]))
    print(OR_obj.predict([1, 0]))
    print(OR_obj.predict([1, 1]))

     

    AND

    학습 데이터 준비

    # 학습 데이터 준비
    # AND 데이터
    xdata = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
    tdata = np.array([0, 0, 0, 1])

    학습 및 결과

    AND_obj = LogicGate("AND_GATE", xdata, tdata)
    AND_obj.train()
    
    print(AND_obj.predict([0, 0]))
    print(AND_obj.predict([0, 1]))
    print(AND_obj.predict([1, 0]))
    print(AND_obj.predict([1, 1]))

    NAND

    학습 데이터 준비

    # 학습 데이터 준비
    # NAND 데이터
    xdata = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
    tdata = np.array([1, 1, 1, 0])

    학습 및 결과

    NAND_obj = LogicGate("NAND_GATE", xdata, tdata)
    NAND_obj.train()
    
    print(NAND_obj.predict([0, 0]))
    print(NAND_obj.predict([0, 1]))
    print(NAND_obj.predict([1, 0]))
    print(NAND_obj.predict([1, 1]))

     

    XOR

    학습 데이터 준비

    # 학습 데이터 준비
    # XOR 데이터
    xdata = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
    tdata = np.array([1, 0, 0, 1])

    학습 및 결과

    XOR_obj = LogicGate("XOR_GATE", xdata, tdata)
    XOR_obj.train()
    
    print(XOR_obj.predict([0, 0]))
    print(XOR_obj.predict([0, 1]))
    print(XOR_obj.predict([1, 0]))
    print(XOR_obj.predict([1, 1]))
    

    XOR 는 값이 이상하게 나오는걸 확인 할 수 있습니다.

    1 0 0 1 이 나와야 하는데 0 0 0 1 이죠? 이걸 XOR 문제라고 합니다.

     

    아래 그림은 게이트 문제를 그림으로 표현한 것입니다.

    입력 x1, x2 가 주어졌을 때 결과가 1이면 빈 동그라미, 0이면 색칠된 동그라미인데

    AND와 OR 는 하나의 선으로 두 데이터를 정확히 가를 수 있지만 XOR 는 어떻게 해도 하나의 직선으로는 어렵다는 것을 알 수 있습니다.

    따라서 XOR 값을 구하려면 직접적인 학습 방법으로는 쉽지 않습니다.

    그럼 어떻게 XOR 문제를 해결할 수 있을까요?

     

    Multi layer

    첫 번째 방법은 XOR = AND(NAND, OR) 를 활용하는 것입니다.

     

    XOR 를 구하기 위해 내부적으로 다른 모델들을 사용하는 것을 Multi layer 라고 합니다.

    코드 및 결과

    # 학습 데이터 준비
    # OR 데이터
    xdata = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
    tdata = np.array([0, 1, 1, 1])
    
    OR_obj = LogicGate("OR_GATE", xdata, tdata)
    OR_obj.train()
    
    # 학습 데이터 준비
    # AND 데이터
    tdata = np.array([0, 0, 0, 1])
    
    AND_obj = LogicGate("AND_GATE", xdata, tdata)
    AND_obj.train()
    
    # 학습 데이터 준비
    # NAND 데이터
    tdata = np.array([1, 1, 1, 0])
    
    NAND_obj = LogicGate("NAND_GATE", xdata, tdata)
    NAND_obj.train()
    
    
    for input_data in xdata:
        print(AND_obj.predict([
            NAND_obj.predict(input_data)[1],
            OR_obj.predict(input_data)[1]
        ]))

     

    한 모델의 Output 이 다른 모델의 Input 으로 들어간다는 Multi layer 는 CNN 신경망 알고리즘에 핵심 아이디어입니다.

    '인공지능' 카테고리의 다른 글

    딥러닝 MNIST 필기체 인식  (0) 2020.06.03
    딥러닝 기초 (XOR 문제 해결)  (0) 2020.06.01
    AI Logistic regression 예제  (0) 2020.05.26
    AI Logistic regression : 분류(Classification)  (0) 2020.05.24
    AI Linear regression 예제  (0) 2020.05.24

    댓글

Designed by Tistory.