How can I register a custom environment in OpenAI's gym? - reinforcement-learning

I have created a custom environment, as per the OpenAI Gym framework; containing step, reset, action, and reward functions. I aim to run OpenAI baselines on this custom environment. But prior to this, the environment has to be registered on OpenAI gym. I would like to know how the custom environment could be registered on OpenAI gym? Also, Should I be modifying the OpenAI baseline codes to incorporate this?

You do not need to modify baselines repo.
Here is a minimal example. Say you have myenv.py, with all the needed functions (step, reset, ...). The name of the class environment is MyEnv, and you want to add it to the classic_control folder. You have to
Place myenv.py file in gym/gym/envs/classic_control
Add to __init__.py (located in the same folder)
from gym.envs.classic_control.myenv import MyEnv
Register the environment in gym/gym/envs/__init__.py by adding
gym.envs.register(
id='MyEnv-v0',
entry_point='gym.envs.classic_control:MyEnv',
max_episode_steps=1000,
)
At registration, you can also add reward_threshold and kwargs (if your class takes some arguments).
You can also directly register the environment in the script you will run (TRPO, PPO, or whatever) instead of doing it in gym/gym/envs/__init__.py.
EDIT
This is a minimal example to create the LQR environment.
Save the code below in lqr_env.py and place it in the classic_control folder of gym.
import gym
from gym import spaces
from gym.utils import seeding
import numpy as np
class LqrEnv(gym.Env):
def __init__(self, size, init_state, state_bound):
self.init_state = init_state
self.size = size
self.action_space = spaces.Box(low=-state_bound, high=state_bound, shape=(size,))
self.observation_space = spaces.Box(low=-state_bound, high=state_bound, shape=(size,))
self._seed()
def _seed(self, seed=None):
self.np_random, seed = seeding.np_random(seed)
return [seed]
def _step(self,u):
costs = np.sum(u**2) + np.sum(self.state**2)
self.state = np.clip(self.state + u, self.observation_space.low, self.observation_space.high)
return self._get_obs(), -costs, False, {}
def _reset(self):
high = self.init_state*np.ones((self.size,))
self.state = self.np_random.uniform(low=-high, high=high)
self.last_u = None
return self._get_obs()
def _get_obs(self):
return self.state
Add from gym.envs.classic_control.lqr_env import LqrEnv to __init__.py (also in classic_control).
In your script, when you create the environment, do
gym.envs.register(
id='Lqr-v0',
entry_point='gym.envs.classic_control:LqrEnv',
max_episode_steps=150,
kwargs={'size' : 1, 'init_state' : 10., 'state_bound' : np.inf},
)
env = gym.make('Lqr-v0')

Environment registration process can be found here.
Please go through this example custom environment if you have any more issues.
Refer to this stackoverflow issue for further information.

That problem is related to versions of gym try upgrading your gym environment.

Related

Stable-Baselines make_vec_env() not calling the wrapper kwargs as expected

I have a custom gym environment where I am implementing action masking. The code below works well
from toyEnv_mask import PortfolioEnv # file with my custom gym environment
from sb3_contrib import MaskablePPO
from sb3_contrib.common.wrappers import ActionMasker
from stable_baselines3.common.vec_env import DummyVecEnv
from stable_baselines3.common.env_util import make_vec_env
from sb3_contrib.common.maskable.utils import get_action_masks
env = PortfolioEnv()
env = ActionMasker(env,action_mask_fn=PortfolioEnv.action_masks)
env = DummyVecEnv([lambda: env])
model = MaskablePPO("MlpPolicy", env, gamma=0.4, verbose=1, tensorboard_log="./MPPO_tensorboard/")
...
i want to parallelize this and I am trying to use the make_vec_env() class. This sets up ok and starts running, but it does not respect the action masks anymore. This is the line i am using to replace the 3 lines above where i initialize the env.
env = make_vec_env(PortfolioEnv, wrapper_class=ActionMasker,wrapper_kwargs={'action_mask_fn':PortfolioEnv.action_masks} ,n_envs=2)
Any suggestions / help would be greatly appreciated.
i was making it unnecessarily complicated.
a simple env = make_vec_env(PortfolioEnv,n_envs=16) works
and the 3 lines that were working previously could have been just
env = PortfolioEnv()
env = DummyVecEnv([lambda: env])

How to use Allen NLP interpret on custom models

I wish to use Allen NLP Interpret for integrated visualization and Saliency mapping.on custom transformer model, can you please tell me how to do that?
It can be done by having AllenNLP wrappers around your custom model. The interpret modules require a Predictor object, so you can write your own, or use an existing one.
Here's an example for a classification model:
from allennlp.data.vocabulary import Vocabulary
from allennlp.predictors.text_classifier import TextClassifierPredictor
from allennlp.data.dataset_readers import TextClassificationJsonReader
import torch
class ModelWrapper(Model):
def __init__(self, vocab, your_model):
super().__init__(vocab)
self.your_model = your_model
self.logits_to_probs = torch.nn.Softmax()
self.loss = torch.nn.CrossEntropyLoss()
def forward(self, tokens, label=None):
if label is not None:
outputs = self.your_model(tokens, label=label)
else:
outputs = self.your_model(tokens)
probs = self.logits_to_probs(outputs["logits"])
if label is not None:
loss = self.loss(outputs["logits"], label)
outputs["loss"] = loss
outputs["probs"] = probs
return outputs
Your custom transformer model may not have an identifiable TextFieldEmbedder. This is the initial embedding layer of your model, against which gradients are calculated for the saliency interpreters. These can be specified by overriding the following methods in the Predictor.
class PredictorWrapper(TextClassifierPredictor):
def get_interpretable_layer(self):
return self._model.model.bert.embeddings.word_embeddings # This is the initial layer for huggingface's `bert-base-uncased`; change according to your custom model.
def get_interpretable_text_field_embedder(self):
return self._model.model.bert.embeddings.word_embeddings
predictor = PredictorWrapper(model=ModelWrapper(vocab, your_model),
dataset_reader=TextClassificationJsonReader())
Now you have an AllenNLP predictor, which can be used with the interpret module as follows:
from allennlp.interpret.saliency_interpreters import SimpleGradient
interpreter = SimpleGradient(predictor)
interpreter.saliency_interpret_from_json({"sentence": "This is a good movie."})
This should give you the gradients with respect to each input token.

How to disable model/weight serialization fully with AllenNLP settings?

I wish disable serializing all model/state weights in standard AllenNLP model training via the use of jsonnet config files.
The reason for this is that I am running automatic hyperparameter optimization using Optuna.
Testing dozens of models fills up a drive pretty quickly.
I already have disabled the checkpointer by setting num_serialized_models_to_keep to 0:
trainer +: {
checkpointer +: {
num_serialized_models_to_keep: 0,
},
I do not wish to set serialization_dir to None as I still want the default behaviour regarding logging of intermediate metrics, etc. I only want to disable the default model state, training state, and best model weights writing.
Besides the option I set above, are there any default trainer or checkpointer options to disable all serialization of model weights? I checked the API docs and webpage but could not find any.
If I need to define the functionality for such an option myself, which base function(s) from the AllenNLP should I override in my Model subclass?
Alternatively, is their any utility for cleaning up intermediate model state when training is concluded?
EDIT: #petew's answer shows the solution for a custom checkpointer, but I am not clear on how to make this code findable to allennlp train for my use-case.
I wish to make the custom_checkpointer callable from a config file as below:
trainer +: {
checkpointer +: {
type: empty,
},
What would be best practice to load the checkpointer when calling allennlp train --include-package <$my_package>?
I have my_package with submodules in subdirectories such as my_package/modelss and my_package/training.
I would like to place the custom checkpointer code in my_package/training/custom_checkpointer.py
My main model is located in my_package/models/main_model.py.
Do I have to edit or import any code/functions in my main_model class to use the custom checkpointer?
You could create and register a custom Checkpointer that basically just does nothing:
#Checkpointer.register("empty")
class EmptyCheckpointer(Registrable):
def maybe_save_checkpoint(
self, trainer: "allennlp.training.trainer.Trainer", epoch: int, batches_this_epoch: int
) -> None:
pass
def save_checkpoint(
self,
epoch: Union[int, str],
trainer: "allennlp.training.trainer.Trainer",
is_best_so_far: bool = False,
save_model_only=False,
) -> None:
pass
def find_latest_checkpoint(self) -> Optional[Tuple[str, str]]:
pass
def restore_checkpoint(self) -> Tuple[Dict[str, Any], Dict[str, Any]]:
return {}, {}
def best_model_state(self) -> Dict[str, Any]:
return {}

Pact.io, Junit - How to test againts multiple consumers with different tags?

I have multiple (not only junit) consumer applications, which create pacts in pact broker.
These consumers have many different git branches - e.g.:
consumer1: release123, release007, release999
consumer2: release69, release420, release50
Question
how to run provider tests against specific combinations of consumers and their tags?
e.g. consumer1 release007, consumer2 release69 AND release50 ?
is these something like -Dpactbroker.consumers=consumer1:release007,consumer2:release69,consumer2:release50 ?
I especially need this for junit, as we mostly use java apps as providers.
What I have found:
in junit, there is annotation #PactBroker which allows you to specify tags and consumers
according to description, these can be set via system properties pactbroker.tags and pactbroker.consumers
there can be specified multiple of each, separated by comma - e.g.: -Dpactbroker.consumers=consumer1,consumer2
I havent found if tags and consumers can be paired while running provider tests
Please try below solution might be it will help
You can add like below on Provider Class
API used
import au.com.dius.pact.provider.junit.IgnoreNoPactsToVerify;
import au.com.dius.pact.provider.junit.Provider;
import au.com.dius.pact.provider.junit.State;
import au.com.dius.pact.provider.junit.loader.PactBroker;
import au.com.dius.pact.provider.junit.loader.PactBrokerAuth;
import au.com.dius.pact.provider.junit.loader.PactFolder;
import au.com.dius.pact.provider.junit.target.Target;
import au.com.dius.pact.provider.junit.target.TestTarget;
import au.com.dius.pact.provider.spring.SpringRestPactRunner;
import au.com.dius.pact.provider.spring.target.SpringBootHttpTarget;
Provider Added on Class
#IgnoreNoPactsToVerify
#PactBroker(
authentication = #PactBrokerAuth(password = "*******", username = "********"),
host = "*******",
tags = {"test", "dev", "latest"},
port = "*****",
failIfNoPactsFound = false,
protocol = "http")
On consumer end you can add on each test case like below
API used
import au.com.dius.pact.consumer.Pact;
import au.com.dius.pact.consumer.PactProviderRuleMk2;
import au.com.dius.pact.consumer.PactVerification;
import au.com.dius.pact.consumer.dsl.PactDslWithProvider;
import au.com.dius.pact.model.RequestResponsePact;
Test Case Level
#Pact(consumer = "consumer-service-name")

generating test report using html test runner in sikuli

I have read that we can generate test reports in sikuli using HTML test runner.
I have installed SIKULI X and have script for which I want to generate reports.
Is there any particular version of html test runner I need to install for this version of Sikuli ?
I have downloaded the "html-testRunner-1.0.3.tar.gz (md5)" from the path "https://pypi.python.org/pypi/html-testRunner".
Can anyone guide me on how I should install and integrate the same to my script ?
For me, I downloaded HTMLTestRunner.py from this website and put somewhere in my computer. Say if I put it in ~/Downloads/HTMLTestRunner folder, I just need to tell my sikulix program to find the path into that folder, and import HTMLTestRunner afterwards. This part is as follows:
import sys
_path = r"Downloads/HTMLTestRunner"
sys.path.append(_path)
import HTMLTestRunner
After that, everything goes as usual. Lemme try to make one example below.
import unittest
import sys
_path = r"Downloads/HTMLTestRunner"
sys.path.append(_path)
import HTMLTestRunner
class TestDemo(unittest.TestCase):
def testA(self):
assert True
def testB(self):
assert False
class TestDemo2(unittest.TestCase):
def testC(self):
assert True
def testD(self):
assert True
def suite():
suite = unittest.TestSuite()
# TestDemo
suite.addTest(TestDemo('testA'))
suite.addTest(TestDemo('testB'))
# TestDemo2
suite.addTest(TestDemo2('testC'))
suite.addTest(TestDemo2('testD'))
return suite
if __name__ == "__main__":
suite = suite()
unittest.TextTestRunner(verbosity=2)
output = open("results.html", 'w')
runner = HTMLTestRunner.HTMLTestRunner(stream=output, title='Test Report', description='This is a test')
runner.run(suite)
When you run it, you will get the following report
Hope it helps