Implementation of Invalid Action Masking

बनाया गया Diff कभी समाप्त नहीं होता
5 हटाए गए
465 लाइनें
23 जोड़े गए
478 लाइनें
import torch
import torch
import torch.nn as nn
import torch.nn as nn
import torch.optim as optim
import torch.optim as optim
import torch.nn.functional as F
import torch.nn.functional as F
from torch.distributions.categorical import Categorical
from torch.distributions.categorical import Categorical
from torch.utils.tensorboard import SummaryWriter
from torch.utils.tensorboard import SummaryWriter


from cleanrl.common import preprocess_obs_space, preprocess_ac_space
from cleanrl.common import preprocess_obs_space, preprocess_ac_space
import argparse
import argparse
import numpy as np
import numpy as np
import gym
import gym
import gym_microrts
import gym_microrts
from gym.wrappers import TimeLimit, Monitor
from gym.wrappers import TimeLimit, Monitor
import pybullet_envs
import pybullet_envs
from gym.spaces import Discrete, Box, MultiBinary, MultiDiscrete, Space
from gym.spaces import Discrete, Box, MultiBinary, MultiDiscrete, Space
import time
import time
import random
import random
import os
import os


# taken from https://github.com/openai/baselines/blob/master/baselines/common/vec_env/vec_normalize.py
# taken from https://github.com/openai/baselines/blob/master/baselines/common/vec_env/vec_normalize.py
class RunningMeanStd(object):
class RunningMeanStd(object):
def __init__(self, epsilon=1e-4, shape=()):
def __init__(self, epsilon=1e-4, shape=()):
self.mean = np.zeros(shape, 'float64')
self.mean = np.zeros(shape, 'float64')
self.var = np.ones(shape, 'float64')
self.var = np.ones(shape, 'float64')
self.count = epsilon
self.count = epsilon


def update(self, x):
def update(self, x):
batch_mean = np.mean([x], axis=0)
batch_mean = np.mean([x], axis=0)
batch_var = np.var([x], axis=0)
batch_var = np.var([x], axis=0)
batch_count = 1
batch_count = 1
self.update_from_moments(batch_mean, batch_var, batch_count)
self.update_from_moments(batch_mean, batch_var, batch_count)


def update_from_moments(self, batch_mean, batch_var, batch_count):
def update_from_moments(self, batch_mean, batch_var, batch_count):
self.mean, self.var, self.count = update_mean_var_count_from_moments(
self.mean, self.var, self.count = update_mean_var_count_from_moments(
self.mean, self.var, self.count, batch_mean, batch_var, batch_count)
self.mean, self.var, self.count, batch_mean, batch_var, batch_count)


def update_mean_var_count_from_moments(mean, var, count, batch_mean, batch_var, batch_count):
def update_mean_var_count_from_moments(mean, var, count, batch_mean, batch_var, batch_count):
delta = batch_mean - mean
delta = batch_mean - mean
tot_count = count + batch_count
tot_count = count + batch_count


new_mean = mean + delta * batch_count / tot_count
new_mean = mean + delta * batch_count / tot_count
m_a = var * count
m_a = var * count
m_b = batch_var * batch_count
m_b = batch_var * batch_count
M2 = m_a + m_b + np.square(delta) * count * batch_count / tot_count
M2 = m_a + m_b + np.square(delta) * count * batch_count / tot_count
new_var = M2 / tot_count
new_var = M2 / tot_count
new_count = tot_count
new_count = tot_count


return new_mean, new_var, new_count
return new_mean, new_var, new_count
class NormalizedEnv(gym.core.Wrapper):
class NormalizedEnv(gym.core.Wrapper):
def __init__(self, env, ob=True, ret=True, clipob=10., cliprew=10., gamma=0.99, epsilon=1e-8):
def __init__(self, env, ob=True, ret=True, clipob=10., cliprew=10., gamma=0.99, epsilon=1e-8):
super(NormalizedEnv, self).__init__(env)
super(NormalizedEnv, self).__init__(env)
self.ob_rms = RunningMeanStd(shape=self.observation_space.shape) if ob else None
self.ob_rms = RunningMeanStd(shape=self.observation_space.shape) if ob else None
self.ret_rms = RunningMeanStd(shape=(1,)) if ret else None
self.ret_rms = RunningMeanStd(shape=(1,)) if ret else None
self.clipob = clipob
self.clipob = clipob
self.cliprew = cliprew
self.cliprew = cliprew
self.ret = np.zeros(())
self.ret = np.zeros(())
self.gamma = gamma
self.gamma = gamma
self.epsilon = epsilon
self.epsilon = epsilon


def step(self, action):
def step(self, action):
obs, rews, news, infos = self.env.step(action)
obs, rews, news, infos = self.env.step(action)
infos['real_reward'] = rews
infos['real_reward'] = rews
# print("before", self.ret)
# print("before", self.ret)
self.ret = self.ret * self.gamma + rews
self.ret = self.ret * self.gamma + rews
# print("after", self.ret)
# print("after", self.ret)
obs = self._obfilt(obs)
obs = self._obfilt(obs)
if self.ret_rms:
if self.ret_rms:
self.ret_rms.update(np.array([self.ret].copy()))
self.ret_rms.update(np.array([self.ret].copy()))
rews = np.clip(rews / np.sqrt(self.ret_rms.var + self.epsilon), -self.cliprew, self.cliprew)
rews = np.clip(rews / np.sqrt(self.ret_rms.var + self.epsilon), -self.cliprew, self.cliprew)
self.ret = self.ret * (1-float(news))
self.ret = self.ret * (1-float(news))
return obs, rews, news, infos
return obs, rews, news, infos


def _obfilt(self, obs):
def _obfilt(self, obs):
if self.ob_rms:
if self.ob_rms:
self.ob_rms.update(obs)
self.ob_rms.update(obs)
obs = np.clip((obs - self.ob_rms.mean) / np.sqrt(self.ob_rms.var + self.epsilon), -self.clipob, self.clipob)
obs = np.clip((obs - self.ob_rms.mean) / np.sqrt(self.ob_rms.var + self.epsilon), -self.clipob, self.clipob)
return obs
return obs
else:
else:
return obs
return obs


def reset(self):
def reset(self):
self.ret = np.zeros(())
self.ret = np.zeros(())
obs = self.env.reset()
obs = self.env.reset()
return self._obfilt(obs)
return self._obfilt(obs)


if __name__ == "__main__":
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='PPO agent')
parser = argparse.ArgumentParser(description='PPO agent')
# Common arguments
# Common arguments
parser.add_argument('--exp-name', type=str, default=os.path.basename(__file__).rstrip(".py"),
parser.add_argument('--exp-name', type=str, default=os.path.basename(__file__).rstrip(".py"),
help='the name of this experiment')
help='the name of this experiment')
parser.add_argument('--gym-id', type=str, default="MicrortsMining10x10F9-v0",
parser.add_argument('--gym-id', type=str, default="MicrortsMining10x10F9-v0",
help='the id of the gym environment')
help='the id of the gym environment')
parser.add_argument('--seed', type=int, default=1,
parser.add_argument('--seed', type=int, default=1,
help='seed of the experiment')
help='seed of the experiment')
parser.add_argument('--episode-length', type=int, default=0,
parser.add_argument('--episode-length', type=int, default=0,
help='the maximum length of each episode')
help='the maximum length of each episode')
parser.add_argument('--total-timesteps', type=int, default=100000,
parser.add_argument('--total-timesteps', type=int, default=100000,
help='total timesteps of the experiments')
help='total timesteps of the experiments')
parser.add_argument('--no-torch-deterministic', action='store_false', dest="torch_deterministic", default=True,
parser.add_argument('--no-torch-deterministic', action='store_false', dest="torch_deterministic", default=True,
help='if toggled, `torch.backends.cudnn.deterministic=False`')
help='if toggled, `torch.backends.cudnn.deterministic=False`')