diff --git a/agent/A2C_agent.py b/agent/A2C_agent.py index 8b3b12d..0c71e40 100644 --- a/agent/A2C_agent.py +++ b/agent/A2C_agent.py @@ -32,7 +32,7 @@ class A2CAgent(BaseAgent): states = self.states for _ in range(config.rollout_length): prob, log_prob, value = self.network.predict(config.state_normalizer(states)) - actions = [self.policy.sample(p) for p in prob.data.cpu().numpy()] + actions = [self.policy.sample(p) for p in prob.cpu().detach().numpy()] next_states, rewards, terminals, _ = self.task.step(actions) self.episode_rewards += rewards rewards = config.reward_normalizer(rewards) @@ -50,34 +50,34 @@ class A2CAgent(BaseAgent): processed_rollout = [None] * (len(rollout) - 1) advantages = self.network.tensor(np.zeros((config.num_workers, 1))) - returns = pending_value.data + returns = pending_value.detach() for i in reversed(range(len(rollout) - 1)): prob, log_prob, value, actions, rewards, terminals = rollout[i] terminals = self.network.tensor(terminals).unsqueeze(1) rewards = self.network.tensor(rewards).unsqueeze(1) - actions = self.network.tensor(actions, torch.LongTensor).unsqueeze(1) + actions = self.network.tensor(actions).unsqueeze(1).long() next_value = rollout[i + 1][2] returns = rewards + config.discount * terminals * returns if not config.use_gae: - advantages = returns - value.data + advantages = returns - value.detach() else: - td_error = rewards + config.discount * terminals * next_value.data - value.data + td_error = rewards + config.discount * terminals * next_value.detach() - value.detach() advantages = advantages * config.gae_tau * config.discount * terminals + td_error processed_rollout[i] = [prob, log_prob, value, actions, returns, advantages] prob, log_prob, value, actions, returns, advantages = map(lambda x: torch.cat(x, dim=0), zip(*processed_rollout)) - policy_loss = -log_prob.gather(1, Variable(actions)) * Variable(advantages) + policy_loss = -log_prob.gather(1, actions) * advantages entropy_loss = torch.sum(prob * log_prob, dim=1, keepdim=True) - value_loss = 0.5 * (Variable(returns) - value).pow(2) + value_loss = 0.5 * (returns - value).pow(2) - self.policy_loss = np.mean(policy_loss.data.cpu().numpy()) - self.entropy_loss = np.mean(entropy_loss.data.cpu().numpy()) - self.value_loss = np.mean(value_loss.data.cpu().numpy()) + self.policy_loss = np.mean(policy_loss.cpu().detach().numpy()) + self.entropy_loss = np.mean(entropy_loss.cpu().detach().numpy()) + self.value_loss = np.mean(value_loss.cpu().detach().numpy()) self.optimizer.zero_grad() (policy_loss + config.entropy_weight * entropy_loss + config.value_loss_weight * value_loss).mean().backward() - nn.utils.clip_grad_norm(self.network.parameters(), config.gradient_clip) + nn.utils.clip_grad_norm_(self.network.parameters(), config.gradient_clip) self.optimizer.step() self.evaluate(config.rollout_length) diff --git a/agent/CategoricalDQN_agent.py b/agent/CategoricalDQN_agent.py index 9e40447..bae59d1 100644 --- a/agent/CategoricalDQN_agent.py +++ b/agent/CategoricalDQN_agent.py @@ -34,8 +34,8 @@ class CategoricalDQNAgent(BaseAgent): self.delta_atom = (config.categorical_v_max - config.categorical_v_min) / float(config.categorical_n_atoms - 1) def evaluation_action(self, state): - value = self.network.predict(np.stack([self.config.state_normalizer(state)])).squeeze(0).data - value = (value * self.atoms).sum(-1).cpu().numpy().flatten() + value = self.network.predict(np.stack([self.config.state_normalizer(state)])).squeeze(0).detach() + value = (value * self.atoms).sum(-1).cpu().detach().numpy().flatten() return np.argmax(value) def episode(self, deterministic=False): @@ -44,9 +44,9 @@ class CategoricalDQNAgent(BaseAgent): total_reward = 0.0 steps = 0 while True: - value = self.network.predict(np.stack([self.config.state_normalizer(state)])).squeeze(0).data + value = self.network.predict(np.stack([self.config.state_normalizer(state)])).squeeze(0).detach() # self.config.logger.histo_summary('prob', value, self.total_steps) - value = (value * self.atoms).sum(-1).cpu().numpy().flatten() + value = (value * self.atoms).sum(-1).cpu().detach().numpy().flatten() # self.config.logger.histo_summary('q', value, self.total_steps) if deterministic: action = np.argmax(value) @@ -68,13 +68,13 @@ class CategoricalDQNAgent(BaseAgent): states, actions, rewards, next_states, terminals = experiences states = self.config.state_normalizer(states) next_states = self.config.state_normalizer(next_states) - prob_next = self.target_network.predict(next_states).data + prob_next = self.target_network.predict(next_states).detach() q_next = (prob_next * self.atoms).sum(-1) - # self.config.logger.histo_summary('q next', q_next.cpu().numpy(), self.total_steps) + # self.config.logger.histo_summary('q next', q_next.cpu().detach().numpy(), self.total_steps) _, a_next = torch.max(q_next, dim=1) a_next = a_next.view(-1, 1, 1).expand(-1, -1, prob_next.size(2)) prob_next = prob_next.gather(1, a_next).squeeze(1) - # self.config.logger.histo_summary('prob next', prob_next.cpu().numpy(), self.total_steps) + # self.config.logger.histo_summary('prob next', prob_next.cpu().detach().numpy(), self.total_steps) rewards = self.network.tensor(rewards) terminals = self.network.tensor(terminals) @@ -92,14 +92,13 @@ class CategoricalDQNAgent(BaseAgent): target_prob[i].index_add_(0, u[i].long(), d_m_u[i]) prob = self.network.predict(states) - actions = self.network.tensor(actions, torch.LongTensor) + actions = self.network.tensor(actions).long() actions = actions.view(-1, 1, 1).expand(-1, -1, prob.size(2)) - prob = prob.gather(1, Variable(actions)).squeeze(1) - loss = -(Variable(target_prob) * prob.log()).sum(-1).mean() - # self.config.logger.scalar_summary('loss', loss.data.cpu().numpy().flatten(), self.total_steps) + prob = prob.gather(1, actions).squeeze(1) + loss = -(target_prob * prob.log()).sum(-1).mean() self.optimizer.zero_grad() loss.backward() - nn.utils.clip_grad_norm(self.network.parameters(), self.config.gradient_clip) + nn.utils.clip_grad_norm_(self.network.parameters(), self.config.gradient_clip) self.optimizer.step() self.evaluate() diff --git a/agent/DDPG_agent.py b/agent/DDPG_agent.py index c564728..0b62391 100644 --- a/agent/DDPG_agent.py +++ b/agent/DDPG_agent.py @@ -35,8 +35,9 @@ class DDPGAgent(BaseAgent): def soft_update(self, target, src): for target_param, param in zip(target.parameters(), src.parameters()): - target_param.data.copy_(target_param.data * (1.0 - self.config.target_network_mix) + - param.data * self.config.target_network_mix) + target_param.detach_() + target_param.copy_(target_param * (1.0 - self.config.target_network_mix) + + param * self.config.target_network_mix) def evaluation_action(self, state): self.config.state_normalizer.set_read_only() @@ -82,8 +83,8 @@ class DDPGAgent(BaseAgent): experiences = self.replay.sample() states, actions, rewards, next_states, terminals = experiences q_next = target_critic.predict(next_states, target_actor.predict(next_states)) - terminals = critic.variable(terminals).unsqueeze(1) - rewards = critic.variable(rewards).unsqueeze(1) + terminals = critic.tensor(terminals).unsqueeze(1) + rewards = critic.tensor(rewards).unsqueeze(1) q_next = config.discount * q_next * (1 - terminals) q_next.add_(rewards) q_next = q_next.detach() @@ -96,15 +97,14 @@ class DDPGAgent(BaseAgent): self.critic_opt.step() actions = actor.predict(states, False) - var_actions = Variable(actions.data, requires_grad=True) + var_actions = actions.detach().requires_grad_() q = critic.predict(states, var_actions) q.backward(critic.tensor(np.ones(q.size()))) actor.zero_grad() self.actor_opt.zero_grad() - actions.backward(-var_actions.grad.data) - for param in actor.parameters(): - param.grad.data.clamp(-config.gradient_clip, config.gradient_clip) + actions.backward(-var_actions.grad) + torch.nn.utils.clip_grad_value_(actor.parameters(), config.gradient_clip) self.actor_opt.step() self.soft_update(self.target_network, self.network) diff --git a/agent/DQN_agent.py b/agent/DQN_agent.py index dedffb7..ccb2974 100644 --- a/agent/DQN_agent.py +++ b/agent/DQN_agent.py @@ -61,17 +61,17 @@ class DQNAgent(BaseAgent): q_next = q_next.gather(1, best_actions.unsqueeze(1)).squeeze(1) else: q_next, _ = q_next.max(1) - terminals = self.network.variable(terminals) - rewards = self.network.variable(rewards) + terminals = self.network.tensor(terminals) + rewards = self.network.tensor(rewards) q_next = self.config.discount * q_next * (1 - terminals) q_next.add_(rewards) - actions = self.network.variable(actions, torch.LongTensor).unsqueeze(1) + actions = self.network.tensor(actions).unsqueeze(1).long() q = self.network.predict(states, False) q = q.gather(1, actions).squeeze(1) loss = self.criterion(q, q_next) self.optimizer.zero_grad() loss.backward() - nn.utils.clip_grad_norm(self.network.parameters(), self.config.gradient_clip) + nn.utils.clip_grad_norm_(self.network.parameters(), self.config.gradient_clip) self.optimizer.step() self.evaluate() diff --git a/agent/NStepDQN_agent.py b/agent/NStepDQN_agent.py index 5358f06..61fa1b8 100644 --- a/agent/NStepDQN_agent.py +++ b/agent/NStepDQN_agent.py @@ -36,7 +36,7 @@ class NStepDQNAgent(BaseAgent): states = self.states for _ in range(config.rollout_length): q = self.network.predict(self.config.state_normalizer(states)) - actions = [self.policy.sample(v) for v in q.data.cpu().numpy()] + actions = [self.policy.sample(v) for v in q.cpu().detach().numpy()] next_states, rewards, terminals, _ = self.task.step(actions) self.episode_rewards += rewards rewards = config.reward_normalizer(rewards) @@ -56,22 +56,22 @@ class NStepDQNAgent(BaseAgent): self.states = states processed_rollout = [None] * (len(rollout)) - returns = self.target_network.predict(config.state_normalizer(states)).data + returns = self.target_network.predict(config.state_normalizer(states)).detach() returns, _ = torch.max(returns, dim=1, keepdim=True) for i in reversed(range(len(rollout))): q, actions, rewards, terminals = rollout[i] - actions = self.network.tensor(actions, torch.LongTensor).unsqueeze(1) - q = q.gather(1, Variable(actions)) + actions = self.network.tensor(actions).unsqueeze(1).long() + q = q.gather(1, actions) terminals = self.network.tensor(terminals).unsqueeze(1) rewards = self.network.tensor(rewards).unsqueeze(1) returns = rewards + config.discount * terminals * returns processed_rollout[i] = [q, returns] q, returns= map(lambda x: torch.cat(x, dim=0), zip(*processed_rollout)) - loss = 0.5 * (q - Variable(returns)).pow(2).mean() + loss = 0.5 * (q - returns).pow(2).mean() self.optimizer.zero_grad() loss.backward() - nn.utils.clip_grad_norm(self.network.parameters(), config.gradient_clip) + nn.utils.clip_grad_norm_(self.network.parameters(), config.gradient_clip) self.optimizer.step() self.evaluate(config.rollout_length) \ No newline at end of file diff --git a/agent/PPO_agent.py b/agent/PPO_agent.py index 407a6a1..89d4b14 100644 --- a/agent/PPO_agent.py +++ b/agent/PPO_agent.py @@ -32,7 +32,7 @@ class PPOAgent(BaseAgent): states = self.states for _ in range(config.rollout_length): actions, log_probs, _, values = self.network.predict(states) - next_states, rewards, terminals, _ = self.task.step(actions.data.cpu().numpy()) + next_states, rewards, terminals, _ = self.task.step(actions.cpu().detach().numpy()) self.episode_rewards += rewards rewards = config.reward_normalizer(rewards) for i, terminal in enumerate(terminals): @@ -49,33 +49,31 @@ class PPOAgent(BaseAgent): processed_rollout = [None] * (len(rollout) - 1) advantages = self.network.tensor(np.zeros((config.num_workers, 1))) - returns = pending_value.data + returns = pending_value.detach() for i in reversed(range(len(rollout) - 1)): states, value, actions, log_probs, rewards, terminals = rollout[i] terminals = self.network.tensor(terminals).unsqueeze(1) rewards = self.network.tensor(rewards).unsqueeze(1) - actions = self.network.variable(actions) - states = self.network.variable(states) + actions = self.network.tensor(actions) + states = self.network.tensor(states) next_value = rollout[i + 1][1] returns = rewards + config.discount * terminals * returns if not config.use_gae: - advantages = returns - value.data + advantages = returns - value.detach() else: - td_error = rewards + config.discount * terminals * next_value.data - value.data + td_error = rewards + config.discount * terminals * next_value.detach() - value.detach() advantages = advantages * config.gae_tau * config.discount * terminals + td_error processed_rollout[i] = [states, actions, log_probs, returns, advantages] states, actions, log_probs_old, returns, advantages = map(lambda x: torch.cat(x, dim=0), zip(*processed_rollout)) advantages = (advantages - advantages.mean()) / advantages.std() - advantages = Variable(advantages) - returns = Variable(returns) batcher = Batcher(states.size(0) // config.num_mini_batches, [np.arange(states.size(0))]) for _ in range(config.optimization_epochs): batcher.shuffle() while not batcher.end(): batch_indices = batcher.next_batch()[0] - batch_indices = self.network.variable(batch_indices, torch.LongTensor) + batch_indices = self.network.tensor(batch_indices).long() sampled_states = states[batch_indices] sampled_actions = actions[batch_indices] sampled_log_probs_old = log_probs_old[batch_indices] @@ -93,7 +91,7 @@ class PPOAgent(BaseAgent): self.network.zero_grad() (policy_loss + value_loss).backward() - nn.utils.clip_grad_norm(self.network.parameters(), config.gradient_clip) + nn.utils.clip_grad_norm_(self.network.parameters(), config.gradient_clip) self.network.step() steps = config.rollout_length * config.num_workers diff --git a/agent/QuantileRegressionDQN_agent.py b/agent/QuantileRegressionDQN_agent.py index 0448850..e5b83b2 100644 --- a/agent/QuantileRegressionDQN_agent.py +++ b/agent/QuantileRegressionDQN_agent.py @@ -36,8 +36,8 @@ class QuantileRegressionDQNAgent(BaseAgent): return 0.5 * x.pow(2) * cond + (x.abs() - 0.5) * (1 - cond) def evaluation_action(self, state): - value = self.network.predict(np.stack([self.config.state_normalizer(state)])).squeeze(0).data - value = (value * self.quantile_weight).sum(-1).cpu().numpy().flatten() + value = self.network.predict(np.stack([self.config.state_normalizer(state)])).squeeze(0).detach() + value = (value * self.quantile_weight).sum(-1).cpu().detach().numpy().flatten() return np.argmax(value) def episode(self, deterministic=False): @@ -46,8 +46,8 @@ class QuantileRegressionDQNAgent(BaseAgent): total_reward = 0.0 steps = 0 while True: - value = self.network.predict(np.stack([self.config.state_normalizer(state)])).squeeze(0).data - value = (value * self.quantile_weight).sum(-1).cpu().numpy().flatten() + value = self.network.predict(np.stack([self.config.state_normalizer(state)])).squeeze(0).detach() + value = (value * self.quantile_weight).sum(-1).cpu().detach().numpy().flatten() if deterministic: action = np.argmax(value) elif self.total_steps < self.config.exploration_steps: @@ -69,7 +69,7 @@ class QuantileRegressionDQNAgent(BaseAgent): states = self.config.state_normalizer(states) next_states = self.config.state_normalizer(next_states) - quantiles_next = self.target_network.predict(next_states).data + quantiles_next = self.target_network.predict(next_states).detach() q_next = (quantiles_next * self.quantile_weight).sum(-1) _, a_next = torch.max(q_next, dim=1) a_next = a_next.view(-1, 1, 1).expand(-1, -1, quantiles_next.size(2)) @@ -80,13 +80,13 @@ class QuantileRegressionDQNAgent(BaseAgent): quantiles_next = rewards.view(-1, 1) + self.config.discount * (1 - terminals.view(-1, 1)) * quantiles_next quantiles = self.network.predict(states) - actions = self.network.tensor(actions, torch.LongTensor) + actions = self.network.tensor(actions).long() actions = actions.view(-1, 1, 1).expand(-1, -1, quantiles.size(2)) - quantiles = quantiles.gather(1, Variable(actions)).squeeze(1) + quantiles = quantiles.gather(1, actions).squeeze(1) quantiles_next = quantiles_next.t().unsqueeze(-1) - diff = Variable(quantiles_next) - quantiles - loss = self.huber(diff) * Variable(self.cumulative_density.view(1, -1) - (diff.data < 0).float()).abs() + diff = quantiles_next - quantiles + loss = self.huber(diff) * (self.cumulative_density.view(1, -1) - (diff.detach() < 0).float()).abs() self.optimizer.zero_grad() loss.mean(1).sum().backward() diff --git a/main.py b/main.py index eaeb51b..d48b0a8 100644 --- a/main.py +++ b/main.py @@ -275,9 +275,9 @@ def dqn_ram_atari(name): def ppo_continuous(): config = Config() config.num_workers = 1 - # task_fn = lambda log_dir: Pendulum(log_dir=log_dir) + task_fn = lambda log_dir: Pendulum(log_dir=log_dir) # task_fn = lambda log_dir: Roboschool('RoboschoolInvertedPendulum-v1', log_dir=log_dir) - task_fn = lambda log_dir: Roboschool('RoboschoolAnt-v1', log_dir=log_dir) + # task_fn = lambda log_dir: Roboschool('RoboschoolAnt-v1', log_dir=log_dir) # task_fn = lambda log_dir: Roboschool('RoboschoolReacher-v1', log_dir=log_dir) # task_fn = lambda log_dir: Roboschool('RoboschoolHopper-v1', log_dir=log_dir) # task_fn = lambda log_dir: DMControl('cartpole', 'balance', log_dir=log_dir) @@ -307,15 +307,15 @@ def ppo_continuous(): def ddpg_continuous(): config = Config() log_dir = get_default_log_dir(ddpg_continuous.__name__) - # config.task_fn = lambda: Pendulum(log_dir=log_dir) + config.task_fn = lambda: Pendulum(log_dir=log_dir) # config.task_fn = lambda: Roboschool('RoboschoolInvertedPendulum-v1', log_dir=log_dir) # config.task_fn = lambda: Roboschool('RoboschoolReacher-v1', log_dir=log_dir) - config.task_fn = lambda: Roboschool('RoboschoolHopper-v1') + # config.task_fn = lambda: Roboschool('RoboschoolHopper-v1') # config.task_fn = lambda: Roboschool('RoboschoolAnt-v1', log_dir=log_dir) # config.task_fn = lambda: Roboschool('RoboschoolWalker2d-v1', log_dir=log_dir) # config.task_fn = lambda: DMControl('cartpole', 'balance', log_dir=log_dir) # config.task_fn = lambda: DMControl('finger', 'spin', log_dir=log_dir) - config.evaluation_env = Roboschool('RoboschoolHopper-v1', log_dir=log_dir) + # config.evaluation_env = Roboschool('RoboschoolHopper-v1', log_dir=log_dir) config.actor_network_fn = lambda state_dim, action_dim: DeterministicActorNet(state_dim, action_dim) config.critic_network_fn = lambda state_dim, action_dim: DeterministicCriticNet(state_dim, action_dim) config.actor_optimizer_fn = lambda params: torch.optim.Adam(params, lr=1e-4) @@ -374,6 +374,8 @@ if __name__ == '__main__': mkdir('dataset') mkdir('log') os.system('export OMP_NUM_THREADS=1') + os.system('export MKL_NUM_THREADS=1') + torch.set_num_threads(1) # logger.setLevel(logging.DEBUG) logger.setLevel(logging.INFO) diff --git a/model/action_conditional_video_prediction.py b/model/action_conditional_video_prediction.py index e0f8ec0..a28b7b0 100644 --- a/model/action_conditional_video_prediction.py +++ b/model/action_conditional_video_prediction.py @@ -21,7 +21,7 @@ from utils import * from tqdm import tqdm from network import * -class Network(nn.Module, BasicNet): +class Network(nn.Module, BaseNet): def __init__(self, num_actions, gpu=0): super(Network, self).__init__() @@ -46,17 +46,18 @@ class Network(nn.Module, BasicNet): self.init_weights() self.criterion = nn.MSELoss() self.opt = torch.optim.Adam(self.parameters(), 1e-4) + + self.set_gpu(gpu) - BasicNet.__init__(self, gpu) def init_weights(self): for layer in self.children(): if isinstance(layer, nn.Conv2d) or isinstance(layer, nn.ConvTranspose2d): - nn.init.xavier_uniform(layer.weight.data) - nn.init.constant(layer.bias.data, 0) - nn.init.uniform(self.fc_encode.weight.data, -1, 1) - nn.init.uniform(self.fc_decode.weight.data, -1, 1) - nn.init.uniform(self.fc_action.weight.data, -0.1, 0.1) + nn.init.xavier_uniform_(layer.weight.data) + nn.init.constant_(layer.bias.data, 0) + nn.init.uniform_(self.fc_encode.weight.data, -1, 1) + nn.init.uniform_(self.fc_decode.weight.data, -1, 1) + nn.init.uniform_(self.fc_action.weight.data, -0.1, 0.1) def forward(self, obs, action): x = F.relu(self.conv1(obs)) @@ -78,9 +79,9 @@ class Network(nn.Module, BasicNet): return x def fit(self, x, a, y): - x = self.variable(x) - a = self.variable(a) - y = self.variable(y) + x = self.tensor(x) + a = self.tensor(a) + y = self.tensor(y) y_ = self.forward(x, a) loss = self.criterion(y_, y) self.opt.zero_grad() @@ -91,16 +92,16 @@ class Network(nn.Module, BasicNet): return np.asscalar(loss.cpu().data.numpy()) def evaluate(self, x, a, y): - x = self.variable(x) - a = self.variable(a) - y = self.variable(y) + x = self.tensor(x) + a = self.tensor(a) + y = self.tensor(y) y_ = self.forward(x, a) loss = self.criterion(y_, y) return np.asscalar(loss.cpu().data.numpy()) def predict(self, x, a): - x = self.variable(x) - a = self.variable(a) + x = self.tensor(x) + a = self.tensor(a) return self.forward(x, a).cpu().data.numpy() def load_episode(game, ep, num_actions, prefix): diff --git a/network/network_bodies.py b/network/network_bodies.py index 6e43d28..d614ae5 100644 --- a/network/network_bodies.py +++ b/network/network_bodies.py @@ -36,7 +36,7 @@ class TwoLayerFCBody(nn.Module): y = self.gate(self.fc2(y)) return y -class DeterministicActorNet(nn.Module, BasicNet): +class DeterministicActorNet(nn.Module, BaseNet): def __init__(self, state_dim, action_dim, @@ -52,15 +52,15 @@ class DeterministicActorNet(nn.Module, BasicNet): self.action_scale = action_scale self.non_linear = non_linear self.init_weights() - BasicNet.__init__(self, gpu) + self.set_gpu(gpu) def init_weights(self): bound = 3e-3 - nn.init.uniform(self.layer3.weight.data, -bound, bound) - nn.init.constant(self.layer3.bias.data, 0) + nn.init.uniform_(self.layer3.weight.data, -bound, bound) + nn.init.constant_(self.layer3.bias.data, 0) def forward(self, x): - x = self.variable(x) + x = self.tensor(x) x = self.non_linear(self.layer1(x)) x = self.non_linear(self.layer2(x)) x = self.layer3(x) @@ -70,10 +70,10 @@ class DeterministicActorNet(nn.Module, BasicNet): def predict(self, x, to_numpy=False): y = self.forward(x) if to_numpy: - y = y.cpu().data.numpy() + y = y.cpu().detach().numpy() return y -class DeterministicCriticNet(nn.Module, BasicNet): +class DeterministicCriticNet(nn.Module, BaseNet): def __init__(self, state_dim, action_dim, @@ -85,16 +85,16 @@ class DeterministicCriticNet(nn.Module, BasicNet): self.layer3 = nn.Linear(300, 1) self.non_linear = non_linear self.init_weights() - BasicNet.__init__(self, gpu) + self.set_gpu(gpu) def init_weights(self): bound = 3e-3 - nn.init.uniform(self.layer3.weight.data, -bound, bound) - nn.init.constant(self.layer3.bias.data, 0) + nn.init.uniform_(self.layer3.weight.data, -bound, bound) + nn.init.constant_(self.layer3.bias.data, 0) def forward(self, x, action): - x = self.variable(x) - action = self.variable(action) + x = self.tensor(x) + action = self.tensor(action) x = self.non_linear(self.layer1(x)) x = self.non_linear(self.layer2(torch.cat([x, action], dim=1))) x = self.layer3(x) @@ -103,7 +103,7 @@ class DeterministicCriticNet(nn.Module, BasicNet): def predict(self, x, action): return self.forward(x, action) -class GaussianActorNet(nn.Module, BasicNet): +class GaussianActorNet(nn.Module, BaseNet): def __init__(self, state_dim, action_dim, @@ -120,15 +120,15 @@ class GaussianActorNet(nn.Module, BasicNet): self.non_linear = non_linear self.init_weights() - BasicNet.__init__(self, gpu) + self.set_gpu(gpu) def init_weights(self): bound = 3e-3 - nn.init.uniform(self.fc_action.weight.data, -bound, bound) - nn.init.constant(self.fc_action.bias.data, 0) + nn.init.uniform_(self.fc_action.weight.data, -bound, bound) + nn.init.constant_(self.fc_action.bias.data, 0) def forward(self, x): - x = self.variable(x) + x = self.tensor(x) phi = self.non_linear(self.fc1(x)) phi = self.non_linear(self.fc2(phi)) mean = F.tanh(self.fc_action(phi)) @@ -139,7 +139,7 @@ class GaussianActorNet(nn.Module, BasicNet): def predict(self, x): return self.forward(x) -class GaussianCriticNet(nn.Module, BasicNet): +class GaussianCriticNet(nn.Module, BaseNet): def __init__(self, state_dim, gpu=-1, @@ -151,15 +151,15 @@ class GaussianCriticNet(nn.Module, BasicNet): self.fc_value = nn.Linear(hidden_size, 1) self.non_linear = non_linear self.init_weights() - BasicNet.__init__(self, gpu) + self.set_gpu(gpu) def init_weights(self): bound = 3e-3 - nn.init.uniform(self.fc_value.weight.data, -bound, bound) - nn.init.constant(self.fc_value.bias.data, 0) + nn.init.uniform_(self.fc_value.weight.data, -bound, bound) + nn.init.constant_(self.fc_value.bias.data, 0) def forward(self, x): - x = self.variable(x) + x = self.tensor(x) phi = self.non_linear(self.fc1(x)) phi = self.non_linear(self.fc2(phi)) value = self.fc_value(phi) diff --git a/network/network_heads.py b/network/network_heads.py index 62f497a..54a338a 100644 --- a/network/network_heads.py +++ b/network/network_heads.py @@ -6,89 +6,85 @@ from .network_utils import * -class VanillaNet(nn.Module, BasicNet): +class VanillaNet(nn.Module, BaseNet): def __init__(self, output_dim, body, gpu=-1): super(VanillaNet, self).__init__() self.fc_head = layer_init(nn.Linear(body.feature_dim, output_dim)) self.body = body - BasicNet.__init__(self, gpu) + self.set_gpu(gpu) def predict(self, x, to_numpy=False): - phi = self.body(self.variable(x)) + phi = self.body(self.tensor(x)) y = self.fc_head(phi) if to_numpy: - y = y.cpu().data.numpy() + y = y.cpu().detach().numpy() return y -class DuelingNet(nn.Module, BasicNet): +class DuelingNet(nn.Module, BaseNet): def __init__(self, action_dim, body, gpu=-1): super(DuelingNet, self).__init__() self.fc_value = layer_init(nn.Linear(body.feature_dim, 1)) self.fc_advantage = layer_init(nn.Linear(body.feature_dim, action_dim)) self.body = body - BasicNet.__init__(self, gpu) + self.set_gpu(gpu) def predict(self, x, to_numpy=False): - phi = self.body(self.variable(x)) + phi = self.body(self.tensor(x)) value = self.fc_value(phi) advantange = self.fc_advantage(phi) q = value.expand_as(advantange) + (advantange - advantange.mean(1, keepdim=True).expand_as(advantange)) if to_numpy: - return q.cpu().data.numpy() + return q.cpu().detach().numpy() return q -class ActorCriticNet(nn.Module, BasicNet): +class ActorCriticNet(nn.Module, BaseNet): def __init__(self, action_dim, body, gpu=-1): super(ActorCriticNet, self).__init__() self.fc_actor = layer_init(nn.Linear(body.feature_dim, action_dim)) self.fc_critic = layer_init(nn.Linear(body.feature_dim, 1)) self.body = body - BasicNet.__init__(self, gpu) + self.set_gpu(gpu) def predict(self, x, to_numpy=False): - phi = self.body(self.variable(x)) + phi = self.body(self.tensor(x)) pre_prob = self.fc_actor(phi) prob = F.softmax(pre_prob, dim=1) log_prob = F.log_softmax(pre_prob, dim=1) value = self.fc_critic(phi) if to_numpy: - return prob.cpu().data.numpy() + return prob.cpu().detach().numpy() return prob, log_prob, value -class CategoricalNet(nn.Module, BasicNet): +class CategoricalNet(nn.Module, BaseNet): def __init__(self, action_dim, num_atoms, body, gpu=-1): super(CategoricalNet, self).__init__() self.fc_categorical = layer_init(nn.Linear(body.feature_dim, action_dim * num_atoms)) self.action_dim = action_dim self.num_atoms = num_atoms self.body = body - BasicNet.__init__(self, gpu) + self.set_gpu(gpu) def predict(self, x, to_numpy=False): - phi = self.body(self.variable(x)) + phi = self.body(self.tensor(x)) pre_prob = self.fc_categorical(phi).view((-1, self.action_dim, self.num_atoms)) prob = F.softmax(pre_prob, dim=-1) if to_numpy: - return prob.cpu().data.numpy() + return prob.cpu().detach().numpy() return prob -class QuantileNet(nn.Module, BasicNet): +class QuantileNet(nn.Module, BaseNet): def __init__(self, action_dim, num_quantiles, body, gpu=-1): super(QuantileNet, self).__init__() self.fc_quantiles = layer_init(nn.Linear(body.feature_dim, action_dim * num_quantiles)) self.action_dim = action_dim self.num_quantiles = num_quantiles self.body = body - BasicNet.__init__(self, gpu) + self.set_gpu(gpu) def predict(self, x, to_numpy=False): - phi = self.body(self.variable(x)) + phi = self.body(self.tensor(x)) quantiles = self.fc_quantiles(phi) quantiles = quantiles.view((-1, self.action_dim, self.num_quantiles)) if to_numpy: - quantiles = quantiles.data.cpu().numpy() + quantiles = quantiles.cpu().detach().numpy() return quantiles - - - - diff --git a/network/network_utils.py b/network/network_utils.py index 178b845..fca5135 100644 --- a/network/network_utils.py +++ b/network/network_utils.py @@ -5,37 +5,20 @@ ####################################################################### import torch -from torch.autograd import Variable import torch.nn as nn import torch.nn.functional as F import numpy as np -class BasicNet: - def __init__(self, gpu): - if not torch.cuda.is_available(): - gpu = -1 - self.gpu = gpu - if self.gpu >= 0: - self.cuda(self.gpu) +class BaseNet: + def set_gpu(self, gpu): + if gpu >= 0 and torch.cuda.is_available(): + self.device = torch.device('gpu:%d' % (gpu)) + else: + self.device = torch.device('cpu') + self.to(self.device) - def supported_dtype(self, x, torch_type): - if torch_type == torch.FloatTensor: - return np.asarray(x, dtype=np.float32) - if torch_type == torch.LongTensor: - return np.asarray(x, dtype=np.int64) - - def variable(self, x, dtype=torch.FloatTensor): - if isinstance(x, Variable): - return x - x = dtype(torch.from_numpy(self.supported_dtype(x, dtype))) - if self.gpu >= 0: - x = x.cuda(self.gpu) - return Variable(x) - - def tensor(self, x, dtype=torch.FloatTensor): - x = dtype(torch.from_numpy(self.supported_dtype(x, dtype))) - if self.gpu >= 0: - x = x.cuda(self.gpu) + def tensor(self, x): + x = torch.tensor(x, device=self.device, dtype=torch.float32) return x class DisjointActorCriticWrapper: @@ -74,11 +57,8 @@ class GaussianActorCriticWrapper: log_probs = torch.sum(log_probs, dim=1, keepdim=True) return actions, log_probs, 0, values - def variable(self, x, dtype=torch.FloatTensor): - return self.actor.variable(x, dtype) - - def tensor(self, x, dtype=torch.FloatTensor): - return self.actor.tensor(x, dtype) + def tensor(self, x): + return self.actor.tensor(x) def zero_grad(self): self.actor_opt.zero_grad() @@ -112,11 +92,8 @@ class CategoricalActorCriticWrapper: log_prob = dist.log_prob(action).unsqueeze(1) return action, log_prob, entropy_loss.mean(0), value - def variable(self, x, dtype=torch.FloatTensor): - return self.network.variable(x, dtype) - - def tensor(self, x, dtype=torch.FloatTensor): - return self.network.tensor(x, dtype) + def tensor(self, x): + return self.network.tensor(x) def zero_grad(self): self.opt.zero_grad() @@ -134,6 +111,6 @@ class CategoricalActorCriticWrapper: self.network.load_state_dict(state_dicts) def layer_init(layer): - nn.init.orthogonal(layer.weight.data) - nn.init.constant(layer.bias.data, 0) + nn.init.orthogonal_(layer.weight.data) + nn.init.constant_(layer.bias.data, 0) return layer \ No newline at end of file diff --git a/utils/tf_logger.py b/utils/tf_logger.py index 08f4339..3d3bc93 100644 --- a/utils/tf_logger.py +++ b/utils/tf_logger.py @@ -30,7 +30,7 @@ class Logger(object): if isinstance(v, torch.autograd.Variable): v = v.data if isinstance(v, torch.FloatTensor): - v = v.cpu().numpy() + v = v.cpu().detach().numpy() return v def get_step(self, tag):