728x90
반응형
지난 포스트에서 퍼셉트론을 이용해 대표적인 논리 게이트인 AND 게이트, NAND 게이트, OR 게이트를 구현해보았다. 이번 포스트에선 또 다른 대표적인 논리 게이트인 XOR 게이트를 구현해보자.
1. XOR 게이트
- XOR 게이트는 배타적(자기 자신을 제외하고 나머지는 거부한다.) 논리합이라는 회로로, 변수 중 단 하나만 True(참 = 1) 일 때, True(=1)을 반환한다.
- XOR 게이트의 진리표는 다음과 같다.
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
- 자, 위 진리표를 구현할 수 있는 가중치($w_1, w_2, b$)를 찾을 수 있는가?
$$ y = \begin{cases}
0, \ \ (w_1*0 + w_2*0 + b \leq 0) \\
1, \ \ (w_1*0 + w_2*1 + b \leq 0) \\
1, \ \ (w_1*1 + w_2*0 + b \leq 0) \\
0, \ \ (w_1*1 + w_2*1 + b > 0)
\end{cases} $$
- 위 공식에 들어 맞는 가중치를 찾는 것은 불가능하다.
- 그 이유는 앞서 말한 퍼셉트론 역시 회귀분석과 마찬가지로 선형성을 이용해서 0보다 크고, 작은 지를 구분해내기 때문이다.
- 위 말을 이해하기 쉽도록 위 진리표를 시각적으로 보자.
>>> import matplotlib.pyplot as plt
# 캔버스 설정
>>> fig = plt.figure(figsize=(8,8)) # 캔버스 생성
>>> fig.set_facecolor('white') # 캔버스 색상 설정
>>> plt.title('XOR Gate, Visualization of True table', fontsize = 25)
>>> plt.ylim(-1, 4)
>>> plt.xlim(-1, 4)
>>> plt.axhline(color = 'k', alpha = 0.5)
>>> plt.axvline(color = 'k', alpha = 0.5)
>>> plt.xlabel("x1", fontsize = 20)
>>> plt.ylabel("x2", fontsize = 20, rotation = 0)
>>> plt.scatter([0, 1], [0, 1], s = 200, c = "green", marker="v")
>>> plt.scatter([0, 1], [1, 0], s = 200, c = "blue", marker="s")
>>> plt.show()
- 위에서 퍼셉트론의 구분 방법은 선형성을 이용한다고 했다.
- 선형성을 이용한다는 소리는 위 그래프에서 선 하나(퍼셉트론)로 파란 네모 점과 녹색 세모 점을 구분할 수 있어야 한다는 소리다.
- 직선이 아닌 곡선을 사용하지 않는한, 그 어떠한 방법으로도 하나의 직선으로는 위 점을 서로 다른 2개의 집단으로 구분해낼 수 없다.
- 즉, 퍼셉트론 하나로는 논리 게이트의 구현이 불가능하다는 것이고, 이는 퍼셉트론 하나로는 컴퓨터 같은 고등 연산을 수행할 수 없다는 것이다!
2. XOR 게이트의 해결 방법
머리가 비상하게 좋은 친구라면(블로그 주인장은 그렇지 못하지만...), "앞서 만들었던 논리 게이트를 조합해서 이 문제를 해결할 수 있지 않을까?"라는 생각이 들지도 모른다.
우리는 앞에서 AND, NAND, OR 게이트를 만들어보았고, 이들을 조합해서 문제를 해결할 수는 없을까?
- 위 그림을 보면, NAND, OR, AND 논리 게이트를 조합하면 우리가 위에서 만들었던 XOR 진리표의 결과를 출력하는 것을 알 수 있다.
- $x_1, x_2$는 일정하며, 어떤 논리 게이트를 결정하느냐에 따라 가중치($w_1, w_2, b$)만 바뀐다.
- 반대로 말하면, 가중치만 다른 퍼셉트론을 조합해서 내가 원하는 기능을 얻을 수 있다는 것이다.
- 자, 위 그림을 코드로 구현해보자. 이번에는 조금 더 코드 친화적으로 Numpy의 array를 이용해서 짜 보겠다.
>>> import numpy as np
>>> def step_function(x):
>>> y = x > 0
>>> return y.astype(np.int)
>>> def Perceptron(x, dict_name, gate_name):
>>> weight = dict_name[gate_name]
>>> y = np.sum(x*weight['w']) + weight["b"]
>>> return step_function(y)
>>> def XOR_gate(x):
>>> array_x = np.array(x)
>>> dict_W = {"AND":{"w":[0.5,0.5], "b":-0.7},
>>> "NAND":{"w":[-0.5,-0.5], "b":0.7},
>>> "OR":{"w":[0.5,0.5], "b":-0.2}}
>>> y1 = Perceptron(array_x, dict_W, "NAND")
>>> y2 = Perceptron(array_x, dict_W, "OR")
>>> X = np.array([y1, y2])
>>> Y = Perceptron(X, dict_W, "AND")
>>> return step_function(Y)
>>> print("XOR Gate")
>>> print("----"*20)
>>> print("(0,0):", XOR_gate([0,0]))
>>> print("(0,1):", XOR_gate([0,1]))
>>> print("(1,0):", XOR_gate([1,0]))
>>> print("(1,1):", XOR_gate([1,1]))
XOR Gate
--------------------------------------------------------------------------------
(0,0): 0
(0,1): 1
(1,0): 1
(1,1): 0
- 위 코드에서 새롭게 ster_function()이라는 함수가 생겼는데, 이는 계단 함수로, 앞서 우리가 if문을 이용해서 합산된 결과가 0보다 클 때, 1을 반환하고, 0보다 작거나 같으면, 0을 반환하던 부분이다.
- 이를 활성화 함수(Activation Function)라 하는데, 활성화 함수를 통해 합산된 값을 출력할지, 출력한다면 어떻게 출력할지를 결정한다.
- 계단 함수는 이후 활성화 함수를 자세히 다룰 때, 다시 이야기하도록 하겠다.
- 위 코드를 보면, 오로지 가중치만 다른 퍼셉트론을 겹쳐서 사용했는데, XOR 게이트 문제를 해결한 것을 알 수 있다.
- 이렇게 2개 이상의 퍼셉트론을 쌓는 것을 다층 퍼셉트론이라고 한다.
3. 논리를 비약시켜보자.
- 위에서 우리는 2개 이상의 층(Layer)을 쌓아, 우리가 원하는 문제를 해결하였다.
- 이 곳에 사용된 층들은 오로지 가중치만 다르며, 이 가중치가 갖는 의미도 꽤 다르다.
- $w_1, w_2$ 같은 가중치는, 각 입력 신호에 부여되는 영향력(중요도)을 조절한다.
- $\theta$는 임계점이라 하였는데, 좌변으로 이항 시켜, $b$로 만들어주었고, 이는 편향(bias)라고 한다. 편향은 뉴런이 얼마나 쉽게 활성화되느냐에 영향을 미치며, $b$의 크기에 따라 활성화 함수가 작동하는지, 마는지가 결정된다.
- 지금까지 우리가 학습한 내용을 단순화시켜보면, 층을 많이 쌓고, 가중치를 맞게 설정해주면, 내가 원하는 결과를 얻을 수 있다는 것이다.
- 층을 많이 쌓는다는 것이 바로 우리가 아는 딥러닝(Deep Learning)의 딥(Deep)을 의미하며, 층이 많이 쌓인 신경망은 각 노드에서 다음 노드로 이동하는 신호에 부여하는 가중치를 다르게만 한다면, 구체적으로 함수 식을 모른다 할지라도 우리가 원하는 결과를 알 수 있다는 것이다.
- 그런데, 만약 그 가중치를 컴퓨터가 알아서 찾을 수 있다면 어떨까?
- 여기서 조금 어려워질지도 모르겠는데, 기계가 어떠한 방법(손실 함수)을 이용해서 가장 적합한 가중치를 찾아낸다면, 우리가 스스로 공부를 해서 어떤 결과를 도출하는 것처럼 컴퓨터도 적합한 가중치를 찾기 위한 활동, 즉! 학습과 동일하게 보이는 행동을 통해 데이터만 가지고 원하는 결과를 도출할 수 있다는 것이다.
- 여기서 "기계가 학습한다(Machine Learning)"이라는 말이 나오게 되는 것이며, 학습을 하되(가중치를 찾는 과정) 그것을 다층 레이어를 통해 찾아내는 것을 딥러닝(Deep Learning)이라 하게 되는 것이다.
이번 포스트에선 퍼셉트론을 이용해 머신러닝이라는 단어와 딥러닝이라는 단어가 어떻게 만들어졌는지를 학습해보았다. 다음 포스트에서는 짧게 짚고 넘어갔던 활성화 함수에 대해 학습해보자.
728x90
반응형
'Machine Learning > Deep Learning' 카테고리의 다른 글
딥러닝-3.2. 활성화함수(3)-소프트맥스 함수(Softmax) (0) | 2021.01.26 |
---|---|
딥러닝-3.1. 활성화함수(2)-시그모이드 함수(Sigmoid) (3) | 2021.01.25 |
딥러닝-3.0. 활성화함수(1)-계단함수와 선형함수 (4) | 2021.01.25 |
딥러닝-2.0. 퍼셉트론(1)-논리회로 (0) | 2021.01.23 |
딥러닝-1.0. 신경 세포와 퍼셉트론 (1) | 2021.01.22 |