MLP의 기초 개념과 작동 원리
MLP란 무엇인가
MLP(Multi-Layer Perceptron)는 가장 기본적인 형태의 인공신경망 중 하나다. 쉽게 말하면 숫자로 표현된 입력을 받아서 원하는 결과를 출력하도록 학습하는 함수다.
예를 들어 게임 AI라면 다음과 같은 정보를 입력으로 받을 수 있다.
HP = 35
적 HP = 80
적과의 거리 = 12
탄약 = 3
엄폐물 = 있음
아군 수 = 2
MLP는 이 정보를 보고 다음 행동을 판단할 수 있다.
공격 0.12
엄폐 0.67
후퇴 0.17
재장전 0.04
즉 MLP 자체는 "생각해서 문장을 만드는 AI"라기보다는 입력을 받아 분류하거나 숫자를 예측하는 신경망에 가깝다.
가장 기본적인 구조
MLP는 여러 개의 층(layer)을 연결해서 만든다.
입력층
│
▼
은닉층
│
▼
은닉층
│
▼
출력층
예를 들어 입력이 6개이고 출력이 4개라면:
입력 6개
│
▼
Linear 6 → 32
│
ReLU
│
▼
Linear 32 → 32
│
ReLU
│
▼
Linear 32 → 4
│
▼
Softmax
│
├── attack
├── cover
├── retreat
└── reload
여기서 32는 은닉층의 뉴런 수일 뿐이며 반드시 32여야 하는 것은 아니다.
뉴런이 하는 일
뉴런 하나는 입력에 각각 다른 가중치를 곱한 뒤 모두 더한다. 예를 들어 입력이 세 개라면:
x1 × w1
x2 × w2
x3 × w3
+
b
↓
결과
수식으로 쓰면 다음과 같다.
y = w1x1 + w2x2 + w3x3 + b
여기서 x는 입력, w는 weight, b는 bias, y는 출력이다. 신경망은 학습 과정에서 w와 b를 계속 수정한다. 결국 MLP가 학습한다는 것은 본질적으로 수많은 weight와 bias의 값을 적절하게 찾아가는 과정이다.
Linear Layer
MLP의 기본 구성요소가 Linear layer다. PyTorch에서는 다음과 같이 만든다.
nn.Linear(6, 32)
이는 입력 6개를 받아서 출력 32개를 만든다는 뜻이다. 수식으로 표현하면 다음과 같다.
y = Wx + b
입력은 6개의 숫자, weight는 32 × 6 행렬, bias는 32개의 숫자이고, 결과는 32개의 숫자가 된다.
Activation Function
Linear layer만 여러 개 연결하면 사실 하나의 Linear layer와 크게 다르지 않다. 그래서 층 사이에 비선형 함수를 넣는다. 대표적으로 ReLU가 있다.
ReLU(x) = max(0, x)
즉 −3은 0, −1은 0, 0은 0, 2는 2, 5는 5처럼 음수는 0으로 만들고 양수는 그대로 통과시킨다. PyTorch에서는 nn.ReLU()라고 한다. 이 비선형성이 있기 때문에 MLP가 복잡한 관계를 학습할 수 있다.
Forward Pass
실제 입력을 넣어서 결과를 계산하는 과정을 forward pass라고 한다.
[HP, enemy_hp, distance, ammo, cover, allies]
│
▼
Linear 6 → 32
│
ReLU
│
▼
Linear 32 → 32
│
ReLU
│
▼
Linear 32 → 4
│
▼
Softmax
이 과정을 거쳐 최종 결과가 나온다. 처음에는 weight가 무작위이므로 결과도 엉망이다.
Softmax
출력이 여러 개의 선택지 중 하나를 고르는 문제라면 Softmax를 사용할 수 있다. 예를 들어 마지막 출력이 [2.1, 0.7, 1.3, -0.5]라고 하면 Softmax를 통해 확률 형태로 변환할 수 있다.
attack 0.55
cover 0.14
retreat 0.29
reload 0.02
이렇게 하면 가장 높은 값을 가진 행동을 선택할 수 있다.
action = probabilities.argmax()
학습이란 무엇인가
MLP가 처음 만들어졌을 때는 아무것도 모른다. 예를 들어 HP가 낮고 탄약이 적으며 엄폐물이 있는 상황에서 정답이 cover인데, 처음에는 이렇게 잘못 판단할 수 있다.
attack 0.62
cover 0.11
retreat 0.20
reload 0.07
그러면 MLP의 예측과 정답을 비교한다.
Loss
예측이 정답에서 얼마나 벗어났는지를 숫자로 표현한 것이 loss다. 정답이 cover인데 예측이 위와 같다면 loss가 높다. 반대로 다음과 같으면 loss가 낮다.
attack 0.02
cover 0.91
retreat 0.05
reload 0.02
학습의 목표는 loss를 계속 줄이는 것이다.
Backpropagation
loss를 계산한 다음에는 어떤 weight를 얼마나 수정해야 하는지 계산한다. 이를 backpropagation이라고 한다. 개념적으로는 다음과 같은 과정을 반복한다.
입력
↓
MLP
↓
예측
↓
정답과 비교
↓
Loss
↓
어떤 weight가 잘못됐는지 계산
↓
weight 수정
↓
다시 예측
이 과정에서 미분과 gradient가 사용된다.
Optimizer
gradient를 이용해서 실제 weight를 수정하는 역할을 optimizer가 한다. 대표적인 것이 Adam이다.
optimizer = torch.optim.Adam(
model.parameters(),
lr=0.001
)
lr은 learning rate다. 너무 크면 학습이 불안정할 수 있고, 너무 작으면 학습이 매우 느려진다.
전체 학습 과정
MLP 학습은 결국 다음 과정의 반복이다.
학습 데이터
↓
입력 X
↓
MLP
↓
예측값
↓
정답 y와 비교
↓
Loss
↓
Backpropagation
↓
Optimizer
↓
Weight 수정
↓
다음 데이터
이것을 수천~수백만 번 반복한다.
학습 데이터
MLP에서 가장 중요한 것은 학습 데이터다. 다음과 같은 형태로 만들어야 한다.
입력 정답
[0.9, 0.2, 0.1, 0.8, 1, 3] attack
[0.2, 0.8, 0.1, 0.1, 1, 2] retreat
[0.4, 0.7, 0.3, 0.8, 1, 1] cover
[0.5, 0.2, 0.8, 0.0, 1, 2] reload
즉 MLP 자체보다 어떤 데이터를 주고 어떤 정답을 붙이는지가 더 중요하다. 데이터가 좋으면 작은 모델도 상당히 좋은 판단을 할 수 있다.
LLM을 이용해서 학습 데이터를 만들 수 있다
앞서 이야기한 Jev와 연결되는 부분이다. 예를 들어 DeepSeek나 Qwen에게 상황을 만들어주고 판단을 요청할 수 있다.
현재 상태:
HP = 30
적과 거리 = 10m
탄약 = 2
엄폐물 = 있음
아군 = 1
다음 행동을 선택하라.
attack
cover
retreat
reload
LLM이 여기서 cover라고 판단하게 만든다. 이런 데이터를 수만~수십만 개 만들면 LLM이 판단 데이터를 생성하고, 그것이 학습 데이터가 되어 MLP를 학습시키는 구조를 만들 수 있다. 이런 방식은 큰 모델의 판단 패턴을 작은 모델로 옮기는 distillation의 한 형태로 볼 수 있다.
MLP와 작은 LLM의 차이
작은 LLM도 판단을 할 수 있지만 목적이 다르다. LLM은 입력을 받아 Transformer를 거쳐 다음 token을 계속 생성하며 문장을 만든다. MLP는 입력을 받아 Linear, ReLU, Linear를 거쳐 곧바로 출력한다.
따라서 입력이 이미 숫자로 잘 정의되어 있다면 MLP가 훨씬 작고 빠르다. HP, ammo, distance, enemy_count, cover, time 같은 데이터라면 MLP가 적합하다. 반면 "ImportError가 발생했는데 config를 수정한 뒤에도 같은 오류가 계속 발생한다"처럼 자연어를 직접 이해해야 한다면 Transformer 계열 모델이 더 적합하다.
필요한 라이브러리
가장 기본적인 MLP 실험에는 사실 몇 개만 필요하다.
Python
전체 개발 환경의 기본 언어다. Python 3.10 이상을 사용하는 것이 무난하다.
PyTorch
신경망을 만들고 학습시키는 핵심 라이브러리다.
pip install torch
PyTorch에서 사용하는 핵심 기능은 import torch와 import torch.nn as nn이다. torch는 tensor 계산과 GPU 연산 등을 담당하고, torch.nn은 신경망 layer를 제공한다.
NumPy
숫자 데이터를 다루기 위한 기본 라이브러리다.
pip install numpy
PyTorch만으로도 상당 부분 처리할 수 있기 때문에 필수는 아니지만 거의 항상 함께 사용한다.
pandas
CSV 같은 데이터를 다룰 때 편리하다.
pip install pandas
예를 들어 data.csv에 저장된 학습 데이터를 읽을 때 사용한다.
scikit-learn
데이터 전처리와 평가에 유용하다.
pip install scikit-learn
특히 train/test 분리, 데이터 정규화, confusion matrix, accuracy, precision, recall 등을 쉽게 사용할 수 있다.
최소 개발 환경
처음 배우는 단계라면 다음 정도면 충분하다.
pip install torch numpy scikit-learn pandas
그리고 기본적인 MLP는 별도의 AI 프레임워크 없이 PyTorch만으로 만들 수 있다.
아주 작은 MLP 예제
전체 모델은 다음 정도로 만들 수 있다.
import torch
import torch.nn as nn
class DecisionMLP(nn.Module):
def __init__(self):
super().__init__()
self.network = nn.Sequential(
nn.Linear(6, 32),
nn.ReLU(),
nn.Linear(32, 32),
nn.ReLU(),
nn.Linear(32, 4)
)
def forward(self, x):
return self.network(x)
model = DecisionMLP()
x = torch.tensor([
[0.35, 0.80, 0.12, 0.30, 1.0, 0.20]
])
output = model(x)
print(output)
여기까지는 MLP를 만들고 실행한 것이다. 아직 학습하지 않았기 때문에 결과는 의미가 없다. 학습하려면 여기에 Dataset, Loss function, Optimizer, Training loop를 추가해야 한다.
MLP를 실제 프로젝트에 사용하는 전체 구조
Jev와 비슷한 시스템을 직접 만든다면 다음 구조가 된다.
큰 LLM
Qwen / DeepSeek
│
│ 판단
▼
학습 데이터 생성
│
▼
┌─────────────────┐
│ Training │
│ │
│ PyTorch │
│ ↓ │
│ MLP │
└─────────────────┘
│
▼
decision model
│
▼
실제 프로그램 / Agent
실행할 때는 큰 LLM을 부를 필요가 없다. 현재 상태를 로컬 MLP에 넣어 [0.03, 0.72, 0.08, 0.17] 같은 출력을 받고, 가장 높은 행동을 선택하면 된다. 이 때문에 모델 크기와 실행 비용을 크게 줄일 수 있다.
MLP의 장점과 한계
MLP의 가장 큰 장점은 작고 빠르다는 것이다. 입력이 구조화되어 있다면 수백만 번의 판단도 매우 빠르게 수행할 수 있다. GPU가 없어도 실행할 수 있는 경우가 많다.
반면 자연어를 이해하거나 긴 문맥을 추론하거나 복잡한 reasoning을 하는 능력은 매우 제한적이다. 따라서 MLP는 LLM의 대체품이라기보다는 LLM이 해야 할 일 중 반복적이고 단순한 판단을 떼어내는 용도로 생각하는 것이 좋다.
특히 다음과 같은 문제에 잘 맞는다.
분류, 예측, 점수 계산, Routing, 행동 선택, 이상 탐지, 위험도 평가, 추천, 상태 판단.
정리
결국 핵심은 다음과 같다. MLP는 입력 데이터를 받아 Linear, Activation, Linear, Activation, Linear를 거쳐 출력을 낸다. 학습은 입력, 예측, 정답과의 비교, Loss, Backpropagation, Weight 수정을 반복하는 과정이다.
그리고 Jev와 연결하면 가장 중요한 개념은 "큰 LLM이 복잡한 판단을 하고, 작은 MLP가 반복적인 판단을 대신하게 만든다"는 것이다. 이 관점에서 보면 MLP는 단순한 신경망이라기보다 프로그램 안에 넣을 수 있는 아주 작은 학습 가능한 함수라고 이해하는 것이 가장 좋다.