딥러닝 기초 부수기 - 퍼셉트론(perceptron)
딥러닝 기초 부수기 - 퍼셉트론(perceptron)
본 게시글은 한빛미디어 출판사의 '밑바닥부터 시작하는 딥러닝(저자: 사이토 고키)' 도서 내용을 바탕으로 작성하였습니다.
1. 서론
이번 글에서는 신경망(딥러닝)의 기원이 되는 퍼셉트론(perceptron)에 대해 정리해보겠다.
2. 퍼셉트론이란?
(1) 퍼셉트론(perceptron)
퍼셉트론은 다수의 신호를 입력받아 하나의 신호를 출력한다. 1957년 프랑크 로젠블라트(Frank Rosenblatt)가 고안한 신경망(딥러닝)의 기원이 되는 알고리즘이다. '신호가 흐른다'는 의미를 1로, '신호가 흐르지 않는다'는 의미를 0으로 표시한다.
(2) 퍼셉트론 동작 원리
x1과 x2는 입력 신호, y는 출력 신호, w1과 w2는 가중치, 원은 뉴런(노드)을 의미한다. 여기서 가중치는 각 신호가 결과에 주는 영향력을 조절한다. 가중치가 클수록 해당 신호가 그만큼 더 중요하다는 의미이다. 입력 신호가 뉴런에 보내질 때, w1*x1과 w2*x2 형태로 각각 고유한 가중치가 곱해진다. 뉴런에서 보내온 신호의 총합이 임계값(정해진 한계, θ)을 넘어설 때만 1을 출력한다.
(3) 퍼셉트론 수식
3. 단순한 논리 회로
퍼셉트론으로 AND, NAND, OR 논리 회로를 표현할 수 있다.
(1) AND 게이트
두 입력이 모두 1일 때만 1을 출력하고 그 외 경우에는 0을 출력한다.
(2) NAND 게이트
두 입력이 모두 1일 때만 0을 출력하고 그 외 경우에는 1을 출력한다.
(3) OR 게이트
입력 중 하나 이상이 1이면 1을 출력한다.
위 3개의 게이트에서 중요한 점은, 퍼셉트론 구조는 동일하다는 것이다. 다른 것은 매개변수(가중치, 임계값)의 값이다.
4. 퍼셉트론 구현
퍼셉트론을 파이썬(Python)으로 구현한 모습을 살펴보자.
(1) 간단한 구현
# AND 게이트 구현
def AND(x1, x2): # x1, x2 : 입력
w1, w2, theta = 0.5, 0.5, 0.7 # w1, w2 : 가중치 / theta : 임계값
tmp = x1*w1 + x2*w2 # tmp : 가중치를 곱한 입력의 총합
if tmp <= theta:
return 0
elif tmp > theta:
return 1
# AND 게이트 출력 결과
AND(0, 0) # 0을 출력
AND(1, 0) # 0을 출력
AND(0, 1) # 0을 출력
AND(1, 1) # 1을 출력
NAND 게이트, OR 게이트도 동일하게 구현할 수 있다. 다른 것은 w1, w2, theta의 값이다! 이렇게 구현하면 직관적이고 알기 쉽지만 편향(bias) 개념을 도입하여 구현을 수정할 수 있다.
(2) 가중치와 편향 도입
위에서 봤던 퍼셉트론 수식에서 θ를 -b로 치환하여 수식을 다시 정의할 수 있다. 기호 표기만 바꿨을 뿐 의미는 같다.
위 수식에서 b를 편향(bias)이라고 한다. 편향은 뉴런이 얼마나 쉽게 활성화(결과로 1을 출력)하느냐를 조정한다. 예를 들자면 b가 -0.1인 경우, 각 입력에 가중치를 곱한 값들의 합이 0.1을 넘어설 때만 뉴런이 활성화된다. 위 수식을 해석하자면 입력에 가중치를 곱한 값과 편향을 합하는데, 그 값이 0을 넘으면 1을 출력하고 넘지 않으면 0을 출력한다는 의미이다. 앞으로는 문맥에 따라 가중치와 편향을 모두 '가중치 매개변수'라고 지칭한다.
(3) 가중치와 편향 구현
# 가중치와 편향을 도입한 AND 게이트
import numpy as np
def AND(x1, x2):
x = np.array([x1, x2])
w = np.array([0.5, 0.5]) # 가중치 배열을 넘파이 배열로 변환
b = -0.7 # b : 편향
tmp = np.sum(w*x) + b
if tmp <= 0:
return 0
else:
return 1
# 가중치와 편향을 도입한 NAND 게이트
import numpy as np
def NAND(x1, x2):
x = np.array([x1, x2])
w = np.array([-0.5, -0.5]) # AND 게이트의 w(가중치)와 다르다.
b = 0.7 # AND 게이트의 b(편향)와 다르다.
tmp = np.sum(w*x) + b
if tmp <= 0:
return 0
else:
return 1
# 가중치와 편향을 도입한 OR 게이트
import numpy as np
def OR(x1, x2):
x = np.array([x1, x2])
w = np.array([0.5, 0.5]) # NAND 게이트의 w(가중치)와 다르다.
b = -0.2 # AND, NAND 게이트의 b(편향)와 다르다.
tmp = np.sum(w*x) + b
if tmp <= 0:
return 0
else:
return 1
3개 게이트의 차이는 가중치 매개변수(가중치, 편향)의 값이다!
5. 퍼셉트론의 한계
XOR 게이트를 보며 퍼셉트론의 한계에 대해 살펴보자.
(1) XOR 게이트
배타적 논리합이라는 논리 회로이다. 여기서 '배타적'은 자기 외에는 거부한다는 의미이다. 입력 중 한쪽이 1일 때만 1을 출력한다. XOR 게이트는 지금까지의 퍼셉트론으로는 구현이 불가하다. '(2) 선형과 비선형'에서 이유를 알아보자!
(2) 선형과 비선형
위 그림에서는 0을 원으로, 1을 삼각형으로 표시했다. 지금까지 본 퍼셉트론 수식은 직선으로 나뉜 두 영역(1을 출력하는 영역과 0을 출력하는 영역)을 만든다. AND, NAND, OR 게이트를 만들려면 그림에 보이는 원과 삼각형을 직선으로 나눠야 한다. 이때 직선의 영역을 선형 영역이라 한다.
XOR 게이트에서 원과 삼각형을 하나의 직선으로 나누는 것은 불가능하다! 이것이 XOR 게이트를 지금까지의 퍼셉트론으로 구현할 수 없는 이유이다.
하지만 직선이 아닌 곡선을 사용하면 XOR 게이트의 원과 삼각형을 나눌 수 있다! 이때 곡선의 영역을 비선형 영역이라 한다. 지금까지의 퍼셉트론으로는 곡선을 표현할 수 없지만, 다층 퍼셉트론으로는 표현할 수 있다!
6. 다층 퍼셉트론
지금까지 봤던 퍼셉트론은 층이 하나인 단층 퍼셉트론(single-layer perceptron)이다. 이번에는 층을 쌓아 만들 수 있는 다층 퍼셉트론(multi-layer perceptron)으로 XOR 게이트를 표현한 모습을 살펴볼 것이다. 다층 퍼셉트론 이전에, 기존 게이트를 조합하여 XOR 게이트를 구현한 모습을 먼저 봐보자.
(1) 기존 게이트 조합하기
(2) XOR 게이트 구현
# 기존 게이트를 조합하여 구현한 XOR 게이트
def XOR(x1, x2):
s1 = NAND(x1, x2)
s2 = OR(x1, x2)
y = AND(s1, s2) # NAND, OR 게이트의 출력이 AND 게이트의 입력으로 이어짐!
return y
# 기존 게이트를 조합하여 구현한 XOR 게이트 출력 결과
XOR(0, 0) # 0을 출력
XOR(1, 0) # 1을 출력
XOR(0, 1) # 1을 출력
XOR(1, 1) # 0을 출력
(3) XOR의 퍼셉트론
XOR은 2층 퍼셉트론이며, 층이 여러 개인 퍼셉트론을 다층 퍼셉트론(multi-layer perceptron)이라 한다. 위 그림의 퍼셉트론은 3층으로 구성되지만, 가중치를 갖는 층이 2개(0층~1층, 1층~2층)이므로 '2층 퍼셉트론'이라 부르자! 단, 문헌에 따라서는 층수를 기준으로 '3층 퍼셉트론'이라 하는 경우도 있다고 한다!
(4) XOR의 퍼셉트론 동작 방식
- 0층의 두 뉴런이 입력 신호를 받아 1층의 뉴런으로 신호를 보낸다.
- 신호를 받은 1층의 뉴런이 2층의 뉴런으로 신호를 보낸다.
- 신호를 받은 2층의 뉴런은 y를 출력한다.
다층 퍼셉트론 장점은 단층 퍼셉트론으로는 표현하지 못하는 것을 층을 늘려서 구현이 가능하다는 것이다!