Atari 게임 환경은 강화학습 알고리즘의 성능을 검증하는 대표적인 테스트베드로 자리 잡았다. 본문에서는 Breakout 게임을 대상으로 가치 기반 접근법인 DQN(Deep Q-Network)과 정책 기반 접근법인 A3C(Asynchronous Advantage Actor-Critic)의 동작 특성과 실제 성능 차이를 살펴본다.
알고리즘 핵심 메커니즘
DQN: 경험 재활용 기반 가치 추정
DQN은 Q-learning을 딥러닝 프레임워크로 확장한 알고리즘으로, 고차원 상태 공간에서도 안정적인 학습이 가능하도록 설계되었다. 핵심 구조는 다음과 같다.
- 신경망을 통해 상태-행동 쌍의 가치를 근사
- 경험 재생 버퍼(Replay Buffer)에서 무작위 샘플링으로 데이터 상관관계 제거
- 타겟 네트워크 분리로 학습 발산 방지
- ε-탐욕 정책으로 탐험과 활용의 균형 조절
A3C: 병렬 에이전트 기반 정책 최적화
A3C는 다중 에이전트가 비동기적으로 환경과 상호작용하며 글로벌 파라미터를 갱신하는 구조를 채택한다. 특징은 다음과 같다.
- 다중 스레드 병렬 실행으로 다양한 탐험 경험 동시 수집
- Actor(정책)와 Critic(가치) 트워크의 협력적 업데이트
- Advantage 함수를 통한 분산 감소 및 학습 안정성 향상
- 경험 재생 메모리 불필요로 메모리 효율성 우수
실험 환경 및 전첸 파이프라인
모든 실험은 OpenAI Gym의 Breakout-v0 환경에서 수행되었으며, 다음과 같은 동일한 전첸 파이프라인을 적용했다.
def preprocess_frame(frame):
# RGB -> 그레이스케일 변환
gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
# 84x84로 축소
resized = cv2.resize(gray, (84, 84), interpolation=cv2.INTER_AREA)
# 픽셀값 정규화
normalized = resized.astype(np.float32) / 255.0
return normalized
추가 설정 사항:
- 4프레임 스택을 단일 상태 입력으로 사용
- 보상 클리핑: [-1, 1] 범위로 제한
- 에피소드당 5개 생명(Life) 부여
- 스킵 프레임(Frame Skip): 4프레임
하이퍼파라미터 설정
| 파라미터 | DQN | A3C |
|---|---|---|
| 학습률 | 2.5e-4 | 1.0e-4 |
| 할인계수 γ | 0.99 | 0.99 |
| 경험 버퍼 크기 | 500,000 | 미사용 |
| 병렬 커 수 | 1 | 5 |
| 타겟 네트워크 동기화 주기 | 10,000 스텝 | 해당 없음 |
| 미니배치 크기 | 32 | 5×20 (워커×스텝) |
성능 지표 분석
학습 동향 비교
실제 훈련 로그를 분석한 결과, 두 알고리즘은 뚜렷한 차이를 보였다.
수렴 속도: A3C는 약 1M 스텝에서 성능이 안정화되는 반면, DQN은 2M 스텝 이후에야 비슷한 수준의 안정성을 달성했다. 이는 A3C의 병렬 탐험이 더 다양한 상태를 빠르게 커버했기 때문으로 분석된다.
최종 성능: DQN의 평균 최고 점수는 180점대에 머물렀으나, A3C는 220점 이상을 기록했다. 특히 A3C는 벽돌 뒤편으로 공을 보내는 고급 전략을 더 일관되게 학습했다.
리소스 효율성: A3C는 순수 CPU 환경에서도 3배가량 빠른 샘플 처리량을 보였다. 반면 DQN은 경험 버퍼로 인해 약 8GB의 추가 메모리가 소요되었다.
구현 예시: 핵심 학습 루프
DQN 핵심 업데이트
class DQNAgent:
def __init__(self, state_dim, action_dim):
self.q_network = QNetwork(state_dim, action_dim)
self.target_net = QNetwork(state_dim, action_dim)
self.replay_buffer = PrioritizedBuffer(capacity=500000)
self.optimizer = optim.Adam(self.q_network.parameters(), lr=0.00025)
def update(self):
if len(self.replay_buffer) < 10000:
return
states, actions, rewards, next_states, dones = self.replay_buffer.sample(32)
# 현재 Q값 계산
current_q = self.q_network(states).gather(1, actions.unsqueeze(1))
# 타겟 Q값 계산 (Double DQN 방식)
next_actions = self.q_network(next_states).argmax(dim=1, keepdim=True)
next_q = self.target_net(next_states).gather(1, next_actions).squeeze(1)
target_q = rewards + 0.99 * next_q * (~dones)
# 손실 함수 및 역전파
loss = F.smooth_l1_loss(current_q.squeeze(), target_q)
self.optimizer.zero_grad()
loss.backward()
self.optimizer.step()
A3C 핵심 업데이트
class A3CWorker(mp.Process):
def __init__(self, global_model, optimizer, worker_id):
super().__init__()
self.local_model = ActorCriticNet()
self.global_model = global_model
self.optimizer = optimizer
self.worker_id = worker_id
def compute_advantages(self, rewards, values, next_value):
advantages = []
gae = 0
for r, v in zip(reversed(rewards), reversed(values)):
# 일반화된 어드밴티지 추정 (GAE)
delta = r + 0.99 * next_value - v
gae = delta + 0.99 * 0.95 * gae
advantages.insert(0, gae)
next_value = v
return torch.stack(advantages)
def run(self):
for step in range(MAX_STEPS):
# 로컬 에피소드 수집
log_probs, values, rewards = self.collect_trajectory()
# 글로벌 파라미터 동기화 및 업데이트
with self.optimizer.lock:
self.optimizer.zero_grad()
total_loss = self.calculate_loss(log_probs, values, rewards)
total_loss.backward()
for local_param, global_param in zip(
self.local_model.parameters(),
self.global_model.parameters()
):
global_param._grad = local_param.grad
self.optimizer.step()
# 글로벌 모델로 로컬 가중치 초기화
self.local_model.load_state_dict(self.global_model.state_dict())
실전 적용 가이드
실행 방법
# 저장소 클론
git clone https://gitcode.com/gh_mirrors/rein/reinforcement-learning
cd reinforcement-learning
# 가상 환경 구성
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# DQN 학습 실행
cd 3-atari/1-breakout
python breakout_dqn.py --render --save_freq 100000
# A3C 학습 실행
python breakout_a3c.py --num_workers 5 --save_freq 100000
알고리즘 선택 체크리스트
| 조건 | 권장 알고리즘 | 근거 |
|---|---|---|
| GPU 미보유 / 메모리 제약 | A3C | 경험 버퍼 불필요, CPU 병렬로 충분 |
| 재현성이 중요한 연구 | DQN | 결정적 샘플링으로 디버깅 용이 |
| 복잡한 행동 공간 | A3C | 연속적/확률적 정책의 자연스러운 표현 |
| 안정적인 베이스라인 필요 | DQN | 검증된 수많은 변형 알고리즘 존재 |
확장 및 개선 방향
기본 알고리즘의 한계를 극복하기 위한 개선안은 다음과 같다.
- DQN 개선: PER(Prioritized Experience Replay) 도입으로 중요 샘플의 샘플링 확률 증대
- A3C 개선: A2C(Synchronous A2C)로 동기화 방식 변경, 학습 안정성 향상
- 아키텍처 개선: Dueling Network 구조로 가치/어드밴티지 분리 추정
- 분산 학습: IMPALA 아키텍처로 대규모 병렬 처리 환경 구축
두 알고리즘 모두 Atari 환경에서 검증된 견고한 접근법이며, 최종 선택은 하드웨어 제약, 개발 일정, 팀의 기술적 친숙도 등 종합적 요인을 고려해야 한다.