본문 바로가기

딥러닝

퍼셉트론 - 신경망(딥러닝)의 기원이 되는 알고리즘

1. 퍼셉트론

1.1 퍼셉트론이란?

■ 퍼셉트론은 다수의 신호를 받아 하나의 신호를 출력하는 것이다.

- 여기서 신호는 '흐른다/안 흐른다 (1 이나 0)'의 두 가지 값을 가질 수 있다.

입력이 2개인 퍼셉트론

$x_{1}, x_{2}$는 입력 신호, y는 출력 신호, w는 가중치, 원은 뉴런 또는 노드라고 함

■ 퍼셉트론 동작 원리는 입력 신호($x_{1}, x_{2}$)가 출력 신호가 있는 노드(뉴런)으로 이동할 때, 입력 신호 $x_{1}, x_{2}$에 각각 가중치 $w_{1}, w_{2}$가 곱해진다.

- 입력 신호가 있는 노드에서 이동한 신호의 총합 $w_1x_1 + w_2x_2$이 임계값\( (\theta) \)을 넘으면 1을 출력하고, 그렇지 않으면 0을 출력한다.

- 이때 출력 노드로 이동하는 신호의 총합은 선형(일차)결합의 형태임을 알 수 있다. 즉, 가중치 w는 입력 신호가 출력 결과에 미치는 영향력을 조절하는 요인이므로 가중치가 클수록 해당 신호가 더 중요하다는 것을 의미한다.

■ 위의 동작원리를 수식으로 나타내면 \(y = \begin{cases} 0 & \text{if } w_1x_1 + w_2x_2 \leq \theta \\ 1 & \text{if } w_1x_1 + w_2x_2 > \theta \end{cases} \)

- 이때, 이렇게 주어진 입력 신호에 따라 특정한 출력을 내는 논리 회로를 게이트(gate)라고 한다.

 

1.2 논리회로

1.2.1 AND 게이트

■ AND 게이트는 입력 신호는 2개, 출력 신호는 1개이다 .

- AND 게이트의 진리표를 보면 두 입력이 모두 1일때만 1을, 그 외에는 0을 출력한다. 

(*진리표: 입력 신호와 출력 신호의 대응표)

$x_1$ $x_2$ $y$
0 0 0
1 0 0
0 1 0
1 1 1

■ AND 게이트를 파이썬에서 다음과 같이 구현할 수 있다.

def AND_GATE(x1, x2, w1, w2, theta):
    linear_c = x1*w1 + x2*w2
    if linear_c <= theta:
        return 0
    else:
        return 1

■ 학습 데이터의 허용 범위를 지정하는 편향(bias)라는 개념이 있다. 이 편향도 퍼셉트론의 입력값 중 하나로서 퍼셉트론의 출력값을 조절하는 역할을 한다. 

- 편향이 없으면 퍼셉트론은  $w_1x_1 + w_2x_2$이므로 입력값들의 가중치 합에만 의존하게 된다. 편향을 추가하게 되면 입력값이 전부 0이더라도 임곗값을 넘겨 출력을 1로 만들 수도 있다.

■ 이런 관점에서 편향과 가중치가 하는 역할이 비슷해 보일 수 있지만, 기능이 완전 다르다.

- 가중치는 입력값이 결과에 주는 영향력(중요도)을 조절하는 것이며, 편향은 결과가 1로 출력되게 영향을 미치는 매개변수이다.

- 예를 들어 $b = -0.1$이면 $w_1x_1 + w_2x_2$의 값이 0.1을 초과하면 결과를 1로 출력(뉴런이 활성화)된다.

- 반면, $b = -10$이면 $w_1x_1 + w_2x_2$의 값이 10을 초과히자 않으면 뉴런이 활성화되지 않는다.

- 편향은 위의 수식 \( \theta \)를 \( -b \)로 치환하면 되며, 이를 수식으로 나타내면

\[
y = \begin{cases} 
0 & \text{if } w_1x_1 + w_2x_2 \leq \theta \\ 
1 & \text{if } w_1x_1 + w_2x_2 > \theta 
\end{cases} 
\iff 
\begin{cases} 
\sum_{i=1}^{2} w_i x_i \leq \theta & \Rightarrow y = 0 \\ 
\sum_{i=1}^{2} w_i x_i > \theta & \Rightarrow y = 1 
\end{cases} 
\rightarrow 
\begin{cases} 
\sum_{i=1}^{2} w_i x_i + b \leq 0 & \Rightarrow y = 0 \\ 
\sum_{i=1}^{2} w_i x_i + b > 0 & \Rightarrow y = 1 
\end{cases} 
\iff y = \begin{cases} 
0 & \text{if } w_1x_1 + w_2x_2 + b \leq 0 \\ 
1 & \text{if } w_1x_1 + w_2x_2 + b > 0
\end{cases} 
\]
\[
y = \begin{cases} 
0 & \text{if } w_1x_1 + w_2x_2 + b \leq 0 \\ 
1 & \text{if } w_1x_1 + w_2x_2 + b > 0 
\end{cases}
\]
이 수식의 의미는 퍼셉트론이 입력값들과 그 입력값들의 가중치를 곱한 값에 편향을 더해 계산한 결과가 0을 넘으면 1을 출력, 그렇지 않으면 0을 출력한다는 의미를 갖는다.

■ 위의 식을 파이썬에서 구현하면 다음과 같다.

def AND_GATE(x1, x2, w1 = 0.5, w2 = 0.5, b = -0.7):
    X = np.array([x1, x2])
    W = np.array([w1, w2])
    C = np.sum(W*X) + b # 넘파이 곱셈은 두 배열의 원소의 수가 동일하면 각 원소끼리 곱셉을 계산
    if C <= 0:
        return 0
    else:
        return 1

AND_GATE(0, 0), AND_GATE(1, 0), AND_GATE(0, 1), AND_GATE(1, 1)
```#결과#```
(0, 0, 0, 1)
````````````

 

1.2.2 NAND 게이트

 

NAND 게이트는 Not AND 게이트이다. 즉 AND 게이트와 반대로 x1, x2가 모두 1이면 0을, 그 외에는 1을 출력한다.다음 표는 NAND 게이트의 진리표이다.

$x_1$ $x_2$ $y$
0 0 1
1 0 1
0 1 1
1 1 0

■ NAND 게이트를 파이썬에서 구현하면 다음과 같다.

def NAND_GATE(x1, x2, w1 = -0.5, w2 = -0.5, b = 0.7):
    X = np.array([x1, x2])
    W = np.array([w1, w2])
    C = np.sum(W*X)+ b
    if C <= 0:
        return 0
    else:
        return 1
        
NAND_GATE(0, 0), NAND_GATE(1, 0), NAND_GATE(0, 1), NAND_GATE(1, 1)
```#결과#```
(1, 1, 1, 0)
````````````

 

1.2.3 OR 게이트

■ OR 게이트는 입력 신호 중 적어도 하나가 1이면 1을 출력한다. 다음 표는 OR 게이트의 진리표이다.

$x_1$ $x_2$ $y$
0 0 0
1 0 1
0 1 1
1 1 1

■ OR 게이트를 파이썬에서 구현하면 다음과 같다.

def OR_GATE(x1, x2, w1 = 0.5, w2 = 0.5, b = -0.2):
    X = np.array([x1, x2])
    W = np.array([w1, w2])
    C = np.sum(W*X) + b
    if C <= 0:
        return 0
    else:
        return 1

OR_GATE(0, 0), OR_GATE(1, 0), OR_GATE(0, 1), OR_GATE(1, 1)
```#결과#```
(0, 1, 1, 1)
````````````

NAND와 OR 게이트는 앞서 구현한 ADD_GATE 함수의 가중치와 편향 값만 다르게 입력하여 구할 수 있다.

이렇게 퍼셉트론은 AND, NAND, OR 게이트로 표현할 수 있고, AND, NAND, OR 게이트는 코드로 구현하였을 때를 보면 모두 같은 구조의 퍼셉트론임을 알 수 있다.

 

1.3 (단층) 퍼셉트론의 한계

■ 결론부터 얘기하자면 위와 같은 단층 퍼셉트론을 이용하면 AND, NAND, OR 논리 게이트를 구현할 수 있다.

그러나 XOR 게이트의 경우 퍼셉트론으로 구현할 수 없다. 입력값의 조합인 (x1, x2)를 한 직선으로 구분할 수 없기 때문이다.

■ XOR 게이트는 x1, x2 중 한쪽이 1일 때만 1을 출력하는 배타적 논리합이라는 논리 게이트이다.

XOR 게이트의 진리표는 다음과 같다.

$x_1$ $x_2$ $y$
0 0 0
1 0 1
0 1 1
1 1 0

사실, 진리표만 봐도 직선으로 구분이 불가하다는 것을 알 수 있다. (x1, x2) = (0, 0), (1, 1)일 때 0을 출력하는데, (x1, x2) = (1.0), (0, 1)이면 1을 출력하기 때문이다.

■ 예를 들어 \( w_1 = w_2 = 1, b = -0.5 \)인 OR 게이트를 식으로 나타내면 다음과 같다.

\[
y = \begin{cases} 
0 & \text{if } x_1 + x_2 - 0.5 \leq 0 \\ 
1 & \text{if } x_1 + x_2 - 0.5 > 0 
\end{cases}
\]

- 즉, 좌표 평면에서 $ x_1 + x_2 = 0.5$라는 직선으로 두 영역을 나누는 것으로 해석할 수 있다.

- $ x_1 + x_2 > 0.5$인 영역은 1을 출력(<=> y = 1), $ x_1 + x_2 ≤ 0.5$인 영역은 0을 출력(<=> y = 0)하는 것이다.

- OR 게이트의 진리표를 생각해보면 $ x_1, x_2$ 한쪽이 1인 경우 1을 출력하므로 (x1, x2) = (0, 0)이면 0,

(x1, x2) = (1, 0), (0, 1), (1, 1)이면 1을 출력한다. 따라서 다음과 같이 직선으로 0과 1을 분리할 수 있지만

XOR 게이트를 OR 게이트처럼 0과 1을 직선으로 나누는 것은 어렵기 때문에 0과 1을 나누려면 다음과 같이 곡선을 이용해 나눠야 한다. 

- 여기서 단층 퍼셉트론의 한계가 드러난다. 바로 퍼셉트론은 직선 하나로 나눈 영역만 표현할 수 있다는 점이다. 따라서 위의 그림과 같이 곡선으로 영역을 나눌 수 없다는 것이다.

- 이때 OR 게이트의 좌표평면에서의 그림과 같이 직선의 영역을 선형, 위의 XOR 그림 같이 곡선 영역을 비선형이라 한다.

 

1.4 다층 퍼셉트론

참고) MLP

■ 사실 XOR은 단층 퍼셉트론에 층을 하나 더 만들어서 XOR을 표현할 수 있다. 이렇게 층을 만드는 퍼셉트론을 다층 퍼셉트론(multi layer perceptron)이라 한다.

■ 층을 하나 더 쌓아 XOR을 만드는 방법 중에 많이 알려진 방법으로 AND, NAND, OR 게이트를 조합하여 XOR 게이트를 만드는 방법이 있다.

- 이 방법은 $ x_1, x_2$가 NAND와 OR 게이트의 입력으로 들어오고, NAND와 OR의 출력이 AND의 입력이 되게 하는 것이다.

- NAND의 출력을 n, OR의 출력을 o라고 하면 다음과 같이 나타낼 수 있다. 

- 이 구조의 진리표를 만들면 다음과 같다.

$ x_1$ $ x_2$ n (NAND) o (OR)     n o $ y$ (n과 o의 AND 게이트)
0 0 1 0     1 0 0
1 0 1 1     1 1 1
0 1 1 1     1 1 1
1 1 0 1     0 1 0

여기서 $ x_1, x_2$ 그리고 결과인 y를 보면 XOR 진리표에서 본 y와 동일하다는 것을 확인할 수 있다.

■ 또한 XOR의 퍼셉트론과 입력이 2개인 퍼셉트론의 구조를 비교해 보면

XOR 퍼셉트론의 층이 하나 더 있는 것을 알 수 있다. 

- 이처럼 AND, OR 같이 층이 1층이면 단층 퍼셉트론, XOR처럼 층이 여러 개를 가지는 퍼셉트론을 다층 퍼셉트론이라 한다.

- 또한 위에서 언급한 것처럼 'XOR은 비선형으로 영역을 나눌 수 있다'는 것을 확인하였는데, 이를 통해 알 수 있는 것은 

'여러 개의 층을 가지는 다층 퍼셉트론은 비선형으로 영역을 나눌 수 있다'라는 점이다. 즉, 단층 퍼셉트론으로 표현하지 못하는 경우 층을 쌓아 다층 퍼셉트론으로 구현할 수 있다는 것이다.

■ XOR 게이트는 AND, NAND, OR을 조합해 구현할 수 있다. 따라서 파이썬에서도 앞서 정의한 AND, NAND, OR 게이트 함수를 조합하여 XOR을 구현하면 된다.

def XOR_GATE(x1, x2):
    n = NAND_GATE(x1, x2) # n은 x1, x2를 입력값으로 하는 NAND의 출력
    o = OR_GATE(x1, x2) # o는 x1, x2를 입력값으로 하는 OR의 출력
    y = AND_GATE(n, o) # 결과인 y는 n, o를 입력값으로 하는 AND의 출력
    return y

XOR_GATE(0, 0), XOR_GATE(1, 0), XOR_GATE(0, 1), XOR_GATE(1, 1)
```#결과#```
(0, 1, 1, 0)
````````````

'딥러닝' 카테고리의 다른 글

오차역전파 (3)  (0) 2024.09.24
신경망 학습(2)  (1) 2024.09.13
신경망 학습(1)  (1) 2024.09.12
신경망 (2)  (0) 2024.09.05
신경망(1)  (0) 2024.08.30