머신러닝 딥러닝
[강화학습-10] 액터-크리틱(Actor-Critic)
Qcoding
2025. 5. 28. 17:34
반응형
10. Actor–Critic 구조 (A2C·A3C) & Advantage 함수
Actor–Critic(AC)은 정책(Actor) 과 가치 추정(Critic)을 동시에 학습해 정책 기반 방법의 높은 표현력과 TD 부트스트랩의 샘플 효율을 결합합니다.

10-1. A2C (Advantage Actor-Critic)
- 동기식 A2C :
N
개의 워커가 동시에 n-step Return을 계산, 미니배치로 정책/가치 네트워크를 업데이트. - Advantage $A_t = R_t^{(n)} - V_\phi(S_t)$ 를 이용해 baseline 분산↓.
- 목표 손실 $$\mathcal{L} = \underbrace{\bigl(\!R_t^{(n)} - V_\phi(S_t)\bigr)^2}_{\text{Critic}} \;-\;\beta\;A_t\;\log\pi_\theta(A_t\!\mid\!S_t) \;+\;\alpha\;\mathcal{H}\!\bigl[\pi_\theta(\cdot\mid S_t)\bigr]$$ 여기서 $\mathcal{H}$는 엔트로피 보너스(탐험 유도).
10-2. A3C (Asynchronous A2C)
멀티쓰레드 워커가 비동기로 환경을 탐험 → 각 워커 gradients를 글로벌 네트워크에 lock-free로 더하면서 학습 속도 크게 ↑.
특징 | A2C (동기) | A3C (비동기) |
---|---|---|
병렬성 | GPU 벡터화 | CPU 멀티쓰레드 |
업데이트 간격 | 고정 $n$ step | 워커마다 가변 |
장점 | 안정적 배치 학습 | 빠른 탐험·수렴 |
단점 | GPU 메모리↑ | Thread 경합 조정 필요 |
10-3. Advantage 함수 & GAE(λ)
Advantage $A_t$ 는 “행동 $a$의 상대적 우수성”을 측정해 Policy Gradient 분산을 낮춘다.
- 1-step TD 오차 : $\delta_t = r_t + \gamma V(S_{t+1}) - V(S_t)$
- GAE(λ) : $$A_t^{(\lambda)}=\sum_{k=0}^{\infty}(\gamma\lambda)^k\,\delta_{t+k}$$ λ ↑ ⇒ Bias ↓ · Variance ↑ (REINFORCE에 가까움)
10-4. 간단 구현 : A2C로 LunarLander-v2

PyTorch 200줄 내 코어 코드 (다중 워커 생략 — 단일 인스턴스 n-step A2C):
"""
pip install gymnasium torch numpy
"""
import gymnasium as gym, numpy as np, torch, torch.nn as nn, torch.optim as optim
from collections import deque
env_id = "LunarLander-v2"
env = gym.make(env_id)
gamma, n_step = 0.99, 5
class ActorCritic(nn.Module):
def __init__(self, s_dim, a_dim):
super().__init__()
self.shared = nn.Sequential(
nn.Linear(s_dim, 256), nn.ReLU(),
nn.Linear(256, 128), nn.ReLU())
self.pi = nn.Sequential(nn.Linear(128, a_dim))
self.v = nn.Linear(128, 1)
def forward(self, s):
h = self.shared(s)
return self.pi(h), self.v(h)
net = ActorCritic(env.observation_space.shape[0], env.action_space.n)
opt = optim.Adam(net.parameters(), lr=3e-4)
buffer= deque(maxlen=4096)
def get_action(state):
with torch.no_grad():
logits, _ = net(torch.tensor(state, dtype=torch.float32))
probs = torch.softmax(logits, dim=-1)
return int(torch.multinomial(probs, 1))
def compute_returns(rewards, next_v, dones):
R = next_v
returns = []
for r, d in zip(reversed(rewards), reversed(dones)):
R = r + gamma * R * (1 - d)
returns.insert(0, R)
return returns
for ep in range(800):
s, _ = env.reset()
traj_s,traj_a,traj_r,traj_d = [],[],[],[]
done, ep_ret = False, 0
while not done:
a = get_action(s)
s2, r, term, trunc, _ = env.step(a)
d = term or trunc
traj_s.append(s); traj_a.append(a); traj_r.append(r); traj_d.append(d)
s, done, ep_ret = s2, d, ep_ret+r
# n-step rollout
if len(traj_r) >= n_step or done:
with torch.no_grad():
_, next_v = net(torch.tensor(s, dtype=torch.float32))
R = compute_returns(traj_r, next_v.item(), traj_d)
for i in range(len(R)):
buffer.append((traj_s[i], traj_a[i], R[i]))
traj_s=traj_a=traj_r=traj_d=[]
# 학습
if len(buffer) >= 1024:
batch = [buffer.popleft() for _ in range(1024)]
states = torch.tensor([b[0] for b in batch], dtype=torch.float32)
actions= torch.tensor([b[1] for b in batch])
targets= torch.tensor([b[2] for b in batch], dtype=torch.float32)
logits, values = net(states)
logp = torch.log_softmax(logits, dim=-1)
adv = targets - values.squeeze()
loss_pi= -(logp[range(len(actions)), actions] * adv.detach()).mean()
loss_v = 0.5*adv.pow(2).mean()
entropy= -(torch.softmax(logits,dim=-1)*logp).sum(1).mean()
loss = loss_pi + loss_v - 0.01*entropy
opt.zero_grad(); loss.backward(); opt.step()
if (ep+1)%20==0:
print(f"[{ep+1:4d}] Return = {ep_ret:7.1f}")
- 성공 기준 : 평균 Score ≥ 200 (OpenAI Gym).
- 멀티 워크 (A3C) 를 사용하면 CPU만으로 수렴 속도 ↑ & 샘플 효율 ↑.
10-5. 요약 & 다음 편 예고
- Actor + Critic 조합은 Advantage로 Policy Gradient를 안정화한다.
- A2C는 GPU 벡터화, A3C는 비동기 쓰레드로 학습 가속.
- LunarLander 같은 복합 box2d 미션도 n-step A2C만으로 해결 가능.
다음 글 : 신뢰 영역으로 정책 업데이트를 제어하는 PPO(Clip/TRPO)와 Soft Actor-Critic 의 엔트로피 정책 최적화를 다루겠습니다.
참고 자료
- Mnih et al., “Asynchronous Methods for Deep RL,” ICML 2016
- Sutton & Barto, RL: An Introduction, Ch. 13
- Schulman et al., “High-Dimensional Continuous Control with GAE,” ICLR 2016
반응형