๐Ÿš€ Double DQN ยท LunarLander-v3

LunarLander-v3 ๋ฅผ 1000 ์—ํ”ผ์†Œ๋“œ ํ•™์Šต์‹œํ‚จ Double DQN ์—์ด์ „ํŠธ์ž…๋‹ˆ๋‹ค. stable-baselines3 ๊ฐ™์€ RL ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์“ฐ์ง€ ์•Š๊ณ , Q๋„คํŠธ์›Œํฌ / ๋ฆฌํ”Œ๋ ˆ์ด ๋ฒ„ํผ / ํƒ€๊นƒ ๋„คํŠธ์›Œํฌ๋ฅผ PyTorch ์ฝ”๋“œ๋กœ ์ง์ ‘ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

A Double DQN agent for LunarLander-v3, trained for 1000 episodes. No RL framework (stable-baselines3 etc.) โ€” the Q-network, replay buffer and target network are plain PyTorch code.

replay

์ถœ์ฒ˜ / Provenance

์ •ํ™•ํžˆ ๋ฐํž™๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ๋Š” ๋ฐฑ์ง€์—์„œ ์ƒˆ๋กœ ์“ด ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค.

  • ๊ธฐ๋ฐ˜: ๋„๋ฆฌ ์“ฐ์ด๋Š” DQN ํŠœํ† ๋ฆฌ์–ผ ๊ตฌํ˜„(Udacity ์Šคํƒ€์ผ)์—์„œ ์ถœ๋ฐœํ•œ Colab ๋…ธํŠธ๋ถ ์ฝ”๋“œ
  • ์—ฌ๊ธฐ์— ๋”ํ•œ ๊ฒƒ: ์‹คํ–‰์ด ์•ˆ ๋˜๋˜ import ๋ˆ„๋ฝ ์ˆ˜์ •, Double DQN ์ „ํ™˜, Huber ์†์‹ค + ๊ทธ๋ž˜๋””์–ธํŠธ ํด๋ฆฌํ•‘, ์€๋‹‰์ธต 64โ†’128, ํƒ€๊นƒ๋ง ์ดˆ๊ธฐํ™” ์ •๋ฆฌ, ์ฒดํฌํฌ์ธํŠธ ํฌ๋งท, ํ‰๊ฐ€/๋…นํ™” ์Šคํฌ๋ฆฝํŠธ, ์‹ค์‹œ๊ฐ„ ์›น ๋Œ€์‹œ๋ณด๋“œ, ์ฐฉ๋ฅ™ ํ’ˆ์งˆ ์ ์ˆ˜
  • ์ž‘์„ฑ: ์œ„ ์ˆ˜์ •ยทํ™•์žฅ๊ณผ ๋ฌธ์„œํ™”๋Š” Claude (Claude Code) ์˜ ๋„์›€์„ ๋ฐ›์•„ ์ง„ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

Honest attribution: this is not a from-scratch implementation. It starts from a widely circulated DQN tutorial notebook (Udacity-style), with bug fixes and the additions listed above; that work and this model card were done with the help of Claude (Claude Code).

์„ฑ๋Šฅ / Results

์•„๋ž˜ ์ˆ˜์น˜๋Š” ํ•™์Šต์ด ๋๋‚œ ๋ชจ๋ธ์„ 100๋ฒˆ ์ฐฉ๋ฅ™์‹œ์ผœ ์žฐ ํ‰๊ฐ€ ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค (ํ•™์Šต ์ž์ฒด๋Š” 1000 ์—ํ”ผ์†Œ๋“œ ยท ํƒํ—˜ ์—†์Œ ฮต=0 ยท ๊ณ ์ • ์‹œ๋“œ, evaluate.py --episodes 100). Evaluation over 100 episodes of the finished agent (training itself ran for 1000 episodes).

์ฒดํฌํฌ์ธํŠธ ํ‰๊ท  ๋ณด์ƒ ์ฐฉ๋ฅ™ ์„ฑ๊ณต๋ฅ  ํ‰๊ท  ์ฐฉ๋ฅ™ ํ’ˆ์งˆ
lunarlander_dqn.pth (๊ธฐ๋ณธ) 223.14 ยฑ 84.58 74% 61.3 / 100
lunarlander_dqn_softlanding.pth 203.30 ยฑ 62.41 84% 64.5 / 100
  • ํ‰๊ท  ๋ณด์ƒ์ด ๋†’์€ ์ชฝ์€ ๊ธฐ๋ณธ ๋ชจ๋ธ, ๊น”๋”ํ•˜๊ฒŒ ์ฐฉ์ง€ํ•˜๋Š” ๋นˆ๋„๋Š” soft-landing ์ชฝ์ด ๋†’์Šต๋‹ˆ๋‹ค.
  • ํ•™์Šต 1000ํŒ ์ค‘ 498ํŒ์งธ์— 200์  ๊ธฐ์ค€์„ ๋ŒํŒŒํ–ˆ๊ณ , ์ดํ›„ ๊ณ„์† ํ•™์Šตํ•ด 1000ํŒ์„ ์ฑ„์› ์Šต๋‹ˆ๋‹ค.
  • ํ•™์Šต ์ค‘(ฮต=0.05) ์ตœ๊ทผ 100ํŒ ์ด๋™ํ‰๊ท  ์ตœ๊ณ  ๊ธฐ๋ก: 260.5์ , ๊ทธ ๊ตฌ๊ฐ„ ์ฐฉ๋ฅ™ ์„ฑ๊ณต๋ฅ  97~98% (์ด๋™ํ‰๊ท ์˜ "100"์€ ํ‰๊ท ์„ ๋‚ด๋Š” ์ฐฝ ํฌ๊ธฐ์ด์ง€, ํ•™์Šต ํŒ์ˆ˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.)

The default checkpoint scores higher on mean reward; the softlanding one lands cleanly more often (its failures are mostly hovering until timeout rather than crashes).

์‚ฌ์šฉ๋ฒ• / Usage

import gymnasium as gym, torch
from huggingface_hub import hf_hub_download
from dqn_agent import Agent          # ์ด ์ €์žฅ์†Œ์˜ dqn_agent.py

ckpt = hf_hub_download("SionJang/lunarlander-v3-double-dqn", "lunarlander_dqn.pth")
env = gym.make("LunarLander-v3", render_mode="human")
agent = Agent(env.observation_space.shape[0], int(env.action_space.n)).load(ckpt)

state, _ = env.reset()
done = False
while not done:
    action = agent.act(state, 0.0)      # eps=0 โ†’ ํƒํ—˜ ์—†์ด ์‹ค๋ ฅ๋งŒ
    state, reward, terminated, truncated, _ = env.step(action)
    done = terminated or truncated
env.close()

์ €์žฅ์†Œ์— ๋“ค์–ด ์žˆ๋Š” ์Šคํฌ๋ฆฝํŠธ๋กœ ๋ฐ”๋กœ ๋Œ๋ฆด ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:

python evaluate.py --ckpt lunarlander_dqn.pth --episodes 100   # ํ‰๊ฐ€
python watch.py    --ckpt lunarlander_dqn.pth                  # ์›น์œผ๋กœ ๊ฐ์ƒ
python record_gif.py --ckpt lunarlander_dqn.pth                # GIF ๋…นํ™”
python train.py --episodes 1000                                # ์ฒ˜์Œ๋ถ€ํ„ฐ ์žฌํ•™์Šต

ํ•™์Šต ์„ค์ • / Training setup

ํ•ญ๋ชฉ ๊ฐ’
์•Œ๊ณ ๋ฆฌ์ฆ˜ Double DQN (ํ–‰๋™ ์„ ํƒ = ํ•™์Šต๋ง, ๊ฐ€์น˜ ํ‰๊ฐ€ = ํƒ€๊นƒ๋ง)
์‹ ๊ฒฝ๋ง 8 โ†’ 128 โ†’ 128 โ†’ 4 (ReLU)
์˜ตํ‹ฐ๋งˆ์ด์ € Adam, lr 5e-4
์†์‹ค Huber (smooth L1), grad clip 10
ํƒํ—˜ ฮต 1.0 โ†’ 0.05, ํŒ๋งˆ๋‹ค ร—0.995
์—ํ”ผ์†Œ๋“œ 1000 (ํŒ๋‹น ์ตœ๋Œ€ 1000 ์Šคํ…)
๋ฆฌํ”Œ๋ ˆ์ด ๋ฒ„ํผ 100,000 / ๋ฐฐ์น˜ 64 / 4์Šคํ…๋งˆ๋‹ค ํ•™์Šต
ํƒ€๊นƒ๋ง soft update ฯ„ = 0.001
๊ฐ๋งˆ 0.99
ํ•™์Šต ์‹œ๊ฐ„ ์•ฝ 28๋ถ„ (Intel i7-11800H, CPU๋งŒ ์‚ฌ์šฉ / CUDA ๋ฏธ์‚ฌ์šฉ)

์ฐฉ๋ฅ™ ํ’ˆ์งˆ ์ ์ˆ˜ (Landing style score)

ํ™˜๊ฒฝ ๋ณด์ƒ์€ "์„ฑ๊ณตํ–ˆ๋Š”๊ฐ€"๋งŒ ๋ณด๊ธฐ ๋•Œ๋ฌธ์—, "์–ผ๋งˆ๋‚˜ ๊น”๋”ํ•˜๊ฒŒ ๋‚ด๋ ธ๋Š”๊ฐ€"๋ฅผ ๋”ฐ๋กœ 0~100์œผ๋กœ ๋งค๊ฒผ์Šต๋‹ˆ๋‹ค (style_score.py). The env reward only tells you whether it landed; this extra score measures how well.

ํ•ญ๋ชฉ ๋ฐฐ์  ๊ธฐ์ค€
์ค‘์•™ ์ •ํ™•๋„ 40 ์ฐฉ๋ฅ™๋Œ€ ์ •์ค‘์•™์— ๊ฐ€๊นŒ์šธ์ˆ˜๋ก
์ ‘์ง€ ๋ถ€๋“œ๋Ÿฌ์›€ 25 ์ ‘์ง€ ์†๋„๊ฐ€ ๋А๋ฆด์ˆ˜๋ก
์ž์„ธ ์ˆ˜ํ‰ 20 ๊ธฐ์šธ๊ธฐยทํšŒ์ „์ด ์ ์„์ˆ˜๋ก
์—ฐ๋ฃŒ ์ ˆ์•ฝ 15 ์—”์ง„ ์ ํ™” ๋น„์œจ์ด ๋‚ฎ์„์ˆ˜๋ก

๋“ฑ๊ธ‰ / grades: S(90+) A(80+) B(65+) C(45+) D

์‹ค์‹œ๊ฐ„ ํ•™์Šต ๋Œ€์‹œ๋ณด๋“œ / Live training dashboard

train.py๋Š” ํ•™์Šต ๊ณผ์ •์„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ณด์—ฌ์ฃผ๋Š” ์›น ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ํ•จ๊ป˜ ๋„์›๋‹ˆ๋‹ค (http://127.0.0.1:7000). Flask ๊ฐ™์€ ์›น ํ”„๋ ˆ์ž„์›Œํฌ ์—†์ด ํŒŒ์ด์ฌ ํ‘œ์ค€ http.server ๋กœ ๋Œ์•„๊ฐ€๊ณ , ํ™”๋ฉด ํ”„๋ ˆ์ž„์„ JPEG๋กœ ๋ฐ”๊พธ๋Š” ๋ฐ๋งŒ Pillow๋ฅผ ์”๋‹ˆ๋‹ค. ์‹ค์‹œ๊ฐ„ ์ฐฉ๋ฅ™ ํ™”๋ฉด + HUD, ํ•™์Šต ๊ณก์„ , ฮต ๊ฐ์†Œ ๊ณก์„ , ์ฐฉ๋ฅ™ ํ’ˆ์งˆ ์ ์ˆ˜, ์ž˜๋œ ์ฐฉ๋ฅ™ GIF ๋ชจ์Œ์ด ๋“ค์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

train.py also serves a live dashboard โ€” no web framework, just the stdlib http.server (plus Pillow for JPEG encoding of frames): streamed render of the lander, telemetry HUD, learning curve, ฮต schedule, and a hall of fame of the best landings.

ํ•œ๊ณ„ / Limitations

  • ์‹คํŒจ ์‚ฌ๋ก€ ๋Œ€๋ถ€๋ถ„์€ ์ถ”๋ฝ์ด ์•„๋‹ˆ๋ผ ์ฐฉ๋ฅ™๋Œ€ ์œ„์—์„œ ๋งด๋Œ๋‹ค 1000์Šคํ… ํƒ€์ž„์•„์›ƒ์ž…๋‹ˆ๋‹ค. ฮต=0์˜ ๊ฒฐ์ •๋ก ์  ์ •์ฑ…์ด ๊ฐ€์ง„ ์ „ํ˜•์  ์•ฝ์ ์ž…๋‹ˆ๋‹ค.
  • ํ‘œ์ค€ํŽธ์ฐจ๊ฐ€ ํฝ๋‹ˆ๋‹ค(ยฑ85). ์‹œ๋“œ์— ๋”ฐ๋ผ ํŽธ์ฐจ๊ฐ€ ์žˆ์œผ๋‹ˆ ์žฌํ˜„ ์‹œ ์ฐธ๊ณ ํ•˜์„ธ์š”.
Downloads last month
-
Video Preview
loading

Evaluation results