์ธํฐ๋ท์ ๋ค ๋ค์ ธ๋ดค๋๋ฐ ๊ฐํํ์ต์ gym์์ ์ ๊ณตํ๋ ๊ฒ์ agent ์ฌ์ฉํด์ ํ๋ ์์ ๋ ์ก์ฒ๋ง ๊ฐ๊ณ ์ปค์คํ ํด์ ํ์ต์ ํ๋ ์์ ๋ ๋จ ํ ๊ฐ ์์๋ค. ์ด์ ๋ง ๊ณต๋ถ๋ฅผ ์์ํ๋ ์ฌ๋๋ค์๊ฒ ๋์์ด ๋์์ผ๋ฉด ํ๋ ๋ง์์ผ๋ก ๊ฐ๋จํ๊ฒ ์จ๋ณด๊ณ ์ ํ๋ค.
1. Gym์ Env ๊ตฌ์กฐ ์ดํด๋ณด๊ธฐ
๊ผญ ๊ทธ๋์ผํ๋ ๊ฒ์ ์๋์ง๋ง(๋ฐ๋ฐ๋ฅ๋ถํฐ ๊ตฌํํ๋ ๋ฐฉ๋ฒ๋ ์๊ธด ํ๋ค) ์ด์จ๋ gym ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ environment ๊ตฌ์กฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํด์ ๊ตฌํํด๋ณผ ๊ฒ์ด๋ค.
!pip install gym
gym ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ env ๊ตฌ์กฐ๋ ๋์ถฉ ์๋์ ๊ฐ๋ค. site-packages/gym/core.py ์์ ์ง์ ๋ณผ ์ ์๋ค.
class Env(Generic[ObsType, ActType]):m.Generator] = None
"""
The main API methods that users of this class need to know are:
- :meth:`step` - Takes a step in the environment using an action returning the next observation, reward,
if the environment terminated and observation information.
- :meth:`reset` - Resets the environment to an initial state, returning the initial observation and observation information.
- :meth:`render` - Renders the environment observation with modes depending on the output
- :meth:`close` - Closes the environment, important for rendering where pygame is imported
And set the following attributes:
- :attr:`action_space` - The Space object corresponding to valid actions
- :attr:`observation_space` - The Space object corresponding to valid observations
- :attr:`reward_range` - A tuple corresponding to the minimum and maximum possible rewards
- :attr:`spec` - An environment spec that contains the information used to initialise the environment from `gym.make`
- :attr:`metadata` - The metadata of the environment, i.e. render modes
- :attr:`np_random` - The random number generator for the environment
"""
def step(self, action: ActType) -> Tuple[ObsType, float, bool, bool, dict]:
raise NotImplementedError
def reset(
self,
*,
seed: Optional[int] = None,
options: Optional[dict] = None,
) -> Tuple[ObsType, dict]:
# Initialize the RNG if the seed is manually passed
if seed is not None:
self._np_random, seed = seeding.np_random(seed)
def render(self) -> Optional[Union[RenderFrame, List[RenderFrame]]]:
raise NotImplementedError
def close(self):
pass
@property
def unwrapped(self) -> "Env":
return self
def __str__(self):
"""Returns a string of the environment with the spec id if specified."""
if self.spec is None:
return f"<{type(self).__name__} instance>"
else:
return f"<{type(self).__name__}<{self.spec.id}>>"
def __enter__(self):
"""Support with-statement for the environment."""
return self
def __exit__(self, *args):
"""Support with-statement for the environment."""
self.close()
# propagate exception
return False
- ๊ณต์ ๋ฌธ์ ์ค๋ช
์ค๊ฐ ์ฃผ์์ ์ฃ๋ค ์ง์์ ์งง์๋ณด์ธ๋ค. ์๋ฌดํผ ์ค์ํ ๊ฒ์ ์๋์ ๊ฐ๋ค.
- Method
- step ํจ์๋ ์ด๋ค action ์ ์ทจํ์ ๋, state์ ๋ณํ์ ๊ทธ์ ๋ฐ๋ฅธ ๋ณด์์ ์ฑ
์ ํ๋ ๋ถ๋ถ์ด๋ค. ์จ๋๋ก ์๋ฅผ ๋ค๋ฉด ํ์ฌ state ๊ฐ 20๋์ด๊ณ , ๋ชฉํ ์จ๋๊ฐ 30๋๋ผ๋ฉด ์ด๋ค action ์ ์ทจํ๊ณ ๋ ๋ค์ state์ ๋ณํ๊ฐ ๊ธ์ ์ ์ธ์ง, ๋ถ์ ์ ์ธ์ง์ ๋ฐ๋ผ์ reward๋ฅผ ์ฃผ๋ ๋ถ๋ถ์ด ์ด ๋ถ๋ถ์ด๋ค.
- return → observation, reward, terminated, truncated, info, done
- reset ํจ์๋ ํ episode(ํน์ ๊ฒ์, ์ผ์ ์๊ฐ ๋ฑ ํ์ต ์ฃผ๊ธฐ๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค)๋ฅผ ์์ํ ๋ attributes๋ฅผ ์ด๊ธฐํํ๋ ํจ์์ด๋ค.
- return → observation, info
- step ํจ์๋ ์ด๋ค action ์ ์ทจํ์ ๋, state์ ๋ณํ์ ๊ทธ์ ๋ฐ๋ฅธ ๋ณด์์ ์ฑ
์ ํ๋ ๋ถ๋ถ์ด๋ค. ์จ๋๋ก ์๋ฅผ ๋ค๋ฉด ํ์ฌ state ๊ฐ 20๋์ด๊ณ , ๋ชฉํ ์จ๋๊ฐ 30๋๋ผ๋ฉด ์ด๋ค action ์ ์ทจํ๊ณ ๋ ๋ค์ state์ ๋ณํ๊ฐ ๊ธ์ ์ ์ธ์ง, ๋ถ์ ์ ์ธ์ง์ ๋ฐ๋ผ์ reward๋ฅผ ์ฃผ๋ ๋ถ๋ถ์ด ์ด ๋ถ๋ถ์ด๋ค.
- Attributes
- action_space ๋ ์ด ๋ชจ๋ธ์ด ์ทจํ ์ ์๋ ํ๋๋ค์ ์งํฉ์ด๋ค. ์ ์ ์งํฉ์ผ ์๋ ์๊ณ , DDPG ๋ชจ๋ธ๊ณผ ๊ฐ์ ๊ฒฝ์ฐ์๋ ์ฐ์์ ์ธ ๊ณต๊ฐ์ผ๋ก ์ค์ ํ ์๋ ์๋ค. ์ด๋ฅผํ ๋ฉด ๋ถ์ ๊บผ๋ผ, ์ผ๋ผ, ๋ฐ๊ธฐ๋ฅผ ๋ฐ์ผ๋ก ๋ฎ์ถฐ๋ผ์ ๊ฐ์ ํ๋๋ช ๋ น์ ๋ฆฌ์คํธ์ ๊ฐ๊น๋ค๊ณ ๋ณด๋ฉด ๋๋ค.
- observation_space ๋ ๋ฐํํ state์ ํ์๊ณผ ๋ฒ์์ ์ ์์ด๋ค.
- state ๋ ํ๊ฒฝ์ ์ํ์ด๋ค.
- reward ๋ state์ ๋ํด action์ ์ทจํ์ ๋ ๋ฐํํด์ค ๋ณด์์ด๋ค. reward function์ ๋๊ฐ ์ ํด์ค ์ ์๋ ๊ฒ์ ์๋๊ณ , ํ๊ฒฝ์ ๋ง์ถฐ์ ์ ์ ํ ๋ง๋ค์ด์ค์ผํ๋ค. ์ด ๋ถ๋ถ๋ ์์ ์ ๋ฃ๊ธด ํ์ผ๋ ๊ฑฑ์ ๋ง์.
๊ทธ๋ผ ๊ฑฐ๋์ ๋ฏธํ๊ณ ๊ณง์ฅ ํ ๋ฒ ์ง๋ณด๋๋ก ํ์.
* ์ด ์์ ์ ๋ชฉํ๋ ๋๋คํ๊ฒ ์ค์ ๋ ์ซ์๋ฅผ ์ํ๋ ๋ฒ์ ์์ผ๋ก ๋ค์ด์ค๋๋ก ํ๋ ๊ฒ์ด๋ค.
2. Gym Custom Environment ์์ฑํ๊ธฐ
gym library์ Env ๋ฅผ ๊ฐ์ ธ์์ ์์๋ฐ์ ๊ฒ์ด๋ ์ฐ์ import ํ๋ค.
from gym import Env
from gym.spaces import Box # observation space ์ฉ
__init__ ํจ์ ์๋์ action space, observation space, state, ๊ทธ๋ฆฌ๊ณ episode length ๋ฅผ ์ ์ธํด์ฃผ์๋ค.
a. Attributes ์ค์
class ENV(Env):
def __init__(self):
self.action_space = [i for i in range(-2, 3)]
self.observation_space = Box(low=np.array([0]), high=np.array([100]), dtype=np.int8)
self.state = np.random.choice([-20, 0, 20, 40, 60])
self.prev_state = self.state
self.episode_length = 100
def step(self, action):
pass
def reset(self):
pass
ํ๋์ฉ ๋ณด์.
- action space → -2์์ 2 ์ฌ์ด์ ์ ์๋ค๋ก ์ด๋ฃจ์ด์ง ๊ธธ์ด 5์ง๋ฆฌ ๋ฆฌ์คํธ์ด๋ค. gym.spaces.Discrete ๋ฅผ ์ฌ์ฉํด์ ์ ์ํ๋ ๋ฐฉ๋ฒ๋ ์๋๋ฐ, ์ด๋ฒ ์์ ์์ ์ฌ์ฉํ ์์ ๋ชจ๋ธ์ธ Dueling DQN์ action ์ถ๋ก ์ ์ค์ง ์์๋ก๋ง ํ๋ค. ๋ฐ๋ผ์ action space์ index๋ฅผ action์ผ๋ก ํ์ตํ๊ธฐ ์ํด์ ์ด๋ ๊ฒ ์ ์ธ์ ํด์คฌ๋ค.
- observation space → gym.spaces.Box ๋ฅผ ์ฌ์ฉํ๋ค. low์ high์ ์์ฃผ ํฐ ์๋ฏธ๊ฐ ์์ง๋ ์๋ค.
- state → ํ์ฌ ์ฐ๋ฆฌ๋ ์ค์ ์ํ ํ๊ฒฝ์ด ์์ผ๋ฏ๋ก ์ ๋นํ ๋๋คํ๊ฒ ์ค์ ํ๋๋ก ํ๋ค.
- episode_length → ํ๋์ episode์ ๋ช ๊ฐ์ action์ ์คํํ ๊ฒ์ธ์ง๋ฅผ ์ค์ ํ ์ ์๋ค. ์ด ๋ ์์ด 0์ด ๋๋ฉด step ํจ์์ return ์ค ํ๋์ธ done ์ True๋ก ๋ง๋ค๋ฉด ๋๋ค.
b. reset ํจ์ ์์ฑ
์ด์ reset ํจ์๋ฅผ ์์ฑํ๋ค. ์ด๊ธฐํ๋ผ ๋ง๋งํ๋ค.
def reset(self):
self.state = np.random.choice([-20, 0, 20, 40, 60])
self.episode_length = 100
return self.get_obs()
def get_obs(self):
return np.array([self.state], dtype=int)
get_obs ๋ผ๋ ๋ ์์ด ๋ฑ์ฅํ๋ค. ๋ณด์๋ฉด ์์๊ฒ ์ง๋ง Dueling Double DQN์ ํฌํจ๋ neural network์ input์ผ๋ก ์ฌ์ฉ๋ state๋ฅผ ๋ฏธ๋ฆฌ numpy array์ (1, ) shape๋ก ๋ง๋ค์ด์ ์ ๊ฒฝ๋ง ํต๊ณผ ๊ณผ์ ์์ ๋ฌธ์ ๊ฐ ์๊ธฐ์ง ์๋๋ก ํด์ค ๊ฒ์ธ๋ฐ, ์ด๊ฑด ์ฌ์ฉํ๋ ๋ชจ๋ธ์ ๋ง์ถฐ์ ์กฐ์ ํด์ฃผ์ด์ผํ๋ค.
c. step ํจ์ ์์ฑ
์กฐ๊ธ ์ด๋ ค์ด step ํจ์๋ฅผ ์์ฑํด๋ณด์.
def step(self, action):
self.state += self.action_space[action]
self.episode_length -= 1
# Reward ์ฑ
์
if self.state >= 20 and self.state <= 25:
reward = +100
else:
reward = -100
prev_diff = min(abs(self.prev_state - 20), abs(self.prev_state - 25))
curr_diff = min(abs(self.state - 20), abs(self.state - 25))
if curr_diff <= prev_diff:
if reward != 100: reward = reward + 50
else: reward = 100
if curr_diff > prev_diff: reward -= 50
self.prev_state = self.state
# Episode ๋๋ฌ๋์ง ํ์ธ
if self.episode_length <= 0:
done = True
else:
done = False
info = {}
return self.get_obs(), reward, done, info
๋ค์ ์กฐ์กํด๋ณด์ด๋ reward function์ ์ด๋ ๊ฒ ์์ฑํด์ฃผ์๋ค.
- ๋ฒ์ ์์ state๊ฐ ์์ผ๋ฉด reward = 100, ์์ผ๋ฉด reward = -100
- ์ด์ ๋ณด๋ค ๋ฒ์์ ๊ฐ๊น์์ก์ผ๋ฉด +50, ๋ฉ์ด์ก์ผ๋ฉด -50
- ๋จ, ์ด๋ฏธ ๋ฒ์ ์์ ์๋ ๊ฒฝ์ฐ 100์ผ๋ก ๊ณ ์
๊ทธ๋ฆฌ๊ณ episode length์ ๋ฐ๋ผ episode๊ฐ ๋๋ฌ๋์ง ํ๋ณํด์ฃผ๊ณ , returnํ๋ฉด ๋๋ค.
์ ์ํด์ผํ ๊ฒ์, ์ง๊ธ ์ด ๋ณด์ํจ์๋ ์ ๋ง๋ ๋ณด์ํจ์๊ฐ ์๋๋ค!!!!!!!!!!!!!! ๋ ๋ง์ ์ํฉ์ ๊ณ ๋ คํด์ ์ ์ ํ ๋ณด์ํจ์๋ฅผ ๋ง๋ค์ด๋๊ฐ๋ ๊ฒ์ด ์ข๋ค. ์ฐ๋ฆฌ ๋ชจ๋ธ์ ๊ถ๊ทน์ ์ผ๋ก 0๊ณผ 1๋ก ์ด๋ฃจ์ด์ ธ ์์ผ๋ฏ๋ก ๊ธฐ๋ฉด ๊ธฐ๊ณ ์๋๋ฉด ์๋๋ผ๋ ๊ฒ์ ์ผ๋์ ๋์. ๋จ์ํ ๋ ์์๊ฒ ๋ณต์กํ ๊ฒ์ ๊ฐ๋ฅด์น๋ ค๋ฉด ์ ์๋์ด ์ฐ๊ตฌ๋ฅผ ์ข ํด์ผํ๋ค. (ํ์๋ ์์ง ์ ๋ชจ๋ฅธ๋คใ )
์ด์ธ์๋ render ํจ์๋ close ํจ์ ๋ฑ gym environment class์์ ์ถ๊ฐ์ ์ผ๋ก ์์ฑํด์ค ์ ์๋ ํจ์๋ค์ด ์์ง๋ง ๋๋ ์๊ฐํ๋ฅผ ํ๋ค๋๊ฐ ํ๋ ์์ฌ๊น์ง๋ ์์ผ๋ฏ๋ก ์ง๊ธ์ ์๋ตํ๋๋ก ํ๊ฒ ๋ค.
3. ๋ชจ๋ธ ์ ์ฉ
๊ทธ๋ผ ์ด์ ๋ชจ๋ธ๊ณผ ํจ๊ป ์ฌ์ฉํด๋ณด์. ์ฝ๋๋ ๋ฏธ๋ฆฌ ๋ง๋ค์ด๋ ์๋ repository ์ฝ๋๋ฅผ ์ฌ์ฉํ ๊ฒ์ด๋ค. ์๋ ๋ ํฌ์งํ ๋ฆฌ ํ์์ DDDQN ํด๋์ ์ฝ๋๋ฅผ ๋ณด์.
์๋ณธ ์ฝ๋๋ ์ฌ๊ธฐ์์ ํ์ธํ ์ ์๋ค. ReinforcementLearning/DeepQLearning ์๋์ ์๋ค.
DDDQN(Dueling Double Deep Q-Network) ๋ชจ๋ธ์ DDQN(Double Deep Q-Network) ๋ชจ๋ธ๊ณผ Dueling DQN ๋ชจ๋ธ์ ์ฅ์ ์ ์์ด ๋ง๋ ๋ชจ๋ธ์ด๋ค. ์ฌ๊ธฐ์๋ ์์ธํ ๋ชจ๋ธ ์ค๋ช ์ ํ์ง ์์ ๊ฒ์ด๋ฏ๋ก ์ถํ์ Dueling DQN / Double DQN๋ชจ๋ธ์ ๋ํ ํฌ์คํ ์ ํ๊ฒ๋๋ฉด ์ถ๊ฐํ๋๋ก ํ๊ฒ ๋ค. ๋ชจ๋ธ ๊ตฌ์กฐ๋ ์ฐ๋ฆฌ์๊ฒ ์ค์ํ
๊ธด ํ์ง๋ง ์์ฃผ ์ค์ํ์ง ์๋ค. ์ฝ๋๋ง ์ ๋ณด๋ฉด ๋๋ค.
a. DDDQN ํบ์๋ณด๊ธฐ
env = ENV()
agent = Agent(env=env, lr=1e-3, gamma=0.99, n_actions=5, epsilon=1.0,
batch_size=64, input_dims=[1])
์ฐ๋ฆฌ๊ฐ ์์ ๋ง๋ค์ด๋ ENV๋ฅผ env๋ก ์ ์ํ ๋ค์ DDDQN agent๋ฅผ ์ ์ธํด์ค๋ค. agent๋ฅผ ๊ฐ๋จํ ๋ณด๋๋ก ํ์.
class Agent():
def __init__(self, input_dims, env, epsilon=1, lr=1e-3, gamma=0.99, n_actions=2, batch_size=64,
epsilon_dec=1e-3, eps_end=0.01,
mem_size=100000, fc1_dims=128,
fc2_dims=128, replace=100):
self.env = env
self.gamma = gamma
self.epsilon = epsilon
self.eps_dec = epsilon_dec
self.eps_min = eps_end
self.replace = replace
self.batch_size = batch_size
self.learn_step_counter = 1
self.memory = ReplayBuffer(mem_size, input_dims)
self.q_eval = DuelingDeepQNetwork(n_actions, fc1_dims, fc2_dims)
self.q_next = DuelingDeepQNetwork(n_actions, fc1_dims, fc2_dims)
self.q_eval.compile(optimizer=Adam(learning_rate=lr),
loss='mean_squared_error')
self.q_next.compile(optimizer=Adam(learning_rate=lr),
loss='mean_squared_error')
self.action_space = [i for i in range(n_actions)]
์์์์ฃผ ๊ฐ๋จํ๊ฒ ๊ธฐ๋ณธ์ ์ธ ๋ชจ๋ธ์ ๋ํ ์ค๋ช ์ ํ์๋ฉด, ์ด ๋ชจ๋ธ์ ๋ ๊ฐ์ ๋คํธ์ํฌ๋ฅผ ์ฌ์ฉํด์ ํ๋๋ action-reward์ ๋ฐ๋ผ ๋ฐ๋ก๋ฐ๋ก ์ ๋ฐ์ดํธ๋ฅผ ํ๊ณ , ํ๋๋ ์ผ์ ๊ธฐ๊ฐ ์ ๋ฐ์ดํธ๋ฅผ ํ์ง ์๋ค๊ฐ ์ ๋ฐ์ดํธ๋ฅผ ํ๋ ์ง์ฐ๋ target ๋คํธ์ํฌ๋ฅผ ๊ฐ์ง๋ค.
๋ํ state-action-reward์ ๋ํ ์ ๋ณด๋ฅผ ํ์ตํ ๋๋ ๋ฐ๋ก ์ค์๊ฐ์ผ๋ก ๋ค์ด์ค๋ ์ ๋ณด๋ค์ ํ์ฉํ์ง ์๊ณ , Replay Memory๋ผ๋ ์ผ์ข ์ ์ ์ฅ์์ ์ ์ฅํด๋์๋ค๊ฐ ๋๋คํ๊ฒ ๊บผ๋ธ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ํ์ตํ์ฌ ์์กด๋๋ผ๋๊ฐ ๋ญ ๊ธฐํ๋ฑ๋ฑ ์ฑ๋ฅํฅ์์ ๋๋ชจํ๋ค.
๋๋ถ์ด ํ์ต ์ด๋ฐ์ epsilon์ ์ํด ๋๋คํ๊ฒ ๋ช ๋ฒ action์ ์ทจํ๋๋ก ํด์ ๊ณผ์ ํฉ(...๋ง๋ ํํ์ธ์ง ๋ชจ๋ฅด๊ฒ ๋ค.) ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๊ณ ํ๋ค๊ณ ํ๋ค.
gamma์ ๊ฒฝ์ฐ์๋ ๊ฐ์ด 1์ ๊ฐ๊น์ธ ์๋ก ๋ฏธ๋์งํฅ์ ์ผ๋ก, ํ์ฌ์ ๊ฐ์ด ๋ฏธ๋์ ๋ฏธ์น ์ํฅ์ ๋ ๋ง์ด ๊ณ ๋ คํ๋ค๋ ๋ป์ด๋ค. Gradient Vanishing ๋ฌธ์ ์์ ๋คํธ์ํฌ๊ฐ ์งํ๋ ์๋ก ์์ ๊ฐ์ด ์ํ๋ ๊ฒ๊ณผ ๋น์ทํ ๋๋์ด๋ผ๊ณ ์๊ฐํ ์ ์๊ฒ ๋๋ฐ, gamma๊ฐ 1์ด๋ฉด ๋์ค์ ํ์ฌ ๋คํธ์ํฌ์ ์์ธก ๊ฒฐ๊ณผ๊ฐ ๋ฏธ๋๊น์ง ์ํฅ์ ์จ์ ํ, ๋ง์ด ๋ฏธ์น๋ ๊ฒ์ด๋ค.
n_action์ action space์ ๊ธธ์ด(action ๊ฐ์)์ด๋ค. self.action space๋ environment ๊ตฌ์ฑํ ๋ ์ด์ผ๊ธฐํ ๊ฒ์ฒ๋ผ ์ด๋ฒ ์์ ์์ ์ฌ์ฉํ ์์ ๋ชจ๋ธ์ธ Dueling DQN์ action ์ถ๋ก ์ ์ค์ง ์์๋ก๋ง ํ๋ค. ๋ฐ๋ผ์ action space์ index๋ฅผ environment step์ action์ผ๋ก ํ์ตํ๊ธฐ ์ํด 0~n_action ์ฌ์ด๋ก ์ค์ ํด์ฃผ์๋ค.
DDDQN์ ํ์ต ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ๋ค.
- ๋คํธ์ํฌ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก action ๊ณ ๋ฅด๊ธฐ
- env.step์ผ๋ก state์ reward ๋ฐ๊ธฐ
- ๋ฐ์ reward์ state, action ๋ฑ์ memory์ ์ ์ฅํ๊ธฐ
- memory์ ์ ์ฅ๋ ๋ฐ์ดํฐ๋ฅผ ๋๋คํ๊ฒ ๋ฝ์์ ํ์ตํ๊ณ ๋คํธ์ํฌ๋ฅผ ๊ฐ์ ํ๊ธฐ
- 1~4 ๋ฐ๋ณต
๊ทธ๋ฆฌ๊ณ ํ๋ ์ ์ํด์ผํ ๊ฒ์ด ์๋ค๋ฉด Readme ํ์ผ์๋ ์์ฑํด๋ ๊ฒ์ฒ๋ผ ํ์ต ๊ณผ์ ์์ reward function์ ์๋นํ ๋ง์ด ๋ฏฟ๊ณ !!! ์ํฅ์ ๋ง์ด ๋ฐ์์ ์ ๋ฐ์ดํธ๋ฅผ ์ํค๊ธฐ ์ํด์ network target ๊ฐ์ reward์ ๋ฐ์์จ 10๋ฐฐ ์ด๋ฒคํธ๋ฅผ ์ค์ ํ๋ค. ์๋๋๋ก๋ผ๋ฉด ์๋์ * 10์ด ์์ด์ผํ๋ค.
# dddqn.py, line 59-62
for idx, terminal in enumerate(dones):
q_target[idx, actions[idx]] = rewards[idx] * 10 + \
self.gamma*q_next[idx, max_actions[idx]]*(1-int(dones[idx]))
self.q_eval.train_on_batch(states, q_target)
๊ทธ๋ฌ๋ ๋ญ๊ฐ ์๋ชป๋๊ณ ์๋ ๊ฒ ๊ฐ๋ค๋ฉด ์ด ๋ ์์ ์์ฌํด๋ณด์๊ธธ ๋ฐ๋๋ค.
4. ์คํ
python DDDQN_custom/main.py
์ด์ ์คํ์ ํด์ฃผ๊ณ , load checkpoint๋ training resume์ ๋ค False๋ฅผ ์ฒ๋ฆฌํด์ฃผ๋ฉด ์ฒ์๋ถํฐ ํ์ต์ด ์์๋๋ค.
์ด๋ฐ ์์ผ๋ก ํ์ต์ด ๋๋๋ฐ, ๋ง์ฝ์ ๋ญ๊ฐ...ํ์ต์ด...์ด์ํ๋คใ ใ ? ํ๋ฉด choose_action์ ์๋์ ๊ฐ์ด ์์ ํด์ฃผ์. ๋จ evaluate๋ฅผ ํ๊ณ ์ถ์ ๋๋ ๋ค์ ๋๋ ค์ค์ผํ๋ค ใ .. ํด๊ฒฐ๋๋ฉด ๊นํ์ ์ ๋ฐ์ดํธ ํ๋๋ก ํ๊ฒ ๋ค.
def choose_action(self, observation, evaluate=False):
if np.random.random() < self.epsilon:# and evaluate is False:
action = np.random.choice(self.action_space)
else:
state = np.array([observation])
actions = self.q_eval.advantage(state)
action = tf.math.argmax(actions, axis=1).numpy()[0]
return action
์ด๋ ๊ฒ ํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด
initial state: [80] - action: 1 | state: [79] | reward: -50
- action: 1 | state: [78] | reward: -50
- action: 1 | state: [77] | reward: -50
- action: 1 | state: [76] | reward: -50
- action: 1 | state: [75] | reward: -50
- action: 1 | state: [74] | reward: -50
- action: 1 | state: [73] | reward: -50
- action: 1 | state: [72] | reward: -50
- action: 1 | state: [71] | reward: -50
- action: 1 | state: [70] | reward: -50
- action: 1 | state: [69] | reward: -50
- action: 1 | state: [68] | reward: -50
- action: 1 | state: [67] | reward: -50
- action: 1 | state: [66] | reward: -50
- action: 0 | state: [64] | reward: -50
- action: 0 | state: [62] | reward: -50
- action: 0 | state: [60] | reward: -50
- action: 0 | state: [58] | reward: -50
...
- action: 2 | state: [24] | reward: 100
- action: 2 | state: [24] | reward: 100
- action: 2 | state: [24] | reward: 100
- action: 2 | state: [24] | reward: 100
- action: 2 | state: [24] | reward: 100
- action: 2 | state: [24] | reward: 100
- action: 2 | state: [24] | reward: 100
- action: 2 | state: [24] | reward: 100
- action: 2 | state: [24] | reward: 100
- action: 2 | state: [24] | reward: 100
- action: 2 | state: [24] | reward: 100
- action: 2 | state: [24] | reward: 100
- action: 2 | state: [24] | reward: 100
- action: 2 | state: [24] | reward: 100
- action: 2 | state: [24] | reward: 100
- action: 2 | state: [24] | reward: 100
- action: 2 | state: [24] | reward: 100
- action: 2 | state: [24] | reward: 100
| episode: 0 | score: 4900.00 | average score 4900.00
- last state: [24] | reward: 100 | action: 2 | epsilon: 0.999
์๋ก์ฝ๋กฌ ์ ๋๋๋ ๊ฒ์ ๋ณผ ์ ์์๋ค.
๋!!!!!!!!!!!! ํ๋ค๊ฐ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๊ฑฐ๋ ์ค๋ช ์ค ํ๋ฆฐ ๋ถ๋ถ์ด ์๋ค๋ฉด ์ผ๋ง๋ ์ง ๋๊ธ ๋ถํ๋๋ฆฝ๋๋ค(_ _)
'๐ฌ ML & Data > ๐ฎ Reinforcement Learning' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[๊ฐํํ์ต] Dealing with Sparse Reward Environments - ํฌ๋ฐํ ๋ณด์ ํ๊ฒฝ์์ ํ์ตํ๊ธฐ (2) | 2023.10.23 |
---|---|
[๊ฐํํ์ต] DDPG(Deep Deterministic Policy Gradient) (0) | 2023.10.16 |
[๊ฐํํ์ต] Dueling Double Deep Q Learning(DDDQN / Dueling DQN / D3QN) (0) | 2023.10.06 |
[๊ฐํํ์ต] DQN(Deep Q-Network) (0) | 2023.08.01 |
[๊ฐํํ์ต] Markov Decision Process & Q-Learning (0) | 2023.08.01 |