퍼셉트론

퍼셉트론은 로젠 블렛이 1957년에 고안한 알고리즘입니다. 퍼셉트론은 입력 데이터를 2개의 부류중 하나로 분류하는 분류기(classifier)입니다.

신경세포와 퍼셉트론

_images/neuron-node1.png

사람의 뇌신경 세포의 동작과정을 흉내내어 만든 수학적 모델이 퍼셉트론입니다.

퍼셉트론은 학습이 가능한 초창기 신경망 모델로 현대적 의미로 보면 상당히 원시적인 신경망으로 볼 수 있습니다. 하지만 노드, 가중치, 층과 같은 개념이 도입되어 딥러닝을 포함하여 현대 신경망의 중요한 구성요소들을 이해하는데 의미가 있습니다.

퍼셉트론

퍼셉트론의 구조는 입력층과 출력층이라는 2개의 층으로 구성되는 단순한 구조로 이루어집니다.

_images/fig2-1.png

그림 2-1 입력이 2개인 퍼셉트론

그림 2-1은 입력으로 2개의 신호를 받은 퍼셉트론의 예입니다. \(x_1\), \(x_2\)는 입력 신호, \(y\)는 출력신호, \(w_1\), \(w_2\)가중치(weight)를 뜻합니다. 그림에서 원은 뉴런 혹은 노드라고 부릅니다.

2개 입력에 대한 퍼셉트론은 다음과 같은 수식으로 나타낼 수 있습니다.

(1)\[\begin{split}y = \begin{cases} 0, & \text{if} \quad w_1 x_1 + w_2 x_2 <= \beta \\ 1, & \text{if} \quad w_1 x_1 + w_2 x_2 > \beta \end{cases}\end{split}\]

더 일반적으로 \(d\) 개의 입력을 가지는 퍼셉트론은 다음과 같이 나타낼 수 있습니다.

\[\begin{split}y = \tau(w_1 x_1 + w_2 x_2 + \cdots + w_d x_d) \\ \tau(a) = \begin{cases} 0, & \text{if} \quad a <= \beta \\ 1, & \text{if} \quad a > \beta \end{cases}\end{split}\]

다음은 \(d=2\)일 때 예를 들어서 설명합니다.

단순한 논리연산

퍼셉트론을 활용한 간단한 문제를 살펴봅니다. 첫번째로 논리곱(AND) 진리표를 살펴봅니다. 두 입력이 모두 1일 때만 1을 출력하고 그 외에는 0을 출력합니다.

논리곱(AND 게이트)

논리곱

\(x_1\)

\(x_2\)

\(y\)

0

0

0

1

0

0

0

1

0

1

1

1

위 표를 퍼셉트론으로 표현한다는 것은 \(w_1, w_2, \beta\)를 결정하는 것입니다. 위 조건을 만족하는 매개변수 조합은 무수히 많습니다. 가령 \((w_1, w_2, \beta) = (0.5, 0.5, 0.5)\)로 하거나 \((0.5, 0.5, 0.8)\)로 하는 등 무수히 많은 조합을 찾을 수 있습니다.

부정 논리곱(NAND 게이트)

NAND는 not and를 의미하며 AND의 출력을 부정한 것이 됩니다.

부정 논리곱

\(x_1\)

\(x_2\)

\(y\)

0

0

1

1

0

1

0

1

1

1

1

0

NAND 게이트를 표현하는 방법은 무수히 많지만, 예를 들어 \((w_1, w_2, \beta) = (-0.5, -0.5, -0.7)\)의 조합이 있을 수 있습니다.

논리합(OR 게이트)

논리합

\(x_1\)

\(x_2\)

\(y\)

0

0

0

1

0

1

0

1

1

1

1

1

퍼셉트론 구현

간단한 구현

다음은 논리곱(AND 게이트)를 구현한 것입니다. \(x_1\), \(x_2\)를 입력받아 결과를 반환합니다.

In [1]: def AND(x1, x2):
   ...:   w1, w2, beta = 0.5, 0.5, 0.7
   ...:   tmp = x1 * w1 + x2 * w2
   ...:   if tmp <= beta:
   ...:     return 0
   ...:   elif tmp > beta:
   ...:     return 1
   ...: 
In [2]: print("AND(0, 0)={}, AND(1, 0)={}, AND(0, 1)={}, AND(1, 1)={}".format(AND(0, 0), AND(1, 0), AND(0, 1), AND(1, 1)))
AND(0, 0)=0, AND(1, 0)=0, AND(0, 1)=0, AND(1, 1)=1

직접하기

  1. NAND 게이트를 파이썬 함수로 구현해서 확인 해보세요. 여기서 \(w_1 = w_2 = -0.5\), \(\beta = -0.7\)을 사용해보고 가능한 다른 값들은 무엇이 있는지 생각해보세요.

  2. OR 게이트를 구현하기 위해 필요한 \(w_1, w_2, \beta\)을 결정하고 OR 함수를 작성 하세요.

벡터 표현

퍼셉트론을 다르게 표현하면 다음과 같습니다. 위 식 (1)에서 \(-\beta\)\(b\)로 표현한 것입니다.

\[\begin{split}y = \begin{cases} 0, & \text{if} \quad w_1 x_1 + w_2 x_2 + b <= 0 \\ 1, & \text{if} \quad w_1 x_1 + w_2 x_2 + b > 0 \end{cases}\end{split}\]

여기서 \(b\)는 입력 \(x_1, x_2\)이 모두 0일 때 퍼셉트론이 0으로부터 벗어난 정도를 나타낸다고 편향bias 이라고 합니다.

단순한 논리연산 퍼셉트론을 좌표평면 위에 기하적으로 표현하면 4개의 점을 분리하는 직선의 방정식을 찾는 문제와 같습니다. 이 직선은 벡터 \(\mathbf{w} = (w_1, w_2)\)에 수직인 직선이 됩니다.

또한 다음과 같이 3차원 공간 \((x, y, z)\)에서 표현하면 4점을 분리하는 평면의 방정식을 찾는 것과 같다고 할 수 있습니다.

\[z = w_1 x + w_2 y + b\]

\(z\)가 0보다 작거나 같으면 0을 반환하고 그렇지 않으면 1을 반환하는 알고리즘입니다. 즉 공간의 점 \((x,y,z)\)\(xy\) 평면 아래 있는 것과 위에 있는 것으로 분리하는 것과 마찬가지입니다.

넘파이를 이용해서 구현을 해봅니다.

In [5]: import numpy as np
   ...: x = np.array([0, 1])
   ...: w = np.array([0.5, 0.5])
   ...: b = -0.7
   ...: print(w * x)
   ...: print(np.sum(w * x))
   ...: print(np.sum(w * x) + b)
   ...: 
[0.  0.5]
0.5
-0.19999999999999996

두 벡터 \(w = (w_1, w_2)\), \(x = (x_1, x_2)\)의 성분끼리 곱 w * x을 한 후 b를 더하여 구한 것입니다.

이것을 이용해서 AND 게이트를 다시 구현해봅니다.

In [6]: def AND(x1, x2):
   ...:   x = np.array([x1, x2])
   ...:   w = np.array([0.5, 0.5])
   ...:   b = -0.7
   ...:   tmp = np.sum(w * x) + b
   ...:   if tmp <= 0:
   ...:     return 0
   ...:   elif tmp > 0:
   ...:     return 1
   ...: 

\(w_1, w_2\)는 입력 신호가 결과에 주는 영향력(중요도)을 조절하는 매개변수이고 편향은 뉴런이 얼마나 쉽게 활성화하느냐를 조정하는 매개변수입니다. 예를 들어 b-0.1이면 각 입력 신호에 가중치를 곱한 값들이 0.1을 초과할 때만 뉴런이 활성화됩니다. 반면 b-20.0이면 각 입력신호에 가중치를 곱한 값들의 합이 20.0을 넘지 않으면 뉴런은 활성화되지 않습니다. 이처럼 편향의 값은 뉴런(노드)이 얼마나 쉽게 활성화되는지를 결정합니다.

직접하기

  1. NAND 게이트를 넘파이 배열을 이용해서 구현하고 테스트 해보세요. \(w_1 = w_2 = -0.5\), \(b = 0.7\)을 사용하세요.

  2. OR 게이트를 넘파이 배열을 이용해서 구현하기 위한 \(w_1, w_2, b\)을 결정하고 OR 함수를 작성해서 확인해보세요.

다층 퍼셉트론

앞에서 봤던 퍼셉트론은 선형분리 가능한 문제에만 작동을 합니다. 다음과 같은 XOR 게이트 연산을 푸는데 사용할 수 없습니다.

XOR 게이트

XOR 게이트는 배타적 논리합(exclusive or)이라는 연산입니다.

XOR 게이트

\(x_1\)

\(x_2\)

\(y\)

0

0

0

1

0

1

0

1

1

1

1

0

_images/xor_gate.png

앞에서 봤던 퍼셉트론은 좌표 평면에서 직선으로 분리하는 방법이었습니다. 그러나 XOR 게이트는 어떤 직선으로도 세모와 동그라미를 분리할 수 없는 것을 알 수 있습니다. 따라서 퍼셉트론으로는 해결할 수 없는 문제가 됩니다.

하지만 퍼셉트론을 한 층 더 쌓으면 이 문제를 해결할 수 있습니다. 우선 논리 게이트 표시에 대해 알아봅니다.

_images/logic_gates.png

어떤 조합을 하면 XOR 게이트를 표현할 수 있을지를 생각해봅니다.

_images/xor_pre.png

NAND, OR, AND를 다음과 같이 조합하면 XOR 게이트를 완성할 수 있습니다.

_images/xor_solution.png

이것을 진리표로 나타내면 다음과 같습니다.

XOR(2층 퍼셉트론)

\(x_1\)

\(x_2\)

\(s_1(x_1\text{NAND}x_2)\)

\(s_2(x_1\text{OR}x_2)\)

\(y(s_1\text{AND}s_2)\)

0

0

1

0

0

1

0

1

1

1

0

1

1

1

1

1

1

0

1

0

XOR 게이트 구현

In [7]: def XOR(x1, x2):
   ...:   s1 = NAND(x1, x2)
   ...:   s2 = OR(x1, x2)
   ...:   y = AND(s1, s2)
   ...:   return y
   ...: 

실행해보면 다음과 같이 맞게 출력되는 것을 볼 수 있습니다.

In [8]: print(XOR(0, 0))
   ...: print(XOR(1, 0))
   ...: print(XOR(0, 1))
   ...: print(XOR(1, 1))
   ...: 
0
1
1
0

그림으로 나타내면 다음과 같습니다.

_images/xor_2layers.png

\(x_1, x_2\)를 입력층, NAND, OR 계산이 1층, AND 계산을 2층이라고 하며 다층 퍼셉트론이라고 합니다.

연습문제

  1. 다음 표를 만족하는 퍼셉트론을 구현해 보세요. 즉, 다음 식을 만족하는 \(w_1, w_2, b\)를 구해서 파이썬 함수로 만들어 보세요.

    \[\begin{split}y = \begin{cases} 0, & \text{if} \quad w_1 x_1 + w_2 x_2 + b <= 0 \\ 1, & \text{if} \quad w_1 x_1 + w_2 x_2 + b > 0 \end{cases}\end{split}\]

    \(x_1\)

    \(x_2\)

    \(y\)

    0

    0

    0

    -1

    0

    1

    -1

    1

    1

    0

    1

    1

  2. 다음 표를 만족하는 퍼셉트론을 구현해 보세요. 즉, 다음 식을 만족하는 \(w_1, w_2, b\)를 구해서 파이썬 함수로 만들어 보세요.

    \[\begin{split}y = \begin{cases} 0, & \text{if} \quad w_1 x_1 + w_2 x_2 + b <= 0 \\ 1, & \text{if} \quad w_1 x_1 + w_2 x_2 + b > 0 \end{cases}\end{split}\]

    \(x_1\)

    \(x_2\)

    \(y\)

    -1

    -1

    0

    -1

    1

    1

    1

    -1

    1

    1

    1

    1

  3. 다음 표를 만족하는 퍼셉트론이 가능한지를 판단하고, 가능하다면 다음 식을 만족하는 \(w_1, w_2, b\)를 구해서 파이썬 함수로 만들어 보세요.

    \[\begin{split}y = \begin{cases} -1, & \text{if} \quad w_1 x_1 + w_2 x_2 + b <= 1 \\ 1, & \text{if} \quad w_1 x_1 + w_2 x_2 + b > 1 \end{cases}\end{split}\]

    \(x_1\)

    \(x_2\)

    \(y\)

    0.3

    0.6

    -1

    0.5

    0.1

    1

    0.7

    2

    1

    1.2

    0.5

    1

연습문제 풀이