[개인 공부] 강화 학습에 대한 스터디 노트

2026. 3. 2. 00:47·3. 자습 & 메모(실전, 실습, 프로젝트)/3-2 메모(실전, 프로젝트)

실제 게임에 강화학습을 적용하면서 배운 내용 정리


1. 학습 vs 실제 게임 실행 — 왜 학습이 빠른가?

핵심: 학습은 실제 게임을 돌리지 않는다. 완전히 별개의 방식이다.

비교표

구분 학습 (train.py) 실제 게임 (rl_bridge.py)
환경 Python game_env.py (수학 시뮬레이션) 브라우저 Phaser 3 (렌더링+물리)
1스텝 소요 ~0.001초 ~0.5초 (decision_interval)
그래픽 없음 스프라이트, 투사체, 애니메이션
전투 total_dps × dt 단순 곱셈 개별 유닛이 타겟 탐색→투사체 발사→충돌 판정
적 이동 HP 숫자만 존재 원형 궤도 물리 이동
병렬 8개 환경 동시 실행 1개 브라우저

학습 환경의 전투 로직

# game_env.py - _apply_combat()
damage_pool = total_dps * dt  # 이게 전투의 전부. 그래픽 없음
for enemy in self.enemies:
    if enemy['hp'] <= damage_pool:
        killed.append(enemy)

 

실제 게임에서는 유닛마다 사거리 체크 → 타겟 탐색 → 투사체 생성 → 충돌 판정 → 데미지 적용을 매 프레임(60fps) 수행하지만, 학습 환경에서는 "총 DPS × 시간 = 데미지"라는 수학 한 줄로 모든 전투를 대체한다.

속도 차이

  • 10M 스텝 학습: ~1시간 45분
  • 같은 양을 실제 게임으로 실행 시: 수만 시간 소요 예상

이것이 가능한 이유는 학습 환경이 게임의 핵심 의사결정 구조만 추상화했기 때문이다. 그래픽, 물리, 애니메이션은 AI가 최적의 결정을 내리는 법을 배우는 데 필요하지 않다.


2. 사용 알고리즘: MaskablePPO

2-1 강화학습 알고리즘 계보

강화학습(RL)
├── Value-based (가치 기반)
│   ├── Q-Learning
│   └── DQN (Deep Q-Network)
│
├── Policy-based (정책 기반)
│   ├── REINFORCE
│   └── Policy Gradient
│
└── Actor-Critic (가치 + 정책 결합) ★ 우리가 사용한 방식
    ├── A2C / A3C
    ├── PPO (Proximal Policy Optimization)
    └── MaskablePPO ← 실제 프로젝트 적용 모델

2-2 세 가지 방법론 설명

Value-based (가치 기반) — "각 행동의 가치를 매긴다"

  • 상태-행동 쌍 $Q(s, a)$의 가치를 학습한다.
  • 가장 높은 Q값을 가진 행동을 선택한다.
  • 대표 알고리즘: DQN

Policy-based (정책 기반) — "행동 확률을 직접 학습한다"

  • 정책 $\pi(a|s)$ (상태 $s$에서 행동 $a$를 할 확률)를 직접 학습한다.
  • 확률 분포를 출력하므로 연속적인 행동 공간에도 적합하다.
  • 대표 알고리즘: REINFORCE, Policy Gradient

Actor-Critic (결합) — "둘 다 사용한다"

  • Actor (정책 네트워크): "어떤 행동을 할까?" → 행동 확률 출력
  • Critic (가치 네트워크): "이 상태가 얼마나 좋은가?" → 가치 평가
  • Actor가 행동하면, Critic이 "그 행동이 예상보다 좋았는지/나빴는지" 피드백을 준다.
  • 대표 알고리즘: A2C, PPO, MaskablePPO

DQN vs PPO — 왜 DQN을 안 쓰는가?

DQN (Deep Q Network) 가치 기반 알고리즘 중에 괜찮다는 얘기를 듣고 찾아봤다.

간단하게 설명하자면, "신경망을 이용하여 Q-value를 근사하는 방법입니다. Atari 게임, 로봇 제어, 복잡한 환경같은 문제에서 사용됩니다."

구분 DQN PPO (현재 사용)
방식 $Q(s,a)$ 테이블로 각 행동의 가치 학습 정책 $\pi(a|s)$를 직접 학습
행동 공간 수십 개까지 적합 170개 이상의 이산 행동도 원활히 처리
Action Masking 구현이 매우 까다로움 MaskablePPO로 네이티브 지원
안정성 불안정함 (Overestimation 문제) 클리핑을 통해 매우 안정적으로 업데이트
샘플 효율 리플레이 버퍼를 사용해 효율적임 상대적으로 덜 효율적이나 학습이 안정적

이 게임에서 DQN이 부적합한 핵심 이유

170개 행동 중 대부분이 특정 시점에 '무효'하다:

  • 그리드에 유닛이 없으면 → PLACE/SELL 불가
  • 골드가 부족하면 → SUMMON 불가
  • 재료 유닛이 없으면 → COMBINE 불가

MaskablePPO는 무효 행동을 마스킹(Action Masking)하여 AI가 유효한 행동만 고려하도록 강제한다. 이를 통해 학습 효율을 비약적으로 높일 수 있다.


PPO가 학습하는 방식 (Step-by-Step)

  1. 경험 수집: 8개 병렬 환경에서 각 4,096스텝씩 데이터를 모은다 (총 32,768개 경험).
  2. 이점(Advantage) 계산: 각 행동이 "예상(Critic의 판단)보다 얼마나 더 좋았는지" 계산한다.
    • $Advantage > 0$: 예상보다 좋았던 행동
    • $Advantage < 0$: 예상보다 나빴던 행동
  3. 정책 업데이트: "예상보다 좋았던 행동"의 확률은 올리고, 나빴던 행동의 확률은 내린다. 단, 정책이 급격히 변해 망가지는 것을 막기 위해 클리핑(clip_range=0.2)을 적용한다.
  4. 가치 네트워크 업데이트: Critic이 현재 상태의 가치를 더 정확하게 예측하도록 학습시킨다.
  5. 반복: 위 과정을 수백~수천 번 반복하며 최적의 전략을 찾아낸다.

PPO 핵심 수식

$$L^{CLIP}(\theta) = \hat{\mathbb{E}}_t \left[ \min \left( r_t(\theta) \hat{A}_t, \; \text{clip}(r_t(\theta), 1-\epsilon, 1+\epsilon) \hat{A}_t \right) \right]$$
  • $r_t(\theta) = \frac{\pi_\theta(a_t|s_t)}{\pi_{\theta_{old}}(a_t|s_t)}$: 새로운 정책과 이전 정책의 확률 비율
  • $\hat{A}_t$: 이점 추정값 (Advantage)
  • $\epsilon$: 클리핑 범위 (clip_range=0.2)

핵심 아이디어: 정책을 너무 급격히 바꾸면 학습이 산으로 갈 수 있다. 그래서 변화율 $r_t$가 $[0.8, 1.2]$ 범위를 벗어나면 강제로 잘라내어(clip) 안정성을 확보한다.


3. 하이퍼파라미터 가이드

config.py 설정값의 의미와 역할:

파라미터 값 역할
N_STEPS 4096 환경당 경험 수집량. 클수록 안정적이지만 학습 속도가 느려짐
BATCH_SIZE 2048 한 번에 학습하는 경험의 묶음 크기. GPU 메모리에 맞춰 조절
N_EPOCHS 10 수집한 데이터를 몇 번 반복해서 학습할 것인가
CLIP_RANGE 0.2 정책 변화의 제한폭. 작을수록 보수적으로 학습함
ENT_COEF 0.03 엔트로피 계수. 높으면 탐색(Exploration)을 장려, 낮으면 활용(Exploitation) 중시
GAMMA 0.998 할인 계수. 1에 가까울수록 먼 미래의 보상을 중요하게 여김
LEARNING_RATE 1e-4 학습 속도. 파인튜닝 시 낮게 설정하면 세밀한 조정 가능
GAE_LAMBDA 0.95 Generalized Advantage Estimation. 이점 추정의 분산과 편향 조절
N_ENVS 8 동시에 실행할 병렬 환경 수. CPU 코어 수에 최적화

실제 튜닝 경험

  • 엔트로피(ENT_COEF): 초기엔 다양한 시도를 위해 높게(0.05), 학습 후반부 파인튜닝 시에는 특정 전략에 집중하도록 낮게(0.03) 조정했다.
  • 할인 계수(GAMMA): 이 게임은 90라운드까지 버티는 것이 목표이므로, 눈앞의 보상보다 최종 생존을 위해 0.998이라는 높은 값을 사용했다.

4. 학습 로그 읽는 법 (Tensorboard)

| rollout/ep_rew_mean    | 553          |  ← 평균 에피소드 보상 (높을수록 성능 우수)
| rollout/ep_len_mean    | 1660         |  ← 평균 에피소드 길이 (길수록 오래 생존)
| train/entropy_loss     | -0.527       |  ← 엔트로피 (절댓값이 작아질수록 확신 있는 정책)
| train/clip_fraction    | 0.033        |  ← 클리핑 발생 비율 (낮으면 안정적으로 수렴 중)
| train/explained_var    | 0.997        |  ← 가치 추정 정확도 (1에 가까울수록 Critic이 정확함)
| train/approx_kl        | 0.0047       |  ← KL 발산 (정책 변화량, 급격한 변화 여부 판단)

핵심 지표 해석 방법

  1. explained_variance ≈ 1.0:
    • Critic이 보상을 거의 완벽하게 예측하고 있다는 신호로, 모델이 게임의 구조를 잘 이해하고 있음을 뜻한다.
  2. entropy_loss 점진적 감소:
    • 처음엔 무작위로 행동하다가 점점 특정 상황에서 최선의 수를 찾아가고 있다는 증거다.
  3. approx_kl < 0.01:
    • 업데이트가 너무 튀지 않고 안정적으로 진행되고 있음을 의미한다.

5. 프로젝트 구조 요약

학습 파이프라인

  1. game_data.py: 유닛 능력치, 조합 레시피, 보스 데이터 정의
  2. game_env.py: Python 기반의 경량 시뮬레이션 환경 (Gymnasium 표준)
  3. train.py: MaskablePPO 알고리즘으로 모델 학습 (Stable Baselines3 기반)
  4. models/: 학습이 완료된 가중치 파일 저장 (.zip)

실행(Inference) 파이프라인

  1. 모델 로드: 학습된 .zip 모델을 불러옴
  2. rl_bridge.py: 모델과 실제 게임 간의 인터페이스 (WebSocket 통신)
  3. server.js: Node.js 서버를 통한 데이터 중계 (Socket.IO)
  4. game.js: 브라우저에서 실행되는 실제 Phaser 3 게임 환경

https://github.com/gonida1010/MyDefenseGame

 

GitHub - gonida1010/MyDefenseGame: A fan-made, web-based Demon Slayer random defense game built with Phaser.js, featuring real-t

A fan-made, web-based Demon Slayer random defense game built with Phaser.js, featuring real-time multiplayer co-op, strategic unit combinations, and diverse game modes. [Phaser.js 기반의 팬메이드 '귀멸의...

github.com

 

'3. 자습 & 메모(실전, 실습, 프로젝트) > 3-2 메모(실전, 프로젝트)' 카테고리의 다른 글

[MEMO] 실사용 모드  (0) 2026.02.08
[Memo] PaddleOCR v5 REC 파이프라인 재구축 회고  (0) 2026.01.04
[PaddleOCR] 학습용 REC 데이터셋 생성 스크립트(업데이트 버전)  (0) 2026.01.04
[PaddleOCR] 학습용 REC 데이터셋 생성 스크립트  (0) 2026.01.02
[MEMO] PaddleOCR 코드 문법 인식 모델 학습  (0) 2026.01.01
'3. 자습 & 메모(실전, 실습, 프로젝트)/3-2 메모(실전, 프로젝트)' 카테고리의 다른 글
  • [MEMO] 실사용 모드
  • [Memo] PaddleOCR v5 REC 파이프라인 재구축 회고
  • [PaddleOCR] 학습용 REC 데이터셋 생성 스크립트(업데이트 버전)
  • [PaddleOCR] 학습용 REC 데이터셋 생성 스크립트
고니3000원
고니3000원
공부 내용 정리, 자기발전 블로그 입니다. 기존 네이버 블로그에서 티스토리로 이전했습니다. https://blog.naver.com/pak1010pak
  • 고니3000원
    곤이의 공부 블로그
    고니3000원
  • 전체
    오늘
    어제
    • 분류 전체보기 (178) N
      • 1. AI 논문 + 모델 분석 (20)
        • AI 논문 분석 (13)
        • AI 모델 분석 (7)
      • 2. 자료구조와 알고리즘 (16)
        • 2-1 자료구조와 알고리즘 (13)
        • 2-2 강화학습 알고리즘 (3)
      • 3. 자습 & 메모(실전, 실습, 프로젝트) (25)
        • 3-1 문제 해석 (4)
        • 3-2 메모(실전, 프로젝트) (14)
        • 3-3 배포 실전 공부 (7)
      • 4. [팀] 프로젝트 및 공모전 (14)
        • 4-1 팀 프로젝트(메모, 공부) (1)
        • 4-2 Meat-A-Eye (6)
        • 4-3 RL-Tycoon-Agent (3)
        • 4-4 구조물 안정성 물리 추론 AI 경진대회(D.. (4)
      • 5. [개인] 프로젝트 및 공모전 (0)
        • 4-1 귀멸의칼날디펜스(자바스크립트 활용) (5)
        • 4-2 바탕화면 AI 펫 프로그램 (4)
        • 4-3 개인 프로젝트(기타) (3)
      • 개념 정리 step1 (32)
        • Python 기초 (7)
        • DBMS (1)
        • HTML | CSS (3)
        • Git | GitHub (1)
        • JavaScript (5)
        • Node.js (5)
        • React (1)
        • 데이터 분석 (6)
        • Python Engineering (3)
      • 개념 정리 step2 (57) N
        • Machine | Deep Learning (15)
        • 멀티모달(Multi-modal) (23)
        • 강화 학습 (10)
        • AI Agent (9) N
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 네이버 곤이의 블로그(Naver->Tistory)
    • Github
  • 공지사항

  • 인기 글

  • 태그

    OCR학습
    프로젝트
    알고리즘
    데이터분석
    구현
    Ai
    학습
    pandas
    EfficientNet
    강화 학습
    Python
    강화학습
    Grad-CAM
    파이썬
    파인튜닝
    bottleneck
    OCR
    paddleocr
    ViT
    자료구조
    Attention Is All You Need
    공모전
    html
    transformer
    javascript
    논문 리뷰
    자바스크립트
    github
    귀칼
    Vision
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
고니3000원
[개인 공부] 강화 학습에 대한 스터디 노트
상단으로

티스토리툴바