diff --git a/README.md b/README.md index 2bad1ad..07b7bd0 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ============ [![Read the Docs](https://img.shields.io/readthedocs/blobrl?style=for-the-badge)](https://blobrl.readthedocs.io/en/latest/?badge=latest) -[![Build Status](https://img.shields.io/travis/french-ai/reinforcement?branch=master.svg&style=for-the-badge)](https://travis-ci.org/french-ai/reinforcement) +[![Build Status](https://img.shields.io/travis/french-ai/reinforcement/master.svg?=master&style=for-the-badge)](https://travis-ci.org/french-ai/reinforcement) [![CodeFactor](https://www.codefactor.io/repository/github/french-ai/reinforcement/badge?style=for-the-badge)](https://www.codefactor.io/repository/github/french-ai/reinforcement) [![Codecov](https://img.shields.io/codecov/c/github/french-ai/reinforcement?style=for-the-badge)](https://codecov.io/gh/french-ai/reinforcement) [![Discord](https://img.shields.io/badge/discord-chat-7289DA.svg?logo=Discord&style=for-the-badge)](https://discord.gg/f5MZP2K) diff --git a/TODO.md b/TODO.md index 9588dd1..db6ad41 100644 --- a/TODO.md +++ b/TODO.md @@ -20,6 +20,7 @@ - [x] Random Agent - [x] Constant Agent + - [x] Deep Q Network (Mnih *et al.*, [2013](https://arxiv.org/abs/1312.5602)) - [ ] Deep Recurrent Q Network (Hausknecht *et al.*, [2015](https://arxiv.org/abs/1507.06527)) - [ ] Persistent Advantage Learning (Bellamare *et al.*, [2015](https://arxiv.org/abs/1512.04860)) @@ -30,34 +31,41 @@ - [x] Categorical Deep Q Network (Bellamare *et al.*, [2017](https://arxiv.org/abs/1707.06887)) - [ ] Quantile Regression DQN (Dabney et al, [2017](https://arxiv.org/abs/1710.10044)) + - [ ] Rainbow (Hessel *et al.*, [2017](https://arxiv.org/abs/1710.02298)) - [ ] Quantile Regression Deep Q Network (Dabney *et al.*, [2017](https://arxiv.org/abs/1710.10044)) + - [ ] Soft Actor-Critic (Haarnoja et al, [2018](https://arxiv.org/abs/1801.01290)) + - [ ] Vanilla Policy Gradient ([2000](https://papers.nips.cc/paper/1713-policy-gradient-methods-for-reinforcement-learning-with-function-approximation.pdf)) + - [ ] Deep Deterministic Policy Gradient (Lillicrap et al, [2015](https://arxiv.org/abs/1509.02971)) - [ ] Twin Delayed DDPG (Fujimoto et al, [2018](https://arxiv.org/abs/1802.09477)) + - [ ] Trust Region Policy Optimization (Schulman *et al.*, [2015](https://arxiv.org/abs/1502.05477)) - [ ] Proximal Policy Optimizations (Schulman *et al.*, [2017](https://arxiv.org/abs/1707.06347)) + - [ ] A2C (Mnih et al, [2016](https://arxiv.org/abs/1602.01783)) - [ ] A3C (Mnih et al, [2016](https://arxiv.org/abs/1602.01783)) + - [ ] Hindsight Experience Replay (Andrychowicz et al, [2017](https://arxiv.org/abs/1707.01495)) # Network -- [ ] base network support discrete action space -- [ ] base network support continuous action space -- [ ] base network support discrete observation space -- [ ] base network support continuous observation space -- [ ] simple network support discrete/continuous action/observation space -- [ ] c51 network support discrete/continuous action/observation space -- [ ] base dueling network support discrete/continuous action/observation space -- [ ] simple dueling network support discrete/continuous action/observation space +- [x] base network support discrete action space +- [x] base network support continuous action space +- [x] base network support discrete observation space +- [x] base network support continuous observation space +- [x] simple network support discrete/continuous action/observation space +- [x] c51 network support discrete action/observation space +- [x] base dueling network support discrete/continuous action/observation space +- [x] simple dueling network support discrete/continuous action/observation space # Explorations list diff --git a/blobrl/agents/__init__.py b/blobrl/agents/__init__.py index 4ab51f5..4215af5 100644 --- a/blobrl/agents/__init__.py +++ b/blobrl/agents/__init__.py @@ -3,5 +3,4 @@ from .agent_random import AgentRandom from .dqn import DQN from .double_dqn import DoubleDQN -from .dueling_dqn import DuelingDQN from .categorical_dqn import CategoricalDQN diff --git a/blobrl/agents/agent_constant.py b/blobrl/agents/agent_constant.py index a002143..cdafb72 100644 --- a/blobrl/agents/agent_constant.py +++ b/blobrl/agents/agent_constant.py @@ -25,14 +25,7 @@ def __init__(self, observation_space, action_space, device=None): :param action_space: Space for init action size :type observation_space: gym.Space """ - super().__init__(device) - if not isinstance(action_space, Space): - raise TypeError("action_space need to be instance of gym.spaces.Space, not :" + str(type(action_space))) - if not isinstance(observation_space, Space): - raise TypeError( - "observation_space need to be instance of gym.spaces.Space, not :" + str(type(observation_space))) - self.action_space = action_space - self.observation_space = observation_space + super().__init__(observation_space, action_space, device) self.action = self.action_space.sample() diff --git a/blobrl/agents/agent_interface.py b/blobrl/agents/agent_interface.py index efe1abd..2117505 100644 --- a/blobrl/agents/agent_interface.py +++ b/blobrl/agents/agent_interface.py @@ -2,15 +2,30 @@ import torch +from gym.spaces import Space + class AgentInterface(metaclass=abc.ABCMeta): - def __init__(self, device): + def __init__(self, observation_space, action_space, device): """ + :param device: torch device to run agent + :type: torch.device + :param observation_space: Space for init observation size + :type observation_space: gym.Space :param device: torch device to run agent :type: torch.device """ + + if not isinstance(action_space, Space): + raise TypeError("action_space need to be instance of gym.spaces.Space, not :" + str(type(action_space))) + if not isinstance(observation_space, Space): + raise TypeError( + "observation_space need to be instance of gym.spaces.Space, not :" + str(type(observation_space))) + self.action_space = action_space + self.observation_space = observation_space + if device is None: device = torch.device("cpu") if not isinstance(device, torch.device): diff --git a/blobrl/agents/agent_random.py b/blobrl/agents/agent_random.py index 291512e..484d612 100644 --- a/blobrl/agents/agent_random.py +++ b/blobrl/agents/agent_random.py @@ -2,7 +2,6 @@ import pickle import torch -from gym.spaces import Space from blobrl.agents import AgentInterface @@ -25,14 +24,7 @@ def __init__(self, observation_space, action_space, device=None): :param action_space: Space for init action size :type observation_space: gym.Space """ - super().__init__(device) - if not isinstance(action_space, Space): - raise TypeError("action_space need to be instance of gym.spaces.Space, not :" + str(type(action_space))) - if not isinstance(observation_space, Space): - raise TypeError( - "observation_space need to be instance of gym.spaces.Space, not :" + str(type(observation_space))) - self.action_space = action_space - self.observation_space = observation_space + super().__init__(observation_space, action_space, device) def get_action(self, observation): """ Return action randomly choice in action_space diff --git a/blobrl/agents/categorical_dqn.py b/blobrl/agents/categorical_dqn.py index 496f2d5..1a32a0f 100644 --- a/blobrl/agents/categorical_dqn.py +++ b/blobrl/agents/categorical_dqn.py @@ -1,7 +1,7 @@ import torch import torch.nn.functional as F import torch.optim as optim -from gym.spaces import Discrete, Space, flatdim, flatten +from gym.spaces import flatten from blobrl.agents import DQN from blobrl.memories import ExperienceReplay @@ -10,8 +10,8 @@ class CategoricalDQN(DQN): - def __init__(self, action_space, observation_space, memory=ExperienceReplay(), neural_network=None, num_atoms=51, - r_min=-10, r_max=10, step_train=2, batch_size=32, gamma=0.99, + def __init__(self, observation_space, action_space, memory=ExperienceReplay(), network=None, num_atoms=51, + r_min=-10, r_max=10, step_train=1, batch_size=32, gamma=1.0, optimizer=None, greedy_exploration=None, device=None): """ @@ -20,7 +20,7 @@ def __init__(self, action_space, observation_space, memory=ExperienceReplay(), n :param action_space: :param observation_space: :param memory: - :param neural_network: + :param network: :param num_atoms: :param r_min: :param r_max: @@ -30,25 +30,16 @@ def __init__(self, action_space, observation_space, memory=ExperienceReplay(), n :param optimizer: :param greedy_exploration: """ - loss = None - - if not isinstance(action_space, Discrete): - raise TypeError( - "action_space need to be instance of gym.spaces.Space.Discrete, not :" + str(type(action_space))) - if not isinstance(observation_space, Space): - raise TypeError( - "observation_space need to be instance of gym.spaces.Space.Discrete, not :" + str( - type(observation_space))) - - if neural_network is None and optimizer is None: - neural_network = C51Network(observation_shape=flatdim(observation_space), - action_shape=flatdim(action_space)) + if network is None and optimizer is None: + network = C51Network(observation_space=observation_space, + action_space=action_space) num_atoms = 51 - optimizer = optim.Adam(neural_network.parameters()) + optimizer = optim.Adam(network.parameters()) - super().__init__(action_space, observation_space, memory, neural_network, step_train, batch_size, gamma, loss, - optimizer, greedy_exploration, device=device) + super().__init__(observation_space=observation_space, action_space=action_space, memory=memory, + network=network, step_train=step_train, batch_size=batch_size, gamma=gamma, + loss=None, optimizer=optimizer, greedy_exploration=greedy_exploration, device=device) self.num_atoms = num_atoms self.r_min = r_min @@ -63,70 +54,77 @@ def get_action(self, observation): :param observation: stat of environment :type observation: gym.Space """ - observation = torch.tensor([flatten(self.observation_space, observation)], device=self.device) + if not self.greedy_exploration.be_greedy(self.step) and self.with_exploration: + return self.action_space.sample() - prediction = self.neural_network.forward(observation).detach()[0] - q_values = prediction * self.z - q_values = torch.sum(q_values, dim=1) + observation = torch.tensor([flatten(self.observation_space, observation)], device=self.device).float() - return torch.argmax(q_values).detach().item() + prediction = self.network.forward(observation) - def train(self): - """ + def return_values(values): + if isinstance(values, list): + return [return_values(v) for v in values] - """ - self.batch_size = 3 + q_values = values * self.z + q_values = torch.sum(q_values, dim=2) + return torch.argmax(q_values).detach().item() + + return return_values(prediction) + + def apply_loss(self, next_prediction, prediction, actions, rewards, next_observations, dones, len_space): + if isinstance(next_prediction, list): + [self.apply_loss(n, p, a, rewards, next_observations, dones, c) for n, p, a, c in + zip(next_prediction, prediction, actions.permute(1, 0, *[i for i in range(2, len(actions.shape))]), + len_space)] + else: - observations, actions, rewards, next_observations, dones = self.memory.sample(self.batch_size, - device=self.device) + q_values_next = next_prediction * self.z + q_values_next = torch.sum(q_values_next, dim=2) - actions = actions.to(torch.long) - actions = F.one_hot(actions, num_classes=self.action_space.n) + actions = F.one_hot(actions.long(), num_classes=len_space) - predictions_next = self.neural_network.forward(next_observations).detach() - q_values_next = predictions_next * self.z - q_values_next = torch.sum(q_values_next, dim=2) + actions_next = torch.argmax(q_values_next, dim=1) + actions_next = F.one_hot(actions_next, num_classes=len_space) - actions_next = torch.argmax(q_values_next, dim=1) - actions_next = actions_next.to(torch.long) - actions_next = F.one_hot(actions_next, num_classes=self.action_space.n) + dones = dones.view(-1, 1) - dones = dones.view(-1, 1) + tz = rewards.view(-1, 1) + self.gamma * self.z * (1 - dones) + tz = tz.clamp(self.r_min, self.r_max) + b = (tz - self.r_min) / self.delta_z - tz = torch.clamp(rewards.view(-1, 1) + self.gamma * self.z * (1 - dones), self.r_min, self.r_max) - b = (tz - self.r_min) / self.delta_z + l, u = b.floor().to(torch.int64), b.ceil().to(torch.int64) - l, u = b.floor().to(torch.int64), b.ceil().to(torch.int64) + l[(u > 0) * (l == u)] -= 1 + u[(l < (self.num_atoms - 1)) * (l == u)] += 1 - m_prob = torch.zeros((self.batch_size, self.action_space.n, self.num_atoms), device=self.device) + m_prob = torch.zeros((self.batch_size, len_space, self.num_atoms), device=self.device) - predictions_next = predictions_next[actions_next == 1, :] + predictions_next = next_prediction[actions_next == 1, :] - offset = torch.linspace(0, (self.batch_size - 1) * self.num_atoms, self.batch_size, device=self.device).view(-1, - 1) - offset = offset.expand(self.batch_size, self.num_atoms) + offset = torch.linspace(0, (self.batch_size - 1) * self.num_atoms, self.batch_size, + device=self.device).view(-1, + 1) + offset = offset.expand(self.batch_size, self.num_atoms) - u_index = (u + offset).view(-1).to(torch.int64) - l_index = (l + offset).view(-1).to(torch.int64) + u_index = (u + offset).view(-1).to(torch.int64) + l_index = (l + offset).view(-1).to(torch.int64) - predictions_next = (dones + (1 - dones) * predictions_next) + predictions_next = (dones + (1 - dones) * predictions_next) - m_prob_action = m_prob[actions == 1, :].view(-1) - m_prob_action.index_add_(0, u_index, (predictions_next * (u - b)).view(-1)) - m_prob_action.index_add_(0, l_index, (predictions_next * (b - l)).view(-1)) + m_prob_action = m_prob[actions == 1, :].view(-1) + m_prob_action.index_add_(0, u_index, (predictions_next * (u - b)).view(-1)) + m_prob_action.index_add_(0, l_index, (predictions_next * (b - l)).view(-1)) - m_prob[actions == 1, :] = m_prob_action.view(-1, self.num_atoms) + m_prob[actions == 1, :] = m_prob_action.view(-1, self.num_atoms) - self.optimizer.zero_grad() - predictions = self.neural_network.forward(observations) - loss = - predictions.log() * m_prob - loss.sum((1, 2)).mean().backward() + self.optimizer.zero_grad() - self.optimizer.step() + loss = - prediction.log() * m_prob + loss.sum((1, 2)).mean().backward(retain_graph=True) def __str__(self): return 'CategoricalDQN-' + str(self.observation_space) + "-" + str(self.action_space) + "-" + str( - self.neural_network) + "-" + str(self.memory) + "-" + str(self.step_train) + "-" + str( + self.network) + "-" + str(self.memory) + "-" + str(self.step_train) + "-" + str( self.step) + "-" + str(self.batch_size) + "-" + str(self.gamma) + "-" + str(self.loss) + "-" + str( self.optimizer) + "-" + str(self.greedy_exploration) + "-" + str(self.num_atoms) + "-" + str( self.r_min) + "-" + str(self.r_max) + "-" + str(self.delta_z) + "-" + str(self.z) diff --git a/blobrl/agents/double_dqn.py b/blobrl/agents/double_dqn.py index 994882a..35b55e4 100644 --- a/blobrl/agents/double_dqn.py +++ b/blobrl/agents/double_dqn.py @@ -5,7 +5,7 @@ import torch import torch.nn.functional as F import torch.optim as optim -from gym.spaces import flatdim +from gym.spaces import Discrete, MultiDiscrete from blobrl.agents import DQN from blobrl.memories import ExperienceReplay @@ -14,8 +14,8 @@ class DoubleDQN(DQN): """ from 'Deep Reinforcement Learning with Double Q-learning' in https://arxiv.org/pdf/1509.06461.pdf """ - def __init__(self, action_space, observation_space, memory=ExperienceReplay(), neural_network=None, step_copy=500, - step_train=2, batch_size=32, gamma=0.99, loss=None, optimizer=None, greedy_exploration=None, + def __init__(self, observation_space, action_space, memory=ExperienceReplay(), network=None, step_copy=500, + step_train=1, batch_size=32, gamma=1.0, loss=None, optimizer=None, greedy_exploration=None, device=None): """ @@ -24,7 +24,7 @@ def __init__(self, action_space, observation_space, memory=ExperienceReplay(), n :param action_space: :param observation_space: :param memory: - :param neural_network: + :param network: :param step_copy: :param step_train: :param batch_size: @@ -33,17 +33,17 @@ def __init__(self, action_space, observation_space, memory=ExperienceReplay(), n :param optimizer: :param greedy_exploration: """ - super().__init__(action_space, observation_space, memory, neural_network, step_train, batch_size, gamma, loss, + super().__init__(observation_space, action_space, memory, network, step_train, batch_size, gamma, loss, optimizer, greedy_exploration, device=device) - self.neural_network_target = deepcopy(self.neural_network) + self.network_target = deepcopy(self.network) self.copy_online_to_target() self.step_copy = step_copy if optimizer is None: - self.optimizer = optim.Adam(self.neural_network.parameters()) + self.optimizer = optim.Adam(self.network.parameters()) - self.neural_network_target.to(self.device) + self.network_target.to(self.device) def learn(self, observation, action, reward, next_observation, done) -> None: """ learn from parameters @@ -72,25 +72,45 @@ def train(self): observations, actions, rewards, next_observations, dones = self.memory.sample(self.batch_size, device=self.device) - actions_next = torch.argmax(self.neural_network.forward(next_observations).detach(), dim=1) - actions_next_one_hot = F.one_hot(actions_next.to(torch.int64), num_classes=self.action_space.n) - q_next = self.neural_network_target.forward(next_observations).detach() * actions_next_one_hot + next_prediction = self.network.forward(next_observations) + prediction = self.network.forward(observations) + target_next_prediction = self.network_target.forward(next_observations) + + if isinstance(self.action_space, Discrete): + self.apply_loss(next_prediction, prediction, actions, rewards, next_observations, dones, + self.action_space.n, target_next_prediction) + # find space for one_hot encore action in apply loss + elif isinstance(self.action_space, MultiDiscrete): + self.apply_loss(next_prediction, prediction, actions, rewards, next_observations, dones, + self.action_space.nvec, target_next_prediction) + self.optimizer.step() - q = rewards + self.gamma * torch.max(q_next, dim=1)[0] * (1 - dones) + def apply_loss(self, next_prediction, prediction, actions, rewards, next_observations, dones, len_space, + target_next_prediction): + if isinstance(next_prediction, list): + [self.apply_loss(n, p, a, rewards, next_observations, dones, c, t) for n, p, a, c, t in + zip(next_prediction, prediction, actions.permute(1, 0, *[i for i in range(2, len(actions.shape))]), + len_space, target_next_prediction)] + else: - actions_one_hot = F.one_hot(actions.to(torch.int64), num_classes=self.action_space.n) - q_predict = torch.max(self.neural_network.forward(observations) * actions_one_hot, dim=1)[0] + actions_next = torch.argmax(next_prediction.detach(), dim=1) + actions_next_one_hot = F.one_hot(actions_next.to(torch.int64), num_classes=len_space) + q_next = target_next_prediction.detach() * actions_next_one_hot - self.optimizer.zero_grad() - loss = self.loss(q_predict, q) - loss.backward() - self.optimizer.step() + q = rewards + self.gamma * torch.max(q_next, dim=1)[0] * (1 - dones) + + actions_one_hot = F.one_hot(actions.to(torch.int64), num_classes=len_space) + q_predict = torch.max(prediction * actions_one_hot, dim=1)[0] + + self.optimizer.zero_grad() + loss = self.loss(q_predict, q) + loss.backward(retain_graph=True) def copy_online_to_target(self): """ """ - self.neural_network_target.load_state_dict(self.neural_network.state_dict()) + self.network_target.load_state_dict(self.network.state_dict()) def save(self, file_name, dire_name="."): """ Save agent at dire_name/file_name @@ -105,8 +125,8 @@ def save(self, file_name, dire_name="."): dict_save = dict() dict_save["observation_space"] = pickle.dumps(self.observation_space) dict_save["action_space"] = pickle.dumps(self.action_space) - dict_save["neural_network_class"] = pickle.dumps(type(self.neural_network)) - dict_save["neural_network"] = self.neural_network.state_dict() + dict_save["network_class"] = pickle.dumps(type(self.network)) + dict_save["network"] = self.network.state_dict() dict_save["step_train"] = pickle.dumps(self.step_train) dict_save["batch_size"] = pickle.dumps(self.batch_size) dict_save["gamma"] = pickle.dumps(self.gamma) @@ -130,14 +150,14 @@ def load(cls, file_name, dire_name=".", device=None): """ dict_save = torch.load(os.path.abspath(os.path.join(dire_name, file_name))) - neural_network = pickle.loads(dict_save["neural_network_class"])( - observation_shape=flatdim(pickle.loads(dict_save["observation_space"])), - action_shape=flatdim(pickle.loads(dict_save["action_space"]))) - neural_network.load_state_dict(dict_save["neural_network"]) + network = pickle.loads(dict_save["network_class"])( + observation_space=pickle.loads(dict_save["observation_space"]), + action_space=pickle.loads(dict_save["action_space"])) + network.load_state_dict(dict_save["network"]) double_dqn = DoubleDQN(observation_space=pickle.loads(dict_save["observation_space"]), action_space=pickle.loads(dict_save["action_space"]), - neural_network=neural_network, + network=network, step_train=pickle.loads(dict_save["step_train"]), batch_size=pickle.loads(dict_save["batch_size"]), gamma=pickle.loads(dict_save["gamma"]), @@ -152,6 +172,6 @@ def load(cls, file_name, dire_name=".", device=None): def __str__(self): return 'DoubleDQN-' + str(self.observation_space) + "-" + str(self.action_space) + "-" + str( - self.neural_network) + "-" + str(self.memory) + "-" + str(self.step_train) + "-" + str( + self.network) + "-" + str(self.memory) + "-" + str(self.step_train) + "-" + str( self.step) + "-" + str(self.batch_size) + "-" + str(self.gamma) + "-" + str(self.loss) + "-" + str( self.optimizer) + "-" + str(self.greedy_exploration) + "-" + str(self.step_copy) diff --git a/blobrl/agents/dqn.py b/blobrl/agents/dqn.py index 24827b0..47a3c2a 100644 --- a/blobrl/agents/dqn.py +++ b/blobrl/agents/dqn.py @@ -1,11 +1,10 @@ import os import pickle -from abc import ABCMeta import torch import torch.nn.functional as F import torch.optim as optim -from gym.spaces import Discrete, Space, flatdim, flatten +from gym.spaces import Discrete, MultiDiscrete, flatten from blobrl.agents import AgentInterface from blobrl.explorations import GreedyExplorationInterface, EpsilonGreedy @@ -13,69 +12,69 @@ from blobrl.networks import SimpleNetwork -class DQN(AgentInterface, metaclass=ABCMeta): +class DQN(AgentInterface): def enable_exploration(self): - self.trainable = True + self.with_exploration = True def disable_exploration(self): - self.trainable = False + self.with_exploration = False - def __init__(self, action_space, observation_space, memory=ExperienceReplay(), neural_network=None, - step_train=2, batch_size=32, gamma=0.99, loss=None, optimizer=None, greedy_exploration=None, - device=None): + def __init__(self, observation_space, action_space, memory=None, network=None, step_train=1, batch_size=32, + gamma=1.00, loss=None, optimizer=None, greedy_exploration=None, device=None): """ - :param device: torch device to run agent - :type: torch.device + :param action_space: :param observation_space: :param memory: - :param neural_network: + :param network: :param step_train: :param batch_size: :param gamma: :param loss: :param optimizer: :param greedy_exploration: + :param device: torch device to run agent + :type: torch.device """ - if not isinstance(action_space, Discrete): + if not isinstance(action_space, (Discrete, MultiDiscrete)): raise TypeError( - "action_space need to be instance of gym.spaces.Space.Discrete, not :" + str(type(action_space))) - if not isinstance(observation_space, Space): - raise TypeError( - "observation_space need to be instance of gym.spaces.Space.Discrete, not :" + str( - type(observation_space))) - - if neural_network is None and optimizer is not None: - raise TypeError("If neural_network is None, optimizer need to be None not " + str(type(optimizer))) + "action_space need to be instance of Discrete or MultiDiscrete, not :" + str(type(action_space))) - if neural_network is None: - neural_network = SimpleNetwork(observation_shape=flatdim(observation_space), - action_shape=flatdim(action_space)) - if not isinstance(neural_network, torch.nn.Module): - raise TypeError("neural_network need to be instance of torch.nn.Module, not :" + str(type(neural_network))) + if memory is None: + memory = ExperienceReplay() if not isinstance(memory, MemoryInterface): raise TypeError( "memory need to be instance of blobrls.memories.MemoryInterface, not :" + str(type(memory))) if loss is not None and not isinstance(loss, torch.nn.Module): - raise TypeError("loss need to be instance of blobrls.memories.MemoryInterface, not :" + str(type(loss))) + raise TypeError("loss need to be instance of torch.nn.Module, not :" + str(type(loss))) if optimizer is not None and not isinstance(optimizer, optim.Optimizer): raise TypeError( - "optimizer need to be instance of blobrls.memories.MemoryInterface, not :" + str(type(optimizer))) + "optimizer need to be instance of torch.optim.Optimizer, not :" + str(type(optimizer))) + + if network is None and optimizer is not None: + raise TypeError("If network is None, optimizer need to be None not " + str(type(optimizer))) if greedy_exploration is not None and not isinstance(greedy_exploration, GreedyExplorationInterface): raise TypeError( "greedy_exploration need to be instance of blobrls.explorations.GreedyExplorationInterface, not :" + str( type(greedy_exploration))) + if network is None: + network = SimpleNetwork(observation_space=observation_space, + action_space=action_space) + if not isinstance(network, torch.nn.Module): + raise TypeError("network need to be instance of torch.nn.Module, not :" + str(type(network))) + + super().__init__(observation_space=observation_space, action_space=action_space, device=device) + + self.network = network + self.network.to(self.device) - self.observation_space = observation_space - self.action_space = action_space - self.neural_network = neural_network self.memory = memory self.step_train = step_train @@ -90,7 +89,7 @@ def __init__(self, action_space, observation_space, memory=ExperienceReplay(), n self.loss = loss if optimizer is None: - self.optimizer = optim.Adam(self.neural_network.parameters()) + self.optimizer = optim.Adam(self.network.parameters(), lr=0.01) else: self.optimizer = optimizer @@ -99,10 +98,7 @@ def __init__(self, action_space, observation_space, memory=ExperienceReplay(), n else: self.greedy_exploration = greedy_exploration - self.trainable = True - - super().__init__(device) - self.neural_network.to(self.device) + self.with_exploration = True def get_action(self, observation): """ Return action choice by the agents @@ -110,14 +106,20 @@ def get_action(self, observation): :param observation: stat of environment :type observation: gym.Space """ - if not self.greedy_exploration.be_greedy(self.step) and self.trainable: + if not self.greedy_exploration.be_greedy(self.step) and self.with_exploration: return self.action_space.sample() - observation = torch.tensor([flatten(self.observation_space, observation)], device=self.device) + observation = torch.tensor([flatten(self.observation_space, observation)], device=self.device).float() + + q_values = self.network.forward(observation) - q_values = self.neural_network.forward(observation) + def return_values(values): + if isinstance(values, list): + return [return_values(v) for v in values] - return torch.argmax(q_values).detach().item() + return torch.argmax(values).detach().item() + + return return_values(q_values) def learn(self, observation, action, reward, next_observation, done) -> None: """ learn from parameters @@ -134,7 +136,8 @@ def learn(self, observation, action, reward, next_observation, done) -> None: :param done: if env is finished :type done: bool """ - self.memory.append(observation, action, reward, next_observation, done) + self.memory.append([flatten(self.observation_space, observation)], action, reward, + [flatten(self.observation_space, next_observation)], done) self.step += 1 if (self.step % self.step_train) == 0: @@ -150,18 +153,37 @@ def train(self): observations, actions, rewards, next_observations, dones = self.memory.sample(self.batch_size, device=self.device) - q = rewards + self.gamma * torch.max(self.neural_network.forward(next_observations), dim=1)[0].detach() * ( - 1 - dones) + next_prediction = self.network.forward(next_observations) - actions_one_hot = F.one_hot(actions.to(torch.int64), num_classes=self.action_space.n) - q_values_predict = self.neural_network.forward(observations) * actions_one_hot - q_predict = torch.max(q_values_predict, dim=1) + prediction = self.network.forward(observations) - self.optimizer.zero_grad() - loss = self.loss(q_predict[0], q) - loss.backward() + if isinstance(self.action_space, Discrete): + self.apply_loss(next_prediction, prediction, actions, rewards, next_observations, dones, + self.action_space.n) + # find space for one_hot encore action in apply loss + elif isinstance(self.action_space, MultiDiscrete): + self.apply_loss(next_prediction, prediction, actions, rewards, next_observations, dones, + self.action_space.nvec) self.optimizer.step() + def apply_loss(self, next_prediction, prediction, actions, rewards, next_observations, dones, len_space): + if isinstance(next_prediction, list): + [self.apply_loss(n, p, a, rewards, next_observations, dones, c) for n, p, a, c in + zip(next_prediction, prediction, actions.permute(1, 0, *[i for i in range(2, len(actions.shape))]), + len_space)] + else: + + q = rewards + self.gamma * next_prediction.max(1)[0].detach() * ( + 1 - dones) + + actions_one_hot = F.one_hot(actions.to(torch.int64), num_classes=len_space) + q_values_predict = prediction * actions_one_hot + q_predict = torch.max(q_values_predict, dim=1) + + self.optimizer.zero_grad() + loss = self.loss(q_predict[0], q) + loss.backward(retain_graph=True) + def save(self, file_name, dire_name="."): """ Save agent at dire_name/file_name @@ -175,8 +197,8 @@ def save(self, file_name, dire_name="."): dict_save = dict() dict_save["observation_space"] = pickle.dumps(self.observation_space) dict_save["action_space"] = pickle.dumps(self.action_space) - dict_save["neural_network_class"] = pickle.dumps(type(self.neural_network)) - dict_save["neural_network"] = self.neural_network.cpu().state_dict() + dict_save["network_class"] = pickle.dumps(type(self.network)) + dict_save["network"] = self.network.cpu().state_dict() dict_save["step_train"] = pickle.dumps(self.step_train) dict_save["batch_size"] = pickle.dumps(self.batch_size) dict_save["gamma"] = pickle.dumps(self.gamma) @@ -199,14 +221,14 @@ def load(cls, file_name, dire_name=".", device=None): """ dict_save = torch.load(os.path.abspath(os.path.join(dire_name, file_name))) - neural_network = pickle.loads(dict_save["neural_network_class"])( - observation_shape=flatdim(pickle.loads(dict_save["observation_space"])), - action_shape=flatdim(pickle.loads(dict_save["action_space"]))) - neural_network.load_state_dict(dict_save["neural_network"]) + network = pickle.loads(dict_save["network_class"])( + observation_space=pickle.loads(dict_save["observation_space"]), + action_space=pickle.loads(dict_save["action_space"])) + network.load_state_dict(dict_save["network"]) return DQN(observation_space=pickle.loads(dict_save["observation_space"]), action_space=pickle.loads(dict_save["action_space"]), - neural_network=neural_network, + network=network, step_train=pickle.loads(dict_save["step_train"]), batch_size=pickle.loads(dict_save["batch_size"]), gamma=pickle.loads(dict_save["gamma"]), @@ -217,6 +239,6 @@ def load(cls, file_name, dire_name=".", device=None): def __str__(self): return 'DQN-' + str(self.observation_space) + "-" + str(self.action_space) + "-" + str( - self.neural_network) + "-" + str(self.memory) + "-" + str(self.step_train) + "-" + str( + self.network) + "-" + str(self.memory) + "-" + str(self.step_train) + "-" + str( self.step) + "-" + str(self.batch_size) + "-" + str(self.gamma) + "-" + str(self.loss) + "-" + str( self.optimizer) + "-" + str(self.greedy_exploration) diff --git a/blobrl/agents/dueling_dqn.py b/blobrl/agents/dueling_dqn.py deleted file mode 100644 index 7dcd38d..0000000 --- a/blobrl/agents/dueling_dqn.py +++ /dev/null @@ -1,84 +0,0 @@ -import os -import pickle - -import torch -from gym.spaces import flatdim - -from blobrl.agents import DoubleDQN -from blobrl.memories import ExperienceReplay -from blobrl.networks import SimpleDuelingNetwork, BaseDuelingNetwork - - -class DuelingDQN(DoubleDQN): - """ from 'Dueling Network Architectures for Deep Reinforcement Learning' in https://arxiv.org/abs/1511.06581 """ - - def __init__(self, action_space, observation_space, memory=ExperienceReplay(), neural_network=None, step_copy=500, - step_train=2, batch_size=32, gamma=0.99, loss=None, optimizer=None, greedy_exploration=None, - device=None): - """ - - :param device: torch device to run agent - :type: torch.device - :param action_space: - :param observation_space: - :param memory: - :param neural_network: - :param step_copy: - :param step_train: - :param batch_size: - :param gamma: - :param loss: - :param optimizer: - :param greedy_exploration: - """ - - if neural_network is None: - neural_network = SimpleDuelingNetwork(observation_shape=flatdim(observation_space), - action_shape=flatdim(action_space)) - - if not isinstance(neural_network, BaseDuelingNetwork): - raise TypeError("neural_network need to be instance of blobrl.agents.BaseDuelingNetwork, not :" + str( - type(neural_network))) - - super().__init__(action_space, observation_space, memory=memory, neural_network=neural_network, - step_copy=step_copy, step_train=step_train, batch_size=batch_size, gamma=gamma, loss=loss, - optimizer=optimizer, greedy_exploration=greedy_exploration, device=device) - - @classmethod - def load(cls, file_name, dire_name=".", device=None): - """ load agent form dire_name/file_name - - :param device: torch device to run agent - :type: torch.device - :param file_name: name of file for load - :type file_name: string - :param dire_name: name of directory where we would load it - :type file_name: string - """ - dict_save = torch.load(os.path.abspath(os.path.join(dire_name, file_name))) - - neural_network = pickle.loads(dict_save["neural_network_class"])( - observation_shape=flatdim(pickle.loads(dict_save["observation_space"])), - action_shape=flatdim(pickle.loads(dict_save["action_space"]))) - neural_network.load_state_dict(dict_save["neural_network"]) - - dueling_dqn = DuelingDQN(observation_space=pickle.loads(dict_save["observation_space"]), - action_space=pickle.loads(dict_save["action_space"]), - neural_network=neural_network, - step_train=pickle.loads(dict_save["step_train"]), - batch_size=pickle.loads(dict_save["batch_size"]), - gamma=pickle.loads(dict_save["gamma"]), - loss=pickle.loads(dict_save["loss"]), - optimizer=pickle.loads(dict_save["optimizer"]), - greedy_exploration=pickle.loads(dict_save["greedy_exploration"]), - device=device) - - dueling_dqn.step_copy = pickle.loads(dict_save["step_copy"]) - - return dueling_dqn - - def __str__(self): - return 'DuelingDQN-' + str(self.observation_space) + "-" + str(self.action_space) + "-" + str( - self.neural_network) + "-" + str(self.memory) + "-" + str(self.step_train) + "-" + str( - self.step) + "-" + str(self.batch_size) + "-" + str(self.gamma) + "-" + str(self.loss) + "-" + str( - self.optimizer) + "-" + str(self.greedy_exploration) + "-" + str(self.step_copy) diff --git a/blobrl/memories/experience_replay.py b/blobrl/memories/experience_replay.py index 6bcc120..37ff4de 100644 --- a/blobrl/memories/experience_replay.py +++ b/blobrl/memories/experience_replay.py @@ -6,7 +6,7 @@ class ExperienceReplay(MemoryInterface): - def __init__(self, max_size=300): + def __init__(self, max_size=5000): """ :param max_size: @@ -38,28 +38,8 @@ def extend(self, observations, actions, rewards, next_observations, dones): :param next_observations: :param dones: """ - datas = np.array((observations, actions, rewards, next_observations, dones)).T - - len_datas = len(datas) - - if len_datas > self.max_size: - datas = datas[-self.max_size:] - len_datas = self.max_size - - datas[:, 0] = [np.array(observation) for observation in datas[:, 0]] - datas[:, 3] = [np.array(next_observation) for next_observation in datas[:, 3]] - - idx_max = self.index + len_datas - - if idx_max > self.max_size: - idx_max = self.max_size - idx_max - self.buffer[self.index:self.max_size] = datas[:idx_max] - self.buffer[:idx_max] = datas[idx_max:] - else: - self.buffer[self.index:idx_max] = datas - - self.size = min(self.size + len_datas, self.max_size) - self.index = idx_max + for o, a, r, n, d in zip(observations, actions, rewards, next_observations, dones): + self.append(o, a, r, n, d) def sample(self, batch_size, device): """ diff --git a/blobrl/networks/__init__.py b/blobrl/networks/__init__.py index 3fec55c..6ce6207 100644 --- a/blobrl/networks/__init__.py +++ b/blobrl/networks/__init__.py @@ -3,3 +3,5 @@ from .base_dueling_network import BaseDuelingNetwork from .simple_dueling_network import SimpleDuelingNetwork from .c51_network import C51Network + +from .utils import get_last_layers diff --git a/blobrl/networks/base_dueling_network.py b/blobrl/networks/base_dueling_network.py index eaad7df..7459069 100644 --- a/blobrl/networks/base_dueling_network.py +++ b/blobrl/networks/base_dueling_network.py @@ -5,21 +5,31 @@ class BaseDuelingNetwork(BaseNetwork): @abc.abstractmethod - def __init__(self, observation_shape, action_shape): + def __init__(self, network): """ - :param observation_shape: - :param action_shape: + :param network: network when we add Value head + :type network: BaseNetwork and not BaseDuelingNetwork """ - super().__init__(observation_shape=observation_shape, action_shape=action_shape) - self.features = None - self.advantage = None - self.value = None + if not isinstance(network, BaseNetwork): + raise TypeError("network need to be instance of BaseNetwork, not :" + str(type(network))) + if isinstance(network, BaseDuelingNetwork): + raise TypeError("network can't be instance of BaseDuelingNetwork :" + str(type(network))) + + super().__init__(observation_space=network.observation_space, action_space=network.action_space) + self.network = network + self.value_outputs = None def forward(self, observation): x = observation.view(observation.shape[0], -1) - x = self.features(x) - advantage = self.advantage(x) - value = self.value(x) - return value + advantage - advantage.mean() + x = self.network.network(x) + + def map_forward(layers, last_tensor, value_outputs): + if isinstance(layers, list): + return [map_forward(layers, last_tensor, value_outputs) for layers in layers] + advantage = layers(last_tensor) + value = value_outputs(last_tensor) + return value + advantage - advantage.mean() + + return map_forward(self.network.outputs, x, self.value_outputs, ) diff --git a/blobrl/networks/base_network.py b/blobrl/networks/base_network.py index 66f13e9..751e4b6 100644 --- a/blobrl/networks/base_network.py +++ b/blobrl/networks/base_network.py @@ -1,19 +1,36 @@ import abc - +from gym.spaces import Space import torch.nn as nn class BaseNetwork(nn.Module, metaclass=abc.ABCMeta): @abc.abstractmethod - def __init__(self, observation_shape, action_shape): + def __init__(self, observation_space, action_space): """ - :param observation_shape: - :param action_shape: + :param observation_space: + :param action_space: """ super().__init__() - self.observation_space = observation_shape - self.action_space = action_shape + + if not isinstance(observation_space, Space): + raise TypeError("observation_space need to be Space not " + str(type(observation_space))) + if not isinstance(action_space, Space): + raise TypeError("action_space need to be Space not " + str(type(action_space))) + + self.observation_space = observation_space + self.action_space = action_space + self.outputs = None + self.network = None + + @abc.abstractmethod + def forward(self, observation): + """ + + :param observation: + :return: + """ + pass @abc.abstractmethod def __str__(self): diff --git a/blobrl/networks/c51_network.py b/blobrl/networks/c51_network.py index eb1856e..a82b4ec 100644 --- a/blobrl/networks/c51_network.py +++ b/blobrl/networks/c51_network.py @@ -1,42 +1,56 @@ import numpy as np import torch import torch.nn as nn +from gym.spaces import flatdim, Discrete, MultiDiscrete from blobrl.networks import BaseNetwork class C51Network(BaseNetwork): - def __init__(self, observation_shape, action_shape): + def __init__(self, observation_space, action_space): """ - :param observation_shape: - :param action_shape: + :param observation_space: + :param action_space: """ - super().__init__(observation_shape=observation_shape, action_shape=action_shape) + if not isinstance(action_space, (Discrete, MultiDiscrete)): + raise TypeError( + "action_space need to be instance of Discrete or MultiDiscrete, not :" + str(type(action_space))) - if not isinstance(observation_shape, (tuple, int)): - raise TypeError("observation_space need to be Space not " + str(type(observation_shape))) - if not isinstance(action_shape, (tuple, int)): - raise TypeError("action_space need to be Space not " + str(type(action_shape))) + super().__init__(observation_space=observation_space, action_space=action_space) self.NUM_ATOMS = 51 self.network = nn.Sequential() - self.network.add_module("C51_Linear_Input", nn.Linear(np.prod(self.observation_space), 64)) + self.network.add_module("C51_Linear_Input", nn.Linear(np.prod(flatdim(self.observation_space)), 64)) self.network.add_module("C51_LeakyReLU_Input", nn.LeakyReLU()) self.network.add_module("C51_Linear_1", nn.Linear(64, 64)) self.network.add_module("C51_LeakyReLU_1", nn.LeakyReLU()) self.distributional_list = [] - self.len_distributional = np.prod(self.action_space) + if isinstance(self.action_space, Discrete): + self.len_distributional = self.action_space.n - for i in range(self.len_distributional): - distributional = nn.Sequential() - distributional.add_module("C51_Distributional_" + str(i) + "_Linear", nn.Linear(64, self.NUM_ATOMS)) - distributional.add_module("C51_Distributional_" + str(i) + "_Softmax", nn.Softmax(dim=1)) + for i in range(self.len_distributional): + distributional = nn.Sequential() + distributional.add_module("C51_Distributional_" + str(i) + "_Linear", nn.Linear(64, self.NUM_ATOMS)) + distributional.add_module("C51_Distributional_" + str(i) + "_Softmax", nn.Softmax(dim=1)) - self.add_module("C51_Distributional_" + str(i) + "_Sequential", distributional) - self.distributional_list.append(distributional) + self.add_module("C51_Distributional_" + str(i) + "_Sequential", distributional) + self.distributional_list.append(distributional) + + elif isinstance(self.action_space, MultiDiscrete): + def gen_outputs(nvec): + dis = [] + for nspace in nvec: + if isinstance(nspace, (list, np.ndarray)): + dis.append(gen_outputs(nspace)) + else: + dis.append( + [nn.Sequential(nn.Linear(64, self.NUM_ATOMS), nn.Softmax(dim=1)) for i in range(nspace)]) + return dis + + self.distributional_list = gen_outputs(self.action_space.nvec) def forward(self, observation): """ @@ -46,13 +60,27 @@ def forward(self, observation): """ x = observation.view(observation.shape[0], -1) x = self.network(x) + if isinstance(self.action_space, Discrete): + q = [distributionalLayer(x) for distributionalLayer in self.distributional_list] + q = torch.cat(q) + q = torch.reshape(q, (self.action_space.n, -1, self.NUM_ATOMS)) + q = q.permute(1, 0, 2) + + return q + if isinstance(self.action_space, MultiDiscrete): + + def do_forward(nvec, llayers, x): + if isinstance(llayers[-1], list): + return [do_forward(n, l, x) for n, l in zip(nvec, llayers)] + + q = [distributionalLayer(x) for distributionalLayer in llayers] + q = torch.cat(q) + q = torch.reshape(q, (nvec, -1, self.NUM_ATOMS)) + q = q.permute(1, 0, 2) - q = [distributionalLayer(x) for distributionalLayer in self.distributional_list] - q = torch.cat(q) - q = torch.reshape(q, (self.len_distributional, -1, self.NUM_ATOMS)) - q = q.permute(1, 0, 2) + return q - return q + return do_forward(self.action_space.nvec, self.distributional_list, x) def __str__(self): return 'C51Network-' + str(self.observation_space) + "-" + str(self.action_space) diff --git a/blobrl/networks/simple_dueling_network.py b/blobrl/networks/simple_dueling_network.py index 769592c..9ccc201 100644 --- a/blobrl/networks/simple_dueling_network.py +++ b/blobrl/networks/simple_dueling_network.py @@ -1,36 +1,22 @@ -import numpy as np from torch import nn - from blobrl.networks import BaseDuelingNetwork class SimpleDuelingNetwork(BaseDuelingNetwork): - def __init__(self, observation_shape, action_shape): + def __init__(self, network): """ - :param observation_shape: - :param action_shape: + :param observation_space: + :param action_space: """ - super().__init__(observation_shape=observation_shape, action_shape=action_shape) - - self.features = nn.Sequential() - self.features.add_module("NetWorkSimple_Linear_Input", nn.Linear(np.prod(self.observation_space), 64)) - self.features.add_module("NetWorkSimple_LeakyReLU_Input", nn.LeakyReLU()) - self.features.add_module("NetWorkSimple_Linear_1", nn.Linear(64, 64)) - self.features.add_module("NetWorkSimple_LeakyReLU_1", nn.LeakyReLU()) - self.features.add_module("NetWorkSimple_Linear_Output", nn.Linear(64, 64)) - self.advantage = nn.Sequential( - nn.Linear(64, 64), - nn.LeakyReLU(), - nn.Linear(64, np.prod(self.action_space)) - ) + super().__init__(network=network) - self.value = nn.Sequential( + self.value_outputs = nn.Sequential( nn.Linear(64, 64), nn.LeakyReLU(), nn.Linear(64, 1) ) def __str__(self): - return 'SimpleDuelingNetwork-' + str(self.observation_space) + "-" + str(self.action_space) + return 'SimpleDuelingNetwork-' + str(self.network) diff --git a/blobrl/networks/simple_network.py b/blobrl/networks/simple_network.py index c1c482a..f6155de 100644 --- a/blobrl/networks/simple_network.py +++ b/blobrl/networks/simple_network.py @@ -1,29 +1,26 @@ import numpy as np import torch.nn as nn - +from gym.spaces import flatdim +from .utils import get_last_layers from blobrl.networks import BaseNetwork class SimpleNetwork(BaseNetwork): - def __init__(self, observation_shape, action_shape): + def __init__(self, observation_space, action_space): """ - :param observation_shape: - :param action_shape: + :param observation_space: + :param action_space: """ - super().__init__(observation_shape=observation_shape, action_shape=action_shape) - - if not isinstance(observation_shape, (tuple, int)): - raise TypeError("observation_space need to be Space not " + str(type(observation_shape))) - if not isinstance(action_shape, (tuple, int)): - raise TypeError("action_space need to be Space not " + str(type(action_shape))) + super().__init__(observation_space=observation_space, action_space=action_space) self.network = nn.Sequential() - self.network.add_module("NetWorkSimple_Linear_Input", nn.Linear(np.prod(self.observation_space), 64)) + self.network.add_module("NetWorkSimple_Linear_Input", nn.Linear(np.prod(flatdim(self.observation_space)), 64)) self.network.add_module("NetWorkSimple_LeakyReLU_Input", nn.LeakyReLU()) self.network.add_module("NetWorkSimple_Linear_1", nn.Linear(64, 64)) self.network.add_module("NetWorkSimple_LeakyReLU_1", nn.LeakyReLU()) - self.network.add_module("NetWorkSimple_Linear_Output", nn.Linear(64, np.prod(self.action_space))) + + self.outputs = get_last_layers(self.action_space, last_dim=64) def forward(self, observation): """ @@ -31,8 +28,16 @@ def forward(self, observation): :param observation: :return: """ + x = observation.view(observation.shape[0], -1) - return self.network(x) + x = self.network(x) + + def forwards(last_tensor, layers): + if isinstance(layers, list): + return [forwards(last_tensor, layers) for layers in layers] + return layers(last_tensor) + + return forwards(x, self.outputs) def __str__(self): return 'SimpleNetwork-' + str(self.observation_space) + "-" + str(self.action_space) diff --git a/blobrl/networks/utils.py b/blobrl/networks/utils.py new file mode 100644 index 0000000..c939e89 --- /dev/null +++ b/blobrl/networks/utils.py @@ -0,0 +1,38 @@ +from gym.spaces import flatdim +from gym.spaces import Box, Discrete, MultiDiscrete, MultiBinary, Tuple, Dict +import torch.nn as nn +import numpy as np + + +def get_last_layers(space, last_dim): + if isinstance(space, Box): + def map_box(ld, n): + if isinstance(n, list): + return [map_box(ld, x) for x in n] + return nn.Linear(ld, 1) + + return map_box(last_dim, np.empty(space.shape).tolist()) + if isinstance(space, Discrete): + return nn.Sequential(*[nn.Linear(last_dim, flatdim(space))]) + if isinstance(space, Tuple): + return [get_last_layers(s, last_dim) for s in space] + if isinstance(space, Dict): + return [get_last_layers(s, last_dim) for s in space.spaces.values()] + if isinstance(space, MultiBinary): + def map_multibinary(ld, n): + if isinstance(n, list): + return [map_multibinary(ld, x) for x in n] + + return nn.Sequential(*[nn.Linear(ld, 1), nn.Sigmoid()]) + + return map_multibinary(last_dim, np.empty(space.n).tolist()) + if isinstance(space, MultiDiscrete): + def map_multidiscrete(ld, n): + if isinstance(n, list): + return [map_multidiscrete(ld, x) for x in n] + + return nn.Sequential(*[nn.Linear(ld, n)]) + + return map_multidiscrete(last_dim, space.nvec.tolist()) + + raise NotImplementedError diff --git a/blobrl/trainer.py b/blobrl/trainer.py index 4722c5b..b1caff0 100644 --- a/blobrl/trainer.py +++ b/blobrl/trainer.py @@ -7,7 +7,7 @@ from IPython import display from blobrl import Logger, Record -from blobrl.agents import AgentInterface, AgentRandom, DQN, DoubleDQN, CategoricalDQN, DuelingDQN +from blobrl.agents import AgentInterface, AgentRandom, DQN, DoubleDQN, CategoricalDQN class Trainer: @@ -25,7 +25,7 @@ def __init__(self, environment, agent, log_dir="./runs"): self.agent = agent(observation_space=observation_space, action_space=action_space) elif isinstance(agent, AgentInterface): import warnings - warnings.warn("be sure of agent have good input and output dimension") + warnings.warn("be sure of your agent need to have good input and output dimension") self.agent = agent else: raise TypeError("this type (" + str(type(agent)) + ") is an AgentInterface or instance of AgentInterface") @@ -52,14 +52,10 @@ def do_step(self, observation, learn=True, logger=None, render=True): :param observation: - :param env: - :param agent: :param learn: :param logger: :param render: if show env render :type render: bool - :param on_notebook: if render is on notebook - :type on_notebook: bool :return: """ if render: @@ -75,13 +71,9 @@ def do_step(self, observation, learn=True, logger=None, render=True): def do_episode(self, logger=None, render=True): """ - :param env: - :param agent: :param logger: :param render: if show env render :type render: bool - :param on_notebook: if render is on notebook - :type on_notebook: bool """ self.agent.enable_exploration() observation = self.environment.reset() @@ -96,13 +88,9 @@ def do_episode(self, logger=None, render=True): def evaluate(self, logger=None, render=True): """ - :param env: - :param agent: :param logger: :param render: if show env render :type render: bool - :param on_notebook: if render is on notebook - :type on_notebook: bool """ self.agent.disable_exploration() observation = self.environment.reset() @@ -120,16 +108,19 @@ def train(self, max_episode=1000, nb_evaluation=4, render=True): :param max_episode: :param render: if show env render :type render: bool - :param on_notebook: if render is on notebook - :type on_notebook: bool """ self.environment.reset() for i_episode in range(1, max_episode + 1): self.do_episode(logger=self.logger, render=render) - if nb_evaluation != 0: - if i_episode == 1 or i_episode == max_episode or i_episode % (max_episode // (nb_evaluation - 1)) == 0: - self.evaluate(logger=self.logger, render=True) + if nb_evaluation > 0: + if nb_evaluation <= 1: + if i_episode == max_episode: + self.evaluate(logger=self.logger, render=render) + + elif i_episode == 1 or i_episode == max_episode or i_episode % int( + max_episode // (nb_evaluation - 1)) == 0: + self.evaluate(logger=self.logger, render=render) self.close() def render(self): @@ -182,8 +173,6 @@ def arg_to_agent(arg_agent) -> AgentInterface: return DoubleDQN if arg_agent == "categorical_dqn": return CategoricalDQN - if arg_agent == "dueling_dqn": - return DuelingDQN raise ValueError("this agent (" + str(arg_agent) + ") is not implemented") @@ -194,9 +183,6 @@ def arg_to_agent(arg_agent) -> AgentInterface: parser.add_argument('--max_episode', type=int, help='number of episode to train', nargs='?', const=1, default=100) parser.add_argument('--render', type=bool, help='if show render on each step or not', nargs='?', const=1, default=False) - # parser.add_argument('--train', type=bool, help='if train agent or not', nargs='?', const=1, - # default=True) - # parser.add_argument('--file_path', type=str, help='path to file for load trained agent') args = parser.parse_args() trainer = Trainer(environment=args.env, agent=arg_to_agent(args.agent)) diff --git a/examples/example_train_jupyter.ipynb b/examples/example_train_jupyter.ipynb new file mode 100644 index 0000000..b460bdf --- /dev/null +++ b/examples/example_train_jupyter.ipynb @@ -0,0 +1,723 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "ZTuJfCB_CYzh" + }, + "source": [ + "## OpenAI Gym Available Environment\n", + "\n", + "Gym comes with a diverse suite of environments that range from easy to difficult and involve many different kinds of data. View the [full list of environments](https://gym.openai.com/envs) to get the birds-eye view.\n", + "\n", + "- [Classic control](https://gym.openai.com/envs#classic_control) and [toy text](https://gym.openai.com/envs#toy_text): complete small-scale tasks, mostly from the RL literature. They’re here to get you started.\n", + "\n", + "- [Algorithmic](https://gym.openai.com/envs#algorithmic): perform computations such as adding multi-digit numbers and reversing sequences. One might object that these tasks are easy for a computer. The challenge is to learn these algorithms purely from examples. These tasks have the nice property that it’s easy to vary the difficulty by varying the sequence length.\n", + "\n", + "- [Atari](https://gym.openai.com/envs#atari): play classic Atari games. \n", + "\n", + "- [2D and 3D robots](https://gym.openai.com/envs#mujoco): control a robot in simulation. These tasks use the MuJoCo physics engine, which was designed for fast and accurate robot simulation. \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Don't forget to set matplotlib to inline" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "NEnwOnr6qHbO" + }, + "source": [ + "# CartPole-v1 exemple" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Fj9G5c5kqM_y" + }, + "source": [ + "## Initialize environment" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "colab_type": "code", + "id": "5Q7p1iRwdGpE", + "outputId": "fa6bfbf8-a868-402e-a1d7-344ba712b002" + }, + "outputs": [], + "source": [ + "import gym\n", + "env = gym.make('CartPole-v1')\n", + "_ = env.reset()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "observation_space= Box(4,) action_space= Discrete(2)\n" + ] + } + ], + "source": [ + "print(\"observation_space=\",env.observation_space, \"action_space=\",env.action_space)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "mxUtaISFqQ4Q" + }, + "source": [ + "## Initialize agent" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "srJt2AZPp58A" + }, + "outputs": [], + "source": [ + "from blobrl.agents import DQN\n", + "agent = DQN(observation_space=env.observation_space, action_space=env.action_space)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "EX_NctEhqfgu" + }, + "source": [ + "## Train" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "fldGbNR2qlDo" + }, + "source": [ + "Create Trainer" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 54 + }, + "colab_type": "code", + "id": "CY1LF52LqeyH", + "outputId": "96567768-4a32-4e02-8fc8-c3f7e17897ab" + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "D:\\Users\\nathan\\Anaconda3\\envs\\RL\\lib\\site-packages\\blobrl\\trainer.py:28: UserWarning: be sure of your agent need to have good input and output dimension\n", + " warnings.warn(\"be sure of your agent need to have good input and output dimension\")\n" + ] + } + ], + "source": [ + "from blobrl import Trainer\n", + "trainer = Trainer(environment=env, agent=agent, log_dir=\"./logs\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "cGq2ksiRqkRR" + }, + "source": [ + "Start train" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "0BACJeOjqkXO" + }, + "outputs": [], + "source": [ + "trainer.train(max_episode=200, nb_evaluation=0, render=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "trainer.evaluate()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "env.close()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# MountainCar-v0 exemple" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "import gym\n", + "env = gym.make('MountainCar-v0')\n", + "_ = env.reset()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "observation_space= Box(2,) action_space= Discrete(3)\n" + ] + } + ], + "source": [ + "print(\"observation_space=\",env.observation_space, \"action_space=\",env.action_space)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Initialize agent" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "from blobrl.agents import DQN\n", + "agent = DQN(observation_space=env.observation_space, action_space=env.action_space)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Train" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create Trainer" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "from blobrl import Trainer\n", + "trainer = Trainer(environment=env, agent=agent, log_dir=\"./logs\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Start train" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "trainer.train(max_episode=200, nb_evaluation=0, render=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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bWtxMuACnjeH53wOh0MtW7Y0x8eOHdNPP/1kYSIAwDmHDx82y44kderUibIDr+MRhcfPz0/z5s0zNxjdvn27evfurdWrV1ucDAB8W1pamj766CNzfMsttyg2NtbCRMD18YjCI2XP9B87dqx5f/iXX35R//79zW0oAAB5KzMzUy+88IKGDRsmSapQoYJGjx6d44o84C08pvBIUnh4uHr06GGON27cyK0tALCAYRh6/PHH9fbbb0uSSpUqpXHjxql58+YWJwOuj0cVHkmKiYnRyJEjzfH06dO1fPlyCxMBgG/68MMPzX8XKFBATZs2tTANcGM8rvCEh4erd+/eGjFihKTsvVkef/xxrV+/3uJkAOA7ateubS4uWKRIEc2aNcviRMCN8YjH0i8mKSlJI0eOVFxcnKTsNR+WL1+uypUrWxUJAHzCnXfeqV9//VWGYSg8PFzbt29XyZIlrY4FXI1LPpbun5cprkW+fPlUoEABc3zkyBGlp6dbmAgA7K969epm2fH399c///yjm266yepYwA3zuFta5+vbt68GDBhgju+++279888/usJVKQDAdTAMQ6dOnTJ/xjocDsoObMNjb2mZAQxDPXr00IcffqisrCxJ2Vd7ChUqxGZ1AOAm6enpqlevnvlkbFBQkJKTk+V0evTfxcC/XbIYeHzhOadJkyZaunSpOU5PT8+xHQUA4Pq1atVKCxYsMMfJyckKCQmxMBFwXTx7a4mrUbRoUQUGBprjPXv2cGsLANzg2LFjSkpKMscxMTFcQYfteE3h+fDDD9W+fXuz9FSqVEkbN260OBUAeLcDBw7oySef1LJlyyRJVatW1S+//KLg4GCLkwHu5TWFR5I+/vhjde7cWf7+/jIMQ3Xq1NHixYutjgUAXik+Pl4DBw7Ul19+KUmqU6eOvv32W0VGRlobDMgFXjOH53wRERE6ffq0JKlw4cI6cuSIxYkAwPtMnjxZPXv2NMfr1q1jY1B4O++fw3O+559/3nxyICkpSePHj7c4EQB4lz///FNff/21OW7fvr1KlChhYSIgd3nlFR4p518mERERevHFFzVo0CCLUwGA59uzZ4969+6tJUuWSJI6deqkuLg4xcTEWBsMuHHe/1j6vxmGofnz5+vhhx+WlL2x3cCBAzV48GCLkwGA5zp06JA6dOigVatWScq+svPGG29QdmAX9rqlJWWv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KDQ0VPv27bMooecbM2aMXnvtNUnS6dOn5XK5zHP+/v46fPiwnE6nIiMjrYoIADeCwgP7cLlc6tSpkz755JOLng8MDNQtt9yiX3/9VZKua8Vhuzj3/b148WK1atVKmZmZF923LCEhQaGhode84SgAeBgKD+zl3P/fVq9eXdu2bVN6evpFX/fQQw9p9uzZkrKvYPjChpaGYZj/+/j7779VqVKli77O399fTqdT8fHxio6O9uliCMA2KDywt1KlSuns2bMyDEMnT5686GvGjRunjh07Kn/+/PL3t+cSVImJicrKylJUVNRFzwcHByskJESStGjRIsXGxuZlPADIbRQe+Ibk5GRVrlxZGRkZOnDgwEVfs2DBAlWpUkWSFBMT4/VXNg4fPmyuTn3nnXdetPCFhIQoOjpaffr0uWDiNwDYCIUHvuXvv/9W+/btlZiYqN27d1/ydWvXrjX3nwoKClLVqlXzKuJ1S0xM1K5du8xx//79tWbNmou+NjAwUFWrVlXt2rX1zjvv5FFCALAMhQe+ac2aNXr99dclSb/99pv2799/ydcWKVJEU6dONccVKlTQzTffnOsZryQzMzPHisk//vijRowYcdmvadasmaTs/6Zp06blaj4A8CAUHmD69Olau3atFixYoBMnTlzx9S1atFDLli1zHOvUqVOub5j55Zdf5siXnp6u3r17X9XXdurUSUFBQZo6darX36oDgOtA4QHOmTBhgjm/54033rhgheHLefHFF5UvX75Lno+NjVWDBg0u+x5nzpzRuHHjLnl+/PjxOnTo0FVnateunbna9Msvv6zQ0NCr/loAsBkKD3Ax7733nrkuzfHjxzV8+PAber877rjjik8+JSUl6cMPP7zuz6hWrZqeeOIJc/zAAw8oJibmut8PAGyEwgNcydmzZ3PMlZk/f/4lFzfMS4GBgZo1a5Y5LlasmGrVqmVhIgDwWBQe4Fr9888/io+Pz3GsRYsWOnXqVK5+7rRp01ShQgVz7HQ6Vbt27Vz9TACwCQoP4A67du3Ksf/Uv02dOlVjxoy57HsUKlRIq1atuuT5mJiYXJ8YDQA2ReEB8kJSUpLOnj172dc4nU4VKlQojxIBgE+h8AAAANu7ZOFx5mUKAAAAK1B4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7VF4AACA7flf4bwjT1IAAADkIq7wAAAA26PwAAAA26PwAAAA26PwAAAA26PwAAAA26PwAAAA2/t/Uq7k7scEE/gAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "trainer.evaluate()" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "env.close()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Copy-v0 exemple" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "import gym\n", + "env = gym.make('Copy-v0')\n", + "_ = env.reset()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "observation_space= Discrete(6) action_space= Tuple(Discrete(2), Discrete(2), Discrete(5))\n" + ] + } + ], + "source": [ + "print(\"observation_space=\",env.observation_space, \"action_space=\",env.action_space)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Initialize agent" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from blobrl.agents import DQN\n", + "agent = DQN(observation_space=env.observation_space, action_space=env.action_space)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Train" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create Trainer" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "from blobrl import Trainer\n", + "trainer = Trainer(environment=env, agent=agent, log_dir=\"./logs\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Start train" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "trainer.train(max_episode=200, nb_evaluation=0, render=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "trainer.evaluate()\n", + "env.close()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# FrozenLake-v0 example" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "import gym\n", + "env = gym.make('FrozenLake-v0')\n", + "_ = env.reset()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "observation_space= Discrete(16) action_space= Discrete(4)\n" + ] + } + ], + "source": [ + "print(\"observation_space=\",env.observation_space, \"action_space=\",env.action_space)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Initialize agent" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "from blobrl.agents import DQN\n", + "agent = DQN(observation_space=env.observation_space, action_space=env.action_space)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Train" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create Trainer" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "D:\\Users\\nathan\\Anaconda3\\envs\\RL\\lib\\site-packages\\blobrl\\trainer.py:28: UserWarning: be sure of your agent need to have good input and output dimension\n", + " warnings.warn(\"be sure of your agent need to have good input and output dimension\")\n" + ] + } + ], + "source": [ + "from blobrl import Trainer\n", + "trainer = Trainer(environment=env, agent=agent, log_dir=\"./logs\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Start train" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "trainer.train(max_episode=1000, nb_evaluation=0, render=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " (Right)\n", + "SFFF\n", + "\u001b[41mF\u001b[0mHFH\n", + "FFFH\n", + "HFFG\n", + " (Right)\n", + "SFFF\n", + "\u001b[41mF\u001b[0mHFH\n", + "FFFH\n", + "HFFG\n" + ] + } + ], + "source": [ + "trainer.evaluate()\n", + "env.close()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Assault-v0 example" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "import gym\n", + "env = gym.make('Assault-v0')\n", + "_ = env.reset()" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "observation_space= Box(250, 160, 3) action_space= Discrete(7)\n" + ] + } + ], + "source": [ + "print(\"observation_space=\",env.observation_space, \"action_space=\",env.action_space)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Initialize agent" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "from blobrl.agents import DQN\n", + "agent = DQN(observation_space=env.observation_space, action_space=env.action_space)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Train" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create Trainer" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "from blobrl import Trainer\n", + "trainer = Trainer(environment=env, agent=agent, log_dir=\"./logs\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Start train" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "trainer.train(max_episode=200, nb_evaluation=0, render=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAWoAAAIuCAYAAACW+UIEAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy86wFpkAAAACXBIWXMAAAsTAAALEwEAmpwYAAAtMElEQVR4nO3deZCk6UHf+d/zHplv3nVX9VVdfU1P99waRkJCSAJpQFzCgiC4vAJjB2HwGkeYdaxjHQ577b8cYQOGIHaxDTbGWhtjYWDXgBAIja7Bo2Ome47unpk+pq+q6rqy8j7eY//Imqyq7s7SqKeq6+np7ydiIqYy3/fNNys6vv30814mSRIBAOzl7PYOAAC2RqgBwHKEGgAsR6gBwHKEGgAsR6gBwHLeVm8aYzh3DwDugiRJzKD3GFEDgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOUINQBYjlADgOW83d4B2CHreTpaKinwBv+RWGg2dalSUTLgfSPpYKGgiWx24DZaUaTz5bLqYThwmeF0WoeKRXnO7ccRiaSrtZpm6/WB2/AcR0dKJZVSqYHLVDodnV9dVTeOBy4zlc3qQKEgM+D9KEl0YXVVK+32wG1sx+8W9zdCDUnS3lxO/+DJJ3Ugnx+4zB+/8YZ+5fnn1RkQNtdx9MNHj+oHDh0auI3r9br+z+ee07mVlYHLPDQ6qn/45JPK+/5t308k/buXX9Ynz50buI2C7+tnH35YT46PD1zm1OKi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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "trainer.evaluate()\n", + "env.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [], + "name": "Copie de Gym_Envs_1_preamble_evn_list.ipynb", + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/results/Analyse_result.ipynb b/results/Analyse_result.ipynb index 53b6994..a34f3d6 100644 --- a/results/Analyse_result.ipynb +++ b/results/Analyse_result.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -17,7 +17,7 @@ "import pandas as pd\n", "from pandas.core.common import flatten\n", "import seaborn as sns\n", - "import matplotlib.pyplot as plt\n" + "import matplotlib.pyplot as plt" ] }, { @@ -75,6 +75,15 @@ " df = pd.concat([df,ite], ignore_index=True)" ] }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "df.drop(columns=[\"max\",\"min\",\"avg\"], inplace=True)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -84,7 +93,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -120,9 +129,6 @@ " memories\n", " max_size\n", " step\n", - " max\n", - " min\n", - " avg\n", " sum\n", " \n", " \n", @@ -131,191 +137,161 @@ " 0\n", " CategoricalDQN\n", " 1\n", - " 1\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", + " 32\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", " C51Network\n", " \n", " Adam\n", " 0.0001\n", " ExperienceReplay\n", - " 128\n", + " 2048\n", " 1\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", " 9.0\n", " \n", " \n", " 1\n", " CategoricalDQN\n", " 1\n", - " 1\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", + " 32\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", " C51Network\n", " \n", " Adam\n", " 0.0001\n", " ExperienceReplay\n", - " 128\n", - " 166\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 10\n", " 10.0\n", " \n", " \n", " 2\n", " CategoricalDQN\n", " 1\n", - " 1\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", + " 32\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", " C51Network\n", " \n", " Adam\n", " 0.0001\n", " ExperienceReplay\n", - " 128\n", - " 332\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 9.0\n", + " 2048\n", + " 20\n", + " 10.0\n", " \n", " \n", " 3\n", " CategoricalDQN\n", " 1\n", - " 1\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", + " 32\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", " C51Network\n", " \n", " Adam\n", " 0.0001\n", " ExperienceReplay\n", - " 128\n", - " 498\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 11.0\n", + " 2048\n", + " 30\n", + " 9.0\n", " \n", " \n", " 4\n", " CategoricalDQN\n", " 1\n", - " 1\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", + " 32\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", " C51Network\n", " \n", " Adam\n", " 0.0001\n", " ExperienceReplay\n", - " 128\n", - " 500\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 40\n", " 9.0\n", " \n", " \n", " 5\n", " CategoricalDQN\n", " 1\n", - " 1\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", + " 32\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", " C51Network\n", " \n", " Adam\n", " 0.0001\n", " ExperienceReplay\n", - " 16\n", - " 1\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 14.0\n", + " 2048\n", + " 50\n", + " 8.0\n", " \n", " \n", " 6\n", " CategoricalDQN\n", " 1\n", - " 1\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", + " 32\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", " C51Network\n", " \n", " Adam\n", " 0.0001\n", " ExperienceReplay\n", - " 16\n", - " 166\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 8.0\n", + " 2048\n", + " 60\n", + " 9.0\n", " \n", " \n", " 7\n", " CategoricalDQN\n", " 1\n", - " 1\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", + " 32\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", " C51Network\n", " \n", " Adam\n", " 0.0001\n", " ExperienceReplay\n", - " 16\n", - " 332\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 9.0\n", + " 2048\n", + " 70\n", + " 10.0\n", " \n", " \n", " 8\n", " CategoricalDQN\n", " 1\n", - " 1\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", + " 32\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", " C51Network\n", " \n", " Adam\n", " 0.0001\n", " ExperienceReplay\n", - " 16\n", - " 498\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 80\n", " 10.0\n", " \n", " \n", " 9\n", " CategoricalDQN\n", " 1\n", - " 1\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", + " 32\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", " C51Network\n", " \n", " Adam\n", " 0.0001\n", " ExperienceReplay\n", - " 16\n", - " 500\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 10.0\n", + " 2048\n", + " 90\n", + " 9.0\n", " \n", " \n", "\n", @@ -323,43 +299,43 @@ ], "text/plain": [ " algo step_train batch_size gamma \\\n", - "0 CategoricalDQN 1 1 0.99 \n", - "1 CategoricalDQN 1 1 0.99 \n", - "2 CategoricalDQN 1 1 0.99 \n", - "3 CategoricalDQN 1 1 0.99 \n", - "4 CategoricalDQN 1 1 0.99 \n", - "5 CategoricalDQN 1 1 0.99 \n", - "6 CategoricalDQN 1 1 0.99 \n", - "7 CategoricalDQN 1 1 0.99 \n", - "8 CategoricalDQN 1 1 0.99 \n", - "9 CategoricalDQN 1 1 0.99 \n", + "0 CategoricalDQN 1 32 0.95 \n", + "1 CategoricalDQN 1 32 0.95 \n", + "2 CategoricalDQN 1 32 0.95 \n", + "3 CategoricalDQN 1 32 0.95 \n", + "4 CategoricalDQN 1 32 0.95 \n", + "5 CategoricalDQN 1 32 0.95 \n", + "6 CategoricalDQN 1 32 0.95 \n", + "7 CategoricalDQN 1 32 0.95 \n", + "8 CategoricalDQN 1 32 0.95 \n", + "9 CategoricalDQN 1 32 0.95 \n", "\n", " greedy_exploration network optimizer lr \\\n", - "0 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 C51Network Adam 0.0001 \n", - "1 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 C51Network Adam 0.0001 \n", - "2 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 C51Network Adam 0.0001 \n", - "3 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 C51Network Adam 0.0001 \n", - "4 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 C51Network Adam 0.0001 \n", - "5 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 C51Network Adam 0.0001 \n", - "6 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 C51Network Adam 0.0001 \n", - "7 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 C51Network Adam 0.0001 \n", - "8 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 C51Network Adam 0.0001 \n", - "9 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 C51Network Adam 0.0001 \n", + "0 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 C51Network Adam 0.0001 \n", + "1 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 C51Network Adam 0.0001 \n", + "2 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 C51Network Adam 0.0001 \n", + "3 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 C51Network Adam 0.0001 \n", + "4 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 C51Network Adam 0.0001 \n", + "5 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 C51Network Adam 0.0001 \n", + "6 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 C51Network Adam 0.0001 \n", + "7 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 C51Network Adam 0.0001 \n", + "8 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 C51Network Adam 0.0001 \n", + "9 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 C51Network Adam 0.0001 \n", "\n", - " memories max_size step max min avg sum \n", - "0 ExperienceReplay 128 1 1.0 1.0 1.0 9.0 \n", - "1 ExperienceReplay 128 166 1.0 1.0 1.0 10.0 \n", - "2 ExperienceReplay 128 332 1.0 1.0 1.0 9.0 \n", - "3 ExperienceReplay 128 498 1.0 1.0 1.0 11.0 \n", - "4 ExperienceReplay 128 500 1.0 1.0 1.0 9.0 \n", - "5 ExperienceReplay 16 1 1.0 1.0 1.0 14.0 \n", - "6 ExperienceReplay 16 166 1.0 1.0 1.0 8.0 \n", - "7 ExperienceReplay 16 332 1.0 1.0 1.0 9.0 \n", - "8 ExperienceReplay 16 498 1.0 1.0 1.0 10.0 \n", - "9 ExperienceReplay 16 500 1.0 1.0 1.0 10.0 " + " memories max_size step sum \n", + "0 ExperienceReplay 2048 1 9.0 \n", + "1 ExperienceReplay 2048 10 10.0 \n", + "2 ExperienceReplay 2048 20 10.0 \n", + "3 ExperienceReplay 2048 30 9.0 \n", + "4 ExperienceReplay 2048 40 9.0 \n", + "5 ExperienceReplay 2048 50 8.0 \n", + "6 ExperienceReplay 2048 60 9.0 \n", + "7 ExperienceReplay 2048 70 10.0 \n", + "8 ExperienceReplay 2048 80 10.0 \n", + "9 ExperienceReplay 2048 90 9.0 " ] }, - "execution_count": 7, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -377,11 +353,11 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ - "for c in [\"step_train\", \"batch_size\", \"gamma\", \"lr\", \"step\", \"max\", \"min\", \"avg\", \"sum\"]:\n", + "for c in [\"step_train\", \"batch_size\", \"gamma\", \"lr\", \"step\", \"sum\"]:\n", " df[c] = df[c].astype(float)\n", "for c in df.columns:\n", " if df[c].dtypes == \"object\":\n", @@ -390,7 +366,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -426,604 +402,696 @@ " memories\n", " max_size\n", " step\n", - " max\n", - " min\n", - " avg\n", " sum\n", " \n", " \n", " \n", " \n", - " 3436\n", - " DQN\n", - " 1.0\n", - " 32.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", - " SimpleNetwork\n", - " \n", - " Adam\n", - " 0.0010\n", - " ExperienceReplay\n", - " 128\n", - " 166.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 500.0\n", - " \n", - " \n", - " 3711\n", - " DQN\n", - " 1.0\n", - " 64.0\n", - " 0.99\n", - " EpsilonGreedy-0.1\n", - " SimpleNetwork\n", - " \n", - " Adam\n", - " 0.0010\n", - " ExperienceReplay\n", - " 16\n", - " 166.0\n", - " 1.0\n", - " 1.0\n", + " 12340\n", + " DoubleDQN\n", " 1.0\n", - " 500.0\n", - " \n", - " \n", - " 4176\n", - " DQN\n", " 32.0\n", - " 64.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", - " SimpleNetwork\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.1000\n", + " 0.001\n", " ExperienceReplay\n", - " 16\n", - " 166.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 20.0\n", " 500.0\n", " \n", " \n", - " 2117\n", + " 12930\n", " DoubleDQN\n", " 1.0\n", - " 64.0\n", - " 0.99\n", - " EpsilonGreedy-0.6\n", - " SimpleNetwork\n", - " \n", - " Adam\n", - " 0.0001\n", - " ExperienceReplay\n", - " 128\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 500.0\n", - " \n", - " \n", - " 3442\n", - " DQN\n", - " 1.0\n", " 32.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", + " 1.00\n", + " EpsilonGreedy-0.1\n", " SimpleNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 16\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 512\n", + " 30.0\n", " 500.0\n", " \n", " \n", - " 3537\n", + " 31127\n", " DQN\n", " 1.0\n", " 32.0\n", - " 0.99\n", - " EpsilonGreedy-0.1\n", + " 1.00\n", + " EpsilonGreedy-0.6\n", " SimpleNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 32\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 30.0\n", " 500.0\n", " \n", " \n", - " 3612\n", + " 31716\n", " DQN\n", " 1.0\n", " 64.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", - " SimpleNetwork\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0001\n", + " 0.001\n", " ExperienceReplay\n", - " 32\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 512\n", + " 30.0\n", " 500.0\n", " \n", " \n", - " 3717\n", + " 34103\n", " DQN\n", " 1.0\n", " 64.0\n", " 0.99\n", - " EpsilonGreedy-0.1\n", - " SimpleNetwork\n", - " \n", - " Adam\n", - " 0.0010\n", - " ExperienceReplay\n", - " 32\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 500.0\n", - " \n", - " \n", - " 4797\n", - " DQN\n", - " 4.0\n", - " 64.0\n", - " 0.99\n", - " EpsilonGreedy-0.1\n", + " EpsilonGreedy-0.6\n", " SimpleNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 32\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 30.0\n", " 500.0\n", " \n", " \n", - " 1953\n", + " 11412\n", " DoubleDQN\n", " 1.0\n", " 32.0\n", " 0.99\n", - " EpsilonGreedy-0.6\n", + " EpsilonGreedy-0.1\n", " SimpleNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 128\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 40.0\n", " 500.0\n", " \n", " \n", - " 2118\n", + " 24122\n", " DoubleDQN\n", - " 1.0\n", + " 32.0\n", " 64.0\n", " 0.99\n", - " EpsilonGreedy-0.6\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", " SimpleNetwork\n", " \n", " Adam\n", - " 0.0001\n", + " 0.100\n", " ExperienceReplay\n", - " 128\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 40.0\n", " 500.0\n", " \n", " \n", - " 3268\n", + " 27997\n", " DQN\n", " 1.0\n", - " 1.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", - " SimpleNetwork\n", + " 32.0\n", + " 0.95\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 32\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 512\n", + " 40.0\n", " 500.0\n", " \n", " \n", - " 3538\n", + " 29082\n", " DQN\n", " 1.0\n", " 32.0\n", " 0.99\n", " EpsilonGreedy-0.1\n", - " SimpleNetwork\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 32\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 40.0\n", " 500.0\n", " \n", " \n", - " 3573\n", + " 30601\n", " DQN\n", " 1.0\n", " 32.0\n", - " 0.99\n", - " EpsilonGreedy-0.6\n", - " SimpleNetwork\n", - " \n", - " Adam\n", - " 0.0010\n", - " ExperienceReplay\n", - " 128\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 500.0\n", - " \n", - " \n", - " 3718\n", - " DQN\n", - " 1.0\n", - " 64.0\n", - " 0.99\n", + " 1.00\n", " EpsilonGreedy-0.1\n", - " SimpleNetwork\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 32\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 512\n", + " 40.0\n", " 500.0\n", " \n", - " \n", - " 3753\n", - " DQN\n", - " 1.0\n", - " 64.0\n", - " 0.99\n", - " EpsilonGreedy-0.6\n", - " SimpleNetwork\n", - " \n", - " Adam\n", - " 0.0010\n", - " ExperienceReplay\n", - " 128\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 500.0\n", + " \n", + "\n", + "" + ], + "text/plain": [ + " algo step_train batch_size gamma \\\n", + "12340 DoubleDQN 1.0 32.0 1.00 \n", + "12930 DoubleDQN 1.0 32.0 1.00 \n", + "31127 DQN 1.0 32.0 1.00 \n", + "31716 DQN 1.0 64.0 0.95 \n", + "34103 DQN 1.0 64.0 0.99 \n", + "11412 DoubleDQN 1.0 32.0 0.99 \n", + "24122 DoubleDQN 32.0 64.0 0.99 \n", + "27997 DQN 1.0 32.0 0.95 \n", + "29082 DQN 1.0 32.0 0.99 \n", + "30601 DQN 1.0 32.0 1.00 \n", + "\n", + " greedy_exploration network \\\n", + "12340 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork \n", + "12930 EpsilonGreedy-0.1 SimpleNetwork \n", + "31127 EpsilonGreedy-0.6 SimpleNetwork \n", + "31716 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork \n", + "34103 EpsilonGreedy-0.6 SimpleNetwork \n", + "11412 EpsilonGreedy-0.1 SimpleNetwork \n", + "24122 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork \n", + "27997 EpsilonGreedy-0.6 SimpleDuelingNetwork \n", + "29082 EpsilonGreedy-0.1 SimpleDuelingNetwork \n", + "30601 EpsilonGreedy-0.1 SimpleDuelingNetwork \n", + "\n", + " optimizer lr memories max_size step sum \n", + "12340 Adam 0.001 ExperienceReplay 2048 20.0 500.0 \n", + "12930 Adam 0.001 ExperienceReplay 512 30.0 500.0 \n", + "31127 Adam 0.001 ExperienceReplay 2048 30.0 500.0 \n", + "31716 Adam 0.001 ExperienceReplay 512 30.0 500.0 \n", + "34103 Adam 0.001 ExperienceReplay 2048 30.0 500.0 \n", + "11412 Adam 0.001 ExperienceReplay 2048 40.0 500.0 \n", + "24122 Adam 0.100 ExperienceReplay 2048 40.0 500.0 \n", + "27997 Adam 0.001 ExperienceReplay 512 40.0 500.0 \n", + "29082 Adam 0.001 ExperienceReplay 2048 40.0 500.0 \n", + "30601 Adam 0.001 ExperienceReplay 512 40.0 500.0 " + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.sort_values(by =[\"sum\",\"step\"], ascending = [False, True]).head(10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Correlation matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "df_corr = df.copy()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "for c in df_corr.columns:\n", + " try:\n", + " df_corr[c] = df_corr[c].cat.codes\n", + " except:\n", + " pass" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "algo 0.061506\n", + "step_train -0.314323\n", + "batch_size 0.044669\n", + "gamma -0.005792\n", + "greedy_exploration 0.017274\n", + "network 0.076661\n", + " NaN\n", + "optimizer NaN\n", + "lr -0.166335\n", + "memories NaN\n", + "max_size -0.018768\n", + "step 0.161043\n", + "sum 1.000000\n", + "Name: sum, dtype: float64" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_corr.corr()[\"sum\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(figsize=(10,10)) \n", + "sns.heatmap(df.corr()[abs(df.corr()) > 0.05], annot = True, fmt='.2g',cmap= 'coolwarm', ax=ax)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Correlation matrix for best result" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "df_corr_best = df_corr[df_corr[\"sum\"] >= 300]" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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nN9Pv+Fn0bZDHxbPfAWAAaPOo6x4G289fDZVFSWYeVg47QXOvW4SZcXb+OLVm3B+H845eg06me4Ddr+7fO6Scg45MIGH/9iZqurA5WN2uOmybJ56Lbif/6CAq/+vHeedks7qDVV8PiswDH3koEROPDwFX3A//+BLgatErFhXxVcLyrjv2k74fI41G6r4dGZxyBiiSTScNWyhxoBEk+DJIh845w4O3r8eSAaeJ5CUdQRigVecc3ea2RHA0wSqiGc751aa2Trgr865CWZ2M3BecEzgjuU/C2TR9GSRD5xzbwTb3U7w8jFmdhJwL3CCc65uK6/nZ9evbRVvXM9+7cMdQq17L28T7hAAuPvVfXtdveaa/smScIdQ67fPnxXuEGqNq14a7hBalYUrtoQ7hFoDe4d/f/LPd1vFrhWAr6auDXcItV67v0e4Q9ihRftq8xd82WIfiLaDjgpLP3TUVwSdc2uAg+vdr38dv5NDtJ9Oo8vHOOe61fv/bgJjBesvv0nfgXPu4kb3b6/3/0fAR81dBxEREdkHNEZQRERERCJV1FcERUREREKJhjGCkb+GIiIiIhKSKoIiIiIiIbiWPTclLFQRFBEREYlSSgRFREREopS6hkVERERC0MkiIiIiIhKxVBEUERERCUUXlBYRERGRSKWKoIiIiEgILgrqZZG/hiIiIiISkiqCIiIiIiE4jREUERERkUiliqCIiIhICLqOoIiIiIhELHPOhTsG2TN640REJNq06KC9Td/Pa7Fjbcf+Q8IyIFEVQREREZEopTGCIiIiIiFojKCIiIiIRCxVBEVERERC0HUERURERCRiKREUERERiVLqGhYREREJwbXs1WrCQhVBERERkSiliqCIiIhICLp8jIiIiIhELFUERURERELQGEERERERiViqCIqIiIiEoDGCIiIiIhKxVBEUERERCUFjBEVEREQkYqkiKCIiIhKCxgiKiIiISMRSRVBEREQkBI0RFBEREZGIpURwP2Jm481sjpnNmTBhQrjDERERiWjOrMVu4aKu4f2Ic24CsCMDdOGMRURERPZ/SgRFREREQnBOYwRFREREJEIpERQRERGJUkoERUREREJweFrstitmdrKZLTWzFWZ20w+0G25mPjM7uznrqERQREREpBUzMy/wGHAKMAA438wG7KTdfcBHzV22EkERERGREBzWYrddGAGs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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(figsize=(10,10)) \n", + "sns.heatmap(df_corr_best.corr()[abs(df_corr_best.corr()) > 0.05], annot = True, fmt='.2g',cmap= 'coolwarm', ax=ax)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Result by algo" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### DQN" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### SimpleNetwork" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "df_DQN = df[df[\"algo\"] == \"DQN\"].copy()\n", + "df_DQN = df_DQN[df_DQN[\"network\"] == \"SimpleNetwork\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", + " \n", + " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", + " \n", " \n", + " \n", + " \n", + " \n", + " \n", " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", @@ -1032,1517 +1100,714 @@ " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", + " \n", " \n", + " \n", + " \n", + " \n", + " \n", " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", + " \n", " \n", + " \n", + " \n", + " \n", + " \n", " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", + " \n", " \n", + " \n", + " \n", + " \n", + " \n", " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", + " \n", + " \n", " \n", + " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", + " \n", " \n", " \n", " \n", - " \n", - " \n", + " \n", + " \n", " \n", " \n", " \n", - " \n", + " \n", " \n", - " \n", + " \n", + " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
algostep_trainbatch_sizegammagreedy_explorationnetworkoptimizerlrmemoriesmax_sizestepsum
452331127DQN4.01.032.00.99AdaptativeEpsilonGreedy-0.3-0.1-50000-01.00EpsilonGreedy-0.6SimpleNetworkAdam0.00100.001ExperienceReplay16498.01.01.01.0204830.0500.0
466834103DQN4.032.01.064.00.99EpsilonGreedy-0.6SimpleNetworkAdam0.10000.001ExperienceReplay128498.01.01.01.0204830.0500.0
470333050DQN4.01.064.00.99AdaptativeEpsilonGreedy-0.3-0.1-50000-0AdaptativeEpsilonGreedy-0.3-0.1-30000-0SimpleNetworkAdam0.00100.100ExperienceReplay16498.01.01.01.0204840.0500.0
475332648DQN4.01.064.00.99AdaptativeEpsilonGreedy-0.8-0.2-50000-00.95EpsilonGreedy-0.6SimpleNetworkAdam0.00100.001ExperienceReplay32498.01.01.01.051250.0500.0
479334508DQN4.01.064.00.99EpsilonGreedy-0.11.00AdaptativeEpsilonGreedy-0.3-0.1-30000-0SimpleNetworkAdam0.00100.001ExperienceReplay16498.01.01.01.051250.0500.0
479828898DQN4.064.01.032.00.99EpsilonGreedy-0.1AdaptativeEpsilonGreedy-0.8-0.2-10000-0SimpleNetworkAdam0.00100.001ExperienceReplay32498.01.01.01.0204860.0500.0
6173DuelingDQN4.032.033052DQN1.064.00.99AdaptativeEpsilonGreedy-0.8-0.2-50000-0SimpleDuelingNetworkAdaptativeEpsilonGreedy-0.3-0.1-30000-0SimpleNetworkAdam0.00010.100ExperienceReplay16498.01.01.01.0204860.0500.0
6448DuelingDQN4.034943DQN1.064.00.99EpsilonGreedy-0.6SimpleDuelingNetwork1.00AdaptativeEpsilonGreedy-0.8-0.2-10000-0SimpleNetworkAdam0.00010.100ExperienceReplay32498.01.01.01.051260.0500.0
326435687DQN1.01.00.99AdaptativeEpsilonGreedy-0.3-0.1-50000-064.01.00EpsilonGreedy-0.6SimpleNetworkAdam0.00100.100ExperienceReplay16500.01.01.01.051260.0500.0
339931906DQN1.01.00.99EpsilonGreedy-0.664.00.95AdaptativeEpsilonGreedy-0.8-0.2-10000-0SimpleNetworkAdam0.00100.001ExperienceReplay16500.01.01.01.051270.0500.0
342932991DQN1.032.064.00.99AdaptativeEpsilonGreedy-0.3-0.1-50000-0AdaptativeEpsilonGreedy-0.3-0.1-30000-0SimpleNetworkAdam0.00010.001ExperienceReplay16204870.0500.0
34479DQN1.01.01.064.01.00AdaptativeEpsilonGreedy-0.3-0.1-30000-0SimpleNetworkAdam0.001ExperienceReplay204870.0500.0
353928559DQN1.032.00.99EpsilonGreedy-0.1AdaptativeEpsilonGreedy-0.3-0.1-30000-0SimpleNetworkAdam0.00100.001ExperienceReplay32500.01.01.01.051280.0500.0
357428993DQN1.032.00.99EpsilonGreedy-0.6AdaptativeEpsilonGreedy-0.8-0.2-10000-0SimpleNetworkAdam0.00100.100ExperienceReplay128500.01.01.01.051280.0500.0
362431163DQN1.064.00.99AdaptativeEpsilonGreedy-0.3-0.1-50000-032.01.00EpsilonGreedy-0.6SimpleNetworkAdam0.00100.001ExperienceReplay16500.01.01.01.051280.0500.0
366931225DQN1.064.00.99AdaptativeEpsilonGreedy-0.8-0.2-50000-032.01.00EpsilonGreedy-0.6SimpleNetworkAdam0.00100.100ExperienceReplay16500.01.01.01.051280.0500.0
371933798DQN1.064.0SimpleNetworkAdam0.00100.100ExperienceReplay32500.01.01.01.0204880.0500.0
375435255DQN1.064.00.99EpsilonGreedy-0.61.00EpsilonGreedy-0.1SimpleNetworkAdam0.00100.001ExperienceReplay128500.01.01.01.051280.0500.0
452427072DQN4.01.032.00.99AdaptativeEpsilonGreedy-0.3-0.1-50000-00.95AdaptativeEpsilonGreedy-0.3-0.1-30000-0SimpleNetworkAdam0.00100.001ExperienceReplay16500.01.01.01.051290.0500.0
461927785DQN4.01.032.00.990.95EpsilonGreedy-0.1SimpleNetworkAdam0.00100.001ExperienceReplay32500.01.01.01.0204890.0500.0
465928188DQN4.01.032.00.990.95EpsilonGreedy-0.6SimpleNetworkAdam0.00100.001ExperienceReplay16500.01.01.01.051290.0500.0
466931164DQN4.01.032.00.991.00EpsilonGreedy-0.6SimpleNetworkAdam0.10000.001ExperienceReplay12851290.0500.0
32714DQN1.01.01.064.00.95EpsilonGreedy-0.6SimpleNetworkAdam0.100ExperienceReplay51290.0500.0
470432993DQN4.01.064.00.99AdaptativeEpsilonGreedy-0.3-0.1-50000-0AdaptativeEpsilonGreedy-0.3-0.1-30000-0SimpleNetworkAdam0.00100.001ExperienceReplay16500.01.01.01.0204890.0500.0
479433055DQN4.01.064.00.99EpsilonGreedy-0.1AdaptativeEpsilonGreedy-0.3-0.1-30000-0SimpleNetworkAdam0.00100.100ExperienceReplay16500.01.01.01.0204890.0500.0
479933768DQN4.01.064.00.99EpsilonGreedy-0.1SimpleNetworkAdam0.00100.001ExperienceReplay3251290.0500.0
28561DQN1.032.00.99AdaptativeEpsilonGreedy-0.3-0.1-30000-0SimpleNetworkAdam0.001ExperienceReplay512100.0500.0
30390DQN1.032.01.00AdaptativeEpsilonGreedy-0.8-0.2-10000-0SimpleNetworkAdam0.001ExperienceReplay2048100.0500.0
31134DQN1.032.01.00EpsilonGreedy-0.6SimpleNetworkAdam0.001ExperienceReplay2048100.0500.0
484433025DQN4.01.064.00.99EpsilonGreedy-0.6AdaptativeEpsilonGreedy-0.3-0.1-30000-0SimpleNetworkAdam0.00100.001ExperienceReplay32512100.0500.0
33397DQN1.01.01.064.00.99AdaptativeEpsilonGreedy-0.8-0.2-10000-0SimpleNetworkAdam0.001ExperienceReplay512100.0500.0
375833428DQN1.064.00.99EpsilonGreedy-0.6AdaptativeEpsilonGreedy-0.8-0.2-10000-0SimpleNetworkAdam0.00100.100ExperienceReplay16498.01.01.01.0486.02048100.0500.0
456427074DQN4.01.032.00.99AdaptativeEpsilonGreedy-0.8-0.2-50000-00.95AdaptativeEpsilonGreedy-0.3-0.1-30000-0SimpleNetworkAdam0.00100.001ExperienceReplay128512110.0500.01.01.01.0485.0
348428562DQN1.032.00.99AdaptativeEpsilonGreedy-0.8-0.2-50000-0AdaptativeEpsilonGreedy-0.3-0.1-30000-0SimpleNetworkAdam0.00100.001ExperienceReplay128512110.0500.01.01.01.0483.0
361933026DQN1.064.00.99AdaptativeEpsilonGreedy-0.3-0.1-50000-0AdaptativeEpsilonGreedy-0.3-0.1-30000-0SimpleNetworkAdam0.00100.001ExperienceReplay128512110.0500.01.01.01.0467.0
361733367DQN1.064.00.99AdaptativeEpsilonGreedy-0.3-0.1-50000-0AdaptativeEpsilonGreedy-0.8-0.2-10000-0SimpleNetworkAdam0.00100.001ExperienceReplay128332.01.01.01.0465.02048110.0500.0
361834514DQN1.064.00.99AdaptativeEpsilonGreedy-0.3-0.1-50000-01.00AdaptativeEpsilonGreedy-0.3-0.1-30000-0SimpleNetworkAdam0.00100.001ExperienceReplay128498.01.01.0512110.0500.0
35599DQN1.0450.064.01.00EpsilonGreedy-0.6SimpleNetworkAdam0.001ExperienceReplay2048110.0500.0
5087DuelingDQN27075DQN1.032.00.99AdaptativeEpsilonGreedy-0.8-0.2-50000-0SimpleDuelingNetwork0.95AdaptativeEpsilonGreedy-0.3-0.1-30000-0SimpleNetworkAdam0.00010.001ExperienceReplay128332.01.01.01.0421.0512120.0500.0
567CategoricalDQN32.028563DQN1.032.00.99AdaptativeEpsilonGreedy-0.3-0.1-50000-0C51NetworkAdaptativeEpsilonGreedy-0.3-0.1-30000-0SimpleNetworkAdam0.00100.001ExperienceReplay32332.01.01.01.0405.0512120.0500.0
355930020DQN1.032.00.99EpsilonGreedy-0.61.00AdaptativeEpsilonGreedy-0.3-0.1-30000-0SimpleNetworkAdam0.00010.001ExperienceReplay1282048120.0500.01.01.01.0398.0
\n", - "
" - ], - "text/plain": [ - " algo step_train batch_size gamma \\\n", - "3436 DQN 1.0 32.0 0.99 \n", - "3711 DQN 1.0 64.0 0.99 \n", - "4176 DQN 32.0 64.0 0.99 \n", - "2117 DoubleDQN 1.0 64.0 0.99 \n", - "3442 DQN 1.0 32.0 0.99 \n", - "3537 DQN 1.0 32.0 0.99 \n", - "3612 DQN 1.0 64.0 0.99 \n", - "3717 DQN 1.0 64.0 0.99 \n", - "4797 DQN 4.0 64.0 0.99 \n", - "1953 DoubleDQN 1.0 32.0 0.99 \n", - "2118 DoubleDQN 1.0 64.0 0.99 \n", - "3268 DQN 1.0 1.0 0.99 \n", - "3538 DQN 1.0 32.0 0.99 \n", - "3573 DQN 1.0 32.0 0.99 \n", - "3718 DQN 1.0 64.0 0.99 \n", - "3753 DQN 1.0 64.0 0.99 \n", - "4523 DQN 4.0 32.0 0.99 \n", - "4668 DQN 4.0 32.0 0.99 \n", - "4703 DQN 4.0 64.0 0.99 \n", - "4753 DQN 4.0 64.0 0.99 \n", - "4793 DQN 4.0 64.0 0.99 \n", - "4798 DQN 4.0 64.0 0.99 \n", - "6173 DuelingDQN 4.0 32.0 0.99 \n", - "6448 DuelingDQN 4.0 64.0 0.99 \n", - "3264 DQN 1.0 1.0 0.99 \n", - "3399 DQN 1.0 1.0 0.99 \n", - "3429 DQN 1.0 32.0 0.99 \n", - "3539 DQN 1.0 32.0 0.99 \n", - "3574 DQN 1.0 32.0 0.99 \n", - "3624 DQN 1.0 64.0 0.99 \n", - "3669 DQN 1.0 64.0 0.99 \n", - "3719 DQN 1.0 64.0 0.99 \n", - "3754 DQN 1.0 64.0 0.99 \n", - "4524 DQN 4.0 32.0 0.99 \n", - "4619 DQN 4.0 32.0 0.99 \n", - "4659 DQN 4.0 32.0 0.99 \n", - "4669 DQN 4.0 32.0 0.99 \n", - "4704 DQN 4.0 64.0 0.99 \n", - "4794 DQN 4.0 64.0 0.99 \n", - "4799 DQN 4.0 64.0 0.99 \n", - "4844 DQN 4.0 64.0 0.99 \n", - "3758 DQN 1.0 64.0 0.99 \n", - "4564 DQN 4.0 32.0 0.99 \n", - "3484 DQN 1.0 32.0 0.99 \n", - "3619 DQN 1.0 64.0 0.99 \n", - "3617 DQN 1.0 64.0 0.99 \n", - "3618 DQN 1.0 64.0 0.99 \n", - "5087 DuelingDQN 1.0 32.0 0.99 \n", - "567 CategoricalDQN 32.0 1.0 0.99 \n", - "3559 DQN 1.0 32.0 0.99 \n", - "\n", - " greedy_exploration network \\\n", - "3436 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork \n", - "3711 EpsilonGreedy-0.1 SimpleNetwork \n", - "4176 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork \n", - "2117 EpsilonGreedy-0.6 SimpleNetwork \n", - "3442 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork \n", - "3537 EpsilonGreedy-0.1 SimpleNetwork \n", - "3612 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork \n", - "3717 EpsilonGreedy-0.1 SimpleNetwork \n", - "4797 EpsilonGreedy-0.1 SimpleNetwork \n", - "1953 EpsilonGreedy-0.6 SimpleNetwork \n", - "2118 EpsilonGreedy-0.6 SimpleNetwork \n", - "3268 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork \n", - "3538 EpsilonGreedy-0.1 SimpleNetwork \n", - "3573 EpsilonGreedy-0.6 SimpleNetwork \n", - "3718 EpsilonGreedy-0.1 SimpleNetwork \n", - "3753 EpsilonGreedy-0.6 SimpleNetwork \n", - "4523 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork \n", - "4668 EpsilonGreedy-0.6 SimpleNetwork \n", - "4703 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork \n", - "4753 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleNetwork \n", - "4793 EpsilonGreedy-0.1 SimpleNetwork \n", - "4798 EpsilonGreedy-0.1 SimpleNetwork \n", - "6173 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleDuelingNetwork \n", - "6448 EpsilonGreedy-0.6 SimpleDuelingNetwork \n", - "3264 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork \n", - "3399 EpsilonGreedy-0.6 SimpleNetwork \n", - "3429 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork \n", - "3539 EpsilonGreedy-0.1 SimpleNetwork \n", - "3574 EpsilonGreedy-0.6 SimpleNetwork \n", - "3624 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork \n", - "3669 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleNetwork \n", - "3719 EpsilonGreedy-0.1 SimpleNetwork \n", - "3754 EpsilonGreedy-0.6 SimpleNetwork \n", - "4524 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork \n", - "4619 EpsilonGreedy-0.1 SimpleNetwork \n", - "4659 EpsilonGreedy-0.6 SimpleNetwork \n", - "4669 EpsilonGreedy-0.6 SimpleNetwork \n", - "4704 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork \n", - "4794 EpsilonGreedy-0.1 SimpleNetwork \n", - "4799 EpsilonGreedy-0.1 SimpleNetwork \n", - "4844 EpsilonGreedy-0.6 SimpleNetwork \n", - "3758 EpsilonGreedy-0.6 SimpleNetwork \n", - "4564 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleNetwork \n", - "3484 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleNetwork \n", - "3619 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork \n", - "3617 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork \n", - "3618 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork \n", - "5087 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleDuelingNetwork \n", - "567 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 C51Network \n", - "3559 EpsilonGreedy-0.6 SimpleNetwork \n", - "\n", - " optimizer lr memories max_size step max min avg sum \n", - "3436 Adam 0.0010 ExperienceReplay 128 166.0 1.0 1.0 1.0 500.0 \n", - "3711 Adam 0.0010 ExperienceReplay 16 166.0 1.0 1.0 1.0 500.0 \n", - "4176 Adam 0.1000 ExperienceReplay 16 166.0 1.0 1.0 1.0 500.0 \n", - "2117 Adam 0.0001 ExperienceReplay 128 332.0 1.0 1.0 1.0 500.0 \n", - "3442 Adam 0.0010 ExperienceReplay 16 332.0 1.0 1.0 1.0 500.0 \n", - "3537 Adam 0.0010 ExperienceReplay 32 332.0 1.0 1.0 1.0 500.0 \n", - "3612 Adam 0.0001 ExperienceReplay 32 332.0 1.0 1.0 1.0 500.0 \n", - "3717 Adam 0.0010 ExperienceReplay 32 332.0 1.0 1.0 1.0 500.0 \n", - "4797 Adam 0.0010 ExperienceReplay 32 332.0 1.0 1.0 1.0 500.0 \n", - "1953 Adam 0.0010 ExperienceReplay 128 498.0 1.0 1.0 1.0 500.0 \n", - "2118 Adam 0.0001 ExperienceReplay 128 498.0 1.0 1.0 1.0 500.0 \n", - "3268 Adam 0.0010 ExperienceReplay 32 498.0 1.0 1.0 1.0 500.0 \n", - "3538 Adam 0.0010 ExperienceReplay 32 498.0 1.0 1.0 1.0 500.0 \n", - "3573 Adam 0.0010 ExperienceReplay 128 498.0 1.0 1.0 1.0 500.0 \n", - "3718 Adam 0.0010 ExperienceReplay 32 498.0 1.0 1.0 1.0 500.0 \n", - "3753 Adam 0.0010 ExperienceReplay 128 498.0 1.0 1.0 1.0 500.0 \n", - "4523 Adam 0.0010 ExperienceReplay 16 498.0 1.0 1.0 1.0 500.0 \n", - "4668 Adam 0.1000 ExperienceReplay 128 498.0 1.0 1.0 1.0 500.0 \n", - "4703 Adam 0.0010 ExperienceReplay 16 498.0 1.0 1.0 1.0 500.0 \n", - "4753 Adam 0.0010 ExperienceReplay 32 498.0 1.0 1.0 1.0 500.0 \n", - "4793 Adam 0.0010 ExperienceReplay 16 498.0 1.0 1.0 1.0 500.0 \n", - "4798 Adam 0.0010 ExperienceReplay 32 498.0 1.0 1.0 1.0 500.0 \n", - "6173 Adam 0.0001 ExperienceReplay 16 498.0 1.0 1.0 1.0 500.0 \n", - "6448 Adam 0.0001 ExperienceReplay 32 498.0 1.0 1.0 1.0 500.0 \n", - "3264 Adam 0.0010 ExperienceReplay 16 500.0 1.0 1.0 1.0 500.0 \n", - "3399 Adam 0.0010 ExperienceReplay 16 500.0 1.0 1.0 1.0 500.0 \n", - "3429 Adam 0.0001 ExperienceReplay 16 500.0 1.0 1.0 1.0 500.0 \n", - "3539 Adam 0.0010 ExperienceReplay 32 500.0 1.0 1.0 1.0 500.0 \n", - "3574 Adam 0.0010 ExperienceReplay 128 500.0 1.0 1.0 1.0 500.0 \n", - "3624 Adam 0.0010 ExperienceReplay 16 500.0 1.0 1.0 1.0 500.0 \n", - "3669 Adam 0.0010 ExperienceReplay 16 500.0 1.0 1.0 1.0 500.0 \n", - "3719 Adam 0.0010 ExperienceReplay 32 500.0 1.0 1.0 1.0 500.0 \n", - "3754 Adam 0.0010 ExperienceReplay 128 500.0 1.0 1.0 1.0 500.0 \n", - "4524 Adam 0.0010 ExperienceReplay 16 500.0 1.0 1.0 1.0 500.0 \n", - "4619 Adam 0.0010 ExperienceReplay 32 500.0 1.0 1.0 1.0 500.0 \n", - "4659 Adam 0.0010 ExperienceReplay 16 500.0 1.0 1.0 1.0 500.0 \n", - "4669 Adam 0.1000 ExperienceReplay 128 500.0 1.0 1.0 1.0 500.0 \n", - "4704 Adam 0.0010 ExperienceReplay 16 500.0 1.0 1.0 1.0 500.0 \n", - "4794 Adam 0.0010 ExperienceReplay 16 500.0 1.0 1.0 1.0 500.0 \n", - "4799 Adam 0.0010 ExperienceReplay 32 500.0 1.0 1.0 1.0 500.0 \n", - "4844 Adam 0.0010 ExperienceReplay 32 500.0 1.0 1.0 1.0 500.0 \n", - "3758 Adam 0.0010 ExperienceReplay 16 498.0 1.0 1.0 1.0 486.0 \n", - "4564 Adam 0.0010 ExperienceReplay 128 500.0 1.0 1.0 1.0 485.0 \n", - "3484 Adam 0.0010 ExperienceReplay 128 500.0 1.0 1.0 1.0 483.0 \n", - "3619 Adam 0.0010 ExperienceReplay 128 500.0 1.0 1.0 1.0 467.0 \n", - "3617 Adam 0.0010 ExperienceReplay 128 332.0 1.0 1.0 1.0 465.0 \n", - "3618 Adam 0.0010 ExperienceReplay 128 498.0 1.0 1.0 1.0 450.0 \n", - "5087 Adam 0.0001 ExperienceReplay 128 332.0 1.0 1.0 1.0 421.0 \n", - "567 Adam 0.0010 ExperienceReplay 32 332.0 1.0 1.0 1.0 405.0 \n", - "3559 Adam 0.0001 ExperienceReplay 128 500.0 1.0 1.0 1.0 398.0 " - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df.sort_values(by =[\"sum\",\"step\"], ascending = [False, True]).head(50)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Correlation matrix" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "df_corr = df.copy()" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "for c in df_corr.columns:\n", - " try:\n", - " df_corr[c] = df_corr[c].cat.codes\n", - " except:\n", - " pass" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "algo 7.373685e-02\n", - "step_train -1.697983e-01\n", - "batch_size 1.182673e-01\n", - "gamma -5.161482e-15\n", - "greedy_exploration 2.540062e-02\n", - "network 1.525560e-01\n", - " NaN\n", - "optimizer NaN\n", - "lr -1.308714e-01\n", - "memories NaN\n", - "max_size -1.339293e-02\n", - "step 1.712250e-01\n", - "max NaN\n", - "min NaN\n", - "avg NaN\n", - "sum 1.000000e+00\n", - "Name: sum, dtype: float64" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_corr.corr()[\"sum\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
algostep_trainbatch_sizegammagreedy_explorationnetworkoptimizerlrmemoriesmax_sizestepmaxminavgsum
algo1.000000e+00-8.992421e-180.000000e+000.000000e+000.000000e+004.045199e-01NaNNaN0.000000e+00NaN0.000000e+008.101552e-20NaNNaNNaN7.373685e-02
step_train-8.992421e-181.000000e+001.563538e-18-3.133980e-178.992421e-181.524091e-15NaNNaN2.026146e-17NaN-4.809914e-201.297656e-20NaNNaNNaN-1.697983e-01
batch_size0.000000e+001.563538e-181.000000e+000.000000e+000.000000e+001.533537e-15NaNNaN-1.642472e-16NaN-5.221288e-200.000000e+00NaNNaNNaN1.182673e-01
gamma0.000000e+00-3.133980e-170.000000e+001.000000e+000.000000e+000.000000e+00NaNNaN-1.533798e-14NaN0.000000e+009.148140e-17NaNNaNNaN-5.161482e-15
greedy_exploration0.000000e+008.992421e-180.000000e+000.000000e+001.000000e+000.000000e+00NaNNaN0.000000e+00NaN0.000000e+008.101552e-20NaNNaNNaN2.540062e-02
network4.045199e-011.524091e-151.533537e-150.000000e+000.000000e+001.000000e+00NaNNaN-1.978668e-16NaN0.000000e+002.660026e-17NaNNaNNaN1.525560e-01
NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
optimizerNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
lr0.000000e+002.026146e-17-1.642472e-16-1.533798e-140.000000e+00-1.978668e-16NaNNaN1.000000e+00NaN1.118946e-193.477634e-17NaNNaNNaN-1.308714e-01
memoriesNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
max_size0.000000e+00-4.809914e-20-5.221288e-200.000000e+000.000000e+000.000000e+00NaNNaN1.118946e-19NaN1.000000e+000.000000e+00NaNNaNNaN-1.339293e-02
step8.101552e-201.297656e-200.000000e+009.148140e-178.101552e-202.660026e-17NaNNaN3.477634e-17NaN0.000000e+001.000000e+00NaNNaNNaN1.712250e-01
maxNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
minNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
avgNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
sum7.373685e-02-1.697983e-011.182673e-01-5.161482e-152.540062e-021.525560e-01NaNNaN-1.308714e-01NaN-1.339293e-021.712250e-01NaNNaNNaN1.000000e+00
\n", - "
" - ], - "text/plain": [ - " algo step_train batch_size gamma \\\n", - "algo 1.000000e+00 -8.992421e-18 0.000000e+00 0.000000e+00 \n", - "step_train -8.992421e-18 1.000000e+00 1.563538e-18 -3.133980e-17 \n", - "batch_size 0.000000e+00 1.563538e-18 1.000000e+00 0.000000e+00 \n", - "gamma 0.000000e+00 -3.133980e-17 0.000000e+00 1.000000e+00 \n", - "greedy_exploration 0.000000e+00 8.992421e-18 0.000000e+00 0.000000e+00 \n", - "network 4.045199e-01 1.524091e-15 1.533537e-15 0.000000e+00 \n", - " NaN NaN NaN NaN \n", - "optimizer NaN NaN NaN NaN \n", - "lr 0.000000e+00 2.026146e-17 -1.642472e-16 -1.533798e-14 \n", - "memories NaN NaN NaN NaN \n", - "max_size 0.000000e+00 -4.809914e-20 -5.221288e-20 0.000000e+00 \n", - "step 8.101552e-20 1.297656e-20 0.000000e+00 9.148140e-17 \n", - "max NaN NaN NaN NaN \n", - "min NaN NaN NaN NaN \n", - "avg NaN NaN NaN NaN \n", - "sum 7.373685e-02 -1.697983e-01 1.182673e-01 -5.161482e-15 \n", - "\n", - " greedy_exploration network optimizer \\\n", - "algo 0.000000e+00 4.045199e-01 NaN NaN \n", - "step_train 8.992421e-18 1.524091e-15 NaN NaN \n", - "batch_size 0.000000e+00 1.533537e-15 NaN NaN \n", - "gamma 0.000000e+00 0.000000e+00 NaN NaN \n", - "greedy_exploration 1.000000e+00 0.000000e+00 NaN NaN \n", - "network 0.000000e+00 1.000000e+00 NaN NaN \n", - " NaN NaN NaN NaN \n", - "optimizer NaN NaN NaN NaN \n", - "lr 0.000000e+00 -1.978668e-16 NaN NaN \n", - "memories NaN NaN NaN NaN \n", - "max_size 0.000000e+00 0.000000e+00 NaN NaN \n", - "step 8.101552e-20 2.660026e-17 NaN NaN \n", - "max NaN NaN NaN NaN \n", - "min NaN NaN NaN NaN \n", - "avg NaN NaN NaN NaN \n", - "sum 2.540062e-02 1.525560e-01 NaN NaN \n", - "\n", - " lr memories max_size step max \\\n", - "algo 0.000000e+00 NaN 0.000000e+00 8.101552e-20 NaN \n", - "step_train 2.026146e-17 NaN -4.809914e-20 1.297656e-20 NaN \n", - "batch_size -1.642472e-16 NaN -5.221288e-20 0.000000e+00 NaN \n", - "gamma -1.533798e-14 NaN 0.000000e+00 9.148140e-17 NaN \n", - "greedy_exploration 0.000000e+00 NaN 0.000000e+00 8.101552e-20 NaN \n", - "network -1.978668e-16 NaN 0.000000e+00 2.660026e-17 NaN \n", - " NaN NaN NaN NaN NaN \n", - "optimizer NaN NaN NaN NaN NaN \n", - "lr 1.000000e+00 NaN 1.118946e-19 3.477634e-17 NaN \n", - "memories NaN NaN NaN NaN NaN \n", - "max_size 1.118946e-19 NaN 1.000000e+00 0.000000e+00 NaN \n", - "step 3.477634e-17 NaN 0.000000e+00 1.000000e+00 NaN \n", - "max NaN NaN NaN NaN NaN \n", - "min NaN NaN NaN NaN NaN \n", - "avg NaN NaN NaN NaN NaN \n", - "sum -1.308714e-01 NaN -1.339293e-02 1.712250e-01 NaN \n", - "\n", - " min avg sum \n", - "algo NaN NaN 7.373685e-02 \n", - "step_train NaN NaN -1.697983e-01 \n", - "batch_size NaN NaN 1.182673e-01 \n", - "gamma NaN NaN -5.161482e-15 \n", - "greedy_exploration NaN NaN 2.540062e-02 \n", - "network NaN NaN 1.525560e-01 \n", - " NaN NaN NaN \n", - "optimizer NaN NaN NaN \n", - "lr NaN NaN -1.308714e-01 \n", - "memories NaN NaN NaN \n", - "max_size NaN NaN -1.339293e-02 \n", - "step NaN NaN 1.712250e-01 \n", - "max NaN NaN NaN \n", - "min NaN NaN NaN \n", - "avg NaN NaN NaN \n", - "sum NaN NaN 1.000000e+00 " - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_corr.corr()" - ] - }, - { - "cell_type": "code", - "execution_count": 66, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 66, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "fig, ax = plt.subplots(figsize=(10,10)) \n", - "sns.heatmap(df.corr()[df.corr() > 0.05], annot = True, fmt='.2g',cmap= 'coolwarm', ax=ax)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Correlation matrix for best result" - ] - }, - { - "cell_type": "code", - "execution_count": 56, - "metadata": {}, - "outputs": [], - "source": [ - "df_corr_best = df_corr[df_corr[\"sum\"] >= 300]" - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", " \n", " \n", "
algostep_trainbatch_sizegammagreedy_explorationnetworkoptimizerlrmemoriesmax_sizestepmaxminavgsum
algo1.000000e+00-2.024974e-01-4.931761e-023.482840e-161.613751e-01-6.653163e-01NaNNaN-1.387198e-01NaN3.924623e-022.674115e-02NaNNaNNaN-3.890492e-01
step_train-2.024974e-011.000000e+004.067992e-024.391100e-17-2.457767e-01-2.033679e-01NaNNaN5.822535e-01NaN2.226417e-01-2.898155e-01NaNNaNNaN-2.090821e-02
batch_size-4.931761e-024.067992e-021.000000e+002.820643e-164.627404e-022.620456e-01NaNNaN3.432420e-02NaN4.325075e-027.685944e-02NaNNaNNaN1.187327e-01
gamma3.482840e-164.391100e-172.820643e-161.000000e+006.223740e-17-3.238646e-16NaNNaN1.441029e-16NaN1.306218e-16-1.823356e-16NaNNaNNaN-3.410748e-16
greedy_exploration1.613751e-01-2.457767e-014.627404e-026.223740e-171.000000e+00-7.484315e-03NaNNaN-2.102527e-02NaN-1.114625e-011.432139e-01NaNNaNNaN-2.831818e-02
network-6.653163e-01-2.033679e-012.620456e-01-3.238646e-16-7.484315e-031.000000e+00NaNNaN1.019551e-01NaN-1.256836e-019.331015e-02NaNNaNNaN2.632569e-01
NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
optimizerNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN30423DQN1.032.01.00AdaptativeEpsilonGreedy-0.8-0.2-10000-0SimpleNetworkAdam0.001ExperienceReplay512120.0500.0
lr-1.387198e-015.822535e-013.432420e-021.441029e-16-2.102527e-021.019551e-01NaNNaN1.000000e+00NaN-4.741960e-02-1.683165e-01NaNNaNNaN7.717727e-0231136DQN1.032.01.00EpsilonGreedy-0.6SimpleNetworkAdam0.001ExperienceReplay2048120.0500.0
memoriesNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN31167DQN1.032.01.00EpsilonGreedy-0.6SimpleNetworkAdam0.001ExperienceReplay512120.0500.0
max_size3.924623e-022.226417e-014.325075e-021.306218e-16-1.114625e-01-1.256836e-01NaNNaN-4.741960e-02NaN1.000000e+00-8.632279e-02NaNNaNNaN5.969496e-0231911DQN1.064.00.95AdaptativeEpsilonGreedy-0.8-0.2-10000-0SimpleNetworkAdam0.001ExperienceReplay512120.0500.0
step2.674115e-02-2.898155e-017.685944e-02-1.823356e-161.432139e-019.331015e-02NaNNaN-1.683165e-01NaN-8.632279e-021.000000e+00NaNNaNNaN5.831934e-0234112DQN1.064.00.99EpsilonGreedy-0.6SimpleNetworkAdam0.001ExperienceReplay2048120.0500.0
maxNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN34856DQN1.064.01.00AdaptativeEpsilonGreedy-0.8-0.2-10000-0SimpleNetworkAdam0.001ExperienceReplay2048120.0500.0
minNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN35259DQN1.064.01.00EpsilonGreedy-0.1SimpleNetworkAdam0.001ExperienceReplay512120.0500.0
avgNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN35693DQN1.064.01.00EpsilonGreedy-0.6SimpleNetworkAdam0.100ExperienceReplay512120.0500.0
sum-3.890492e-01-2.090821e-021.187327e-01-3.410748e-16-2.831818e-022.632569e-01NaNNaN7.717727e-02NaN5.969496e-025.831934e-02NaNNaNNaN1.000000e+0028192DQN1.032.00.95EpsilonGreedy-0.6SimpleNetworkAdam0.001ExperienceReplay512130.0500.0
\n", "
" ], "text/plain": [ - " algo step_train batch_size gamma \\\n", - "algo 1.000000e+00 -2.024974e-01 -4.931761e-02 3.482840e-16 \n", - "step_train -2.024974e-01 1.000000e+00 4.067992e-02 4.391100e-17 \n", - "batch_size -4.931761e-02 4.067992e-02 1.000000e+00 2.820643e-16 \n", - "gamma 3.482840e-16 4.391100e-17 2.820643e-16 1.000000e+00 \n", - "greedy_exploration 1.613751e-01 -2.457767e-01 4.627404e-02 6.223740e-17 \n", - "network -6.653163e-01 -2.033679e-01 2.620456e-01 -3.238646e-16 \n", - " NaN NaN NaN NaN \n", - "optimizer NaN NaN NaN NaN \n", - "lr -1.387198e-01 5.822535e-01 3.432420e-02 1.441029e-16 \n", - "memories NaN NaN NaN NaN \n", - "max_size 3.924623e-02 2.226417e-01 4.325075e-02 1.306218e-16 \n", - "step 2.674115e-02 -2.898155e-01 7.685944e-02 -1.823356e-16 \n", - "max NaN NaN NaN NaN \n", - "min NaN NaN NaN NaN \n", - "avg NaN NaN NaN NaN \n", - "sum -3.890492e-01 -2.090821e-02 1.187327e-01 -3.410748e-16 \n", - "\n", - " greedy_exploration network optimizer \\\n", - "algo 1.613751e-01 -6.653163e-01 NaN NaN \n", - "step_train -2.457767e-01 -2.033679e-01 NaN NaN \n", - "batch_size 4.627404e-02 2.620456e-01 NaN NaN \n", - "gamma 6.223740e-17 -3.238646e-16 NaN NaN \n", - "greedy_exploration 1.000000e+00 -7.484315e-03 NaN NaN \n", - "network -7.484315e-03 1.000000e+00 NaN NaN \n", - " NaN NaN NaN NaN \n", - "optimizer NaN NaN NaN NaN \n", - "lr -2.102527e-02 1.019551e-01 NaN NaN \n", - "memories NaN NaN NaN NaN \n", - "max_size -1.114625e-01 -1.256836e-01 NaN NaN \n", - "step 1.432139e-01 9.331015e-02 NaN NaN \n", - "max NaN NaN NaN NaN \n", - "min NaN NaN NaN NaN \n", - "avg NaN NaN NaN NaN \n", - "sum -2.831818e-02 2.632569e-01 NaN NaN \n", + " algo step_train batch_size gamma \\\n", + "31127 DQN 1.0 32.0 1.00 \n", + "34103 DQN 1.0 64.0 0.99 \n", + "33050 DQN 1.0 64.0 0.99 \n", + "32648 DQN 1.0 64.0 0.95 \n", + "34508 DQN 1.0 64.0 1.00 \n", + "28898 DQN 1.0 32.0 0.99 \n", + "33052 DQN 1.0 64.0 0.99 \n", + "34943 DQN 1.0 64.0 1.00 \n", + "35687 DQN 1.0 64.0 1.00 \n", + "31906 DQN 1.0 64.0 0.95 \n", + "32991 DQN 1.0 64.0 0.99 \n", + "34479 DQN 1.0 64.0 1.00 \n", + "28559 DQN 1.0 32.0 0.99 \n", + "28993 DQN 1.0 32.0 0.99 \n", + "31163 DQN 1.0 32.0 1.00 \n", + "31225 DQN 1.0 32.0 1.00 \n", + "33798 DQN 1.0 64.0 0.99 \n", + "35255 DQN 1.0 64.0 1.00 \n", + "27072 DQN 1.0 32.0 0.95 \n", + "27785 DQN 1.0 32.0 0.95 \n", + "28188 DQN 1.0 32.0 0.95 \n", + "31164 DQN 1.0 32.0 1.00 \n", + "32714 DQN 1.0 64.0 0.95 \n", + "32993 DQN 1.0 64.0 0.99 \n", + "33055 DQN 1.0 64.0 0.99 \n", + "33768 DQN 1.0 64.0 0.99 \n", + "28561 DQN 1.0 32.0 0.99 \n", + "30390 DQN 1.0 32.0 1.00 \n", + "31134 DQN 1.0 32.0 1.00 \n", + "33025 DQN 1.0 64.0 0.99 \n", + "33397 DQN 1.0 64.0 0.99 \n", + "33428 DQN 1.0 64.0 0.99 \n", + "27074 DQN 1.0 32.0 0.95 \n", + "28562 DQN 1.0 32.0 0.99 \n", + "33026 DQN 1.0 64.0 0.99 \n", + "33367 DQN 1.0 64.0 0.99 \n", + "34514 DQN 1.0 64.0 1.00 \n", + "35599 DQN 1.0 64.0 1.00 \n", + "27075 DQN 1.0 32.0 0.95 \n", + "28563 DQN 1.0 32.0 0.99 \n", + "30020 DQN 1.0 32.0 1.00 \n", + "30423 DQN 1.0 32.0 1.00 \n", + "31136 DQN 1.0 32.0 1.00 \n", + "31167 DQN 1.0 32.0 1.00 \n", + "31911 DQN 1.0 64.0 0.95 \n", + "34112 DQN 1.0 64.0 0.99 \n", + "34856 DQN 1.0 64.0 1.00 \n", + "35259 DQN 1.0 64.0 1.00 \n", + "35693 DQN 1.0 64.0 1.00 \n", + "28192 DQN 1.0 32.0 0.95 \n", "\n", - " lr memories max_size step max \\\n", - "algo -1.387198e-01 NaN 3.924623e-02 2.674115e-02 NaN \n", - "step_train 5.822535e-01 NaN 2.226417e-01 -2.898155e-01 NaN \n", - "batch_size 3.432420e-02 NaN 4.325075e-02 7.685944e-02 NaN \n", - "gamma 1.441029e-16 NaN 1.306218e-16 -1.823356e-16 NaN \n", - "greedy_exploration -2.102527e-02 NaN -1.114625e-01 1.432139e-01 NaN \n", - "network 1.019551e-01 NaN -1.256836e-01 9.331015e-02 NaN \n", - " NaN NaN NaN NaN NaN \n", - "optimizer NaN NaN NaN NaN NaN \n", - "lr 1.000000e+00 NaN -4.741960e-02 -1.683165e-01 NaN \n", - "memories NaN NaN NaN NaN NaN \n", - "max_size -4.741960e-02 NaN 1.000000e+00 -8.632279e-02 NaN \n", - "step -1.683165e-01 NaN -8.632279e-02 1.000000e+00 NaN \n", - "max NaN NaN NaN NaN NaN \n", - "min NaN NaN NaN NaN NaN \n", - "avg NaN NaN NaN NaN NaN \n", - "sum 7.717727e-02 NaN 5.969496e-02 5.831934e-02 NaN \n", + " greedy_exploration network optimizer \\\n", + "31127 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + "34103 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + "33050 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam \n", + "32648 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + "34508 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam \n", + "28898 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam \n", + "33052 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam \n", + "34943 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam \n", + "35687 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + "31906 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam \n", + "32991 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam \n", + "34479 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam \n", + "28559 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam \n", + "28993 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam \n", + "31163 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + "31225 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + "33798 EpsilonGreedy-0.1 SimpleNetwork Adam \n", + "35255 EpsilonGreedy-0.1 SimpleNetwork Adam \n", + "27072 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam \n", + "27785 EpsilonGreedy-0.1 SimpleNetwork Adam \n", + "28188 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + "31164 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + "32714 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + "32993 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam \n", + "33055 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam \n", + "33768 EpsilonGreedy-0.1 SimpleNetwork Adam \n", + "28561 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam \n", + "30390 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam \n", + "31134 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + "33025 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam \n", + "33397 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam \n", + "33428 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam \n", + "27074 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam \n", + "28562 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam \n", + "33026 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam \n", + "33367 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam \n", + "34514 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam \n", + "35599 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + "27075 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam \n", + "28563 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam \n", + "30020 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam \n", + "30423 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam \n", + "31136 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + "31167 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + "31911 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam \n", + "34112 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + "34856 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam \n", + "35259 EpsilonGreedy-0.1 SimpleNetwork Adam \n", + "35693 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + "28192 EpsilonGreedy-0.6 SimpleNetwork Adam \n", "\n", - " min avg sum \n", - "algo NaN NaN -3.890492e-01 \n", - "step_train NaN NaN -2.090821e-02 \n", - "batch_size NaN NaN 1.187327e-01 \n", - "gamma NaN NaN -3.410748e-16 \n", - "greedy_exploration NaN NaN -2.831818e-02 \n", - "network NaN NaN 2.632569e-01 \n", - " NaN NaN NaN \n", - "optimizer NaN NaN NaN \n", - "lr NaN NaN 7.717727e-02 \n", - "memories NaN NaN NaN \n", - "max_size NaN NaN 5.969496e-02 \n", - "step NaN NaN 5.831934e-02 \n", - "max NaN NaN NaN \n", - "min NaN NaN NaN \n", - "avg NaN NaN NaN \n", - "sum NaN NaN 1.000000e+00 " + " lr memories max_size step sum \n", + "31127 0.001 ExperienceReplay 2048 30.0 500.0 \n", + "34103 0.001 ExperienceReplay 2048 30.0 500.0 \n", + "33050 0.100 ExperienceReplay 2048 40.0 500.0 \n", + "32648 0.001 ExperienceReplay 512 50.0 500.0 \n", + "34508 0.001 ExperienceReplay 512 50.0 500.0 \n", + "28898 0.001 ExperienceReplay 2048 60.0 500.0 \n", + "33052 0.100 ExperienceReplay 2048 60.0 500.0 \n", + "34943 0.100 ExperienceReplay 512 60.0 500.0 \n", + "35687 0.100 ExperienceReplay 512 60.0 500.0 \n", + "31906 0.001 ExperienceReplay 512 70.0 500.0 \n", + "32991 0.001 ExperienceReplay 2048 70.0 500.0 \n", + "34479 0.001 ExperienceReplay 2048 70.0 500.0 \n", + "28559 0.001 ExperienceReplay 512 80.0 500.0 \n", + "28993 0.100 ExperienceReplay 512 80.0 500.0 \n", + "31163 0.001 ExperienceReplay 512 80.0 500.0 \n", + "31225 0.100 ExperienceReplay 512 80.0 500.0 \n", + "33798 0.100 ExperienceReplay 2048 80.0 500.0 \n", + "35255 0.001 ExperienceReplay 512 80.0 500.0 \n", + "27072 0.001 ExperienceReplay 512 90.0 500.0 \n", + "27785 0.001 ExperienceReplay 2048 90.0 500.0 \n", + "28188 0.001 ExperienceReplay 512 90.0 500.0 \n", + "31164 0.001 ExperienceReplay 512 90.0 500.0 \n", + "32714 0.100 ExperienceReplay 512 90.0 500.0 \n", + "32993 0.001 ExperienceReplay 2048 90.0 500.0 \n", + "33055 0.100 ExperienceReplay 2048 90.0 500.0 \n", + "33768 0.001 ExperienceReplay 512 90.0 500.0 \n", + "28561 0.001 ExperienceReplay 512 100.0 500.0 \n", + "30390 0.001 ExperienceReplay 2048 100.0 500.0 \n", + "31134 0.001 ExperienceReplay 2048 100.0 500.0 \n", + "33025 0.001 ExperienceReplay 512 100.0 500.0 \n", + "33397 0.001 ExperienceReplay 512 100.0 500.0 \n", + "33428 0.100 ExperienceReplay 2048 100.0 500.0 \n", + "27074 0.001 ExperienceReplay 512 110.0 500.0 \n", + "28562 0.001 ExperienceReplay 512 110.0 500.0 \n", + "33026 0.001 ExperienceReplay 512 110.0 500.0 \n", + "33367 0.001 ExperienceReplay 2048 110.0 500.0 \n", + "34514 0.001 ExperienceReplay 512 110.0 500.0 \n", + "35599 0.001 ExperienceReplay 2048 110.0 500.0 \n", + "27075 0.001 ExperienceReplay 512 120.0 500.0 \n", + "28563 0.001 ExperienceReplay 512 120.0 500.0 \n", + "30020 0.001 ExperienceReplay 2048 120.0 500.0 \n", + "30423 0.001 ExperienceReplay 512 120.0 500.0 \n", + "31136 0.001 ExperienceReplay 2048 120.0 500.0 \n", + "31167 0.001 ExperienceReplay 512 120.0 500.0 \n", + "31911 0.001 ExperienceReplay 512 120.0 500.0 \n", + "34112 0.001 ExperienceReplay 2048 120.0 500.0 \n", + "34856 0.001 ExperienceReplay 2048 120.0 500.0 \n", + "35259 0.001 ExperienceReplay 512 120.0 500.0 \n", + "35693 0.100 ExperienceReplay 512 120.0 500.0 \n", + "28192 0.001 ExperienceReplay 512 130.0 500.0 " ] }, - "execution_count": 57, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "df_corr_best.corr()" + "df_DQN.sort_values(by =[\"sum\",\"step\"], ascending = [False, True]).head(50)" ] }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -2551,13 +1816,13 @@ "" ] }, - "execution_count": 65, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -2570,35 +1835,12 @@ ], "source": [ "fig, ax = plt.subplots(figsize=(10,10)) \n", - "sns.heatmap(df_corr_best.corr()[df_corr_best.corr() > 0.05], annot = True, fmt='.2g',cmap= 'coolwarm', ax=ax)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Result by algo" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### DQN" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [], - "source": [ - "df_DQN = df[df[\"algo\"] == \"DQN\"].copy()" + "sns.heatmap(df_DQN.corr()[abs(df_DQN.corr()) > 0.05], annot = True, fmt='.2g',cmap= 'coolwarm', ax=ax)" ] }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 20, "metadata": {}, "outputs": [ { @@ -2622,186 +1864,783 @@ " \n", " \n", " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " step\n", + " sum\n", + " \n", + " \n", + " algo\n", " step_train\n", " batch_size\n", " gamma\n", + " greedy_exploration\n", + " network\n", + " optimizer\n", " lr\n", - " step\n", - " max\n", - " min\n", - " avg\n", - " sum\n", + " memories\n", + " max_size\n", + " \n", + " \n", + " \n", " \n", " \n", " \n", " \n", - " step_train\n", - " 1.000000e+00\n", - " 6.254152e-18\n", - " -3.338836e-15\n", - " -1.947613e-17\n", - " 5.190625e-20\n", - " NaN\n", - " NaN\n", - " NaN\n", - " -2.081287e-01\n", + " DQN\n", + " 1.0\n", + " 32.0\n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 17\n", + " 17\n", + " 17\n", + " \n", + " \n", + " 64.0\n", + " 1.00\n", + " EpsilonGreedy-0.1\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 14\n", + " 14\n", + " 14\n", + " \n", + " \n", + " 32.0\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 10\n", + " 10\n", + " 10\n", + " \n", + " \n", + " 64.0\n", + " 1.00\n", + " EpsilonGreedy-0.6\n", + " SimpleNetwork\n", + " Adam\n", + " 0.1000\n", + " ExperienceReplay\n", + " 512\n", + " 9\n", + " 9\n", + " 9\n", + " \n", + " \n", + " 0.99\n", + " EpsilonGreedy-0.6\n", + " SimpleNetwork\n", + " Adam\n", + " 0.1000\n", + " ExperienceReplay\n", + " 512\n", + " 9\n", + " 9\n", + " 9\n", + " \n", + " \n", + " 32.0\n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 8\n", + " 8\n", + " 8\n", + " \n", + " \n", + " 1.00\n", + " EpsilonGreedy-0.6\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 8\n", + " 8\n", + " 8\n", + " \n", + " \n", + " 64.0\n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 8\n", + " 8\n", + " 8\n", + " \n", + " \n", + " 1.00\n", + " EpsilonGreedy-0.6\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 7\n", + " 7\n", + " 7\n", + " \n", + " \n", + " 0.99\n", + " EpsilonGreedy-0.6\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 6\n", + " 6\n", + " 6\n", + " \n", + " \n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 5\n", + " 5\n", + " 5\n", + " \n", + " \n", + " 32.0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 5\n", + " 5\n", + " 5\n", + " \n", + " \n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 5\n", + " 5\n", + " 5\n", + " \n", + " \n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 5\n", + " 5\n", + " 5\n", + " \n", + " \n", + " 64.0\n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.1000\n", + " ExperienceReplay\n", + " 2048\n", + " 5\n", + " 5\n", + " 5\n", + " \n", + " \n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " 0.99\n", + " EpsilonGreedy-0.6\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " 0.95\n", + " EpsilonGreedy-0.6\n", + " SimpleNetwork\n", + " Adam\n", + " 0.1000\n", + " ExperienceReplay\n", + " 512\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " 2048\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " 32.0\n", + " 0.95\n", + " EpsilonGreedy-0.6\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " 1.00\n", + " EpsilonGreedy-0.6\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 3\n", + " 3\n", + " 3\n", + " \n", + " \n", + " 64.0\n", + " 0.99\n", + " EpsilonGreedy-0.1\n", + " SimpleNetwork\n", + " Adam\n", + " 0.1000\n", + " ExperienceReplay\n", + " 2048\n", + " 3\n", + " 3\n", + " 3\n", + " \n", + " \n", + " 32.0\n", + " 0.95\n", + " EpsilonGreedy-0.1\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 3\n", + " 3\n", + " 3\n", + " \n", + " \n", + " 1.00\n", + " EpsilonGreedy-0.6\n", + " SimpleNetwork\n", + " Adam\n", + " 0.1000\n", + " ExperienceReplay\n", + " 512\n", + " 3\n", + " 3\n", + " 3\n", + " \n", + " \n", + " 64.0\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 3\n", + " 3\n", + " 3\n", + " \n", + " \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.1000\n", + " ExperienceReplay\n", + " 512\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 32.0\n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.1000\n", + " ExperienceReplay\n", + " 512\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " EpsilonGreedy-0.6\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 64.0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 0.99\n", + " EpsilonGreedy-0.1\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " batch_size\n", - " 6.254152e-18\n", - " 1.000000e+00\n", - " -5.096548e-15\n", - " 1.309431e-16\n", - " 0.000000e+00\n", - " NaN\n", - " NaN\n", - " NaN\n", - " 1.477390e-01\n", + " 0.1000\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " gamma\n", - " -3.338836e-15\n", - " -5.096548e-15\n", - " 1.000000e+00\n", - " 1.070395e-14\n", - " -1.030754e-16\n", - " NaN\n", - " NaN\n", - " NaN\n", - " 3.327095e-16\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " lr\n", - " -1.947613e-17\n", - " 1.309431e-16\n", - " 1.070395e-14\n", - " 1.000000e+00\n", - " -3.622535e-19\n", - " NaN\n", - " NaN\n", - " NaN\n", - " -1.253560e-01\n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " step\n", - " 5.190625e-20\n", - " 0.000000e+00\n", - " -1.030754e-16\n", - " -3.622535e-19\n", - " 1.000000e+00\n", - " NaN\n", - " NaN\n", - " NaN\n", - " 2.112197e-01\n", + " 32.0\n", + " 1.00\n", + " EpsilonGreedy-0.1\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " max\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " min\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", + " EpsilonGreedy-0.1\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " avg\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", + " 0.99\n", + " EpsilonGreedy-0.1\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " sum\n", - " -2.081287e-01\n", - " 1.477390e-01\n", - " 3.327095e-16\n", - " -1.253560e-01\n", - " 2.112197e-01\n", - " NaN\n", - " NaN\n", - " NaN\n", - " 1.000000e+00\n", + " 64.0\n", + " 0.95\n", + " EpsilonGreedy-0.6\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 32.0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", "\n", "" ], "text/plain": [ - " step_train batch_size gamma lr \\\n", - "step_train 1.000000e+00 6.254152e-18 -3.338836e-15 -1.947613e-17 \n", - "batch_size 6.254152e-18 1.000000e+00 -5.096548e-15 1.309431e-16 \n", - "gamma -3.338836e-15 -5.096548e-15 1.000000e+00 1.070395e-14 \n", - "lr -1.947613e-17 1.309431e-16 1.070395e-14 1.000000e+00 \n", - "step 5.190625e-20 0.000000e+00 -1.030754e-16 -3.622535e-19 \n", - "max NaN NaN NaN NaN \n", - "min NaN NaN NaN NaN \n", - "avg NaN NaN NaN NaN \n", - "sum -2.081287e-01 1.477390e-01 3.327095e-16 -1.253560e-01 \n", + " \\\n", + "algo step_train batch_size gamma greedy_exploration network optimizer lr memories max_size \n", + "DQN 1.0 32.0 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 17 \n", + " 64.0 1.00 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 512 14 \n", + " 32.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 10 \n", + " 64.0 1.00 EpsilonGreedy-0.6 SimpleNetwork Adam 0.1000 ExperienceReplay 512 9 \n", + " 0.99 EpsilonGreedy-0.6 SimpleNetwork Adam 0.1000 ExperienceReplay 512 9 \n", + " 32.0 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 8 \n", + " 1.00 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 8 \n", + " 64.0 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 8 \n", + " 1.00 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 7 \n", + " 0.99 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 512 6 \n", + " 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 5 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 5 \n", + " 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 5 \n", + " 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 5 \n", + " 64.0 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 2048 5 \n", + " 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 4 \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 0.99 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 4 \n", + " 0.95 EpsilonGreedy-0.6 SimpleNetwork Adam 0.1000 ExperienceReplay 512 4 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 2048 4 \n", + " 32.0 0.95 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 1.00 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 3 \n", + " 64.0 0.99 EpsilonGreedy-0.1 SimpleNetwork Adam 0.1000 ExperienceReplay 2048 3 \n", + " 32.0 0.95 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 3 \n", + " 1.00 EpsilonGreedy-0.6 SimpleNetwork Adam 0.1000 ExperienceReplay 512 3 \n", + " 64.0 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 3 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 512 2 \n", + " 32.0 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 512 2 \n", + " EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 512 2 \n", + " 64.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 2 \n", + " 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 2 \n", + " 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0001 ExperienceReplay 2048 2 \n", + " 0.99 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 512 2 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 0.1000 ExperienceReplay 2048 1 \n", + " 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 32.0 1.00 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 0.99 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 64.0 0.95 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 0.0001 ExperienceReplay 2048 1 \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + "\n", + " step \\\n", + "algo step_train batch_size gamma greedy_exploration network optimizer lr memories max_size \n", + "DQN 1.0 32.0 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 17 \n", + " 64.0 1.00 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 512 14 \n", + " 32.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 10 \n", + " 64.0 1.00 EpsilonGreedy-0.6 SimpleNetwork Adam 0.1000 ExperienceReplay 512 9 \n", + " 0.99 EpsilonGreedy-0.6 SimpleNetwork Adam 0.1000 ExperienceReplay 512 9 \n", + " 32.0 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 8 \n", + " 1.00 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 8 \n", + " 64.0 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 8 \n", + " 1.00 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 7 \n", + " 0.99 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 512 6 \n", + " 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 5 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 5 \n", + " 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 5 \n", + " 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 5 \n", + " 64.0 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 2048 5 \n", + " 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 4 \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 0.99 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 4 \n", + " 0.95 EpsilonGreedy-0.6 SimpleNetwork Adam 0.1000 ExperienceReplay 512 4 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 2048 4 \n", + " 32.0 0.95 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 1.00 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 3 \n", + " 64.0 0.99 EpsilonGreedy-0.1 SimpleNetwork Adam 0.1000 ExperienceReplay 2048 3 \n", + " 32.0 0.95 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 3 \n", + " 1.00 EpsilonGreedy-0.6 SimpleNetwork Adam 0.1000 ExperienceReplay 512 3 \n", + " 64.0 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 3 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 512 2 \n", + " 32.0 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 512 2 \n", + " EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 512 2 \n", + " 64.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 2 \n", + " 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 2 \n", + " 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0001 ExperienceReplay 2048 2 \n", + " 0.99 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 512 2 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 0.1000 ExperienceReplay 2048 1 \n", + " 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 32.0 1.00 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 0.99 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 64.0 0.95 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 0.0001 ExperienceReplay 2048 1 \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", "\n", - " step max min avg sum \n", - "step_train 5.190625e-20 NaN NaN NaN -2.081287e-01 \n", - "batch_size 0.000000e+00 NaN NaN NaN 1.477390e-01 \n", - "gamma -1.030754e-16 NaN NaN NaN 3.327095e-16 \n", - "lr -3.622535e-19 NaN NaN NaN -1.253560e-01 \n", - "step 1.000000e+00 NaN NaN NaN 2.112197e-01 \n", - "max NaN NaN NaN NaN NaN \n", - "min NaN NaN NaN NaN NaN \n", - "avg NaN NaN NaN NaN NaN \n", - "sum 2.112197e-01 NaN NaN NaN 1.000000e+00 " + " sum \n", + "algo step_train batch_size gamma greedy_exploration network optimizer lr memories max_size \n", + "DQN 1.0 32.0 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 17 \n", + " 64.0 1.00 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 512 14 \n", + " 32.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 10 \n", + " 64.0 1.00 EpsilonGreedy-0.6 SimpleNetwork Adam 0.1000 ExperienceReplay 512 9 \n", + " 0.99 EpsilonGreedy-0.6 SimpleNetwork Adam 0.1000 ExperienceReplay 512 9 \n", + " 32.0 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 8 \n", + " 1.00 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 8 \n", + " 64.0 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 8 \n", + " 1.00 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 7 \n", + " 0.99 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 512 6 \n", + " 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 5 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 5 \n", + " 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 5 \n", + " 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 5 \n", + " 64.0 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 2048 5 \n", + " 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 4 \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 0.99 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 4 \n", + " 0.95 EpsilonGreedy-0.6 SimpleNetwork Adam 0.1000 ExperienceReplay 512 4 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 2048 4 \n", + " 32.0 0.95 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 1.00 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 3 \n", + " 64.0 0.99 EpsilonGreedy-0.1 SimpleNetwork Adam 0.1000 ExperienceReplay 2048 3 \n", + " 32.0 0.95 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 3 \n", + " 1.00 EpsilonGreedy-0.6 SimpleNetwork Adam 0.1000 ExperienceReplay 512 3 \n", + " 64.0 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 3 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 512 2 \n", + " 32.0 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 512 2 \n", + " EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 512 2 \n", + " 64.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 2 \n", + " 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 2 \n", + " 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0001 ExperienceReplay 2048 2 \n", + " 0.99 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 512 2 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 0.1000 ExperienceReplay 2048 1 \n", + " 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 32.0 1.00 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 0.99 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 64.0 0.95 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 0.0001 ExperienceReplay 2048 1 \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 " ] }, - "execution_count": 17, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "df_DQN.corr()" + "columns = [\"algo\",\"step_train\",\"batch_size\",\"gamma\",\"greedy_exploration\",\"network\",\"optimizer\",\"lr\",\"memories\",\"max_size\"]\n", + "df_DQN[df_DQN[\"sum\"] >= 500].groupby(by=columns, observed=True).count().sort_values(by=['sum'], ascending=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### DuelingNetwork" ] }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 21, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(500.0, 8.0)" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "max(df_DQN[\"sum\"]), min(df_DQN[\"sum\"])" + "df_DQN = df[df[\"algo\"] == \"DQN\"].copy()\n", + "df_DQN = df_DQN[df_DQN[\"network\"] == \"SimpleDuelingNetwork\"]" ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 22, "metadata": {}, "outputs": [ { @@ -2837,391 +2676,328 @@ " memories\n", " max_size\n", " step\n", - " max\n", - " min\n", - " avg\n", " sum\n", " \n", " \n", " \n", " \n", - " 3436\n", - " DQN\n", - " 1.0\n", - " 32.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", - " SimpleNetwork\n", - " \n", - " Adam\n", - " 0.0010\n", - " ExperienceReplay\n", - " 128\n", - " 166.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 500.0\n", - " \n", - " \n", - " 3711\n", + " 31716\n", " DQN\n", " 1.0\n", " 64.0\n", - " 0.99\n", - " EpsilonGreedy-0.1\n", - " SimpleNetwork\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 16\n", - " 166.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 512\n", + " 30.0\n", " 500.0\n", " \n", " \n", - " 4176\n", + " 27997\n", " DQN\n", + " 1.0\n", " 32.0\n", - " 64.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", - " SimpleNetwork\n", + " 0.95\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.1000\n", + " 0.001\n", " ExperienceReplay\n", - " 16\n", - " 166.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 512\n", + " 40.0\n", " 500.0\n", " \n", " \n", - " 3442\n", + " 29082\n", " DQN\n", " 1.0\n", " 32.0\n", " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", - " SimpleNetwork\n", + " EpsilonGreedy-0.1\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 16\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 40.0\n", " 500.0\n", " \n", " \n", - " 3537\n", + " 30601\n", " DQN\n", " 1.0\n", " 32.0\n", - " 0.99\n", + " 1.00\n", " EpsilonGreedy-0.1\n", - " SimpleNetwork\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 32\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 512\n", + " 40.0\n", " 500.0\n", " \n", " \n", - " 3612\n", + " 32461\n", " DQN\n", " 1.0\n", " 64.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", - " SimpleNetwork\n", + " 0.95\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0001\n", + " 0.001\n", " ExperienceReplay\n", - " 32\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 512\n", + " 40.0\n", " 500.0\n", " \n", " \n", - " 3717\n", + " 33918\n", " DQN\n", " 1.0\n", " 64.0\n", " 0.99\n", - " EpsilonGreedy-0.1\n", - " SimpleNetwork\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 32\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 40.0\n", " 500.0\n", " \n", " \n", - " 4797\n", + " 27626\n", " DQN\n", - " 4.0\n", - " 64.0\n", - " 0.99\n", + " 1.0\n", + " 32.0\n", + " 0.95\n", " EpsilonGreedy-0.1\n", - " SimpleNetwork\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 32\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 512\n", + " 50.0\n", " 500.0\n", " \n", " \n", - " 3268\n", + " 29827\n", " DQN\n", " 1.0\n", - " 1.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", - " SimpleNetwork\n", + " 32.0\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 32\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 50.0\n", + " 500.0\n", + " \n", + " \n", + " 31346\n", + " DQN\n", " 1.0\n", + " 64.0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " \n", + " Adam\n", + " 0.001\n", + " ExperienceReplay\n", + " 512\n", + " 50.0\n", " 500.0\n", " \n", " \n", - " 3538\n", + " 32803\n", " DQN\n", " 1.0\n", - " 32.0\n", + " 64.0\n", " 0.99\n", - " EpsilonGreedy-0.1\n", - " SimpleNetwork\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 32\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 50.0\n", " 500.0\n", " \n", " \n", - " 3573\n", + " 28340\n", " DQN\n", " 1.0\n", " 32.0\n", " 0.99\n", - " EpsilonGreedy-0.6\n", - " SimpleNetwork\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 128\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 60.0\n", " 500.0\n", " \n", " \n", - " 3718\n", + " 29859\n", " DQN\n", " 1.0\n", - " 64.0\n", - " 0.99\n", - " EpsilonGreedy-0.1\n", - " SimpleNetwork\n", + " 32.0\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 32\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 512\n", + " 60.0\n", " 500.0\n", " \n", " \n", - " 3753\n", + " 32804\n", " DQN\n", " 1.0\n", " 64.0\n", " 0.99\n", - " EpsilonGreedy-0.6\n", - " SimpleNetwork\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 128\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 60.0\n", " 500.0\n", " \n", " \n", - " 4523\n", + " 30201\n", " DQN\n", - " 4.0\n", + " 1.0\n", " 32.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", - " SimpleNetwork\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 16\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 70.0\n", " 500.0\n", " \n", " \n", - " 4668\n", + " 32805\n", " DQN\n", - " 4.0\n", - " 32.0\n", + " 1.0\n", + " 64.0\n", " 0.99\n", - " EpsilonGreedy-0.6\n", - " SimpleNetwork\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.1000\n", + " 0.001\n", " ExperienceReplay\n", - " 128\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 70.0\n", " 500.0\n", " \n", " \n", - " 4703\n", + " 33921\n", " DQN\n", - " 4.0\n", + " 1.0\n", " 64.0\n", " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", - " SimpleNetwork\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 16\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 70.0\n", " 500.0\n", " \n", " \n", - " 4753\n", + " 35409\n", " DQN\n", - " 4.0\n", + " 1.0\n", " 64.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", - " SimpleNetwork\n", + " 1.00\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 32\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 70.0\n", " 500.0\n", " \n", " \n", - " 4793\n", + " 28745\n", " DQN\n", - " 4.0\n", - " 64.0\n", + " 1.0\n", + " 32.0\n", " 0.99\n", - " EpsilonGreedy-0.1\n", - " SimpleNetwork\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 16\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 512\n", + " 80.0\n", " 500.0\n", " \n", " \n", - " 4798\n", + " 31349\n", " DQN\n", - " 4.0\n", + " 1.0\n", " 64.0\n", - " 0.99\n", - " EpsilonGreedy-0.1\n", - " SimpleNetwork\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 32\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 512\n", + " 80.0\n", " 500.0\n", " \n", " \n", - " 3264\n", + " 28343\n", " DQN\n", " 1.0\n", - " 1.0\n", + " 32.0\n", " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", - " SimpleNetwork\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.001\n", " ExperienceReplay\n", - " 16\n", - " 500.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 2048\n", + " 90.0\n", " 500.0\n", " \n", " \n", @@ -3229,74 +3005,74 @@ "" ], "text/plain": [ - " algo step_train batch_size gamma \\\n", - "3436 DQN 1.0 32.0 0.99 \n", - "3711 DQN 1.0 64.0 0.99 \n", - "4176 DQN 32.0 64.0 0.99 \n", - "3442 DQN 1.0 32.0 0.99 \n", - "3537 DQN 1.0 32.0 0.99 \n", - "3612 DQN 1.0 64.0 0.99 \n", - "3717 DQN 1.0 64.0 0.99 \n", - "4797 DQN 4.0 64.0 0.99 \n", - "3268 DQN 1.0 1.0 0.99 \n", - "3538 DQN 1.0 32.0 0.99 \n", - "3573 DQN 1.0 32.0 0.99 \n", - "3718 DQN 1.0 64.0 0.99 \n", - "3753 DQN 1.0 64.0 0.99 \n", - "4523 DQN 4.0 32.0 0.99 \n", - "4668 DQN 4.0 32.0 0.99 \n", - "4703 DQN 4.0 64.0 0.99 \n", - "4753 DQN 4.0 64.0 0.99 \n", - "4793 DQN 4.0 64.0 0.99 \n", - "4798 DQN 4.0 64.0 0.99 \n", - "3264 DQN 1.0 1.0 0.99 \n", + " algo step_train batch_size gamma \\\n", + "31716 DQN 1.0 64.0 0.95 \n", + "27997 DQN 1.0 32.0 0.95 \n", + "29082 DQN 1.0 32.0 0.99 \n", + "30601 DQN 1.0 32.0 1.00 \n", + "32461 DQN 1.0 64.0 0.95 \n", + "33918 DQN 1.0 64.0 0.99 \n", + "27626 DQN 1.0 32.0 0.95 \n", + "29827 DQN 1.0 32.0 1.00 \n", + "31346 DQN 1.0 64.0 0.95 \n", + "32803 DQN 1.0 64.0 0.99 \n", + "28340 DQN 1.0 32.0 0.99 \n", + "29859 DQN 1.0 32.0 1.00 \n", + "32804 DQN 1.0 64.0 0.99 \n", + "30201 DQN 1.0 32.0 1.00 \n", + "32805 DQN 1.0 64.0 0.99 \n", + "33921 DQN 1.0 64.0 0.99 \n", + "35409 DQN 1.0 64.0 1.00 \n", + "28745 DQN 1.0 32.0 0.99 \n", + "31349 DQN 1.0 64.0 0.95 \n", + "28343 DQN 1.0 32.0 0.99 \n", "\n", - " greedy_exploration network optimizer \\\n", - "3436 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork Adam \n", - "3711 EpsilonGreedy-0.1 SimpleNetwork Adam \n", - "4176 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork Adam \n", - "3442 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork Adam \n", - "3537 EpsilonGreedy-0.1 SimpleNetwork Adam \n", - "3612 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork Adam \n", - "3717 EpsilonGreedy-0.1 SimpleNetwork Adam \n", - "4797 EpsilonGreedy-0.1 SimpleNetwork Adam \n", - "3268 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork Adam \n", - "3538 EpsilonGreedy-0.1 SimpleNetwork Adam \n", - "3573 EpsilonGreedy-0.6 SimpleNetwork Adam \n", - "3718 EpsilonGreedy-0.1 SimpleNetwork Adam \n", - "3753 EpsilonGreedy-0.6 SimpleNetwork Adam \n", - "4523 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork Adam \n", - "4668 EpsilonGreedy-0.6 SimpleNetwork Adam \n", - "4703 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork Adam \n", - "4753 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleNetwork Adam \n", - "4793 EpsilonGreedy-0.1 SimpleNetwork Adam \n", - "4798 EpsilonGreedy-0.1 SimpleNetwork Adam \n", - "3264 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork Adam \n", + " greedy_exploration network \\\n", + "31716 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork \n", + "27997 EpsilonGreedy-0.6 SimpleDuelingNetwork \n", + "29082 EpsilonGreedy-0.1 SimpleDuelingNetwork \n", + "30601 EpsilonGreedy-0.1 SimpleDuelingNetwork \n", + "32461 EpsilonGreedy-0.6 SimpleDuelingNetwork \n", + "33918 EpsilonGreedy-0.6 SimpleDuelingNetwork \n", + "27626 EpsilonGreedy-0.1 SimpleDuelingNetwork \n", + "29827 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork \n", + "31346 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork \n", + "32803 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork \n", + "28340 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork \n", + "29859 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork \n", + "32804 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork \n", + "30201 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork \n", + "32805 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork \n", + "33921 EpsilonGreedy-0.6 SimpleDuelingNetwork \n", + "35409 EpsilonGreedy-0.6 SimpleDuelingNetwork \n", + "28745 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork \n", + "31349 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork \n", + "28343 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork \n", "\n", - " lr memories max_size step max min avg sum \n", - "3436 0.0010 ExperienceReplay 128 166.0 1.0 1.0 1.0 500.0 \n", - "3711 0.0010 ExperienceReplay 16 166.0 1.0 1.0 1.0 500.0 \n", - "4176 0.1000 ExperienceReplay 16 166.0 1.0 1.0 1.0 500.0 \n", - "3442 0.0010 ExperienceReplay 16 332.0 1.0 1.0 1.0 500.0 \n", - "3537 0.0010 ExperienceReplay 32 332.0 1.0 1.0 1.0 500.0 \n", - "3612 0.0001 ExperienceReplay 32 332.0 1.0 1.0 1.0 500.0 \n", - "3717 0.0010 ExperienceReplay 32 332.0 1.0 1.0 1.0 500.0 \n", - "4797 0.0010 ExperienceReplay 32 332.0 1.0 1.0 1.0 500.0 \n", - "3268 0.0010 ExperienceReplay 32 498.0 1.0 1.0 1.0 500.0 \n", - "3538 0.0010 ExperienceReplay 32 498.0 1.0 1.0 1.0 500.0 \n", - "3573 0.0010 ExperienceReplay 128 498.0 1.0 1.0 1.0 500.0 \n", - "3718 0.0010 ExperienceReplay 32 498.0 1.0 1.0 1.0 500.0 \n", - "3753 0.0010 ExperienceReplay 128 498.0 1.0 1.0 1.0 500.0 \n", - "4523 0.0010 ExperienceReplay 16 498.0 1.0 1.0 1.0 500.0 \n", - "4668 0.1000 ExperienceReplay 128 498.0 1.0 1.0 1.0 500.0 \n", - "4703 0.0010 ExperienceReplay 16 498.0 1.0 1.0 1.0 500.0 \n", - "4753 0.0010 ExperienceReplay 32 498.0 1.0 1.0 1.0 500.0 \n", - "4793 0.0010 ExperienceReplay 16 498.0 1.0 1.0 1.0 500.0 \n", - "4798 0.0010 ExperienceReplay 32 498.0 1.0 1.0 1.0 500.0 \n", - "3264 0.0010 ExperienceReplay 16 500.0 1.0 1.0 1.0 500.0 " + " optimizer lr memories max_size step sum \n", + "31716 Adam 0.001 ExperienceReplay 512 30.0 500.0 \n", + "27997 Adam 0.001 ExperienceReplay 512 40.0 500.0 \n", + "29082 Adam 0.001 ExperienceReplay 2048 40.0 500.0 \n", + "30601 Adam 0.001 ExperienceReplay 512 40.0 500.0 \n", + "32461 Adam 0.001 ExperienceReplay 512 40.0 500.0 \n", + "33918 Adam 0.001 ExperienceReplay 2048 40.0 500.0 \n", + "27626 Adam 0.001 ExperienceReplay 512 50.0 500.0 \n", + "29827 Adam 0.001 ExperienceReplay 2048 50.0 500.0 \n", + "31346 Adam 0.001 ExperienceReplay 512 50.0 500.0 \n", + "32803 Adam 0.001 ExperienceReplay 2048 50.0 500.0 \n", + "28340 Adam 0.001 ExperienceReplay 2048 60.0 500.0 \n", + "29859 Adam 0.001 ExperienceReplay 512 60.0 500.0 \n", + "32804 Adam 0.001 ExperienceReplay 2048 60.0 500.0 \n", + "30201 Adam 0.001 ExperienceReplay 2048 70.0 500.0 \n", + "32805 Adam 0.001 ExperienceReplay 2048 70.0 500.0 \n", + "33921 Adam 0.001 ExperienceReplay 2048 70.0 500.0 \n", + "35409 Adam 0.001 ExperienceReplay 2048 70.0 500.0 \n", + "28745 Adam 0.001 ExperienceReplay 512 80.0 500.0 \n", + "31349 Adam 0.001 ExperienceReplay 512 80.0 500.0 \n", + "28343 Adam 0.001 ExperienceReplay 2048 90.0 500.0 " ] }, - "execution_count": 19, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -3307,7 +3083,7 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 23, "metadata": {}, "outputs": [ { @@ -3316,13 +3092,13 @@ "" ] }, - "execution_count": 67, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -3335,28 +3111,12 @@ ], "source": [ "fig, ax = plt.subplots(figsize=(10,10)) \n", - "sns.heatmap(df_DQN.corr()[df_DQN.corr() > 0.05], annot = True, fmt='.2g',cmap= 'coolwarm', ax=ax)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### DoubleDQN" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [], - "source": [ - "df_DoubleDQN = df[df[\"algo\"] == \"DoubleDQN\"].copy()" + "sns.heatmap(df_DQN.corr()[abs(df_DQN.corr()) > 0.05], annot = True, fmt='.2g',cmap= 'coolwarm', ax=ax)" ] }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 24, "metadata": {}, "outputs": [ { @@ -3380,186 +3140,910 @@ " \n", " \n", " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " step\n", + " sum\n", + " \n", + " \n", + " algo\n", " step_train\n", " batch_size\n", " gamma\n", + " greedy_exploration\n", + " network\n", + " optimizer\n", " lr\n", - " step\n", - " max\n", - " min\n", - " avg\n", - " sum\n", + " memories\n", + " max_size\n", + " \n", + " \n", + " \n", " \n", " \n", " \n", " \n", - " step_train\n", - " 1.000000e+00\n", - " 6.254152e-18\n", - " -3.338836e-15\n", - " -1.947613e-17\n", - " 5.190625e-20\n", - " NaN\n", - " NaN\n", - " NaN\n", - " -2.016153e-01\n", + " DQN\n", + " 1.0\n", + " 32.0\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 21\n", + " 21\n", + " 21\n", + " \n", + " \n", + " 64.0\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 20\n", + " 20\n", + " 20\n", + " \n", + " \n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 17\n", + " 17\n", + " 17\n", + " \n", + " \n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 15\n", + " 15\n", + " 15\n", + " \n", + " \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 14\n", + " 14\n", + " 14\n", + " \n", + " \n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 14\n", + " 14\n", + " 14\n", + " \n", + " \n", + " 32.0\n", + " 1.00\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 14\n", + " 14\n", + " 14\n", + " \n", + " \n", + " 64.0\n", + " 1.00\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 13\n", + " 13\n", + " 13\n", + " \n", + " \n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 11\n", + " 11\n", + " 11\n", + " \n", + " \n", + " 32.0\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 11\n", + " 11\n", + " 11\n", + " \n", + " \n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 11\n", + " 11\n", + " 11\n", + " \n", + " \n", + " 64.0\n", + " 1.00\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 10\n", + " 10\n", + " 10\n", + " \n", + " \n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 8\n", + " 8\n", + " 8\n", + " \n", + " \n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 7\n", + " 7\n", + " 7\n", + " \n", + " \n", + " 32.0\n", + " 0.95\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 6\n", + " 6\n", + " 6\n", + " \n", + " \n", + " 64.0\n", + " 0.95\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 6\n", + " 6\n", + " 6\n", + " \n", + " \n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 5\n", + " 5\n", + " 5\n", + " \n", + " \n", + " EpsilonGreedy-0.1\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 5\n", + " 5\n", + " 5\n", + " \n", + " \n", + " 1.00\n", + " EpsilonGreedy-0.1\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 5\n", + " 5\n", + " 5\n", + " \n", + " \n", + " 0.99\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " 32.0\n", + " 0.95\n", + " EpsilonGreedy-0.1\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " 0.99\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " 64.0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 3\n", + " 3\n", + " 3\n", + " \n", + " \n", + " 0.99\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 3\n", + " 3\n", + " 3\n", + " \n", + " \n", + " 32.0\n", + " 0.95\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 3\n", + " 3\n", + " 3\n", + " \n", + " \n", + " EpsilonGreedy-0.1\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 3\n", + " 3\n", + " 3\n", + " \n", + " \n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 3\n", + " 3\n", + " 3\n", + " \n", + " \n", + " 0.99\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 3\n", + " 3\n", + " 3\n", + " \n", + " \n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 3\n", + " 3\n", + " 3\n", + " \n", + " \n", + " 64.0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 32.0\n", + " 0.95\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 0.99\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 64.0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 32.0\n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 64.0\n", + " 1.00\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 32.0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 1.00\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 0.99\n", + " EpsilonGreedy-0.1\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 64.0\n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 32.0\n", + " 1.00\n", + " EpsilonGreedy-0.1\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " batch_size\n", - " 6.254152e-18\n", - " 1.000000e+00\n", - " -5.096548e-15\n", - " 1.309431e-16\n", - " 0.000000e+00\n", - " NaN\n", - " NaN\n", - " NaN\n", - " 1.556979e-01\n", + " 64.0\n", + " 0.95\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " gamma\n", - " -3.338836e-15\n", - " -5.096548e-15\n", - " 1.000000e+00\n", - " 1.070395e-14\n", - " -1.030754e-16\n", - " NaN\n", - " NaN\n", - " NaN\n", - " 2.291126e-16\n", + " EpsilonGreedy-0.1\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " lr\n", - " -1.947613e-17\n", - " 1.309431e-16\n", - " 1.070395e-14\n", - " 1.000000e+00\n", - " -3.622535e-19\n", - " NaN\n", - " NaN\n", - " NaN\n", - " -1.461935e-01\n", + " 32.0\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " step\n", - " 5.190625e-20\n", - " 0.000000e+00\n", - " -1.030754e-16\n", - " -3.622535e-19\n", - " 1.000000e+00\n", - " NaN\n", - " NaN\n", - " NaN\n", - " 1.829836e-01\n", + " 64.0\n", + " 0.95\n", + " EpsilonGreedy-0.1\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " max\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " min\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", + " 32.0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " avg\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", + " 64.0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " sum\n", - " -2.016153e-01\n", - " 1.556979e-01\n", - " 2.291126e-16\n", - " -1.461935e-01\n", - " 1.829836e-01\n", - " NaN\n", - " NaN\n", - " NaN\n", - " 1.000000e+00\n", + " 32.0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", "\n", "" ], "text/plain": [ - " step_train batch_size gamma lr \\\n", - "step_train 1.000000e+00 6.254152e-18 -3.338836e-15 -1.947613e-17 \n", - "batch_size 6.254152e-18 1.000000e+00 -5.096548e-15 1.309431e-16 \n", - "gamma -3.338836e-15 -5.096548e-15 1.000000e+00 1.070395e-14 \n", - "lr -1.947613e-17 1.309431e-16 1.070395e-14 1.000000e+00 \n", - "step 5.190625e-20 0.000000e+00 -1.030754e-16 -3.622535e-19 \n", - "max NaN NaN NaN NaN \n", - "min NaN NaN NaN NaN \n", - "avg NaN NaN NaN NaN \n", - "sum -2.016153e-01 1.556979e-01 2.291126e-16 -1.461935e-01 \n", + " \\\n", + "algo step_train batch_size gamma greedy_exploration network optimizer lr memories max_size \n", + "DQN 1.0 32.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 21 \n", + " 64.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 20 \n", + " 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 17 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 15 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 14 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 14 \n", + " 32.0 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 14 \n", + " 64.0 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 13 \n", + " 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 11 \n", + " 32.0 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 11 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 11 \n", + " 64.0 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 10 \n", + " 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 8 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 7 \n", + " 32.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 6 \n", + " 64.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 6 \n", + " 0.0001 ExperienceReplay 512 5 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 5 \n", + " 1.00 EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 5 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 4 \n", + " 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 4 \n", + " 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 32.0 0.95 EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 4 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 4 \n", + " 64.0 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 3 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 3 \n", + " 32.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 3 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 3 \n", + " 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 3 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 3 \n", + " 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 3 \n", + " 64.0 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 32.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 64.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 2 \n", + " 32.0 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 2 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 64.0 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 0.99 EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 64.0 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 32.0 1.00 EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 64.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 32.0 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 64.0 0.95 EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 64.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", "\n", - " step max min avg sum \n", - "step_train 5.190625e-20 NaN NaN NaN -2.016153e-01 \n", - "batch_size 0.000000e+00 NaN NaN NaN 1.556979e-01 \n", - "gamma -1.030754e-16 NaN NaN NaN 2.291126e-16 \n", - "lr -3.622535e-19 NaN NaN NaN -1.461935e-01 \n", - "step 1.000000e+00 NaN NaN NaN 1.829836e-01 \n", - "max NaN NaN NaN NaN NaN \n", - "min NaN NaN NaN NaN NaN \n", - "avg NaN NaN NaN NaN NaN \n", - "sum 1.829836e-01 NaN NaN NaN 1.000000e+00 " + " step \\\n", + "algo step_train batch_size gamma greedy_exploration network optimizer lr memories max_size \n", + "DQN 1.0 32.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 21 \n", + " 64.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 20 \n", + " 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 17 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 15 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 14 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 14 \n", + " 32.0 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 14 \n", + " 64.0 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 13 \n", + " 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 11 \n", + " 32.0 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 11 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 11 \n", + " 64.0 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 10 \n", + " 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 8 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 7 \n", + " 32.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 6 \n", + " 64.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 6 \n", + " 0.0001 ExperienceReplay 512 5 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 5 \n", + " 1.00 EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 5 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 4 \n", + " 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 4 \n", + " 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 32.0 0.95 EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 4 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 4 \n", + " 64.0 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 3 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 3 \n", + " 32.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 3 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 3 \n", + " 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 3 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 3 \n", + " 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 3 \n", + " 64.0 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 32.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 64.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 2 \n", + " 32.0 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 2 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 64.0 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 0.99 EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 64.0 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 32.0 1.00 EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 64.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 32.0 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 64.0 0.95 EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 64.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + "\n", + " sum \n", + "algo step_train batch_size gamma greedy_exploration network optimizer lr memories max_size \n", + "DQN 1.0 32.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 21 \n", + " 64.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 20 \n", + " 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 17 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 15 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 14 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 14 \n", + " 32.0 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 14 \n", + " 64.0 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 13 \n", + " 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 11 \n", + " 32.0 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 11 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 11 \n", + " 64.0 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 10 \n", + " 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 8 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 7 \n", + " 32.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 6 \n", + " 64.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 6 \n", + " 0.0001 ExperienceReplay 512 5 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 5 \n", + " 1.00 EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 5 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 4 \n", + " 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 4 \n", + " 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 32.0 0.95 EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 4 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 4 \n", + " 64.0 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 3 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 3 \n", + " 32.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 3 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 3 \n", + " 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 3 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 3 \n", + " 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 3 \n", + " 64.0 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 32.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 64.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 2 \n", + " 32.0 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 2 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 64.0 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 0.99 EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 64.0 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 32.0 1.00 EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 64.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 32.0 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 64.0 0.95 EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 64.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 " ] }, - "execution_count": 21, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "df_DoubleDQN.corr()" + "columns = [\"algo\",\"step_train\",\"batch_size\",\"gamma\",\"greedy_exploration\",\"network\",\"optimizer\",\"lr\",\"memories\",\"max_size\"]\n", + "df_DQN[df_DQN[\"sum\"] >= 500].groupby(by=columns, observed=True).count().sort_values(by=['sum'], ascending=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### DoubleDQN" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### SimpleNetwork" ] }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 25, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(500.0, 8.0)" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "max(df_DoubleDQN[\"sum\"]), min(df_DoubleDQN[\"sum\"])" + "df_DoubleDQN = df[df[\"algo\"] == \"DoubleDQN\"].copy()\n", + "df_DoubleDQN = df_DoubleDQN[df_DoubleDQN[\"network\"] == \"SimpleNetwork\"]" ] }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 26, "metadata": {}, "outputs": [ { @@ -3589,483 +4073,230 @@ " gamma\n", " greedy_exploration\n", " network\n", - " \n", - " optimizer\n", - " lr\n", - " memories\n", - " max_size\n", - " step\n", - " max\n", - " min\n", - " avg\n", - " sum\n", - " \n", - " \n", - " \n", - " \n", - " 2117\n", - " DoubleDQN\n", - " 1.0\n", - " 64.0\n", - " 0.99\n", - " EpsilonGreedy-0.6\n", - " SimpleNetwork\n", - " \n", - " Adam\n", - " 0.0001\n", - " ExperienceReplay\n", - " 128\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 500.0\n", - " \n", - " \n", - " 1953\n", - " DoubleDQN\n", - " 1.0\n", - " 32.0\n", - " 0.99\n", - " EpsilonGreedy-0.6\n", - " SimpleNetwork\n", - " \n", - " Adam\n", - " 0.0010\n", - " ExperienceReplay\n", - " 128\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 500.0\n", - " \n", - " \n", - " 2118\n", - " DoubleDQN\n", - " 1.0\n", - " 64.0\n", - " 0.99\n", - " EpsilonGreedy-0.6\n", - " SimpleNetwork\n", - " \n", - " Adam\n", - " 0.0001\n", - " ExperienceReplay\n", - " 128\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 500.0\n", - " \n", - " \n", - " 2089\n", - " DoubleDQN\n", - " 1.0\n", - " 64.0\n", - " 0.99\n", - " EpsilonGreedy-0.1\n", - " SimpleNetwork\n", - " \n", - " Adam\n", - " 0.0010\n", - " ExperienceReplay\n", - " 128\n", - " 500.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 386.0\n", - " \n", - " \n", - " 1938\n", - " DoubleDQN\n", - " 1.0\n", - " 32.0\n", - " 0.99\n", - " EpsilonGreedy-0.6\n", - " SimpleNetwork\n", - " \n", - " Adam\n", - " 0.0001\n", - " ExperienceReplay\n", - " 128\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 380.0\n", - " \n", - " \n", - " 2029\n", - " DoubleDQN\n", - " 1.0\n", - " 64.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", - " SimpleNetwork\n", - " \n", - " Adam\n", - " 0.0001\n", - " ExperienceReplay\n", - " 128\n", - " 500.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 379.0\n", - " \n", - " \n", - " 2008\n", - " DoubleDQN\n", - " 1.0\n", - " 64.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", - " SimpleNetwork\n", - " \n", - " Adam\n", - " 0.0010\n", - " ExperienceReplay\n", - " 32\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 369.0\n", - " \n", - " \n", - " 1962\n", - " DoubleDQN\n", - " 1.0\n", - " 32.0\n", - " 0.99\n", - " EpsilonGreedy-0.6\n", - " SimpleNetwork\n", - " \n", - " Adam\n", - " 0.0010\n", - " ExperienceReplay\n", - " 32\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 347.0\n", - " \n", - " \n", - " 3132\n", - " DoubleDQN\n", - " 4.0\n", - " 64.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", - " SimpleNetwork\n", - " \n", - " Adam\n", - " 0.0010\n", - " ExperienceReplay\n", - " 32\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 337.0\n", + " \n", + " optimizer\n", + " lr\n", + " memories\n", + " max_size\n", + " step\n", + " sum\n", " \n", + " \n", + " \n", " \n", - " 3134\n", + " 12930\n", " DoubleDQN\n", - " 4.0\n", - " 64.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", - " SimpleNetwork\n", - " \n", - " Adam\n", - " 0.0010\n", - " ExperienceReplay\n", - " 32\n", - " 500.0\n", - " 1.0\n", - " 1.0\n", " 1.0\n", - " 326.0\n", - " \n", - " \n", - " 3044\n", - " DoubleDQN\n", - " 4.0\n", " 32.0\n", - " 0.99\n", - " EpsilonGreedy-0.6\n", + " 1.00\n", + " EpsilonGreedy-0.1\n", " SimpleNetwork\n", " \n", " Adam\n", " 0.0010\n", " ExperienceReplay\n", - " 32\n", + " 512\n", + " 30.0\n", " 500.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 316.0\n", " \n", " \n", - " 1818\n", + " 11412\n", " DoubleDQN\n", " 1.0\n", " 32.0\n", " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", + " EpsilonGreedy-0.1\n", " SimpleNetwork\n", " \n", " Adam\n", " 0.0010\n", " ExperienceReplay\n", - " 128\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 314.0\n", + " 2048\n", + " 40.0\n", + " 500.0\n", " \n", " \n", - " 3133\n", + " 24122\n", " DoubleDQN\n", - " 4.0\n", + " 32.0\n", " 64.0\n", " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", " SimpleNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.1000\n", " ExperienceReplay\n", - " 32\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 310.0\n", + " 2048\n", + " 40.0\n", + " 500.0\n", " \n", " \n", - " 2138\n", + " 14796\n", " DoubleDQN\n", " 1.0\n", " 64.0\n", - " 0.99\n", + " 0.95\n", " EpsilonGreedy-0.6\n", " SimpleNetwork\n", " \n", " Adam\n", " 0.0010\n", " ExperienceReplay\n", - " 16\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 309.0\n", + " 512\n", + " 90.0\n", + " 500.0\n", " \n", " \n", - " 1939\n", + " 17742\n", " DoubleDQN\n", " 1.0\n", - " 32.0\n", - " 0.99\n", + " 64.0\n", + " 1.00\n", " EpsilonGreedy-0.6\n", " SimpleNetwork\n", " \n", " Adam\n", - " 0.0001\n", + " 0.0010\n", " ExperienceReplay\n", - " 128\n", + " 2048\n", + " 100.0\n", " 500.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 294.0\n", " \n", " \n", - " 2028\n", + " 14802\n", " DoubleDQN\n", " 1.0\n", " 64.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", + " 0.95\n", + " EpsilonGreedy-0.6\n", " SimpleNetwork\n", " \n", " Adam\n", - " 0.0001\n", + " 0.0010\n", " ExperienceReplay\n", - " 128\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 293.0\n", + " 512\n", + " 150.0\n", + " 500.0\n", " \n", " \n", - " 3223\n", + " 15580\n", " DoubleDQN\n", - " 4.0\n", + " 1.0\n", " 64.0\n", " 0.99\n", - " EpsilonGreedy-0.6\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", " SimpleNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.1000\n", " ExperienceReplay\n", - " 32\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 293.0\n", + " 2048\n", + " 180.0\n", + " 500.0\n", " \n", " \n", - " 1951\n", + " 17719\n", " DoubleDQN\n", " 1.0\n", - " 32.0\n", - " 0.99\n", + " 64.0\n", + " 1.00\n", " EpsilonGreedy-0.6\n", " SimpleNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.0001\n", " ExperienceReplay\n", - " 128\n", - " 166.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 287.0\n", + " 512\n", + " 180.0\n", + " 500.0\n", " \n", " \n", - " 1952\n", + " 15922\n", " DoubleDQN\n", " 1.0\n", - " 32.0\n", + " 64.0\n", " 0.99\n", - " EpsilonGreedy-0.6\n", + " EpsilonGreedy-0.1\n", " SimpleNetwork\n", " \n", " Adam\n", " 0.0010\n", " ExperienceReplay\n", - " 128\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 283.0\n", + " 512\n", + " 190.0\n", + " 500.0\n", " \n", " \n", - " 1957\n", + " 17720\n", " DoubleDQN\n", " 1.0\n", - " 32.0\n", - " 0.99\n", + " 64.0\n", + " 1.00\n", " EpsilonGreedy-0.6\n", " SimpleNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.0001\n", " ExperienceReplay\n", - " 16\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 283.0\n", + " 512\n", + " 190.0\n", + " 500.0\n", " \n", " \n", "\n", "" ], "text/plain": [ - " algo step_train batch_size gamma \\\n", - "2117 DoubleDQN 1.0 64.0 0.99 \n", - "1953 DoubleDQN 1.0 32.0 0.99 \n", - "2118 DoubleDQN 1.0 64.0 0.99 \n", - "2089 DoubleDQN 1.0 64.0 0.99 \n", - "1938 DoubleDQN 1.0 32.0 0.99 \n", - "2029 DoubleDQN 1.0 64.0 0.99 \n", - "2008 DoubleDQN 1.0 64.0 0.99 \n", - "1962 DoubleDQN 1.0 32.0 0.99 \n", - "3132 DoubleDQN 4.0 64.0 0.99 \n", - "3134 DoubleDQN 4.0 64.0 0.99 \n", - "3044 DoubleDQN 4.0 32.0 0.99 \n", - "1818 DoubleDQN 1.0 32.0 0.99 \n", - "3133 DoubleDQN 4.0 64.0 0.99 \n", - "2138 DoubleDQN 1.0 64.0 0.99 \n", - "1939 DoubleDQN 1.0 32.0 0.99 \n", - "2028 DoubleDQN 1.0 64.0 0.99 \n", - "3223 DoubleDQN 4.0 64.0 0.99 \n", - "1951 DoubleDQN 1.0 32.0 0.99 \n", - "1952 DoubleDQN 1.0 32.0 0.99 \n", - "1957 DoubleDQN 1.0 32.0 0.99 \n", + " algo step_train batch_size gamma \\\n", + "12930 DoubleDQN 1.0 32.0 1.00 \n", + "11412 DoubleDQN 1.0 32.0 0.99 \n", + "24122 DoubleDQN 32.0 64.0 0.99 \n", + "14796 DoubleDQN 1.0 64.0 0.95 \n", + "17742 DoubleDQN 1.0 64.0 1.00 \n", + "14802 DoubleDQN 1.0 64.0 0.95 \n", + "15580 DoubleDQN 1.0 64.0 0.99 \n", + "17719 DoubleDQN 1.0 64.0 1.00 \n", + "15922 DoubleDQN 1.0 64.0 0.99 \n", + "17720 DoubleDQN 1.0 64.0 1.00 \n", "\n", - " greedy_exploration network optimizer \\\n", - "2117 EpsilonGreedy-0.6 SimpleNetwork Adam \n", - "1953 EpsilonGreedy-0.6 SimpleNetwork Adam \n", - "2118 EpsilonGreedy-0.6 SimpleNetwork Adam \n", - "2089 EpsilonGreedy-0.1 SimpleNetwork Adam \n", - "1938 EpsilonGreedy-0.6 SimpleNetwork Adam \n", - "2029 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleNetwork Adam \n", - "2008 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork Adam \n", - "1962 EpsilonGreedy-0.6 SimpleNetwork Adam \n", - "3132 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleNetwork Adam \n", - "3134 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleNetwork Adam \n", - "3044 EpsilonGreedy-0.6 SimpleNetwork Adam \n", - "1818 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleNetwork Adam \n", - "3133 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleNetwork Adam \n", - "2138 EpsilonGreedy-0.6 SimpleNetwork Adam \n", - "1939 EpsilonGreedy-0.6 SimpleNetwork Adam \n", - "2028 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleNetwork Adam \n", - "3223 EpsilonGreedy-0.6 SimpleNetwork Adam \n", - "1951 EpsilonGreedy-0.6 SimpleNetwork Adam \n", - "1952 EpsilonGreedy-0.6 SimpleNetwork Adam \n", - "1957 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + " greedy_exploration network optimizer \\\n", + "12930 EpsilonGreedy-0.1 SimpleNetwork Adam \n", + "11412 EpsilonGreedy-0.1 SimpleNetwork Adam \n", + "24122 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam \n", + "14796 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + "17742 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + "14802 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + "15580 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam \n", + "17719 EpsilonGreedy-0.6 SimpleNetwork Adam \n", + "15922 EpsilonGreedy-0.1 SimpleNetwork Adam \n", + "17720 EpsilonGreedy-0.6 SimpleNetwork Adam \n", "\n", - " lr memories max_size step max min avg sum \n", - "2117 0.0001 ExperienceReplay 128 332.0 1.0 1.0 1.0 500.0 \n", - "1953 0.0010 ExperienceReplay 128 498.0 1.0 1.0 1.0 500.0 \n", - "2118 0.0001 ExperienceReplay 128 498.0 1.0 1.0 1.0 500.0 \n", - "2089 0.0010 ExperienceReplay 128 500.0 1.0 1.0 1.0 386.0 \n", - "1938 0.0001 ExperienceReplay 128 498.0 1.0 1.0 1.0 380.0 \n", - "2029 0.0001 ExperienceReplay 128 500.0 1.0 1.0 1.0 379.0 \n", - "2008 0.0010 ExperienceReplay 32 498.0 1.0 1.0 1.0 369.0 \n", - "1962 0.0010 ExperienceReplay 32 332.0 1.0 1.0 1.0 347.0 \n", - "3132 0.0010 ExperienceReplay 32 332.0 1.0 1.0 1.0 337.0 \n", - "3134 0.0010 ExperienceReplay 32 500.0 1.0 1.0 1.0 326.0 \n", - "3044 0.0010 ExperienceReplay 32 500.0 1.0 1.0 1.0 316.0 \n", - "1818 0.0010 ExperienceReplay 128 498.0 1.0 1.0 1.0 314.0 \n", - "3133 0.0010 ExperienceReplay 32 498.0 1.0 1.0 1.0 310.0 \n", - "2138 0.0010 ExperienceReplay 16 498.0 1.0 1.0 1.0 309.0 \n", - "1939 0.0001 ExperienceReplay 128 500.0 1.0 1.0 1.0 294.0 \n", - "2028 0.0001 ExperienceReplay 128 498.0 1.0 1.0 1.0 293.0 \n", - "3223 0.0010 ExperienceReplay 32 498.0 1.0 1.0 1.0 293.0 \n", - "1951 0.0010 ExperienceReplay 128 166.0 1.0 1.0 1.0 287.0 \n", - "1952 0.0010 ExperienceReplay 128 332.0 1.0 1.0 1.0 283.0 \n", - "1957 0.0010 ExperienceReplay 16 332.0 1.0 1.0 1.0 283.0 " + " lr memories max_size step sum \n", + "12930 0.0010 ExperienceReplay 512 30.0 500.0 \n", + "11412 0.0010 ExperienceReplay 2048 40.0 500.0 \n", + "24122 0.1000 ExperienceReplay 2048 40.0 500.0 \n", + "14796 0.0010 ExperienceReplay 512 90.0 500.0 \n", + "17742 0.0010 ExperienceReplay 2048 100.0 500.0 \n", + "14802 0.0010 ExperienceReplay 512 150.0 500.0 \n", + "15580 0.1000 ExperienceReplay 2048 180.0 500.0 \n", + "17719 0.0001 ExperienceReplay 512 180.0 500.0 \n", + "15922 0.0010 ExperienceReplay 512 190.0 500.0 \n", + "17720 0.0001 ExperienceReplay 512 190.0 500.0 " ] }, - "execution_count": 23, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "df_DoubleDQN.sort_values(by =[\"sum\",\"step\"], ascending = [False, True]).head(20)" + "df_DoubleDQN.sort_values(by =[\"sum\",\"step\"], ascending = [False, True]).head(10)" ] }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 27, "metadata": {}, "outputs": [ { @@ -4074,13 +4305,13 @@ "" ] }, - "execution_count": 68, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjUAAAJDCAYAAADzbuVEAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy86wFpkAAAACXBIWXMAAAsTAAALEwEAmpwYAAA4wklEQVR4nO3debhdZXn38e+dEEgIATLIFMYiBgEhDCIIFooKlEEULGJ9nYqNtlKhDojVOlALitgWUKTRMjgrmPcVhIpKFQRRSWQeIpFQEkAwhCEkIdO53z/WTjgk55C9cva0Vr6f69rX2cPae917Jfvs+/yeZ60VmYkkSVLVDet2AZIkSa1gUyNJkmrBpkaSJNWCTY0kSaoFmxpJklQLNjWSJKkWbGokSVJLRcTFEfF4RNw1yOMREedHxKyIuCMi9mnFem1qJElSq10KHPkij/8lsEvjMgX4SitWalMjSZJaKjNvAOa/yCLHAV/Pwq+BzSNi66Gud4OhvkAzrh4xycMWN+noZTO7XYIkDergY6/vdgmVceNVh0Sn1tXp79ljlv/+vRQJy0pTM3NqiZeYCMzpd3tu475Hh1JXR5oaSZJUH40GpkwTs7qBGr4hN2YOP0mSpE6bC2zX7/a2wCNDfVGTGkmSKi5GdGykq1WuBE6JiO8CrwKezswhDT2BTY0kSWqxiPgOcCgwISLmAp8CRgBk5kXANcBRwCxgEfDuVqzXpkaSpIobtkFvJTWZ+da1PJ7A+1u9XufUSJKkWjCpkSSp4mKEGQWY1EiSpJowqZEkqeJ6bU5Nt5jUSJKkWjCpkSSp4ip4nJq2MKmRJEm1YFMjSZJqweEnSZIqzonCBZMaSZJUCyY1kiRVnBOFCyY1kiSpFkxqJEmqOOfUFExqJElSLZjUSJJUcTHcpAZMaiRJUk2Y1EiSVHHDTGoAkxpJklQTJjWSJFVcDDOpAZMaSZJUEyY1kiRVXAw3owCTGkmSVBMmNZIkVZx7PxVMaiRJUi3Y1EiSpFpw+EmSpIpzl+6CSY0kSaoFkxpJkirOicIFkxpJklQLJjWSJFVcmNQAJjWSJKkmTGokSaq4GGZGASY1kiSpJkxqJEmqOI9TUzCpkSRJtWBSI0lSxXmcmsJ619Ts+dWz2OKoQ1n6+BPcsPex3S5HkrQWp07ZmQP3Hc9zS1Zw1nkz+f0fnl1jmTP+4WXsussYAOY8spiz/uM+Fj/Xx5jRG/CxUyexzVYjWbqsj7PPm8nshxZ1+i2oQ9a74ae5l03jt8e8p9tlSJKacMC+49hum4056b2/5Qtf/j0f/rtdBlzu/K/9gXd9YAbv+sAMHvvTEk44ZiIAbz9xe+5/4Fne9YEZfPbf7+PUKS/tZPkdE8Oio5detd41NfNvnM6y+U93uwxJUhNec8B4fvw/fwTg7pkL2GT0Bowfu+Eayy1avGLV9Y02HEZmcX3H7TZmxh1PAvDQ3MVsvcVIxm4+ov2Fqyuabmoi4viIuD8ino6IZyJiQUQ8087iJEnrtwnjN+LxeUtW3X78iSVMGL9mUwPwsVMnceXXD2SHbTfmih89DMCs2Qv58wNfAsDLdxnDlluMZIvxG7W/8A6LYcM6eulVZSo7B3hDZm6WmZtm5pjM3HSwhSNiSkRMj4jpP+57asiFSpLWPwMOdOTAy5593kze+K6b+d+5C3ntwUUj880rHmLMJhtwyXn7csKxE7n/gQWsWDHIC6jyykwUfiwz72124cycCkwFuHrEJP8HSZKacvxR23DsEVsDcO/9C9hiwvPJyhbjN2Le/KWDPrevD6775Z946/Hbcc11j7Fo8QrOPm/mqscv/9qreOSx59pXvLqqTFMzPSK+B/w/YFUWmJnTWl2UJGn9Ne2aR5h2zSMAHLjfOE44ZiI/u+FP7D5pDM8uWs4TT67Z1EzceiQPP1o0KwftP56H5hZ7OG0yejjPLelj+fLk2MO34va7n3rB/Ju66OXJu51UpqnZFFgEHN7vvgQq1dRM/sYXGX/I/mw4YSyHzb6e+8+8gDmXXNHtsiRJA7h5+nwO3G8c35u6/6pdulf6wqf24HMX/J75Ty7l46ftyuiNhxMRzJr9LOdeeD8AO2w7mk98cBJ9ffDgQwv53Pm/79ZbUQdEZvtHhhx+at7Ry2aufSFJ6pKDj72+2yVUxo1XHdKx+OTu4w7r6Pfs7j/8n56Mhtaa1ETE6Zl5TkRcwADTszLzA22pTJIkqYRmhp9WTg6e3s5CJEnSunFOTWGtTU1mXtX4eVn7y5EkSVo3TU8UjoiXAB8FdgNGrrw/Mw9rQ12SJKlJvXxAvE4qsxW+RTEUtRPwGeBB4JY21CRJklRamV26x2fmf0XEqZl5PXB9RDgNXpKkLnNOTaFMU7Os8fPRiDgaeATYtvUlSZIklVemqflsRGwGfAi4gOJgfP/YlqokSVLTTGoKTTU1ETEc2CUzfwQ8DfxFW6uSJEkqqamJwpm5AnhDm2uRJEnrIIZFRy+9qszw068i4kvA94CFK+/MzN+1vCpJkqSSyjQ1r278PLPffQl4nBpJkrrI49QUyjQ1J2fmA/3viIg/a3E9kiRJ66RMU3MFsM9q910O7Nu6ciRJUlnDhvfuPJdOauYs3bsCuwObRcTx/R7alH6nS5AkSeqmZpKaScAxwObAsf3uXwD8bRtqkiRJKq2Zs3T/EPhhRByYmTcPtlxEfCwzz25pdZIkaa16eTfrTmp6uvSLNTQNfzXEWiRJktZZmYnCa2ObKElSF7hLd6GVWyFb+FqSJEmlmNRIklRxzqkptDKpubyFryVJklRK001NRPxZRFwVEfMi4vGI+GH/Iwpn5lntKVGSJL0YT2hZKJPUfBv4PrAVsA1FMvOddhQlSZJUVpk5NZGZ3+h3+5sRcUqrC5IkSeW491OhzFb4eUScERE7RsQOEXE6cHVEjIuIce0qUJIkVUtEHBkRMyNiVkScMcDjmzWmtNweEXdHxLtbsd4ySc1bGj/fu9r9f0OxO7dn7JYkqQt6aZ5LRAwHvgy8HpgL3BIRV2bmPf0Wez9wT2YeGxEvAWZGxLcyc+lQ1t10U5OZOw1lRZIkab2wPzArMx8AiIjvAscB/ZuaBMZERACbAPOB5UNdcdNNTURsDHwQ2D4zp0TELsCkzPzRUIuQJEnrrtNzaiJiCjCl311TM3Nq4/pEYE6/x+YCr1rtJb4EXAk8AowB3pKZfUOtq8zw0yXADODV/Yq8HLCpkSRpPdJoYKYO8vBAY2Grn3XgCOA24DBgZ+CnEfHLzHxmKHWVae12zsxzgGUAmbkYjyIsSVL3RXT28uLmAtv1u70tRSLT37uBaVmYBcwGdh3qZijT1CyNiFE0uq2I2BlYMtQCJElSrdwC7BIRO0XEhsBJFENN/T0EvBYgIrYEJgEPDHXFZYafPg38GNguIr4FHETRaUmSJAGQmcsbx7G7FhgOXJyZd0fE+xqPXwT8C3BpRNxJMerz0cycN9R1l9n76ScRMQM4oFHAqa0oQJIkDU0v7dINkJnXANesdt9F/a4/Ahze6vWWOffTdZn5RGZenZk/ysx5EXFdqwuSJElaF2tNaiJiJLAxMCEixvL85OBNKc4BJUmSusjTJBSaGX56L3AaRQMzg6KpSWABxX7mkiRJXbfW1i4zz2scTfhfgcmN65dQzFK+uc31SZKktYhh0dFLryqTV705M5+JiIMpzudwKfCVtlQlSZJUUpldulc0fh4NXJSZP4yIT7e+pPXb1SMmdbuESjh62cxulyBJPcM5NYUyTc3DEfGfwOuAz0fERjSZ9PgF1BwbGkm97sarDul2CdKgyjQ1JwJHAudm5lMRsTXwkfaUJUmSmtXL81w6qczB9xYB0/rdfhR4tB1FSZIklVUmqZEkST3IpKbgzCJJklQLJjWSJFWdez8BJjWSJKkmTGokSaq4COfUgEmNJEmqCZsaSZJUCw4/SZJUcZ4moeBWkCRJtWBSI0lSxXnwvYJJjSRJqgWTGkmSqs45NYBJjSRJqgmTGkmSKs45NQWTGkmSVAsmNZIkVVyEGQWY1EiSpJowqZEkqeqcUwOY1EiSpJowqZEkqeI891PBrSBJkmrBpEaSpIrzODUFkxpJklQLNjWSJKkWHH6SJKnqPPgeYFIjSZJqwqRGkqSKc6JwwaRGkiTVgkmNJElV58H3AJMaSZJUEyY1kiRVXIRzasCkRpIk1YRJjSRJVeecGsCkRpIk1YRJjSRJFedxagomNZIkqRZMaiRJqjrP/QSY1EiSpJowqdGg9vzqWWxx1KEsffwJbtj72G6XI0kajHNqAJMavYi5l03jt8e8p9tlSJLUFJsaDWr+jdNZNv/pbpchSVJTHH6SJKniwonCQImkJiJeFhHXRcRdjdt7RsQnXmT5KRExPSKmT506tRW1SpIkDapMUvNV4CPAfwJk5h0R8W3gswMtnJlTgZXdTA6lSEmS9CKcKAyUm1OzcWb+drX7lreyGEmSpHVVpqmZFxE700hdIuLNwKNtqUo9YfI3vsirf/ldRk/aicNmX892735zt0uSJA0ghg3r6KVXlRl+ej/FcNKuEfEwMBv4P22pSj3htrd/qNslSJLUtKabmsx8AHhdRIwGhmXmgvaVJUmSmhbOqYFyez+tiIjPAYtWNjQR8bu2VSZJklRCmeGnuymaoJ9ExFsycz5gayhJUrf18DyXTiqzFZZn5ukUu3b/MiL2xV21JUlSjyiT1ARAZn4/Iu4GvgNs35aqJElS85xTA5Rralad2TAz746Ig4E3trwiSZKkdbDWpiYiDsvM/wF2iIgdVnv42faUJUmSmtXLx47ppGaSmkOA/wGOHeCxBKa1tCJJkqR1sNamJjM/1fj57vaXI0mSSvMs3UC549ScGhGbRuFrEfG7iDi8ncVJkiQ1q0xr9zeZ+QxwOLAF8G7gc22pSpIkqaTSu3QDRwGXZObtEe5DJklS1w3z6xjKJTUzIuInFE3NtRExBuhrT1mSJEnllGlqTgbOAF6ZmYuADSmGoACIiN1bXJskSWpCxLCOXtZeTxwZETMjYlZEnDHIModGxG0RcXdEXN+K7VDmLN19wO/63X4CeKLfIt8A9mlFUZIkqZoiYjjwZeD1wFzgloi4MjPv6bfM5sCFwJGZ+VBEbNGKdZeZU7M2DuhJktQNvTWnZn9gVmY+ABAR3wWOA+7pt8xfA9My8yGAzHy8FStu5Y7tntxSkqT1QERMiYjp/S5T+j08EZjT7/bcxn39vQwYGxG/iIgZEfGOVtTVyqRGkiR1Q4cPvpeZU4Gpgzw8UGy0evCxAbAv8FpgFHBzRPw6M38/lLpa2dQsbeFrSZKkapoLbNfv9rbAIwMsMy8zFwILI+IGYC+gc01NREwEduj/vMy8ofHzgKEUIkmS1lFvHTbuFmCXiNgJeBg4iWIOTX8/BL4UERtQ7E39KuDfh7rippuaiPg88BaKiT4rGncncMNQi5AkSfWQmcsj4hTgWmA4cHFm3h0R72s8flFm3hsRPwbuoDjm3dcy866hrrtMUvNGYFJmLhnqSiVJUgsN660TWmbmNcA1q9130Wq3vwB8oZXrLbMVHgBGtHLlkiRJrbLWpCYiLqAYZloE3BYR1wGr0prM/ED7ypMkSWvV4b2felUzw0/TGz9nAFe2sRZJkqR1ttamJjMvA4iI0cBzmbmicXs4sFF7y5MkSWvVW0cU7poyedV1FAfIWWkU8LPWliNJkrRuyjQ1IzPz2ZU3Gtc3bn1JkiRJ5ZXZpXthROyTmb8DiIh9gcXtKUuSJDXNicJAuabmNODyiFh5qOOtKY4SKEmS1HVlmpo7gF2BSRQnq7qP1p7lW5IkrYveOk1C15RpSm7OzGWZeVdm3pmZy4Cb21WYJElSGc0cfG8rYCIwKiL25vlTim+KE4UlSeq+HjtNQrc0M/x0BPAuilOH/1u/+xcA/9SGmiRJkkpr9uB7l0XECZn5gw7UJEmSynBODVBionBm/iAijgZ2B0b2u//MdhQmSZJURtNNTURcRDGH5i+ArwFvBn7bprokSVKzPE4NUG7vp1dn5juAJzPzM8CBwHbtKUuSJKmcMsepWXn04EURsQ3wBLBT60uSJEmluPcTUK6p+VFEbA6cA8xo3Pe1llckSZK0Dso0NecCfwe8huKge78EvtKOoqS1uXrEpG6XUBlHL5vZ7RIktZt7PwHlmprLKI5Nc37j9luBrwMntrqo9ZVfPs2xoZEkDaRMUzMpM/fqd/vnEXF7qwuSJEklufcTUG7vp1sj4oCVNyLiVcBNrS9JkiSpvGbO/XQnkMAI4B0R8VDj9g7APe0tT5IkqTnNDD8d0/YqJEnSunOiMNDcuZ/+txOFSJIkDUWZicKSJKkXefA9oNxEYUmSpJ5lUiNJUsWlc2oAkxpJklQTJjWSJFWdB98DTGokSVJNmNRIklR1JjWASY0kSaoJkxpJkirOvZ8KJjWSJKkWTGokSao659QAJjWSJKkmTGokSao659QAJjWSJKkmbGokSVItOPwkSVLVDTOjAJMaSZJUEyY1kiRVnAffK5jUSJKkWjCpkSSp6jz4HmBSI0mSasKkRpKkikuTGsCkRpIk1YRJjSRJVefeT4BJjSRJqgmTGkmSKs45NQW3giRJqgWTGkmSqs45NYBJjSRJqgmTGkmSqs45NYBJjSRJqgmbGkmSVAsOP0mSVHHpRGHApEaSJNWESY0kSVXnRGHApEYasj2/ehave/hX/PmtV3W7FElar9nUSEM097Jp/PaY93S7DEnrsSQ6eulVNjXSEM2/cTrL5j/d7TIkab3nnBpJkirOE1oWmt4KEXFARNwSEc9GxNKIWBERz7zI8lMiYnpETJ86dWprqpUkSRpEmaTmS8BJwOXAfsA7gJcOtnBmTgVWdjO5rgVKkqS1MKkBSg4/ZeasiBiemSuASyLiV22qS5IkqZQyTc2iiNgQuC0izgEeBUa3pyypOiZ/44uMP2R/NpwwlsNmX8/9Z17AnEuu6HZZktYjHlG4UKapeTswHDgF+EdgO+CEdhQlVcltb/9Qt0uQJFGiqcnM/21cXQx8pj3lSJKksnpt76eIOBI4jyIM+Vpmfm6Q5V4J/Bp4S2YOOeIus/fTMRFxa0TMj4hnImLBi+39JEmS1j8RMRz4MvCXwG7AWyNit0GW+zxwbavWXWb46T+A44E7M9O9mSRJ6hW9Nadmf2BWZj4AEBHfBY4D7lltuX8AfgC8slUrLpNXzQHusqGRJGn91v9YdI3LlH4PT6ToGVaa27iv//MnAm8CLmplXWWSmtOBayLiemDJyjsz899aWZAkSSqn03NqVjsW3eoGio1WD0T+A/hoZq6IFqZMZZqafwWeBUYCG7asAkmSVCdzKfaQXmlb4JHVltkP+G6joZkAHBURyzPz/w1lxWWamnGZefhQViZJkmrvFmCXiNgJeJjibAR/3X+BzNxp5fWIuBT40VAbGijX1PwsIg7PzJ8MdaWSJKl1csARn+7IzOURcQrFXk3DgYsz8+6IeF/j8ZbOo+kvmp33GxELKI4gvARYRjFmlpm5aRNPd3KxWubqEZO6XUKlHL1sZrdLkNZXHes05t11c0e/ZyfscWDvdFH9lDn43ph2FiJJktZNrx18r1tKndAyIvYEduz/vMyc1uKaJEmSSmu6qYmIi4E9gbuBvsbdCdjUSJLUTb118L2uKZPUHJCZaxzmWJIkqReUaWpujojdMnP1wxxLkqQuylInCKivMk3NZRSNzR8p9oBauffTnm2pTJIkqYQyTc3FwNuBO3l+To0kSeqydE4NUK6peSgzr2xbJZIkSUNQpqm5LyK+DVzFC09o6d5PkiR1kcepKZRpakZRNDP9z//kLt2SJKknlDmi8LvbWYgkSVo3vXTup24qc/C9kcDJwO7AyJX3Z+bftKEuSZKkUsoMwn0D2Ao4Arge2BZY0I6iJElS8zKGdfTSq8pU9tLM/GdgYWZeBhwNvKI9ZUmSJJVTpqlZ1vj5VETsAWxGcXJLSZKkriuz99PUiBgLfAK4EtgE+Oe2VCVJkprmwfcKZZqazYCVe0B9ufFzeURMzszbWlqVJElSSWWamn2B/SgOvgfFnJpbgPdFxOWZeU6ri5MkSWvnLt2FMk3NeGCfzHwWICI+BVwB/DkwA7CpkSRJXVOmqdkeWNrv9jJgh8xcHBFLBnmOJElqs17ezbqTyjQ13wZ+HRE/bNw+FvhORIwG7ml5ZZIkSSWUOU3Cv0TENcDBQADvy8zpjYff1o7iJEnS2jmnplAmqSEzZ1DMn5EkSeoppZoaSZLUe5xTU3ArSJKkWjCpkSSp4pxTUzCpkSRJtWBSI0lSxTmnpuBWkCRJtWBSI0lSxTmnpmBSI0mSasGkRqq5q0dM6nYJlXD0spndLqESTvzQg90uoTK+/8Udu13CesemRpXjl0/zbGik9UOGw0/g8JMkSaoJkxpJkiou06QGTGokSVJNmNRIklRxaUYBmNRIkqSaMKmRJKniPPhewaRGkiTVgkmNJEkVZ1JTMKmRJEm1YFIjSVLFmdQUTGokSVItmNRIklRxJjUFkxpJklQLJjWSJFWc534qmNRIkqRasKmRJEm14PCTJEkV50ThgkmNJEmqBZMaSZIqzqSmYFIjSZJqwaRGkqSKM6kpmNRIkqRaMKmRJKniPPhewaRGkiTVgkmNJEkV1+ecGsCkRpIk1YRJjSRJFefeTwWTGkmSVAsmNZIkVZx7PxVMaiRJUi2Y1EiSVHHOqSmY1EiSpFqwqZEkSbXg8JMkSRXnROGCSY0kSaoFkxpJkirOicIFkxpJktRSEXFkRMyMiFkRccYAj78tIu5oXH4VEXu1Yr0mNZIkVVwvzamJiOHAl4HXA3OBWyLiysy8p99is4FDMvPJiPhLYCrwqqGu26RGkiS10v7ArMx8IDOXAt8Fjuu/QGb+KjOfbNz8NbBtK1ZsUiOpI/b86llscdShLH38CW7Y+9hul6MKefcbx7H3y0exZGly4XfnMfvhpWss8w9vm8DO227E8hXJH+YsYerlT7CiD449dFNes88mAAwbBttuOYKTPzmHhYv7Ov022qrH3s1EYE6/23N58RTmZOC/W7FikxpJHTH3smn89pj3dLsMVczeu45iqwkb8IGzH2bq5U/wnhPGD7jcjTMWctrnH+bD5z7ChiOCw141BoCrfvEMp//bI5z+b4/wnWue5J4/PFe7hqYbImJKREzvd5nS/+EBnpKDvM5fUDQ1H21FXSY1kjpi/o3TGbXDxG6XoYrZb4+NuWHGQgDuf2gJo0cNY/Mxw3lqwYoXLHfrfYtXXZ/10FLGbz58jdc6aO/R3HTrwvYW3CWdnlOTmVMp5sEMZC6wXb/b2wKPrL5QROwJfA34y8x8ohV1NZXURMSwiLirFSuUJKlZ4zYbzrynlq+6/cTTyxm32ZoNy0rDh8Fr9h3Nbf2aHIANRwSTdx3Fr+9Y1LZatcotwC4RsVNEbAicBFzZf4GI2B6YBrw9M3/fqhU31dRkZh9we6OIpvSPpqZOHayZkyRpcE2PYzS854Tx3PvAEu6bveQF9++7+yhmzl5S26GnJDp6edFaMpcDpwDXAvcC38/MuyPifRHxvsZinwTGAxdGxG0RMb0V26HM8NPWwN0R8VtgVX6XmW8YaOHVoqkX+z8oSdIqRxw0htc25sT8Yc4SJmy+ATMpmpTxm23Ak0+vGPB5bz58MzbdZDhTL318jccOmjyaG2s69NSLMvMa4JrV7ruo3/X3AC2fZFemqflMq1cuSdLqrr1pAdfetACAvV8+iiMPGsNNty5kl+03YtFzfWvMpwE47FWbsNekUZz5lcfI1f6MHjUy2G3nkVzw7XmdKL8reuk4Nd3UdFOTmde3sxBJ9Tb5G19k/CH7s+GEsRw2+3ruP/MC5lxyRbfLUo+79d7F7PPyUZz/sYksXVbs0r3SGe/Zgv/8/hM8+cwK/vaE8fzpyeX86we2BuA3dy7kBz99GoD9XzGa22c+x5KlDhrUXeTqLe3qC0QsYODhowAyMzdtYj3+T5K64OoRk7pdQmUcvWxmt0uohBM/9GC3S6iM739xx47FJzfes7Cj37MH7za6J6OhtSY1mTmmE4VIkiQNhQffkyRJteDB9yRJqrg+J3kAJjWSJKkmTGokSaq4tR0Qb31hUiNJkmrBpEaSpIrz4HsFkxpJklQLJjWSJFXcWo6ju94wqZEkSbVgUiNJUsX1ufcTYFIjSZJqwqRGkqSKc++ngkmNJEmqBZMaSZIqzr2fCiY1kiSpFkxqJEmqOM/9VDCpkSRJtWBTI0mSasHhJ0mSKq7PicKASY0kSaoJkxpJkirOg+8VTGokSVItmNRIklRxHnyvYFIjSZJqwaRGkqSK6/Pge4BJjSRJqgmTGkmSKs45NQWTGkmSVAsmNZIkVZzHqSmY1EiSpFowqZEkqeI891PBpEaSJNWCSY0kSRXn3k8FkxpJklQLNjWSJKkWHH6SJKni0tMkACY1kiSpJkxqJEmqOHfpLpjUSJKkWjCpkSTg6hGTul1CJfz9rbd1uwQNwF26CzY1Uo0dvWxmt0uoBBsaqR5saiRJqjiTmoJzaiRJUi2Y1EiSVHF96XFqwKRGkiTVhEmNJEkV55yagkmNJEmqBZMaSZIqzqSmYFIjSZJqwaRGkqSK89xPBZMaSZJUCzY1kiSpFhx+kiSp4tKD7wEmNZIkqSZMaiRJqjh36S6Y1EiSpFowqZEkqeLcpbtgUiNJkmrBpEaSpIpzTk3BpEaSJNWCSY0kSRVnUlMwqZEkSbVgUiNJUsW591PBpEaSJNWCSY0kSRXnnJqCSY0kSaoFmxpJkiqur6+zl7WJiCMjYmZEzIqIMwZ4PCLi/Mbjd0TEPq3YDjY1kiSpZSJiOPBl4C+B3YC3RsRuqy32l8AujcsU4CutWLdNjSRJaqX9gVmZ+UBmLgW+Cxy32jLHAV/Pwq+BzSNi66Gu2KZGkqSKy+zsJSKmRMT0fpcp/cqZCMzpd3tu4z5KLlOaez9JkqRSMnMqMHWQh2Ogp6zDMqXZ1EiSVHE9tkv3XGC7fre3BR5Zh2VKc/hJkiS10i3ALhGxU0RsCJwEXLnaMlcC72jsBXUA8HRmPjrUFZvUSJJUcb10moTMXB4RpwDXAsOBizPz7oh4X+Pxi4BrgKOAWcAi4N2tWLdNjSRJaqnMvIaicel/30X9rifw/lav16ZGkqSKy45Pqhlonm/3OadGkiTVgkmNJEkV12N7P3WNSY0kSaoFkxpJkiqumZNMrg9MaiRJUi2Y1EhSj9nzq2exxVGHsvTxJ7hh72O7XU5X3XXrTXz/4nPo6+vj4Ne+iSOP/5sXPP7HubO59MufYs4D93LcX5/C4ce9c9VjixY+wzcuPJOHH5pFRPCO93+anSft1em30BHOqSnY1EhSj5l72TQevPCbTL74890upav6VqzgO189m9M+eRFjx2/J2R99G3u+8hC22W7nVctsPGYzTjr5dG77zc/XeP73Lj6H3fd+Ne/9yLksX7aMpUsXd7J8dYHDT5LUY+bfOJ1l85/udhldN3vWXWyx1Xa8ZKtt2WDECPY7+Ahuv+UXL1hm083GseNL92D4Bi/8G33xome5/57fcdBr3wTABiNGsPHoTTtVesf1ZWcvvarppiYi/iwiroqIeRHxeET8MCL+rJ3FSZLWX0/Nf5yxE7ZadXvsuC156onHm3ruvMfmMmbTsVz2pU/y2Q+/ha9f+BmWPGdSU3dlkppvA98HtgK2AS4HvjPYwhExJSKmR8T0qVMHOzu5JEmDGGiiSDR3JNsVK1bw0AP3ccgRJ/KJc7/HRhuN5Mf/9+IWF9g7Mjt76VVl5tREZn6j3+1vNk5YNaDMnAqs7GZ6eBNIknrR5uO35Ml5f1x1+8n5j7H5uJc09dyx47dk7Pgt2OllrwBgnwNfX+umRoUySc3PI+KMiNgxInaIiNOBqyNiXESMa1eBkqT1044v3Z3HH32IeY89zPJly5h+47Xstd8hTT13s7ETGDthK/748IMA3Hfnb9h6W2dM1F00exKsiJj9Ig9nZr7Y/xaTGkk96+oRk7pdwgtM/sYXGX/I/mw4YSxLHnuC+8+8gDmXXNHtsgAYfettHV3fnTN+yfcv+QJ9fX0cdNhxHPXmv+X6ay8H4JAj/oqnn5zHWaf/Nc8tXkhEsNHIjfn0edMYtfEmzJl9H1//ypmsWLaMCVtO5J2nnMnoTTo3WfjQPUZ17KyP507r7PTdDx8/rCfPaNl0UzNENjWSelavNTW9rNNNTZXZ1HRe03NqImJj4IPA9pk5JSJ2ASZl5o/aVp0kSVqrXt7NupPKzKm5BFgKvLpxey7w2ZZXJEmStA7KNDU7Z+Y5wDKAzFwM9GT8JEnS+sRdugtlmpqlETGKxvyYiNgZWNKWqiRJkkoqc5yaTwM/BraLiG8BBwHvbkdRkiSpeX1OqgFKNDWZ+ZOImAEcQDHsdGpmzmtbZZIkSSWU2fvpusx8LXD1APdJkqQu6eV5Lp201qYmIkYCGwMTImIsz08O3pTiHFCSJEld10xS817gNIoGZgZFU5PAAuBLbatMkiQ1xaSmsNa9nzLzvMzcCfhXYHLj+iXAA8DNba5PkiSpKWV26X5zZj4TEQcDrwcuBb7SlqokSVLT+jI7eulVZZqaFY2fRwMXZeYPgQ1bX5IkSVJ5ZY5T83BE/CfwOuDzEbER5ZoiSZLUBtnX7Qp6Q5mm5ETgWuDIzHwKGAd8pB1FSZIklVXm4HuLgGn9bj8KPNqOoiRJksoqM/wkSZJ6UPbw5N1Ock6MJEmqBZMaSZIqrs+JwoBJjSRJqgmTGkmSKs45NQWTGkmSVAsmNZIkVVyfQQ1gUiNJkmrCpEaSpIpLoxrApEaSJNWESY0kSRXnzk8FkxpJklQLJjWSJFVcn3NqAJMaSZJUEyY1kiRVnEcULpjUSJKkWrCpkSRJteDwkyRJFZd93a6gN5jUSJKkWjCpkSSp4vqcKAyY1EiSpJowqZEkqeLcpbtgUiNJkmrBpEaSpIrzNAkFkxpJklQLHUlqDj72+k6sphZuvOqQbpegGjnxQw92u4RK+Ptbb+t2CZWxcO/J3S6hOpbN7NiqnFJTMKmRJEm14JwaSZIqLp1TA5jUSJKkmjCpkSSp4jyicMGkRpIk1YJJjSRJFeecmoJJjSRJqgWbGkmSVAsOP0mSVHEOPxVMaiRJUi2Y1EiSVHEGNQWTGkmSVAsmNZIkVZxzagomNZIkqWMiYlxE/DQi7m/8HDvAMttFxM8j4t6IuDsiTm3mtW1qJEmquMzs6GWIzgCuy8xdgOsat1e3HPhQZr4cOAB4f0TstrYXtqmRJEmddBxwWeP6ZcAbV18gMx/NzN81ri8A7gUmru2FnVMjSVLF9XV4Tk1ETAGm9LtramZObfLpW2bmo1A0LxGxxVrWtSOwN/Cbtb2wTY0kSSql0cAM2sRExM+ArQZ46ONl1hMRmwA/AE7LzGfWtrxNjSRJFdeCeS4tlZmvG+yxiHgsIrZupDRbA48PstwIiobmW5k5rZn1OqdGkiR10pXAOxvX3wn8cPUFIiKA/wLuzcx/a/aFbWokSaq47MuOXoboc8DrI+J+4PWN20TENhFxTWOZg4C3A4dFxG2Ny1Fre2GHnyRJUsdk5hPAawe4/xHgqMb1G4Eo+9o2NZIkVZxHFC44/CRJkmrBpkaSJNWCw0+SJFVcX4/t0t0tJjWSJKkWTGokSao4JwoXTGokSVItmNRIklRxvXaahG4xqZEkSbVgUiNJUsX1OacGMKmRJEk1YVIjSVLFufdTwaRGkiTVgkmNJEkV595PBZMaSZJUCyY1kiRVXPb1dbuEnmBSI0mSasGkRpKkivM4NYXaNjWnTtmZA/cdz3NLVnDWeTP5/R+eXWOZM/7hZey6yxgA5jyymLP+4z4WP9fHmNEb8LFTJ7HNViNZuqyPs8+byeyHFnX6LUiV9O43jmPvl49iydLkwu/OY/bDS9dY5h/eNoGdt92I5SuSP8xZwtTLn2BFHxx76Ka8Zp9NABg2DLbdcgQnf3IOCxfXK1q/69ab+P7F59DX18fBr30TRx7/Ny94/I9zZ3Pplz/FnAfu5bi/PoXDj3vnqscWLXyGb1x4Jg8/NIuI4B3v/zQ7T9qr02+hJ+z51bPY4qhDWfr4E9yw97HdLkc9oJZNzQH7jmO7bTbmpPf+lt0njeHDf7cLUz586xrLnf+1P7Bo8QoATjl5Z044ZiLfvGIObz9xe+5/4Fn+6ay72X7bUXzwfbtw2ifu6PTbkCpn711HsdWEDfjA2Q+zy/Yb8Z4TxvPx8x9dY7kbZyzkgm/NA+DU/zOBw141hp/evICrfvEMV/3iGQD23W0UR//5prVraPpWrOA7Xz2b0z55EWPHb8nZH30be77yELbZbudVy2w8ZjNOOvl0bvvNz9d4/vcuPofd93417/3IuSxftoylSxd3svyeMveyaTx44TeZfPHnu12KekQt59S85oDx/Ph//gjA3TMXsMnoDRg/dsM1llvZ0ABstOEwVu4Rt+N2GzPjjicBeGjuYrbeYiRjNx/R/sKlittvj425YcZCAO5/aAmjRw1j8zHD11ju1vue/yKe9dBSxm++5jIH7T2am25d2L5iu2T2rLvYYqvteMlW27LBiBHsd/AR3H7LL16wzKabjWPHl+7B8A1e+Hfn4kXPcv89v+Og174JgA1GjGDj0Zt2qvSeM//G6Syb/3S3y+gJmdnRS6+qZVMzYfxGPD5vyarbjz+xhAnj12xqAD526iSu/PqB7LDtxlzxo4cBmDV7IX9+4EsAePkuY9hyi5FsMX6j9hcuVdy4zYYz76nlq24/8fRyxm22ZsOy0vBh8Jp9R3PbfS9MGzYcEUzedRS/vqN+w75PzX+csRO2WnV77LgteeqJx5t67rzH5jJm07Fc9qVP8tkPv4WvX/gZljy3/iY10uqabmoiYnhEvCEiPhARH1x5aWdx6yoGunOQxvLs82byxnfdzP/OXchrDy4amW9e8RBjNtmAS87blxOOncj9DyxgxYre7UylXjHQZ+/FPjnvOWE89z6whPtmL3nB/fvuPoqZs5fUbugJgIH+yo0Bf2utYcWKFTz0wH0ccsSJfOLc77HRRiP58f+9uMUFqoqyLzt66VVl5tRcBTwH3Ams9TdNREwBpgDs/IoPsdUO7Z3EdfxR23DsEVsDcO/9C9hiwvPJyhbjN2Le/DUnK67U1wfX/fJPvPX47bjmusdYtHgFZ583c9Xjl3/tVTzy2HPtK16qsCMOGsNrX1VMuP/DnCVM2HwDZlI0KeM324Ann14x4PPefPhmbLrJcKZeumZKcdDk0dxYw6EngM3Hb8mT8/646vaT8x9j83Evaeq5Y8dvydjxW7DTy14BwD4Hvt6mRuqnTFOzbWbu2ezCmTkVmApw8LHXt72tm3bNI0y75hEADtxvHCccM5Gf3fAndp80hmcXLeeJJ9dsaiZuPZKHHy2alYP2H89Dc4uoe5PRw3luSR/LlyfHHr4Vt9/91Avm30h63rU3LeDamxYAsPfLR3HkQWO46daF7LL9Rix6ro+nFqz52TnsVZuw16RRnPmVx9YILkaNDHbbeSQXfHteJ8rvuB1fujuPP/oQ8x57mM3HbcH0G6/l5NPOauq5m42dwNgJW/HHhx9kq4k7ct+dv2Hrbf+szRWrCno5PemkMk3Nf0fE4Zn5k7ZV0yI3T5/PgfuN43tT91+1S/dKX/jUHnzugt8z/8mlfPy0XRm98XAiglmzn+XcC+8HYIdtR/OJD06irw8efGghnzv/9916K1Kl3HrvYvZ5+SjO/9hEli4rdule6Yz3bMF/fv8JnnxmBX97wnj+9ORy/vUDRbr6mzsX8oOfFhM+93/FaG6f+RxLltbzl/Tw4Rtw0nvO4Lx/+Tv6+vo46LDj2Gb7l3L9tZcDcMgRf8XTT87jrNP/mucWLyQiuO5H3+LT501j1MabcNLJH+W/zvsnVixbxoQtJ/LOU87s8jvqnsnf+CLjD9mfDSeM5bDZ13P/mRcw55Irul2WuiiancUcEW8CvkkxD2cZxfB5ZuZap953IqmpixuvOqTbJahGTvzQg90uoRL+/t1bdruEyli49+Rul1AZRy+b2dxkqRY4/gOzOvo9O+38l3bsvZVRJqn5InAgcGf28v5ckiRpvVSmqbkfuMuGRpKk3uKcmkKZpuZR4BcR8d/Aqv0vM/PfWl6VJElSSWWamtmNy4aNiyRJ6gEmNYWmm5rM/Ew7C5EkSRqKppuaiPg5AxwcNDMPa2lFkiSpFKe7FsoMP3243/WRwAnA8kGWlSRJ6qgyw08zVrvrpoi4vsX1SJKkkvr6anietHVQZvhpXL+bw4D9gK0GWVySJKmjygw/zaCYUxMURxR+EDi5DTVJkiSVVqap+Sjw48x8JiL+GdgHWNSesiRJUrPcpbswrMSyn2g0NAcDrwcuBb7SlqokSZJKKtPUrGj8PBq4KDN/iAfhkySp6zL7OnrpVWWamocj4j+BE4FrImKjks+XJElqmzJzak4EjgTOzcynImJr4CPtKUuSJDXLOTWFMsepWQRM63f7UYqTXEqSJHVdmaRGkiT1IJOagnNiJElSLZjUSJJUcX09vEdSJ5nUSJKkWjCpkSSp4pxTUzCpkSRJtWBSI0lSxWWfc2rApEaSJNWESY0kSRXnnJqCSY0kSaoFmxpJklQLDj9JklRx6cH3AJMaSZJUEyY1kiRVXJ8ThQGTGkmSVBMmNZIkVZwH3yuY1EiSpFowqZEkqeI8+F7BpEaSJNWCSY0kSRXncWoKJjWSJKkWTGokSao459QUTGokSVItmNRIklRxHqemYFIjSZJqITLXz3G4iJiSmVO7XUcVuK2a43ZqntuqOW6n5ridtNL6nNRM6XYBFeK2ao7bqXluq+a4nZrjdhKwfjc1kiSpRmxqJElSLazPTY3jr81zWzXH7dQ8t1Vz3E7NcTsJWI8nCkuSpHpZn5MaSZJUIzY1kiSpFmxqJHVERDzb7Rp6WUScFhEbd7sOqcoq1dS040MfEW+MiN3W4XlviIgzWlnLOtSwY0TcVWL5d0XENk0s86Uh1nVmRLxuKK+h9UNEDO92DT3kNMCmRhqCSjU1tOdD/0ZgwKYmIgY9N1ZmXpmZn2txLe32LuBFm5pWyMxPZubP2r2eVoqIf46I+yLipxHxnYj4cET8bUTcEhG3R8QPVjbUEXFpRHwlIn4eEQ9ExCERcXFE3BsRl/Z7zWcj4vMRMSMifhYR+0fELxrPeUNjmR0j4pcR8bvG5dVd2gQdExGHNrbdt4E7u11PN0TE6Ii4uvF/666I+BTFZ/PnEfHzxjKHR8TNjf8Xl0fEJo37H2z8v/pt4/LSbr6XdhpgO72l8f4nNB7fLyJ+0bj+6Yi4LCJ+0ljm+Ig4JyLujIgfR8SIrr4ZdUTPNjWd+NA3vkDeAHwhIm6LiJ0bXzpnRcT1wKkRcWxE/CYibm18MW3ZeO6qRKPxJXd+RPyq8YX15g5sopU2aHyQ74iIKyJi44j4ZOPL+K6ImBqFNwP7Ad9qvNdREfHKRs23N7bTmMZrbtP4JXB/RJwz2IojYnjjvd/V+MXxj437L42INzd+4dzWuNwZEdl4fOfG689ofKHv2vat9CIiYj/gBGBv4HiK7QQwLTNfmZl7AfcCJ/d72ljgMOAfgauAfwd2B14REZMby4wGfpGZ+wILgM8CrwfeBJzZWOZx4PWZuQ/wFuD8drzHHrQ/8PHMLJ2S1sSRwCOZuVdm7gH8B/AI8BeZ+ReNL+1PAK9r/N+YDnyw3/Ofycz9gS81nltXq2+nH69l+Z2Bo4HjgG8CP8/MVwCLG/er5nq2qaEDH/rM/BVwJfCRzJycmX9oPLR5Zh6SmV8EbgQOyMy9ge8Cpw9S79bAwcAxQCcTnEnA1MzcE3gG+HvgS40v4z2AUcAxmXkFxTZ6W2ZOBlYA3wNObXxpv47igw8wmeIL9hXAWyJiu0HWPRmYmJl7NH5xXNL/wcyc3tiukyl+GZ3beGgq8A+NL/sPAxcObRMM2cHADzNzcWYuoGhSAPZoNF13Am+jaFpWuiqL4yHcCTyWmXdmZh9wN7BjY5mlPP9L+E7g+sxc1ri+cpkRwFcb67icQVLDGvptZs7udhFddCfwusYfX6/JzKdXe/wAiv8LN0XEbcA7gR36Pf6dfj8PbHexXbS27bS6/+73GRvOCz9/O7avTPWKQYdXesCdwLkR8XngR5n5y4jo/3j/Dz3AhsDN/R7v/6H/95Lr/l6/69sC34uIrRvrGOwX8f9rfKndszLN6ZA5mXlT4/o3gQ8AsyPidIqhunEUX7RXrfa8ScCjmXkLQGY+A9DYltet/OUREfdQ/DKdM8C6HwD+LCIuAK4GfjJQgRFxIrAPcHgjTXs1cHm/f8+NSr7nVotB7r8UeGNm3h4R7wIO7ffYksbPvn7XV95e+blals8fCGrVcpnZF88Pbf4j8BiwF8UfGc+t87uoloXdLqCbMvP3EbEvcBRwdkSs/tkJ4KeZ+dbBXmKQ67UyyHZazvN/kI9c7Sn9P2Orf/56+ftOLdKzSU1m/h7Yl6K5OTsiPrnaIis/9JMbl90ys//wwFA+9P1/4V5AkXy8Angva36IVur/xTbYl2Q7rP7ekiL5eHOj5q8ycM0xwHNX6v9eVjDIL4PMfJLiy/gXwPuBr62xkojdgc8AJ2XmCor/c0/1+3ebnJkvH6SOTrkRODYiRjaarpUx9Rjg0cZY/NvatO7NKJrLPuDtFH9dquaimLC/KDO/SZFg7kMxRLlyCPjXwEErh84bw8ov6/cSb+n3s/8fc7UyyHZ6kOK7AYphY2mVnm1qOvih7/+aA9kMeLhx/Z2l3kRnbB8RK+Pnt1J8QQPMa3xB95/f0/+93kcxd+aVABExJl5kYvRAGkOAwzLzB8A/U/wb9X98M4ohu3dk5p9gVSI0OyL+qrFMRMReZdbbao206krgdmAaxTDd0xTv6TfATym2VztcCLwzIn4NvIz1PMFYj7wC+G1jaOnjFPOtpgL/HRE/b3xe3gV8JyLuoPh913/u2UYR8RvgVIq0r64G2k6fAc6LiF9S/NElrdKzp0mIiCOAL1DEhsuAv6MYO34/xV+2fxERhwGf5/nhi09k5pUR8SDF/I6jKBq3t2bmrEHWcxBFmrGEogH4L+DDmTm98fhxFMNXD1P8YnllZh7aGI7YLzNPiWKPlx815q0QEc9m5iat3B6D1L4jcA1wA8WQzv0Uf+3/E3ASxV80c4D/zcxPR8QJwFkUc2cOBPagSKJGNe57HcU22C8zT2ms40fAuZn5iwHWvxfFdl7ZHH8sM/975fagmCh7AcUwFQCZOTkidgK+QjEPaQTw3cw8ky6KiE0y89ko9nC6AZiSmb/rZk3SQBq/3/bLzHndrkXqNT3b1AyFH3qVFcXuxbtRDNVdlplnd7kkaUD+fpMGZ1MjSZJqoZZNzUAi4uPAX6129+WZ+a/dqKdqGuP3q++l9PbMXC8PniZJ6j3rTVMjSZLqrWf3fpIkSSrDpkaSJNWCTY0kSaoFmxpJklQL/x9GY3OfJz7iYAAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] @@ -4093,28 +4324,12 @@ ], "source": [ "fig, ax = plt.subplots(figsize=(10,10)) \n", - "sns.heatmap(df_DoubleDQN.corr()[df_DoubleDQN.corr() > 0.05], annot = True, fmt='.2g',cmap= 'coolwarm', ax=ax)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### DuelingDQN" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [], - "source": [ - "df_DuelingDQN = df[df[\"algo\"] == \"DuelingDQN\"].copy()" + "sns.heatmap(df_DQN.corr()[abs(df_DQN.corr()) > 0.05], annot = True, fmt='.2g',cmap= 'coolwarm', ax=ax)" ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 28, "metadata": {}, "outputs": [ { @@ -4138,186 +4353,373 @@ " \n", " \n", " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " step\n", + " sum\n", + " \n", + " \n", + " algo\n", " step_train\n", " batch_size\n", " gamma\n", + " greedy_exploration\n", + " network\n", + " optimizer\n", " lr\n", - " step\n", - " max\n", - " min\n", - " avg\n", - " sum\n", + " memories\n", + " max_size\n", + " \n", + " \n", + " \n", " \n", " \n", " \n", " \n", - " step_train\n", - " 1.000000e+00\n", - " 6.254152e-18\n", - " -3.338836e-15\n", - " -1.947613e-17\n", - " 5.190625e-20\n", - " NaN\n", - " NaN\n", - " NaN\n", - " -2.254267e-01\n", + " DoubleDQN\n", + " 1.0\n", + " 64.0\n", + " 0.99\n", + " EpsilonGreedy-0.1\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " 32.0\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " 64.0\n", + " 1.00\n", + " EpsilonGreedy-0.6\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 3\n", + " 3\n", + " 3\n", + " \n", + " \n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.1000\n", + " ExperienceReplay\n", + " 2048\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " EpsilonGreedy-0.6\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " batch_size\n", - " 6.254152e-18\n", - " 1.000000e+00\n", - " -5.096548e-15\n", - " 1.309431e-16\n", - " 0.000000e+00\n", - " NaN\n", - " NaN\n", - " NaN\n", - " 1.375869e-01\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " gamma\n", - " -3.338836e-15\n", - " -5.096548e-15\n", - " 1.000000e+00\n", - " 1.070395e-14\n", - " -1.030754e-16\n", - " NaN\n", - " NaN\n", - " NaN\n", - " -4.766649e-16\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.1000\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " lr\n", - " -1.947613e-17\n", - " 1.309431e-16\n", - " 1.070395e-14\n", - " 1.000000e+00\n", - " -3.622535e-19\n", - " NaN\n", - " NaN\n", - " NaN\n", - " -2.261230e-01\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " step\n", - " 5.190625e-20\n", - " 0.000000e+00\n", - " -1.030754e-16\n", - " -3.622535e-19\n", - " 1.000000e+00\n", - " NaN\n", - " NaN\n", - " NaN\n", - " 2.421773e-01\n", + " 32.0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " max\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", + " 64.0\n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.1000\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " min\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", + " 32.0\n", + " 0.95\n", + " EpsilonGreedy-0.6\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " avg\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.1000\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " sum\n", - " -2.254267e-01\n", - " 1.375869e-01\n", - " -4.766649e-16\n", - " -2.261230e-01\n", - " 2.421773e-01\n", - " NaN\n", - " NaN\n", - " NaN\n", - " 1.000000e+00\n", + " EpsilonGreedy-0.1\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " EpsilonGreedy-0.6\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 0.99\n", + " EpsilonGreedy-0.1\n", + " SimpleNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 32.0\n", + " 64.0\n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleNetwork\n", + " Adam\n", + " 0.1000\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", "\n", "" ], "text/plain": [ - " step_train batch_size gamma lr \\\n", - "step_train 1.000000e+00 6.254152e-18 -3.338836e-15 -1.947613e-17 \n", - "batch_size 6.254152e-18 1.000000e+00 -5.096548e-15 1.309431e-16 \n", - "gamma -3.338836e-15 -5.096548e-15 1.000000e+00 1.070395e-14 \n", - "lr -1.947613e-17 1.309431e-16 1.070395e-14 1.000000e+00 \n", - "step 5.190625e-20 0.000000e+00 -1.030754e-16 -3.622535e-19 \n", - "max NaN NaN NaN NaN \n", - "min NaN NaN NaN NaN \n", - "avg NaN NaN NaN NaN \n", - "sum -2.254267e-01 1.375869e-01 -4.766649e-16 -2.261230e-01 \n", + " \\\n", + "algo step_train batch_size gamma greedy_exploration network optimizer lr memories max_size \n", + "DoubleDQN 1.0 64.0 0.99 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 32.0 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 64.0 1.00 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 3 \n", + " 0.0001 ExperienceReplay 512 2 \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 2048 2 \n", + " 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 2 \n", + " EpsilonGreedy-0.6 SimpleNetwork Adam 0.0001 ExperienceReplay 2048 2 \n", + " 0.0010 ExperienceReplay 512 2 \n", + " 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 512 1 \n", + " 0.0010 ExperienceReplay 2048 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 64.0 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 2048 1 \n", + " 32.0 0.95 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 512 1 \n", + " EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " EpsilonGreedy-0.6 SimpleNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 0.99 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 32.0 64.0 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 2048 1 \n", + "\n", + " step \\\n", + "algo step_train batch_size gamma greedy_exploration network optimizer lr memories max_size \n", + "DoubleDQN 1.0 64.0 0.99 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 32.0 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 64.0 1.00 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 3 \n", + " 0.0001 ExperienceReplay 512 2 \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 2048 2 \n", + " 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 2 \n", + " EpsilonGreedy-0.6 SimpleNetwork Adam 0.0001 ExperienceReplay 2048 2 \n", + " 0.0010 ExperienceReplay 512 2 \n", + " 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 512 1 \n", + " 0.0010 ExperienceReplay 2048 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 64.0 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 2048 1 \n", + " 32.0 0.95 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 512 1 \n", + " EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " EpsilonGreedy-0.6 SimpleNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 0.99 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 32.0 64.0 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 2048 1 \n", "\n", - " step max min avg sum \n", - "step_train 5.190625e-20 NaN NaN NaN -2.254267e-01 \n", - "batch_size 0.000000e+00 NaN NaN NaN 1.375869e-01 \n", - "gamma -1.030754e-16 NaN NaN NaN -4.766649e-16 \n", - "lr -3.622535e-19 NaN NaN NaN -2.261230e-01 \n", - "step 1.000000e+00 NaN NaN NaN 2.421773e-01 \n", - "max NaN NaN NaN NaN NaN \n", - "min NaN NaN NaN NaN NaN \n", - "avg NaN NaN NaN NaN NaN \n", - "sum 2.421773e-01 NaN NaN NaN 1.000000e+00 " + " sum \n", + "algo step_train batch_size gamma greedy_exploration network optimizer lr memories max_size \n", + "DoubleDQN 1.0 64.0 0.99 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 32.0 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 4 \n", + " 64.0 1.00 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 3 \n", + " 0.0001 ExperienceReplay 512 2 \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 2048 2 \n", + " 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 2 \n", + " EpsilonGreedy-0.6 SimpleNetwork Adam 0.0001 ExperienceReplay 2048 2 \n", + " 0.0010 ExperienceReplay 512 2 \n", + " 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 512 1 \n", + " 0.0010 ExperienceReplay 2048 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 64.0 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 2048 1 \n", + " 32.0 0.95 EpsilonGreedy-0.6 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 512 1 \n", + " EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " EpsilonGreedy-0.6 SimpleNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 0.99 EpsilonGreedy-0.1 SimpleNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 32.0 64.0 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleNetwork Adam 0.1000 ExperienceReplay 2048 1 " ] }, - "execution_count": 25, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "df_DuelingDQN.corr()" + "columns = [\"algo\",\"step_train\",\"batch_size\",\"gamma\",\"greedy_exploration\",\"network\",\"optimizer\",\"lr\",\"memories\",\"max_size\"]\n", + "df_DoubleDQN[df_DoubleDQN[\"sum\"] >= 500].groupby(by=columns, observed=True).count().sort_values(by=['sum'], ascending=False)" ] }, { - "cell_type": "code", - "execution_count": 26, + "cell_type": "markdown", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(500.0, 8.0)" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "max(df_DuelingDQN[\"sum\"]), min(df_DuelingDQN[\"sum\"])" + "#### DuelingNetwork" ] }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "df_DoubleDQN = df[df[\"algo\"] == \"DoubleDQN\"].copy()\n", + "df_DoubleDQN = df_DoubleDQN[df_DoubleDQN[\"network\"] == \"SimpleDuelingNetwork\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 30, "metadata": {}, "outputs": [ { @@ -4353,392 +4755,169 @@ " memories\n", " max_size\n", " step\n", - " max\n", - " min\n", - " avg\n", " sum\n", " \n", " \n", " \n", " \n", - " 6173\n", - " DuelingDQN\n", - " 4.0\n", - " 32.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", - " SimpleDuelingNetwork\n", - " \n", - " Adam\n", - " 0.0001\n", - " ExperienceReplay\n", - " 16\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 500.0\n", - " \n", - " \n", - " 6448\n", - " DuelingDQN\n", - " 4.0\n", - " 64.0\n", - " 0.99\n", - " EpsilonGreedy-0.6\n", - " SimpleDuelingNetwork\n", - " \n", - " Adam\n", - " 0.0001\n", - " ExperienceReplay\n", - " 32\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 500.0\n", - " \n", - " \n", - " 5087\n", - " DuelingDQN\n", + " 12340\n", + " DoubleDQN\n", " 1.0\n", " 32.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", - " SimpleDuelingNetwork\n", - " \n", - " Adam\n", - " 0.0001\n", - " ExperienceReplay\n", - " 128\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 421.0\n", - " \n", - " \n", - " 6354\n", - " DuelingDQN\n", - " 4.0\n", - " 64.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", - " SimpleDuelingNetwork\n", - " \n", - " Adam\n", - " 0.0001\n", - " ExperienceReplay\n", - " 16\n", - " 500.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 386.0\n", - " \n", - " \n", - " 4932\n", - " DuelingDQN\n", - " 1.0\n", - " 1.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", " SimpleDuelingNetwork\n", " \n", " Adam\n", " 0.0010\n", " ExperienceReplay\n", - " 32\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 379.0\n", - " \n", - " \n", - " 4918\n", - " DuelingDQN\n", - " 1.0\n", - " 1.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", - " SimpleDuelingNetwork\n", - " \n", - " Adam\n", - " 0.0001\n", - " ExperienceReplay\n", - " 32\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 376.0\n", - " \n", - " \n", - " 5274\n", - " DuelingDQN\n", - " 1.0\n", - " 64.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", - " SimpleDuelingNetwork\n", - " \n", - " Adam\n", - " 0.0001\n", - " ExperienceReplay\n", - " 16\n", + " 2048\n", + " 20.0\n", " 500.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 372.0\n", " \n", " \n", - " 6449\n", - " DuelingDQN\n", - " 4.0\n", + " 17645\n", + " DoubleDQN\n", + " 1.0\n", " 64.0\n", - " 0.99\n", + " 1.00\n", " EpsilonGreedy-0.6\n", " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0001\n", + " 0.1000\n", " ExperienceReplay\n", - " 32\n", + " 512\n", + " 60.0\n", " 500.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 337.0\n", - " \n", - " \n", - " 5017\n", - " DuelingDQN\n", - " 1.0\n", - " 1.0\n", - " 0.99\n", - " EpsilonGreedy-0.6\n", - " SimpleDuelingNetwork\n", - " \n", - " Adam\n", - " 0.0010\n", - " ExperienceReplay\n", - " 16\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 335.0\n", " \n", " \n", - " 5358\n", - " DuelingDQN\n", + " 13775\n", + " DoubleDQN\n", " 1.0\n", " 64.0\n", - " 0.99\n", - " EpsilonGreedy-0.6\n", - " SimpleDuelingNetwork\n", - " \n", - " Adam\n", - " 0.0001\n", - " ExperienceReplay\n", - " 128\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 330.0\n", - " \n", - " \n", - " 5187\n", - " DuelingDQN\n", - " 1.0\n", - " 32.0\n", - " 0.99\n", - " EpsilonGreedy-0.6\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", " SimpleDuelingNetwork\n", " \n", " Adam\n", " 0.0001\n", " ExperienceReplay\n", - " 32\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 329.0\n", + " 2048\n", + " 110.0\n", + " 500.0\n", " \n", " \n", - " 5088\n", - " DuelingDQN\n", + " 9747\n", + " DoubleDQN\n", " 1.0\n", " 32.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", + " 0.95\n", + " EpsilonGreedy-0.1\n", " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0001\n", + " 0.0010\n", " ExperienceReplay\n", - " 128\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 328.0\n", + " 2048\n", + " 130.0\n", + " 500.0\n", " \n", " \n", - " 5094\n", - " DuelingDQN\n", + " 12320\n", + " DoubleDQN\n", " 1.0\n", " 32.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", " SimpleDuelingNetwork\n", " \n", " Adam\n", " 0.0001\n", " ExperienceReplay\n", - " 16\n", + " 512\n", + " 130.0\n", " 500.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 317.0\n", " \n", " \n", - " 5177\n", - " DuelingDQN\n", + " 13777\n", + " DoubleDQN\n", " 1.0\n", - " 32.0\n", - " 0.99\n", - " EpsilonGreedy-0.6\n", + " 64.0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", " SimpleDuelingNetwork\n", " \n", " Adam\n", " 0.0001\n", " ExperienceReplay\n", - " 128\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 307.0\n", + " 2048\n", + " 130.0\n", + " 500.0\n", " \n", " \n", - " 5179\n", - " DuelingDQN\n", + " 12321\n", + " DoubleDQN\n", " 1.0\n", " 32.0\n", - " 0.99\n", - " EpsilonGreedy-0.6\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", " SimpleDuelingNetwork\n", " \n", " Adam\n", " 0.0001\n", " ExperienceReplay\n", - " 128\n", + " 512\n", + " 140.0\n", " 500.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 299.0\n", - " \n", - " \n", - " 6138\n", - " DuelingDQN\n", - " 4.0\n", - " 32.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", - " SimpleDuelingNetwork\n", - " \n", - " Adam\n", - " 0.0010\n", - " ExperienceReplay\n", - " 128\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 291.0\n", " \n", " \n", - " 6188\n", - " DuelingDQN\n", - " 4.0\n", - " 32.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", - " SimpleDuelingNetwork\n", - " \n", - " Adam\n", - " 0.0010\n", - " ExperienceReplay\n", - " 16\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", + " 14522\n", + " DoubleDQN\n", " 1.0\n", - " 278.0\n", - " \n", - " \n", - " 6374\n", - " DuelingDQN\n", - " 4.0\n", " 64.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", + " 0.95\n", + " EpsilonGreedy-0.6\n", " SimpleDuelingNetwork\n", " \n", " Adam\n", - " 0.0010\n", + " 0.0001\n", " ExperienceReplay\n", - " 32\n", + " 2048\n", + " 140.0\n", " 500.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 273.0\n", " \n", " \n", - " 5364\n", - " DuelingDQN\n", + " 16785\n", + " DoubleDQN\n", " 1.0\n", " 64.0\n", - " 0.99\n", - " EpsilonGreedy-0.6\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", " SimpleDuelingNetwork\n", " \n", " Adam\n", " 0.0001\n", " ExperienceReplay\n", - " 16\n", + " 512\n", + " 140.0\n", " 500.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 261.0\n", " \n", " \n", - " 5367\n", - " DuelingDQN\n", + " 10803\n", + " DoubleDQN\n", " 1.0\n", - " 64.0\n", + " 32.0\n", " 0.99\n", - " EpsilonGreedy-0.6\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", " SimpleDuelingNetwork\n", " \n", " Adam\n", " 0.0001\n", " ExperienceReplay\n", - " 32\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 260.0\n", + " 2048\n", + " 150.0\n", + " 500.0\n", " \n", " \n", "\n", @@ -4746,84 +4925,54 @@ ], "text/plain": [ " algo step_train batch_size gamma \\\n", - "6173 DuelingDQN 4.0 32.0 0.99 \n", - "6448 DuelingDQN 4.0 64.0 0.99 \n", - "5087 DuelingDQN 1.0 32.0 0.99 \n", - "6354 DuelingDQN 4.0 64.0 0.99 \n", - "4932 DuelingDQN 1.0 1.0 0.99 \n", - "4918 DuelingDQN 1.0 1.0 0.99 \n", - "5274 DuelingDQN 1.0 64.0 0.99 \n", - "6449 DuelingDQN 4.0 64.0 0.99 \n", - "5017 DuelingDQN 1.0 1.0 0.99 \n", - "5358 DuelingDQN 1.0 64.0 0.99 \n", - "5187 DuelingDQN 1.0 32.0 0.99 \n", - "5088 DuelingDQN 1.0 32.0 0.99 \n", - "5094 DuelingDQN 1.0 32.0 0.99 \n", - "5177 DuelingDQN 1.0 32.0 0.99 \n", - "5179 DuelingDQN 1.0 32.0 0.99 \n", - "6138 DuelingDQN 4.0 32.0 0.99 \n", - "6188 DuelingDQN 4.0 32.0 0.99 \n", - "6374 DuelingDQN 4.0 64.0 0.99 \n", - "5364 DuelingDQN 1.0 64.0 0.99 \n", - "5367 DuelingDQN 1.0 64.0 0.99 \n", + "12340 DoubleDQN 1.0 32.0 1.00 \n", + "17645 DoubleDQN 1.0 64.0 1.00 \n", + "13775 DoubleDQN 1.0 64.0 0.95 \n", + "9747 DoubleDQN 1.0 32.0 0.95 \n", + "12320 DoubleDQN 1.0 32.0 1.00 \n", + "13777 DoubleDQN 1.0 64.0 0.95 \n", + "12321 DoubleDQN 1.0 32.0 1.00 \n", + "14522 DoubleDQN 1.0 64.0 0.95 \n", + "16785 DoubleDQN 1.0 64.0 1.00 \n", + "10803 DoubleDQN 1.0 32.0 0.99 \n", "\n", - " greedy_exploration network \\\n", - "6173 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleDuelingNetwork \n", - "6448 EpsilonGreedy-0.6 SimpleDuelingNetwork \n", - "5087 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleDuelingNetwork \n", - "6354 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleDuelingNetwork \n", - "4932 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleDuelingNetwork \n", - "4918 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleDuelingNetwork \n", - "5274 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleDuelingNetwork \n", - "6449 EpsilonGreedy-0.6 SimpleDuelingNetwork \n", - "5017 EpsilonGreedy-0.6 SimpleDuelingNetwork \n", - "5358 EpsilonGreedy-0.6 SimpleDuelingNetwork \n", - "5187 EpsilonGreedy-0.6 SimpleDuelingNetwork \n", - "5088 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleDuelingNetwork \n", - "5094 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleDuelingNetwork \n", - "5177 EpsilonGreedy-0.6 SimpleDuelingNetwork \n", - "5179 EpsilonGreedy-0.6 SimpleDuelingNetwork \n", - "6138 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 SimpleDuelingNetwork \n", - "6188 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleDuelingNetwork \n", - "6374 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 SimpleDuelingNetwork \n", - "5364 EpsilonGreedy-0.6 SimpleDuelingNetwork \n", - "5367 EpsilonGreedy-0.6 SimpleDuelingNetwork \n", + " greedy_exploration network \\\n", + "12340 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork \n", + "17645 EpsilonGreedy-0.6 SimpleDuelingNetwork \n", + "13775 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork \n", + "9747 EpsilonGreedy-0.1 SimpleDuelingNetwork \n", + "12320 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork \n", + "13777 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork \n", + "12321 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork \n", + "14522 EpsilonGreedy-0.6 SimpleDuelingNetwork \n", + "16785 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork \n", + "10803 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork \n", "\n", - " optimizer lr memories max_size step max min avg sum \n", - "6173 Adam 0.0001 ExperienceReplay 16 498.0 1.0 1.0 1.0 500.0 \n", - "6448 Adam 0.0001 ExperienceReplay 32 498.0 1.0 1.0 1.0 500.0 \n", - "5087 Adam 0.0001 ExperienceReplay 128 332.0 1.0 1.0 1.0 421.0 \n", - "6354 Adam 0.0001 ExperienceReplay 16 500.0 1.0 1.0 1.0 386.0 \n", - "4932 Adam 0.0010 ExperienceReplay 32 332.0 1.0 1.0 1.0 379.0 \n", - "4918 Adam 0.0001 ExperienceReplay 32 498.0 1.0 1.0 1.0 376.0 \n", - "5274 Adam 0.0001 ExperienceReplay 16 500.0 1.0 1.0 1.0 372.0 \n", - "6449 Adam 0.0001 ExperienceReplay 32 500.0 1.0 1.0 1.0 337.0 \n", - "5017 Adam 0.0010 ExperienceReplay 16 332.0 1.0 1.0 1.0 335.0 \n", - "5358 Adam 0.0001 ExperienceReplay 128 498.0 1.0 1.0 1.0 330.0 \n", - "5187 Adam 0.0001 ExperienceReplay 32 332.0 1.0 1.0 1.0 329.0 \n", - "5088 Adam 0.0001 ExperienceReplay 128 498.0 1.0 1.0 1.0 328.0 \n", - "5094 Adam 0.0001 ExperienceReplay 16 500.0 1.0 1.0 1.0 317.0 \n", - "5177 Adam 0.0001 ExperienceReplay 128 332.0 1.0 1.0 1.0 307.0 \n", - "5179 Adam 0.0001 ExperienceReplay 128 500.0 1.0 1.0 1.0 299.0 \n", - "6138 Adam 0.0010 ExperienceReplay 128 498.0 1.0 1.0 1.0 291.0 \n", - "6188 Adam 0.0010 ExperienceReplay 16 498.0 1.0 1.0 1.0 278.0 \n", - "6374 Adam 0.0010 ExperienceReplay 32 500.0 1.0 1.0 1.0 273.0 \n", - "5364 Adam 0.0001 ExperienceReplay 16 500.0 1.0 1.0 1.0 261.0 \n", - "5367 Adam 0.0001 ExperienceReplay 32 332.0 1.0 1.0 1.0 260.0 " + " optimizer lr memories max_size step sum \n", + "12340 Adam 0.0010 ExperienceReplay 2048 20.0 500.0 \n", + "17645 Adam 0.1000 ExperienceReplay 512 60.0 500.0 \n", + "13775 Adam 0.0001 ExperienceReplay 2048 110.0 500.0 \n", + "9747 Adam 0.0010 ExperienceReplay 2048 130.0 500.0 \n", + "12320 Adam 0.0001 ExperienceReplay 512 130.0 500.0 \n", + "13777 Adam 0.0001 ExperienceReplay 2048 130.0 500.0 \n", + "12321 Adam 0.0001 ExperienceReplay 512 140.0 500.0 \n", + "14522 Adam 0.0001 ExperienceReplay 2048 140.0 500.0 \n", + "16785 Adam 0.0001 ExperienceReplay 512 140.0 500.0 \n", + "10803 Adam 0.0001 ExperienceReplay 2048 150.0 500.0 " ] }, - "execution_count": 27, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "df_DuelingDQN.sort_values(by =[\"sum\",\"step\"], ascending = [False, True]).head(20)" + "df_DoubleDQN.sort_values(by =[\"sum\",\"step\"], ascending = [False, True]).head(10)" ] }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 31, "metadata": {}, "outputs": [ { @@ -4832,13 +4981,13 @@ "" ] }, - "execution_count": 69, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -4851,28 +5000,12 @@ ], "source": [ "fig, ax = plt.subplots(figsize=(10,10)) \n", - "sns.heatmap(df_DuelingDQN.corr()[df_DuelingDQN.corr() > 0.05], annot = True, fmt='.2g',cmap= 'coolwarm', ax=ax)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### CategoricalDQN" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [], - "source": [ - "df_CategoricalDQN = df[df[\"algo\"] == \"CategoricalDQN\"].copy()" + "sns.heatmap(df_DoubleDQN.corr()[abs(df_DoubleDQN.corr()) > 0.05], annot = True, fmt='.2g',cmap= 'coolwarm', ax=ax)" ] }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 32, "metadata": {}, "outputs": [ { @@ -4896,186 +5029,700 @@ " \n", " \n", " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " step\n", + " sum\n", + " \n", + " \n", + " algo\n", " step_train\n", " batch_size\n", " gamma\n", + " greedy_exploration\n", + " network\n", + " optimizer\n", " lr\n", - " step\n", - " max\n", - " min\n", - " avg\n", - " sum\n", + " memories\n", + " max_size\n", + " \n", + " \n", + " \n", " \n", " \n", " \n", " \n", - " step_train\n", - " 1.000000e+00\n", - " 6.254152e-18\n", - " -3.338836e-15\n", - " -1.947613e-17\n", - " 5.190625e-20\n", - " NaN\n", - " NaN\n", - " NaN\n", - " 6.569585e-02\n", + " DoubleDQN\n", + " 1.0\n", + " 64.0\n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 6\n", + " 6\n", + " 6\n", + " \n", + " \n", + " 32.0\n", + " 0.99\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 6\n", + " 6\n", + " 6\n", + " \n", + " \n", + " 0.95\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 5\n", + " 5\n", + " 5\n", + " \n", + " \n", + " 64.0\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " 0.99\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 4\n", + " 4\n", + " 4\n", + " \n", + " \n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 3\n", + " 3\n", + " 3\n", + " \n", + " \n", + " EpsilonGreedy-0.1\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 3\n", + " 3\n", + " 3\n", + " \n", + " \n", + " 32.0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 64.0\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 32.0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 64.0\n", + " 1.00\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.1000\n", + " ExperienceReplay\n", + " 512\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 32.0\n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 2048\n", + " 2\n", + " 2\n", + " 2\n", + " \n", + " \n", + " 64.0\n", + " 0.95\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " batch_size\n", - " 6.254152e-18\n", - " 1.000000e+00\n", - " -5.096548e-15\n", - " 1.309431e-16\n", - " 0.000000e+00\n", - " NaN\n", - " NaN\n", - " NaN\n", - " -4.414052e-02\n", + " 1.00\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " gamma\n", - " -3.338836e-15\n", - " -5.096548e-15\n", - " 1.000000e+00\n", - " 1.070395e-14\n", - " -1.030754e-16\n", - " NaN\n", - " NaN\n", - " NaN\n", - " 4.203546e-16\n", + " EpsilonGreedy-0.1\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " lr\n", - " -1.947613e-17\n", - " 1.309431e-16\n", - " 1.070395e-14\n", - " 1.000000e+00\n", - " -3.622535e-19\n", - " NaN\n", - " NaN\n", - " NaN\n", - " -2.343891e-02\n", + " 32.0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " step\n", - " 5.190625e-20\n", - " 0.000000e+00\n", - " -1.030754e-16\n", - " -3.622535e-19\n", - " 1.000000e+00\n", - " NaN\n", - " NaN\n", - " NaN\n", - " -5.528580e-02\n", + " 64.0\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " max\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", + " 32.0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " min\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", + " 64.0\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " avg\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", - " NaN\n", + " 0.99\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", - " sum\n", - " 6.569585e-02\n", - " -4.414052e-02\n", - " 4.203546e-16\n", - " -2.343891e-02\n", - " -5.528580e-02\n", - " NaN\n", - " NaN\n", - " NaN\n", - " 1.000000e+00\n", + " 32.0\n", + " 0.95\n", + " EpsilonGreedy-0.1\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 64.0\n", + " 0.95\n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " EpsilonGreedy-0.1\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 32.0\n", + " 0.99\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " EpsilonGreedy-0.1\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 64.0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 32.0\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " 512\n", + " 1\n", + " 1\n", + " 1\n", + " \n", + " \n", + " EpsilonGreedy-0.6\n", + " SimpleDuelingNetwork\n", + " Adam\n", + " 0.0001\n", + " ExperienceReplay\n", + " 2048\n", + " 1\n", + " 1\n", + " 1\n", " \n", " \n", "\n", "" ], "text/plain": [ - " step_train batch_size gamma lr \\\n", - "step_train 1.000000e+00 6.254152e-18 -3.338836e-15 -1.947613e-17 \n", - "batch_size 6.254152e-18 1.000000e+00 -5.096548e-15 1.309431e-16 \n", - "gamma -3.338836e-15 -5.096548e-15 1.000000e+00 1.070395e-14 \n", - "lr -1.947613e-17 1.309431e-16 1.070395e-14 1.000000e+00 \n", - "step 5.190625e-20 0.000000e+00 -1.030754e-16 -3.622535e-19 \n", - "max NaN NaN NaN NaN \n", - "min NaN NaN NaN NaN \n", - "avg NaN NaN NaN NaN \n", - "sum 6.569585e-02 -4.414052e-02 4.203546e-16 -2.343891e-02 \n", + " \\\n", + "algo step_train batch_size gamma greedy_exploration network optimizer lr memories max_size \n", + "DoubleDQN 1.0 64.0 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 6 \n", + " 32.0 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 6 \n", + " 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 5 \n", + " 64.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 4 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 4 \n", + " 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 4 \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 4 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 3 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 3 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 2 \n", + " 64.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 2 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 2 \n", + " 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 64.0 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.1000 ExperienceReplay 512 2 \n", + " 32.0 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 2048 2 \n", + " 64.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 64.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 64.0 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 32.0 0.95 EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 0.0001 ExperienceReplay 2048 1 \n", + " 64.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 0.0001 ExperienceReplay 512 1 \n", + " 32.0 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 64.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 32.0 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 512 1 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + "\n", + " step \\\n", + "algo step_train batch_size gamma greedy_exploration network optimizer lr memories max_size \n", + "DoubleDQN 1.0 64.0 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 6 \n", + " 32.0 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 6 \n", + " 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 5 \n", + " 64.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 4 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 4 \n", + " 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 4 \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 4 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 3 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 3 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 2 \n", + " 64.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 2 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 2 \n", + " 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 64.0 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.1000 ExperienceReplay 512 2 \n", + " 32.0 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 2048 2 \n", + " 64.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 64.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 64.0 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 32.0 0.95 EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 0.0001 ExperienceReplay 2048 1 \n", + " 64.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 0.0001 ExperienceReplay 512 1 \n", + " 32.0 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 64.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 32.0 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 512 1 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", "\n", - " step max min avg sum \n", - "step_train 5.190625e-20 NaN NaN NaN 6.569585e-02 \n", - "batch_size 0.000000e+00 NaN NaN NaN -4.414052e-02 \n", - "gamma -1.030754e-16 NaN NaN NaN 4.203546e-16 \n", - "lr -3.622535e-19 NaN NaN NaN -2.343891e-02 \n", - "step 1.000000e+00 NaN NaN NaN -5.528580e-02 \n", - "max NaN NaN NaN NaN NaN \n", - "min NaN NaN NaN NaN NaN \n", - "avg NaN NaN NaN NaN NaN \n", - "sum -5.528580e-02 NaN NaN NaN 1.000000e+00 " + " sum \n", + "algo step_train batch_size gamma greedy_exploration network optimizer lr memories max_size \n", + "DoubleDQN 1.0 64.0 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 6 \n", + " 32.0 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 6 \n", + " 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 5 \n", + " 64.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 4 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 4 \n", + " 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 4 \n", + " AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 4 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 3 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 3 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 2 \n", + " 64.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 2 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 2 \n", + " 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 64.0 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.1000 ExperienceReplay 512 2 \n", + " 32.0 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 2 \n", + " 2048 2 \n", + " 64.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 64.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 32.0 0.95 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 64.0 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 0.99 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 \n", + " 32.0 0.95 EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 0.99 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 1 \n", + " 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 0.0001 ExperienceReplay 2048 1 \n", + " 64.0 0.95 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 0.0001 ExperienceReplay 512 1 \n", + " 32.0 0.99 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " EpsilonGreedy-0.1 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 64.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " 32.0 1.00 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 512 1 \n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 2048 1 \n", + " 512 1 \n", + " EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0001 ExperienceReplay 2048 1 " ] }, - "execution_count": 29, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "df_CategoricalDQN.corr()" + "columns = [\"algo\",\"step_train\",\"batch_size\",\"gamma\",\"greedy_exploration\",\"network\",\"optimizer\",\"lr\",\"memories\",\"max_size\"]\n", + "df_DoubleDQN[df_DoubleDQN[\"sum\"] >= 500].groupby(by=columns, observed=True).count().sort_values(by=['sum'], ascending=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### CategoricalDQN" ] }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 33, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(405.0, 8.0)" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "max(df_CategoricalDQN[\"sum\"]), min(df_CategoricalDQN[\"sum\"])" + "df_CategoricalDQN = df[df[\"algo\"] == \"CategoricalDQN\"].copy()" ] }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 34, "metadata": {}, "outputs": [ { @@ -5111,392 +5758,329 @@ " memories\n", " max_size\n", " step\n", - " max\n", - " min\n", - " avg\n", " sum\n", " \n", " \n", " \n", " \n", - " 567\n", + " 2672\n", " CategoricalDQN\n", - " 32.0\n", " 1.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", + " 64.0\n", + " 0.95\n", + " EpsilonGreedy-0.1\n", " C51Network\n", " \n", " Adam\n", " 0.0010\n", " ExperienceReplay\n", - " 32\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 405.0\n", - " \n", - " \n", - " 1110\n", - " CategoricalDQN\n", - " 4.0\n", - " 1.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", - " C51Network\n", - " \n", - " Adam\n", - " 0.1000\n", - " ExperienceReplay\n", - " 128\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 108.0\n", + " 2048\n", + " 60.0\n", + " 500.0\n", " \n", " \n", - " 300\n", + " 8419\n", " CategoricalDQN\n", - " 1.0\n", " 32.0\n", - " 0.99\n", - " EpsilonGreedy-0.1\n", + " 64.0\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", " C51Network\n", " \n", " Adam\n", - " 0.1000\n", + " 0.0001\n", " ExperienceReplay\n", - " 128\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 105.0\n", + " 512\n", + " 180.0\n", + " 500.0\n", " \n", " \n", - " 1505\n", + " 3979\n", " CategoricalDQN\n", - " 4.0\n", + " 1.0\n", " 64.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", " C51Network\n", " \n", " Adam\n", " 0.0010\n", " ExperienceReplay\n", - " 16\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 74.0\n", + " 2048\n", + " 110.0\n", + " 403.0\n", " \n", " \n", - " 685\n", + " 5525\n", " CategoricalDQN\n", " 32.0\n", - " 1.0\n", + " 32.0\n", " 0.99\n", - " EpsilonGreedy-0.6\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", " C51Network\n", " \n", " Adam\n", - " 0.0001\n", + " 0.1000\n", " ExperienceReplay\n", - " 32\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 71.0\n", + " 2048\n", + " 70.0\n", + " 388.0\n", " \n", " \n", - " 689\n", + " 463\n", " CategoricalDQN\n", - " 32.0\n", " 1.0\n", - " 0.99\n", - " EpsilonGreedy-0.6\n", + " 32.0\n", + " 0.95\n", + " EpsilonGreedy-0.1\n", " C51Network\n", " \n", " Adam\n", - " 0.0001\n", + " 0.0010\n", " ExperienceReplay\n", - " 32\n", - " 500.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 67.0\n", + " 2048\n", + " 290.0\n", + " 355.0\n", " \n", " \n", - " 543\n", + " 2163\n", " CategoricalDQN\n", - " 32.0\n", " 1.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", + " 32.0\n", + " 1.00\n", + " EpsilonGreedy-0.6\n", " C51Network\n", " \n", " Adam\n", - " 0.0001\n", + " 0.0010\n", " ExperienceReplay\n", - " 128\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 59.0\n", + " 512\n", + " 240.0\n", + " 328.0\n", " \n", " \n", - " 435\n", + " 2659\n", " CategoricalDQN\n", " 1.0\n", " 64.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", + " 0.95\n", + " EpsilonGreedy-0.1\n", " C51Network\n", " \n", " Adam\n", - " 0.1000\n", + " 0.0001\n", " ExperienceReplay\n", - " 128\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 46.0\n", + " 512\n", + " 240.0\n", + " 327.0\n", " \n", " \n", - " 1465\n", + " 2488\n", " CategoricalDQN\n", - " 4.0\n", + " 1.0\n", " 64.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", " C51Network\n", " \n", " Adam\n", " 0.0010\n", " ExperienceReplay\n", - " 32\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 44.0\n", + " 2048\n", + " 80.0\n", + " 326.0\n", " \n", " \n", - " 544\n", + " 1975\n", " CategoricalDQN\n", - " 32.0\n", " 1.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", + " 32.0\n", + " 1.00\n", + " EpsilonGreedy-0.1\n", " C51Network\n", " \n", " Adam\n", - " 0.0001\n", + " 0.0010\n", " ExperienceReplay\n", - " 128\n", - " 500.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 44.0\n", + " 512\n", + " 220.0\n", + " 316.0\n", " \n", " \n", - " 761\n", + " 2493\n", " CategoricalDQN\n", - " 32.0\n", - " 32.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", + " 1.0\n", + " 64.0\n", + " 0.95\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", " C51Network\n", " \n", " Adam\n", - " 0.1000\n", + " 0.0010\n", " ExperienceReplay\n", - " 32\n", - " 166.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 42.0\n", + " 2048\n", + " 130.0\n", + " 312.0\n", " \n", " \n", - " 861\n", + " 4366\n", " CategoricalDQN\n", - " 32.0\n", - " 32.0\n", - " 0.99\n", + " 1.0\n", + " 64.0\n", + " 1.00\n", " EpsilonGreedy-0.6\n", " C51Network\n", " \n", " Adam\n", - " 0.0001\n", + " 0.0010\n", " ExperienceReplay\n", - " 16\n", - " 166.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 41.0\n", + " 2048\n", + " 260.0\n", + " 305.0\n", " \n", " \n", - " 55\n", + " 461\n", " CategoricalDQN\n", " 1.0\n", - " 1.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", + " 32.0\n", + " 0.95\n", + " EpsilonGreedy-0.1\n", " C51Network\n", " \n", " Adam\n", - " 0.0001\n", + " 0.0010\n", " ExperienceReplay\n", - " 32\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 38.0\n", + " 2048\n", + " 270.0\n", + " 294.0\n", " \n", " \n", - " 1136\n", + " 3974\n", " CategoricalDQN\n", - " 4.0\n", " 1.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.8-0.2-50000-0\n", + " 64.0\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", " C51Network\n", " \n", " Adam\n", - " 0.0001\n", + " 0.0010\n", " ExperienceReplay\n", - " 32\n", - " 166.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 38.0\n", + " 2048\n", + " 60.0\n", + " 292.0\n", " \n", " \n", - " 1036\n", + " 8906\n", " CategoricalDQN\n", " 32.0\n", " 64.0\n", - " 0.99\n", + " 1.00\n", " EpsilonGreedy-0.6\n", " C51Network\n", " \n", " Adam\n", - " 0.0001\n", + " 0.1000\n", " ExperienceReplay\n", - " 128\n", - " 166.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 37.0\n", + " 512\n", + " 90.0\n", + " 292.0\n", " \n", " \n", - " 702\n", + " 2158\n", " CategoricalDQN\n", - " 32.0\n", " 1.0\n", - " 0.99\n", + " 32.0\n", + " 1.00\n", " EpsilonGreedy-0.6\n", " C51Network\n", " \n", " Adam\n", " 0.0010\n", " ExperienceReplay\n", - " 32\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 37.0\n", + " 512\n", + " 190.0\n", + " 290.0\n", " \n", " \n", - " 688\n", + " 2159\n", " CategoricalDQN\n", - " 32.0\n", " 1.0\n", - " 0.99\n", + " 32.0\n", + " 1.00\n", " EpsilonGreedy-0.6\n", " C51Network\n", " \n", " Adam\n", - " 0.0001\n", + " 0.0010\n", " ExperienceReplay\n", - " 32\n", - " 498.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 36.0\n", + " 512\n", + " 200.0\n", + " 282.0\n", " \n", " \n", - " 485\n", + " 4023\n", " CategoricalDQN\n", " 1.0\n", " 64.0\n", - " 0.99\n", - " EpsilonGreedy-0.1\n", + " 1.00\n", + " AdaptativeEpsilonGreedy-0.8-0.2-10000-0\n", " C51Network\n", " \n", " Adam\n", - " 0.1000\n", + " 0.0010\n", " ExperienceReplay\n", - " 16\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 34.0\n", + " 512\n", + " 240.0\n", + " 278.0\n", " \n", " \n", - " 862\n", + " 2133\n", " CategoricalDQN\n", + " 1.0\n", " 32.0\n", - " 32.0\n", - " 0.99\n", + " 1.00\n", " EpsilonGreedy-0.6\n", " C51Network\n", " \n", " Adam\n", - " 0.0001\n", + " 0.0010\n", " ExperienceReplay\n", - " 16\n", - " 332.0\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", - " 34.0\n", + " 2048\n", + " 250.0\n", + " 276.0\n", " \n", " \n", - " 1475\n", + " 2726\n", " CategoricalDQN\n", - " 4.0\n", + " 1.0\n", " 64.0\n", - " 0.99\n", - " AdaptativeEpsilonGreedy-0.3-0.1-50000-0\n", + " 0.95\n", + " EpsilonGreedy-0.1\n", " C51Network\n", " \n", " Adam\n", - " 0.1000\n", + " 0.0010\n", " ExperienceReplay\n", - " 16\n", - " 1.0\n", - " 1.0\n", - " 1.0\n", + " 512\n", + " 290.0\n", + " 266.0\n", + " \n", + " \n", + " 2156\n", + " CategoricalDQN\n", " 1.0\n", - " 33.0\n", + " 32.0\n", + " 1.00\n", + " EpsilonGreedy-0.6\n", + " C51Network\n", + " \n", + " Adam\n", + " 0.0010\n", + " ExperienceReplay\n", + " 512\n", + " 170.0\n", + " 261.0\n", " \n", " \n", "\n", @@ -5504,73 +6088,73 @@ ], "text/plain": [ " algo step_train batch_size gamma \\\n", - "567 CategoricalDQN 32.0 1.0 0.99 \n", - "1110 CategoricalDQN 4.0 1.0 0.99 \n", - "300 CategoricalDQN 1.0 32.0 0.99 \n", - "1505 CategoricalDQN 4.0 64.0 0.99 \n", - "685 CategoricalDQN 32.0 1.0 0.99 \n", - "689 CategoricalDQN 32.0 1.0 0.99 \n", - "543 CategoricalDQN 32.0 1.0 0.99 \n", - "435 CategoricalDQN 1.0 64.0 0.99 \n", - "1465 CategoricalDQN 4.0 64.0 0.99 \n", - "544 CategoricalDQN 32.0 1.0 0.99 \n", - "761 CategoricalDQN 32.0 32.0 0.99 \n", - "861 CategoricalDQN 32.0 32.0 0.99 \n", - "55 CategoricalDQN 1.0 1.0 0.99 \n", - "1136 CategoricalDQN 4.0 1.0 0.99 \n", - "1036 CategoricalDQN 32.0 64.0 0.99 \n", - "702 CategoricalDQN 32.0 1.0 0.99 \n", - "688 CategoricalDQN 32.0 1.0 0.99 \n", - "485 CategoricalDQN 1.0 64.0 0.99 \n", - "862 CategoricalDQN 32.0 32.0 0.99 \n", - "1475 CategoricalDQN 4.0 64.0 0.99 \n", + "2672 CategoricalDQN 1.0 64.0 0.95 \n", + "8419 CategoricalDQN 32.0 64.0 1.00 \n", + "3979 CategoricalDQN 1.0 64.0 1.00 \n", + "5525 CategoricalDQN 32.0 32.0 0.99 \n", + "463 CategoricalDQN 1.0 32.0 0.95 \n", + "2163 CategoricalDQN 1.0 32.0 1.00 \n", + "2659 CategoricalDQN 1.0 64.0 0.95 \n", + "2488 CategoricalDQN 1.0 64.0 0.95 \n", + "1975 CategoricalDQN 1.0 32.0 1.00 \n", + "2493 CategoricalDQN 1.0 64.0 0.95 \n", + "4366 CategoricalDQN 1.0 64.0 1.00 \n", + "461 CategoricalDQN 1.0 32.0 0.95 \n", + "3974 CategoricalDQN 1.0 64.0 1.00 \n", + "8906 CategoricalDQN 32.0 64.0 1.00 \n", + "2158 CategoricalDQN 1.0 32.0 1.00 \n", + "2159 CategoricalDQN 1.0 32.0 1.00 \n", + "4023 CategoricalDQN 1.0 64.0 1.00 \n", + "2133 CategoricalDQN 1.0 32.0 1.00 \n", + "2726 CategoricalDQN 1.0 64.0 0.95 \n", + "2156 CategoricalDQN 1.0 32.0 1.00 \n", "\n", " greedy_exploration network optimizer lr \\\n", - "567 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 C51Network Adam 0.0010 \n", - "1110 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 C51Network Adam 0.1000 \n", - "300 EpsilonGreedy-0.1 C51Network Adam 0.1000 \n", - "1505 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 C51Network Adam 0.0010 \n", - "685 EpsilonGreedy-0.6 C51Network Adam 0.0001 \n", - "689 EpsilonGreedy-0.6 C51Network Adam 0.0001 \n", - "543 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 C51Network Adam 0.0001 \n", - "435 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 C51Network Adam 0.1000 \n", - "1465 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 C51Network Adam 0.0010 \n", - "544 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 C51Network Adam 0.0001 \n", - "761 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 C51Network Adam 0.1000 \n", - "861 EpsilonGreedy-0.6 C51Network Adam 0.0001 \n", - "55 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 C51Network Adam 0.0001 \n", - "1136 AdaptativeEpsilonGreedy-0.8-0.2-50000-0 C51Network Adam 0.0001 \n", - "1036 EpsilonGreedy-0.6 C51Network Adam 0.0001 \n", - "702 EpsilonGreedy-0.6 C51Network Adam 0.0010 \n", - "688 EpsilonGreedy-0.6 C51Network Adam 0.0001 \n", - "485 EpsilonGreedy-0.1 C51Network Adam 0.1000 \n", - "862 EpsilonGreedy-0.6 C51Network Adam 0.0001 \n", - "1475 AdaptativeEpsilonGreedy-0.3-0.1-50000-0 C51Network Adam 0.1000 \n", + "2672 EpsilonGreedy-0.1 C51Network Adam 0.0010 \n", + "8419 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 C51Network Adam 0.0001 \n", + "3979 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 C51Network Adam 0.0010 \n", + "5525 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 C51Network Adam 0.1000 \n", + "463 EpsilonGreedy-0.1 C51Network Adam 0.0010 \n", + "2163 EpsilonGreedy-0.6 C51Network Adam 0.0010 \n", + "2659 EpsilonGreedy-0.1 C51Network Adam 0.0001 \n", + "2488 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 C51Network Adam 0.0010 \n", + "1975 EpsilonGreedy-0.1 C51Network Adam 0.0010 \n", + "2493 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 C51Network Adam 0.0010 \n", + "4366 EpsilonGreedy-0.6 C51Network Adam 0.0010 \n", + "461 EpsilonGreedy-0.1 C51Network Adam 0.0010 \n", + "3974 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 C51Network Adam 0.0010 \n", + "8906 EpsilonGreedy-0.6 C51Network Adam 0.1000 \n", + "2158 EpsilonGreedy-0.6 C51Network Adam 0.0010 \n", + "2159 EpsilonGreedy-0.6 C51Network Adam 0.0010 \n", + "4023 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 C51Network Adam 0.0010 \n", + "2133 EpsilonGreedy-0.6 C51Network Adam 0.0010 \n", + "2726 EpsilonGreedy-0.1 C51Network Adam 0.0010 \n", + "2156 EpsilonGreedy-0.6 C51Network Adam 0.0010 \n", "\n", - " memories max_size step max min avg sum \n", - "567 ExperienceReplay 32 332.0 1.0 1.0 1.0 405.0 \n", - "1110 ExperienceReplay 128 1.0 1.0 1.0 1.0 108.0 \n", - "300 ExperienceReplay 128 1.0 1.0 1.0 1.0 105.0 \n", - "1505 ExperienceReplay 16 1.0 1.0 1.0 1.0 74.0 \n", - "685 ExperienceReplay 32 1.0 1.0 1.0 1.0 71.0 \n", - "689 ExperienceReplay 32 500.0 1.0 1.0 1.0 67.0 \n", - "543 ExperienceReplay 128 498.0 1.0 1.0 1.0 59.0 \n", - "435 ExperienceReplay 128 1.0 1.0 1.0 1.0 46.0 \n", - "1465 ExperienceReplay 32 1.0 1.0 1.0 1.0 44.0 \n", - "544 ExperienceReplay 128 500.0 1.0 1.0 1.0 44.0 \n", - "761 ExperienceReplay 32 166.0 1.0 1.0 1.0 42.0 \n", - "861 ExperienceReplay 16 166.0 1.0 1.0 1.0 41.0 \n", - "55 ExperienceReplay 32 1.0 1.0 1.0 1.0 38.0 \n", - "1136 ExperienceReplay 32 166.0 1.0 1.0 1.0 38.0 \n", - "1036 ExperienceReplay 128 166.0 1.0 1.0 1.0 37.0 \n", - "702 ExperienceReplay 32 332.0 1.0 1.0 1.0 37.0 \n", - "688 ExperienceReplay 32 498.0 1.0 1.0 1.0 36.0 \n", - "485 ExperienceReplay 16 1.0 1.0 1.0 1.0 34.0 \n", - "862 ExperienceReplay 16 332.0 1.0 1.0 1.0 34.0 \n", - "1475 ExperienceReplay 16 1.0 1.0 1.0 1.0 33.0 " + " memories max_size step sum \n", + "2672 ExperienceReplay 2048 60.0 500.0 \n", + "8419 ExperienceReplay 512 180.0 500.0 \n", + "3979 ExperienceReplay 2048 110.0 403.0 \n", + "5525 ExperienceReplay 2048 70.0 388.0 \n", + "463 ExperienceReplay 2048 290.0 355.0 \n", + "2163 ExperienceReplay 512 240.0 328.0 \n", + "2659 ExperienceReplay 512 240.0 327.0 \n", + "2488 ExperienceReplay 2048 80.0 326.0 \n", + "1975 ExperienceReplay 512 220.0 316.0 \n", + "2493 ExperienceReplay 2048 130.0 312.0 \n", + "4366 ExperienceReplay 2048 260.0 305.0 \n", + "461 ExperienceReplay 2048 270.0 294.0 \n", + "3974 ExperienceReplay 2048 60.0 292.0 \n", + "8906 ExperienceReplay 512 90.0 292.0 \n", + "2158 ExperienceReplay 512 190.0 290.0 \n", + "2159 ExperienceReplay 512 200.0 282.0 \n", + "4023 ExperienceReplay 512 240.0 278.0 \n", + "2133 ExperienceReplay 2048 250.0 276.0 \n", + "2726 ExperienceReplay 512 290.0 266.0 \n", + "2156 ExperienceReplay 512 170.0 261.0 " ] }, - "execution_count": 31, + "execution_count": 34, "metadata": {}, "output_type": "execute_result" } @@ -5581,7 +6165,7 @@ }, { "cell_type": "code", - "execution_count": 70, + "execution_count": 35, "metadata": {}, "outputs": [ { @@ -5590,13 +6174,13 @@ "" ] }, - "execution_count": 70, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiwAAAJDCAYAAAAo1U9mAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy86wFpkAAAACXBIWXMAAAsTAAALEwEAmpwYAAA6AUlEQVR4nO3deZhcZZX48e/pzkISQgiJbIEAIgQBIawGhAmiKBLAERlFHR0Y/UUdcdAZR3HGfWEExUFwYaLDMjiKooysIiNCEAEhQXYIYU/YQhayk6S7z++Pqk4qSXe6C7q66nZ9P89TT7rufevWuZWuqtPnXW5kJpIkSY2spd4BSJIk9cSERZIkNTwTFkmS1PBMWCRJUsMzYZEkSQ3PhEWSJDU8ExZJktSnIuKCiJgXEfd3sz8i4tyIeDQi7o2I/Xs6pgmLJEnqaxcBR29i/zuA3cq3qcCPejqgCYskSepTmXkzsHATTd4J/HeW3A5sGRHbbeqYg/oywO5cM3iCy+n20pQ1s+odgiR167Djptc7hMK45arJ0V/P1d/fs8e2PfJRSpWRTtMyc1oVhxgHzKm4P7e87bnuHtAvCYskSRo4yslJNQnKhrpK5jaZdNklJEmS+ttcYMeK+zsAz27qAVZYJEkquBjcb71PfeVK4NSIuBR4I7A4M7vtDgITFkmS1Mci4ufAEcDYiJgLfBkYDJCZ5wPXAscAjwIrgFN6OqYJiyRJBdcyqLEqLJn5vh72J/CJao7pGBZJktTwrLBIklRwMXjg1x8G/hlKkqTCs8IiSVLBNdoYllqwwiJJkhqeFRZJkgqugOuwVM0KiyRJangmLJIkqeHZJSRJUsE56FaSJKkBWGGRJKngHHQrSZLUAKywSJJUcI5hkSRJagBWWCRJKrhotcIiSZJUd1ZYJEkquBYrLJIkSfVnhUWSpIKLFisskiRJdWeFRZKkgovWgV9/GPhnKEmSCs8KiyRJBecsIUmSpAZgwiJJkhqeXUKSJBWc05olSZIagBUWSZIKzkG3kiRJDcAKiyRJBRdWWCRJkurPCoskSQUXLQO//jDwz1CSJBWeFRZJkgrOdVgkSZIagBUWSZIKrhnWYWm6hGWfH5/B1sccwep5C7h5v+PqHY4kqQenTd2VQw4Yw8ur2jnje7N45LFlG7U5Ycr2vOf4Hdhh+2FM+cCfWLykDYCjJm/NB969IwArX27n7B/O5tEnl/dr/OobTdclNPfiy7nj2I/UOwxJUi9MOmArdtx+OCd99A6+/YNH+MzHd+uy3X0PLeFTX7yH5154eb3tz73wMp/8/D2c/I8zufgXT/PZU3fvj7D7XbREv97qoekqLAtvmcGwncbVOwxJUi8cPmkM1/3heQAemLWUzUcMYszoISxYtHq9drMf37jqAnD/w0vW/vzAw0t4zdihtQtWNdXrhCUiTgDOBLYGonzLzNyiRrFJkprc2DFDmTd/1dr78xasYuyYjROW3jj2bdty+8yFfRlew3AdlvWdBRyfmaMyc4vMHLmpZCUipkbEjIiYcV3HS686UElS8+my8yGrP85+b9iSKUdty48uevzVhqQ6qaZL6IXMfKi3jTNzGjAN4JrBE17Br5ckqRmdcMz2HPf27QB4aPZStq7oxtl6zFDmL6yuurLrziM4/ZO785mv3MeSpW19Gqv6TzUJy4yI+AXwG2BtfS4zL+/roCRJzevya5/l8mufBeCQA7fi3ceO4/c3v8heE0aybEVbVd1B27xmKN/8/F58/bsPM+fZlbUKue6aYeG4ahKWLYAVwNsqtiVQqIRl4iVnM2bywQwZO5ojn5jO7K+dx5wLf1XvsCRJXbhtxkIOOXArfjHt4LXTmjt9+8t7863zHmHBwtWceNw43n/Cjmw1eggXn3sgt81cyJnnPcLJJ+3EqC0G8c/l2UXt7clH/umuep2OXoXIrH1vjV1CvTdlzayeG0lSnRx23PR6h1AYt1w1ud/KHg+888h+/Z7d64o/9HtJp8cKS0R8NjPPiojz6GKoU2b+Y00ikyRJKutNl1DnQNsZtQxEkiS9Mo5hATLzqvK/F9c+HEmSpI1Vs3Dca4DPAXsCm3Vuz8wjaxCXJEnqJReOW9//UOoe2gX4KvAkcGcNYpIkSVpPNdOax2Tmf0XEaZk5HZgeEQ4XlySpzhzDsr415X+fi4gpwLPADn0fkiRJ0vqqSVi+ERGjgH8GzqO0kNynaxKVJEnqNSssZRHRCuyWmVcDi4E31zQqSZKkCr0adJuZ7cDxNY5FkiS9AtES/Xqrh2q6hG6NiO8DvwCWd27MTC/KIEmSaqqahOXQ8r9fq9iWgOuwSJJUR82wDks1CcuHM/Pxyg0R8do+jkeSJGkj1SQsvwL232DbZcABfReOJEmqVkurs4SIiD2AvYBREXFCxa4tqFiiX5IkqVZ6U2GZABwLbAkcV7F9KfD/ahCTJEnSenpzteYrgCsi4pDMvK27dhHx+cz89z6NTpIk9agZFo7r9bDiTSUrZX/zKmORJEnqUjWDbnsy8NM7SZIaUDNMa+7LM8w+PJYkSdJaVlgkSSo4x7BU57I+PJYkSdJavU5YIuK1EXFVRMyPiHkRcUXlSreZeUZtQpQkSZvSDBc/rKbC8jPgl8C2wPaUKio/r0VQkiRJlaoZwxKZeUnF/Z9GxKl9HZAkSapOM8wSqiZhuTEiTgcupTQj6L3ANRGxFUBmLqxBfJIkSVUlLO8t//vRDbb/PaUExis3S5JUB80wS6jXCUtm7lLLQCRJkrrT64QlIoYD/wSMz8ypEbEbMCEzr65ZdJIkqUfNMIalmjO8EFgNHFq+Pxf4Rp9HJEmStIFqEpZdM/MsYA1AZq7E1W0lSaq/iP691UE1CcvqiBhG+ZpBEbErsKomUUmSJFWoZpbQV4DrgB0j4n+ANwGn1CIoSZKkStXMEro+ImYCkyh1BZ2WmfNrFpkkSeqVZpjWXM21hG7IzAWZeU1mXp2Z8yPihloGJ0mSBL2osETEZsBwYGxEjGbdQNstKF1TSJIk1VEzTGvuTZfQR4FPUUpOZlJKWBJYCny/ZpFJkiSV9ZiSZeb3yqvcfhOYWP75QuBx4LYaxydJknoQLdGvt3qopoZ0YmYuiYjDgKOAi4Af1SQqSZKkCtVMa24v/zsFOD8zr4iIr/R9SM3tmsET6h1CIUxZM6veIUhSw3AMy/qeiYj/BN4KnBkRQ+llhcYvl94xWZHU6G65anK9Q1CTqiZheQ9wNPCdzHwpIrYD/qU2YUmSpN5qhnVYqlk4bgVwecX954DnahGUJElSpYHf6SVJ0gDXaLOEIuLoiJgVEY9GxOld7B8VEVdFxD0R8UBE9HipHxMWSZLUZyKiFfgB8A5gT+B9EbHnBs0+ATyYmfsCRwBnR8SQTR23mjEskiSpETXWLKGDgUcz83GAiLgUeCfwYEWbBEZGRACbAwuBtk0dtKHOUJIkFd44YE7F/bnlbZW+D7weeBa4j9IFlTs2dVATFkmSCi4i+vs2NSJmVNymVobTRYi5wf23A3dTuuzPROD7EbHFps7RLiFJklSVzJwGTOtm91xgx4r7O1CqpFQ6BfhWZibwaEQ8AewB3NHdc1phkSRJfelOYLeI2KU8kPYk4MoN2jwNvAUgIrYBJlC6RmG3rLBIklRwjbQ0f2a2RcSpwO+AVuCCzHwgIj5W3n8+8HXgooi4j1IX0ucyc/6mjmvCIkmS+lRmXgtcu8G28yt+fhZ4WzXHNGGRJKngmmFp/sapIUmSJHXDCoskSUXXQGNYamXgn6EkSSo8KyySJBWcY1gkSZIagBUWSZIKLmLg1x8G/hlKkqTCs8IiSVLROYZFkiSp/qywSJJUcI10LaFaGfhnKEmSCs8KiyRJBec6LJIkSQ3AhEWSJDU8u4QkSSo6F46TJEmqPysskiQVnINuJUmSGoAVFkmSis6F4yRJkurPCoskSQUX4RgWSZKkurPCIklS0TmGRZIkqf6ssEiSVHCuwyJJktQArLBIklR0XktIkiSp/qywqFv7/PgMtj7mCFbPW8DN+x1X73AkSd1xDIua2dyLL+eOYz9S7zAkSTJhUfcW3jKDNQsX1zsMSZLsEpIkqejCQbfrRMTuEXFDRNxfvr9PRHxhE+2nRsSMiJgxbdq0vohVkiQ1qWoqLD8G/gX4T4DMvDcifgZ8o6vGmTkN6MxU8tUEKUmSNsFBt+sZnpl3bLCtrS+DkSRJ6ko1Ccv8iNiVcrUkIk4EnqtJVGoIEy85m0P/eCkjJuzCkU9MZ8dTTqx3SJKkLkRLS7/e6qGaLqFPUOri2SMingGeAP62JlGpIdz9wX+udwiSJAFVJCyZ+Tjw1ogYAbRk5tLahSVJknotHMOyVkS0R8S3gBWdyUpE3FWzyCRJksqq6RJ6gFKCc31EvDczFwIDP6WTJKnR1WlcSX+q5gzbMvOzlKY3/zEiDsDpypIkqR9UU2EJgMz8ZUQ8APwcGF+TqCRJUu81wRiWahKWtVfBy8wHIuIw4K/7PCJJkqQN9JiwRMSRmfkHYKeI2GmD3ctqE5YkSeqteq2N0p96U2GZDPwBOK6LfQlc3qcRSZIkbaDHhCUzv1z+95TahyNJkqrm1ZrXiYjTImKLKPlJRNwVEW+rZXCSJElQ3bTmv8/MJcDbgK2BU4Bv1SQqSZKkClVPawaOAS7MzHsimmAelSRJja5l4H8dV1NhmRkR11NKWH4XESOBjtqEJUmStE41FZYPAxOBxzNzRUSModQtBEBE7JWZD/RxfJIkqQfRBINuq7lacwdwV8X9BcCCiiaXAPv3XWiSJEkl1VRYejLwO9AkSWpEjmGpihdClCRJNdGXFRZJklQPTTCGpS/PcHUfHkuSJGmtqiosETEO2KnycZl5c/nfSX0bmiRJ6pUmWBat1wlLRJwJvBd4EGgvb07g5hrEJUmStFY1FZa/BiZk5qoaxSJJkl6JFsewVHocGFyrQCRJkrrTY4UlIs6j1PWzArg7Im4A1lZZMvMfaxeeJEnqURPMEupNl9CM8r8zgStrGIskSVKXekxYMvNigIgYAbycme3l+63A0NqGJ0mSeuRKt+u5ARhWcX8Y8Pu+DUeSJGlj1SQsm2Xmss475Z+H931IkiRJ66tmWvPyiNg/M+8CiIgDgJW1CUuSJPWag27X8yngsoh4tnx/O+CkPo9IkiRpA9UkLPcCewATgAAepm+vRSRJkl6JJliav5qE47bMXJOZ92fmfZm5BritVoFJkiR16s3CcdsC44BhEbEfpeoKwBY46FaSpPprgqX5e9Ml9HbgZGAH4LsV25cC/1qDmCRJktbT24XjLo6Id2fmr/shJkmSVI0mGMPS60G3mfnriJgC7AVsVrH9a7UITJIkqVOvE5aIOJ/SmJU3Az8BTgTuqFFckiSpt5pgHZZqzvDQzPwQsCgzvwocAuxYm7AkSZLWqWYdls5VbVdExPbAAmCXvg9JkiRVxVlC67k6IrYEzgJmlrf9pM8jkiRJ2kA1Cct3gI8Dh1NaMO6PwI9qEZTUk2sGT6h3CIUxZc2seoegAeQdJ99b7xAK47cX7dN/T+YsofVcTGntlXPL998H/Dfwnr4Oqln5xdI7JiuS1HyqSVgmZOa+FfdvjIh7+jogSZJUJWcJrecvETGp805EvBH4U9+HJEmStL7eXEvoPiCBwcCHIuLp8v2dgAdrG54kSVLvuoSOrXkUkiTplXPQLWTmU/0RiCRJUneqGXQrSZIaURMsHDfwz1CSJBWeFRZJkgoum2AMixUWSZLU8ExYJEkqumjp31tP4UQcHRGzIuLRiDi9mzZHRMTdEfFAREzv6Zh2CUmSpD4TEa3AD4CjgLnAnRFxZWY+WNFmS+CHwNGZ+XREbN3TcU1YJEkqusZamv9g4NHMfBwgIi4F3sn6i82+H7g8M58GyMx5PR20oc5QkiQ1voiYGhEzKm5TK3aPA+ZU3J9b3lZpd2B0RNwUETMj4kM9PacVFkmSCq6/Zwll5jRgWje7uwomN7g/CDgAeAswDLgtIm7PzEe6e04TFkmS1JfmAjtW3N8BeLaLNvMzczmwPCJuBvYFuk1Y7BKSJKnoGmuW0J3AbhGxS0QMAU4CrtygzRXA4RExKCKGA28EHtrUQa2wSJKkPpOZbRFxKvA7oBW4IDMfiIiPlfefn5kPRcR1wL1AB/CTzLx/U8c1YZEkqegabKXbzLwWuHaDbedvcP/bwLd7e0y7hCRJUsMzYZEkSQ3PLiFJkoquZeDXHwb+GUqSpMKzwiJJUsH198Jx9WCFRZIkNTwrLJIkFV1jXfywJgb+GUqSpMKzwiJJUsGlFRZJkqT6s8IiSVLROUtIkiSp/qywSJJUcI5hkSRJagBWWCRJKjrHsEiSJNWfFRZJkorOMSySJEn1Z8IiSZIanl1CkiQVXDroVpIkqf6ssEiSVHRNMOjWhEV6lfb58RlsfcwRrJ63gJv3O67e4UgDwsc+sD0H7TOSVas7OPsnc3nsqZUbtdlm7GBO//hOjBzRyqNPreQ70+bQ1p4AvGGPEXz0/dszqDVYsrSNz37rccZtO5TP/8P4tY/f7jVDuOR/X+A318/vt/PSK2fCIr1Kcy++nCd/+FMmXnBmvUORBoSD9hnJ9tsM4cOfm8Ueuw7n1A+N49Nff3Sjdn//nu34zfUvMv3Pizn178bx9r8azTU3LmTE8BZO/eA4vnD2E7y4cA2jRrYC8Mzzqzj1S7MBaAm45JzXc+vMxf16brWSOIZFUg8W3jKDNQsHxoee1Agm7bcFN/zpJQAefmwFmw9vZfSojf++3vf1m/PHO0vvvd/fsohD9h8FwBGTRvOnmYt5ceEaABYvbd/osRP33Jzn5q1m3oI1NToL9TUrLJKkhjJm9GDmL1y99v78RasZO3owixa3rd22xeatLF/RTkdHZ5s1jBk9GIAdth1Ca2tw5umvZdhmLVxx/XxuuPWl9Z5j8hu3ZPrt628rMi9+WCEiJkXEnRGxLCJWR0R7RCzZRPupETEjImZMmzatb6KVJA14Xc3QzexNm1KjlpZgt52H8aXvPsEXvvME7zt+G8ZtM2Rtu0GtwRv322JtdUbFUE2F5fvAScBlwIHAh4DXddc4M6cBnZlKdtdOkqRj3zKGoydvBcAjT6xg7FZDgBUAjB09hAUvrd91s3hpOyOGt9LSAh0dMHb0YBa+VKrAzF+0hiXL2lm1Olm1up37H1nOLuOH8cwLparNgfuM5LGnVvLSkjYGDCss68vMR4HWzGzPzAuBN9cmLElSM7n6hgWc+qXZnPql2dx21xLe8qYtAdhj1+EsX9m+XndQp3sfXsbhB5XGrbz1sNHc9pdS0f/2u5aw9+7DaWmBoUOCCa8dzpxnX177uCMmbclNA6g7qFlUU2FZERFDgLsj4izgOWBEbcKSimPiJWczZvLBDBk7miOfmM7sr53HnAt/Ve+wpMK6856lHLTPSC44awIvr+rgP/5r7tp9X/v0zpxz4VwWvtTGBb98ntM/Pp4PnbAtjz29kutvXgjAnOdWMeO+Zfzo67vTkfC7mxfy1DOrgFICs99em3PuRXO7fO6iaoaVbiM37BjsrmHETsA8YDDwaWAU8MNy1aUndgmpz1wzeEK9QyiUKWtm1TsEDSDvOPneeodQGL+9aJ9+yyIW3TO9X79nR+87ud8zpF5XWDLzqfKPK4Gv1iYcSZJULWcJVYiIYyPiLxGxMCKWRMTSTc0SkiRJ6ivVjGE5BzgBuC97248kSZJqrwnGsFRTQ5oD3G+yIkmS+ls1FZbPAtdGxHRgVefGzPxun0clSZJ6rRnGsFSTsHwTWAZsBgzpoa0kSVKfqSZh2Soz31azSCRJkrpRTQ3p9xFhwiJJUoNJol9v9VBNwvIJ4LqIWOm0ZkmS1J+qWThuZC0DkSRJr4yDbjcQEfsAO1c+LjMv7+OYJEmS1tPrhCUiLgD2AR4AOsqbEzBhkSSpnppg4bhqKiyTMnPPmkUiSZLUjWoSltsiYs/MfLBm0UiSpKplVXNoiqmahOViSknL85RWug0gM3OfmkQmSZJUVk3CcgHwQeA+1o1hkSRJdZaOYVnP05l5Zc0ikSRJ6kY1CcvDEfEz4CrWv/ihs4QkSaoj12FZ3zBKiUrl8vxOa5YkSTVXzUq3p9QyEEmS9MrU6/o+/amaheM2Az4M7AVs1rk9M/++BnFJkiStVU2n1yXAtsDbgenADsDSWgQlSZJ6L6OlX2/1UM2zvi4zvwgsz8yLgSnAG2oTliRJ0jrVJCxryv++FBF7A6MoXQhRkiSppqqZJTQtIkYDXwCuBDYHvliTqCRJUq+5cNz6RgGdM4V+UP63LSImZubdfRqVJElShWoSlgOAAyktHAelMSx3Ah+LiMsy86y+Dk6SJPXMac3rGwPsn5nLACLiy8CvgL8CZgImLJIkqSaqSVjGA6sr7q8BdsrMlRGxqpvHSJKkGnNp/vX9DLg9Iq4o3z8O+HlEjAAe7PPIJEmSyqpZmv/rEXEtcBgQwMcyc0Z59wdqEZwkSeqZY1g2kJkzKY1XkSRJ6jdVJSySJKnxNMMYloF/hpIkqfCssEiSVHDNMIbFCoskSWp4VlgkSSo4x7BIkiQ1ACsskiQVnGNYJEmSGoAVFmmAu2bwhHqHUAhT1syqdwiFsHTBonqHoCZlwqLC8Yul90xWpOaQYZeQJElS3VlhkSSp4DKtsEiSJNWdFRZJkgoum6D+MPDPUJIkFZ4VFkmSCs6F4yRJkhqAFRZJkgrOCoskSVIDsMIiSVLBWWGRJElqAFZYJEkqOCsskiRJDcAKiyRJBee1hCRJkhqACYskSepTEXF0RMyKiEcj4vRNtDsoItoj4sSejmmXkCRJBddIg24johX4AXAUMBe4MyKuzMwHu2h3JvC73hzXCoskSepLBwOPZubjmbkauBR4ZxftPgn8GpjXm4OasEiSVHBJ9OstIqZGxIyK29SKcMYBcyruzy1vWysixgHvAs7v7TnaJSRJkqqSmdOAad3s7qp/Kje4fw7wucxsj+hdd5YJiyRJBddIY1goVVR2rLi/A/DsBm0OBC4tJytjgWMioi0zf9PdQU1YJElSX7oT2C0idgGeAU4C3l/ZIDN36fw5Ii4Crt5UsgImLJIkFV4jLRyXmW0RcSql2T+twAWZ+UBEfKy8v9fjViqZsEiSpD6VmdcC126wrctEJTNP7s0xTVgkSSq4jsYaw1ITTmuWJEkNzwqLJEkF12CzhGrCCoskSWp4VlgkSSq4RpolVCtWWCRJUsOzwiJJUsE5hkWSJKkBmLBIkqSGZ5eQJEkF56BbSZKkBmCFRZKkgnPQrSRJUgOwwiJJUsE5hkWSJKkBmLBI6hf7/PgM3vrMrfzVX66qdygqmNOm7sql/3kwF517ALvvunmXbU6Ysj2X/ufB3HLVZEZtsa7zYPwOwzj/2/vxh8sP533v2qG/Qu53Hf18qwcTFkn9Yu7Fl3PHsR+pdxgqmEkHbMWO2w/npI/ewbd/8Aif+fhuXba776ElfOqL9/DcCy+vt33J0jbOmfYol/7vnP4IVzVkwiKpXyy8ZQZrFi6udxgqmMMnjeG6PzwPwAOzlrL5iEGMGT1ko3azH1/G8/NWbbT9pcVreHj2Utrasuax1lNm9OutHnqVsERES0TcX+tgJEmqNHbMUObNX5eIzFuwirFjNk5YNPD1KmHJzA7gnogY39sDR8TUiJgRETOmTZv2igOUJDWvLv+WH9jFklckiX691UM105q3Ax6IiDuA5Z0bM/P4rhpn5jSgM1Px10uS1CsnHLM9x719OwAemr2UrccOXbtv6zFDmb9wdb1CUx1Vk7B8tWZRSJJUdvm1z3L5tc8CcMiBW/HuY8fx+5tfZK8JI1m2oo0Fi0xYNtQM67D0OmHJzOm1DETSwDbxkrMZM/lghowdzZFPTGf2185jzoW/qndYanC3zVjIIQduxS+mHczLq9o543uz1u779pf35lvnPcKChas58bhxvP+EHdlq9BAuPvdAbpu5kDPPe4StthzMT/7jAEYMb6WjA/7m+B3423+4kxUr2+t4VnolInPTvTURsZSuu3QCyMzcohfPY5eQVAfXDJ5Q7xAKY8qaWT03Eocd59+uvXXLVZP7rexxy4PL+/V79rA9R/R7SafHCktmjuyPQCRJkrrjOiySJKnhefFDSZIKrqMJBl5YYZEkSQ3PCoskSQVXr8Xc+pMVFkmS1PCssEiSVHDNsHCcFRZJktTwrLBIklRwPawBOyBYYZEkSQ3PCoskSQXX4SwhSZKk+rPCIklSwTlLSJIkqQFYYZEkqeCcJSRJktQArLBIklRwXktIkiSpAZiwSJKkhmeXkCRJBdfhoFtJkqT6s8IiSVLBuXCcJElSA7DCIklSwblwnCRJUgOwwiJJUsF1uHCcJElS/VlhkSSp4BzDIkmS1ACssEiSVHCuwyJJktQArLBIklRwXktIkiSpAVhhkSSp4JwlJEmS1ABMWCRJUsOzS0iSpIJLl+aXJEmqPysskiQVnNOaJUmSGoAVFkkCrhk8od4hFMKh591d7xDUhWaY1mzCIg1gU9bMqncIhWCyIjU+ExZJkgquGSosjmGRJEkNzwqLJEkF15GuwyJJklR3VlgkSSo4x7BIkiQ1ACsskiQVnBUWSZKkBmCFRZKkgvNaQpIkSQ3AhEWSJDU8u4QkSSq4dOE4SZKk+rPCIklSwTmtWZIkqQFYYZEkqeCc1ixJktQArLBIklRwjmGRJElqAFZYJEkqOCsskiRJDcAKiyRJBecsIUmSpCpFxNERMSsiHo2I07vY/4GIuLd8uzUi9u3pmFZYJEkquEYawxIRrcAPgKOAucCdEXFlZj5Y0ewJYHJmLoqIdwDTgDdu6rhWWCRJUl86GHg0Mx/PzNXApcA7Kxtk5q2Zuah893Zgh54OaoVFkqSC6+jo3+eLiKnA1IpN0zJzWvnnccCcin1z2XT15MPAb3t6ThMWSZJUlXJyMq2b3dHVQ7psGPFmSgnLYT09pwmLJEnqS3OBHSvu7wA8u2GjiNgH+Anwjsxc0NNBTVgkSSq4Rhp0C9wJ7BYRuwDPACcB769sEBHjgcuBD2bmI705qAmLJEnqM5nZFhGnAr8DWoELMvOBiPhYef/5wJeAMcAPIwKgLTMP3NRxTVgkSSq4BquwkJnXAtdusO38ip8/AnykmmM6rVmSJDU8KyySJBWcS/NLkiQ1ACsskiQVXPb7IJaullqpLSsskiSp4VlhkSSp4BptllAtWGGRJEkNzwqLJEkF198XP6wHKyySJKnhWWGRpAazz4/PYOtjjmD1vAXcvN9x9Q6n3+2+YwvvfNNgIuCOh9q56e62jdoc/6bB7DG+hTVt8MsbV/PM/NIgjsP3aeWgPUpfbc8v6OCXN62hrR2OOnAQB79+EMtXltpdd8caHn564JQlHMMiSep3cy++nDuOrWrV8gEjAt512GD+65rVnP2LVUx8XStbj15/Cu0e41sYOyo46+er+PX01bzr8CEAbDEC3rT3IM799Sq++8tVRAvs+7rWtY/7471tnPOrVZzzq1UDKllpFlZYJKnBLLxlBsN2GlfvMOpix61bmL8kWbi0VDK457F29tq5lXmL1lVZ9ty5lbseaQfg6XnJsKEwcnhpX0sLDB5UGtMxZFCwZHkTlB5ojpVue52wRMRrge8BhwAdwG3ApzPz8RrFJklqMqNGwOJl6759Fy9LdtymZYM2wUsVbV5alowaEcx9MZl+Txv/+rebsaYNZs9tZ/bcdZWUQ/du5YDdW5n7YgdX37qGlatrfz7qO9V0Cf0M+CWwLbA9cBnw8+4aR8TUiJgRETOmTZv26qKUJDWvXlQPMmHYENhr51a+9T8v841LXmbwoGC/3UpdQrc90MaZP1vFOZetYsmK5NhDB9c46P6V2b+3eqimSygy85KK+z+NiFO7a5yZ04DOTKUJilWSpFdr8XIYtfm6MSujNg+WrMgN2iRbVrTZstzmdTu0sHBJsvzl0vb7n2hnp21b+MvsdpatXPf4Ox5q55R3DKnpeajvVVNhuTEiTo+InSNip4j4LHBNRGwVEVvVKkBJUvOYO6+DsaOC0SOD1hbYd9dWHnyyfb02Dz7Zzv67lyon47cOVq6GpStKXUPjt2lhcPlP8deNa2HeolKXUOcYF4C9d2nh+YUOui2aaios7y3/+9ENtv89pQrKa/skIklqchMvOZsxkw9myNjRHPnEdGZ/7TzmXPireofVLzoSrrhlDR+ZMoSWgDtntfPComTSnqUE5fYH23n46Q72GJ987n1DWd0Gl91UGowyZ15y3+PtnPbuoXQkPDO/gz8/WEp2jpk0mO3HlP5GX7Q0+fXNA2sAS/b7qNv+v/hh9NMVHu0SktSwrhk8od4hFMb08+6udwiFcdbHhvXbt/p3Lu/fjOUzJ7T0e8ZSzSyh4cA/AeMzc2pE7AZMyMyraxadJEnqUTNMa65mDMuFwGrg0PL9ucA3+jwiSZKkDVSTsOyamWcBawAycyX16MSSJEnraYZpzdUkLKsjYhjl8SgRsSuwqiZRSZIkVahmltBXgOuAHSPif4A3AafUIihJktR7HU0wiKXXCUtmXh8RM4FJlLqCTsvM+TWLTJIkqayaWUI3ZOZbgGu62CZJkuqkXuNK+lOPCUtEbAYMB8ZGxGjWDbTdgtI1hSRJkmqqNxWWjwKfopSczKSUsCSwFPh+zSKTJEm90gwVlh5nCWXm9zJzF+CbwMTyzxcCjwO31Tg+SZKkqqY1n5iZSyLiMOAo4CLgRzWJSpIk9VpHZr/e6qGahKXzcplTgPMz8wrA63NLkqSaq2Ydlmci4j+BtwJnRsRQqkt4JElSDWRHvSOovWoSjvcAvwOOzsyXgK2Af6lFUJIkSZWqWThuBXB5xf3ngOdqEZQkSVKlarqEJElSA8ommNfsGBRJktTwrLBIklRwHQ66lSRJqj8rLJIkFZxjWCRJkhqAFRZJkgquY+AXWKywSJKkxmeFRZKkgssmKLFYYZEkSQ3PCoskSQXXBJOErLBIkqTGZ4VFkqSC63AMiyRJUv1ZYZEkqeBc6VaSJKkBmLBIkqSGZ5eQJEkFlx31jqD2rLBIkqSGZ4VFkqSC63DQrSRJUv1ZYZEkqeCc1ixJktQArLBIklRwLs0vSZLUAPqlwnLYcdP742kGhFuumlzvEBreO06+t94hFMbSBYvqHUIhHHre3fUOoTAmf3JivUMojo/N6renaoIhLFZYJElS43MMiyRJBZeOYZEkSao/KyySJBWcK91KkiQ1ACsskiQVnGNYJEmSGoAJiyRJanh2CUmSVHB2CUmSJDUAKyySJBVcExRYrLBIkqTGZ4VFkqSCcwyLJElSA7DCIklSwaVL80uSJNWfFRZJkgquwzEskiRJ9WeFRZKkgnMMiyRJUgOwwiJJUsG5DoskSVIDsMIiSVLBWWGRJElqACYskiSp4dklJElSwXU4rVmSJKn+rLBIklRwDrqVJElqACYskiQVXGb2660nEXF0RMyKiEcj4vQu9kdEnFvef29E7N/TMU1YJElSn4mIVuAHwDuAPYH3RcSeGzR7B7Bb+TYV+FFPx3UMiyRJBdfRWGNYDgYezczHASLiUuCdwIMVbd4J/HeWyjW3R8SWEbFdZj7X3UGtsEiSpL40DphTcX9ueVu1bdZjhUWSpILr71lCETGVUldOp2mZOa1zdxcP2TDA3rRZjwmLJEmqSjk5mdbN7rnAjhX3dwCefQVt1mOXkCRJBddgs4TuBHaLiF0iYghwEnDlBm2uBD5Uni00CVi8qfErYIVFkiT1ocxsi4hTgd8BrcAFmflARHysvP984FrgGOBRYAVwSk/HNWGRJKngsqOj3iGsJzOvpZSUVG47v+LnBD5RzTHtEpIkSQ3PCoskSQXXYOuw1IQVFkmS1PAGbIXltKm7csgBY3h5VTtnfG8Wjzy2bKM2J0zZnvccvwM7bD+MKR/4E4uXtAFw1OSt+cC7S7OtVr7cztk/nM2jTy7v1/hVfx/7wPYctM9IVq3u4OyfzOWxp1Zu1GabsYM5/eM7MXJEK48+tZLvTJtDW3vpL5037DGCj75/ewa1BkuWtvHZbz3OuG2H8vl/GL/28du9ZgiX/O8L/Ob6+f12XrX2at5743cYxr+etge777o5P77kCX7+v3P7O/ya2X3HFt75psFEwB0PtXPT3W0btTn+TYPZY3wLa9rglzeu5pn5pd+lw/dp5aA9Sh/Xzy/o4Jc3raGtHY46cBAHv34Qy1eW2l13xxoefrqxxjLU0j4/PoOtjzmC1fMWcPN+x9U7HNXYgExYJh2wFTtuP5yTPnoHe00YyWc+vhtTP/OXjdrd99ASbr3zHs47Y+J625974WU++fl7WLq8jUkHbMVnT929y8dr4Dpon5Fsv80QPvy5Weyx63BO/dA4Pv31Rzdq9/fv2Y7fXP8i0/+8mFP/bhxv/6vRXHPjQkYMb+HUD47jC2c/wYsL1zBqZCsAzzy/ilO/NBuAloBLznk9t85c3K/nVkuv9r23ZGkb50x7lL+aNKafIu4fEfCuwwbz46tXs3h58skThvLgU+3MW7SujL/H+BbGjgrO+vkqxm8dvOvwIXz/f1exxQh4096D+M4vVtHWDh84ajD7vq6VmbPaAfjjvW3cfM/GyU8zmHvx5Tz5w58y8YIz6x1K3fXmgoRFNyC7hA6fNIbr/vA8AA/MWsrmIwYxZvSQjdrNfnwZz89btdH2+x9ewtLlpQ+ABx5ewmvGDq1twGo4k/bbghv+9BIADz+2gs2HtzJ61Mb5/b6v35w/3llKOH5/yyIO2X8UAEdMGs2fZi7mxYVrAFi8tH2jx07cc3Oem7eaeQvW1Ogs+t+rfe+9tHgND89eSlvbwPrw3XHrFuYvSRYuTdo74J7H2tlr59b12uy5cyt3PVL6PXl6XjJsKIwcXtrX0gKDB5WS3CGDgiXLB9br80otvGUGaxYOnIRfm9brCkv56otTgJ0rH5eZ3+37sF6dsWOGMm/+ug/DeQtWMXbMEBYsWl31sY5927bcPnNhX4anAhgzejDzF677fZm/aDVjRw9m0eJ1f8lusXkry1e00zmbcP6iNYwZPRiAHbYdQmtrcObpr2XYZi1ccf18brj1pfWeY/Ibt2T67etvK7q+fO8NJKNGwOJl65KMxcuSHbdp2aBN8FJFm5eWJaNGBHNfTKbf08a//u1mrGmD2XPbmT13XbfPoXu3csDurcx9sYOrb13DyuZ+qZtWfy/NXw/VVFiuAk4GxgAjK25dioipETEjImY8/9RVryrIanV1gYJNX6Gga/u9YUumHLUtP7ro8Vcbkgomuvgl2rDi2nWbUqOWlmC3nYfxpe8+wRe+8wTvO34bxm2zrtIwqDV4435brK3ODBR99d5rCr14XTJh2BDYa+dWvvU/L/ONS15m8KBgv91K1ZnbHmjjzJ+t4pzLVrFkRXLsoYNrHLRUP9WMYdkhM/fpbePK6wwcdtz0mn9knXDM9hz39u0AeGj2Urau6MbZeszQ9f5a7o1ddx7B6Z/cnc985T6WLG3O/uFmc+xbxnD05K0AeOSJFYzdagilBRhh7OghLHhp/a6bxUvbGTG8lZYW6OiAsaMHs/Cl0u/K/EVrWLKsnVWrk1Wr27n/keXsMn4Yz7xQ+j08cJ+RPPbUSl5aUvzfrb5+7w1Ei5fDqM3XpXOjNg+WrMgN2iRbVrTZstzmdTu0sHBJsvzl0vb7n2hnp21b+MvsdpZVjAO/46F2TnnHxt1vag5WWNb324h4W80ieZUuv/ZZTjltJqecNpM/3j6fo4/cFoC9Joxk2Yq2qkrS27xmKN/8/F58/bsPM+fZjWeGaGC6+oYFnPql2Zz6pdncdtcS3vKmLQHYY9fhLF/Zvl53UKd7H17G4QeVxq289bDR3PaXJQDcftcS9t59OC0tMHRIMOG1w5nz7MtrH3fEpC25aYB0B/Xle2+gmjuvg7GjgtEjg9YW2HfXVh58cv1xTQ8+2c7+u5cqJ+O3DlauhqUrSl1D47dpYXD5z8vXjWth3qJSl1DnGBeAvXdp4fmFzTNDSM2nmgrL7cD/RkQLsIZS9Tczc4uaRPYq3DZjIYccuBW/mHbw2qmVnb795b351nmPsGDhak48bhzvP2FHtho9hIvPPZDbZi7kzPMe4eSTdmLUFoP454/vBkB7e/KRf7qrXqejOrjznqUctM9ILjhrAi+v6uA//mvd9NqvfXpnzrlwLgtfauOCXz7P6R8fz4dO2JbHnl7J9TeXxjvNeW4VM+5bxo++vjsdCb+7eSFPPVMa2zF0SLDfXptz7kUDZ8pup1f73ttqy8H85D8OYMTwVjo64G+O34G//Yc7WbFy40HLRdKRcMUta/jIlCG0BNw5q50XFiWT9iwlKLc/2M7DT3ewx/jkc+8byuo2uOymUqI3Z15y3+PtnPbuoXQkPDO/gz8/WHo9jpk0mO3HlP7uXLQ0+fXNzZUcTrzkbMZMPpghY0dz5BPTmf2185hz4a/qHVZddOTAT1ajt1OhIuJx4K+B+7LK+VP90SU0UNxy1eR6h9Dw3nHyvfUOoTCWLlhU7xAK4dApB9c7hMKY/MmJ9Q6hMKasmdXlsK5aOOEfH+3X79nLz31dv51bp2oqLLOB+6tNViRJUm01wxiWahKW54CbIuK3wNp5i404rVmSJA0s1SQsT5RvQ8o3SZLUAKywVMjMr9YyEEmSpO5Us9LtjXSx1FFmHtmnEUmSpKo0w/DSarqEPlPx82bAu4Hir3olSZIaXjVdQjM32PSniJjex/FIkqQqdXQM/HVYqukS2qribgtwILBtn0ckSZK0gWq6hGZSGsMSlFa6fRL4cA1ikiRJWk81CcvngOsyc0lEfBHYn84rw0mSpLpphmnN1Vz88AvlZOUw4CjgIuBHNYlKkiSpQjUJS+fVx6YA52fmFbiAnCRJdZfZ0a+3eqgmYXkmIv4TeA9wbUQMrfLxkiRJr0g1Y1jeAxwNfCczX4qI7YB/qU1YkiSpt5phDEs167CsAC6vuP8cpQsiSpIk1VQ1FRZJktSAmqHC4hgUSZLU8KywSJJUcB11mrnTn6ywSJKkhmeFRZKkgnMMiyRJUgOwwiJJUsFlh2NYJEmS6s4KiyRJBecYFkmSpAZgwiJJkhqeXUKSJBVcunCcJElS/VlhkSSp4DocdCtJklR/VlgkSSo4F46TJElqAFZYJEkqOBeOkyRJagBWWCRJKjjXYZEkSWoAVlgkSSo4x7BIkiQ1ACsskiQVnOuwSJIkNYDIHPj9Xl2JiKmZOa3ecRSBr1Xv+Dr1nq9V7/g69Y6vU3No5grL1HoHUCC+Vr3j69R7vla94+vUO75OTaCZExZJklQQJiySJKnhNXPCYn9n7/la9Y6vU+/5WvWOr1Pv+Do1gaYddCtJkoqjmSsskiSpIExYJElSwzNhkdQvImJZvWNoZBHxqYgYXu84pEZVqISlFm/oiPjriNjzFTzu+Ig4vS9jeQUx7BwR91fR/uSI2L4Xbb7/KuP6WkS89dUcQ80hIlrrHUMD+RRgwiJ1o1AJC7V5Q/810GXCEhHdXmspM6/MzG/1cSy1djKwyYSlL2TmlzLz97V+nr4UEV+MiIcj4v8i4ucR8ZmI+H8RcWdE3BMRv+5MliPiooj4UUTcGBGPR8TkiLggIh6KiIsqjrksIs6MiJkR8fuIODgibio/5vhym50j4o8RcVf5dmidXoJ+ExFHlF+7nwH31TueeoiIERFxTfl36/6I+DKl9+aNEXFjuc3bIuK28u/FZRGxeXn7k+XfqzvKt9fV81xqqYvX6b3l8x9b3n9gRNxU/vkrEXFxRFxfbnNCRJwVEfdFxHURMbiuJ6NXrWETlv54Q5e/HI4Hvh0Rd0fEruUvlDMiYjpwWkQcFxF/joi/lL90tik/dm0lovwFdm5E3Fr+MjqxH16iToPKb9J7I+JXETE8Ir5U/qK9PyKmRcmJwIHA/5TPdVhEHFSO+Z7y6zSyfMzty2/w2RFxVndPHBGt5XO/v/yh8Ony9osi4sTyh8nd5dt9EZHl/buWjz+z/GW9R81fpU2IiAOBdwP7ASdQep0ALs/MgzJzX+Ah4MMVDxsNHAl8GrgK+A9gL+ANETGx3GYEcFNmHgAsBb4BHAW8C/hauc084KjM3B94L3BuLc6xAR0M/FtmVl3dHCCOBp7NzH0zc2/gHOBZ4M2Z+ebyF/IXgLeWfzdmAP9U8fglmXkw8P3yYweqDV+n63povyswBXgn8FPgxsx8A7CyvF0F1rAJC/3whs7MW4ErgX/JzImZ+Vh515aZOTkzzwZuASZl5n7ApcBnu4l3O+Aw4FigPysvE4BpmbkPsAT4B+D75S/avYFhwLGZ+StKr9EHMnMi0A78Ajit/IX8VkpvaoCJlL483wC8NyJ27Oa5JwLjMnPv8ofChZU7M3NG+XWdSOmD5jvlXdOAT5a/yD8D/PDVvQSv2mHAFZm5MjOXUkpAAPYuJ1T3AR+glJB0uipLawLcB7yQmfdlZgfwALBzuc1q1n3A3gdMz8w15Z872wwGflx+jsvopto3AN2RmU/UO4g6ug94a/kPq8Mzc/EG+ydR+l34U0TcDfwdsFPF/p9X/HtIrYOto55epw39tuI91sr677+daxem+kO3XR4N4D7gOxFxJnB1Zv4xIir3V76hAYYAt1Xsr3xD/0eVz/2Lip93AH4REduVn6O7D9nflL+wHuyswvSTOZn5p/LPPwX+EXgiIj5LqftsK0pfoldt8LgJwHOZeSdAZi4BKL+WN3R+METEg5Q+KOd08dyPA6+NiPOAa4DruwowIt4D7A+8rVwFOxS4rOL/c2iV59zXopvtFwF/nZn3RMTJwBEV+1aV/+2o+Lnzfuf7ak2uW+hobbvM7Ih13Y2fBl4A9qX0B8TLr/gsimV5vQOop8x8JCIOAI4B/j0iNnzvBPB/mfm+7g7Rzc8DSjevUxvr/tjebIOHVL7HNnz/NfL3nXqhYSssmfkIcAClxOXfI+JLGzTpfENPLN/2zMzKkv2reUNXfpieR6li8Qbgo2z8BulU+aXV3RdgLWx4bkmpYnFiOeYf03XM0cVjO1WeSzvdvNEzcxGlL9qbgE8AP9noSSL2Ar4KnJSZ7ZR+516q+H+bmJmv7yaO/nILcFxEbFZOqDpLxyOB58p93x+o0XOPopQ4dgAfpPRXoQa4KA1+X5GZP6VUedyfUrdhZ7fs7cCbOruzy129u1cc4r0V/1b+oTagdPM6PUnpuwFKXblqEg2bsPTjG7rymF0ZBTxT/vnvqjqJ/jE+IjpLwu+j9OULML/85Vs5nqbyXB+mNFblIICIGBmbGGTclXK3XEtm/hr4IqX/o8r9oyh1o30oM1+EtZWcJyLib8ptIiL2reZ5+1q5ynQlcA9wOaWus8WUzunPwP9Rer1q4YfA30XE7cDuNHnloYm8Abij3N3zb5TGN00DfhsRN5bfLycDP4+Ieyl93lWO9RoaEX8GTqNUpRuounqdvgp8LyL+SOkPKjWJhl2aPyLeDnybUilvDfBxSn21n6D0F+mbI+JI4EzWdSl8ITOvjIgnKY2nOIZSUva+zHy0m+d5E6UqxCpKX+7/BXwmM2eU97+TUpfSM5Q+NA7KzCPKXQQHZuapUZoZcnV5nAgRsSwzN+/L16Ob2HcGrgVuptTNMpvSX+n/CpxE6S+ROcBTmfmViHg3cAalsSqHAHtTqiANK297K6XX4MDMPLX8HFcD38nMm7p4/n0pvc6die/nM/O3na8HpUGn51HqOgIgMydGxC7AjyiN+xkMXJqZX6OOImLzzFwWpZlANwNTM/OuesYkdaX8+XZgZs6vdyxSf2rYhOXV8A2takVpiu2elLrPLs7Mf69zSFKX/HxTszJhkSRJDW9AJixdiYh/A/5mg82XZeY36xFP0ZT7yzeczfPBzGzKhb8kSf2raRIWSZJUXA07S0iSJKmTCYskSWp4JiySJKnhmbBIkqSG9/8BfzgUKNmHDFoAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] @@ -5609,7 +6193,241 @@ ], "source": [ "fig, ax = plt.subplots(figsize=(10,10)) \n", - "sns.heatmap(df_CategoricalDQN.corr()[df_CategoricalDQN.corr() > 0.05], annot = True, fmt='.2g',cmap= 'coolwarm', ax=ax)" + "sns.heatmap(df_CategoricalDQN.corr()[abs(df_CategoricalDQN.corr()) > 0.05], annot = True, fmt='.2g',cmap= 'coolwarm', ax=ax)" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
stepsum
algostep_trainbatch_sizegammagreedy_explorationnetworkoptimizerlrmemoriesmax_size
CategoricalDQN1.064.00.95EpsilonGreedy-0.1C51NetworkAdam0.0010ExperienceReplay20481.01.01.0
32.064.01.00AdaptativeEpsilonGreedy-0.8-0.2-10000-0C51NetworkAdam0.0001ExperienceReplay5121.01.01.0
1.064.00.95AdaptativeEpsilonGreedy-0.3-0.1-30000-0C51NetworkAdam0.0001ExperienceReplay2048NaNNaNNaN
512NaNNaNNaN
0.0010ExperienceReplay2048NaNNaNNaN
.......................................
DoubleDQN32.064.01.00EpsilonGreedy-0.6SimpleDuelingNetworkAdam0.0010ExperienceReplay512NaNNaNNaN
SimpleNetworkAdam0.0001ExperienceReplay2048NaNNaNNaN
512NaNNaNNaN
0.0010ExperienceReplay2048NaNNaNNaN
512NaNNaNNaN
\n", + "

576 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " \\\n", + "algo step_train batch_size gamma greedy_exploration network optimizer lr memories max_size \n", + "CategoricalDQN 1.0 64.0 0.95 EpsilonGreedy-0.1 C51Network Adam 0.0010 ExperienceReplay 2048 1.0 \n", + " 32.0 64.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 C51Network Adam 0.0001 ExperienceReplay 512 1.0 \n", + " 1.0 64.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 C51Network Adam 0.0001 ExperienceReplay 2048 NaN \n", + " 512 NaN \n", + " 0.0010 ExperienceReplay 2048 NaN \n", + "... ... \n", + "DoubleDQN 32.0 64.0 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 NaN \n", + " SimpleNetwork Adam 0.0001 ExperienceReplay 2048 NaN \n", + " 512 NaN \n", + " 0.0010 ExperienceReplay 2048 NaN \n", + " 512 NaN \n", + "\n", + " step \\\n", + "algo step_train batch_size gamma greedy_exploration network optimizer lr memories max_size \n", + "CategoricalDQN 1.0 64.0 0.95 EpsilonGreedy-0.1 C51Network Adam 0.0010 ExperienceReplay 2048 1.0 \n", + " 32.0 64.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 C51Network Adam 0.0001 ExperienceReplay 512 1.0 \n", + " 1.0 64.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 C51Network Adam 0.0001 ExperienceReplay 2048 NaN \n", + " 512 NaN \n", + " 0.0010 ExperienceReplay 2048 NaN \n", + "... ... \n", + "DoubleDQN 32.0 64.0 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 NaN \n", + " SimpleNetwork Adam 0.0001 ExperienceReplay 2048 NaN \n", + " 512 NaN \n", + " 0.0010 ExperienceReplay 2048 NaN \n", + " 512 NaN \n", + "\n", + " sum \n", + "algo step_train batch_size gamma greedy_exploration network optimizer lr memories max_size \n", + "CategoricalDQN 1.0 64.0 0.95 EpsilonGreedy-0.1 C51Network Adam 0.0010 ExperienceReplay 2048 1.0 \n", + " 32.0 64.0 1.00 AdaptativeEpsilonGreedy-0.8-0.2-10000-0 C51Network Adam 0.0001 ExperienceReplay 512 1.0 \n", + " 1.0 64.0 0.95 AdaptativeEpsilonGreedy-0.3-0.1-30000-0 C51Network Adam 0.0001 ExperienceReplay 2048 NaN \n", + " 512 NaN \n", + " 0.0010 ExperienceReplay 2048 NaN \n", + "... ... \n", + "DoubleDQN 32.0 64.0 1.00 EpsilonGreedy-0.6 SimpleDuelingNetwork Adam 0.0010 ExperienceReplay 512 NaN \n", + " SimpleNetwork Adam 0.0001 ExperienceReplay 2048 NaN \n", + " 512 NaN \n", + " 0.0010 ExperienceReplay 2048 NaN \n", + " 512 NaN \n", + "\n", + "[576 rows x 3 columns]" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "columns = [\"algo\",\"step_train\",\"batch_size\",\"gamma\",\"greedy_exploration\",\"network\",\"optimizer\",\"lr\",\"memories\",\"max_size\"]\n", + "df_CategoricalDQN[df_CategoricalDQN[\"sum\"] >= 500].groupby(by=columns).count().sort_values(by=['sum'], ascending=False)" ] }, { diff --git a/results/README.md b/results/README.md index b711526..997a44c 100644 --- a/results/README.md +++ b/results/README.md @@ -6,7 +6,7 @@ There are one subdirectory by environment used. ## CartPole -Example with agent: DQN, network: SimpleNetwork, Algo: Adam, Memorie: ExperienceReplay(max_size=32), Step train: 1, Batch size: 64, Gamma: 0.99, Exploration: EpsilonGreedy(0.1), Learning rate: 0.001 +Example with agent: DQN, network: SimpleNetwork, Algo: Adam, Memorie: ExperienceReplay(max_size=2048), Step train: 1, Batch size: 32, Gamma: 0.95, Exploration: AdaptativeEpsilonGreedy(0.8, 0.2, 10000, 0), Learning rate: 0.0001 ![CartPoleExemple.gif](./ressources/cartpole.gif) @@ -23,85 +23,125 @@ We test to train all this agent with this parameters. We train agent with 300 max_step. * Agent - * Algo : [DQN, DoubleDQN, DuelingDQN, CategoricalDQN] + * Algo : [DQN, DoubleDQN, CategoricalDQN] - * Step train : [1, 4, 32] + * Step train : [1, 32] - * Batch size : [1, 32, 64] + * Batch size : [32, 64] - * Gamma : [0.99] + * Gamma : [1.0, 0.99, 0.95] - * Exploration : [EpsilonGreedy(0.1), - EpsilonGreedy(0.6), - AdaptativeEpsilonGreedy(0.3, 0.1, 50000, 0), - AdaptativeEpsilonGreedy(0.8, 0.2, 50000,² 0)] + * Exploration : [EpsilonGreedy(0.1), EpsilonGreedy(0.6), AdaptativeEpsilonGreedy(0.3, 0.1, 30000, 0), + AdaptativeEpsilonGreedy(0.8, 0.2, 10000, 0)] + * Network -For _DQN, DoubleDQN_ : SimpleNetwork - -For _DuelingDQN_ : SimpleDuelingNetwork +For _DQN, DoubleDQN_ : SimpleNetwork, SimpleDuelingNetwork For _CategoricalDQN_ : C51Network + * Optimizer * Algo : Adam - * Learning rate : [0.1, 0.001, 0.001] + * Learning rate : [0.1, 0.001, 0.0001] * Memories * Algo : [ExperienceReplay] + * max_size: [512, 2048] ### Result analysis -We stop training at 500 step. We can find differant result if we add more training step. +We stop training at 300 step. We can find different result if we add more training step. #### Agent performance -DQN, DoubleDQN and DuelingDQN can reach in 500(max) steps. CategoricalDQN reach ~400 steps. +DQN, DoubleDQN, CategoricalDQN can reach 500 rewards in 300 (max) steps. * DQN -500 step is read with after 166 episode with this parameters. +500 step is reach with after 30 episode with this parameters. + +with SimpleNetwork: + +| algo | step_train | batch_size | gamma | greedy_exploration | network | optimizer | lr | memories | max_size | step | max | min | avg | sum | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +|DQN|1.0|32.0|1.00|EpsilonGreedy-0.6|SimpleNetwork|Adam|0.001|ExperienceReplay|2048|30.0|1.0|1.0|1.0|500.0| +|DQN|1.0|64.0|0.99|EpsilonGreedy-0.6|SimpleNetwork|Adam|0.001|ExperienceReplay|2048|30.0|1.0|1.0|1.0|500.0| +|DQN|1.0|64.0|0.99|AdaptativeEpsilonGreedy-0.3-0.1-30000-0|SimpleNetwork|Adam|0.100|ExperienceReplay|2048|40.0|1.0|1.0|1.0|500.0| +|DQN|1.0|64.0|0.95|EpsilonGreedy-0.6|SimpleNetwork|Adam|0.001|ExperienceReplay|512|50.0|1.0|1.0|1.0|500.0| +|DQN|1.0|64.0|1.00|AdaptativeEpsilonGreedy-0.3-0.1-30000-0|SimpleNetwork|Adam|0.001|ExperienceReplay|512|50.0|1.0|1.0|1.0|500.0| +|DQN|1.0|32.0|0.99|AdaptativeEpsilonGreedy-0.8-0.2-10000-0|SimpleNetwork|Adam|0.001|ExperienceReplay|2048|60.0|1.0|1.0|1.0|500.0| +|DQN|1.0|64.0|0.99|AdaptativeEpsilonGreedy-0.3-0.1-30000-0|SimpleNetwork|Adam|0.100|ExperienceReplay|2048|60.0|1.0|1.0|1.0|500.0| +|DQN|1.0|64.0|1.00|AdaptativeEpsilonGreedy-0.8-0.2-10000-0|SimpleNetwork|Adam|0.100|ExperienceReplay|512|60.0|1.0|1.0|1.0|500.0| +|DQN|1.0|64.0|1.00|EpsilonGreedy-0.6|SimpleNetwork|Adam|0.100|ExperienceReplay|512|60.0|1.0|1.0|1.0|500.0| +|DQN|1.0|64.0|0.95|AdaptativeEpsilonGreedy-0.8-0.2-10000-0|SimpleNetwork|Adam|0.001|ExperienceReplay|512|70.0|1.0|1.0|1.0|500.0| +|DQN|1.0|64.0|0.99|AdaptativeEpsilonGreedy-0.3-0.1-30000-0|SimpleNetwork|Adam|0.001|ExperienceReplay|2048|70.0|1.0|1.0|1.0|500.0| +|DQN|1.0|64.0|1.00|AdaptativeEpsilonGreedy-0.3-0.1-30000-0|SimpleNetwork|Adam|0.001|ExperienceReplay|2048|70.0|1.0|1.0|1.0|500.0| +|DQN|1.0|32.0|0.99|AdaptativeEpsilonGreedy-0.3-0.1-30000-0|SimpleNetwork|Adam|0.001|ExperienceReplay|512|80.0|1.0|1.0|1.0|500.0| +|DQN|1.0|32.0|0.99|AdaptativeEpsilonGreedy-0.8-0.2-10000-0|SimpleNetwork|Adam|0.100|ExperienceReplay|512|80.0|1.0|1.0|1.0|500.0| +|DQN|1.0|32.0|1.00|EpsilonGreedy-0.6|SimpleNetwork| Adam|0.001|ExperienceReplay|512|80.0|1.0|1.0|1.0|500.0 + +with SimpleDuelingNetwork: | algo | step_train | batch_size | gamma | greedy_exploration | network | optimizer | lr | memories | max_size | step | max | min | avg | sum | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| DQN | 1.0 | 32.0 | 0.99 | AdaptativeEpsilonGreedy-0.3-0.1-50000-0 | SimpleNetwork | Adam | 0.0010 | ExperienceReplay | 128 | 166.0 | 1.0 | 1.0 | 1.0 | 500.0 | -| DQN | 1.0 | 64.0 | 0.99 | EpsilonGreedy-0.1 | SimpleNetwork | Adam | 0.0010 | ExperienceReplay | 16 | 166.0 | 1.0 | 1.0 | 1.0 | 500.0 | -| DQN | 32.0 | 64.0 | 0.99 | AdaptativeEpsilonGreedy-0.3-0.1-50000-0 | SimpleNetwork | Adam | 0.1000 | ExperienceReplay | 16 | 166.0 | 1.0 | 1.0 | 1.0 | 500.0 | +|DQN|1.0|64.0|0.95|AdaptativeEpsilonGreedy-0.8-0.2-10000-0|SimpleDuelingNetwork|Adam|0.001|ExperienceReplay|512|30.0|1.0|1.0|1.0|500.0| +|DQN|1.0|32.0|0.95|EpsilonGreedy-0.6|SimpleDuelingNetwork|Adam|0.001|ExperienceReplay|512|40.0|1.0|1.0|1.0|500.0| +|DQN|1.0|32.0|0.99|EpsilonGreedy-0.1|SimpleDuelingNetwork|Adam|0.001|ExperienceReplay|2048|40.0|1.0|1.0|1.0|500.0| +|DQN|1.0|32.0|1.00|EpsilonGreedy-0.1|SimpleDuelingNetwork|Adam|0.001|ExperienceReplay|512|40.0|1.0|1.0|1.0|500.0| +|DQN|1.0|64.0|0.95|EpsilonGreedy-0.6|SimpleDuelingNetwork|Adam|0.001|ExperienceReplay|512|40.0|1.0|1.0|1.0|500.0| +|DQN|1.0|64.0|0.99|EpsilonGreedy-0.6|SimpleDuelingNetwork|Adam|0.001|ExperienceReplay|2048|40.0|1.0|1.0|1.0|500.0| +|DQN|1.0|32.0|0.95|EpsilonGreedy-0.1|SimpleDuelingNetwork|Adam|0.001|ExperienceReplay|512|50.0|1.0|1.0|1.0|500.0| +|DQN|1.0|32.0|1.00|AdaptativeEpsilonGreedy-0.3-0.1-30000-0|SimpleDuelingNetwork|Adam|0.001|ExperienceReplay|2048|50.0|1.0|1.0|1.0|500.0| +|DQN|1.0|64.0|0.95|AdaptativeEpsilonGreedy-0.3-0.1-30000-0|SimpleDuelingNetwork|Adam|0.001|ExperienceReplay|512|50.0|1.0|1.0|1.0|500.0| +|DQN|1.0|64.0|0.99|AdaptativeEpsilonGreedy-0.3-0.1-30000-0|SimpleDuelingNetwork|Adam|0.001|ExperienceReplay|2048|50.0|1.0|1.0|1.0|500.0| +|DQN|1.0|32.0|0.99|AdaptativeEpsilonGreedy-0.3-0.1-30000-0|SimpleDuelingNetwork|Adam|0.001|ExperienceReplay|2048|60.0|1.0|1.0|1.0|500.0| +|DQN|1.0|32.0|1.00|AdaptativeEpsilonGreedy-0.3-0.1-30000-0|SimpleDuelingNetwork|Adam|0.001|ExperienceReplay|512|60.0|1.0|1.0|1.0|500.0| +|DQN|1.0|64.0|0.99|AdaptativeEpsilonGreedy-0.3-0.1-30000-0|SimpleDuelingNetwork|Adam|0.001|ExperienceReplay|2048|60.0|1.0|1.0|1.0|500.0| * DoubleDQN -Same for doubleDQN but less training reach 500 step and need more episode to reach that. +500 step is reach with after 20 episode with this parameters with SimpleDuelingNetwork. + +with SimpleNetwork: | algo | step_train | batch_size | gamma | greedy_exploration | network | optimizer | lr | memories | max_size | step | max | min | avg | sum | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -|DoubleDQN|1.0|64.0|0.99|EpsilonGreedy-0.6|SimpleNetwork|Adam|0.0001|ExperienceReplay|128|332.0|1.0|1.0|1.0|500.0| - -* DuelingDQN +|DoubleDQN|1.0|32.0|1.00|EpsilonGreedy-0.1|SimpleNetwork|Adam|0.0010|ExperienceReplay|512|30.0|1.0|1.0|1.0|500.0| +|DoubleDQN|1.0|32.0|0.99|EpsilonGreedy-0.1|SimpleNetwork|Adam|0.0010|ExperienceReplay|2048|40.0|1.0|1.0|1.0|500.0| +|DoubleDQN|32.0|64.0|0.99|AdaptativeEpsilonGreedy-0.3-0.1-30000-0|SimpleNetwork|Adam|0.1000|ExperienceReplay|2048|40.0|1.0|1.0|1.0|500.0| +|DoubleDQN|1.0|64.0|0.95|EpsilonGreedy-0.6|SimpleNetwork|Adam|0.0010|ExperienceReplay|512|90.0|1.0|1.0|1.0|500.0| +|DoubleDQN|1.0|64.0|1.00|EpsilonGreedy-0.6|SimpleNetwork|Adam|0.0010|ExperienceReplay|2048|100.0|1.0|1.0|1.0|500.0| +|DoubleDQN|1.0|64.0|0.95|EpsilonGreedy-0.6|SimpleNetwork|Adam|0.0010|ExperienceReplay|512|150.0|1.0|1.0|1.0|500.0| -Only two train reach 500 for duelingDQN +with SimpleDuelingNetwork: | algo | step_train | batch_size | gamma | greedy_exploration | network | optimizer | lr | memories | max_size | step | max | min | avg | sum | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -|DuelingDQN|4.0|32.0|0.99|AdaptativeEpsilonGreedy-0.8-0.2-50000-0|SimpleDuelingNetwork|Adam|0.0001|ExperienceReplay|16 |498.0 |1.0|1.0|1.0|500.0| -|DuelingDQN|4.0|64.0|0.99|EpsilonGreedy-0.6|SimpleDuelingNetwork|Adam|0.0001|ExperienceReplay|32|498.0|1.0|1.0|1.0|500.0| +|DoubleDQN|1.0|32.0|1.00|AdaptativeEpsilonGreedy-0.8-0.2-10000-0|SimpleDuelingNetwork|Adam|0.0010|ExperienceReplay|2048|20.0|1.0|1.0|1.0|500.0| +|DoubleDQN|1.0|64.0|1.00|EpsilonGreedy-0.6|SimpleDuelingNetwork|Adam|0.1000|ExperienceReplay|512|60.0|1.0|1.0|1.0|500.0| +|DoubleDQN|1.0|64.0|0.95|AdaptativeEpsilonGreedy-0.8-0.2-10000-0|SimpleDuelingNetwork|Adam|0.0001|ExperienceReplay|2048|110.0|1.0|1.0|1.0|500.0| +|DoubleDQN|1.0|32.0|0.95|EpsilonGreedy-0.1|SimpleDuelingNetwork|Adam|0.0010|ExperienceReplay|2048|130.0|1.0|1.0|1.0|500.0| +|DoubleDQN|1.0|32.0|1.00|AdaptativeEpsilonGreedy-0.8-0.2-10000-0|SimpleDuelingNetwork|Adam|0.0001|ExperienceReplay|512|130.0|1.0|1.0|1.0|500.0| +|DoubleDQN|1.0|64.0|0.95|AdaptativeEpsilonGreedy-0.8-0.2-10000-0|SimpleDuelingNetwork|Adam|0.0001|ExperienceReplay|2048|130.0|1.0|1.0|1.0|500.0| * CategoricalDQN -The best training reach 405 steps in one episode. +500 step is reach with after 60 episode with this parameters for only one training. It's less stable then other agent. | algo | step_train | batch_size | gamma | greedy_exploration | network | optimizer | lr | memories | max_size | step | max | min | avg | sum | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -|CategoricalDQN|32.0|1.0|0.99|AdaptativeEpsilonGreedy-0.3-0.1-50000-0|C51Network|Adam|0.0010|ExperienceReplay|32|332.0|1.0|1.0|1.0|405.0| +|CategoricalDQN|1.0|64.0|0.95|EpsilonGreedy-0.1|C51Network|Adam|0.0010|ExperienceReplay|2048|60.0|1.0|1.0|1.0|500.0| +|CategoricalDQN|32.0|64.0|1.00|AdaptativeEpsilonGreedy-0.8-0.2-10000-0|C51Network|Adam|0.0001|ExperienceReplay|512|180.0|1.0|1.0|1.0|500.0| -#### Parameters importance -There are two principal parameters *batch size* and number of *step* trained. When is bigger, much we have best result. +#### Parameters importance -LR and the number of times the model is trained is canceled. When one is large the other is smaller for equivalent results. +There are three principal parameters *step* and number of *step* trained and learning rate. ### Reproduce this result ```batch -python result.py --env "CartPole-v1" --max_episode 500 +python result.py --env "CartPole-v1" --max_episode 300 ``` ## Env2 diff --git a/results/ressources/CartPoleEvaluation.png b/results/ressources/CartPoleEvaluation.png index d4482a3..91e7ee1 100644 Binary files a/results/ressources/CartPoleEvaluation.png and b/results/ressources/CartPoleEvaluation.png differ diff --git a/results/ressources/CartPoleTrainning.png b/results/ressources/CartPoleTrainning.png index 69be2c1..dccc516 100644 Binary files a/results/ressources/CartPoleTrainning.png and b/results/ressources/CartPoleTrainning.png differ diff --git a/results/result.py b/results/result.py index f6ea8e9..2887969 100644 --- a/results/result.py +++ b/results/result.py @@ -1,28 +1,29 @@ from argparse import ArgumentParser +from os import path +import shutil import gym import torch -from gym.spaces import flatdim from torch import optim from blobrl import Trainer -from blobrl.agents import DQN, DoubleDQN, DuelingDQN, CategoricalDQN +from blobrl.agents import DQN, DoubleDQN, CategoricalDQN from blobrl.explorations import EpsilonGreedy, AdaptativeEpsilonGreedy from blobrl.memories import ExperienceReplay from blobrl.networks import SimpleNetwork, SimpleDuelingNetwork, C51Network memory = [ExperienceReplay] -step_train = [1, 4, 32] -batch_size = [1, 32, 64] -gamma = [0.99] +step_train = [1, 32] +batch_size = [32, 64] +gamma = [1.0, 0.99, 0.95] loss = [torch.nn.MSELoss()] optimizer = [optim.Adam] lr = [0.1, 0.001, 0.0001] greedy_exploration = [EpsilonGreedy(0.1), EpsilonGreedy(0.6), - AdaptativeEpsilonGreedy(0.3, 0.1, 50000, 0), - AdaptativeEpsilonGreedy(0.8, 0.2, 50000, 0)] + AdaptativeEpsilonGreedy(0.3, 0.1, 30000, 0), + AdaptativeEpsilonGreedy(0.8, 0.2, 10000, 0)] arg_all = [{"agent": {"class": [DQN, DoubleDQN], "param": {"step_train": step_train, @@ -31,26 +32,13 @@ "greedy_exploration": greedy_exploration } }, - "neural_network": {"class": [SimpleNetwork], - "param": {}}, + "network": {"class": [SimpleNetwork], + "param": {}}, "optimizer": {"class": optimizer, "param": {"lr": lr}}, "memory": {"class": memory, - "param": {"max_size": [16, 32, 128]}}, - }, - {"agent": {"class": [DuelingDQN], - "param": {"step_train": step_train, - "batch_size": batch_size, - "gamma": gamma, - "greedy_exploration": greedy_exploration - } - }, - "neural_network": {"class": [SimpleDuelingNetwork], - "param": {}}, - "optimizer": {"class": optimizer, - "param": {"lr": lr}}, - "memory": {"class": memory, - "param": {"max_size": [16, 32, 128]}}, + "param": {"max_size": [512, 2048]}}, + "dueling": True }, {"agent": {"class": [CategoricalDQN], "param": {"step_train": step_train, @@ -59,12 +47,13 @@ "greedy_exploration": greedy_exploration } }, - "neural_network": {"class": [C51Network], - "param": {}}, + "network": {"class": [C51Network], + "param": {}}, "optimizer": {"class": optimizer, "param": {"lr": lr}}, "memory": {"class": memory, - "param": {"max_size": [16, 32, 128]}}, + "param": {"max_size": [512, 2048]}}, + "dueling": False }] @@ -93,7 +82,7 @@ def dict_mzip(x): if __name__ == '__main__': parser = ArgumentParser() parser.add_argument('--env', type=str, help='name of environment', nargs='?', const=1, default="CartPole-v1") - parser.add_argument('--max_episode', type=int, help='number of episode for train', nargs='?', const=1, default=500) + parser.add_argument('--max_episode', type=int, help='number of episode for train', nargs='?', const=1, default=300) parser.add_argument('--render', type=bool, help='if show render on each step or not', nargs='?', default=False) args = parser.parse_args() @@ -107,14 +96,14 @@ def dict_mzip(x): for arg in arg_all: arg_agent = arg["agent"] - arg_neural_network = arg["neural_network"] + arg_network = arg["network"] arg_optimizer = arg["optimizer"] arg_memory = arg["memory"] for class_agent in arg_agent["class"]: print("###" + class_agent.__name__) - for class_neural_network in arg_neural_network["class"]: - print(" ##" + class_neural_network.__name__) + for class_network in arg_network["class"]: + print(" ##" + class_network.__name__) for class_optimizer in arg_optimizer["class"]: print(" #" + class_optimizer.__name__) @@ -122,36 +111,85 @@ def dict_mzip(x): for param_agent in dict_mzip(arg_agent["param"]): - for param_network in dict_mzip(arg_neural_network["param"]): + for param_network in dict_mzip(arg_network["param"]): for param_optimizer in dict_mzip(arg_optimizer["param"]): for param_memory in dict_mzip(arg_memory["param"]): - neural_network = class_neural_network( - observation_shape=flatdim(env.observation_space), - action_shape=flatdim(env.action_space), - **param_network) - optimizer = class_optimizer(neural_network.parameters(), **param_optimizer) - - memory = class_memory(**param_memory) - - agent = class_agent(observation_space=env.observation_space, - action_space=env.action_space, - neural_network=neural_network, - optimizer=optimizer, memory=memory, device=device, - **param_agent) log_dir = args.env + "/" + class_agent.__name__ + "/" + "_".join( [str(x) for x in list( - param_agent.values())]) + "_" + class_neural_network.__name__ + "_" + "_".join( + param_agent.values())]) + "_" + class_network.__name__ + "_" + "_".join( [str(x) for x in list( param_network.values())]) + "_" + class_optimizer.__name__ + "_" + "_".join( [str(x) for x in list( param_optimizer.values())]) + "_" + class_memory.__name__ + "_" + "_".join( [str(x) for x in list(param_memory.values())]) - trainer = Trainer(environment=env, agent=agent, - log_dir=log_dir) - trainer.train(max_episode=args.max_episode, render=args.render) - - agent.save(file_name="save.p", dire_name=log_dir) + try: + if not path.exists(log_dir): + network = class_network( + observation_space=env.observation_space, + action_space=env.action_space, + **param_network) + optimizer = class_optimizer(network.parameters(), **param_optimizer) + + memory = class_memory(**param_memory) + + agent = class_agent(observation_space=env.observation_space, + action_space=env.action_space, + network=network, + optimizer=optimizer, memory=memory, device=device, + **param_agent) + + trainer = Trainer(environment=env, agent=agent, + log_dir=log_dir) + trainer.train(max_episode=args.max_episode, render=False, + nb_evaluation=int(args.max_episode / 10)) + + agent.save(file_name="save.p", dire_name=log_dir) + except KeyboardInterrupt: + del trainer + shutil.rmtree(log_dir) + break + + if arg["dueling"]: + log_dir = args.env + "/" + class_agent.__name__ + "/" + "_".join( + [str(x) for x in list( + param_agent.values())]) + "_" + SimpleDuelingNetwork.__name__ + "_" + "_".join( + [str(x) for x in list( + param_network.values())]) + "_" + class_optimizer.__name__ + "_" + "_".join( + [str(x) for x in list( + param_optimizer.values())]) + "_" + class_memory.__name__ + "_" + "_".join( + [str(x) for x in list(param_memory.values())]) + + try: + if not path.exists(log_dir): + base_network = class_network( + observation_space=env.observation_space, + action_space=env.action_space, + **param_network) + + network = SimpleDuelingNetwork(base_network) + + optimizer = class_optimizer(network.parameters(), **param_optimizer) + + memory = class_memory(**param_memory) + + agent = class_agent(observation_space=env.observation_space, + action_space=env.action_space, + network=network, + optimizer=optimizer, memory=memory, + device=device, + **param_agent) + + trainer = Trainer(environment=env, agent=agent, + log_dir=log_dir) + trainer.train(max_episode=args.max_episode, render=False, + nb_evaluation=int(args.max_episode / 10)) + + agent.save(file_name="save.p", dire_name=log_dir) + except KeyboardInterrupt: + del trainer + shutil.rmtree(log_dir) + break diff --git a/setup.py b/setup.py index 49233db..ba43734 100644 --- a/setup.py +++ b/setup.py @@ -30,6 +30,7 @@ setuptools.setup( author="french ai team", name='blobrl', + version='0.1.0', license="Apache-2.0", description='Reinforcement learning with pytorch ', long_description=README, diff --git a/tests/agents/__init__.py b/tests/agents/__init__.py index e69de29..ebacbcf 100644 --- a/tests/agents/__init__.py +++ b/tests/agents/__init__.py @@ -0,0 +1,4 @@ +from .test_agent_interface import TestAgentInterface +from .test_dqn import TestDQN +from .test_categorical_dqn import TestCategorical_DQN +from .test_double_dqn import TestDouble_DQN diff --git a/tests/agents/test_agent_constant.py b/tests/agents/test_agent_constant.py index f0c14b1..afd727e 100644 --- a/tests/agents/test_agent_constant.py +++ b/tests/agents/test_agent_constant.py @@ -1,86 +1,68 @@ import os - -import numpy as np import pytest -from gym.spaces import Box, Dict, Discrete, MultiBinary, MultiDiscrete, Tuple from blobrl.agents import AgentConstant +from tests.agents import TestAgentInterface -def test_agent_don_t_work_with_no_space(): - test_list = [1, 100, "100", "somethink", [], dict(), 0.0, 1245.215, None] - for action_space in test_list: - with pytest.raises(TypeError): - AgentConstant(observation_space=Discrete(1), action_space=action_space) - - for observation_space in test_list: - with pytest.raises(TypeError): - AgentConstant(observation_space=observation_space, action_space=Discrete(1)) - - -base_list = {"box": Box(low=-1.0, high=2.0, shape=(3, 4), dtype=np.float32), "discrete": Discrete(3), - "multibinary": MultiBinary(10), "multidiscrete": MultiDiscrete(10)} -dict_list = Dict(base_list) -tuple_list = Tuple(list(base_list.values())) - -test_list = [*base_list.values(), dict_list, tuple_list] - - -def test_agent_work_with_space(): - for space in test_list: - agent = AgentConstant(observation_space=space, action_space=space) - assert agent.observation_space == space - assert agent.action_space == space - -def test_agent_get_action(): - for space in test_list: - agent = AgentConstant(observation_space=space, action_space=space) - agent.get_action(None) +class TestAgentConstant(TestAgentInterface): + __test__ = True + agent = AgentConstant -def test_agent_learn(): - for space in test_list: - agent = AgentConstant(observation_space=space, action_space=space) - agent.learn(None, None, None, None, None) + def test_init(self): + for o, a in self.list_work: + self.agent(o, a) + for o, a in self.list_fail: + with pytest.raises(TypeError): + self.agent(o, a) -def test_agent_episode_finished(): - for space in test_list: - agent = AgentConstant(observation_space=space, action_space=space) - agent.episode_finished() + def test_get_action(self): + for o, a in self.list_work: + agent = self.agent(observation_space=o, action_space=a) + agent.get_action(None) + def test_learn(self): + for o, a in self.list_work: + agent = self.agent(observation_space=o, action_space=a) + agent.learn(None, None, None, None, None) -def test_agent_save_load(): - for space in test_list: - agent = AgentConstant(observation_space=space, action_space=space) + def test_episode_finished(self): + for o, a in self.list_work: + agent = self.agent(observation_space=o, action_space=a) + agent.episode_finished() - agent.save(file_name="deed.pt") - agent_l = AgentConstant.load(file_name="deed.pt") + def test_agent_save_load(self): + for o, a in self.list_work: + agent = self.agent(observation_space=o, action_space=a) - assert agent.observation_space == agent_l.observation_space - assert agent.action_space == agent_l.action_space - os.remove("deed.pt") + agent.save(file_name="deed.pt") + agent_l = self.agent.load(file_name="deed.pt") - agent = AgentConstant(observation_space=space, action_space=space) - agent.save(file_name="deed.pt", dire_name="./remove/") + assert agent.observation_space == agent_l.observation_space + assert agent.action_space == agent_l.action_space + os.remove("deed.pt") - os.remove("./remove/deed.pt") - os.rmdir("./remove/") + agent = self.agent(observation_space=o, action_space=a) + agent.save(file_name="deed.pt", dire_name="./remove/") - with pytest.raises(TypeError): - agent.save(file_name=14548) - with pytest.raises(TypeError): - agent.save(file_name="deed.pt", dire_name=14484) + os.remove("./remove/deed.pt") + os.rmdir("./remove/") - with pytest.raises(FileNotFoundError): - AgentConstant.load(file_name="deed.pt") - with pytest.raises(FileNotFoundError): - AgentConstant.load(file_name="deed.pt", dire_name="/Dede/") + with pytest.raises(TypeError): + agent.save(file_name=14548) + with pytest.raises(TypeError): + agent.save(file_name="deed.pt", dire_name=14484) + with pytest.raises(FileNotFoundError): + self.agent.load(file_name="deed.pt") + with pytest.raises(FileNotFoundError): + self.agent.load(file_name="deed.pt", dire_name="/Dede/") -def test__str__(): - for space in test_list: - agent = AgentConstant(observation_space=space, action_space=space) + def test__str__(self): + for o, a in self.list_work: + agent = self.agent(observation_space=o, action_space=a) - assert 'AgentConstant-' + str(space) + "-" + str(space) + "-" + str(agent.action) == agent.__str__() + assert 'AgentConstant-' + str(o) + "-" + str(a) + "-" + str(agent.action) == agent.__str__() diff --git a/tests/agents/test_agent_interface.py b/tests/agents/test_agent_interface.py index ba5944c..f734fb6 100644 --- a/tests/agents/test_agent_interface.py +++ b/tests/agents/test_agent_interface.py @@ -1,17 +1,13 @@ import pytest import torch +from gym.spaces import Discrete, MultiDiscrete, MultiBinary, Dict, Tuple, Box from blobrl.agents import AgentInterface -def test_can_t_instantiate_agent_interface(): - with pytest.raises(TypeError): - AgentInterface() - - class MOCKAgentInterface(AgentInterface): - def __init__(self, device): - super().__init__(device) + def __init__(self, observation_space, action_space, device): + super().__init__(observation_space, action_space, device) def get_action(self, observation): pass @@ -39,14 +35,68 @@ def __str__(self): return "" -def test_device(): - device = torch.device("cpu") - assert device == MOCKAgentInterface(device).device +class TestAgentInterface: + __test__ = True + + agent = MOCKAgentInterface + + list_work = [ + [Discrete(3), Discrete(1)], + [Discrete(3), Discrete(3)], + [Discrete(10), Discrete(50)], + [MultiDiscrete([3]), MultiDiscrete([1])], + [MultiDiscrete([3, 3]), MultiDiscrete([3, 3])], + [MultiDiscrete([4, 4, 4]), MultiDiscrete([50, 4, 4])], + [MultiDiscrete([[100, 3], [3, 5]]), MultiDiscrete([[100, 3], [3, 5]])], + [MultiDiscrete([[[100, 3], [3, 5]], [[100, 3], [3, 5]]]), + MultiDiscrete([[[100, 3], [3, 5]], [[100, 3], [3, 5]]])], + [MultiBinary(1), MultiBinary(1)], + [MultiBinary(3), MultiBinary(3)], + # [MultiBinary([3, 2]), MultiBinary([3, 2])], # Don't work yet because gym don't implemented this + [Box(low=0, high=10, shape=[1]), Box(low=0, high=10, shape=[1])], + [Box(low=0, high=10, shape=[2, 2]), Box(low=0, high=10, shape=[2, 2])], + [Box(low=0, high=10, shape=[2, 2, 2]), Box(low=0, high=10, shape=[2, 2, 2])], + + [Tuple([Discrete(1), MultiDiscrete([1, 1])]), Tuple([Discrete(1), MultiDiscrete([1, 1])])], + [Dict({"first": Discrete(1), "second": MultiDiscrete([1, 1])}), + Dict({"first": Discrete(1), "second": MultiDiscrete([1, 1])})], + + ] + list_fail = [ + [None, None], + ["dedrfe", "qdzq"], + [1215.4154, 157.48], + ["zdzd", (Discrete(1))], + [Discrete(1), "zdzd"], + ["zdzd", (1, 4, 7)], + [(1, 4, 7), "zdzd"], + [152, 485] + ] + + def test_init(self): + for o, a in self.list_work: + with pytest.raises(TypeError): + self.agent(o, a, "cpu") + + for o, a in self.list_fail: + with pytest.raises(TypeError): + self.agent(o, a, "cpu") + + def test_device(self): + for o, a in self.list_work: + device = torch.device("cpu") + assert device == self.agent(o, a, device).device + + device = None + assert torch.device("cpu") == self.agent(o, a, device).device + + for device in ["dzeqdzqd", 1512, object(), 151.515]: + with pytest.raises(TypeError): + self.agent(o, a, device) + + if torch.cuda.is_available(): + self.agent(o, a, torch.device("cuda")) + + def test__str__(self): - device = None - assert torch.device("cpu") == MOCKAgentInterface(device).device - - devices = ["dzeqdzqd", 1512, object(), 151.515] - for device in devices: - with pytest.raises(TypeError): - MOCKAgentInterface(device) + pass diff --git a/tests/agents/test_agent_random.py b/tests/agents/test_agent_random.py index b8772b4..4aada4d 100644 --- a/tests/agents/test_agent_random.py +++ b/tests/agents/test_agent_random.py @@ -1,86 +1,68 @@ import os - -import numpy as np import pytest -from gym.spaces import Box, Dict, Discrete, MultiBinary, MultiDiscrete, Tuple from blobrl.agents import AgentRandom - -def test_agent_don_t_work_with_no_space(): - test_list = [1, 100, "100", "somethink", [], dict(), 0.0, 1245.215, None] - for action_space in test_list: - with pytest.raises(TypeError): - AgentRandom(observation_space=Discrete(1), action_space=action_space) - - for observation_space in test_list: - with pytest.raises(TypeError): - AgentRandom(observation_space=observation_space, action_space=Discrete(1)) - - -base_list = {"box": Box(low=-1.0, high=2.0, shape=(3, 4), dtype=np.float32), "discrete": Discrete(3), - "multibinary": MultiBinary(10), "multidiscrete": MultiDiscrete(10)} -dict_list = Dict(base_list) -tuple_list = Tuple(list(base_list.values())) - -test_list = [*base_list.values(), dict_list, tuple_list] - - -def test_agent_work_with_space(): - for space in test_list: - agent = AgentRandom(observation_space=space, action_space=space) - assert agent.observation_space == space - assert agent.action_space == space +from tests.agents import TestAgentInterface -def test_agent_get_action(): - for space in test_list: - agent = AgentRandom(observation_space=space, action_space=space) - agent.get_action(None) +class TestAgentRandom(TestAgentInterface): + __test__ = True + agent = AgentRandom -def test_agent_learn(): - for space in test_list: - agent = AgentRandom(observation_space=space, action_space=space) - agent.learn(None, None, None, None, None) + def test_init(self): + for o, a in self.list_work: + self.agent(o, a) + for o, a in self.list_fail: + with pytest.raises(TypeError): + self.agent(o, a) -def test_agent_episode_finished(): - for space in test_list: - agent = AgentRandom(observation_space=space, action_space=space) - agent.episode_finished() + def test_get_action(self): + for o, a in self.list_work: + agent = self.agent(observation_space=o, action_space=a) + agent.get_action(None) + def test_learn(self): + for o, a in self.list_work: + agent = self.agent(observation_space=o, action_space=a) + agent.learn(None, None, None, None, None) -def test_agent_save_load(): - for space in test_list: - agent = AgentRandom(observation_space=space, action_space=space) + def test_episode_finished(self): + for o, a in self.list_work: + agent = self.agent(observation_space=o, action_space=a) + agent.episode_finished() - agent.save(file_name="deed.pt") - agent_l = AgentRandom.load(file_name="deed.pt") + def test_agent_save_load(self): + for o, a in self.list_work: + agent = self.agent(observation_space=o, action_space=a) - assert agent.observation_space == agent_l.observation_space - assert agent.action_space == agent_l.action_space - os.remove("deed.pt") + agent.save(file_name="deed.pt") + agent_l = self.agent.load(file_name="deed.pt") - agent = AgentRandom(observation_space=space, action_space=space) - agent.save(file_name="deed.pt", dire_name="./remove/") + assert agent.observation_space == agent_l.observation_space + assert agent.action_space == agent_l.action_space + os.remove("deed.pt") - os.remove("./remove/deed.pt") - os.rmdir("./remove/") + agent = self.agent(observation_space=o, action_space=a) + agent.save(file_name="deed.pt", dire_name="./remove/") - with pytest.raises(TypeError): - agent.save(file_name=14548) - with pytest.raises(TypeError): - agent.save(file_name="deed.pt", dire_name=14484) + os.remove("./remove/deed.pt") + os.rmdir("./remove/") - with pytest.raises(FileNotFoundError): - AgentRandom.load(file_name="deed.pt") - with pytest.raises(FileNotFoundError): - AgentRandom.load(file_name="deed.pt", dire_name="/Dede/") + with pytest.raises(TypeError): + agent.save(file_name=14548) + with pytest.raises(TypeError): + agent.save(file_name="deed.pt", dire_name=14484) + with pytest.raises(FileNotFoundError): + self.agent.load(file_name="deed.pt") + with pytest.raises(FileNotFoundError): + self.agent.load(file_name="deed.pt", dire_name="/Dede/") -def test__str__(): - for space in test_list: - agent = AgentRandom(observation_space=space, action_space=space) + def test__str__(self): + for o, a in self.list_work: + agent = self.agent(observation_space=o, action_space=a) - assert 'AgentRandom-' + str(space) + "-" + str(space) == agent.__str__() + assert 'AgentRandom-' + str(o) + "-" + str(a) == agent.__str__() diff --git a/tests/agents/test_categorical_dqn.py b/tests/agents/test_categorical_dqn.py index 3c27367..27eda9d 100644 --- a/tests/agents/test_categorical_dqn.py +++ b/tests/agents/test_categorical_dqn.py @@ -1,135 +1,19 @@ -import pytest -import torch -import torch.optim as optim -from gym.spaces import Discrete, Box - from blobrl.agents import CategoricalDQN -from blobrl.explorations import Greedy, EpsilonGreedy -from blobrl.memories import ExperienceReplay from blobrl.networks import C51Network +from tests.agents import TestDQN -def test_categorical_dqn_agent_instantiation(): - CategoricalDQN(Discrete(4), Discrete(4)) - - -def test_categorical_dqn_agent_instantiation_error_action_space(): - with pytest.raises(TypeError): - CategoricalDQN(None, Discrete(1)) - - -def test_categorical_dqn_agent_instantiation_error_observation_space(): - with pytest.raises(TypeError): - CategoricalDQN(Discrete(1), None) - - -def test_categorical_dqn_agent_instantiation_error_neural_network(): - with pytest.raises(TypeError): - CategoricalDQN(Discrete(4), Discrete(4), neural_network=154) - - -def test_categorical_dqn_agent_instantiation_error_memory(): - with pytest.raises(TypeError): - CategoricalDQN(Discrete(4), Discrete(4), None) - - -def test_categorical_dqn_agent_instantiation_error_loss(): - with pytest.raises(TypeError): - CategoricalDQN(Discrete(4), Discrete(4), loss="LOSS_ERROR") - - -def test_categorical_dqn_agent_instantiation_error_optimizer(): - with pytest.raises(TypeError): - CategoricalDQN(Discrete(4), Discrete(4), optimizer="OPTIMIZER_ERROR") - - -def test_categorical_dqn_agent_instantiation_error_greedy_exploration(): - with pytest.raises(TypeError): - CategoricalDQN(Discrete(4), Discrete(4), greedy_exploration="GREEDY_EXPLORATION_ERROR") - - -def test_categorical_dqn_agent_instantiation_custom_optimizer(): - c51 = C51Network((1), (1)) - - CategoricalDQN(Discrete(4), Discrete(4), neural_network=c51, optimizer=optim.RMSprop(c51.parameters())) - - with pytest.raises(TypeError): - CategoricalDQN(Discrete(4), Discrete(4), neural_network=None, optimizer=optim.RMSprop(c51.parameters())) - - -def test_categorical_dqn_agent_getaction(): - agent = CategoricalDQN(Discrete(4), Box(0, 3, (3,)), greedy_exploration=Greedy()) - - observation = [0, 1, 2] - - agent.get_action(observation) - - -def test_categorical_dqn_agent_getaction_non_greedy(): - agent = CategoricalDQN(Discrete(4), Box(0, 3, (3,)), greedy_exploration=EpsilonGreedy(1.)) - - observation = [0, 1, 2] - - agent.get_action(observation) - - -def test_categorical_dqn_agent_learn(): - memory = ExperienceReplay(max_size=5) - - agent = CategoricalDQN(Discrete(4), Box(1, 10, (4,)), memory) - - obs = [1, 2, 5, 0] - action = 0 - reward = 0 - next_obs = [5, 9, 4, 0] - done = False - - obs_s = [obs, obs, obs] - actions = [1, 2, 3] - rewards = [-2.2, 5, 4] - next_obs_s = [next_obs, next_obs, next_obs] - dones = [False, True, False] - - memory.extend(obs_s, actions, rewards, next_obs_s, dones) - - agent.learn(obs, action, reward, next_obs, done) - agent.learn(obs, action, reward, next_obs, done) - - -def test_categorical_dqn_agent_episode_finished(): - agent = CategoricalDQN(Discrete(4), Discrete(4)) - agent.episode_finished() - - -def test__str__(): - agent = CategoricalDQN(Discrete(4), Box(1, 10, (4,))) - - assert 'CategoricalDQN-' + str(agent.observation_space) + "-" + str(agent.action_space) + "-" + str( - agent.neural_network) + "-" + str(agent.memory) + "-" + str(agent.step_train) + "-" + str( - agent.step) + "-" + str(agent.batch_size) + "-" + str(agent.gamma) + "-" + str(agent.loss) + "-" + str( - agent.optimizer) + "-" + str(agent.greedy_exploration) + "-" + str(agent.num_atoms) + "-" + str( - agent.r_min) + "-" + str(agent.r_max) + "-" + str(agent.delta_z) + "-" + str(agent.z) == agent.__str__() - - -def test_device_gpu(): - if torch.cuda.is_available(): - memory = ExperienceReplay(max_size=5) - - agent = CategoricalDQN(Discrete(4), Box(1, 10, (4,)), memory, device=torch.device("cuda")) - - obs = [1, 2, 5, 0] - action = 0 - reward = 0 - next_obs = [5, 9, 4, 0] - done = False - obs_s = [obs, obs, obs] - actions = [1, 2, 3] - rewards = [-2.2, 5, 4] - next_obs_s = [next_obs, next_obs, next_obs] - dones = [False, True, False] +class TestCategorical_DQN(TestDQN): + agent = CategoricalDQN + network = C51Network - memory.extend(obs_s, actions, rewards, next_obs_s, dones) + def test__str__(self): + for o, a in self.list_work: + agent = self.agent(o, a) - agent.learn(obs, action, reward, next_obs, done) - agent.learn(obs, action, reward, next_obs, done) + assert 'CategoricalDQN-' + str(agent.observation_space) + "-" + str(agent.action_space) + "-" + str( + agent.network) + "-" + str(agent.memory) + "-" + str(agent.step_train) + "-" + str( + agent.step) + "-" + str(agent.batch_size) + "-" + str(agent.gamma) + "-" + str(agent.loss) + "-" + str( + agent.optimizer) + "-" + str(agent.greedy_exploration) + "-" + str(agent.num_atoms) + "-" + str( + agent.r_min) + "-" + str(agent.r_max) + "-" + str(agent.delta_z) + "-" + str(agent.z) == agent.__str__() diff --git a/tests/agents/test_double_dqn.py b/tests/agents/test_double_dqn.py index 6865087..3c50f70 100644 --- a/tests/agents/test_double_dqn.py +++ b/tests/agents/test_double_dqn.py @@ -1,261 +1,27 @@ -import os - -import numpy as np -import pytest -import torch -import torch.nn as nn -import torch.nn.functional as F -import torch.optim as optim -from gym.spaces import Discrete, Box, MultiBinary, MultiDiscrete, Dict, Tuple - from blobrl.agents import DoubleDQN -from blobrl.explorations import Greedy, EpsilonGreedy +from tests.agents import TestDQN +from gym.spaces import flatten from blobrl.memories import ExperienceReplay -from blobrl.networks import BaseNetwork - - -class Network(BaseNetwork): - def __str__(self): - return 'Network' - - def __init__(self, observation_shape=None, action_shape=None): - super().__init__(observation_shape, action_shape) - self.dense = nn.Linear(3, 4) - - def forward(self, x): - x = self.dense(x) - x = F.relu(x) - return x - - -def test_double_dqn_agent_instantiation(): - network = Network() - memory = ExperienceReplay(max_size=5) - - DoubleDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory) - DoubleDQN(Discrete(4), Discrete(3)) - - -def test_double_dqn_agent_instantiation_error_action_space(): - network = Network() - memory = ExperienceReplay(max_size=5) - - with pytest.raises(TypeError): - DoubleDQN("ACTION_SPACE_ERROR", Discrete(3), neural_network=network, memory=memory) - - -def test_double_dqn_agent_instantiation_error_observation_space(): - network = Network() - memory = ExperienceReplay(max_size=5) - - with pytest.raises(TypeError): - DoubleDQN(Discrete(1), "OBSERVATION_SPACE_ERROR", neural_network=network, memory=memory) - - -def test_double_dqn_agent_instantiation_error_neural_network(): - memory = ExperienceReplay(max_size=5) - - with pytest.raises(TypeError): - DoubleDQN(Discrete(4), Discrete(3), neural_network="NEURAL_NETWORK_ERROR", memory=memory) - - -def test_double_dqn_agent_instantiation_error_memory(): - network = Network() - - with pytest.raises(TypeError): - DoubleDQN(Discrete(4), Discrete(3), neural_network=network, memory="MEMORY_ERROR") - - -def test_double_dqn_agent_instantiation_error_loss(): - network = Network() - memory = ExperienceReplay(max_size=5) - - with pytest.raises(TypeError): - DoubleDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory, loss="LOSS_ERROR") - - -def test_double_dqn_agent_instantiation_error_optimizer(): - network = Network() - memory = ExperienceReplay(max_size=5) - - with pytest.raises(TypeError): - DoubleDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory, optimizer="OPTIMIZER_ERROR") - - -def test_double_dqn_agent_instantiation_error_greedy_exploration(): - network = Network() - memory = ExperienceReplay(max_size=5) - - with pytest.raises(TypeError): - DoubleDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory, - greedy_exploration="GREEDY_EXPLORATION_ERROR") - - -def test_double_dqn_agent_instantiation_custom_loss(): - network = Network() - memory = ExperienceReplay(max_size=5) - - DoubleDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory, loss=nn.MSELoss()) - - -def test_double_dqn_agent_instantiation_custom_optimizer(): - network = Network() - memory = ExperienceReplay(max_size=5) - - DoubleDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory, - optimizer=optim.RMSprop(network.parameters())) - - -def test_double_dqn_agent_getaction(): - network = Network() - memory = ExperienceReplay(max_size=5) - - agent = DoubleDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory, greedy_exploration=Greedy()) - - observation = [0, 1, 2] - - agent.get_action(observation) - - -def test_double_dqn_agent_getaction_non_greedy(): - network = Network() - memory = ExperienceReplay(max_size=5) - - agent = DoubleDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory, - greedy_exploration=EpsilonGreedy(1.)) - - observation = [0, 1, 2] - - agent.get_action(observation) - - -def test_double_dqn_agent_learn(): - network = Network() - memory = ExperienceReplay(max_size=5) - - agent = DoubleDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory, step_copy=2) - - obs = [1, 2, 5] - action = 0 - reward = 0 - next_obs = [5, 9, 4] - done = False - - obs_s = [obs, obs, obs] - actions = [1, 2, 3] - rewards = [-2.2, 5, 4] - next_obs_s = [next_obs, next_obs, next_obs] - dones = [False, True, False] - - memory.extend(obs_s, actions, rewards, next_obs_s, dones) - - agent.learn(obs, action, reward, next_obs, done) - agent.learn(obs, action, reward, next_obs, done) - - -def test_double_dqn_agent_episode_finished(): - network = Network() - memory = ExperienceReplay(max_size=5) - - agent = DoubleDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory) - agent.episode_finished() - - -base_list = {"box": Box(low=-1.0, high=2.0, shape=(3, 4), dtype=np.float32), "discrete": Discrete(3), - "multibinary": MultiBinary(10), "multidiscrete": MultiDiscrete(10)} -dict_list = Dict(base_list) -tuple_list = Tuple(list(base_list.values())) - -test_list = [*base_list.values(), dict_list, tuple_list] - - -def test_agent_save_load(): - for space in test_list: - agent = DoubleDQN(observation_space=space, action_space=Discrete(2)) - - agent.save(file_name="deed.pt") - agent_l = DoubleDQN.load(file_name="deed.pt") - - assert agent.observation_space == agent_l.observation_space - assert Discrete(2) == agent_l.action_space - os.remove("deed.pt") - - network = Network() - - agent = DoubleDQN(observation_space=space, action_space=Discrete(2), memory=ExperienceReplay(), - neural_network=network, step_train=3, batch_size=12, gamma=0.50, loss=None, - optimizer=torch.optim.Adam(network.parameters()), step_copy=300, - greedy_exploration=EpsilonGreedy(0.2)) - - agent.save(file_name="deed.pt") - agent_l = DoubleDQN.load(file_name="deed.pt") - - os.remove("deed.pt") - - assert agent.observation_space == agent_l.observation_space - assert Discrete(2) == agent_l.action_space - assert isinstance(agent.neural_network, type(agent_l.neural_network)) - for a, b in zip(agent.neural_network.state_dict(), agent_l.neural_network.state_dict()): - assert a == b - assert agent.step_train == agent_l.step_train - assert agent.batch_size == agent_l.batch_size - assert agent.gamma == agent_l.gamma - assert isinstance(agent.loss, type(agent_l.loss)) - for a, b in zip(agent.loss.parameters(), agent_l.loss.parameters()): - assert a == b - assert isinstance(agent.optimizer, type(agent_l.optimizer)) - for a, b in zip(agent.optimizer.state_dict(), agent_l.optimizer.state_dict()): - assert a == b - assert isinstance(agent.greedy_exploration, type(agent_l.greedy_exploration)) - assert agent.step_copy == agent_l.step_copy - - agent = DoubleDQN(observation_space=space, action_space=Discrete(2)) - agent.save(file_name="deed.pt", dire_name="./remove/") - - os.remove("./remove/deed.pt") - os.rmdir("./remove/") - - with pytest.raises(TypeError): - agent.save(file_name=14548) - with pytest.raises(TypeError): - agent.save(file_name="deed.pt", dire_name=14484) - - with pytest.raises(FileNotFoundError): - DoubleDQN.load(file_name="deed.pt") - with pytest.raises(FileNotFoundError): - DoubleDQN.load(file_name="deed.pt", dire_name="/Dede/") - - -def test__str__(): - agent = DoubleDQN(Discrete(4), Box(1, 10, (4,))) - - assert 'DoubleDQN-' + str(agent.observation_space) + "-" + str(agent.action_space) + "-" + str( - agent.neural_network) + "-" + str(agent.memory) + "-" + str(agent.step_train) + "-" + str( - agent.step) + "-" + str(agent.batch_size) + "-" + str(agent.gamma) + "-" + str(agent.loss) + "-" + str( - agent.optimizer) + "-" + str(agent.greedy_exploration) + "-" + str(agent.step_copy) == agent.__str__() -def test_device_gpu(): - if torch.cuda.is_available(): - network = Network() - memory = ExperienceReplay(max_size=5) +class TestDouble_DQN(TestDQN): + agent = DoubleDQN - agent = DoubleDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory, step_copy=2, - device=torch.device("cuda")) + def test_learn(self): + for o, a in self.list_work: + network = self.network(o, a) + memory = ExperienceReplay(max_size=5) - obs = [1, 2, 5] - action = 0 - reward = 0 - next_obs = [5, 9, 4] - done = False + agent = self.agent(observation_space=o, action_space=a, memory=memory, step_copy=10, network=network) - obs_s = [obs, obs, obs] - actions = [1, 2, 3] - rewards = [-2.2, 5, 4] - next_obs_s = [next_obs, next_obs, next_obs] - dones = [False, True, False] + for i in range(20): + agent.learn(o.sample(), a.sample(), 0, o.sample(), False) - memory.extend(obs_s, actions, rewards, next_obs_s, dones) + def test__str__(self): + for o, a in self.list_work: + agent = self.agent(o, a) - agent.learn(obs, action, reward, next_obs, done) - agent.learn(obs, action, reward, next_obs, done) + assert 'DoubleDQN-' + str(agent.observation_space) + "-" + str(agent.action_space) + "-" + str( + agent.network) + "-" + str(agent.memory) + "-" + str(agent.step_train) + "-" + str( + agent.step) + "-" + str(agent.batch_size) + "-" + str(agent.gamma) + "-" + str(agent.loss) + "-" + str( + agent.optimizer) + "-" + str(agent.greedy_exploration) + "-" + str(agent.step_copy) == agent.__str__() diff --git a/tests/agents/test_dqn.py b/tests/agents/test_dqn.py index 4bd457e..7443708 100644 --- a/tests/agents/test_dqn.py +++ b/tests/agents/test_dqn.py @@ -1,276 +1,207 @@ import os - -import numpy as np import pytest import torch -import torch.nn as nn -import torch.nn.functional as F +from gym.spaces import Discrete, Box, MultiBinary, MultiDiscrete, Dict, Tuple, flatten import torch.optim as optim -from gym.spaces import Discrete, Box, MultiBinary, MultiDiscrete, Dict, Tuple from blobrl.agents import DQN from blobrl.explorations import Greedy, EpsilonGreedy from blobrl.memories import ExperienceReplay -from blobrl.networks import BaseNetwork - - -class Network(BaseNetwork): - - def __str__(self): - return 'Network' - - def __init__(self, observation_shape=None, action_shape=None): - super().__init__(observation_shape, action_shape) - self.dense = nn.Linear(4, 4) - - def forward(self, x): - x = self.dense(x) - x = F.relu(x) - return x - - -def test_dqn_agent_instantiation(): - network = Network() - memory = ExperienceReplay(max_size=5) - - DQN(Discrete(4), Discrete(4), memory, neural_network=network) - - -def test_dqn_agent_instantiation_error_action_space(): - network = Network() - memory = ExperienceReplay(max_size=5) - - with pytest.raises(TypeError): - DQN(None, Discrete(1), memory, neural_network=network) - - -def test_dqn_agent_instantiation_error_observation_space(): - network = Network() - memory = ExperienceReplay(max_size=5) - - with pytest.raises(TypeError): - DQN(Discrete(1), None, memory, neural_network=network) - - -def test_dqn_agent_instantiation_error_neural_network(): - memory = ExperienceReplay(max_size=5) - - with pytest.raises(TypeError): - DQN(Discrete(4), Discrete(4), memory, neural_network=154) - - DQN(Discrete(4), Discrete(4), memory, neural_network=None) - - -def test_dqn_agent_instantiation_error_memory(): - network = Network() - - with pytest.raises(TypeError): - DQN(Discrete(4), Discrete(4), None, neural_network=network) - - -def test_dqn_agent_instantiation_error_loss(): - network = Network() - memory = ExperienceReplay(max_size=5) - - with pytest.raises(TypeError): - DQN(Discrete(4), Discrete(4), memory, neural_network=network, loss="LOSS_ERROR") - - -def test_dqn_agent_instantiation_error_optimizer(): - network = Network() - memory = ExperienceReplay(max_size=5) - - with pytest.raises(TypeError): - DQN(Discrete(4), Discrete(4), memory, neural_network=network, optimizer="OPTIMIZER_ERROR") - - -def test_dqn_agent_instantiation_error_greedy_exploration(): - network = Network() - memory = ExperienceReplay(max_size=5) - - with pytest.raises(TypeError): - DQN(Discrete(4), Discrete(4), memory, neural_network=network, greedy_exploration="GREEDY_EXPLORATION_ERROR") - - -def test_dqn_agent_instantiation_custom_loss(): - network = Network() - memory = ExperienceReplay(max_size=5) - - DQN(Discrete(4), Discrete(4), memory, neural_network=network, loss=nn.MSELoss()) - - -def test_dqn_agent_instantiation_custom_optimizer(): - network = Network() - memory = ExperienceReplay(max_size=5) - - DQN(Discrete(4), Discrete(4), memory, neural_network=network, optimizer=optim.RMSprop(network.parameters())) - - with pytest.raises(TypeError): - DQN(Discrete(4), Discrete(4), memory, neural_network=None, optimizer=optim.RMSprop(network.parameters())) - - -def test_dqn_agent_getaction(): - network = Network() - memory = ExperienceReplay(max_size=5) - - agent = DQN(Discrete(4), Discrete(4), memory, neural_network=network, greedy_exploration=Greedy()) - - observation = [0, 1, 2] - - agent.get_action(observation) - - -def test_dqn_agent_getaction_non_greedy(): - network = Network() - memory = ExperienceReplay(max_size=5) - - agent = DQN(Discrete(4), Discrete(4), memory, neural_network=network, greedy_exploration=EpsilonGreedy(1.)) - - observation = [0, 1, 2] - - agent.get_action(observation) - - -def test_dqn_agent_learn(): - network = Network() - memory = ExperienceReplay(max_size=5) - - agent = DQN(Discrete(4), Discrete(4), memory, neural_network=network) - - obs = [1, 2, 5, 0] - action = 0 - reward = 0 - next_obs = [5, 9, 4, 0] - done = False - - obs_s = [obs, obs, obs] - actions = [1, 2, 3] - rewards = [-2.2, 5, 4] - next_obs_s = [next_obs, next_obs, next_obs] - dones = [False, True, False] - - memory.extend(obs_s, actions, rewards, next_obs_s, dones) - - agent.learn(obs, action, reward, next_obs, done) - agent.learn(obs, action, reward, next_obs, done) - - -def test_dqn_agent_episode_finished(): - network = Network() - memory = ExperienceReplay(max_size=5) - - agent = DQN(Discrete(4), Discrete(4), memory, neural_network=network) - agent.episode_finished() - - -base_list = {"box": Box(low=-1.0, high=2.0, shape=(3, 4), dtype=np.float32), "discrete": Discrete(3), - "multibinary": MultiBinary(10), "multidiscrete": MultiDiscrete(10)} -dict_list = Dict(base_list) -tuple_list = Tuple(list(base_list.values())) - -test_list = [*base_list.values(), dict_list, tuple_list] - - -def test_agent_save_load(): - for space in test_list: - agent = DQN(observation_space=space, action_space=Discrete(2)) - - agent.save(file_name="deed.pt") - agent_l = DQN.load(file_name="deed.pt") - - assert agent.observation_space == agent_l.observation_space - assert Discrete(2) == agent_l.action_space - os.remove("deed.pt") - - network = Network() - - agent = DQN(observation_space=space, action_space=Discrete(2), memory=ExperienceReplay(), neural_network=network, - step_train=3, batch_size=12, gamma=0.50, loss=None, optimizer=torch.optim.Adam(network.parameters()), - greedy_exploration=EpsilonGreedy(0.2)) - - agent.save(file_name="deed.pt") - agent_l = DQN.load(file_name="deed.pt") - - os.remove("deed.pt") - - assert agent.observation_space == agent_l.observation_space - assert Discrete(2) == agent_l.action_space - assert isinstance(agent.neural_network, type(agent_l.neural_network)) - for a, b in zip(agent.neural_network.state_dict(), agent_l.neural_network.state_dict()): - assert a == b - assert agent.step_train == agent_l.step_train - assert agent.batch_size == agent_l.batch_size - assert agent.gamma == agent_l.gamma - assert isinstance(agent.loss, type(agent_l.loss)) - for a, b in zip(agent.loss.parameters(), agent_l.loss.parameters()): - assert a == b - assert isinstance(agent.optimizer, type(agent_l.optimizer)) - for a, b in zip(agent.optimizer.state_dict(), agent_l.optimizer.state_dict()): - assert a == b - assert isinstance(agent.greedy_exploration, type(agent_l.greedy_exploration)) - - agent = DQN(observation_space=space, action_space=Discrete(2)) - agent.save(file_name="deed.pt", dire_name="./remove/") - - os.remove("./remove/deed.pt") - os.rmdir("./remove/") - - with pytest.raises(TypeError): - agent.save(file_name=14548) - with pytest.raises(TypeError): - agent.save(file_name="deed.pt", dire_name=14484) - - with pytest.raises(FileNotFoundError): - DQN.load(file_name="deed.pt") - with pytest.raises(FileNotFoundError): - DQN.load(file_name="deed.pt", dire_name="/Dede/") - - -def test__str__(): - agent = DQN(Discrete(4), Box(1, 10, (4,))) - - assert 'DQN-' + str(agent.observation_space) + "-" + str(agent.action_space) + "-" + str( - agent.neural_network) + "-" + str(agent.memory) + "-" + str(agent.step_train) + "-" + str( - agent.step) + "-" + str(agent.batch_size) + "-" + str(agent.gamma) + "-" + str(agent.loss) + "-" + str( - agent.optimizer) + "-" + str(agent.greedy_exploration) == agent.__str__() - - -def test_enable_train(): - agent = DQN(Discrete(4), Box(1, 10, (4,))) - - agent.trainable = False - - agent.enable_exploration() - assert agent.trainable is True - - -def test_disable_train(): - agent = DQN(Discrete(4), Box(1, 10, (4,))) - - agent.disable_exploration() - assert agent.trainable is False - - -def test_device_gpu(): - if torch.cuda.is_available(): - network = Network() - memory = ExperienceReplay(max_size=5) - - agent = DQN(Discrete(4), Discrete(4), memory, neural_network=network, device=torch.device("cuda")) - - obs = [1, 2, 5, 0] - action = 0 - reward = 0 - next_obs = [5, 9, 4, 0] - done = False - - obs_s = [obs, obs, obs] - actions = [1, 2, 3] - rewards = [-2.2, 5, 4] - next_obs_s = [next_obs, next_obs, next_obs] - dones = [False, True, False] - - memory.extend(obs_s, actions, rewards, next_obs_s, dones) +from blobrl.networks import SimpleNetwork + +from tests.agents import TestAgentInterface + + +class TestDQN(TestAgentInterface): + __test__ = True + + agent = DQN + network = SimpleNetwork + + list_work = [ + [Discrete(3), Discrete(1)], + [Discrete(3), Discrete(3)], + [Discrete(5), Discrete(3)], + [Discrete(10), Discrete(50)], + [Discrete(15), Discrete(50)], + [MultiDiscrete([3]), MultiDiscrete([1])], + [MultiDiscrete([3]), Discrete(50)], + [MultiDiscrete([3, 3]), MultiDiscrete([3, 3])], + [MultiDiscrete([4, 4, 4]), MultiDiscrete([50, 4, 4])], + [MultiDiscrete([4, 4, 4]), Discrete(3)], + [MultiDiscrete([[100, 3], [3, 5]]), MultiDiscrete([[100, 3], [3, 5]])], + [MultiDiscrete([[[100, 3], [3, 5]], [[100, 3], [3, 5]]]), + MultiDiscrete([[[100, 3], [3, 5]], [[100, 3], [3, 5]]])] + ] + list_fail = [ + [None, None], + ["dedrfe", "qdzq"], + [1215.4154, 157.48], + ["zdzd", (Discrete(1))], + [Discrete(1), "zdzd"], + ["zdzd", (1, 4, 7)], + [(1, 4, 7), "zdzd"], + [152, 485], + [MultiBinary(1), MultiBinary(1)], + [MultiBinary(3), MultiBinary(3)], + # [MultiBinary([3, 2]), MultiBinary([3, 2])], # Don't work yet because gym don't implemented this + [Box(low=0, high=10, shape=[1]), Box(low=0, high=10, shape=[1])], + [Box(low=0, high=10, shape=[2, 2]), Box(low=0, high=10, shape=[2, 2])], + [Box(low=0, high=10, shape=[2, 2, 2]), Box(low=0, high=10, shape=[2, 2, 2])], + + [Tuple([Discrete(1), MultiDiscrete([1, 1])]), Tuple([Discrete(1), MultiDiscrete([1, 1])])], + [Dict({"first": Discrete(1), "second": MultiDiscrete([1, 1])}), + Dict({"first": Discrete(1), "second": MultiDiscrete([1, 1])})], + ] + + def test_init(self): + for o, a in self.list_work: + self.agent(o, a) + for n in [object(), "dada", 154, 12.1]: + with pytest.raises(TypeError): + self.agent(o, a, optimizer=n) + with pytest.raises(TypeError): + self.agent(o, a, network=n) + with pytest.raises(TypeError): + self.agent(o, a, memory=n) + with pytest.raises(TypeError): + self.agent(o, a, loss=n) + with pytest.raises(TypeError): + self.agent(o, a, greedy_exploration=n) + with pytest.raises(TypeError): + net = self.network(o, a) + self.agent(o, a, optimizer=optim.Adam(net.parameters()), network=None) + + for o, a in self.list_fail: + with pytest.raises(TypeError): + self.agent(o, a) + + def test_get_action(self): + for o, a in self.list_work: + assert 1 + for ge in [Greedy(), EpsilonGreedy(1.)]: + agent = self.agent(o, a, greedy_exploration=ge) + + for i in range(20): + act = agent.get_action(o.sample()) + if isinstance(a, Discrete): + assert act in range(a.n) + + def test_learn(self): + for o, a in self.list_work: + network = self.network(o, a) + memory = ExperienceReplay(max_size=5) + + agent = self.agent(observation_space=o, action_space=a, memory=memory, network=network) + + for i in range(20): + agent.learn(o.sample(), a.sample(), 0, o.sample(), False) + + def test_episode_finished(self): + for o, a in self.list_work: + agent = self.agent(observation_space=o, action_space=a) + agent.episode_finished() + + def test_agent_save_load(self): + for o, a in self.list_work: + agent = self.agent(observation_space=o, action_space=a) + + agent.save(file_name="deed.pt") + agent_l = self.agent.load(file_name="deed.pt") + + assert agent.observation_space == agent_l.observation_space + assert agent.action_space == agent_l.action_space + os.remove("deed.pt") + + agent = self.agent(observation_space=o, action_space=a) + agent.save(file_name="deed.pt", dire_name="./remove/") + + os.remove("./remove/deed.pt") + os.rmdir("./remove/") + + with pytest.raises(TypeError): + agent.save(file_name=14548) + with pytest.raises(TypeError): + agent.save(file_name="deed.pt", dire_name=14484) + + with pytest.raises(FileNotFoundError): + self.agent.load(file_name="deed.pt") + with pytest.raises(FileNotFoundError): + self.agent.load(file_name="deed.pt", dire_name="/Dede/") + + network = self.network(o, a) + + agent = self.agent(observation_space=o, action_space=a, memory=ExperienceReplay(), + network=network, + step_train=3, batch_size=12, gamma=0.50, + optimizer=torch.optim.Adam(network.parameters()), + greedy_exploration=EpsilonGreedy(0.2)) + + agent.save(file_name="deed.pt") + agent_l = self.agent.load(file_name="deed.pt") + + os.remove("deed.pt") + + assert agent.observation_space == agent_l.observation_space + assert a == agent_l.action_space + assert isinstance(agent.network, type(agent_l.network)) + for a, b in zip(agent.network.state_dict(), agent_l.network.state_dict()): + assert a == b + assert agent.step_train == agent_l.step_train + assert agent.batch_size == agent_l.batch_size + assert agent.gamma == agent_l.gamma + assert isinstance(agent.loss, type(agent_l.loss)) + for a, b in zip(agent.loss.parameters(), agent_l.loss.parameters()): + assert a == b + assert isinstance(agent.optimizer, type(agent_l.optimizer)) + for a, b in zip(agent.optimizer.state_dict(), agent_l.optimizer.state_dict()): + assert a == b + assert isinstance(agent.greedy_exploration, type(agent_l.greedy_exploration)) + + def test_device(self): + for o, a in self.list_work: + device = torch.device("cpu") + assert device == self.agent(o, a, device=device).device + + device = None + assert torch.device("cpu") == self.agent(o, a, device=device).device + + for device in ["dzeqdzqd", 1512, object(), 151.515]: + with pytest.raises(TypeError): + self.agent(o, a, device=device) + + if torch.cuda.is_available(): + self.agent(o, a, device=torch.device("cuda")) + + def test_dqn_agent_episode_finished(self): + for o, a in self.list_work: + network = self.network(o, a) + memory = ExperienceReplay(max_size=5) + + agent = self.agent(o, a, memory, network=network) + agent.episode_finished() + + def test_enable_train(self): + for o, a in self.list_work: + agent = self.agent(o, a) + + agent.with_exploration = False - agent.learn(obs, action, reward, next_obs, done) - agent.learn(obs, action, reward, next_obs, done) + agent.enable_exploration() + assert agent.with_exploration is True + + def test_disable_train(self): + for o, a in self.list_work: + agent = self.agent(o, a) + + agent.disable_exploration() + assert agent.with_exploration is False + + def test__str__(self): + for o, a in self.list_work: + agent = self.agent(o, a) + + assert 'DQN-' + str(agent.observation_space) + "-" + str(agent.action_space) + "-" + str( + agent.network) + "-" + str(agent.memory) + "-" + str(agent.step_train) + "-" + str( + agent.step) + "-" + str(agent.batch_size) + "-" + str(agent.gamma) + "-" + str(agent.loss) + "-" + str( + agent.optimizer) + "-" + str(agent.greedy_exploration) == agent.__str__() diff --git a/tests/agents/test_dueling_dqn.py b/tests/agents/test_dueling_dqn.py deleted file mode 100644 index dd7861f..0000000 --- a/tests/agents/test_dueling_dqn.py +++ /dev/null @@ -1,261 +0,0 @@ -import os - -import numpy as np -import pytest -import torch -import torch.nn as nn -import torch.nn.functional as F -import torch.optim as optim -from gym.spaces import Discrete, Box, MultiBinary, MultiDiscrete, Dict, Tuple - -from blobrl.agents import DuelingDQN -from blobrl.explorations import Greedy, EpsilonGreedy -from blobrl.memories import ExperienceReplay -from blobrl.networks import BaseDuelingNetwork - - -class Network(BaseDuelingNetwork): - def __str__(self): - return 'Network' - - def __init__(self, observation_shape=None, action_shape=None): - super().__init__(observation_shape, action_shape) - self.dense = nn.Linear(3, 4) - - def forward(self, x): - x = self.dense(x) - x = F.relu(x) - return x - - -def test_dueling_dqn_agent_instantiation(): - network = Network() - memory = ExperienceReplay(max_size=5) - - DuelingDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory) - DuelingDQN(Discrete(4), Discrete(3)) - - -def test_dueling_dqn_agent_instantiation_error_action_space(): - network = Network() - memory = ExperienceReplay(max_size=5) - - with pytest.raises(TypeError): - DuelingDQN("ACTION_SPACE_ERROR", Discrete(3), neural_network=network, memory=memory) - - -def test_dueling_dqn_agent_instantiation_error_observation_space(): - network = Network() - memory = ExperienceReplay(max_size=5) - - with pytest.raises(TypeError): - DuelingDQN(Discrete(1), "OBSERVATION_SPACE_ERROR", neural_network=network, memory=memory) - - -def test_dueling_dqn_agent_instantiation_error_neural_network(): - memory = ExperienceReplay(max_size=5) - - with pytest.raises(TypeError): - DuelingDQN(Discrete(4), Discrete(3), neural_network="NEURAL_NETWORK_ERROR", memory=memory) - - -def test_dueling_dqn_agent_instantiation_error_memory(): - network = Network() - - with pytest.raises(TypeError): - DuelingDQN(Discrete(4), Discrete(3), neural_network=network, memory="MEMORY_ERROR") - - -def test_dueling_dqn_agent_instantiation_error_loss(): - network = Network() - memory = ExperienceReplay(max_size=5) - - with pytest.raises(TypeError): - DuelingDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory, loss="LOSS_ERROR") - - -def test_dueling_dqn_agent_instantiation_error_optimizer(): - network = Network() - memory = ExperienceReplay(max_size=5) - - with pytest.raises(TypeError): - DuelingDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory, optimizer="OPTIMIZER_ERROR") - - -def test_dueling_dqn_agent_instantiation_error_greedy_exploration(): - network = Network() - memory = ExperienceReplay(max_size=5) - - with pytest.raises(TypeError): - DuelingDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory, - greedy_exploration="GREEDY_EXPLORATION_ERROR") - - -def test_dueling_dqn_agent_instantiation_custom_loss(): - network = Network() - memory = ExperienceReplay(max_size=5) - - DuelingDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory, loss=nn.MSELoss()) - - -def test_dueling_dqn_agent_instantiation_custom_optimizer(): - network = Network() - memory = ExperienceReplay(max_size=5) - - DuelingDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory, - optimizer=optim.RMSprop(network.parameters())) - - -def test_dueling_dqn_agent_getaction(): - network = Network() - memory = ExperienceReplay(max_size=5) - - agent = DuelingDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory, greedy_exploration=Greedy()) - - observation = [0, 1, 2] - - agent.get_action(observation) - - -def test_dueling_dqn_agent_getaction_non_greedy(): - network = Network() - memory = ExperienceReplay(max_size=5) - - agent = DuelingDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory, - greedy_exploration=EpsilonGreedy(1.)) - - observation = [0, 1, 2] - - agent.get_action(observation) - - -def test_dueling_dqn_agent_learn(): - network = Network() - memory = ExperienceReplay(max_size=5) - - agent = DuelingDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory, step_copy=2) - - obs = [1, 2, 5] - action = 0 - reward = 0 - next_obs = [5, 9, 4] - done = False - - obs_s = [obs, obs, obs] - actions = [1, 2, 3] - rewards = [-2.2, 5, 4] - next_obs_s = [next_obs, next_obs, next_obs] - dones = [False, True, False] - - memory.extend(obs_s, actions, rewards, next_obs_s, dones) - - agent.learn(obs, action, reward, next_obs, done) - agent.learn(obs, action, reward, next_obs, done) - - -def test_dueling_dqn_agent_episode_finished(): - network = Network() - memory = ExperienceReplay(max_size=5) - - agent = DuelingDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory) - agent.episode_finished() - - -base_list = {"box": Box(low=-1.0, high=2.0, shape=(3, 4), dtype=np.float32), "discrete": Discrete(3), - "multibinary": MultiBinary(10), "multidiscrete": MultiDiscrete(10)} -dict_list = Dict(base_list) -tuple_list = Tuple(list(base_list.values())) - -test_list = [*base_list.values(), dict_list, tuple_list] - - -def test_agent_save_load(): - for space in test_list: - agent = DuelingDQN(observation_space=space, action_space=Discrete(2)) - - agent.save(file_name="deed.pt") - agent_l = DuelingDQN.load(file_name="deed.pt") - - assert agent.observation_space == agent_l.observation_space - assert Discrete(2) == agent_l.action_space - os.remove("deed.pt") - - network = Network() - - agent = DuelingDQN(observation_space=space, action_space=Discrete(2), memory=ExperienceReplay(), - neural_network=network, step_train=3, batch_size=12, gamma=0.50, loss=None, - optimizer=torch.optim.Adam(network.parameters()), step_copy=300, - greedy_exploration=EpsilonGreedy(0.2)) - - agent.save(file_name="deed.pt") - agent_l = DuelingDQN.load(file_name="deed.pt") - - os.remove("deed.pt") - - assert agent.observation_space == agent_l.observation_space - assert Discrete(2) == agent_l.action_space - assert isinstance(agent.neural_network, type(agent_l.neural_network)) - for a, b in zip(agent.neural_network.state_dict(), agent_l.neural_network.state_dict()): - assert a == b - assert agent.step_train == agent_l.step_train - assert agent.batch_size == agent_l.batch_size - assert agent.gamma == agent_l.gamma - assert isinstance(agent.loss, type(agent_l.loss)) - for a, b in zip(agent.loss.parameters(), agent_l.loss.parameters()): - assert a == b - assert isinstance(agent.optimizer, type(agent_l.optimizer)) - for a, b in zip(agent.optimizer.state_dict(), agent_l.optimizer.state_dict()): - assert a == b - assert isinstance(agent.greedy_exploration, type(agent_l.greedy_exploration)) - assert agent.step_copy == agent_l.step_copy - - agent = DuelingDQN(observation_space=space, action_space=Discrete(2)) - agent.save(file_name="deed.pt", dire_name="./remove/") - - os.remove("./remove/deed.pt") - os.rmdir("./remove/") - - with pytest.raises(TypeError): - agent.save(file_name=14548) - with pytest.raises(TypeError): - agent.save(file_name="deed.pt", dire_name=14484) - - with pytest.raises(FileNotFoundError): - DuelingDQN.load(file_name="deed.pt") - with pytest.raises(FileNotFoundError): - DuelingDQN.load(file_name="deed.pt", dire_name="/Dede/") - - -def test__str__(): - agent = DuelingDQN(Discrete(4), Box(1, 10, (4,))) - - assert 'DuelingDQN-' + str(agent.observation_space) + "-" + str(agent.action_space) + "-" + str( - agent.neural_network) + "-" + str(agent.memory) + "-" + str(agent.step_train) + "-" + str( - agent.step) + "-" + str(agent.batch_size) + "-" + str(agent.gamma) + "-" + str(agent.loss) + "-" + str( - agent.optimizer) + "-" + str(agent.greedy_exploration) + "-" + str(agent.step_copy) == agent.__str__() - - -def test_device_gpu(): - if torch.cuda.is_available(): - network = Network() - memory = ExperienceReplay(max_size=5) - - agent = DuelingDQN(Discrete(4), Discrete(3), neural_network=network, memory=memory, step_copy=2, - device=torch.device("cuda")) - - obs = [1, 2, 5] - action = 0 - reward = 0 - next_obs = [5, 9, 4] - done = False - - obs_s = [obs, obs, obs] - actions = [1, 2, 3] - rewards = [-2.2, 5, 4] - next_obs_s = [next_obs, next_obs, next_obs] - dones = [False, True, False] - - memory.extend(obs_s, actions, rewards, next_obs_s, dones) - - agent.learn(obs, action, reward, next_obs, done) - agent.learn(obs, action, reward, next_obs, done) diff --git a/tests/memories/test_experience_replay.py b/tests/memories/test_experience_replay.py index c1c7e26..f148a66 100644 --- a/tests/memories/test_experience_replay.py +++ b/tests/memories/test_experience_replay.py @@ -8,20 +8,24 @@ def test_experience_replay(): mem = ExperienceReplay(max_size) - obs = [1, 2, 5] - action = 0 - reward = 0 - next_obs = [5, 9, 4] - done = False + for i in range(10): + obs = [1, 2, 5] + action = 0 + reward = 0 + next_obs = [5, 9, 4] + done = False - mem.append(obs, action, reward, next_obs, done) + mem.append(obs, action, reward, next_obs, done) - obs_s = [obs, obs, obs] - actions = [1, 2, 3] - rewards = [-2.2, 5, 4] - next_obs_s = [next_obs, next_obs, next_obs] - dones = [False, True, False] + mem.sample(2, device=torch.device("cpu")) + + for i in range(10): + obs_s = [obs, obs, obs] + actions = [1, 2, 3] + rewards = [-2.2, 5, 4] + next_obs_s = [next_obs, next_obs, next_obs] + dones = [False, True, False] - mem.extend(obs_s, actions, rewards, next_obs_s, dones) + mem.extend(obs_s, actions, rewards, next_obs_s, dones) mem.sample(2, device=torch.device("cpu")) diff --git a/tests/networks/__init__.py b/tests/networks/__init__.py index e69de29..5273a8a 100644 --- a/tests/networks/__init__.py +++ b/tests/networks/__init__.py @@ -0,0 +1,4 @@ +from .test_base_network import TestBaseNetwork +from .test_simple_network import TestSimpleNetwork +from .test_base_dueling_network import TestBaseDuelingNetwork +from .test_simple_dueling_network import TestSimpleDuelingNetwork diff --git a/tests/networks/test_base_dueling_network.py b/tests/networks/test_base_dueling_network.py index c086aa8..48ac2e3 100644 --- a/tests/networks/test_base_dueling_network.py +++ b/tests/networks/test_base_dueling_network.py @@ -1,8 +1,8 @@ -import pytest +from blobrl.networks import BaseDuelingNetwork +from tests.networks import TestBaseNetwork -from blobrl.networks import BaseNetwork +class TestBaseDuelingNetwork(TestBaseNetwork): + __test__ = True -def test_init_base_network_fail(): - with pytest.raises(TypeError): - BaseNetwork(None, None) + network = BaseDuelingNetwork diff --git a/tests/networks/test_base_network.py b/tests/networks/test_base_network.py index c086aa8..b7dd217 100644 --- a/tests/networks/test_base_network.py +++ b/tests/networks/test_base_network.py @@ -1,8 +1,51 @@ import pytest - from blobrl.networks import BaseNetwork +from gym.spaces import Discrete, MultiDiscrete, MultiBinary, Box, Tuple, Dict + + +class TestBaseNetwork: + __test__ = True + + network = BaseNetwork + + list_work = [ + [Discrete(3), Discrete(1)], + [Discrete(3), Discrete(3)], + [Discrete(10), Discrete(50)], + [MultiDiscrete([3]), MultiDiscrete([1])], + [MultiDiscrete([3, 3]), MultiDiscrete([3, 3])], + [MultiDiscrete([4, 4, 4]), MultiDiscrete([50, 4, 4])], + [MultiDiscrete([[100, 3], [3, 5]]), MultiDiscrete([[100, 3], [3, 5]])], + [MultiDiscrete([[[100, 3], [3, 5]], [[100, 3], [3, 5]]]), + MultiDiscrete([[[100, 3], [3, 5]], [[100, 3], [3, 5]]])], + [MultiBinary(1), MultiBinary(1)], + [MultiBinary(3), MultiBinary(3)], + # [MultiBinary([3, 2]), MultiBinary([3, 2])], # Don't work yet because gym don't implemented this + [Box(low=0, high=10, shape=[1]), Box(low=0, high=10, shape=[1])], + [Box(low=0, high=10, shape=[2, 2]), Box(low=0, high=10, shape=[2, 2])], + [Box(low=0, high=10, shape=[2, 2, 2]), Box(low=0, high=10, shape=[2, 2, 2])], + + [Tuple([Discrete(1), MultiDiscrete([1, 1])]), Tuple([Discrete(1), MultiDiscrete([1, 1])])], + [Dict({"first": Discrete(1), "second": MultiDiscrete([1, 1])}), + Dict({"first": Discrete(1), "second": MultiDiscrete([1, 1])})] + ] + + list_fail = [ + [None, None], + ["dedrfe", "qdzq"], + [1215.4154, 157.48], + ["zdzd", (Discrete(1))], + [Discrete(1), "zdzd"], + ["zdzd", (1, 4, 7)], + [(1, 4, 7), "zdzd"], + [152, 485] + ] + def test_init(self): + for ob, ac in self.list_fail: + with pytest.raises(TypeError): + self.network(observation_space=ob, action_space=ac) -def test_init_base_network_fail(): - with pytest.raises(TypeError): - BaseNetwork(None, None) + for ob, ac in self.list_work: + with pytest.raises(TypeError): + self.network(observation_space=ob, action_space=ac) diff --git a/tests/networks/test_c51_network.py b/tests/networks/test_c51_network.py index 8d8fd93..f63c7e6 100644 --- a/tests/networks/test_c51_network.py +++ b/tests/networks/test_c51_network.py @@ -1,34 +1,66 @@ import pytest import torch -from gym.spaces import Discrete +from gym.spaces import flatdim +from gym.spaces import Discrete, MultiDiscrete, MultiBinary, Box, Tuple, Dict from blobrl.networks import C51Network +from tests.networks import TestBaseNetwork -def test_c51_init(): - list_fail = [[None, None], - ["dedrfe", "qdzq"], - [1215.4154, 157.48], - ["zdzd", (Discrete(1))], - [Discrete(1), "zdzd"], - ["zdzd", (1, 4, 7)], - [(1, 4, 7), "zdzd"], - [Discrete(1), Discrete(1)]] - - for ob, ac in list_fail: - with pytest.raises(TypeError): - C51Network(observation_shape=ob, action_shape=ac) - - list_work = [[(454), (4)], - [(454, 54), (5, 2)], - [(454, 54, 45), (4, 5, 3)]] - for ob, ac in list_work: - C51Network(observation_shape=ob, action_shape=ac) - - -def test_c51_forward(): - list_work = [[(454, 54), (4, 2)], - [(454, 54, 45), (5, 1, 2)]] - for ob, ac in list_work: - simple_network = C51Network(observation_shape=ob, action_shape=ac) - simple_network.forward(torch.rand((2, *ob))) +class TestC51Network(TestBaseNetwork): + __test__ = True + + network = C51Network + + list_work = [ + [Discrete(3), Discrete(1)], + [Discrete(3), Discrete(3)], + [Discrete(10), Discrete(50)], + [MultiDiscrete([3]), MultiDiscrete([1])], + [MultiDiscrete([3, 3]), MultiDiscrete([3, 3])], + [MultiDiscrete([4, 4, 4]), MultiDiscrete([50, 4, 4])], + [MultiDiscrete([[100, 3], [3, 5]]), MultiDiscrete([[100, 3], [3, 5]])], + [MultiDiscrete([[[100, 3], [3, 5]], [[100, 3], [3, 5]]]), + MultiDiscrete([[[100, 3], [3, 5]], [[100, 3], [3, 5]]])] + + ] + + list_fail = [ + [None, None], + ["dedrfe", "qdzq"], + [1215.4154, 157.48], + ["zdzd", (Discrete(1))], + [Discrete(1), "zdzd"], + ["zdzd", (1, 4, 7)], + [(1, 4, 7), "zdzd"], + [152, 485], + [MultiBinary(1), MultiBinary(1)], + [MultiBinary(3), MultiBinary(3)], + # [MultiBinary([3, 2]), MultiBinary([3, 2])], # Don't work yet because gym don't implemented this + [Box(low=0, high=10, shape=[1]), Box(low=0, high=10, shape=[1])], + [Box(low=0, high=10, shape=[2, 2]), Box(low=0, high=10, shape=[2, 2])], + [Box(low=0, high=10, shape=[2, 2, 2]), Box(low=0, high=10, shape=[2, 2, 2])], + + [Tuple([Discrete(1), MultiDiscrete([1, 1])]), Tuple([Discrete(1), MultiDiscrete([1, 1])])], + [Dict({"first": Discrete(1), "second": MultiDiscrete([1, 1])}), + Dict({"first": Discrete(1), "second": MultiDiscrete([1, 1])})] + ] + + def test_init(self): + for ob, ac in self.list_fail: + with pytest.raises(TypeError): + self.network(observation_space=ob, action_space=ac) + + for ob, ac in self.list_work: + self.network(observation_space=ob, action_space=ac) + + def test_forward(self): + for ob, ac in self.list_work: + network = self.network(observation_space=ob, action_space=ac) + network.forward(torch.rand((1, flatdim(ob)))) + + def test_str_(self): + for ob, ac in self.list_work: + network = self.network(observation_space=ob, action_space=ac) + + assert 'C51Network-' + str(ob) + "-" + str(ac) == network.__str__() diff --git a/tests/networks/test_simple_dueling_network.py b/tests/networks/test_simple_dueling_network.py index 9e7f033..63e49b6 100644 --- a/tests/networks/test_simple_dueling_network.py +++ b/tests/networks/test_simple_dueling_network.py @@ -1,45 +1,45 @@ import pytest import torch -from gym.spaces import Discrete +from gym.spaces import flatdim, flatten -from blobrl.networks import SimpleDuelingNetwork +from blobrl.networks import SimpleDuelingNetwork, SimpleNetwork +from tests.networks import TestBaseDuelingNetwork -def test_simple_network_init(): - list_fail = [[None, None], - ["dedrfe", "qdzq"], - [1215.4154, 157.48], - ["zdzd", (Discrete(1))], - [Discrete(1), "zdzd"], - ["zdzd", (1, 4, 7)], - [(1, 4, 7), "zdzd"], - [Discrete(1), Discrete(1)]] +class TestSimpleDuelingNetwork(TestBaseDuelingNetwork): + __test__ = True - for ob, ac in list_fail: - with pytest.raises(TypeError): - SimpleDuelingNetwork(observation_shape=ob, action_shape=ac) + network = SimpleDuelingNetwork + net = SimpleNetwork - list_work = [[(454), (874)], - [(454, 54), (48, 44)], - [(454, 54, 45), (48, 44, 47)]] - for ob, ac in list_work: - SimpleDuelingNetwork(observation_shape=ob, action_shape=ac) + list_fail = [1, + 0.1, + "string", + object(), + network(net(TestBaseDuelingNetwork.list_work[0][0], TestBaseDuelingNetwork.list_work[0][1])) + ] + def test_init(self): + for net in self.list_fail: + with pytest.raises(TypeError): + self.network(net) -def test_forward(): - list_work = [[(454, 54), (48, 44)], - [(454, 54, 45), (48, 44, 47)]] - for ob, ac in list_work: - simple_network = SimpleDuelingNetwork(observation_shape=ob, action_shape=ac) - simple_network.forward(torch.rand((1, *ob))) + for ob, ac in self.list_work: + self.network(self.net(observation_space=ob, action_space=ac)) + def test_forward(self): + for ob, ac in self.list_work: + network = self.network(self.net(observation_space=ob, action_space=ac)) + network.forward(torch.rand((1, flatdim(ob)))) + def test_str_(self): + for ob, ac in self.list_work: + net = self.net(observation_space=ob, action_space=ac) + network = self.network(net) -def test__str__(): - list_work = [[(454, 54), (48, 44)], - [(454, 54, 45), (48, 44, 47)]] + assert 'SimpleDuelingNetwork-' + str(net) == network.__str__() - for ob, ac in list_work: - network = SimpleDuelingNetwork(observation_shape=ob, action_shape=ac) - - assert 'SimpleDuelingNetwork-' + str(ob) + "-" + str(ac) == network.__str__() \ No newline at end of file + def test_call_network(self): + for ob, ac in self.list_work: + self.network(SimpleNetwork(observation_space=ob, action_space=ac))( + torch.tensor([flatten(ob, ob.sample())]).float()) diff --git a/tests/networks/test_simple_network.py b/tests/networks/test_simple_network.py index 685e604..78bce4f 100644 --- a/tests/networks/test_simple_network.py +++ b/tests/networks/test_simple_network.py @@ -1,34 +1,36 @@ import pytest import torch -from gym.spaces import Discrete +from gym.spaces import flatdim, flatten from blobrl.networks import SimpleNetwork +from tests.networks import TestBaseNetwork -def test_simple_network_init(): - list_fail = [[None, None], - ["dedrfe", "qdzq"], - [1215.4154, 157.48], - ["zdzd", (Discrete(1))], - [Discrete(1), "zdzd"], - ["zdzd", (1, 4, 7)], - [(1, 4, 7), "zdzd"], - [Discrete(1), Discrete(1)]] - - for ob, ac in list_fail: - with pytest.raises(TypeError): - SimpleNetwork(observation_shape=ob, action_shape=ac) - - list_work = [[(454), (874)], - [(454, 54), (48, 44)], - [(454, 54, 45), (48, 44, 47)]] - for ob, ac in list_work: - SimpleNetwork(observation_shape=ob, action_shape=ac) - - -def test_forward(): - list_work = [[(454, 54), (48, 44)], - [(454, 54, 45), (48, 44, 47)]] - for ob, ac in list_work: - simple_network = SimpleNetwork(observation_shape=ob, action_shape=ac) - simple_network.forward(torch.rand((1, *ob))) +class TestSimpleNetwork(TestBaseNetwork): + __test__ = True + + network = SimpleNetwork + + def test_init(self): + for ob, ac in self.list_fail: + with pytest.raises(TypeError): + self.network(observation_space=ob, action_space=ac) + + for ob, ac in self.list_work: + self.network(observation_space=ob, action_space=ac) + + def test_forward(self): + for ob, ac in self.list_work: + network = self.network(observation_space=ob, action_space=ac) + network.forward(torch.rand((1, flatdim(ob)))) + + def test_str_(self): + for ob, ac in self.list_work: + network = self.network(observation_space=ob, action_space=ac) + + assert 'SimpleNetwork-' + str(ob) + "-" + str(ac) == network.__str__() + + def test_call_network(self): + for ob, ac in self.list_work: + self.network(observation_space=ob, action_space=ac)( + torch.tensor([flatten(ob, ob.sample())]).float()) diff --git a/tests/networks/test_utils.py b/tests/networks/test_utils.py new file mode 100644 index 0000000..36df394 --- /dev/null +++ b/tests/networks/test_utils.py @@ -0,0 +1,98 @@ +from blobrl.networks import get_last_layers +from gym.spaces import Box, Discrete, MultiDiscrete, MultiBinary, Tuple, Dict +import torch.nn as nn + + +def valid_dim(out_v, out_g): + if isinstance(out_v, list): + assert len(out_v) == len(out_g) + for o, g in zip(out_v, out_g): + valid_dim(o, g) + else: + assert len(out_v.state_dict()) == len(out_g.state_dict()) + + +def test_get_last_layers(): + in_values = [ + Discrete(10), + Discrete(1), + Discrete(100), + Discrete(5), + + MultiDiscrete([1]), + MultiDiscrete([10, 110, 3, 50]), + MultiDiscrete([1, 1, 1]), + MultiDiscrete([100, 3, 3, 5]), + + MultiDiscrete([[100, 3], [3, 5]]), + MultiDiscrete([[[100, 3], [3, 5]], [[100, 3], [3, 5]]]), + + MultiBinary(1), + MultiBinary(3), + MultiBinary([3, 2]), + + Box(low=0, high=10, shape=[1]), + Box(low=0, high=10, shape=[2, 2]), + Box(low=0, high=10, shape=[2, 2, 2]), + + Tuple([Discrete(1), MultiDiscrete([1, 1])]), + Dict({"first": Discrete(1), "second": MultiDiscrete([1, 1])}) + + ] + + out_values = [ + + nn.Linear(10, 10), + nn.Linear(10, 1), + nn.Linear(10, 100), + nn.Linear(10, 5), + + [nn.Sequential(*[nn.Linear(10, 10), nn.Softmax()])], + [nn.Sequential(*[nn.Linear(10, 10), nn.Softmax()]), nn.Sequential(*[nn.Linear(10, 110), nn.Softmax()]), + nn.Sequential(*[nn.Linear(10, 3), nn.Softmax()]), nn.Sequential(*[nn.Linear(10, 50), nn.Softmax()])], + [nn.Sequential(*[nn.Linear(10, 1), nn.Softmax()]), nn.Sequential(*[nn.Linear(10, 1), nn.Softmax()]), + nn.Sequential(*[nn.Linear(10, 1), nn.Softmax()])], + [nn.Sequential(*[nn.Linear(10, 100), nn.Softmax()]), nn.Sequential(*[nn.Linear(10, 3), nn.Softmax()]), + nn.Sequential(*[nn.Linear(10, 3), nn.Softmax()]), nn.Sequential(*[nn.Linear(10, 5), nn.Softmax()])], + + [[nn.Sequential(*[nn.Linear(10, 100), nn.Softmax()]), nn.Sequential(*[nn.Linear(10, 3), nn.Softmax()])], + [nn.Sequential(*[nn.Linear(10, 3), nn.Softmax()]), nn.Sequential(*[nn.Linear(10, 5), nn.Softmax()])]], + [ + [[nn.Sequential(*[nn.Linear(10, 100), nn.Softmax()]), nn.Sequential(*[nn.Linear(10, 3), nn.Softmax()])], + [nn.Sequential(*[nn.Linear(10, 3), nn.Softmax()]), nn.Sequential(*[nn.Linear(10, 5), nn.Softmax()])]], + [[nn.Sequential(*[nn.Linear(10, 100), nn.Softmax()]), nn.Sequential(*[nn.Linear(10, 3), nn.Softmax()])], + [nn.Sequential(*[nn.Linear(10, 3), nn.Softmax()]), nn.Sequential(*[nn.Linear(10, 5), nn.Softmax()])]] + ], + + [nn.Sequential(*[nn.Linear(10, 1), nn.Sigmoid()])], + [nn.Sequential(*[nn.Linear(10, 1), nn.Sigmoid()]), + nn.Sequential(*[nn.Linear(10, 1), nn.Sigmoid()]), + nn.Sequential(*[nn.Linear(10, 1), nn.Sigmoid()])], + + [ + [nn.Sequential(*[nn.Linear(10, 1), nn.Sigmoid()]), + nn.Sequential(*[nn.Linear(10, 1), nn.Sigmoid()])], + [nn.Sequential(*[nn.Linear(10, 1), nn.Sigmoid()]), + nn.Sequential(*[nn.Linear(10, 1), nn.Sigmoid()])], + [nn.Sequential(*[nn.Linear(10, 1), nn.Sigmoid()]), + nn.Sequential(*[nn.Linear(10, 1), nn.Sigmoid()])] + ], + + [nn.Linear(10, 1)] + , + [[nn.Linear(10, 1), nn.Linear(10, 1)], [nn.Linear(10, 1), nn.Linear(10, 1)]] + , + [[[nn.Linear(10, 1), nn.Linear(10, 1)], [nn.Linear(10, 1), nn.Linear(10, 1)]], + [[nn.Linear(10, 1), nn.Linear(10, 1)], [nn.Linear(10, 1), nn.Linear(10, 1)]]], + + [nn.Linear(10, 1), + [nn.Sequential(*[nn.Linear(10, 1), nn.Softmax()]), nn.Sequential(*[nn.Linear(10, 1), nn.Softmax()])]], + + [nn.Linear(10, 1), + [nn.Sequential(*[nn.Linear(10, 1), nn.Softmax()]), nn.Sequential(*[nn.Linear(10, 1), nn.Softmax()])]], + + ] + + for in_value, out_value in zip(in_values, out_values): + out_value_gen = get_last_layers(in_value, 10) + valid_dim(out_value, out_value_gen) diff --git a/tests/test_trainer.py b/tests/test_trainer.py index 1aef187..9837c99 100644 --- a/tests/test_trainer.py +++ b/tests/test_trainer.py @@ -7,6 +7,8 @@ import pytest from ipykernel import iostream +from gym.spaces import Discrete + from blobrl import Trainer, Logger from blobrl.agents import AgentInterface from blobrl.trainer import arg_to_agent @@ -14,7 +16,7 @@ def test_arg_to_agent(): fail_list = ["dzdzqd", None, 123, 123.123, [], {}, object] - work_list = ["agent_random", "dqn", "double_dqn", "categorical_dqn", "dueling_dqn"] + work_list = ["agent_random", "dqn", "double_dqn", "categorical_dqn"] for agent in fail_list: with pytest.raises(ValueError): @@ -71,7 +73,7 @@ def save(self, file_name, dire_name="."): pass def __init__(self, observation_space, action_space, device=None): - super().__init__(device) + super().__init__(Discrete(1), Discrete(1), device) self.get_action_done = 0 self.learn_done = 0 self.episode_finished_done = 0 @@ -252,6 +254,14 @@ def test_trainer_train(): assert fake_env.step_done == number_episode + eval and fake_env.reset_done == number_episode + eval + 1 assert fake_env.render_done == number_episode + eval + # test nb_evaluation + fake_env = FakeEnv() + fake_agent = FakeAgent(observation_space=None, action_space=None) + trainer = Trainer(environment=fake_env, agent=fake_agent) + + for i in range(10): + trainer.train(max_episode=100, nb_evaluation=i) + class FakeOutStream(iostream.OutStream): diff --git a/tests/train.py b/tests/train.py new file mode 100644 index 0000000..db66190 --- /dev/null +++ b/tests/train.py @@ -0,0 +1,22 @@ +from blobrl import Trainer, Record +from blobrl.agents import CategoricalDQN, DQN, DoubleDQN + +import gym + +if __name__ == "__main__": + + for agent in [CategoricalDQN, DQN, DoubleDQN]: + + env = gym.make("CartPole-v1") + a = agent(env.observation_space, env.action_space) + trainer = Trainer(environment=env, agent=agent) + + for i in range(100): + + trainer.train(max_episode=50, render=False, nb_evaluation=0) + m = max([Record.sum_records(e) for e in trainer.logger.episodes]) + print(agent.__name__, i, m) + if m > 200: + break + + print("####### ", agent.__name__, i, m, " #######")