프로그래밍/DeepLearning

[밑바닥부터 시작하는 딥러닝 1] 2. 퍼셉트론, 논리 회로

자연대생 2023. 7. 13. 18:22

# 퍼셉트론

퍼셉트론은 인공 신경망의 기원이 되는 알고리즘이다.

퍼셉트론은 다수의 신호를 입력으로 받아 하나의 신호를 출력한다.

퍼셉트론 신호는 흐른다/안 흐른다(1이나 0)의 두 가지 값을 가질 수 있다.

이 책에서는 '신호가 흐른다'를 1, '신호가 흐르지 않는다'를 0으로 쓴다.

 

입력 신호 x가 뉴런에 보내질 땐 각각 고유한 가중치(weight)가 곱해진다. (w₁x₁, wx₂)

뉴런에서 보내온 신호의 총합이 정해진 한계를 넘어설 때만 1을 출력한다.

그 한계를 임계값이라고 하고, θ로 나타낸다.

이상을 수식으로 나타내면 아래와 같다.

 

# 단순한 논리회로

AND, NAND, OR 게이트를 진리표로 나타내었다.

AND 게이트

이 게이트를 퍼셉트론으로 표현하려면 w₁, w₂, θ를 설정하면 된다.

(w₁, w₂, θ) = (0.5, 0.5, 0.7)

(0.5, 0.5, 0.8), 

(1.0, 1.0, 1.0) 등등

매개변수를 이렇게 설정하면

x₁, x가 모두 1일 때 가중 신호의 총합이 주어진 임계값을 웃돌게 된다.

 

NAND 게이트

NAND는 Not AND를 의미한다.

(w₁, w₂, θ) = (-0.5, -0.5, -0.7) 등등

AND 게이트를 구현하는 매개변수의 부호만 모두 바꾸면 NAND 게이트가 된다.

 

OR 게이트

OR 게이트도 마찬가지로 퍼셉트론으로 구현할 수 있다.

 

# 퍼셉트론 구현하기

def AND(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
    
print(AND(0, 0))    # 0
print(AND(1, 0))    # 0
print(AND(0, 1))    # 0
print(AND(1, 1))    # 1

 

# 절편(bias, 편향) 도입

이전 식의 θ를 -b로 치환하면 위의 식이 된다.

b를 절편이라고 하자. (책에서는 편향이라고 했다.)

 

# 넘파이 배열로 논리 게이트를 표현해보자.

import numpy as np
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


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
    
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

 

# XOR 게이트

XOR 게이트

 

# 퍼셉트론의 시각화

OR 게이트의 시각화이다.

회색 영역이 0을 출력하는 영역이며, 전체 영역은 OR 게이트의 성질을 만족한다.

0을 동그라미, 1을 세모로 두었다.

OR 게이트를 만들려면 이 그림의 동그라미와 세모 모양을 직선으로 나누어야 한다.

위 그림의 직선은 모양들을 잘 나눈 것을 볼 수 있다.

이를 선형 영역이라고 한다.

 

XOR 게이트의 시각화이다.

동그라미와 세모를 한 직선으로 나눌 수 없다.

곡선이라면 가능하다.

이를 비선형 영역이라고 한다.

 

# 다층 퍼셉트론

퍼셉트론으로는 XOR 게이트를 표현할 수 없다.

다층 퍼셉트론을 사용해야 한다.

AND, NAND, OR 게이트 하나씩을 조합해 구현할 수 있다.

 

NAND의 출력을 s₁, OR의 출력을 s로 하여 만든 진리표이다.

 

def XOR(x1, x2):
    s1 = NAND(x1, x2)
    s2 = OR(x1, x2)
    y = AND(s1, s2)
    return y

print(XOR(0, 0))    # 0
print(XOR(1, 0))    # 1
print(XOR(0, 1))    # 1
print(XOR(1, 1))    # 0

XOR 게이트를 구현해보면 다음과 같다.