ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • โœฑ ํ•ธ์ฆˆ์˜จ ๋จธ์‹ ๋Ÿฌ๋‹ 18์žฅ ๊ฐ•ํ™” ํ•™์Šต โœฑ
    ๐Ÿฎ ์ด๊ฒƒ์ €๊ฒƒ ๊ณต๋ถ€/โœฉ ํ•ธ์ฆˆ์˜จ ๋จธ์‹ ๋Ÿฌ๋‹ 2026. 2. 6. 20:33

    18.1 ๋ณด์ƒ์„ ์ตœ์ ํ™”ํ•˜๊ธฐ ์œ„ํ•œ ํ•™์Šต

    ๊ฐ•ํ™” ํ•™์Šต์—์„œ ์†Œํ”„ํŠธ์›จ์–ด ์—์ด์ „ํŠธ๋Š” ๊ด€์ธก์„ ํ•˜๊ณ  ์ฃผ์–ด์ง„ ํ™˜๊ฒฝ์—์„œ ํ–‰๋™์„ ํ•œ๋‹ค. 

    ๊ทธ๋ฆฌ๊ณ  ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ ํ™˜๊ฒฝ์œผ๋กœ๋ถ€ํ„ฐ ๋ณด์ƒ์„ ๋ฐ›๋Š”๋‹ค. 

    ์—์ด์ „ํŠธ์˜ ๋ชฉ์ ์€ ๋ณด์ƒ์˜ ์žฅ๊ธฐ๊ฐ„ ๊ธฐ๋Œ€์น˜๋ฅผ ์ตœ๋Œ€๋กœ ๋งŒ๋“œ๋Š” ํ–‰๋™์„ ํ•™์Šตํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

    ์–‘์˜ ๋ณด์ƒ์€ ๊ธฐ์จ์œผ๋กœ, ์Œ์˜ ๋ณด์ƒ์€ ์•„ํ””์œผ๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.


    18.2 ์ •์ฑ… ํƒ์ƒ‰

    ์ •์ฑ… : ์†Œํ”„ํŠธ์›จ์–ด ์—์ด์ „ํŠธ๊ฐ€ ํ–‰๋™์„ ๊ฒฐ์ •ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค. 

    ์˜ˆ) ๊ด€์ธก์„ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›๊ณ  ์ˆ˜ํ–‰ํ•  ํ–‰๋™์„ ์ถœ๋ ฅํ•˜๋Š” ์‹ ๊ฒฝ๋ง

    ์ •์ฑ…์€ ๋ชจ๋“  ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ฒฐ์ •์ ์ผ ํ•„์š”๋Š” ์—†๋‹ค. ์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” ํ™˜๊ฒฝ์„ ๊ด€์ธกํ•  ํ•„์š”๋„ ์—†๋‹ค.

    ๋ฌด์ž‘์œ„์„ฑ์ด ํฌํ•จ๋˜์–ด ์žˆ๋Š” ์ •์ฑ…์„ ํ™•๋ฅ ์  ์ •์ฑ…์ด๋ผ๊ณ  ํ•œ๋‹ค. 

     

    ์˜ˆ) 30๋ถ„ ๋™์•ˆ ์ˆ˜์ง‘ํ•œ ๋จผ์ง€์˜ ์–‘์„ ๋ณด์ƒ์œผ๋กœ ๋ฐ›๋Š” ๋กœ๋ด‡ ์ง„๊ณต์ฒญ์†Œ๊ธฐ๊ฐ€ ์žˆ๋‹ค.

    ์—ฌ๊ธฐ์—๋Š” ๋ณ€๊ฒฝ์ด ๊ฐ€๋Šฅํ•œ ๋‘ ๊ฐœ์˜ ์ •์ฑ… ํŒŒ๋ผ๋ฏธํ„ฐ์ธ ํ™•๋ฅ  p์™€ ๊ฐ๋„์˜ ๋ฒ”์œ„ r์ด ์žˆ๋‹ค. 

    ์ด ํŒŒ๋ผ๋ฏธํ„ฐ์— ๋งŽ์€ ๋‹ค๋ฅธ ๊ฐ’์„ ์‹œ๋„ํ•ด๋ณด๊ณ  ๊ฐ€์žฅ ์„ฑ๋Šฅ์ด ์ข‹์€ ์กฐํ•ฉ์„ ๊ณ ๋ฅด๋Š” ํ•™์Šต ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

    ํ•˜์ง€๋งŒ ์ •์ฑ… ๊ณต๊ฐ„์ด ๋งค์šฐ ํฐ ๊ฒฝ์šฐ์— ์ข‹์€ ํŒŒ๋ผ๋ฏธํ„ฐ ์กฐํ•ฉ์„ ์ฐพ๋Š” ๋ฐ์— ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฐ๋‹ค. 

     

    ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ ์œ ์ „ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์žˆ๋‹ค. 

    ์˜ˆ) 1์„ธ๋Œ€ ์ •์ฑ… 100๊ฐœ๋ฅผ ๋žœ๋คํ•˜๊ฒŒ ์ƒ์„ฑํ•ด์„œ ์‹œ๋„ํ•ด๋ณธ ๋’ค, ์„ฑ๋Šฅ์ด ๋‚ฎ์€ ์ •์ฑ… 80๊ฐœ๋Š” ๋ฒ„๋ฆฌ๊ณ  20๊ฐœ๋ฅผ ์‚ด๋ ค ๊ฐ๊ฐ ์ž์‹ ์ •์ฑ… 4๊ฐœ๋ฅผ ์ƒ์‚ฐํ•œ๋‹ค.

    ์ด ์ž์‹ ์ •์ฑ…์€ ๋ถ€๋ชจ๋ฅผ ๋ณต์‚ฌํ•œ ๊ฒƒ์ด ์•ฝ๊ฐ„์˜ ๋ฌด์ž‘์œ„์„ฑ์„ ๋”ํ•œ ๊ฒƒ์ด๋‹ค.

    ์‚ด์•„๋‚จ์€ ์ •์ฑ…๊ณผ ๊ทธ ์ž์‹์€ 2์„ธ๋Œ€๋ฅผ ๊ตฌ์„ฑํ•˜๋ฉฐ, ์ด๋Ÿฐ ์‹์œผ๋กœ ์ข‹์€ ์ •์ฑ…์„ ์ฐพ์„ ๋•Œ๊นŒ์ง€ ์—ฌ๋Ÿฌ ์„ธ๋Œ€์— ๊ฑธ์ณ ๋ฐ˜๋ณตํ•œ๋‹ค.

    ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ ์ •์ฑ… ํŒŒ๋ผ๋ฏธํ„ฐ์— ๋Œ€ํ•œ ๋ณด์ƒ์˜ ๊ทธ๋ ˆ์ด๋””์–ธํŠธ๋ฅผ ํ‰๊ฐ€ํ•ด์„œ ๋†’์€ ๋ณด์ƒ์˜ ๋ฐฉํ–ฅ์„ ๋”ฐ๋ฅด๋Š” ๊ทธ๋ ˆ์ด๋””์–ธํŠธ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ์ตœ์ ํ™” ๊ธฐ๋ฒ•์ด ์žˆ๋‹ค. (์ •์ฑ… ๊ทธ๋ ˆ์ด๋””์–ธํŠธ(PG))

    ์˜ˆ) ๋กœ๋ด‡์ฒญ์†Œ๊ธฐ์˜ ์˜ˆ์—์„œ p๋ฅผ ์กฐ๊ธˆ ์ฆ๊ฐ€์‹œ์ผœ์„œ 30๋ถ„ ๋™์•ˆ ๋กœ๋ด‡์ด ์ˆ˜์ง‘ํ•œ ๋จผ์ง€ ์–‘์ด ์ฆ๊ฐ€ํ–ˆ๋Š”์ง€ ํ‰๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

    ๋จผ์ง€ ์–‘์ด ๋งŽ์•„์กŒ๋‹ค๋ฉด P๋ฅผ ์กฐ๊ธˆ ์ฆ๊ฐ€์‹œํ‚ค๊ณ  ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด p๋ฅผ ๊ฐ์†Œ์‹œํ‚จ๋‹ค.

    PG ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ํ…์„œํ”Œ๋กœ๋ฅผ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„ํ•˜์ง€๋งŒ ๊ทธ์ „์— ์—์ด์ „ํŠธ๊ฐ€ ํ™œ๋™ํ•  ํ™˜๊ฒฝ์„ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.


    18.3 OpenAI Gym

    ๊ฐ•ํ™” ํ•™์Šต์—์„œ ์–ด๋ ค์šด ์ ์€ ์—์ด์ „ํŠธ๋ฅผ ํ›ˆ๋ จํ•˜๊ธฐ ์œ„ํ•ด ๋จผ์ € ์ž‘์—… ํ™˜๊ฒฝ์„ ๋งˆ๋ จํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

    ์‹ค์ œ ์„ธ์ƒ์—์„œ ํ›ˆ๋ จํ•˜๋Š” ๊ฒƒ์€ ์–ด๋ ต๊ณ  ๋А๋ฆฌ๊ธฐ์— ํ›ˆ๋ จ์„ ์œ„ํ•œ ์ตœ์†Œํ•œ์˜ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ ํ™˜๊ฒฝ์ด ํ•„์š”ํ•˜๋‹ค.

     

    OpenAI Gym์€ ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜์˜ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ ํ™˜๊ฒฝ(์•„ํƒ€๋ฆฌ ๊ฒŒ์ž„, ๋ณด๋“œ ๊ฒŒ์ž„, 2D์™€ 3D ๋ฌผ๋ฆฌ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ ๋“ฑ)์„ ์ œ๊ณตํ•˜๋Š” ํˆด๊นƒ์œผ๋กœ, ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—์ด์ „ํŠธ๋ฅผ ํ›ˆ๋ จํ•˜๊ณ  ์ด๋“ค์„ ๋น„๊ตํ•˜๊ฑฐ๋‚˜ ์ƒˆ๋กœ์šด RL ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋‹ค.

     

    %pip install -q -U gymnasium
    %pip install swig
    %pip install -q -U gymnasium[classic_control, box2d, atari, accept-rom-license]

    ์ฒซ ๋ฒˆ์งธ %pip ๋ช…๋ น์€ Gym์„ ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•œ๋‹ค.

    -q ์˜ต์…˜์€ ์กฐ์šฉํžˆ ์„ค์น˜ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๋ฉฐ ์žฅํ™ฉํ•œ ์ถœ๋ ฅ์„ ๋งŒ๋“ค์ง€ ์•Š๊ณ , -U ์˜ต์…˜์€ ์—…๊ทธ๋ ˆ์ด๋“œ๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

    ๋‘ ๋ฒˆ์งธ %pip ๋ช…๋ น์€ ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜์˜ ํ™˜๊ฒฝ์„ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•œ๋‹ค. ์นดํŠธ์—์„œ ๋ง‰๋Œ€์˜ ๊ท ํ˜•์„ ์žก์€ ๊ฒƒ๊ณผ ๊ฐ™์€ ๊ณ ์ „์ ์ธ ์ œ์–ด ์ด๋ก ์˜ ํ™˜๊ฒฝ์ด ํฌํ•จ๋œ๋‹ค.

    import gymnasium as gym
     
    env = gym.make("CartPole-v1", render_mode="rgb_array")

    Gym์„ ์ž„ํฌํŠธํ•˜๊ณ  ํ™˜๊ฒฝ์„ ๋งŒ๋“ ๋‹ค.

    CartPole ํ™˜๊ฒฝ์„ ๋งŒ๋“ ๋‹ค. ์นดํŠธ ์œ„์— ๋†“์ธ ๋ง‰๋Œ€๊ฐ€ ๋„˜์–ด์ง€์ง€ ์•Š๋„๋ก ์™ผ์ชฝ์ด๋‚˜ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ๊ฐ€์†ํ•  ์ˆ˜ ์žˆ๋Š” 2D ์‹œ๋ฎฌ๋ ˆ์ด์…˜์ด๋‹ค.

    obs, info = env.reset(seed=42)
    obs
    # array([ 0.0273956, -0.00611216, 0.03585979, 0.0197368 ], dtype=float32)
    info
    # {}

    ํ™˜๊ฒฝ์„ ๋งŒ๋“  ํ›„ reset() ๋ฉ”์„œ๋“œ๋กœ ์ดˆ๊ธฐํ™”ํ•ด์•ผ ํ•œ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ์ฒซ ๋ฒˆ์งธ ๊ด€์ธก์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๊ด€์ธก์€ ํ™˜๊ฒฝ์˜ ์ข…๋ฅ˜์— ๋”ฐ๋ผ ๋‹ค๋ฅด๋‹ค.

    CartPole ํ™˜๊ฒฝ์˜ ๊ฒฝ์šฐ ๊ฐ ๊ด€์ธก์€ ๋„ค ๊ฐœ์˜ ์‹ค์ˆ˜๋ฅผ ๋‹ด์€ 1D ๋„˜ํŒŒ์ด ๋ฐฐ์—ด์ด๋‹ค.

    ์ด ์‹ค์ˆ˜๋Š” ์นดํŠธ์˜ ์ˆ˜ํ‰ ์œ„์น˜(0.0 = ์ค‘์•™), ์นดํŠธ์˜ ์†๋„(์–‘์ˆ˜๋Š” ์šฐ์ธก ๋ฐฉํ–ฅ์„ ์˜๋ฏธ), ๋ง‰๋Œ€์˜ ๊ฐ๋„(0.0 = ์ˆ˜์ง), ๋ง‰๋Œ€์˜ ๊ฐ์†๋„(์–‘์ˆ˜๋Š” ์‹œ๊ณ„ ๋ฐฉํ–ฅ์„ ์˜๋ฏธ)๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.

    reset() ๋ฉ”์„œ๋“œ๋Š” ์ถ”๊ฐ€์ ์œผ๋กœ ํ™˜๊ฒฝ์— ๊ด€๋ จ๋œ ์ •๋ณด๋ฅผ ๋‹ด์€ ๋”•์…”๋„ˆ๋ฆฌ๋„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

    CartPole ํ™˜๊ฒฝ

    img = env.render()
    img.shape # ๋†’์ด, ๋„ˆ๋น„, ์ฑ„๋„
    # (400, 600, 3)

    render() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด ์ด ํ™˜๊ฒฝ์„ ์ด๋ฏธ์ง€๋กœ ๋ Œ๋”๋งํ•œ๋‹ค.

    ์ด ํ™˜๊ฒฝ์„ ๋งŒ๋“ค ๋–„ render_mode="rgb_array"๋กœ ์ง€์ •ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฏธ์ง€๋Š” ๋„˜ํŒŒ์ด ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค.

    env.action_space
    # Discrete(2)

    ๋งทํ”Œ๋กฏ๋ฆฝ์˜ imshow() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์ด๋ฏธ์ง€๋ฅผ ํ™”๋ฉด์— ๊ทธ๋ฆด ์ˆ˜ ์žˆ๋‹ค.

    Discrete(2)๋Š” ๊ฐ€๋Šฅํ•œ ํ–‰๋™์ด ์ •์ˆ˜ 0๊ณผ 1์ด๋ผ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. (์™ผ์ชฝ ๊ฐ€์†, ์˜ค๋ฅธ์ชฝ ๊ฐ€์†)

    ๋‹ค๋ฅธ ํ™˜๊ฒฝ์€ ๋” ๋งŽ์€ ๊ฐœ๋ณ„์ ์ธ ํ–‰๋™์„ ๊ฐ€์ง€๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ํ–‰๋™(์˜ˆ. ์—ฐ์†์ ์ธ)์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

    action = 1 # ์˜ค๋ฅธ์ชฝ์œผ๋กœ ๊ฐ€์†
    obs, reward, done, truncated, info = env.step(action)
    obs
    # array([ 0.02727336, 0.18847767, 0.03625453, -0.26141977], dtype=float32)
    reward
    # 1.0
    done
    # False
    truncated
    # False
    info
    # {}

    ๋ง‰๋Œ€๊ฐ€ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ๊ธฐ์šธ์–ด์ ธ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์นดํŠธ๋ฅผ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ๊ฐ€์†ํ•  ์ˆ˜ ์žˆ๋‹ค.

    step() ๋ฉ”์„œ๋“œ๋Š” ์ฃผ์–ด์ง„ ํ–‰๋™์„ ์‹คํ–‰ํ•˜๊ณ  ๋„ค ๊ฐ€์ง€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

     

    obs : ์ƒˆ๋กœ์šด ๊ด€์ธก๊ฐ’์ด๋‹ค. ์ด์ œ ์นดํŠธ๊ฐ€ ์˜ค๋ฅธ์ชฝ ๋ฐฉํ–ฅ์œผ๋กœ ์›€์ง์ธ๋‹ค. (obs[1] > 0). ๋ง‰๋Œ€๊ฐ€ ์—ฌ์ „ํžˆ ์˜ค๋ฅธ์ชฝ ๋ฐฉํ–ฅ์œผ๋กœ ๊ธฐ์šธ์–ด์ ธ ์žˆ์ง€๋งŒ (obs[2] > 0) ๊ฐ์†๋„๊ฐ€ ์Œ์ˆ˜๊ฐ€ ๋˜์—ˆ์œผ๋ฏ€๋กœ (obs[3] < 0) ๋‹ค์Œ ์Šคํ… ํ›„์—๋Š” ์™ผ์ชฝ์œผ๋กœ ๊ธฐ์šธ์–ด์งˆ ๊ฐ€๋Šฅ์„ฑ์ด ํฌ๋‹ค.

    reward : ์ด ํ™˜๊ฒฝ์—์„œ๋Š” ์–ด๋–ค ํ–‰๋™์„ ์‹คํ–‰ํ•ด๋„ ๋งค ์Šคํ…๋งˆ๋‹ค 1.0์˜ ๋ณด์ƒ์„ ๋ฐ›๋Š”๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ์‹œ์Šคํ…œ์˜ ๋ชฉ์ ์€ ๊ฐ€๋Šฅํ•œ ํ•œ ์˜ค๋žซ๋™์•ˆ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

    doen : ์ด ๊ฐ’์ด True์ด๋ฉด ์ด ์—ํ”ผ์†Œ๋“œ๊ฐ€ ๋๋‚œ ๊ฒƒ์ด๋‹ค. ๋ง‰๋Œ€๊ฐ€ ๋„ˆ๋ฌด ๊ธฐ์šธ์–ด์ง€๊ฑฐ๋‚˜ ํ™”๋ฉด ๋ฐ–์œผ๋กœ ๋‚˜๊ฐ€๊ฑฐ๋‚˜ 200 ์Šคํ…์„ ๋„˜๊ธฐ๋ฉด ์—ํ”ผ์†Œ๋“œ๊ฐ€ ๋๋‚œ๋‹ค. (๋งˆ์ง€๋ง‰์˜ ๊ฒฝ์šฐ ์—์ด์ „ํŠธ๊ฐ€ ์ด๊ธด ๊ฒƒ์ด๋‹ค.). ์—ํ”ผ์†Œ๋“œ๊ฐ€ ๋๋‚˜๋ฉด ํ™˜๊ฒฝ์„ ๋‹ค์‹œ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ๊ผญ ์ดˆ๊ธฐํ™”ํ•ด์•ผ ํ•œ๋‹ค.

    trundated : ์ด ๊ฐ’์€ ์—ํ”ผ์†Œ๋“œ๊ฐ€ ์กฐ๊ธฐ์— ์ค‘๋‹จ๋˜๋Š” ๊ฒฝ์šฐ True๊ฐ€ ๋œ๋‹ค. ์ผ๋ถ€ RL ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ค‘๋‹จ๋œ ์—ํ”ผ์†Œ๋“œ๋ฅผ ์ •์ƒ์ ์œผ๋กœ ์™„๋ฃŒ๋œ ์—ํ”ผ์†Œ๋“œ์™€ ๋‹ค๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•˜์ง€๋งŒ ์ด ์žฅ์—์„œ๋Š” ๋™์ผํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•œ๋‹ค.

    info : reset() ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ’์ฒ˜๋Ÿผ ํ™˜๊ฒฝ์— ๊ด€๋ จ๋œ ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ๋‹ด์€ ๋”•์…”๋„ˆ๋ฆฌ์ด๋‹ค. 

     

    def basic_policy(obs)::
        angle = obs[2]
        return 0 if angle < 0 else 1
        
    totals = []
    for episode in range(500):
        episode_rewards = 0
        obs, info = env.reset(seed=episode)
        for step in range(200):
            action = basic_policy(obs)
            obs, reward, done, truncated, info = env.step(action)
            episode_rewards += reward
            if done or truncated:
                break
        
        totals.append(episode_rewards)

    ์ด ์ •์ฑ…์€ ๋ง‰๋Œ€๊ฐ€ ์™ผ์ชฝ์œผ๋กœ ๊ธฐ์šธ์–ด์ง€๋ฉด ์นดํŠธ๋ฅผ ์™ผ์ชฝ์œผ๋กœ ๊ฐ€์†ํ•˜๊ณ  ์˜ค๋ฅธ์ชฝ์œผ๋กœ ๊ธฐ์šธ์–ด์ง€๋ฉด ์˜ค๋ฅธ์ชฝ์œผ๋กœ ๊ฐ€์†ํ•œ๋‹ค.

    import numpy as np
    np.mean(totals), np.std(totals), min(totals), max(totals)
    # (41.698, 8.389445512070509, 24.0, 63.0)

    18.4 ์‹ ๊ฒฝ๋ง ์ •์ฑ…

    ์‹ ๊ฒฝ๋ง์€ ๊ด€์ธก์„ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›๊ณ  ์‹คํ–‰ํ•  ํ–‰๋™์„ ์ถœ๋ ฅํ•œ๋‹ค.

    ๊ฐ ํ–‰๋™์— ๋Œ€ํ•œ ํ™•๋ฅ ์„ ์ถ”์ •ํ•˜๊ณ  ์ถ”์ •๋œ ํ™•๋ฅ ์— ๋”ฐ๋ผ ๋žœ๋คํ•˜๊ฒŒ ํ–‰๋™์„ ์„ ํƒํ•œ๋‹ค.

    ๋žœ๋คํ•˜๊ฒŒ ํ–‰๋™์„ ์„ ํƒํ•˜๋ฉด ์—์ด์ „ํŠธ๊ฐ€ ์ƒˆ๋กœ์šด ํ–‰๋™์„ ํƒํ—˜ํ•˜๋Š” ๊ฒƒ๊ณผ ์ž˜ ํ•  ์ˆ˜ ์žˆ๋Š” ํ–‰๋™์„ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ ์‚ฌ์ด์— ๊ท ํ˜•์„ ๋งž์ถ”๊ฒŒ ๋œ๋‹ค. 

    ์ด๋Ÿฐ ํŠน๋ณ„ํ•œ ํ™˜๊ฒฝ์—์„œ๋Š” ๊ณผ๊ฑฐ์˜ ํ–‰๋™๊ณผ ๊ด€์ธก์„ ๋ฌด์‹œํ•  ์ˆ˜ ์žˆ๋‹ค. 

    ๊ฐ ๊ด€์ธก์ด ํ™˜๊ฒฝ์— ๋Œ€ํ•œ ์™„์ „ํ•œ ์ƒํƒœ๋ฅผ ๋‹ด๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. 

    ๋งŒ์•ฝ ์–ด๋–ค ์ƒํƒœ๊ฐ€ ์ˆจ๊ฒจ์ ธ ์žˆ์„ ๋•Œ ๊ณผ๊ฑฐ์˜ ํ–‰๋™๊ณผ ๊ด€์ธก๋„ ๊ณ ๋ คํ•ด์•ผ ํ•œ๋‹ค. 

    ๊ด€์ธก์— ์žก์Œ์ด ์žˆ์„ ๋•Œ๋Š” ๊ฐ€์žฅ ๊ฐ€๋Šฅ์„ฑ ์žˆ๋Š” ํ˜„์žฌ์˜ ์ƒํƒœ๋ฅผ ์ถ”์ •ํ•˜๊ธฐ ์œ„ํ•ด ์ง€๋‚œ ๊ด€์ธก ๋ช‡ ๊ฐœ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

     

    import tensorflow as tf
    
    model = tf.keras.Sequential([
        tf.keras.layers.Dense(5, activation="relu"),
        tf.keras.layers.Dense(1, activation="sigmoid"),
    ])

    Sequential ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•ด ์ •์ฑ… ๋„คํŠธ์›Œํฌ๋ฅผ ์ €์˜ํ•œ๋‹ค.

    ์ž…๋ ฅ์˜ ๊ฐœ์ˆ˜๋Š” ๊ด€์ธก ๊ณต๊ฐ„์˜ ํฌ๊ธฐ์ด๋‹ค. ์ด ๊ฒฝ์šฐ๋Š” 4์ด๋ฉฐ, ๊ฐ„๋‹จํ•œ ๋ฌธ์ œ์ด๋ฏ€๋กœ ์€๋‹‰ ์œ ๋‹› 5๊ฐœ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

    ๋งˆ์ง€๋ง‰์œผ๋กœ ํ•˜๋‚˜์˜ ํ™•๋ฅ (์™ผ์ชฝ ๋ฐฉํ–ฅ์ผ ํ™•๋ฅ )์ด ํ•„์š”ํ•˜๋ฏ€๋กœ ์‹œ๊ทธ๋ชจ์ด๋“œ ํ™œ์„ฑํ™” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ ํ•˜๋‚˜์˜ ์ถœ๋ ฅ ๋‰ด๋Ÿฐ์„ ๋‘”๋‹ค.

    ๋งŒ์•ฝ ๊ฐ€๋Šฅํ•œ ํ–‰๋™์ด ๋‘ ๊ฐœ๋ณด๋‹ค ๋งŽ์œผ๋ฉด ํ–‰๋™๋งˆ๋‹ค ํ•˜๋‚˜์˜ ์ถœ๋ ฅ ๋‰ด๋Ÿฐ์„ ๋‘๊ณ  ์†Œํ”„ํŠธ๋งฅ์Šค ํ™œ์„ฑํ™” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.


    18.5 ํ–‰๋™ ํ‰๊ฐ€: ์‹ ์šฉ ํ• ๋‹น ๋ฌธ์ œ

    ๊ฐ ์Šคํ…์—์„œ ๊ฐ€์žฅ ์ข‹์€ ํ–‰๋™์ด ๋ฌด์—‡์ธ์ง€ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด ํ‰์†Œ์ฒ˜๋Ÿผ ์ถ”์ •๋œ ํ™•๋ฅ ๊ณผ ํƒ€๊นƒ ํ™•๋ฅ  ์‚ฌ์ด์˜ ํฌ๋กœ์Šค ์—”ํŠธ๋กœํ”ผ๋ฅผ ์ตœ์†Œํ™”ํ•˜๋„๋ก ์‹ ๊ฒฝ๋ง์„ ํ›ˆ๋ จํ•  ์ˆ˜ ์žˆ๋‹ค. 

    ์ผ๋ฐ˜์ ์ธ ์ง€๋„ ํ•™์Šต๊ณผ ๊ฐ™์œผ๋‚˜ ๊ฐ•ํ™” ํ•™์Šต์—์„œ ์—์ด์ „ํŠธ๊ฐ€ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๊ฐ€์ด๋“œ๋Š” ๋ณด์ƒ๋ฟ์ด๋‹ค.

    ๋ณด์ƒ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๋“œ๋ฌผ๊ณ  ์ง€์—ฐ๋˜์–ด ๋‚˜ํƒ€๋‚œ๋‹ค. 

    ์˜ˆ) ์—์ด์ „ํŠธ๊ฐ€ 100 ์Šคํ… ๋™์•ˆ ๋ง‰๋Œ€์˜ ๊ท ํ˜•์„ ์œ ์ง€ํ–ˆ์„ ๋•Œ ์šฐ๋ฆฌ๊ฐ€ ์•„๋Š” ๊ฒƒ์€ ๋งˆ์ง€๋ง‰ ํ–‰๋™ ๋’ค์— ๋ง‰๋Œ€๊ฐ€ ์“ฐ๋ ค์กŒ๋‹ค๋Š” ๊ฒƒ๋ฟ์ด๋‹ค. 

    ์ด 100๋ฒˆ์˜ ํ–‰๋™ ์ค‘ ์–ด๋А ๊ฒƒ์ด ์ข‹๊ณ , ์–ด๋А ๊ฒƒ์ด ๋‚˜์œ์ง€ ์•Œ ์ˆ˜ ์—†๋‹ค.

    ์‹ ์šฉ ํ• ๋‹น ๋ฌธ์ œ : ํ•˜์ง€๋งŒ ๋ชจ๋“  ์ฑ…์ž„์ด ๋งˆ์ง€๋ง‰ ํ–‰๋™์— ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. 

    ์—์ด์ „ํŠธ๊ฐ€ ๋ณด์ƒ์„ ๋ฐ›์•˜์„ ๋•Œ ์–ด๋–ค ํ–‰๋™ ๋•๋ถ„์ธ์ง€ ์•Œ๊ธฐ ์–ด๋ ต๋‹ค.

     

    → ํ–‰๋™์ด ์ผ์–ด๋‚œ ํ›„ ๊ฐ ๋‹จ๊ณ„๋งˆ๋‹ค ํ• ์ธ ๊ณ„์ˆ˜ γ๋ฅผ ์ ์šฉํ•œ ๋ณด์ƒ์„ ๋ชจ๋‘ ํ•ฉํ•˜์—ฌ ํ–‰๋™์„ ํ‰๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

    ํ• ์ธ๋œ ๋ณด์ƒ์˜ ํ•ฉ์„ ํ–‰๋™์˜ ๋Œ€๊ฐ€๋ผ๊ณ  ํ•œ๋‹ค. 

    ํ• ์ธ ๊ณ„์ˆ˜๊ฐ€ 0์— ๊ฐ€๊นŒ์šฐ๋ฉด ๋ฏธ๋ž˜์˜ ๋ณด์ƒ์€ ํ˜„์žฌ์˜ ๋ณด์ƒ๋งŒํผ ์ค‘์š”ํ•˜๊ฒŒ ์ทจ๊ธ‰๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค.

    ๋ฐ˜๋Œ€๋กœ ํ• ์ธ ๊ณ„์ˆ˜๊ฐ€ 1์— ๊ฐ€๊นŒ์šฐ๋ฉด ๋จผ ๋ฏธ๋ž˜์˜ ๋ณด์ƒ์ด ํ˜„์žฌ์˜ ๋ณด์ƒ๋งŒํผ ์ค‘์š”ํ•˜๊ฒŒ ๊ณ ๋ ค๋  ๊ฒƒ์ด๋‹ค.

    ์ „ํ˜•์ ์ธ ํ• ์ธ ๊ณ„์ˆ˜์˜ ๊ฐ’์€ 0.9์—์„œ 0.99์‚ฌ์ด์ด๋‹ค.

    ํ–‰๋™ ์ด์ต : ์šฐ๋ฆฌ๋Š” ํ‰๊ท ์ ์œผ๋กœ ๋‹ค๋ฅธ ๊ฐ€๋Šฅํ•œ ํ–‰๋™๊ณผ ๋น„๊ตํ•ด์„œ ๊ฐ ํ–‰๋™์ด ์–ผ๋งˆ๋‚˜ ์ข‹์€์ง€ ๋‚˜์œ์ง€๋ฅผ ์ถ”์ •ํ•ด์•ผ ํ•œ๋‹ค.

    ๋งŽ์€ ์—ํ”ผ์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๋ชจ๋“  ํ–‰๋™์˜ ๋Œ€๊ฐ€๋ฅผ ์ •๊ทœํ™”ํ•ด์•ผ ํ•œ๋‹ค.

    ํ–‰๋™ ์ด์ต์ด ์Œ์ˆ˜์ธ ํ–‰๋™์€ ๋‚˜์˜๊ณ , ์–‘์ˆ˜์ธ ํ–‰๋™์€ ์ข‹๋‹ค๊ณ  ๊ฐ€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.


    18.6 ์ •์ฑ… ๊ทธ๋ ˆ์ด๋””์–ธํŠธ

    ๋†’์€ ๋ณด์ƒ์„ ์–ป๋Š” ๋ฐฉํ–ฅ์˜ ๊ทธ๋ ˆ์ด๋””์–ธํŠธ๋ฅผ ๋”ฐ๋ฅด๋„๋ก ์ •์ฑ…์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ตœ์ ํ™”ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.

     

    REINFORCEMENT ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์ธ๊ธฐ ์žˆ๋‹ค.

    1. ์‹ ๊ฒฝ๋ง ์ •์ฑ…์ด ์—ฌ๋Ÿฌ ๋ฒˆ์— ๊ฑธ์ณ ๊ฒŒ์ž„์„ ํ”Œ๋ ˆ์ดํ•˜๊ณ  ๋งค ์Šคํ…๋งˆ๋‹ค ์„ ํƒ๋œ ํ–‰๋™์ด ๋” ๋†’์€ ๊ฐ€๋Šฅ์„ฑ์„ ๊ฐ€์ง€๋„๋ก ๋งŒ๋“œ๋Š” ๊ทธ๋ ˆ์ด๋””์–ธํŠธ๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์•„์ง ์ด ๊ทธ๋ ˆ์ด๋””์–ธํŠธ๋ฅด ์ ์šฉํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค.

    2. ์—ํ”ผ์†Œ๋“œ๋ฅผ ๋ช‡ ๋ฒˆ ์‹คํ–‰ํ•œ ๋‹ค์Œ, ๊ฐ ํ–‰๋™์˜ ์ด์ต์„ ๊ฒŒ์‚ฐํ•œ๋‹ค.

    3. ํ•œ ํ–‰๋™์˜ ์ด์ต์ด ์–‘์ˆ˜์ด๋ฉด ์ด ํ–‰๋™์ด ์ข‹์€ ๊ฒƒ์ž„์„ ์˜๋ฏธํ•˜๋ฏ€๋กœ ๋ฏธ๋ž˜์— ์„ ํƒ๋  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋„๋ก ์•ž์„œ ๊ณ„์‚ฐํ•œ ๊ทธ๋ ˆ์ด๋””์–ธํŠธ๋ฅผ ์ ์šฉํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ–‰๋™ ์ด์ต์ด ์Œ์ˆ˜์ด๋ฉด ์ด ํ–‰๋™์ด ๋‚˜์œ ๊ฒƒ์ž„์„ ์˜๋ฏธํ•˜๋ฏ€๋กœ ๋ฏธ๋ž˜์— ์ด ํ–‰๋™์ด ๋œ ์„ ํƒ๋˜๋„๋ก ๋ฐ˜๋Œ€์˜ ๊ทธ๋ ˆ์ด๋””์–ธํŠธ๋ฅผ ์ ์šฉํ•œ๋‹ค. ์ด๋Š” ๊ฐ ๊ทธ๋ ˆ์ด๋””์–ธํŠธ ๋ฒกํ„ฐ์™€ ๊ทธ์— ์ƒ์‘ํ•˜๋Š” ํ–‰๋™์˜ ์ด์ต์„ ๊ณฑํ•˜๋ฉด ๋œ๋‹ค.

    4. ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ชจ๋“  ๊ฒฐ๊ณผ ๊ทธ๋ ˆ์ด๋””์–ธํŠธ ๋ฒกํ„ฐ๋ฅผ ํ‰๊ท  ๋‚ด์–ด ๊ฒฝ์‚ฌ ํ•˜๊ฐ•๋ฒ• ์Šคํ…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. 

     

    def play_one_step(env, obs, model, loss_fn):
        with tf.GradientTape() as tape:
            left_prova = model(obs[np.newaxis])
            action = (tf.random.uniform([1, 1]) > left_proba)
            y_target = tf.constant([[1.]]) - tf.cast(action, tf.float32)
            loss = tf.reduce_mean(loss_fn(y_target, left_proba))
            
        grads = tape.gradient(loss, model.trainable_variables)
        obs, reward, done, truncated, info = env.step(int(action))
        return obs, reward, done, truncated, grads

    ๋จผ์ € ํ•œ ์Šคํ…์„ ์ง„ํ–‰ํ•  ํ•จ์ˆ˜๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

    ์–ด๋–ค ํ–‰๋™์„ ์„ ํƒํ•˜๋”๋ผ๋„ ์†์‹ค๊ณผ ๊ทธ๋ ˆ์ด๋””์–ธํŠธ๋ฅผ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด ์˜ณ์€ ์„ ํƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•œ๋‹ค. 

    (์ด ๊ทธ๋ ˆ์ด๋””์–ธํŠธ๋ฅผ ์ž ์‹œ ๋™์•ˆ ์ผ๋‹จ ์ €์žฅํ–ˆ๋‹ค๊ฐ€ ์ด ํ–‰๋™์ด ์ข‹์€์ง€ ๋‚˜์œ์ง€ ํŒ๋ช…๋œ ํ›„์— ์กฐ์ •ํ•œ๋‹ค.)

     

    GradientTape ๋ธ”๋ก ์•ˆ์—์„œ ํ•˜๋‚˜์˜ ๊ด€์ธก๊ณผ ํ•จ๊ป˜ ๋ชจ๋ธ์„ ์ถœ๋ ฅํ•œ๋‹ค. ๋ชจ๋ธ์€ ๋ฐฐ์น˜๋ฅผ ๊ธฐ๋Œ€ํ•˜๋ฏ€๋กœ ํ•˜๋‚˜์˜ ์ƒ˜ํ”Œ์ด ๋“ค์–ด ์žˆ๋Š” ๋ฐฐ์น˜๊ฐ€ ๋˜๋„๋ก ๊ด€์ธก์˜ ํฌ๊ธฐ๋ฅผ ๋ฐ”๊พผ๋‹ค. ์ด ๋ชจ๋ธ์€ ์™ผ์ชฝ์œผ๋กœ ์ด๋™ํ•  ํ™•๋ฅ ์„ ์ถœ๋ ฅํ•œ๋‹ค.

    0์—์„œ 1 ์‚ฌ์ด์˜ ๋žœ๋คํ•œ ์‹ค์ˆ˜๋ฅผ ์ƒ˜ํ”Œ๋งํ•˜๊ณ  ์ด ๊ฐ’์ด left_proba๋ณด๋‹ค ํฐ์ง€ ํ™•์ธํ•œ๋‹ค. action์€ left_proba ํ™•๋ฅ ๋กœ False๊ฐ€ ๋˜๊ณ  1 - left_proba ํ™•๋ฅ ๋กœ True๊ฐ€ ๋œ๋‹ค. ์ด ๋ถˆ๋ฆฌ์–ธ ๊ฐ’์„ ์ •์ˆ˜๋กœ ๋ณ€ํ™˜ํ•˜๋ฉด action์€ ์ถœ๋ ฅ๋œ ํ™•๋ฅ ์— ๋งž๊ฒŒ 0(์™ผ์ชฝ) ๋˜๋Š” 1(์˜ค๋ฅธ์ชฝ)์ด ๋œ๋‹ค.

    ์™ผ์ชฝ์œผ๋กœ ์ด๋™ํ•  ํƒ€๊นƒ ํ™•๋ฅ ์„ ์ •์˜ํ•œ๋‹ค. ์ด ๊ฐ’์€ 1 - (์‹ค์ˆ˜๋กœ ๋ณ€ํ™˜๋œ) ํ–‰๋™์ด๋‹ค. ํ–‰๋™์ด 0(์™ผ์ชฝ)์ด๋ฉด ์™ผ์ชฝ์œผ๋กœ ์ด๋™ํ•  ํƒ€๊นƒ ํ™•๋ฅ ์€ 1์ด ๋˜๋ฉฐ, ํ–‰๋™์ด 1(์˜ค๋ฅธ์ชฝ)์ด๋ฉด ํƒ€๊นƒ ํ™•๋ฅ ์ด 0์ด ๋œ๋‹ค.

    ์ฃผ์–ด์ง„ ์†์‹ค ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์†์‹ค์„ ๊ณ„์‚ฐํ•˜๊ณ  ํ…Œ์ดํ”„๋ฅผ ์‚ฌ์šฉํ•ด ๋ชจ๋ธ์˜ ํ›ˆ๋ จ ๊ฐ€๋Šฅํ•œ ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์†์‹ค์˜ ๊ทธ๋ ˆ์ด๋””์–ธํŠธ๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค. ์ด ๊ทธ๋ ˆ์ด๋””์–ธํŠธ๋„ ๋‚˜์ค‘์— ์ ์šฉํ•˜๊ธฐ ์ „์— ์ด ํ–‰๋™์ด ์ข‹์€์ง€ ๋‚˜์œ์ง€์— ๋”ฐ๋ผ ์กฐ์ •๋  ๊ฒƒ์ด๋‹ค.

    ์„ ํƒํ•œ ํ–‰๋™์„ ํ”Œ๋ ˆ์ดํ•˜๊ณ  ์ƒˆ๋กœ์šด ๊ด€์ธก, ๋ณด์ƒ, ์—ํ”ผ์†Œ๋“œ ์ข…๋ฃŒ ์—ฌ๋ถ€, ์—ํ”ผ์†Œ๋“œ ์ค‘๋‹จ ์—ฌ๋ถ€, ๊ณ„์‚ฐํ•œ ๊ทธ๋ ˆ์ด๋””์–ธํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

     

    def play_multiple_episodes(env, n_episodes, n_max_steps, model, loss_fn):
        all_rewards = []
        all_grads = []
        for episode in range(n_episodes):
            current_rewards = []
            current_grads = []
            obs, info = env.reset()
            for step in range(n_max_steps):
                obs, reward, done, truncated, grads = play_one_step(
                    env, obs, model, loss_fn)
                current_rewards.append(reward)
                current_grads.append(grads)
                if done or truncated:
                    break
            
            all_rewards.append(current_rewards)
            all_grads.append(current_grads)
        
        return all_rewards, all_grad

    play_one_step() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์—ฌ๋Ÿฌ ์—ํ”ผ์†Œ๋“œ๋ฅผ ํ”Œ๋ ˆ์ดํ•˜๊ณ , ์ „์ฒด ๋ณด์ƒ ๋ฐ ๊ฐ ์—ํ”ผ์†Œ๋“œ์™€ ์Šคํ…์˜ ๊ทธ๋ ˆ์ด๋””์–ธํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. 

    ๋ณด์ƒ ๋ฆฌ์ŠคํŠธ์˜ ๋ฆฌ์ŠคํŠธ(์—ํ”ผ์†Œ๋“œ๋งˆ๋‹ค ๋ณด์ƒ ๋ฆฌ์ŠคํŠธ ํ•˜๋‚˜, ์ด ๋ฆฌ์ŠคํŠธ๋Š” ์Šคํ…๋งˆ๋‹ค ๋ณด์ƒ ํ•˜๋‚˜๋ฅผ ํฌํ•จํ•œ๋‹ค.)์™€ ๊ทธ๋ ˆ์ด๋””์–ธํŠธ ๋ฆฌ์ŠคํŠธ์˜ ๋ฆฌ์ŠคํŠธ(์—ํ”ผ์†Œ๋“œ๋งˆ๋‹ค ๊ทธ๋ ˆ์ด๋””์–ธํŠธ ๋ฆฌ์ŠคํŠธ ํ•˜๋‚˜, ์ด ๋ฆฌ์ŠคํŠธ๋Š” ์Šคํ…๋งˆ๋‹ค ๊ทธ๋ ˆ์ด๋””์–ธํŠธ ํŠœํ”Œ์„ ํ•˜๋‚˜ ํฌํ•จํ•˜๊ณ  ๊ฐ ํŠœํ”Œ์€ ํ›ˆ๋ จ ๊ฐ€๋Šฅํ•œ ๋ณ€์ˆ˜๋งˆ๋‹ค ๊ทธ๋ ˆ์ด๋””์–ธํŠธ ํ…์„œ ํ•˜๋‚˜๋ฅผ ํฌํ•จํ•œ๋‹ค.)๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

    def discount_rewards(rewards, discount_factor):
        discounted = np.array(rewards)
        for step in range(len(rewards) -2, -1, -1):
            discounted[step] += discounted[step + 1] * discount_factor
        return discounted
        
    def discount_and_normalize_rewards(all_rewards, discount_factor):
        all_discounted_rewards = [discount_rewards(rewards, discount_factor)
                                  for rewards in all_rewards]
        flat_rewards = np.concatenate(all_discounted_rewards)
        reward_mean = flat_rewards.mean()
        reward_std = flat_rewards.std()
        return [(discounted_rewards - reward_nean) / reward_std
                for discounted_rewards in all_discounted_rewards]

    ์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ play_multiple_episodes() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ๋ฒˆ ๊ฒŒ์ž„์„ ํ”Œ๋ ˆ์ดํ•œ๋‹ค.

    ๊ทธ๋‹ค์Œ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋ชจ๋“  ๋ณด์ƒ์„ ์‚ดํŽด์„œ ๊ฐ ๋ณด์ƒ์„ ํ• ์ธํ•˜๊ณ  ์ •๊ทœํ™”ํ•œ๋‹ค.

    ์ฒซ ๋ฒˆ์งธ ํ•จ์ˆ˜๋Š” ๊ฐ ์Šคํ…์—์„œ ํ• ์ธ๋œ ๋ฏธ๋ž˜ ๋ณด์ƒ์˜ ํ•ฉ์„ ๊ณ„์‚ฐํ•œ๋‹ค.

    ๋‘ ๋ฒˆ์งธ ํ•จ์ˆ˜๋Š” ์—ฌ๋Ÿฌ ์—ํ”ผ์†Œ๋“œ์— ๊ฑธ์ณ ๊ณ„์‚ฐ๋œ ํ• ์ธ๋œ ๋ชจ๋“  ๋ณด์ƒ(๋Œ€๊ฐ€)์—์„œ ํ‰๊ท ์„ ๋นผ๊ณ  ํ‘œ์ค€ ํŽธ์ฐจ๋กœ ๋‚˜๋ˆ„์–ด ์ก๊ทœํ™”ํ•œ๋‹ค.

    n_iterations = 150
    n_episodes_per_update = 10
    n_max_steps = 200
    discount_factor = 0.95

    ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ •์˜ํ•œ๋‹ค.

    optimizer = tf.keras.optimizers.Nadam(learning_rate=0.01)
    loss_fn = tf.keras.losses.binary_crossentropy

    ์˜ตํ‹ฐ๋งˆ์ด์ €์™€ ์†์‹ค ํ•จ์ˆ˜๋„ ํ•„์š”ํ•˜๋‹ค.

    for iteration in range(n_iterations):
        all_rewards, all_grads = play_multiple_episodes(
            env, n_episodes_per_update, n_max_steps, model, loss_fn)
        all_final_rewards = discount_and_normalize_rewards(all_rewards, discount_factor)
        all_mean_grads = []
        for var_index in range(len(model, trainable_variables)):
            mean_grads = tf.reduce_mean(
                [final_reward * all_grads[episode_index][step][var_index]
                for episode_index, final_rewards in enumerate(all_final_rewards)
                    for step, final_reward in enumerate(final_rewards)], axis=0)
            all_mean_grads.append(mean_grads)
        optimizer.apply_gradients(zip(all_mean_grads, model.trainable_variables))

    ํ›ˆ๋ จ ๋ฐ˜๋ณต์„ ๋งŒ๋“ค์–ด ์‹คํ–‰ํ•  ์ค€๋น„๋ฅผ ํ•œ๋‹ค. 

     

    ๊ฐ ํ›ˆ๋ จ ๋ฐ˜๋ณต์—์„œ play_multiple_episodes() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. 

    discount_and_normalize_rewards() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ฐ ํ–‰๋™์˜ ์ •๊ทœํ™”๋œ ์ด์ต(final_reward)๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค. ์ด ๊ฐ’์€ ๊ฐ ํ–‰๋™์ด ์‹ค์ œ๋กœ ์–ผ๋งˆ๋‚˜ ์ข‹์€์ง€ ๋‚˜์œ์ง€๋ฅผ ์•Œ๋ ค์ค€๋‹ค.

    ํ›ˆ๋ จ ๊ฐ€๋Šฅํ•œ ๋ณ€์ˆ˜๋ฅผ ์ˆœํšŒํ•˜๋ฉด์„œ ๋ชจ๋“  ์—ํ”ผ์†Œ๋“œ์™€ ๋ชจ๋“  ์Šคํ…์— ๋Œ€ํ•œ ๊ฐ ๋ณ€์ˆ˜์˜ ๊ทธ๋ ˆ์ด๋””์–ธํŠธ๋ฅผ final_reward๋กœ ๊ฐ€์ค‘์น˜๋ฅผ ๋‘์–ด ํ‰๊ท ํ•œ๋‹ค.

    ํ‰๊ท  ๊ทธ๋ ˆ์ด๋””์–ธํŠธ๋ฅผ ์˜ตํ‹ฐ๋งˆ์ด์ €์— ์ ์šฉํ•œ๋‹ค. ๋ชจ๋ธ์˜ ํ›ˆ๋ จ ๊ฐ€๋Šฅํ•œ ๋ณ€์ˆ˜๊ฐ€ ๋ณ€๊ฒฝ๋˜๊ณ  ์•„๋งˆ ์ •์ฑ…์ด ์กฐ๊ธˆ ๋” ๋‚˜์•„์งˆ ๊ฒƒ์ด๋‹ค. 

     

    ํฌ๊ณ  ๋ณต์žกํ•œ ๋ฌธ์ œ์—๋Š” ์ž˜ ์ ์šฉํ•˜์ง€ ๋ชปํ•œ๋‹ค.

    ์•„์ฃผ ๊ธด ์‹œ๊ฐ„ ๋™์•ˆ ๊ฒŒ์ž„์„ ํ”Œ๋ ˆ์ดํ•ด์•ผ ์ •์ฑ…์„ ๋งŽ์ด ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ƒ˜ํ”Œ ํšจ์œจ์„ฑ์ด ๋งค์šฐ ์ข‹์ง€ ๋ชปํ•˜๋‹ค. 

    ๊ฐ ํ–‰๋™์˜ ์ด์ต์„ ์ถ”์ •ํ•˜๊ธฐ ์œ„ํ•ด ๋งŽ์€ ์—ํ”ผ์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•ด์•ผ ํ•œ๋‹ค.

    ์•กํ„ฐ-ํฌ๋ฆฌํ‹ฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ฐ™์€ ๋” ๊ฐ•๋ ฅํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜๋„ ์žˆ๋‹ค. 


    18.7 ๋งˆ๋ฅด์ฝ”ํ”„ ๊ฒฐ์ • ๊ณผ์ •

    ๋งˆ๋ฅด์ฝ”ํ”„ ์—ฐ์‡„ : ์ •ํ•ด์ง„ ๊ฐœ์ˆ˜์˜ ์ƒํƒœ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, ๊ฐ ์Šคํ…๋งˆ๋‹ค ํ•œ ์ƒํƒœ์—์„œ ๋‹ค๋ฅธ ์ƒํƒœ๋กœ ๋žœ๋คํ•˜๊ฒŒ ์ „์ด๋œ๋‹ค.

    ์ƒํƒœ s์—์„œ ์ƒํƒœ s'๋กœ ์ „์ดํ•˜๊ธฐ ์œ„ํ•œ ํ™•๋ฅ ์€ ๊ณ ์ •๋˜์–ด ์žˆ์œผ๋ฉฐ, ์‹œ์Šคํ…œ์— ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์—†์œผ๋ฏ€๋กœ ๊ณผ๊ฑฐ ์ƒํƒœ์— ์ƒ๊ด€์—†์ด (s, s') ์Œ์—๋งŒ ์˜์กดํ•œ๋‹ค.

    ๋‚˜์˜ค๋Š” ๊ธธ์ด ์—†์–ด์„œ ์˜์›ํžˆ ๊ทธ ์ƒํƒœ์— ๋‚จ๊ฒŒ ๋˜๋Š” ์ƒํƒœ๋ฅผ ์ข…๋ฃŒ ์ƒํƒœ๋ผ๊ณ  ํ•œ๋‹ค. 

     

    ๋งˆ๋ฅด์ฝ”ํ”„ ๊ฒฐ์ • ๊ณผ์ • : ๋งˆ๋ฅด์ฝ”ํ”„ ์—ฐ์‡„์™€ ๋น„์Šทํ•˜์ง€๋งŒ ์•ฝ๊ฐ„ ๋‹ค๋ฅด๋‹ค.

    ๊ฐ ์Šคํ…์—์„œ ์—์ด์ „ํŠธ๋Š” ์—ฌ๋Ÿฌ ๊ฐ€๋Šฅํ•œ ํ–‰๋™ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๊ณ , ์ „์ด ํ™•๋ฅ ์€ ์„ ํƒ๋œ ํ–‰๋™์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง„๋‹ค.

    ๋˜ํ•œ ์–ด๋–ค ์ƒํƒœ ์ „์ด๋Š” ๋ณด์ƒ(์Œ์ˆ˜ ํ˜น์€ ์–‘์ˆ˜)์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

    ์—์ด์ „ํŠธ์˜ ๋ชฉ์ ์€ ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ๋ณด์ƒ์„ ์ตœ๋Œ€ํ™”ํ•˜๊ธฐ ์œ„ํ•œ ์ •์ฑ…์„ ์ฐพ๋Š” ๊ฒƒ์ด๋‹ค.

     

    ์ตœ์ ์˜ ์ƒํƒœ ๊ฐ€์น˜ V*(s) : ์—์ด์ „ํŠธ๊ฐ€ ์ƒํƒœ s์— ๋„๋‹ฌํ•œ ํ›„ ์ตœ์ ์œผ๋กœ ํ–‰๋™ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ํ‰๊ท ์ ์œผ๋กœ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ๋Š” ํ• ์ธ๋œ ๋ฏธ๋ž˜ ๋ณด์ƒ์˜ ํ•ฉ์ด๋‹ค.

    ์—์ด์ „ํŠธ๊ฐ€ ์ตœ์ ์œผ๋กœ ํ–‰๋™ํ•˜๋ฉด ๋ฒจ๋งŒ ์ตœ์  ๋ฐฉ์ •์‹์ด ์ ์šฉ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์ž…์ฆํ–ˆ๋‹ค. 

    ์ด ์žฌ๊ท€ ์‹์€ ์—์ด์ „ํŠธ๊ฐ€ ์ตœ์ ์œผ๋กœ ํ–‰๋™ํ•˜๋ฉด ํ˜„์žฌ ์ƒํƒœ์˜ ์ตœ์  ๊ฐ€์น˜๋Š” ํ•˜๋‚˜์˜ ์ตœ์  ํ–‰๋™์œผ๋กœ ์ธํ•ด ํ‰๊ท ์ ์œผ๋กœ ๋ฐ›๊ฒŒ ๋  ๋ณด์ƒ๊ณผ ์ด ํ–‰๋™์ด ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๋‹ค์Œ ์ƒํƒœ์˜ ์ตœ์  ๊ฐ€์น˜์˜ ๊ธฐ๋Œ€์น˜๋ฅผ ํ•ฉํ•œ ๊ฒƒ๊ณผ ๊ฐ™๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

    ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ์ƒํƒœ์— ๋Œ€ํ•œ ์ตœ์ ์˜ ์ƒํƒœ ๊ฐ€์น˜๋ฅผ ์ •ํ™•ํžˆ ์ถ”์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค. 

    ๋จผ์ € ๋ชจ๋“  ์ƒํƒœ ๊ฐ€์น˜๋ฅผ 0์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๊ฐ€์น˜ ๋ฐ˜๋ณต ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ˜๋ณต์ ์œผ๋กœ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

    [๊ฐ€์น˜ ๋ฐ˜๋ณต ์•Œ๊ณ ๋ฆฌ์ฆ˜]

    V_k(s)๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ k๋ฒˆ์งธ ๋ฐ˜๋ณต์—์„œ ์ƒํƒœ s์˜ ์ถ”์ • ๊ฐ€์น˜์ด๋‹ค.

    ์ถฉ๋ถ„ํ•œ ์‹œ๊ฐ„์ด ์ฃผ์–ด์ง€๋ฉด ์ด ์ถ”์ •๊ฐ’์ด ์ตœ์ ์˜ ์ •์ฑ…์— ๋Œ€์‘ํ•˜๋Š” ์ตœ์ ์˜ ์ƒํƒœ ๊ฐ€์น˜์— ์ˆ˜๋ ดํ•˜๋Š” ๊ฒƒ์ด ๋ณด์žฅ๋œ๋‹ค.

     

    ์ตœ์ ์˜ ์ƒํƒœ ๊ฐ€์น˜๋ฅผ ์•„๋Š” ๊ฒƒ์€ ํŠนํžˆ ์ •์ฑ…์„ ํ‰๊ฐ€ํ•  ๋•Œ ์œ ์šฉํ•˜๋‹ค. ํ•˜์ง€๋งŒ ์—์ด์ „ํŠธ๋ฅผ ์œ„ํ•œ ์ตœ์ ์˜ ์ •์ฑ…์„ ์•Œ๋ ค์ฃผ์ง€๋Š” ์•Š๋Š”๋‹ค. 

    Q-๊ฐ€์น˜๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ์ตœ์ ์˜ ์ƒํƒœ-ํ–‰๋™ ๊ฐ€์น˜๋ฅผ ์ถ”์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋งค์šฐ ๋น„์Šทํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ๋ฐœ๊ฒฌ๋˜์—ˆ๋‹ค. 

    ์ƒํƒœ-ํ–‰๋™ (s, a) ์Œ์— ๋Œ€ํ•œ ์ตœ์ ์˜ Q-๊ฐ€์น˜์ธ Q'(s, a)๋Š” ์—์ด์ „ํŠธ๊ฐ€ ์ƒํƒœ s์— ๋„๋‹ฌํ•ด์„œ ํ–‰๋™ a๋ฅผ ์„ ํƒํ•œ ํ›„ ์ด ํ–‰๋™์˜ ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ธฐ ์ „์— ํ‰๊ท ์ ์œผ๋กœ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ๋Š” ํ• ์ธ๋œ ๋ฏธ๋ž˜ ๋ณด์ƒ์˜ ํ•ฉ์ด๋‹ค. 

    ์—์ด์ „ํŠธ๋Š” ์—ฌ๊ธฐ์„œ ์ด ํ–‰๋™ ์ดํ›„์— ์ตœ์ ์œผ๋กœ ํ–‰๋™ํ•  ๊ฒƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.

     

    Q-๊ฐ€์น˜์˜ ์ถ”์ •์„ ๋ชจ๋‘ 0์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.

    Q-๊ฐ€์น˜ ๋ฐ˜๋ณต ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•ด ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

    [Q-๊ฐ€์น˜ ๋ฐ˜๋ณต ์•Œ๊ณ ๋ฆฌ์ฆ˜]

     

    ์ตœ์ ์˜ Q-๊ฐ€์น˜๋ฅผ ๊ตฌํ•˜๊ณ  ๋‚˜๋ฉด ์ตœ์ ์˜ ์ •์ฑ…์ธ π*(s)๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•˜๋‹ค.

    ์—์ด์ „ํŠธ๊ฐ€ ์ƒํƒœ s์— ๋„๋‹ฌํ–ˆ์„ ๋•Œ ๊ฐ€์žฅ ๋†’์€ Q-๊ฐ€์น˜๋ฅผ ๊ฐ€์ง„ ํ–‰๋™์„ ์„ ํƒํ•˜๋ฉด ๋œ๋‹ค. 

     

    transition_probabilities = [ # ํฌ๊ธฐ๋Š” [s, a, s']
        [[0.7, 0.3, 0.0], [1.0, 0.0, 0.01, [0.8, 0.2, 0.0]],
        [[0.0, 1.0, 0.0], None, [0.0, 0.0, 1.0]],
        [None, [0.8, 0.1, 0.1], None]
    ]
    rewards = [ # ํฌ๊ธฐ๋Š” [s, a, s']
        [[+10, 0, 0], [O, 0, 0], [0, 0, 0]],
        [[O, 0, 0], [0, 0, 0], [0, 0, -50]],
        [[O, 0, 01, [+40, 0, 0], [0, 0, 0]]
    ]
    possible_actions = [[O, 1, 2], [0, 2], [1]]

    ์˜ˆ) ํ–‰๋™ a_1์„ ํ”Œ๋ ˆ์ดํ•œ ํ›„ s_2์—์„œ s_0์œผ๋กœ ์ „์ดํ•  ํ™•๋ฅ ์„ ์•Œ๊ธฐ ์œ„ํ•ด์„œ๋Š” transition_probabilities[2][1][0]์„ ์ฐธ์กฐํ•œ๋‹ค.

    ์ดํ•ด ํ•ด๋‹นํ•˜๋Š” ๋ณด์ƒ์„ ์–ป์œผ๋ ค๋ฉด rewards[2][1][0]์„ ์ฐธ์กฐํ•œ๋‹ค.

    s_2์—์„œ ๊ฐ€๋Šฅํ•œ ํ–‰๋™์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ์–ป์„๋ฉด possible_actions[2]๋ฅผ ์ฐธ์กฐํ•œ๋‹ค.

    Q_values = np.full((3, 3), -np.inf) # ๋ถˆ๊ฐ€๋Šฅํ•œ ํ–‰๋™์— ๋Œ€ํ•ด์„œ๋Š” -np.inf
    for state, actions in enumerate(possible_actions):
        Q_values[state, actions] = 0.0 # ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ํ–‰๋™์— ๋Œ€ํ•ด์„œ

    ๊ทธ๋‹ค์Œ ๋ชจ๋“  Q-๊ฐ€์น˜๋ฅผ 0์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•ด์•ผ ํ•œ๋‹ค.

    gamma = 0.90 # ํ• ์ธ ๊ณ„์ˆ˜
    
    for iteration in range(50):
        Q_prev = Q_values.copy()
        for s in range(3):
            for a in possible_actions[s]:
                Q_values[s, a] = np.sum([
                    transition_probabilities[s][a][sp]
                    * (rewards[s][a][sp] + gamma * Q_prev[sp].max())
                for sp in range(3)])

    ๋ชจ๋“  ์ƒํƒœ์™€ ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ํ–‰๋™์— ๋Œ€ํ•ด ๋ชจ๋“  Q-๊ฐ€์น˜์— Q-๊ฐ€์น˜ ๋ฐ˜๋ณต ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ ์šฉํ•œ๋‹ค. 

    Q_values
    # array ([[18.91891892, 17.02702702, 13.62162162],
    #         [ 0.        ,        -inf, -4.87971488],
    #         [ -inf      , 50.13365013,        -inf]])

    ์˜ˆ) ์—์ด์ „ํŠธ๊ฐ€ ์ƒํƒœ s_0์— ์žˆ๊ณ  ํ–‰๋™ a_1์„ ์„ ํƒํ–ˆ์„ ๋•Œ ํ• ์ธ๋œ ๋ฏธ๋ž˜ ๋ณด์ƒ์˜ ๊ธฐ๋Œ€ ํ•ฉ์€ ์•ฝ 17.0์ด๋‹ค.

    np.argmax(Q_values, axis=1) # ๊ฐ ์ƒํƒœ์— ๋Œ€ํ•ด ์ตœ์ ์˜ ํ–‰๋™
    # array([0, 0, 1])

    ๊ฐ ์ƒํƒœ์— ๋Œ€ํ•ด ๊ฐ€์žฅ ๋†’์€ Q-๊ฐ€์น˜๋ฅผ ๊ฐ–๋Š” ํ–‰๋™์ด๋‹ค.


    18.8 ์‹œ๊ฐ„์ฐจ ํ•™์Šต

    ๋…๋ฆฝ์ ์ธ ํ–‰๋™์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ๊ฐ•ํ™” ํ•™์Šต ๋ฌธ์ œ๋Š” ๋ณดํ†ต ๋งˆ๋ฅด์ฝ”ํ”„ ๊ฒฐ์ • ๊ณผ์ •์œผ๋กœ ๋ชจ๋ธ๋ง๋  ์ˆ˜ ์žˆ์ง€๋งŒ ์ดˆ๊ธฐ์— ์—์ด์ „ํŠธ๋Š” ์ „์ด ํ™•๋ฅ ์— ๋Œ€ํ•ด ์•Œ์ง€ ๋ชปํ•˜๋ฉฐ(T(s, a, s')๋ฅผ ๋ชจ๋ฅธ๋‹ค.), ๋ณด์ƒ์ด ์–ผ๋งˆ๋‚˜ ๋˜๋Š”์ง€๋„ ์•Œ์ง€ ๋ชปํ•œ๋‹ค.(R(s, a, s')๋ฅผ ๋ชจ๋ฅธ๋‹ค.)

    ๋ณด์ƒ์— ๋Œ€ํ•ด ์•Œ๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ ์–ด๋„ ํ•œ ๋ฒˆ์€ ๊ฐ ์ƒํƒœ์™€ ์ „์ด๋ฅผ ๊ฒฝํ—˜ํ•ด์•ผ ํ•œ๋‹ค.

    ๊ทธ๋ฆฌ๊ณ  ์ „์ด ํ™•๋ฅ ์— ๋Œ€ํ•ด ์‹ ๋ขฐํ•  ๋งŒํ•œ ์ถ”์ •์„ ์–ป์œผ๋ ค๋ฉด ์—ฌ๋Ÿฌ ๋ฒˆ ๊ฒฝํ—˜์„ ํ•ด์•ผ ํ•œ๋‹ค.

     

    ์‹œ๊ฐ„์ฐจ ํ•™์Šต(TD ํ•™์Šต) : Q-๊ฐ€์น˜ ๋ฐ˜๋ณต ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ ๋งค์šฐ ๋น„์Šทํ•˜์ง€๋งŒ ์—์ด์ „ํŠธ๊ฐ€ MDP์— ๋Œ€ํ•ด ์ผ๋ถ€ ์ •๋ณด๋งŒ ์•Œ๊ณ  ์žˆ์„ ๋•Œ๋ฅผ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋„๋ก ๋ณ€ํ˜•ํ•œ ๊ฒƒ์ด๋‹ค.

    ์ผ๋ฐ˜์ ์œผ๋กœ ์—์ด์ „ํŠธ๊ฐ€ ์ดˆ๊ธฐ์— ๊ฐ€๋Šฅํ•œ ์ƒํƒœ์™€ ํ–‰๋™๋งŒ ์•Œ๊ณ  ๋‹ค๋ฅธ ๊ฒƒ์€ ๋ชจ๋ฅธ๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.

    ์—์ด์ „ํŠธ๋Š” ํƒํ—˜ ์ •์ฑ…์„ ์‚ฌ์šฉํ•ด MDP๋ฅผ ํƒํ—˜ํ•œ๋‹ค.

    ํƒํ—˜์ด ์ง„ํ–‰๋ ์ˆ˜๋ก TD ํ•™์Šต ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์‹ค์ œ๋กœ ๊ด€์ธก๋œ ์ „์ด์™€ ๋ณด์ƒ์— ๊ทผ๊ฑฐํ•˜์—ฌ ์ƒํƒœ ๊ฐ€์น˜์˜ ์ถ”์ •๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

    [TD ํ•™์Šต ์•Œ๊ณ ๋ฆฌ์ฆ˜]

    ์ด ์‹์˜ ์ฒซ ๋ฒˆ์งธ ํ˜•ํƒœ๋ฅผ ๋” ๊ฐ„๋‹จํžˆ ์“ฐ๋Š” ๋ฐฉ๋ฒ•์€

    ํ‘œ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

    ๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

    ๊ฐ ์ƒํƒœ s์—์„œ ์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์—์ด์ „ํŠธ๊ฐ€ ํ•ด๋‹น ์ƒํƒœ๋ฅผ ๋– ๋‚ฌ์„ ๋•Œ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๋‹น์žฅ์˜ ๋ณด์ƒ๊ณผ(์ตœ์ ์œผ๋กœ ํ–‰๋™ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์—ฌ) ๋‚˜์ค‘์— ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ๋Š” ๋ณด์ƒ์„ ๋”ํ•œ ์ด๋™ ํ‰๊ท ์„ ์ €์žฅํ•œ๋‹ค.


    18.9 Q-๋Ÿฌ๋‹

    Q-๋Ÿฌ๋‹ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ „์ด ํ™•๋ฅ ๊ณผ ๋ณด์ƒ์„ ์ดˆ๊ธฐ์— ์•Œ์ง€ ๋ชปํ•œ ์ƒํ™ฉ์—์„œ Q-๊ฐ€์น˜ ๋ฐ˜๋ณต ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ ์šฉํ•œ ๊ฒƒ์ด๋‹ค.

    Q-๋Ÿฌ๋‹์€ ์—์ด์ „ํŠธ๊ฐ€ ํ”Œ๋ ˆ์ดํ•˜๋Š” ๊ฒƒ์„ ๋ณด๊ณ  ์ ์ง„์ ์œผ๋กœ Q-๊ฐ€์น˜ ์ถ”์ •์„ ํ–ฅ์ƒํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•œ๋‹ค.

    ์ •ํ™•ํ•œ(์ถฉ๋ถ„ํžˆ ๊ทผ์ ‘ํ•œ) Q-๊ฐ€์น˜ ์ถ”์ •์„ ์–ป๊ฒŒ ๋˜๋ฉด ์ตœ์ ์˜ ์ •์ฑ…์€ ๊ฐ€์žฅ ๋†’์€ Q-๊ฐ€์น˜๋ฅผ ๊ฐ€์ง€๋Š” ํ–‰๋™์„ ์„ ํƒํ•œ๋‹ค. (ํƒ์š•์  ์ •์ฑ…)

     

    [Q-๋Ÿฌ๋‹ ์•Œ๊ณ ๋ฆฌ์ฆ˜]

    ๊ฐ ์ƒํƒœ-ํ–‰๋™ (s, a) ์Œ๋งˆ๋‹ค ์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ํ–‰๋™ a๋ฅผ ์„ ํƒํ•ด ์ƒํƒœ s๋ฅผ ๋– ๋‚ฌ์„ ๋•Œ ์—์ด์ „ํŠธ๊ฐ€ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๋ณด์ƒ r๊ณผ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ๋Š” ํ• ์ธ๋œ ๋ฏธ๋ž˜ ๋ณด์ƒ์˜ ํ•ฉ์„ ๋”ํ•œ ์ด๋™ ํ‰๊ท ์„ ์ €์žฅํ•œ๋‹ค.

    ๋ฏธ๋ž˜ ๋ณด์ƒ์˜ ํ•ฉ์„ ์ถ”์ •ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํƒ€๊นƒ ์ •์ฑ…์ด ์ดํ›„๋กœ ์ตœ์ ์œผ๋กœ ํ–‰๋™ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ๋‹ค์Œ ์ƒํƒœ s'์— ๋Œ€ํ•œ Q-๊ฐ€์น˜ ์ถ”์ •์˜ ์ตœ๋Œ“๊ฐ’์„ ์„ ํƒํ•œ๋‹ค. 

     

    def step(state, action): 
        probas = transition_probabilities[state][action]
        next_state = np.random.choice([0, 1, 2], p=probas)
        reward = rewards[state][action][next_state]
        return next_state, reward

    ๋จผ์ € ์—์ด์ „ํŠธ๊ฐ€ ํ™˜๊ฒฝ์„ ํƒ์ƒ‰ํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

    ์ด๋ฅผ ์œ„ํ•ด ์—์ด์ „ํŠธ๊ฐ€ ํ•œ ํ–‰๋™์„ ์‹คํ–‰ํ•˜๊ณ  ๊ฒฐ๊ณผ ์ƒํƒœ์™€ ๋ณด์ƒ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ์Šคํ… ํ•จ์ˆ˜๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

    def exploration_policy(state):
        return np.random.choice(possible_actions[state])

    ์ด ์ƒํƒœ ๊ณต๊ฐ„์€ ๋งค์šฐ ์ž‘๊ธฐ ๋•Œ๋ฌธ์— ๋‹จ์ˆœํ•œ ๋žœ๋ค ์ •์ฑ…์œผ๋กœ ์ถฉ๋ถ„ํ•˜๋‹ค.

    ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ถฉ๋ถ„ํžˆ ์˜ค๋žซ๋™์•ˆ ์‹คํ–‰ํ•˜๋ฉด ์—์ด์ „ํŠธ๊ฐ€ ๊ฐ ์ƒํƒœ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ฐฉ๋ฌธํ•˜๊ณ  ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ํ–‰๋™์„ ์—ฌ๋Ÿฌ ๋ฒˆ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

    alpha0 = 0.05 # ์ดˆ๊ธฐ ํ•™์Šต๋ฅ 
    decay = 0.005 # ํ•™์Šต๋ฅ  ๊ฐ์‡ 
    gamma = 0.90  # ํ• ์ธ ๊ณ„์ˆ˜
    state = 0     # ์ดˆ๊ธฐ ์ƒํƒœ
    
    for iteration in range(10_000):
        action = exploration_policy(state)
        next_state, reward = step(state, action)
        next_value = Q_values[next_state].max() # ๋‹ค์Œ ์Šคํ…์—์„œ ํƒ์š•์  ์ •์ฑ…
        alpha = alpha0 / (1 + iteration * decay)
        Q_values[state, action] *= 1 - alpha
        Q_values[state, action] += alpha * (reward + gamma * next_value)
        state = next_state

    Q-๊ฐ€์น˜๋ฅผ ์ดˆ๊ธฐํ™”ํ•œ ํ›„ ํ•™์Šต๋ฅ  ๊ฐ์‡ (๊ฑฐ๋“ญ์ œ๊ณฑ ๊ธฐ๋ฐ˜ ์Šค์ผ€์ค„๋ง)๋ฅผ ์‚ฌ์šฉํ•ด Q-๋Ÿฌ๋‹ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‹คํ–‰ํ•œ๋‹ค.

    ์ตœ์ ์˜ Q-๊ฐ€์น˜์— ์ˆ˜๋ ดํ•˜๊ฒ ์ง€๋งŒ ๋งŽ์€ ๋ฐ˜๋ณต๊ณผ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ํŠœ๋‹์ด ํ•„์š”ํ•˜๋‹ค.

    Q-๊ฐ€์น˜ ๋ฐ˜๋ณต ์•Œ๊ณ ๋ฆฌ์ฆ˜(์™ผ์ชฝ)๊ณผ Q-๋Ÿฌ๋‹ ์•Œ๊ณ ๋ฆฌ์ฆ˜(์˜ค๋ฅธ์ชฝ)

    ํ›ˆ๋ จ๋œ ์ •์ฑ…์„ ํ›ˆ๋ จ ์ค‘์— ๋ฐ˜๋“œ์‹œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. (์˜คํ”„-ํด๋ฆฌ์‹œ ์•Œ๊ณ ๋ฆฌ์ฆ˜)

    ์˜ˆ) ์•ž์„  ์ฝ”๋“œ์—์„œ ์‹คํ–‰๋œ ์ •์ฑ…(ํƒํ—˜ ์ •์ฑ…)์€ ์™„์ „ํžˆ ๋žœ๋คํ•œ ์ •์ฑ…์ด๋ฉฐ ํ›ˆ๋ จ๋œ ์ •์ฑ…์€ ์ „ํ˜€ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.)

    ์ตœ์ ์˜ ์ •์ฑ…์€ ํ•ญ์ƒ ๊ฐ€์žฅ ๋†’์€ Q-๊ฐ€์น˜๋ฅผ ๊ฐ€์ง„ ํ–‰๋™์„ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

    ๋ฐ˜๋Œ€๋กœ ์ •์ฑ… ๊ทธ๋ ˆ์ด๋””์–ธํŠธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์˜จ-ํด๋ฆฌ์‹œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.

    ํ›ˆ๋ จ๋œ ์ •์ฑ…์„ ์‚ฌ์šฉํ•ด ํ™˜๊ฒฝ์„ ํƒํ—˜ํ•œ๋‹ค. 

    18.9.1 ํƒํ—˜ ์ •์ฑ…

    Q-๋Ÿฌ๋‹์€ ํƒํ—˜ ์ •์ฑ…์ด MDP๋ฅผ ์ถฉ๋ถ„ํžˆ ํƒํ—˜ํ•ด์•ผ ์ž‘๋™ํ•œ๋‹ค.

    ์™„์ „ํ•œ ๋žœ๋ค ์ •์ฑ…์ด ๊ฒฐ๊ตญ์—๋Š” ๋ชจ๋“  ์ƒํƒœ์™€ ์ „์ด๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๊ฒฝํ—˜ํ•˜๋„๋ก ๋ณด์žฅํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด ๊ทน๋‹จ์ ์œผ๋กœ ์˜ค๋žœ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ๋‹ค.

    ๋” ๋‚˜์€ ๋ฐฉ๋ฒ•์€ ε-๊ทธ๋ฆฌ๋”” ์ •์ฑ…์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

    ๊ฐ ์Šคํ…์—์„œ ε ํ™•๋ฅ ๋กœ ๋žœ๋คํ•˜๊ฒŒ ํ–‰๋™ํ•˜๊ฑฐ๋‚˜ 1 - ε ํ™•๋ฅ ๋กœ ๊ทธ ์ˆœ๊ฐ„ ๊ฐ€์žฅ ์ตœ์„ ์ธ ๊ฒƒ์œผ๋กœ(๊ฐ€์žฅ ๋†’์€ Q-๊ฐ€์น˜๋ฅผ ์„ ํƒํ•˜์—ฌ) ํ–‰๋™ํ•œ๋‹ค. 

    ์™„์ „ํ•œ ๋žœ๋ค ์ •์ฑ…์— ๋น„ํ•ด Q-๊ฐ€์ • ์ถ”์ •์ด ์ ์  ๋” ํ–ฅ์ƒ๋˜๊ธฐ ๋•Œ๋ฌธ์— ํ™˜๊ฒฝ์—์„œ ๊ด€์‹ฌ ์žˆ๋Š” ๋ถ€๋ถ„์„ ์‚ดํ”ผ๋Š” ๋ฐ ์ ์  ๋” ๋งŽ์€ ์‹œ๊ฐ„์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

    ๊ทธ๋Ÿผ์—๋„ ์—ฌ์ „ํžˆ MDP์˜ ์•Œ๋ ค์ง€์ง€ ์•Š์€ ์ง€์—ญ์„ ๋ฐฉ๋ฌธํ•˜๋Š” ๋ฐ ์ผ์ • ์‹œ๊ฐ„์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋‹ค. 

     

    ์ด ์™ธ์—๋„ ํƒํ—˜์˜ ๊ฐ€๋Šฅ์„ฑ์— ์˜์กดํ•˜๋Š” ๋Œ€์‹  ์ด์ „์— ๋งŽ์ด ํ•˜์ง€ ์•Š์•˜๋˜ ํ–‰๋™์„ ์‹œ๋„ํ•˜๋„๋ก ํƒํ—˜ ์ •์ฑ…์„ ๊ฐ•์กฐํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

    ์ด๋Ÿฐ ๋ฐฉ์‹์€ Q-๊ฐ€์น˜ ์ถ”์ •์— ๋ณด๋„ˆ์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„๋œ๋‹ค.

    [ํƒํ—˜ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ Q-๋Ÿฌ๋‹

    18.9.2 ๊ทผ์‚ฌ Q-๋Ÿฌ๋‹๊ณผ ์‹ฌ์ธต Q-๋Ÿฌ๋‹

    Q-๋Ÿฌ๋‹์˜ ์ฃผ์š” ๋ฌธ์ œ๋Š” ๋งŽ์€ ์ƒํƒœ์™€ ํ–‰๋™์„ ๊ฐ€์ง„ ๋Œ€๊ทœ๋ชจ์˜ MDP์— ์ ์šฉํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

    → ์–ด๋–ค ์ƒํƒœ-ํ–‰๋™ (s, a) ์Œ์˜ Q-๊ฐ€์น˜๋ฅผ ๊ทผ์‚ฌํ•˜๋Š” ํ•จ์ˆ˜ Q_θ(s, a)๋ฅผ ์ ์ ˆํ•œ ๊ฐœ์ˆ˜์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฐพ๋Š” ๊ฒƒ์ด๋‹ค. (๊ทผ์‚ฌ Q-๋Ÿฌ๋‹)

    ์‹ฌ์ธต Q-๋„คํŠธ์›Œํฌ(DQN) : Q-๊ฐ€์น˜๋ฅผ ์ถ”์ •ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” DNN

    ์‹ฌ์ธต Q-๋Ÿฌ๋‹ : ๊ทผ์‚ฌ Q-๋Ÿฌ๋‹์„ ์œ„ํ•ด DQN์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ

     

    ์ฃผ์–ด์ง„ ์ƒํƒœ-ํ–‰๋™ ์Œ (s, a)์— ๋Œ€ํ•ด DQN์ด ๊ณ„์‚ฐํ•œ ๊ทผ์‚ฌ Q-๊ฐ€์น˜๋ฅผ ์ƒ๊ฐํ•ด๋ณด๊ฒ ๋‹ค.

    ๋ฒจ๋งŒ ์‹ ๋•๋ถ„์ด ์ด ๊ทผ์‚ฌ Q-๊ฐ€์น˜๋Š” ์ƒํƒœ s์—์„œ ํ–‰๋™ a๋ฅผ ์‹คํ–‰ํ–ˆ์„ ๋•Œ ๊ด€์ธก๋œ ๋ณด์ƒ r๊ณผ ๊ทธ ์ดํ›„์— ์ตœ์ ์œผ๋กœ ํ–‰๋™ํ•ด์„œ ์–ป์€ ํ• ์ธ๋œ ๊ฐ€์น˜๋ฅผ ๋”ํ•œ ๊ฐ’์— ๊ฐ€๋Šฅํ•œ ํ•œ ๊ฐ€๊นŒ์›Œ์•ผ ํ•œ๋‹ค. 

    ์ด ๋ฏธ๋ž˜์˜ ํ• ์ธ๋œ ๊ฐ€์น˜๋ฅผ ์ถ”์ •ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ฐ„๋‹จํ•˜๊ฒŒ ๋‹ค์Œ ์ƒํƒœ s'์™€ ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ํ–‰๋™ a'์— ๋Œ€ํ•ด DQN์„ ์‹คํ–‰ํ•˜๋ฉด ๋œ๋‹ค.

    ๊ทธ๋Ÿผ ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ํ–‰๋™์— ๋Œ€ํ•œ ๋ฏธ๋ž˜์˜ ๊ทผ์‚ฌ Q-๊ฐ€์น˜๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค. 

    ๊ทธ๋‹ค์Œ ๊ทผ์‚ฌ Q-๊ฐ€์น˜๊ฐ€ ๊ฐ€์žฅ ๋†’์€ ๊ฒƒ์„ ๊ณ ๋ฅด๊ณ  ํ• ์ธ์„ ์ ์šฉํ•˜๋ฉด ํ• ์ธ๋œ ๋ฏธ๋ž˜ ๋ณด์ƒ์˜ ์ถ”์ •์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

    ๋ณด์ƒ r๊ณผ ๋ฏธ๋ž˜์˜ ํ• ์ธ๋œ ๊ฐ€์น˜ ์ถ”์ •์„ ๋”ํ•˜๋ฉด ์ƒํƒœ-ํ–‰๋™ ์Œ (s, a)์— ๋Œ€ํ•œ ํƒ€๊นƒ Q-๊ฐ€์น˜ y(s, a)๋ฅผ ์–ป๊ฒŒ ๋œ๋‹ค.

    ์ด ํƒ€๊นƒ Q-๊ฐ€์น˜๋กœ ๊ฒฝ์‚ฌ ํ•˜๊ฐ•๋ฒ•์„ ์‚ฌ์šฉํ•ด ํ›ˆ๋ จ ๋‹จ๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

    ์ถ”์ •๋œ Q-๊ฐ€์น˜ Q(s, a)์™€ ํƒ€๊นƒ Q-๊ฐ€์น˜ y(s, a) ์‚ฌ์ด์˜ ์ œ๊ณฑ ์˜ค์ฐจ๋ฅผ ์ตœ์†Œํ™”ํ•œ๋‹ค.

    ๋˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ํฐ ์˜ค์ฐจ์— ๋ฏผ๊ฐํ•˜์ง€ ์•Š๋„๋ก ํ›„๋ฒ„ ์†์‹ค์„ ์‚ฌ์šฉํ•œ๋‹ค.


    18.10 ์‹ฌ์ธต Q-๋Ÿฌ๋‹ ๊ตฌํ˜„

    ์ฒซ ๋ฒˆ์งธ๋กœ ํ•„์š”ํ•œ ๊ฒƒ์€ ์‹ฌ์ธต Q-๋„คํŠธ์›Œํฌ์ด๋‹ค.

    ์ด๋ก ์ ์œผ๋กœ๋Š” ์ƒํƒœ-ํ–‰๋™ ์Œ์„ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›๊ณ  ๊ทผ์‚ฌ Q-๊ฐ€์น˜๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ์‹ ๊ฒฝ๋ง์ด ํ•„์š”ํ•˜๋‹ค.

    ํ•˜์ง€๋งŒ ์‹ค์ „์—์„œ๋Š” ์ƒํƒœ๋งŒ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›๊ณ  ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ํ–‰๋™์— ๋Œ€ํ•œ ๊ทผ์‚ฌ Q-๊ฐ€์น˜๋ฅผ ๊ฐ๊ฐ ์ถœ๋ ฅํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ํšจ์œจ์ ์ด๋‹ค.

    input_shape = [4] # == env.observation_space.shape
    n_outputs = 2 # == env.action_space.n
    
    model = tf.keras.Sequential([
        tf.keras.layers.Dense(32, activation="elu", input_shape=input_shape),
        tf.keras.layers.dense(32, activation="elu")
        tf.keras.layers.Dense(n_outputs)
    ])
    def epsilon_greedy_policy(state, epsilon=0):
        if np.random.rand() < epsilon:
            return np.random.randint(n_outputs) # ๋žœ๋ค ํ–‰๋™
        else:
            Q_values = model.predict(state[np.newaxis], verbose=0)[0]
            return Q_values.argmax() # DQN์— ๋”ฐ๋ฅธ ์ตœ์ ์˜ ํ–‰๋™

    ์ด DQN์œผ๋กœ ํ–‰๋™์„ ์„ ํƒํ•˜๋ ค๋ฉด ์˜ˆ์ธก Q-๊ฐ€์น˜๊ฐ€ ๊ฐ€์žฅ ํฐ ํ–‰๋™์„ ์„ ํƒํ•œ๋‹ค.

    ์—์ด์ „ํŠธ๊ฐ€ ํ™˜๊ฒฝ์„ ํƒํ—˜ํ•˜๋„๋ก ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ε-๊ทธ๋ฆฌ๋”” ์ •์ฑ…์„ ์‚ฌ์šฉํ•œ๋‹ค. (์ฆ‰, ํ™•๋ฅ  ε๋งŒํผ ๋žœ๋คํ•œ ํ–‰๋™์„ ์„ ํƒํ•œ๋‹ค.)

    from collections import deque
    
    replay_buffer = deque(maxlen=2000)

    ์ตœ๊ทผ์˜ ๊ฒฝํ—˜์—๋งŒ ์˜์ง€ํ•˜์—ฌ DQN์„ ํ›ˆ๋ จํ•˜๋Š” ๋Œ€์‹  ์žฌ์ƒ ๋ฒ„ํผ(์žฌ์ƒ ๋ฉ”๋ชจ๋ฆฌ)์— ๋ชจ๋“  ๊ฒฝํ—˜์„ ์ €์žฅํ•˜๊ณ  ํ›ˆ๋ จ ๋ฐ˜๋ณต๋งˆ๋‹ค ์—ฌ๊ธฐ์—์„œ ๋žœ๋คํ•œ ํ›ˆ๋ จ ๋ฐฐ์น˜๋ฅผ ์ƒ˜ํ”Œ๋งํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฒฝํ—˜๊ณผ ํ›ˆ๋ จ ๋ฐฐ์น˜ ์‚ฌ์ด์˜ ์ƒ๊ด€๊ด€๊ณ„๊ฐ€ ์ค„์–ด๋“ค์–ด ํ›ˆ๋ จ์— ๋„์›€์ด ๋œ๋‹ค.

    ์ด๋ฅผ ์œ„ํ•ด ๋ฑ์„ ์‚ฌ์šฉํ•œ๋‹ค.

    def sample_experiences(batch_size):
        indices = np.random.randint(len(replay_buffer), size=batch_size)
        batch = [replay_buffer[index] for index in indices]
        return [
            np.array([experience[field_index] for experience in batch])
            for field_index in range(6)
        ] # [states, actions, rewards, next_states, dones, truncateds]

    ๊ฐ ๊ฒฝํ—˜์€ ์›์†Œ 6๊ฐœ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.

    ์ƒํƒœ s, ์—์ด์ „ํŠธ๊ฐ€ ์„ ํƒํ•œ ํ–‰๋™ a, ๊ฒฐ๊ณผ ๋ณด์ƒ r, ๋„๋‹ฌํ•œ ๋‹ค์Œ ์ƒํƒœ s', ์—ํ”ผ์†Œ๋“œ๊ฐ€ ์ด๋•Œ ์ข…๋ฃŒ๋˜์—ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ถˆ๋ฆฌ์–ธ ๊ฐ’(done), ๋งˆ์ง€๋ง‰์œผ๋กœ ์—ํ”ผ์†Œ๋“œ๊ฐ€ ์ค‘๋‹จ๋˜์—ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ถˆ๋ฆฌ์–ธ ๊ฐ’(truncated)์ด๋‹ค.

    ์žฌ์ƒ ๋ฒ„ํผ์—์„œ ๊ฒฝํ—˜์„ ๋žœ๋คํ•˜๊ฒŒ ์ƒ˜ํ”„๋งํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์€ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ ๋‹ค.

    ์ด ํ•จ์ˆ˜๋Š” ๊ฒฝํ—˜ ์›์†Œ 6๊ฐœ์— ์ƒ์‘ํ•˜๋Š” ๋„˜ํŒŒ์ด ๋ฐฐ์—ด 6๊ฐœ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

    def play_one_step(env, state, epsilon):
        action = epsilon_greedy_policy(state, epsilon)
        next_state, reward, done, truncated, info = env.step(action)
        replay_buffer.append((state, action, reward, next_state, done, truncated))
        return next_state, reward, done, truncated, info

    ε-๊ทธ๋ฆฌ๋”” ์ •์ฑ…์„ ์‚ฌ์šฉํ•ด ํ•˜๋‚˜์˜ ์Šคํ…์„ ํ”Œ๋ ˆ์ดํ•˜๊ณ  ๋ฐ˜ํ™˜๋œ ๊ฒฝํ—˜์„ ์žฌ์ƒ ๋ฒ„ํผ์— ์ €์žฅํ•œ๋‹ค. 

    batch_size = 32
    discount_factor = 0.95
    optimizer = tf.keras.optimizers.Nadam(learning_rate=1e-2)
    loss_fn = tf.keras.losses.mean_squared_error
    
    def training_step(batch_size):
        experiences = sample_experiences(batch_size)
        states, actions, rewards, next_states, dones, truncateds = experiences
        next_Q_values = next_Q_values.max(axis=0)
        max_next_Q_values = next_Q_values.max(axis=1)
        runs = 1.0 - (dones | truncateds) # ์—ํ”ผ์†Œ๋“œ๊ฐ€ ์ค‘์ง€๋˜๊ฑฐ๋‚˜ ์ข…๋ฃŒ๋˜์ง€ ์•Š์Œ
        target_Q_values = rewards + runs * discount_factor * max_next_Q_values
        target_Q_values = target_Q_values.reshape(-1, 1)
        nask = tf.one_hot(actions, n_outputs)
        with tf.GradientTape() as tape:
            all_Q_values = model(states)
            Q_values = tf.reduce_sum(all_Q_values * mask, axis=1, keepdims=True)
            loss = tf.reduce_mean(loss_fn(target_Q_values, Q_values))
            
        grads = tape.gradient(loss, model.trainable_variables)
        optimizer.apply_gradients(zip(grads, model.trainable_variables))

    ์žฌ์ƒ ๋ฒ„ํผ์—์„œ ๊ฒฝํ—˜ ๋ฐฐ์น˜๋ฅผ ์ƒ˜ํ”Œ๋งํ•˜๊ณ  ์ด ๋ฐฐ์น˜์—์„œ ๊ฒฝ์‚ฌ ํ•˜๊ฐ•๋ฒ• ํ•œ ์Šคํ…์„ ์ˆ˜ํ–‰ํ•˜์—ฌ DQN์„ ํ›ˆ๋ จํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. 

     

    ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ๋ช‡ ๊ฐœ๋ฅผ ์ •์˜ํ•˜๊ณ  ์˜ตํ‹ฐ๋งˆ์ด์ €์™€ ์†์‹ค ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ ๋‹ค.

    training_step() ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ๊ฒฝํ—˜ ๋ฐฐ์น˜๋ฅผ ์ƒ˜ํ”Œ๋งํ•œ ๋‹ค์Œ DQN์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ๊ฒฝํ—˜์˜ ๋‹ค์Œ ์ƒํƒœ์—์„œ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ํ–‰๋™์— ๋Œ€ํ•œ Q-๊ฐ€์น˜๋ฅผ ์˜ˆ์ธกํ•œ๋‹ค. ์—์ด์ „ํŠธ๊ฐ€ ์ตœ์ ์œผ๋กœ ํ”Œ๋ ˆ์ดํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฏ€๋กœ ๋‹ค์Œ ์ƒํƒœ์— ๋Œ€ํ•œ ์ตœ๋Œ€ Q-๊ฐ€์น˜๋งŒ ์ €์žฅํ•œ๋‹ค. ๊ทธ๋‹ค์Œ ํƒ€๊นƒ Q-๊ฐ€์น˜ ์‹์„ ์‚ฌ์šฉํ•ด ๊ฐ ๊ฒฝํ—˜์˜ ์ƒํƒœ-ํ–‰๋™ ์Œ์— ๋Œ€ํ•œ ํƒ€๊นƒ Q-๊ฐ€์น˜๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค.

    DQN์ด ๊ฒฝํ—˜ํ•œ ๊ฐ ์ƒํƒœ-ํ–‰๋™ ์Œ์˜ Q-๊ฐ€์น˜๋ฅผ ๊ณ„์‚ฐํ•˜๊ธธ ์›ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์ด DQN์€ ์—์ด์ „ํŠธ๊ฐ€ ์‹ค์ œ๋กœ ์„ ํƒํ•œ ํ–‰๋™๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ๊ฐ€๋Šฅํ•œ ํ–‰๋™์— ๋Œ€ํ•œ Q-๊ฐ€์น˜๋„ ์ถœ๋ ฅํ•  ๊ฒƒ์ด๋‹ค. ๋”ฐ๋ผ์„œ ํ•„์š”ํ•˜์ง€ ์•Š์€ ๋ชจ๋“  Q-๊ฐ€์น˜๋ฅผ ๋งˆ์Šคํฌ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค. tf.one_hot() ํ•จ์ˆ˜๋Š” ํ–‰๋™ ์ธ๋ฑ์Šค์˜ ๋ฐฐ์—ด์„ ๋งˆ์Šคํฌ๋กœ ๋ณ€ํ™˜ํ•ด์ค€๋‹ค. ์˜ˆ) ์ฒ˜์Œ 3๊ฐœ์˜ ๊ฒฝํ—˜์ด ํ–‰๋™ 1, 1, 0์„ ๊ฐ๊ฐ ๋‹ด๊ณ  ์žˆ๋‹ค๋ฉด ๋งˆ์Šคํฌ๋Š” [[0, 1], [0, 1], [1, 0], ...]๊ณผ ๊ฐ™๋‹ค. ์ด ๋งˆ์Šคํฌ๋ฅผ DQN์˜ ์ถœ๋ ฅ๊ณผ ๊ณฑํ•˜์—ฌ ์›ํ•˜์ง€ ์•Š์€ Q-๊ฐ€์น˜๋ฅผ 0์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋‹ค์Œ 0์„ ์—†์• ๊ธฐ ์œ„ํ•ด ์—ด(axis=1) ๋ฐฉํ–ฅ์œผ๋กœ ๋ง์…ˆํ•˜์—ฌ ๊ฒฝํ—˜๋œ ์ƒํƒœ-ํ–‰๋™ ์Œ์˜ Q-๊ฐ€์น˜๋งŒ ๋‚จ๊ธด๋‹ค. ๊ฒฐ๊ตญ ๋ฐฐ์น˜์— ์žˆ๋Š” ๊ฐ ๊ฒฝํ—˜์— ๋Œ€ํ•ด ์˜ˆ์ธก๋œ Q-๊ฐ€์น˜ ํ•˜๋‚˜๋ฅผ ๋‹ด์€ ํ…์„œ์ธ Q-values๋ฅผ ์–ป๋Š”๋‹ค.

    ์†์‹ค์„ ๊ณ„์‚ฐํ•œ๋‹ค. ์†์‹ค์€ ๊ฒฝํ—˜๋œ ์ƒํƒœ-ํ–‰๋™ ์Œ์— ๋Œ€ํ•œ ํƒ€๊นƒ๊ณผ ์˜ˆ์ธก๋œ Q-๊ฐ€์น˜ ์‚ฌ์ด์˜ ํ‰๊ท  ์ œ๊ณฑ ์˜ค์ฐจ์ด๋‹ค.

    ๋ชจ๋ธ์˜ ํ›ˆ๋ จ ๊ฐ€๋Šฅํ•œ ๋ณ€์ˆ˜์— ๊ด€ํ•œ ์†์‹ค์„ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๊ฒฝ์‚ฌ ํ•˜๊ฐ•๋ฒ•์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

    for episode in range(600):
        obs, info = env.reset)_
        
    for step in range(200):
        epsilon = max(1 - episode / 500, 0.01)
        obs, reward, done, truncated, info = play_one_step(env, obs, epsilon)
        if done or truncated:
            break
            
    if episode > 50:
        training_step(batch_size)

    ์ตœ๋Œ€ ์Šคํ… 200๋ฒˆ์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ์—ํ”ผ์†Œ๋“œ 600๊ฐœ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

    ๊ฐ ์Šคํ…์—์„œ ๋จผ์ € ε-๊ทธ๋ฆฌ๋”” ์ •์ฑ…์— ๋Œ€ํ•œ epsilon ๊ฐ’์„ ๊ณ„์‚ฐํ•œ๋‹ค.

    ์ด ๊ฐ’์€ 500 ์—ํ”ผ์†Œ๋“œ ์ง์ „๊นŒ์ง€ 1์—์„œ 0.01๋กœ ์„ ํ˜•์ ์œผ๋กœ ์ค„์–ด๋“ ๋‹ค.

    ๊ทธ๋‹ค์Œ play_one_step() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ε-๊ทธ๋ฆฌ๋”” ์ •์ฑ…์„ ์‚ฌ์šฉํ•ด ํ–‰๋™์„ ์„ ํƒํ•˜์—ฌ ์‹คํ–‰ํ•˜๊ณ  ๊ทธ ๊ฒฝํ—˜์„ ์žฌ์ƒ ๋ฒ„ํผ์— ๊ธฐ๋กํ•œ๋‹ค.

    ์—ํ”ผ์†Œ๋“œ๊ฐ€ ์ข…๋ฃŒ๋˜๊ฑฐ๋‚˜ ์ค‘๋‹จ๋˜๋ฉด ๋ฐ˜๋ณต์„ ๋๋‚ธ๋‹ค.

    ๋งˆ์ง€๋ง‰์œผ๋กœ 50 ์—ํ”ผ์†Œ๋“œ ์ดํ›„์—๋Š” training_step() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด ์žฌ์ƒ ๋ฒ„ํผ์—์„œ ์ƒ˜ํ”Œ๋งํ•œ ๋ฐฐ์น˜๋กœ ๋ชจ๋ธ์„ ํ›ˆ๋ จํ•œ๋‹ค.

    ํ›ˆ๋ จ ์—†์ด ์—ํ”ผ์†Œ๋“œ๋ฅผ 50๋ฒˆ ํ”Œ๋ ˆ์ดํ•˜๋Š” ์ด์œ ๋Š” ์žฌ์ƒ ๋ฒ„ํผ๊ฐ€ ์ฑ„์›Œ์งˆ ์‹œ๊ฐ„์„ ์ฃผ๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค.

    ์ตœ๋Œ€ ๋ณด์ƒ ๊ทผ์ฒ˜์—์„œ ์•ˆ์ •๋œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์˜€์œผ๋‚˜ ์ ์ˆ˜๊ฐ€ ๊ธ‰๊ฒฉํžˆ ๋–จ์–ด์ง€๋Š” ๊ฑธ ์ตœ์•…์˜ ๋ง๊ฐ์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. 

    ์—์ด์ „ํŠธ๊ฐ€ ํ™˜๊ฒฝ์„ ํƒ์ƒ‰ํ•˜๋ฉด ์ •์ฑ…์„ ์—…๋ฐ์ดํŠธํ•œ๋‹ค. ํ•˜์ง€๋งŒ ํ™˜๊ฒฝ์˜ ํ•œ ๋ถ€๋ถ„์—์„œ ํ•™์Šตํ•œ ๊ฒƒ์ด ์•ž์„œ ๋‹ค๋ฅธ ๋ถ€๋ถ„์—์„œ ํ•™์Šตํ•œ ๊ฒƒ์„ ๋ง๊ฐ€๋œจ๋ฆด ์ˆ˜ ์žˆ๋‹ค. ๊ฒฝํ—˜์€ ํฌ๊ฒŒ ์—ฐ๊ด€๋˜๋ฉฐ ํ•™์Šต ํ™˜๊ฒฝ์€ ๊ณ„์† ๋ฐ”๋€๋‹ค. 


    18.11 ์‹ฌ์ธต Q-๋Ÿฌ๋‹์˜ ๋ณ€ํ˜•

    18.11.1 ๊ณ ์ • Q-๊ฐ€์น˜ ํƒ€๊นƒ

    ๊ธฐ๋ณธ ์‹ฌ์ธต Q-๋Ÿฌ๋‹ ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ๋ชจ๋ธ์€ ์˜ˆ์ธก์„ ๋งŒ๋“ค๊ณ  ํƒ€๊นƒ์„ ์„ค์ •ํ•˜๋Š” ๋ฐ ๋ชจ๋‘ ์‚ฌ์šฉ๋œ๋‹ค.

    ์ด๋Ÿฐ ํ”ผ๋“œ๋ฐฑ ์ˆœํ™˜ ๊ณผ์ •์€ ๋„คํŠธ์›Œํฌ๋ฅผ ๋ถˆ์•ˆ์ •ํ•˜๊ฒŒ ๋งŒ๋“ค์–ด ๋ฐœ์‚ฐ, ์ง„๋™, ๋™๊ฒฐ ๋“ฑ์˜ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค.

    → ํ•œ ๊ฐœ๊ฐ€ ์•„๋‹Œ ๋‘ ๊ฐœ์˜ DQN์„ ์‚ฌ์šฉํ•œ๋‹ค.

    ์ฒซ ๋ฒˆ์งธ DQN์€ ๊ฐ ์Šคํ…์—์„œ ํ•™์Šตํ•˜๊ณ  ์—์ด์ „ํŠธ๋ฅผ ์›€์ง์ด๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” ์˜จ๋ผ์ธ ๋ชจ๋ธ์ด๋‹ค. 

    ๋‘ ๋ฒˆ์งธ DQN์€ ํƒ€๊นƒ์„ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ํƒ€๊นƒ ๋ชจ๋ธ์ด๋ฉฐ, ์ด๋Š” ์˜จ๋ผ์ธ ๋ชจ๋ธ์˜ ๋‹จ์ˆœํ•œ ๋ณต์‚ฌ๋ณธ์ด๋‹ค. 

    target = tf.keras.models.clone_model(model) # ๋ชจ๋ธ ๊ตฌ์กฐ ๋ณต์‚ฌ
    target.set_weights(model.get_weights()) # ๊ฐ€์ค‘์น˜ ๋ณต์‚ฌ
    next_Q_values = target.predict(next_states, verbose=0)

    ๊ทธ๋‹ค์Œ training_step() ํ•จ์ˆ˜์—์„œ ๋‹ค์Œ ์ƒํƒœ์˜ Q-๊ฐ€์น˜๋ฅผ ๊ณ„์‚ฐํ•  ๋•Œ ์˜จ๋ผ์ธ ๋ชจ๋ธ ๋Œ€์‹  ํƒ€๊นƒ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜๋„๋ก ํ•œ ์ค„์„ ๋ฐ”๊พธ์–ด์•ผ ํ•œ๋‹ค.

    if episode % 50 == 0:
        target.set_weights(model.get_weights())

    ๋งˆ์ง€๋ง‰์œผ๋กœ ํ›ˆ๋ จ ๋ฐ˜๋ณต์—์„œ ์ผ์ •ํ•œ ๊ฐ„๊ฒฉ์œผ๋กœ ์˜จ๋ผ์ธ ๋ชจ๋ธ์˜ ๊ฐ€์ค‘์น˜๋ฅผ ํƒ€๊นƒ ๋ชจ๋ธ๋กœ ๋ณต์‚ฌํ•ด์•ผ ํ•œ๋‹ค.

     

    ํƒ€๊นƒ ๋ชจ๋ธ์€ ์˜จ๋ผ์ธ ๋ชจ๋ธ๋ณด๋‹ค ์ž์ฃผ ์—…๋ฐ์ดํŠธ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ Q-๊ฐ€์น˜ ํƒ€๊นƒ์ด ๋” ์•ˆ์ •์ ์ด๋ฉฐ ํ”ผ๋“œ๋ฐฑ ๋ฐ˜๋ณต์„ ์™„ํ™”ํ•˜๊ณ  ์ด์— ๋Œ€ํ•œ ์˜ํ–ฅ์ด ๊ฐ์†Œ๋œ๋‹ค. 

    18.11.2 ๋”๋ธ” DQN

    ํƒ€๊นƒ ๋„คํŠธ์›Œํฌ๊ฐ€ Q-๊ฐ€์น˜๋ฅผ ๊ณผ๋Œ€ํ‰๊ฐ€ํ•˜๊ธฐ ์‰ฝ๋‹ค๋Š” ๊ด€์ธก์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ๋‹ค.

    ๋ชจ๋“  ํ–‰๋™์ด ๋™์ผํ•˜๊ฒŒ ์ข‹๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.

    ํƒ€๊นƒ ๋ชจ๋ธ์ด ์ถ”์ •ํ•œ Q-๊ฐ€์น˜๊ฐ€ ๋™์ผํ•ด์•ผ ํ•˜์ง€๋งŒ ๊ทผ์‚ฟ๊ฐ’์ด๊ธฐ ๋•Œ๋ฌธ์— ์šฐ์—ฐํžˆ ๋‹ค๋ฅธ ๊ฒƒ๋ณด๋‹ค ์กฐ๊ธˆ ๋†’์€ ๊ฐ’์ด ์žˆ์„ ๊ฒƒ์ด๋‹ค.

    ํƒ€๊นƒ ๋ชจ๋ธ์€ ํ•ญ์ƒ ๊ฐ€์žฅ ํฐ Q-๊ฐ€์น˜๋ฅผ ์„ ํƒํ•˜๋ฏ€๋กœ ํ‰๊ท  Q-๊ฐ€์น˜๋ณด๋‹ค ์กฐ๊ธˆ ๋” ์ปค์ง€๊ณ  ์‹ค์ œ Q-๊ฐ€์น˜๋ฅผ ๊ณผ๋Œ€ํ‰๊ฐ€ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค.

    → ๋‹ค์Œ ์ƒํƒœ์—์„œ ์ตœ์„ ์˜ ํ–‰๋™์„ ์„ ํƒํ•  ๋•Œ ํƒ€๊นƒ ๋ชจ๋ธ ๋Œ€์‹  ์˜จ๋ผ์ธ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜๋„๋ก ์ œ์•ˆ๋˜์—ˆ๋‹ค.

    ํƒ€๊นƒ ๋ชจ๋ธ์€ ์ตœ์„ ์˜ ํ–‰๋™์— ๋Œ€ํ•œ Q-๊ฐ€์น˜๋ฅผ ์ถ”์ •ํ•  ๋•Œ๋งŒ ์‚ฌ์šฉํ•œ๋‹ค.

    def training_step(batch_size):
        experiences = sample_experiences(batch_size)
        states, actions, rewards, next_states, dones, truncateds = experiences
        next_Q_value = model.predict(next_states, vervose=0)
        best_next_actions = next_Q_values.argmax(axis=1)
        next_mask = tf.one_hot(best_next_actions, n_outputs).numpy()
        max_next_Q_values = (target.predict(next_states, verbose=0) * next_mask).sum(axis=1)
        [...]

    18.11.3 ์šฐ์„  ์ˆœ์œ„ ๊ธฐ๋ฐ˜ ๊ฒฝํ—˜ ์žฌ์ƒ

    ์ค‘์š”๋„ ์ƒ˜ํ”Œ๋ง(IS), ์šฐ์„  ์ˆœ์œ„ ๊ธฐ๋ฐ˜ ๊ฒฝํ—˜ ์žฌ์ƒ(PER) : ์žฌ์ƒ ๋ฒ„ํผ์—์„œ ๊ฒฝํ—˜์„ ๊ท ์ผํ•˜๊ฒŒ ์ƒ˜ํ”Œ๋งํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ค‘์š”ํ•œ ๊ฒฝํ—˜์„ ๋” ์ž์ฃผ ์ƒ˜ํ”Œ๋งํ•œ๋‹ค. 

    18.11.4 ๋“€์–ผ๋ง DQN

     

Designed by Tistory.