반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- FirebaseV9
- 카트폴
- expo
- Ros
- 머신러닝
- redux
- clone coding
- 클론코딩
- python
- JavaScript
- 전국국밥
- selenium
- 딥러닝
- 강화학습 기초
- 조코딩
- ReactNative
- Reinforcement Learning
- kaggle
- 데이터분석
- coding
- App
- React
- GYM
- Instagrame clone
- 앱개발
- 사이드프로젝트
- pandas
- 강화학습
- 리액트네이티브
- TeachagleMachine
Archives
- Today
- Total
qcoding
[강화학습-9] 정책 기반 방법 (Policy Gradient) – REINFORCE 본문
반응형
9. 정책 기반 방법 (Policy Gradient)
가치기반(Q) 방법이 “가치를 올리며 탐욕적 행동”에 의존한다면, 정책 기반(Policy Gradient)은 “정책 그 자체”를 매개변수화해 곧바로 최적화를 시도합니다.
9-1. REINFORCE 알고리즘
Montezuma’s Revenge처럼 희소 · 고차원 보상 환경에서, 미끄러운 Q 값 추정 대신 정책 확률 $\pi_\theta(a\mid s)$ 를 직접 조정하는 접근입니다.
$$\nabla_\theta J(\theta)=
\mathbb{E}_{\pi_\theta}\!\bigl[
G_t \,\nabla_\theta \log\pi_\theta(A_t\mid S_t)
\bigr] \quad\text{(REINFORCE)}$$
- $J(\theta)=\mathbb{E}_{\pi_\theta}[G_0]$ : 기대 Return.
- $G_t$ : 에피소드 종단까지 할인 누적 보상.
- “로그 likelihood trick” 덕분에 환경 동적모델 $P$ 미분 불필요.
9-2. 기울기 추정과 분산 감소
기법 | 수식 | 효과 |
---|---|---|
Baseline (상수 or $b(s)$) |
$$\nabla_\theta J = \mathbb{E}\bigl[(G_t-b)\nabla_\theta \log\pi_\theta\bigr]$$ | $b$ 는 기댓값에 영향을 주지 않지만 분산을 크게 낮춤 |
Advantage | $$A_t = G_t - V_\phi(S_t)$$ | 상태가치 함수 $V_\phi$ 학습 후 사용 REINFORCE + Baseline 의 일반화 |
GAE(λ) | $$A_t^{(\lambda)}=\sum_{k=0}^{\infty} (\gamma\lambda)^k\,\delta_{t+k}$$ | $\lambda$ 로 Bias–Variance 절충 |
첫걸음으로는 “상수 베이스라인 ↔ 에피소드 평균” 만으로도 학습 안정성이 꽤 오릅니다.
9-3. 예제 – 1차원 연속 제어 (MountainCarContinuous-v0)
MountainCarContinuous-v0
는 하나의 연속 행동($a\in[-1,1]$) 만으로
언덕을 넘어야 하는 1-D 컨트롤 환경입니다. 아래 코드는 Gaussian 정책 REINFORCE + Baseline
(≈ 120 줄) 로 문제를 해결합니다.
"""
pip install gymnasium torch numpy
"""
import gymnasium as gym
import numpy as np
import torch, torch.nn as nn, torch.optim as optim
ENV_ID = "MountainCarContinuous-v0"
EPISODES = 1200
GAMMA = 0.99
LR_ACTOR = 1e-3
LR_CRITIC = 2e-3
BATCH_SIZE = 5 # 에피소드 묶음 학습
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
env = gym.make(ENV_ID)
obs_dim = env.observation_space.shape[0]
act_dim = env.action_space.shape[0]
# --- 네트워크 -----------------------------------------------------------
class Actor(nn.Module):
def __init__(self):
super().__init__()
self.net = nn.Sequential(
nn.Linear(obs_dim, 128), nn.Tanh(),
nn.Linear(128, 128), nn.Tanh()
)
self.mu = nn.Linear(128, act_dim)
self.logstd = nn.Parameter(torch.zeros(act_dim)) # 학습 가능
def forward(self, x):
z = self.net(x)
return self.mu(z)
def get_dist(self, x):
mu = self.forward(x)
std = self.logstd.exp()
return torch.distributions.Normal(mu, std)
class Critic(nn.Module):
def __init__(self):
super().__init__()
self.v = nn.Sequential(
nn.Linear(obs_dim, 128), nn.Tanh(),
nn.Linear(128, 1)
)
def forward(self, x):
return self.v(x)
actor = Actor().to(DEVICE)
critic = Critic().to(DEVICE)
opt_a = optim.Adam(actor.parameters(), lr=LR_ACTOR)
opt_c = optim.Adam(critic.parameters(), lr=LR_CRITIC)
# --- Rollout 저장용 ------------------------------------------------------
class Trajectory:
def __init__(self):
self.states, self.actions = [], []
self.rewards, self.dones = [], []
def push(self, s,a,r,d):
self.states.append(s); self.actions.append(a)
self.rewards.append(r); self.dones.append(d)
def finish(self):
# Discounted Return + Advantage
R, G, A = 0, [], []
for r in self.rewards[::-1]:
R = r + GAMMA * R
G.insert(0, R)
with torch.no_grad():
V = critic(torch.tensor(self.states, dtype=torch.float32, device=DEVICE)).squeeze().cpu().numpy()
A = np.array(G) - V
return np.array(self.states), np.array(self.actions), np.array(G), A
buffer = []
# --- 학습 루프 ----------------------------------------------------------
for ep in range(1, EPISODES+1):
state, _ = env.reset()
traj = Trajectory()
ep_reward = 0
done = False
while not done:
state_v = torch.tensor(state, dtype=torch.float32, device=DEVICE)
dist = actor.get_dist(state_v)
action = dist.sample().clamp(-1.0, 1.0) # env limits
logprob = dist.log_prob(action).sum()
next_state, reward, terminated, truncated, _ = env.step(action.cpu().numpy())
done = terminated or truncated
traj.push(state, action.cpu().numpy(), reward, done)
state = next_state
ep_reward += reward
buffer.append(traj.finish())
# --- 배치 학습 ------------------------------------------------------
if ep % BATCH_SIZE == 0:
states = torch.tensor(np.concatenate([b[0] for b in buffer]),
dtype=torch.float32, device=DEVICE)
actions= torch.tensor(np.concatenate([b[1] for b in buffer]),
dtype=torch.float32, device=DEVICE)
returns= torch.tensor(np.concatenate([b[2] for b in buffer]),
dtype=torch.float32, device=DEVICE)
adv = torch.tensor(np.concatenate([b[3] for b in buffer]),
dtype=torch.float32, device=DEVICE)
# [1] Critic update (MSE)
v_pred = critic(states).squeeze()
loss_v = nn.functional.mse_loss(v_pred, returns)
opt_c.zero_grad(); loss_v.backward(); opt_c.step()
# [2] Actor update (Policy Gradient with baseline)
dist = actor.get_dist(states)
logprob = dist.log_prob(actions).sum(dim=1)
loss_pi = -(logprob * adv).mean()
opt_a.zero_grad(); loss_pi.backward(); opt_a.step()
buffer.clear() # flush
if ep % 50 == 0:
print(f"Ep {ep:4d} | Return {ep_reward:6.1f}")
print("학습 완료!")
env.close()
- MountainCarContinuous 는 평균 Return ≥ 90 (200 만점) 이면 솔브(OpenAI Gym 기준).
- Tip : 표준편차
logstd
를 학습가능 파라미터로 두면 탐험 강도를 자동 조절.
9-4. 요약 & 다음 편 예고
- 정책 그 자체를 매개변수화하면 확률적 행동·연속 행동 공간 모두 자연스럽게 지원.
- REINFORCE 기울기는 $\log\pi$ trick 으로 구하고, Baseline / Advantage 로 분산을 낮춘다.
- 1-D 연속 제어 문제는 “Gaussian 정책 + REINFORCE + Critic Baseline” 조합만으로 충분히 해결.
다음 글 : Advantage 를 좀 더 효율적으로 사용하는 Actor-Critic 구조 (A2C/A3C, PPO, SAC) 를 살펴보고, 보다 복잡한 연속 제어(MuJoCo HalfCheetah 등)에 도전합니다.
참고 자료
- Sutton et al., “Policy Gradient Methods for Reinforcement Learning with Function Approximation,” 1999
- Williams, “Simple Statistical Gradient-Following Algorithms for Connectionist RL,” 1992 (REINFORCE 원논문)
- Schulman et al., “High-Dimensional Continuous Control Using Generalized Advantage Estimation,” 2016
반응형
'머신러닝 딥러닝' 카테고리의 다른 글
[강화학습-11] 고급 기법 & 최신 토픽 – PPO · SAC · 분산 RL · 탐험 전략 (0) | 2025.05.28 |
---|---|
[강화학습-10] 액터-크리틱(Actor-Critic) (0) | 2025.05.28 |
[강화학습-8] 딥 강화학습(Deep RL) 기초 – DQN (2) | 2025.05.28 |
[강화학습-7] 함수 근사 (Function Approximation) (0) | 2025.05.28 |
[강화학습-6] 시간차 학습 (Temporal-Difference, TD) (0) | 2025.05.28 |
Comments