퍼셉트론

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

신경세포와 인공 뉴런

_images/neuron.png

뉴런

인간의 뇌에는 수십억 개 이상의 뉴런이 있습니다. 뉴런은 화학 및 전기적 신호를 처리하고 전달하는 데 관여하는 인간의 뇌에서 서로 연결된 신경 세포입니다. 가지돌기 dendrite는 다른 뉴런으로부터 정보를 받아 세포체 cell body를 거쳐 축삭 axon을 통해서 다른 뉴런으로 신호를 보냅니다.

생물학적 뉴런 대 인공 뉴런

_images/diagram-for-general-view-of-artificial-neuron_2.jpg

인공뉴런

생물학적 뉴런은 다음 표에서와 같이 인공 뉴런과 비슷합니다.

생물학적 뉴런 대 인공 뉴런 1

생물학적 뉴런

인공 뉴런

세포체(cell body)

노드(node)

가지돌기(dedrite)

입력(input)

시냅스(synapse)

가중치(weight)

축삭(axon)

출력(output)

퍼셉트론 개념

퍼셉트론은 로젠 블렛이 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}\]

여기서 \(a = w_1 x_1 + w_2 x_2 + \cdots + w_d x_d\)입니다. 다음은 \(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 함수를 작성해서 확인해보세요.

퍼셉트론 학습 알고리즘

보조정리1

\(\mathbf{w}_1 = \mathbf{w}_0 + \mathbf{x}\) 이고 이루는 각은 각각

\[\cos \theta_0 = \frac{\mathbf{w}_0 \cdot \mathbf{x}}{\| \mathbf{w}_0 \| \| \mathbf{x} \|}, \quad \cos \theta_1 = \frac{\mathbf{w}_1 \cdot \mathbf{x}}{\| \mathbf{w}_1 \| \| \mathbf{x} \|}\]

일 때

\[\cos \theta_0 \le \cos \theta_1\]

입니다. 즉, \(\theta_0 \ge \theta_1\) 을 만족합니다.

증명:

비교를 위해서 분모를 통일합니다.

\[\begin{split}\cos \theta_0 &= \frac{\mathbf{w}_0 \cdot \mathbf{x}}{\| \mathbf{w}_0 \| \| \mathbf{x} \|} \\ &= \frac{(\mathbf{w}_0 \cdot \mathbf{x}) \| \mathbf{w}_0 + \mathbf{x} \|}{\| \mathbf{w}_0 \| \| \mathbf{x} \| \| \mathbf{w}_0 + \mathbf{x} \|},\end{split}\]
\[\begin{split}\cos \theta_1 &= \frac{\mathbf{w}_1 \cdot \mathbf{x}}{\| \mathbf{w}_1 \| \| \mathbf{x} \|} \\ &= \frac{(\mathbf{w}_0 + \mathbf{x}) \cdot \mathbf{x}}{\| \mathbf{w}_0 + \mathbf{x} \| \| \mathbf{x} \|} \\ &= \frac{(\mathbf{w}_0 + \mathbf{x}) \cdot \mathbf{x} \| \mathbf{w}_0 \|}{\| \mathbf{w}_0 + \mathbf{x} \| \| \mathbf{x} \| \| \mathbf{w}_0 \|} \\ &= \frac{(\mathbf{w}_0 \cdot \mathbf{x}) \| \mathbf{w}_0 \| + \| \mathbf{x} \|^2 \| \mathbf{w}_0 \|}{\| \mathbf{w}_0 + \mathbf{x} \| \| \mathbf{x} \| \| \mathbf{w}_0 \|}\end{split}\]

분자를 비교해 봅니다.

\[\begin{split}(\mathbf{w}_0 \cdot \mathbf{x}) \| \mathbf{w}_0 + \mathbf{x} \| & \le (\mathbf{w}_0 \cdot \mathbf{x}) (\| \mathbf{w}_0 \| + \| \mathbf{x} \|) \\ &= (\mathbf{w}_0 \cdot \mathbf{x}) \| \mathbf{w}_0 \| + (\mathbf{w}_0 \cdot \mathbf{x}) \| \mathbf{x} \| \\ &= (\mathbf{w}_0 \cdot \mathbf{x}) \| \mathbf{w}_0 \| + \| \mathbf{w}_0 \| \| \mathbf{x} \|^2\end{split}\]

따라서

\[\cos \theta_0 \le \cos \theta_1\]

보조정리2

\(\mathbf{w}_n = \mathbf{w}_{n-1} + \mathbf{x} = \mathbf{w}_0 + n \mathbf{x}\) 라고 가정하고

\[\cos \theta_n = \frac{\mathbf{w}_n \cdot \mathbf{x}}{\| \mathbf{w}_n \| \| \mathbf{x} \|}\]

일 때

\[\lim_{n \to \infty} \cos \theta_n = 1\]

을 만족합니다. 즉, 두 벡터 \(\mathbf{w}_n\)\(\mathbf{x}\) 가 이루는 각은 \(0\) 으로 수렴합니다.

증명:

\[\begin{split}\cos \theta_n &= \frac{\mathbf{w}_n \cdot \mathbf{x}}{\| \mathbf{w}_n \| \| \mathbf{x} \|} \\ &= \frac{(\mathbf{w}_0 + n \mathbf{x}) \cdot \mathbf{x}}{\| \mathbf{w}_0 + n \mathbf{x} \| \| \mathbf{x} \|} \\ &= \frac{n \left( \dfrac{\mathbf{w}_0}{n} + \mathbf{x} \right) \cdot \mathbf{x}}{n \left\Vert \dfrac{\mathbf{w}_0}{n} + \mathbf{x} \right\Vert \| \mathbf{x} \|} \\ &\to \frac{\| \mathbf{x} \|^2}{\| \mathbf{x} \|^2} = 1 \quad \text{as} \quad n \to \infty\end{split}\]

따라서 \(\theta_n \to 0\) 으로 수렴합니다.

퍼셉트론 의사 알고리즘

_images/perceptron_algo.png

퍼셉트론 의사 알고리즘

퍼셉트론 학습 알고리즘 수렴 증명 2

데이터 집합이 선형으로 분리가능하면 유한번 업데이트를 해서 분리 가능한 초평면 hyperplane을 찾을 수 있습니다.

분리가능하다는 가정에 의해서 모든 \((\mathbf{x}_i , y_i) \in D\)에 대해서 \(y_i(\mathbf{x}^T \mathbf{w}^{\ast})\)를 만족하는 초평면 \(\mathbf{w}^{\ast}\) 이 존재한다는 가정을 합니다.

각 데이터 \(\mathbf{x}_i\)를 단위구 내부로 조정하고(가장 큰 벡터의 크기로 나눕니다), \(\mathbf{w}^{\ast}\) 는 단위 벡터를 만족한다고 가정합니다.

\[\| \mathbf{w}^{\ast} \| = 1 \quad \text{이고} \quad \| \mathbf{x}_i \| \le 1 \quad \forall \mathbf{x}_i \in D\]

초평면과 가장 짧은 거리인 \(\gamma = \min_{(\mathbf{x}_i, y_i) \in D} |\mathbf{x}_i^T \mathbf{w}^{\ast}|\) 를 정의합니다. \(\gamma\)가 초평면과의 가장 작은 거리가 되는 이유는 단위벡터 \(\mathbf{w}^{\ast}\) 와 어떤 벡터와 내적한 값의 절대값은 단위벡터에 정사영된 벡터의 크기이기 때문입니다.

_images/perceptron_gamma.png

초평면과 간격

정리하면 다음과 같은 것을 만족합니다.

  • 모든 입력 \(\mathbf{x}_i\) 는 단위구 안에 있습니다.

  • \(\| \mathbf{w}^{\ast} \| = 1\) 을 만족하는 초평면 \(\mathbf{w}^{\ast}\) 가 존재합니다.

  • \(\gamma\) 는 초평면으로부터 가장 가까운 데이터 까지의 거리입니다.

정리: 위 조건을 만족하면, 퍼셉트론 학습 알고리즘은 \(1/\gamma^2\) 번 업데이트 안에 데이터를 분리하는 초평면을 찾을 수 있습니다.

증명:

\(\mathbf{w}^T \mathbf{w}^{\ast}\)\(\mathbf{w}^T \mathbf{w}\) 의 성질을 관찰함으로 증명을 합니다. 퍼셉트론 학습 알고리즘에 의해서 \(\mathbf{w}\)\(\mathbf{w} + y\mathbf{x}\)로 업데이트가 됩니다. 다음 두 가지 사실을 이용합니다.

  • \(y(\mathbf{x}^T \mathbf{w}) \le 0\): \(\mathbf{x}\) 는 잘못 분류되었다고 간주합니다.

  • \(y(\mathbf{x}^T \mathbf{w}^{\ast}) > 0\): 모든 데이터는 \(\mathbf{w}^{\ast}\)에 의해서 올바르게 분류된다고 간주합니다.

  1. \(\mathbf{w}^T \mathbf{w}^{\ast}\) 에 대한 업데이트

    \[(\mathbf{w} + y \mathbf{x})^T \mathbf{w}^{\ast} = \mathbf{w}^T \mathbf{w}^{\ast} + y(\mathbf{x}^T \mathbf{w}^{\ast}) \ge \mathbf{w}^T \mathbf{w}^{\ast} + \gamma\]

    왜냐면 \(y(\mathbf{x}^T \mathbf{w}^{\ast}) = |\mathbf{x}^T \mathbf{w}^{\ast}| \ge \gamma\) 이기 때문입니다.

    이것으로부터 \(\mathbf{w}^T \mathbf{w}^{\ast}\) 업데이트는 이전보다 적어도 \(\gamma\) 보다 크거나 같은 양만큼 커집니다.

  2. \(\mathbf{w}^T \mathbf{w}\) 에 대한 업데이트

    \[(\mathbf{w} + y \mathbf{x})^T (\mathbf{w} + y \mathbf{x}) = \mathbf{w}^T \mathbf{w} + 2y(\mathbf{w}^T \mathbf{x}) + y^2 (\mathbf{x}^T \mathbf{x}) \le \mathbf{w}^T \mathbf{w} + 1\]
    • \(2y(\mathbf{w}^T \mathbf{x}) < 0\) 입니다. 왜냐면 \(\mathbf{x}\)는 잘못된 분류이기 때문입니다.

    • \(0 \le y^2 (\mathbf{x}^T \mathbf{x}) \le 1\) 입니다. 왜냐면 \(y^2 = 1\) 이고 \(\| \mathbf{x} \| \le 1\) 이기 때문입니다.

    이것으로부터 \(\mathbf{w}^T \mathbf{w}\) 업데이트는 이전보다 1보다 작거나 같은 양만큼 커집니다.

  3. \(M\) 업데이트를 한 후에는 다음 식이 만족됩니다.

    1. \(\mathbf{w}^T \mathbf{w}^{\ast} \ge M \gamma\)

    2. \(\mathbf{w}^T \mathbf{w} \le M\)

    따라서 다음과 같이 증명이 완성됩니다.

    \[\begin{split}M \gamma & \le \mathbf{w}^T \mathbf{w} & \quad \text{by (a)} \\ & = \| \mathbf{w} \| \cos (\theta) & \quad \text{내적} \\ & \le \| \mathbf{w} \| \\ & = \sqrt{\mathbf{w}^T \mathbf{w}} \\ & \le \sqrt{M} \\ \\ & \Rightarrow M \gamma \le \sqrt{M} \\ & \Rightarrow M^2 \gamma^2 \le M \\ & \Rightarrow M \le \frac{1}{\gamma^2}\end{split}\]

다층 퍼셉트론

앞에서 봤던 퍼셉트론은 선형분리 가능한 문제에만 작동을 합니다. 다음과 같은 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

https://www.simplilearn.com/tutorials/deep-learning-tutorial/perceptron

2

https://www.cs.cornell.edu/courses/cs4780/2018fa/lectures/lecturenote03.html

연습문제

  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

  4. 퍼셉트론 의사 알고리즘을 구현하세요.

연습문제 풀이