직접 만들 수 있는 가장 작은 뇌: 파이썬 퍼셉트론
출처: Hacker News
퍼셉트론은 만들 수 있는 가장 작은 뇌입니다. 하나의 숫자가 들어가고, 하나의 예/아니오 답이 나옵니다. 그것이 전부입니다.
너무 단순해서 의미가 없을 것처럼 들리지만, 이 작은 아이디어가 오늘날 실행되는 모든 신경망의 씨앗이 됩니다. 이 글에서는 파이썬으로 퍼셉트론을 처음부터 직접 구현하고, 브라우저에서 실시간으로 학습하는 모습을 보여줍니다. 복잡한 수학도, 거대한 라이브러리도 필요 없습니다. 가중치와 편향, 그리고 반복문만 있으면 됩니다.
저는 원어민이 아니며, 아직도 이 분야를 배우고 있는 중입니다. 그래서 제가 누군가에게 설명을 들을 때 필요했던 방식대로, 천천히, 기초부터 설명하겠습니다.
퍼셉트론이란?
1958년, 프랭크 로젠블랫(Frank Rosenblatt)이라는 연구자가 퍼셉트론이라는 기계를 만들었습니다.
이는 하나의 뇌세포, 즉 뉴런에서 영감을 받았습니다. 뉴런은 신호를 받아들이고, 그 신호가 충분히 강하면 발화합니다. 로젠블랫은 이 아이디어를 수학으로 옮겼습니다:
output = 1 if (w · x + b) > 0
0 otherwise
여기서 x는 입력, w는 가중치, b는 편향입니다. 아직은 이 용어들에 신경 쓰지 마세요. 실제로 무언가를 만들면서 하나씩 만나게 될 겁니다.
먼저 인간처럼 생각해 보기
기계가 결정을 내리기 전에, 인간이 어떻게 결정을 내리는지 살펴봅시다. 존 도(John Doe)를 만나보세요. 그는 직업 제안을 받았고, 하나의 질문에 답해야 합니다: “이 제안을 받아들여야 할까?”
존은 동전을 던지지 않습니다. 그는 여러 요소를 저울질합니다. 어떤 요소는 다른 요소보다 더 중요합니다.
| 요소 (입력) | 값 | 존이 얼마나 신경 쓰는가 (가중치) |
|---|---|---|
| 추가 급여 | 높음 | 많이 |
| 같은 도시에 머무름 | 아니오, 이사해야 함 | 많이 |
존은 각 요소에 자신이 얼마나 신경 쓰는지를 곱한 뒤, 모두 더합니다. 그 합이 충분히 크면 “예”라고 답하고, 그렇지 않으면 “아니오”라고 답합니다.
이것이 바로 퍼셉트론입니다. 요소들은 입력이고, 존이 얼마나 신경 쓰는지는 가중치이며, “충분히 크다”는 기준은 그의 머릿속에 있는 편향(threshold)입니다. 나중에 이 편향을 ‘bias’라고 부르겠습니다.
퍼셉트론을 뉴런으로 그린 그림
두 개의 입력, Pay와 Same city, 각각 가중치와 곱해지고, 편향과 함께 합산되어 하나의 예/아니오 출력이 됩니다.
w₁·x₁ + w₂·x₂ + b→ 제안을 받아들일까? → 예 / 아니오
존 도가 결정을 내리는 과정: 각 입력에 가중치를 곱하고, 편향을 더한 뒤, 그 총합을 하나의 예/아니오 답으로 변환합니다.
가장 간단한 결정: 이 숫자가 양수인가?
문제를 가능한 한 단순하게 만들면 거의 아무것도 남지 않습니다. 입력 하나, 질문 하나.
이 숫자가 양수인가?
그게 전부입니다. 기계에 숫자를 넣으면, 양수이면 True, 음수이면 False를 반환하도록 합니다.
기계는 다음과 같이 예측합니다:
prediction = (weight * value + bias) > 0
입력에 가중치를 곱하고, 편향을 더한 뒤, 결과가 0보다 큰지 확인합니다. 크면 True, 작으면 False를 예측합니다. 이 작은 식이 분류기(classifier), 즉 결정 함수(decision function) 입니다.
시작할 때 가중치와 편향은 무작위 숫자입니다. 그래서 기계는 처음에 엉망진창으로 추측합니다. 이제 유일하게 영리한 단계가 등장합니다: 실수로부터 학습합니다.
if prediction != result:
error = result - prediction # True - False = 1, False - True = -1
weight += learning_rate * error * value
bias += learning_rate * error
예측이 틀렸을 때, 가중치와 편향을 올바른 방향으로 살짝 움직입니다. **오차(error)**는 어느 방향으로 움직여야 하는지를 알려주고, **학습률(learning_rate)**은 한 번에 움직이는 크기를 결정합니다. 모든 예제에 대해 이 과정을 수행하고, 전체 데이터를 다시 한 번 순회합니다. 데이터 전체를 한 번 통과하는 것을 epoch(에포크)라고 부릅니다. 에포크를 반복하는 것이 학습(training) 입니다.
아래는 바로 그 기계입니다. Train 버튼을 눌러 학습 과정을 지켜보세요. 초록 점은 양수(True), 빨간 점은 음수(False)이며, 파란 점선은 현재 기계가 두 클래스를 구분하기 위해 선택한 경계선입니다.
epoch **0**
weight **0**
bias **0**
boundary **–**
accuracy **0%**
기계는 거의 즉시 자리를 잡습니다. 출력값을 보면 경계선이 0 근처에 놓이고, 편향도 0에 가깝게 수렴합니다.
이는 우연이 아닙니다. 이 문제에서는 편향이 전혀 필요하지 않았기 때문입니다. 편향은 보통 중요한 역할을 하는데, 왜 중요한지 확인하려면 더 어려운 질문을 살펴봐야 합니다.
결정 경계(decision boundary)란?
파란 선은 결정 경계(decision boundary) 라고 불립니다. 이는 기계가 False에서 True로 전환되는 정확한 지점입니다.
우리는 이를 계산할 수 있습니다. 경계는 w · x + b = 0을 만족하는 곳에 있습니다. x에 대해 풀면:
decision_boundary = -bias / weight
“이 숫자가 양수인가?” 문제에서는 경계가 0에 있어야 하고, 실제로도 그렇습니다. 이제 정답이 0이 아닌 경우를 살펴보겠습니다.
왜 편향이 필요할까? – 학생 합격 예시
새로운 문제입니다. 같은 기계를 사용합니다. 이번에는 0~100점 사이의 시험 점수를 입력으로 주고, 다음 질문을 합니다:
학생이 합격했는가?
규칙은 간단합니다: 점수가 50점 이상이면 합격입니다. 따라서 결정 경계는 50에 위치해야 합니다, 0이 아니라.
앞서 했던 것처럼 가중치만 사용해 해결해 보겠습니다. 아래 데모에서 **“Use bias”(편향 사용) 옵션을 끈 뒤 Train을 누르세요.
epoch **0**
weight **0**
bias **0**
boundary **–**
accuracy **0%**
Use bias
정확도가 약 50% 정도까지 올라가고 멈춥니다. 얼마나 오래 학습해도 더 이상 개선되지 않습니다.
왜일까요? 편향이 없으면 식은 weight * score 뿐입니다. 모든 시험 점수는 양수이므로, 가중치가 양수이면 기계는 모든 학생을 합격으로, 가중치가 음수이면 모든 학생을 불합격으로 판단합니다. 경계는 0에 고정돼 움직일 수 없습니다