예제 소스
문랜딩 프로그램으로 이해하는 강화학습 · 파일 6개
smoke_test.py
"""환경/에이전트 기본 동작 점검용 스크립트.
torch + pygame 까지 설치된 상태에서 다음을 검증한다:
1. MoonLanderEnv reset/step 이 정상 동작하고 상태/관측 차원이 맞는지.
2. 모든 분사기 ON/OFF 행동을 수행해도 NaN 이 발생하지 않는지.
3. 무동작 시 자유낙하로 종료(추락)되는지.
4. DQNAgent 가 학습 1 step 을 무사히 수행하는지.
사용:
python smoke_test.py
"""
from __future__ import annotations
import math
import sys
import numpy as np
def test_env_basic() -> None:
from lander_env import MoonLanderEnv
env = MoonLanderEnv(seed=0)
obs = env.reset()
assert obs.shape == (env.STATE_DIM,), obs.shape
assert np.all(np.isfinite(obs))
# 무동작 → 자유낙하로 추락
total = 0.0
for _ in range(env.MAX_STEPS + 1):
obs, r, done, info = env.step(0)
total += r
assert np.all(np.isfinite(obs))
if done:
break
assert info.result in ("crashed", "out_of_bounds", "timeout"), info.result
print(f"[ok] free-fall episode -> {info.result}, reward={total:.1f}")
def test_env_actions() -> None:
from lander_env import MoonLanderEnv
env = MoonLanderEnv(seed=1)
for action in range(env.NUM_ACTIONS):
env.reset()
for _ in range(50):
obs, r, done, info = env.step(action)
if done:
break
assert np.all(np.isfinite(obs))
print(f"[ok] all {env.NUM_ACTIONS} actions stable")
def test_main_engine_lifts() -> None:
"""메인 엔진만 켜면 적어도 짧은 시간 동안은 위로 가속해야 한다."""
from lander_env import MoonLanderEnv
env = MoonLanderEnv(seed=2, randomize=False)
env.reset()
vy0 = env.state.vy
for _ in range(10):
env.step(1) # bit 0 = main engine
assert env.state.vy > vy0, "main engine should produce upward acceleration"
print(f"[ok] main engine lifts: vy {vy0:.2f} -> {env.state.vy:.2f}")
def test_dqn_one_step() -> None:
from lander_env import MoonLanderEnv
from dqn_agent import DQNAgent, DQNConfig
env = MoonLanderEnv(seed=3)
cfg = DQNConfig(buffer_size=2_000, learn_start=100, batch_size=32)
agent = DQNAgent(cfg)
# transition 채우기
obs = env.reset()
for _ in range(200):
a = agent.act(obs)
ns, r, d, info = env.step(a)
agent.remember(obs, a, r, ns, d)
obs = env.reset() if d else ns
loss = agent.learn()
assert loss is not None and math.isfinite(loss), loss
print(f"[ok] dqn learn step: loss={loss:.4f}, device={agent.device}")
def main() -> int:
test_env_basic()
test_env_actions()
test_main_engine_lifts()
test_dqn_one_step()
print("\nall smoke tests passed.")
return 0
if __name__ == "__main__":
sys.exit(main())