Model-Based RL이란?
강화학습(Reinforcement Learning)은 크게 Model-Free와 Model-Based 방식으로 나뉩니다. Model-Free RL(DQN, PPO 등)은 환경과 직접 상호작용하며 가치함수나 정책을 학습하지만, Model-Based RL은 환경의 dynamics를 모델로 학습한 뒤 이를 활용해 계획(Planning)을 수립합니다.
핵심 아이디어: 실제 환경 대신 학습된 모델에서 시뮬레이션을 돌려 샘플 효율성을 극대화한다.
이 접근법은 특히 실제 환경에서의 샘플 수집 비용이 높은 로보틱스, 자율주행, 산업 제어 분야에서 필수적입니다.
Model-Based RL의 핵심 컴포넌트
Model-Based RL은 다음 3가지 핵심 요소로 구성됩니다.
1. 환경 모델(Dynamics Model) 학습
환경 모델은 현재 상태 와 행동 가 주어졌을 때 다음 상태 과 보상 를 예측합니다.
여기서:
– : 파라미터 를 가진 학습 가능한 모델 (신경망)
– : 현재 상태
– : 선택한 행동
– : 예측된 다음 상태
– : 예측된 보상
학습 방법: 실제 경험 데이터 을 수집하여 supervised learning으로 학습합니다.
import torch
import torch.nn as nn
class DynamicsModel(nn.Module):
def __init__(self, state_dim, action_dim):
super().__init__()
self.network = nn.Sequential(
nn.Linear(state_dim + action_dim, 256),
nn.ReLU(),
nn.Linear(256, 256),
nn.ReLU(),
nn.Linear(256, state_dim + 1) # 다음 상태 + 보상
)
def forward(self, state, action):
x = torch.cat([state, action], dim=-1)
output = self.network(x)
next_state = output[:, :-1]
reward = output[:, -1:]
return next_state, reward
# 학습 예시
def train_dynamics_model(model, replay_buffer, optimizer):
states, actions, next_states, rewards = replay_buffer.sample(batch_size=256)
pred_next_states, pred_rewards = model(states, actions)
state_loss = nn.MSELoss()(pred_next_states, next_states)
reward_loss = nn.MSELoss()(pred_rewards, rewards)
loss = state_loss + reward_loss
optimizer.zero_grad()
loss.backward()
optimizer.step()
2. Planning (계획 수립)
학습된 모델로 미래를 시뮬레이션하여 최적 행동을 결정합니다. 실제 환경 상호작용 없이 모델 내에서 rollout을 수행합니다.
3. Policy Improvement
Planning 결과를 바탕으로 정책을 개선합니다. Model-Free 방식과 결합하여 하이브리드 접근도 가능합니다.
주요 Planning 알고리즘 비교
| 알고리즘 | 연도 | 모델 타입 | Planning 방식 | 특징 | 적용 분야 |
|---|---|---|---|---|---|
| Dyna-Q | 1990 | Tabular/Simple | Random rollout + Q-learning | 간단하고 직관적, 작은 상태공간 | 그리드월드, 미로 |
| PETS | 2018 | Ensemble NN | MPC with CEM | 불확실성 고려, 샘플 효율적 | 로보틱스 제어 |
| MBPO | 2019 | Probabilistic | Short rollout + SAC | Model-Free와 결합 | 연속 제어 |
| Dreamer | 2020 | Latent RSSM | Imagination in latent | 이미지 입력 처리 | Atari, DMC |
| MuZero | 2020 | Implicit | MCTS + Learned model | 체스/바둑급 성능 | 게임, 복잡한 의사결정 |
Dyna-Q: Model-Based RL의 시작
Dyna-Q는 Richard Sutton이 1990년 제안한 고전 알고리즘으로, Real experience와 Simulated experience를 결합합니다.
작동 원리
- 실제 환경에서 경험 수집:
- Q-learning 업데이트 수행
- 모델 학습:
- Planning: 모델에서 번 시뮬레이션하며 추가 Q-learning
class DynaQ:
def __init__(self, n_states, n_actions, n_planning_steps=5):
self.Q = np.zeros((n_states, n_actions))
self.model = {} # (s, a) -> (r, s')
self.n_planning = n_planning_steps
self.visited = [] # 방문한 (s, a) 쌍 저장
def update(self, s, a, r, s_next, alpha=0.1, gamma=0.95):
# 1. Direct RL (Q-learning)
best_next_action = np.argmax(self.Q[s_next])
td_target = r + gamma * self.Q[s_next, best_next_action]
self.Q[s, a] += alpha * (td_target - self.Q[s, a])
# 2. Model learning
self.model[(s, a)] = (r, s_next)
if (s, a) not in self.visited:
self.visited.append((s, a))
# 3. Planning
for _ in range(self.n_planning):
# 랜덤하게 과거 경험 샘플링
s_sim, a_sim = random.choice(self.visited)
r_sim, s_next_sim = self.model[(s_sim, a_sim)]
# Simulated Q-learning
best_next = np.argmax(self.Q[s_next_sim])
td_target_sim = r_sim + gamma * self.Q[s_next_sim, best_next]
self.Q[s_sim, a_sim] += alpha * (td_target_sim - self.Q[s_sim, a_sim])
장점: 적은 실제 경험으로 빠른 학습
단점: 모델 오차가 누적되면 성능 저하
MuZero: 암묵적 모델로 체스·바둑 정복
DeepMind의 MuZero(2020)는 환경의 실제 상태를 예측하지 않고, 의사결정에 필요한 잠재 표현(latent representation)만 학습합니다.
MuZero의 3가지 핵심 함수
-
Representation 함수 : 관측 를 잠재 상태 로 인코딩
-
Dynamics 함수 : 잠재 상태와 행동을 다음 잠재 상태와 보상으로 변환
-
Prediction 함수 : 정책과 가치 예측
여기서 는 모두 신경망 파라미터입니다.
MCTS와의 결합
MuZero는 Monte Carlo Tree Search(MCTS)를 활용해 planning을 수행합니다.
class MuZeroMCTS:
def __init__(self, model, n_simulations=50):
self.model = model # h, g, f 함수 포함
self.n_simulations = n_simulations
def search(self, observation):
root = Node()
# Representation: 관측을 잠재 상태로
latent_state = self.model.h(observation)
root.expand(latent_state, self.model.f(latent_state))
for _ in range(self.n_simulations):
node = root
search_path = [node]
# Selection: UCB로 노드 선택
while node.expanded:
action, node = node.select_child()
search_path.append(node)
# Expansion
parent = search_path[-2]
latent_state = parent.latent_state
action = search_path[-1].action
# Dynamics: 다음 잠재 상태 예측
reward, next_latent = self.model.g(latent_state, action)
policy, value = self.model.f(next_latent)
node.expand(next_latent, policy)
# Backpropagation
self.backpropagate(search_path, value, reward)
# 최적 행동 선택 (방문 횟수 기반)
return root.select_action(temperature=0)
실전 활용:
– Atari 게임: 픽셀 입력에서 초인적 성능
– 체스/바둑: AlphaZero와 동등하되 환경 규칙 없이 학습
– 로보틱스: 고차원 센서 데이터 처리
MBPO와 Dreamer: 현대적 접근
MBPO (Model-Based Policy Optimization)
핵심 전략: 짧은 rollout으로 모델 오차 최소화
- 모델에서 -step(보통 1~5) rollout만 수행
- 생성된 가상 데이터를 SAC 같은 Model-Free 알고리즘에 추가
- 실제 데이터와 모델 데이터를 혼합하여 학습
def mbpo_training_step(env, model, policy, replay_buffer):
# 1. 실제 환경에서 데이터 수집
real_data = collect_data(env, policy, n_steps=1000)
replay_buffer.add(real_data)
# 2. 모델 학습
train_dynamics_model(model, replay_buffer)
# 3. 짧은 rollout으로 가상 데이터 생성
model_buffer = []
for s in replay_buffer.sample_states(n=10000):
trajectory = []
state = s
for _ in range(k_step_rollout): # k=5
action = policy.sample(state)
next_state, reward = model.predict(state, action)
trajectory.append((state, action, reward, next_state))
state = next_state
model_buffer.extend(trajectory)
# 4. 실제+가상 데이터로 정책 학습 (SAC)
combined_buffer = replay_buffer + model_buffer
policy.update(combined_buffer)
Dreamer
잠재 공간(latent space)에서 모든 planning을 수행하는 월드 모델입니다.
- RSSM (Recurrent State-Space Model): 결정론적 상태 + 확률적 상태로 분리
- 이미지 관측을 latent로 압축 후 imagination으로 정책 학습
- Atari, DeepMind Control Suite에서 뛰어난 샘플 효율성
실전 구현 전략
1. 언제 Model-Based를 사용할까?
| 상황 | 추천 여부 |
|---|---|
| 샘플 수집 비용이 높음 (로봇, 실제 하드웨어) | ✅ 강력 추천 |
| 환경이 deterministic하거나 예측 가능 | ✅ 추천 |
| 복잡한 dynamics, 카오스 시스템 | ⚠️ 모델 학습 어려움 |
| 고차원 상태공간 (이미지) | ✅ Dreamer, MuZero |
| 빠른 프로토타입 필요 | ❌ Model-Free가 간단 |
2. 모델 오차 관리
핵심 원칙: 모델을 완벽하게 만들려 하지 말고, 오차를 인정하고 관리하라.
- Ensemble: 여러 모델을 학습해 불확실성 추정 (PETS)
- Short rollout: MBPO처럼 1~5 step만 시뮬레이션
- Uncertainty penalty: 불확실성이 높은 영역은 보상에 패널티
3. 하이브리드 접근
class HybridAgent:
def __init__(self):
self.model = DynamicsModel()
self.policy = SACPolicy() # Model-Free
def train(self, env):
for episode in range(1000):
# Real experience
real_data = self.policy.collect_rollout(env, n_steps=1000)
# Model learning
self.model.train(real_data)
# Imagined experience (Model-Based)
imagined_data = self.model.generate_rollouts(
initial_states=real_data.states,
policy=self.policy,
horizon=5
)
# Policy update with both
self.policy.update(real_data + imagined_data)
4. 디버깅 팁
- 모델 예측 시각화: 실제 궤적 vs 모델 예측 비교
- Rollout 길이 실험: 1, 3, 5, 10 step 성능 비교
- Model-Free 베이스라인: 항상 SAC/PPO와 성능 비교
마무리
Model-Based RL은 샘플 효율성이라는 강화학습의 가장 큰 과제를 해결하는 핵심 접근법입니다.
핵심 요약:
– Dyna-Q: 간단한 tabular 환경에서 출발점, real + simulated 경험 결합
– MuZero: 암묵적 모델 + MCTS로 게임 AI의 정점, 환경 규칙 없이 학습
– MBPO: 짧은 rollout으로 모델 오차 관리, Model-Free와 시너지
– Dreamer: 잠재 공간 imagination으로 이미지 기반 제어 혁신
실전에서는 하이브리드 접근(Model-Based planning + Model-Free robustness)이 가장 안정적입니다. 환경의 특성을 파악하고, 모델 오차를 인정하며, 적절한 rollout 길이를 실험하는 것이 성공의 열쇠입니다.
로보틱스나 자율주행처럼 실제 샘플이 귀한 도메인이라면 Model-Based RL은 선택이 아닌 필수입니다. MuZero나 Dreamer의 코드를 직접 구현해보며 planning의 위력을 체감해보세요!
Did you find this helpful?
☕ Buy me a coffee
Leave a Reply