Home > Study > Linux > Day3 : Perceptron

Day3 : Perceptron
Study Language

Report : Perceptron


1. 퍼셉트론이란?

  • 생물학적 뉴런을 모방한 가장 기본적인 인공신경망
  • 입력 값 × 가중치 + 바이어스를 통해 선형결합을 만들고, 단위 계단 함수(step function) 로 0 또는 1을 출력
  • 간단한 구조지만, 선형 분리 가능한 문제는 완벽하게 해결할 수 있음

하나의 직선으로 나눌 수 있으면 → 선형 분리 가능
단위 계산 함수 : 입력값이 0보다 크면 1을 출력하고, 그 외엔 0을 출력하는 함수


2. 퍼셉트론 학습 방식 (코드 중심)

# AND & OR & NAND & XOR Gate Perceptron
import numpy as np
import matplotlib.pyplot as plt

class Perceptron:
    def __init__(self, input_size, lr=0.1, epochs=10):
        self.weights = np.zeros(input_size)
        self.bias = 0
        self.lr = lr
        self.epochs = epochs
        self.errors = []

    def activation(self, x):
        return np.where(x > 0, 1, 0)

    def predict(self, x):
        linear_output = np.dot(x, self.weights) + self.bias
        return self.activation(linear_output)

    def train(self, X, y):
        for epoch in range(self.epochs):
            total_error = 0
            for xi, target in zip(X, y):
                prediction = self.predict(xi)
                update = self.lr * (target - prediction)
                self.weights += update * xi
                self.bias += update
                total_error += int(update != 0.0)
            self.errors.append(total_error)
            print(f"Epoch {epoch+1}/{self.epochs}, Errors: {total_error}")

# AND 게이트 데이터 및 학습
X_and = np.array([[0,0],[0,1],[1,0],[1,1]])
y_and = np.array([0,0,0,1])

print(" AND Gate Training")
ppn_and = Perceptron(input_size=2)
ppn_and.train(X_and, y_and)

print("\n AND Gate Test:")
for x in X_and:
    print(f"Input: {x}, Predicted Output: {ppn_and.predict(x)}")

# OR 게이트 데이터 및 학습
X_or = np.array([[0,0],[0,1],[1,0],[1,1]])
y_or = np.array([0,1,1,1])

print("\n OR Gate Training")
ppn_or = Perceptron(input_size=2)
ppn_or.train(X_or, y_or)

print("\n OR Gate Test:")
for x in X_or:
    print(f"Input: {x}, Predicted Output: {ppn_or.predict(x)}")

# NAND 게이트 데이터 및 학습
X_nand = np.array([[0,0],[0,1],[1,0],[1,1]])
y_nand = np.array([1,1,1,0])  # AND와 반대

print("\n NAND Gate Training")
ppn_nand = Perceptron(input_size=2)
ppn_nand.train(X_nand, y_nand)

print("\n NAND Gate Test:")
for x in X_nand:
    print(f"Input: {x}, Predicted Output: {ppn_nand.predict(x)}")

# XOR 게이트 데이터 및 학습
X_xor = np.array([[0,0],[0,1],[1,0],[1,1]])
y_xor = np.array([0,1,1,0])  # 선형 분리 불가능

print("\n XOR Gate Training")
ppn_xor = Perceptron(input_size=2)
ppn_xor.train(X_xor, y_xor)

print("\n XOR Gate Test:")
for x in X_xor:
    print(f"Input: {x}, Predicted Output: {ppn_xor.predict(x)}")

2-1. train() 함수 호출

ppn_and.train(X_and, y_and)
  • X_and: 입력 데이터 배열 (예: [0,0], [1,1] 등)
  • y_and: 각 입력에 대한 정답 출력값

2-2. 전체 반복 (epoch) 시작

for epoch in range(self.epochs):  # 총 10번 반복
  • 한 epoch는 전체 데이터를 한 번 학습하는 주기
  • 총 10번 반복하면서 조금씩 가중치를 조정

2-3. 한 epoch 내 샘플 반복

for xi, target in zip(X, y):
  • 각 데이터 xi와 정답 target을 하나씩 꺼내 순차 학습

2-4. 예측 과정

prediction = self.predict(xi)
  • predict() 내부에서 다음 순서로 작동:
    • linear_output = w·x + b
    • activation() → 0 또는 1 반환

2-5. 오차 계산 및 가중치/바이어스 업데이트

update = self.lr * (target - prediction)
  • 예측이 정답보다 작으면 → update > 0: 가중치 증가
  • 예측이 정답보다 크면 → update < 0: 가중치 감소
  • 예측이 정확하면 → update == 0: 가중치 변화 없음
self.weights += update * xi
self.bias += update
  • 각 입력 값에 따라 가중치 조정
  • 항상 바이어스도 같이 업데이트

2-6. 에러 카운트

total_error += int(update != 0.0)
  • 예측이 틀렸을 때만 에러로 집계

2-7. 학습 결과 출력

self.errors.append(total_error)
print(f"Epoch {epoch+1}/{self.epochs}, Errors: {total_error}")
  • 학습이 진행될수록 Errors가 줄어드는지 확인 가능
  • 하지만 XOR은 줄지 않음 → 선형 분리 불가능 문제

2-8. 최종 예측 결과 확인

  • 각 게이트에 대해 학습이 끝나면 다음을 수행:
for x in X_and:
    print(f"Input: {x}, Predicted Output: {ppn_and.predict(x)}")
  • 학습된 가중치로 새로운 입력을 테스트해보는 과정

2-9. 요약: 퍼셉트론 학습 흐름

입력 X, 정답 y
→ 가중합 계산 (w·x + b)
→ 계단 함수로 예측
→ 오차 계산 (target - predict)
→ w, b 업데이트
→ 에러 기록
→ epoch 반복
→ 학습 완료 후 테스트

3. XOR 게이트가 퍼셉트론으로 안 되는 이유

  • 퍼셉트론은 직선 하나로 출력을 나누는 모델
  • XOR은 어떤 직선으로도 0과 1을 나눌 수 없음
  • 즉, 선형 분리 불가능 문제 → 퍼셉트론 한계

해결책: 다층 퍼셉트론 (MLP)
비선형성을 처리하기 위해 은닉층 + 비선형 활성화 함수 (예: sigmoid, ReLU)를 활용하고,
오차 역전파(Backpropagation)로 학습함