밑바닥부터 시작하는 딥러닝 - 1 (perceptron)

퍼셉트론은 프랭크 로젠블랫이 1957년에 고안한 알고리즘이다. 고대 화석 같은 이 알고리즘을 지금 시점에 왜 배우는가 하면, 퍼셉트론이 신경망의 기원이 되는 알고리즘이기 때문이다.
퍼셉트론이란?
퍼셉트론은 다수의 신호를 입력받아 하나의 신호를 출력한다. 여기서 말하는 신호란 전류나 강물처럼 흐름이 있는 무언가를 상상하면 좋다. 다만, 실제 전류와 달리 퍼셉트론 신호는 흐른다/안흐른다 의 두 가지 값을 가질 수 있다. 여기서 1을 신호가 흐른다, 0을 신호가 흐르지 않는다라는 의미로 쓰겠다.

위 사진은 입력으로 2개의 신호를 받은 퍼셉트론의 예이다. x1과 x2는 입력 신호, y는 출력 신호, w1과 w2는 가중치를 뜻한다. 그림의 원을 뉴런 혹은 노드라고 부른다. 입력 신호가 뉴런에 보내질 때는 각각 고유한 가중치가 곱해진다. (w1x1, w2x2). 뉴런에서 보내온 신호의 총합이 정해진 한계를 넘어설 때만 1을 출력한다. 그 한계를 임계값이라 하며, 세타 기호로 나타낸다.
이것을 수식으로 표현하면 아래와 같다.

퍼셉트론은 복수의 입력 신호 각각에 고유한 가중치를 부여한다. 가중치는 각 신호가 결과에 주는 영향력을 조절하는 요소로 작용한다. 즉, 가중치가 클수록 해당 신호가 그만큼 더 중요함을 뜻한다.
단순한 논리 회로
AND 게이트
퍼셉트론을 활용한 간단한 문제를 살표보자. AND 게이트는 입력이 둘이고 출력은 하나이다.

위 사진과 같은 입력 신호와 출력 신호의 대응 표를 진리표라고 한다. 이 사진은 AND 게이트의 진리표로, 두 입력이 모두 1일 때만 1을 출력하고, 그 외에는 0을 출력한다.
이 AND 게이트를 퍼셉트론으로 표현해보자. 이를 위해서는 진리표대로 작동하도록 하는 w1, w2, 세타 값을 정하는 것이다.
사실 진리표를 만족하는 매개변수 조합은 무한히 많다. 가령 (w1, w2, 세타)가 (0.5, 0.5, 0.7)일 때, 또 (0.5, 0.5, 0.8)이나 (1.0, 1.0, 1.0)일 때 모두 AND 게이트의 조건을 만족한다. 매개변수를 이렇게 설정하면 x1과 x2 모두가 1일때만 가중 신호의 총합이 주어진 임계값을 웃돌게 한다.
NAND 게이트와 OR 게이트
이어서 NAND 게이트를 살표보자. NAND는 Not AND를 의미하며, AND 게이트와 반대되는 값을 출력한다.

진리표로 보면 x1과 x2가 모두 1일때만 0을 출력하고, 그 외에는 1을 출력한다. 그럼 매개변수 값들을 어떻게 조합하면 NAND 게이트가 만들어질까?
예를 들어 (w1, w2, 세타) = (-0.5, -0.5, -0.7) 조합이 있다. 사실 AND 게이트를 구현하는 매개 변수의 부호를 모두 반전하면 NAND 게이트가 된다.
같은 흐름에서 OR 게이트도 생각해보자.

OR 게이트는 입력 신호 중 하나 이상이 1이면 출력이 1이 되는 논리 회로이다.
여기서 중요한 점은 퍼셉트론 구조가 AND, NAND, OR 게이트 모두에서 똑같다는 것이다. 세가지 게이트에서 다른 것은 매개변수 뿐이다.
퍼셉트론 구현하기
간단한 구현부터
이제 논리 회로를 파이썬으로 구현해보자. 아래는 x1과 x2를 인수로 받는 AND라는 함수이다.

매개변수 w1, w2, theta는 함수 안에서 초기화하고, 가중치를 곱한 입력의 총합이 임계값을 넘으면 1을 반환하고 그 외에는 0을 반환한다.
가중치와 편향 도입
앞에서 구현한 AND 게이트는 직관적이고 알기 쉽지만, 앞으로를 생각해서 다른 방식으로 수정해보자.

그 전에 이 식에서 세타를 -b로 치환하면 퍼셉트론의 동작이 아래처럼 바뀐다.

여기에서 b를 편향이라 하며 w1과 w2는 그대로 가중치이다. 퍼셉트론은 입력신호에 가중치를 곱한 값과 편향을 합하여, 그 값이 0을 넘으면 1을 출력하고 그렇지 않으면 0을 출력한다. 넘파이를 사용해서 구현해보자.

넘파이 배열끼리의 곱셈은 두 배열의 원소 수가 같다면 각 원소끼리 곱한다. np.sum()은 입력한 배열에 담긴 모든 원소의 총합을 계산한다.
가중치와 편향 구현하기
가중치와 편향을 도입한 AND 게이트는 다음과 같이 구현할 수 있다.

여기에서 세타가 편향 b로 치환되었다. 그리고 편향은 가중치 w1, w2와 기능이 다르다는 사실에 주의하자. 구체적으로 말하면 w1과 w2는 각 입력 신호가 결과에 주는 영향력을 조절하는 매개변수고, 편향은 뉴런이 얼마나 쉽게 활성화 하느냐를 조정하는 매개변수이다. 예를 들어 b가 -0.1이면 각 입력 신호에 가중치를 곱한 값들의 합이 0.1을 초과할 때만 뉴런이 활성화된다. 반면 b가 -20.0이면 각 입력 신호에 가중치를 곱한 값들의 합이 20.0을 넘지 않으면 뉴런을 활성화되지 않는다. 이처럼 편향의 값은 뉴런이 얼마나 쉽게 활성화되는지를 결정한다. 한편 w1과 w2는 가중치로 b는 편향으로 구별하기도 하지만 문맥에 따라 셋 모두를 가중치라 할 때도 있다.
이어서 NAND 게이트와 OR 게이트를 구현해보자.


앞 절에서 AND, NAND, OR은 모두 같은 구조의 퍼셉트론이고, 차이는 가중치 매개변수의 값뿐이라 했다. 실제로 파이썬으로 작성한 NAND와 OR 게이트의 코드에서도 AND와 다른 곳은 가중치와 편향 값을 설정하는 부분뿐이다.
퍼셉트론의 한계
지금까지 살펴본 것처럼 퍼셉트론을 이용하면 AND, NAND, OR의 3가지 논리 회로를 구현할 수 있다. 계속해서 XOR 게이트도 생각해보자.
XOR 게이트
XOR 게이트는 배타적 논리합이라는 논리 회로이다.

위 사진과 같이 x1과 x2중 한쪽이 1일때만 1을 출력한다. 이 XOR 게이트를 퍼셉트론으로 구현하려면 가중치 매개변수 값을 어떻게 설정하면 될까?
사실 지금까지 본 퍼셉트론으로는 XOR 게이트를 구현할 수 없다. 왜 AND와 OR은 되고 XOR은 안될까? 그림으로 확인해보자.
우선 OR 게이트의 동작을 시각적으로 생각해보자. OR 게이트는 예를 들어 가중치 매개변수가 (b, w1, w2) = (-0.5, 1.0, 1.0) 일때 만족하는 경우의 수이다. 이때의 퍼셉트론은 아래와 같이 표현될 수 있다.

위 식의 퍼셉트론은 직선으로 나뉜 두 영역을 만든다. 직선으로 나뉜 한쪽 영역은 1을 출력하고 다른 한쪽은 0을 출력한다.

OR 게이트는 (x1, x2) = (0, 0) 일때 0을 출력하고, (0,1), (1,0), (1,1)일 때는 1을 출력한다. 위 그림에서 0을 원으로 1을 삼각형으로 표시했다. OR 게이트를 만들려면 그림과 같이 직선을 그어 원과 세모가 섞이지 않도록 영역을 나눠야 한다. 실제로 이 그림의 직선은 네 점을 제대로 나누고 있다.
하지만 XOR 게이트는 위와 같은 OR 게이트와는 같은 방식으로 선을 그을 수 없다.
선형과 비선형
직선 하나로는 원과 세모를 나눌수 없지만, 직선이라는 제약을 없앤다면 가능하다.

퍼셉트론은 직선 하나로 나눈 영역만 표현할 수 있다는 한계가 있다. 위와 같이 곡선은 표현할 수 없다. 위와 같은 곡선의 영역을 비선형 영역, 직선의 영역을 선형 영역이라고 한다.
다층 퍼셉트론이 충돌한다면
안타깝게도 퍼셉트론으로는 XOR 게이트를 표현할 수 없었다. 사실 퍼셉트론의 아름다움은 multi-layer perceptron을 만들 수 있다는데 있다.
기존 게이트 조합하기
XOR 게이트를 만드는 방법은 다양하다. 그 중 하나는 앞서 만든 AND, NAND, OR 게이트를 조합하는 방법이다. 여기에서는 AND, NAND, OR 게이트를 아래 그림과 같이 표기할 것이다.


위와 같은 조합이라면 XOR 게이트를 구현할 수 있다. x1과 x2가 입력 신호, y가 출력신호이다. x1과 x2는 NAND와 OR 게이트의 입력이 되고, NAND와 OR의 출력이 AND 게이트의 입력으로 이어진다.
그럼 위 조합이 정말 XOR을 구현하는지 살펴보자. NAND의 출력을 s1, OR의 출력을 s2로 해서 진리표를 만들면 아래처럼 된다.

x1, x2, y에 주목하면 분명히 XOR 출력과 같다.
XOR 게이트 구현하기
이어서 XOR 게이트를 파이썬으로 구현해보자. 지금까지 정의한 함수를 사용하면 아래와 같이 쉽게 구현할 수 있다.

지금 구현한 XOR을 뉴런을 이용해서 표현하면 아래처럼 그릴 수 있다.

위 퍼셉트론은 다층 구조이다.
지금까지 본 AND, OR 퍼셉트론과 형태가 다르다. 실제로 AND, OR이 단층 퍼셉트론인 데 반해 XOR은 2층 퍼셉트론이다. 이처럼 층이 여러 개인 퍼셉트론을 다층 퍼셉트론 (multi-layer percetron)이라 한다.
위 그림과 같은 2층 퍼셉트론은 0층에서 1층으로 신호가 전달되고, 1층에서 2층으로 신호가 전달된다.