01. 퍼셉트론 - Perceptron
'밑바닥 부터 시작하는 딥러닝'교재로 공부한 것을 정리했습니다.
퍼셉트론 - Perceptron
퍼셉트론(perceptron)은 프랑크 로젠블라트(Fank Rosenblatt)가 1957년에 고안안 알고리즘이다. 이 퍼셉트론이 바로 신경망(딥러닝)의 기원이 되는 알고리즘이다.
퍼셉트론은 다수의 신호(흐름이 있는)를 입력으로 받아 하나의 신호를 출력한다. 퍼셉트론은 이 신호를 입력으로 받아 '흐른다/안 흐른다'(1 또는 0)이라는 정보를 앞으로 전달한다.
위의 그림에서,
과 는 입력 신호, 는 출력 신호, 과 는 가중치(weight)를 의미한다.
원을 뉴런 또는 노드라고 부른다.
입력 신호가 뉴런에 보내질 때는 각각 고유한 가중치가 곱해진다().
뉴런에서 전달 받은 신호의 총합이 임계값 를 넘을 때만 을 출력한다.
이것을 수식으로 나타내면, 아래와 같다.
퍼셉트론은 복수의 입력 신호 각각에 고유한 가중치를 부여한다. 가중치는 각 신호가 결과에 주는 영향력을 조절하는 요소로 작용하며, 가중치가 클수록 해당 신호가 그만큼 더 중요함을 뜻한다.
2. 단순한 논리 회로
2.1 AND 게이트
위의 표는 AND게이트
의 진리표이며 이 AND게이트를 퍼셉트론으로 표현해보자. 이를 위해서는 의 값을 적절하게 정해야 한다.
예를 들어,
일 때, AND 게이트의 조건을 만족한다.
2.2 NAND 게이트와 OR 게이트
NAND 게이트는 Not AND를 의미하며 AND 게이트의 출력을 반대로한 것과 같다.
OR 게이트는 입력 신호 중 하나 이상이 1이면 출력이 1이 되는 논리 회로다.
신경망 학습은 이 매개변수의 값을 정하는 작업을 컴퓨터가 자동으로 하도록 한다. 학습이란 적절한 매개변수 값을 정하는 작업 이며, 사람은 퍼셉트론의 구조(모델)를 고민하고 컴퓨터에 학습할 데이터를 주는 일을 한다.
위의 각 게이트(AND, NAND, OR)의 진리표들을 보면, 퍼셉트론 구조는 모두 동일하며 다른것은 매개변수()의 값뿐이다. 따라서, 매개변수의 값만 적절히 조정하면 AND, NAND, OR을 구현할 수 있다!
3. 퍼셉트론 구현하기
3.1 기본적인 AND gate
import numpy as np
def AND_basic(x1, x2):
w1, w2, theta = 0.5, 0.5, 0.7
tmp = x1*w1 + x2*w2
if tmp <= theta:
return 0
elif tmp > theta:
return 1
inputs = [(0, 0), (1, 0), (0, 1), (1, 1)]
for x1, x2 in inputs:
y = AND_basic(x1, x2)
print('({x1}, {x2}) -> {y}'.format(x1=x1, x2=x2, y=y))
(0, 0) -> 0
(1, 0) -> 0
(0, 1) -> 0
(1, 1) -> 1
3.2 가중치와 편향 도입
위 2.1의 식에서 를 로 치환하면 다음과 같다.
위의 식에서 를 편향(bias) 이라 한다.
편향이라는 용어는 ‘한쪽으로 치우쳐 균형을 깬다’라는 의미를 담고 있다. 실제로 위의 식에서 두 입력()이 모두 0이어도 결과로 (0이 아닌) 편향 값을 출력한다.
3.3 가중치와 편향 구현하기
가중치와 편향을 도입한 AND gate
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
else:
return 1
inputs = [(0, 0), (1, 0), (0, 1), (1, 1)]
for x1, x2 in inputs:
y = AND(x1, x2)
print('({x1}, {x2}) -> {y}'.format(x1=x1, x2=x2, y=y))
(0, 0) -> 0
(1, 0) -> 0
(0, 1) -> 0
(1, 1) -> 1
NAND 게이트와 OR 게이트
# NAND
def NAND(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
else:
return 1
# OR
def OR(x1, x2):
x = np.array([x1, x2])
w = np.array([0.5, 0.5])
b = -0.2
tmp = np.sum(w*x) + b
if tmp <= 0:
return 0
else:
return 1
inputs = [(0, 0), (1, 0), (0, 1), (1, 1)]
print('NAND :')
for x1, x2 in inputs:
y = NAND(x1, x2)
print('({x1}, {x2}) -> {y}'.format(x1=x1, x2=x2, y=y))
print('OR :')
for x1, x2 in inputs:
y = OR(x1, x2)
print('({x1}, {x2}) -> {y}'.format(x1=x1, x2=x2, y=y))
NAND :
(0, 0) -> 1
(1, 0) -> 1
(0, 1) -> 1
(1, 1) -> 0
OR :
(0, 0) -> 0
(1, 0) -> 1
(0, 1) -> 1
(1, 1) -> 1
4. 퍼셉트론의 한계
4.1 XOR 게이트
XOR 게이트는 베타적 논리합 이라는 논리 회로다.
단층 퍼셉트론으로 AND, NAND, OR 게이트는 구현 가능하지만, XOR 게이트는 구현할 수 없다. 퍼셉트론은 아래와 같이 직선 으로 나뉜 두 영역을 만든다. 하지만 XOR은 직선으로 두 영역을 나눌 수 없다.
4.2 선형과 비선형
만약 직선 즉, 선형이라는 제약을 없앤 비선형 이라면 아래와 같이 영역을 나눌 수 있다.
5. 다층 퍼셉트론
단층 퍼셉트론으로는 XOR을 구현할 수 없지만, 다층 퍼센트론(multi-layer perceptron) 으로 XOR 게이트를 구현할 수 있다.
를 각각 NAND
와 OR
게이트에 보낸다음, 그 결과 값들을 AND
게이트에 보내면 XOR
게이트를 구현할 수 있다.
5.1 기존 게이트 조합하기
5.2 XOR 게이트 구현하기
def XOR(x1, x2):
s1 = NAND(x1, x2)
s2 = OR(x1, x2)
y = AND(s1, s2)
return y
print('XOR :')
for x1, x2 in inputs:
y = XOR(x1, x2)
print('({x1}, {x2}) -> {y}'.format(x1=x1, x2=x2, y=y))
XOR :
(0, 0) -> 0
(1, 0) -> 1
(0, 1) -> 1
(1, 1) -> 0
6. 정리
퍼셉트론은 입출력을 갖춘 알고리즘이다. 입력을 주면 정해진 규칙에 따른 값을 출력한다.
퍼셉트론에서는 ‘가중치’와 ‘편향’을 매개변수로 설정한다.
퍼셉트론으로 AND, OR 게이트 등의 논리 회로를 표현할 수 있다.
XOR 게이트는 단층 퍼셉트론으로는 표현할 수 없다.
2층 퍼셉트론을 이용하면 XOR 게이트를 표현할 수 있다.
단층 퍼셉트론은 직선형 영역만 표현할 수 있고, 다층 퍼셉트론은 비선형 영역도 표현할 수 있다.