[딥러닝 알아듣기] 1.5. XOR 문제와 다층 퍼셉트론

“딥러닝 알아듣기” 시리즈는 딥러닝의 기초 지식을 저만의 방식으로 쉽게 풀어내는 시리즈입니다. 이번 챕터에서는 가장 간단한 비선형 문제인 XOR 문제와 다층 퍼셉트론에 대해서 알아봅니다.


1.5.1. XOR 문제와 다층 퍼셉트론

앞선 챕터에서 우리는 이중 분류를 수행하는 퍼셉트론에 대해서 알아보고, AND와 OR 게이트를 구현하는 퍼셉트론을 간단히 만들어보았다. AND와 OR 게이트 퍼셉트론의 구조는 하나의 선형 함수로 표현할 수 있다. 즉, 하나의 결정 경계만으로 입력 값을 잘 구분해내는 퍼셉트론을 만들 수 있었다.

이렇게 단순한 직선 하나를 가지고 분류할 수 있는 간단한 데이터만 있으면 좋겠지만 현실은 그렇지 않다. 현실의 데이터는 입력의 수도 무척 많으며, 그래프 상에서의 분포도 천차만별일 것이다.

멀리 가지 않고 매우 가까운 곳에서 예를 찾을 수 있다. 논리 게이트에 대해 이야기할 때, 보통 AND, OR 게이트와 동시에 이야기되는 게이트가 있다. 바로 XOR 게이트 이다. XOR 게이트는 배타적 논리합 게이트라고도 하며, 두 입력값이 서로 다를 때만 1을 출력 하는 논리 게이트이다. 진리표로 보면 아래와 같다.

<그림 1> XOR 게이트의 진리표

언뜻 보면 XOR 게이트도 어쨌든 논리 게이트니까 쉽게 구현할 수 있지 않을까 싶다. 그러나 안타깝게도, XOR 게이트는 우리가 봐 왔던 단순한 퍼셉트론에 한계가 있다는 점을 너무 명확히 보여준다. XOR 게이트의 입력과 출력을 그래프상에 나타내 보자.

<그림 2> XOR 게이트의 입출력을 나타낸 그래프

AND와 OR 게이트를 구현할 때 처럼, 하나의 선형 함수만을 가지고 검은 점과 하얀 점을 구분해보자. 하나의 결정 경계 직선만을 이용해서 입력을 완벽히 구분할 수 있을까?

<그림 3> 직선 형태의 결정 경계로는 XOR 게이트의 출력을 구분할 수 없다.

아무리 다양하게 시도해봐도, 하나의 결정 경계 직선으로는 입력을 구분할 수 없을 것이다. 다시 말해서, 하나의 선형 함수만을 구현하는 단순한 퍼셉트론으로는 XOR 게이트를 구현할 수 없다.
이는 1960년대에 퍼셉트론을 일선에서 연구하던 학자들에게 충격을 안겨주었다. 퍼셉트론의 가중치와 편향을 아무리 정교하게 설정해도, 하나의 선형 함수로 입력을 구분할 수 없는 문제가 등장했기 때문이었다. 이 문제를 XOR 문제 라고 부른다.

마치 AND와 OR 게이트처럼, 어떠한 문제의 입력 데이터가 하나의 직선으로만 구분이 가능하다면 그것을 선형 문제 라고 한다. 반대로 XOR 게이트처럼, 입력 데이터가 하나의 직선으로는 절대 구분이 불가능하다면 비선형 문제 라고 한다. 애초에 퍼셉트론은 하나의 선형 함수를 표현하고 있는데, 퍼셉트론이 구현하는 직선 하나로 입력을 완벽히 구분할 수 없기 때문이다. 굳이 하나의 선을 쓰려면 아래 그림과 같이 선을 곡선으로 만들어야 하는데, 선형 함수로는 곡선 모양의 결정 경계를 절대 만들 수 없다.

<그림 4> 퍼셉트론으로는 이런 모양의 결정 경계를 만들 수 없다.

실제로 비선형 문제를 하나의 퍼셉트론으로 해결할 수 있는가에 대해서 많은 토론이 오갔다. 퍼셉트론의 창시자인 로젠블라트 박사는 해결할 수 있음을 주장했고, 그의 친구인 민스키 박사는 불가능할 것이라고 믿었다. 얼마 후 1969년, 민스키 박사가 하나의 선형 함수를 구현하는 퍼셉트론으로는 비선형 문제를 풀 수 없다는 사실을 수학적으로 증명한다. 이후 몇 년간 퍼셉트론이 비선형 문제를 풀게 하는 해답은 제시되지 않았다. 이 기간을 인공지능의 첫 번째 겨울 이라고 한다. 퍼셉트론을 필두로 이루어지던 인공지능, 특히 인공 신경망의 연구가 멈추었던 기간이기 때문이다. 그리고 시간이 흘러 1980년대에 들어서, 퍼셉트론이 XOR 문제로 대표되는 비선형 문제를 풀도록 하는 방법이 밝혀진다.

앞에서 보았다시피 하나의 선형 함수로는 XOR 문제를 풀 수 없다. 그럼, 아래와 같이 두 개의 선형 함수를 도입해 두 개의 결정 경계를 만들면 어떨까? 두 개의 결정 경계를 그리면, 아래와 같이 두 직선 사이에 위치하는 점과 그렇지 않은 점을 구분할 수 있을 것이다.

<그림 5> 두 개의 결정 경계를 이용하면 XOR 게이트를 구현할 수 있을 것이다.

입력을 먼저 각각의 결정 경계를 이용해 분류해본 후, 최종적으로 두 경계 사이에 위치하는지 아니면 바깥에 위치하는지 확인해보면 될 것이다. XOR 문제를 풀 수 있는 명확한 해답으로 보인다.

실제로 XOR 게이트가 이미 이러한 구조로 구현되어 있다. 입력 데이터를 NAND 게이트와 OR 게이트에 입력해 각각의 출력을 구하고, 그 출력을 다시 AND 게이트에 넣어 최종 출력을 생성한다. NAND 게이트는 AND 게이트의 출력을 반전시킨 게이트이다.

<그림 6> XOR 게이트의 구조

앞서 구현했던 AND 게이트와 OR 게이트 코드를 이용해서 XOR 게이트를 파이썬으로 구현해볼 수 있다.

# XOR 게이트 #
def XOR(x1, x2):
    h1 = NAND(x1, x2)
    h2 = OR(x1, x2)
    output = AND(h1, h2)
    return output

if __name__ == '__main__':
    print('XOR 0, 0 :', XOR(0, 0))
    print('XOR 0, 1 :', XOR(0, 1))
    print('XOR 1, 0 :', XOR(1, 0))
    print('XOR 1, 1 :', XOR(1, 1))
XOR 0, 0 : 0
XOR 0, 1 : 1
XOR 1, 0 : 1
XOR 1, 1 : 0

NAND 게이트 퍼셉트론은 AND 게이트 퍼셉트론과 결정 경계가 동일하지만 출력이 반전되어 있다. NAND 퍼셉트론은 결정 경계 아래의 입력이 1을 출력하고, OR 퍼셉트론은 결정 경계 위의 입력이 1을 출력한다. 그리고 두 개의 직선을 동시에 그렸을 때, 두 직선 사이에 있는 입력들에 대해서만 XOR 게이트 퍼셉트론이 1을 출력한다.

입력이 두 직선 사이에 있다는 말은, NAND 퍼셉트론의 결정 경계 밑에 있는 점이면서 동시에 OR 퍼셉트론의 결정 경계 위에 있는 점이라는 뜻이다. 따라서 어떤 입력 (x1, x2)가 두 결정 경계 사이에 있으려면, NAND(x1, x2) = 1임과 동시에 OR(x1, x2) = 1이어야 한다. 이렇게 NAND 퍼셉트론과 OR 퍼셉트론의 결정 경계 사이에 있음이 확인된 경우에만 최종 출력으로 1을 출력한다. 그래서 NAND 게이트의 출력과 OR 게이트의 출력을 다시 AND에 입력해 최종 출력을 만드는 것이다. AND 게이트가 두 입력이 1인 경우에만 1을 출력하기 때문이다.

아까 XOR 게이트를 파이썬으로 구현하면서, 우리는 NAND 게이트 퍼셉트론의 출력과 OR 게이트 퍼셉트론의 출력을 다시 AND 게이트 퍼셉트론으로 넣었다.

# XOR 게이트 #
def XOR(x1, x2):
    h1 = NAND(x1, x2)
    h2 = OR(x1, x2)
    output = AND(h1, h2)
    return output

XOR 게이트 퍼셉트론은 그 안에 여러 층의 노드 를 가지고 있는 것이다. 이러한 구조의 퍼셉트론을 다층 퍼셉트론(Multi-Layer Perceptron, MLP) 이라고 한다. 그림 상에서 활성 함수는 생략하였다. 계산 결과를 내놓는 모든 노드의 출력에 활성 함수가 붙어있다고 보면 된다.

<그림 7> XOR 게이트 퍼셉트론은 다층 퍼셉트론이다.

여러개의 선형 함수를 동시에 사용해 결과를 내놓는 퍼셉트론이 다층 퍼셉트론이다. 하나의 노드는 하나의 선형 결정 경계를 만든다. 입력 값들이 노드를 거치는 각각의 순서를 퍼셉트론의 층(Layer) 이라고 한다. 입력 레이어의 값들이 첫 번째 레이어의 노드들에 입력되고, 첫 번째 레이어의 출력 값들이 두 번째 레이어의 노드들에 입력된다. 두 번째 레이어의 출력이 최종 출력이 된다. 마치 노드들로 여러 층을 쌓고 있는 듯한 모양이다.

<그림 8> 퍼셉트론의 각 층

다층 퍼셉트론의 중간에는 얼마든지 많은 층을 쌓을 수 있을 것이다. 이 때, 입력 레이어와 출력 레이어 사이에 위치하는 모든 중간 레이어들을 통들어 은닉층(Hidden Layer) 라고 부른다. 입력과 출력 값만을 취급하는 퍼셉트론의 바깥에서는 내부의 층들이 숨겨져있는 것처럼 보이기 때문이다.

<그림 9> 다층 퍼셉트론의 은닉층

다층 퍼셉트론에 은닉층을 추가하는 것을 ‘층을 쌓는다’ 라고 많이 이야기한다. 또, 하나의 레이어에 많은 노드를 동시에 넣는 것을 퍼셉트론을 넓게 만드는 것 이라고 하고, 레이어 자체를 많이 쌓는 것을 깊게 만드는 것 이라고 한다. 앞으로 자주 보게 될 관용어구니 기억하면 좋다.

<그림 10> 깊은 퍼셉트론과 넓은 퍼셉트론

퍼셉트론을 넓고 깊게 만들어 노드가 많아질수록, 입력 데이터를 구분하기 위한 결정 경계도 많아질 것이다. 이는 더욱 복잡한 비선형 데이터들에 대해서도 퍼셉트론이 활약할 수 있는 원동력이 되었다.

1.5.2. 고차원 입력 데이터의 결정 경계

지금까지는 입력 값이 두 개인 단층 퍼셉트론과 다층 퍼셉트론을 다루었다. 입력 값이 두 개라는 것을 입력 데이터가 2차원 이라고 부른다. 퍼셉트론의 출력에 관여하는 입력 값이 두 개이기 때문에, 결정 경계 그래프를 그리면 2차원의 그래프로 나타내어지기 때문이다. 마찬가지로 입력 값이 세개라면 3차원 입력 데이터 일 것이다.

1차원, 2차원, 3차원, 4차원의 입력을 가지는 각 퍼셉트론의 결정 경계는 어떤 모습일까? 입력의 차원이 바뀌어도, 결정 경계를 구하는 방법은 동일하다. 퍼셉트론의 계산 결과가 임계값을 가지는 모든 입력들을 구하면 된다. 직접 결정 경계들을 그래프에 그려보면 아래와 같은 모습일 것이다.

<그림 11> 입력 데이터의 차원에 따른 결정 경계

1차원 데이터의 결정 경계는 하나의 점, 즉 하나의 실수이다. 2차원 데이터의 결정 경계는 직선이며, 3차원 데이터의 결정 경계는 하나의 평면이다. 입력 데이터가 4차원을 넘어가면 그래프를 그릴 수 없다. 이 때의 결정 경계는 초평면(Hyperplane) 형태라고 한다. 4차원 이상으로 평면의 개념을 확장시킨 것이 초평면이다.

이미 그림에서 보았듯이, N차원 데이터를 입력으로 받는 퍼셉트론의 결정 경계는 N차원 공간을 두 부분으로 나눌 수 있게 한다. 입력 데이터의 차원이 더 늘어나도 이 사실은 동일하다.