rlmodule 0.1.5__tar.gz → 0.1.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rlmodule-0.1.5 → rlmodule-0.1.6}/LICENSE +1 -1
- {rlmodule-0.1.5 → rlmodule-0.1.6}/PKG-INFO +37 -8
- rlmodule-0.1.6/README.md +75 -0
- {rlmodule-0.1.5 → rlmodule-0.1.6}/pyproject.toml +3 -3
- rlmodule-0.1.6/rlmodule/__init__.py +28 -0
- rlmodule-0.1.6/rlmodule/skrl/torch/__init__.py +3 -0
- rlmodule-0.1.6/rlmodule/skrl/torch/gymnasium/pendulum_ppo_mlp_separate_model.py +124 -0
- rlmodule-0.1.6/rlmodule/skrl/torch/gymnasium/pendulum_ppo_mlp_shared_model.py +112 -0
- rlmodule-0.1.6/rlmodule/skrl/torch/gymnasium/pendulum_ppo_rnn_forwarded_input_shared_model.py +123 -0
- rlmodule-0.1.6/rlmodule/skrl/torch/gymnasium/pendulum_ppo_rnn_separate_model.py +130 -0
- rlmodule-0.1.6/rlmodule/skrl/torch/gymnasium/pendulum_ppo_rnn_shared_model.py +121 -0
- rlmodule-0.1.6/rlmodule/skrl/torch/gymnasium/pendulum_sac_mlp_separate_model.py +119 -0
- rlmodule-0.1.5/rlmodule/skrl/torch/examples/gymnasium/skrl_gymnasium_pendulum_no_module.py → rlmodule-0.1.6/rlmodule/skrl/torch/gymnasium/skrl_no_module.py +37 -31
- rlmodule-0.1.6/rlmodule/skrl/torch/gymnasium/skrl_no_module_rnn.py +271 -0
- rlmodule-0.1.6/rlmodule/skrl/torch/gymnasium/skrl_sac.py +118 -0
- rlmodule-0.1.6/rlmodule/skrl/torch/gymnasium/temp.py +216 -0
- rlmodule-0.1.6/rlmodule/skrl/torch/network/__init__.py +19 -0
- rlmodule-0.1.6/rlmodule/skrl/torch/output_layer/__init__.py +2 -0
- rlmodule-0.1.6/rlmodule/source/build.py +41 -0
- {rlmodule-0.1.5 → rlmodule-0.1.6}/rlmodule/source/model.py +241 -365
- {rlmodule-0.1.5 → rlmodule-0.1.6}/rlmodule/source/network.py +66 -65
- {rlmodule-0.1.5 → rlmodule-0.1.6}/rlmodule/source/network_cfg.py +21 -10
- rlmodule-0.1.6/rlmodule/source/nvidia_utils/__init__.py +1 -0
- {rlmodule-0.1.5 → rlmodule-0.1.6}/rlmodule/source/nvidia_utils/configclass.py +10 -7
- {rlmodule-0.1.5 → rlmodule-0.1.6}/rlmodule/source/nvidia_utils/dict.py +3 -2
- {rlmodule-0.1.5 → rlmodule-0.1.6}/rlmodule/source/nvidia_utils/string.py +2 -1
- rlmodule-0.1.6/rlmodule/source/output_layer.py +241 -0
- rlmodule-0.1.6/rlmodule/source/output_layer_cfg.py +73 -0
- rlmodule-0.1.6/rlmodule/source/rlmodel.py +89 -0
- {rlmodule-0.1.5 → rlmodule-0.1.6}/rlmodule/source/rlmodel_cfg.py +18 -8
- {rlmodule-0.1.5 → rlmodule-0.1.6}/rlmodule/source/utils.py +13 -10
- {rlmodule-0.1.5 → rlmodule-0.1.6}/rlmodule.egg-info/PKG-INFO +37 -8
- {rlmodule-0.1.5 → rlmodule-0.1.6}/rlmodule.egg-info/SOURCES.txt +10 -3
- {rlmodule-0.1.5 → rlmodule-0.1.6}/rlmodule.egg-info/requires.txt +1 -1
- rlmodule-0.1.5/README.md +0 -46
- rlmodule-0.1.5/rlmodule/__init__.py +0 -4
- rlmodule-0.1.5/rlmodule/skrl/torch/__init__.py +0 -9
- rlmodule-0.1.5/rlmodule/skrl/torch/examples/gymnasium/skrl_gymnasium_pendulum.py +0 -267
- rlmodule-0.1.5/rlmodule/skrl/torch/network/__init__.py +0 -8
- rlmodule-0.1.5/rlmodule/skrl/torch/output_layer/__init__.py +0 -5
- rlmodule-0.1.5/rlmodule/source/build.py +0 -33
- rlmodule-0.1.5/rlmodule/source/deprecated.py +0 -383
- rlmodule-0.1.5/rlmodule/source/nvidia_utils/__init__.py +0 -1
- rlmodule-0.1.5/rlmodule/source/output_layer.py +0 -150
- rlmodule-0.1.5/rlmodule/source/output_layer_cfg.py +0 -38
- rlmodule-0.1.5/rlmodule/source/rlmodel.py +0 -363
- {rlmodule-0.1.5 → rlmodule-0.1.6}/rlmodule/skrl/__init__.py +0 -0
- {rlmodule-0.1.5 → rlmodule-0.1.6}/rlmodule/source/__init__.py +0 -0
- {rlmodule-0.1.5 → rlmodule-0.1.6}/rlmodule.egg-info/dependency_links.txt +0 -0
- {rlmodule-0.1.5 → rlmodule-0.1.6}/rlmodule.egg-info/top_level.txt +0 -0
- {rlmodule-0.1.5 → rlmodule-0.1.6}/setup.cfg +0 -0
|
@@ -27,4 +27,4 @@ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
|
27
27
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
28
28
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
29
29
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
30
|
-
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
30
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: rlmodule
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: Flexible reinforcement learning models instantiators library
|
|
5
5
|
Author: Lopatovsky
|
|
6
6
|
Author-email: lopatovsky@gmail.com
|
|
@@ -23,7 +23,7 @@ Requires-Python: >=3.6
|
|
|
23
23
|
Description-Content-Type: text/markdown
|
|
24
24
|
License-File: LICENSE
|
|
25
25
|
Requires-Dist: gym
|
|
26
|
-
Requires-Dist: gymnasium
|
|
26
|
+
Requires-Dist: gymnasium>=1.0.0
|
|
27
27
|
Requires-Dist: torch>=1.9
|
|
28
28
|
Requires-Dist: skrl>=1.3.0
|
|
29
29
|
Provides-Extra: skrl
|
|
@@ -34,19 +34,41 @@ Requires-Dist: skrl>=1.3.0; extra == "all"
|
|
|
34
34
|
# rlmodule
|
|
35
35
|
Flexible reinforcement learning models instantiators library
|
|
36
36
|
|
|
37
|
+
Function approximators simple, but still strong. RNN - GRU - LSTM / SAC
|
|
38
|
+
|
|
39
|
+
Now it only supports skrl, but is intended to be library agnostic - in later expansion
|
|
40
|
+
|
|
41
|
+
try other algos
|
|
42
|
+
shared separate model
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
<!--
|
|
46
|
+
# todo
|
|
47
|
+
# some envs have by default range on which they work, like pendulum -2, 2, need to propaget that in.
|
|
48
|
+
# cnn
|
|
49
|
+
# WRITE README tutorial
|
|
50
|
+
# Run & fix pre-commit
|
|
51
|
+
# annotate cfgs in modules - why doesn't work TYPE_CHECKING
|
|
52
|
+
# extensive comments
|
|
53
|
+
# Launch new version to pip
|
|
54
|
+
# Import new version in Isaac-lab
|
|
55
|
+
# lazy linear? what is it ?
|
|
56
|
+
# random model run add function back
|
|
57
|
+
-->
|
|
58
|
+
|
|
37
59
|
|
|
38
60
|
## How to run
|
|
39
61
|
|
|
40
62
|
### Install rlmodule from local code
|
|
41
63
|
|
|
42
|
-
- Make sure you are in base rlmodule
|
|
64
|
+
- Make sure you are in base rlmodule dict.
|
|
43
65
|
|
|
44
66
|
- Start virtual env.
|
|
45
67
|
```
|
|
46
68
|
python3 -m venv venv
|
|
47
69
|
source venv/bin/activate
|
|
48
70
|
```
|
|
49
|
-
- Install library from local code
|
|
71
|
+
- Install library from local code
|
|
50
72
|
```
|
|
51
73
|
pip install -e .
|
|
52
74
|
```
|
|
@@ -54,14 +76,24 @@ Note: sometimes installation may fail, if there is a run/ dir present, you may n
|
|
|
54
76
|
```
|
|
55
77
|
rm -rf runs
|
|
56
78
|
```
|
|
79
|
+
|
|
57
80
|
### Run chosen example
|
|
58
81
|
```
|
|
59
|
-
python3 rlmodule/skrl/
|
|
82
|
+
python3 rlmodule/rlmodule/skrl/torch/gymnasium/pendulum_ppo_mlp_separate_model.py
|
|
60
83
|
```
|
|
61
84
|
|
|
85
|
+
Optional: observe run results in Tensorboard
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
tensorboard --logdir=runs/
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
|
|
62
92
|
|
|
63
93
|
## Update new version to PIP
|
|
64
94
|
|
|
95
|
+
Change version name in pyproject.toml
|
|
96
|
+
|
|
65
97
|
```
|
|
66
98
|
pip install build twine
|
|
67
99
|
```
|
|
@@ -74,6 +106,3 @@ python -m build
|
|
|
74
106
|
```
|
|
75
107
|
twine upload dist/*
|
|
76
108
|
```
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
rlmodule-0.1.6/README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# rlmodule
|
|
2
|
+
Flexible reinforcement learning models instantiators library
|
|
3
|
+
|
|
4
|
+
Function approximators simple, but still strong. RNN - GRU - LSTM / SAC
|
|
5
|
+
|
|
6
|
+
Now it only supports skrl, but is intended to be library agnostic - in later expansion
|
|
7
|
+
|
|
8
|
+
try other algos
|
|
9
|
+
shared separate model
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
<!--
|
|
13
|
+
# todo
|
|
14
|
+
# some envs have by default range on which they work, like pendulum -2, 2, need to propaget that in.
|
|
15
|
+
# cnn
|
|
16
|
+
# WRITE README tutorial
|
|
17
|
+
# Run & fix pre-commit
|
|
18
|
+
# annotate cfgs in modules - why doesn't work TYPE_CHECKING
|
|
19
|
+
# extensive comments
|
|
20
|
+
# Launch new version to pip
|
|
21
|
+
# Import new version in Isaac-lab
|
|
22
|
+
# lazy linear? what is it ?
|
|
23
|
+
# random model run add function back
|
|
24
|
+
-->
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## How to run
|
|
28
|
+
|
|
29
|
+
### Install rlmodule from local code
|
|
30
|
+
|
|
31
|
+
- Make sure you are in base rlmodule dict.
|
|
32
|
+
|
|
33
|
+
- Start virtual env.
|
|
34
|
+
```
|
|
35
|
+
python3 -m venv venv
|
|
36
|
+
source venv/bin/activate
|
|
37
|
+
```
|
|
38
|
+
- Install library from local code
|
|
39
|
+
```
|
|
40
|
+
pip install -e .
|
|
41
|
+
```
|
|
42
|
+
Note: sometimes installation may fail, if there is a run/ dir present, you may need to remove it (TODO: fix)
|
|
43
|
+
```
|
|
44
|
+
rm -rf runs
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Run chosen example
|
|
48
|
+
```
|
|
49
|
+
python3 rlmodule/rlmodule/skrl/torch/gymnasium/pendulum_ppo_mlp_separate_model.py
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Optional: observe run results in Tensorboard
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
tensorboard --logdir=runs/
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
## Update new version to PIP
|
|
61
|
+
|
|
62
|
+
Change version name in pyproject.toml
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
pip install build twine
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
rm -rf runs
|
|
70
|
+
python -m build
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
twine upload dist/*
|
|
75
|
+
```
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "rlmodule"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.6"
|
|
4
4
|
description = "Flexible reinforcement learning models instantiators library"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.6"
|
|
7
7
|
license = {text = "MIT License"}
|
|
8
8
|
authors = [
|
|
9
|
-
{name = "Lopatovsky"},
|
|
9
|
+
{name = "Lopatovsky"},
|
|
10
10
|
{email = "lopatovsky@gmail.com"},
|
|
11
11
|
]
|
|
12
12
|
maintainers = [
|
|
@@ -24,7 +24,7 @@ classifiers = [
|
|
|
24
24
|
]
|
|
25
25
|
dependencies = [
|
|
26
26
|
"gym",
|
|
27
|
-
"gymnasium",
|
|
27
|
+
"gymnasium>=1.0.0",
|
|
28
28
|
"torch>=1.9",
|
|
29
29
|
"skrl>=1.3.0",
|
|
30
30
|
]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
__all__ = ["logger"]
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# logger with format
|
|
8
|
+
class _Formatter(logging.Formatter):
|
|
9
|
+
_format = "[%(name)s:%(levelname)s] %(message)s"
|
|
10
|
+
_formats = {
|
|
11
|
+
logging.DEBUG: f"\x1b[38;20m{_format}\x1b[0m",
|
|
12
|
+
logging.INFO: f"\x1b[38;20m{_format}\x1b[0m",
|
|
13
|
+
logging.WARNING: f"\x1b[33;20m{_format}\x1b[0m",
|
|
14
|
+
logging.ERROR: f"\x1b[31;20m{_format}\x1b[0m",
|
|
15
|
+
logging.CRITICAL: f"\x1b[31;1m{_format}\x1b[0m",
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
def format(self, record):
|
|
19
|
+
return logging.Formatter(self._formats.get(record.levelno)).format(record)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
_handler = logging.StreamHandler()
|
|
23
|
+
_handler.setLevel(logging.DEBUG)
|
|
24
|
+
_handler.setFormatter(_Formatter())
|
|
25
|
+
|
|
26
|
+
logger = logging.getLogger("rlmodule")
|
|
27
|
+
logger.setLevel(logging.DEBUG)
|
|
28
|
+
logger.addHandler(_handler)
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
import gymnasium as gym
|
|
4
|
+
|
|
5
|
+
# import the skrl components to build the RL system
|
|
6
|
+
from skrl.agents.torch.ppo import PPO, PPO_DEFAULT_CONFIG, PPO_RNN
|
|
7
|
+
from skrl.envs.wrappers.torch.gymnasium_envs import GymnasiumWrapper
|
|
8
|
+
from skrl.memories.torch import RandomMemory
|
|
9
|
+
from skrl.resources.preprocessors.torch import RunningStandardScaler
|
|
10
|
+
from skrl.resources.schedulers.torch import KLAdaptiveRL
|
|
11
|
+
from skrl.trainers.torch import SequentialTrainer
|
|
12
|
+
from skrl.utils import set_seed
|
|
13
|
+
|
|
14
|
+
import torch.nn as nn
|
|
15
|
+
|
|
16
|
+
from rlmodule.skrl.torch import RLModelCfg, build_model
|
|
17
|
+
from rlmodule.skrl.torch.network import MlpCfg
|
|
18
|
+
from rlmodule.skrl.torch.output_layer import DeterministicLayerCfg, GaussianLayerCfg
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_model(env):
|
|
22
|
+
"""Instantiate the agent's models (function approximators)."""
|
|
23
|
+
|
|
24
|
+
net_cfg = MlpCfg(
|
|
25
|
+
input_states=env.observation_space,
|
|
26
|
+
hidden_units=[400, 300],
|
|
27
|
+
activation=nn.ReLU,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
print(env.action_space)
|
|
31
|
+
print(env.observation_space)
|
|
32
|
+
|
|
33
|
+
policy_model = build_model(
|
|
34
|
+
RLModelCfg(
|
|
35
|
+
network=net_cfg,
|
|
36
|
+
device=device,
|
|
37
|
+
output_layer=GaussianLayerCfg(
|
|
38
|
+
output_size=env.action_space,
|
|
39
|
+
output_scale=2.0,
|
|
40
|
+
min_log_std=-1.2,
|
|
41
|
+
max_log_std=2,
|
|
42
|
+
initial_log_std=0.0,
|
|
43
|
+
),
|
|
44
|
+
)
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
value_model = build_model(
|
|
48
|
+
RLModelCfg(
|
|
49
|
+
network=net_cfg,
|
|
50
|
+
device=device,
|
|
51
|
+
output_layer=DeterministicLayerCfg(),
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
models = {"policy": policy_model, "value": value_model}
|
|
56
|
+
print(models)
|
|
57
|
+
return models
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
# set seed for reproducibility
|
|
61
|
+
seed = 42
|
|
62
|
+
set_seed(seed)
|
|
63
|
+
|
|
64
|
+
# load and wrap the gymnasium environment.
|
|
65
|
+
env = gym.make_vec("Pendulum-v1", num_envs=4, vectorization_mode="sync")
|
|
66
|
+
env.reset(seed=seed)
|
|
67
|
+
env = GymnasiumWrapper(env)
|
|
68
|
+
device = env.device
|
|
69
|
+
|
|
70
|
+
# instantiate a memory as rollout buffer (any memory can be used for this)
|
|
71
|
+
memory = RandomMemory(memory_size=1024, num_envs=env.num_envs, device=device)
|
|
72
|
+
|
|
73
|
+
models = get_model(env)
|
|
74
|
+
|
|
75
|
+
# configure and instantiate the agent (visit its documentation to see all the options)
|
|
76
|
+
# https://skrl.readthedocs.io/en/latest/api/agents/ppo.html#configuration-and-hyperparameters
|
|
77
|
+
cfg = PPO_DEFAULT_CONFIG.copy()
|
|
78
|
+
cfg["rollouts"] = 1024 # memory_size
|
|
79
|
+
cfg["learning_epochs"] = 10
|
|
80
|
+
cfg["mini_batches"] = 32
|
|
81
|
+
cfg["discount_factor"] = 0.9
|
|
82
|
+
cfg["lambda"] = 0.95
|
|
83
|
+
cfg["learning_rate"] = 1e-3
|
|
84
|
+
cfg["learning_rate_scheduler"] = KLAdaptiveRL
|
|
85
|
+
cfg["learning_rate_scheduler_kwargs"] = {"kl_threshold": 0.008}
|
|
86
|
+
cfg["grad_norm_clip"] = 0.5
|
|
87
|
+
cfg["ratio_clip"] = 0.2
|
|
88
|
+
cfg["value_clip"] = 0.2
|
|
89
|
+
cfg["clip_predicted_values"] = False
|
|
90
|
+
cfg["entropy_loss_scale"] = 0.0
|
|
91
|
+
cfg["value_loss_scale"] = 0.5
|
|
92
|
+
cfg["kl_threshold"] = 0
|
|
93
|
+
cfg["state_preprocessor"] = RunningStandardScaler
|
|
94
|
+
cfg["state_preprocessor_kwargs"] = {"size": env.observation_space, "device": device}
|
|
95
|
+
cfg["value_preprocessor"] = RunningStandardScaler
|
|
96
|
+
cfg["value_preprocessor_kwargs"] = {"size": 1, "device": device}
|
|
97
|
+
# logging to TensorBoard and write checkpoints (in timesteps)
|
|
98
|
+
cfg["experiment"]["write_interval"] = 500
|
|
99
|
+
cfg["experiment"]["checkpoint_interval"] = 5000
|
|
100
|
+
cfg["experiment"]["directory"] = "runs/skrl/torch/"
|
|
101
|
+
cfg["experiment"]["experiment_name"] = (
|
|
102
|
+
os.path.splitext(os.path.basename(__file__))[0] + "_" + datetime.now().strftime("%Y-%m-%d_%H:%M:%S")
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
params = {
|
|
106
|
+
"models": models,
|
|
107
|
+
"memory": memory,
|
|
108
|
+
"cfg": cfg,
|
|
109
|
+
"observation_space": env.observation_space,
|
|
110
|
+
"action_space": env.action_space,
|
|
111
|
+
"device": device,
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if models["policy"].is_rnn:
|
|
115
|
+
agent = PPO_RNN(**params)
|
|
116
|
+
else:
|
|
117
|
+
agent = PPO(**params)
|
|
118
|
+
|
|
119
|
+
# configure and instantiate the RL trainer
|
|
120
|
+
cfg_trainer = {"timesteps": 100000, "headless": True}
|
|
121
|
+
trainer = SequentialTrainer(cfg=cfg_trainer, env=env, agents=[agent])
|
|
122
|
+
|
|
123
|
+
# start training
|
|
124
|
+
trainer.train()
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
import gymnasium as gym
|
|
4
|
+
|
|
5
|
+
# import the skrl components to build the RL system
|
|
6
|
+
from skrl.agents.torch.ppo import PPO, PPO_DEFAULT_CONFIG, PPO_RNN
|
|
7
|
+
from skrl.envs.wrappers.torch.gymnasium_envs import GymnasiumWrapper
|
|
8
|
+
from skrl.memories.torch import RandomMemory
|
|
9
|
+
from skrl.resources.preprocessors.torch import RunningStandardScaler
|
|
10
|
+
from skrl.resources.schedulers.torch import KLAdaptiveRL
|
|
11
|
+
from skrl.trainers.torch import SequentialTrainer
|
|
12
|
+
from skrl.utils import set_seed
|
|
13
|
+
|
|
14
|
+
import torch.nn as nn
|
|
15
|
+
|
|
16
|
+
from rlmodule.skrl.torch import SharedRLModelCfg, build_model
|
|
17
|
+
from rlmodule.skrl.torch.network import MlpCfg
|
|
18
|
+
from rlmodule.skrl.torch.output_layer import DeterministicLayerCfg, GaussianLayerCfg
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_model(env):
|
|
22
|
+
"""Instantiate the agent's models (function approximators)."""
|
|
23
|
+
|
|
24
|
+
net_cfg = MlpCfg(
|
|
25
|
+
input_states=env.observation_space,
|
|
26
|
+
hidden_units=[400, 300],
|
|
27
|
+
activation=nn.ReLU,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
model = build_model(
|
|
31
|
+
SharedRLModelCfg(
|
|
32
|
+
network=net_cfg,
|
|
33
|
+
device=device,
|
|
34
|
+
policy_output_layer=GaussianLayerCfg(
|
|
35
|
+
output_size=env.action_space,
|
|
36
|
+
min_log_std=-1.2,
|
|
37
|
+
max_log_std=2,
|
|
38
|
+
initial_log_std=0.0,
|
|
39
|
+
),
|
|
40
|
+
value_output_layer=DeterministicLayerCfg(),
|
|
41
|
+
)
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
print(model)
|
|
45
|
+
return {"policy": model, "value": model}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# set seed for reproducibility
|
|
49
|
+
seed = 42
|
|
50
|
+
set_seed(seed)
|
|
51
|
+
|
|
52
|
+
# load and wrap the gymnasium environment.
|
|
53
|
+
env = gym.make_vec("Pendulum-v1", num_envs=4, vectorization_mode="sync")
|
|
54
|
+
env.reset(seed=seed)
|
|
55
|
+
env = GymnasiumWrapper(env)
|
|
56
|
+
device = env.device
|
|
57
|
+
|
|
58
|
+
# instantiate a memory as rollout buffer (any memory can be used for this)
|
|
59
|
+
memory = RandomMemory(memory_size=1024, num_envs=env.num_envs, device=device)
|
|
60
|
+
|
|
61
|
+
models = get_model(env)
|
|
62
|
+
|
|
63
|
+
# configure and instantiate the agent (visit its documentation to see all the options)
|
|
64
|
+
# https://skrl.readthedocs.io/en/latest/api/agents/ppo.html#configuration-and-hyperparameters
|
|
65
|
+
cfg = PPO_DEFAULT_CONFIG.copy()
|
|
66
|
+
cfg["rollouts"] = 1024 # memory_size
|
|
67
|
+
cfg["learning_epochs"] = 10
|
|
68
|
+
cfg["mini_batches"] = 32
|
|
69
|
+
cfg["discount_factor"] = 0.9
|
|
70
|
+
cfg["lambda"] = 0.95
|
|
71
|
+
cfg["learning_rate"] = 1e-3
|
|
72
|
+
cfg["learning_rate_scheduler"] = KLAdaptiveRL
|
|
73
|
+
cfg["learning_rate_scheduler_kwargs"] = {"kl_threshold": 0.008}
|
|
74
|
+
cfg["grad_norm_clip"] = 0.5
|
|
75
|
+
cfg["ratio_clip"] = 0.2
|
|
76
|
+
cfg["value_clip"] = 0.2
|
|
77
|
+
cfg["clip_predicted_values"] = False
|
|
78
|
+
cfg["entropy_loss_scale"] = 0.0
|
|
79
|
+
cfg["value_loss_scale"] = 0.5
|
|
80
|
+
cfg["kl_threshold"] = 0
|
|
81
|
+
cfg["state_preprocessor"] = RunningStandardScaler
|
|
82
|
+
cfg["state_preprocessor_kwargs"] = {"size": env.observation_space, "device": device}
|
|
83
|
+
cfg["value_preprocessor"] = RunningStandardScaler
|
|
84
|
+
cfg["value_preprocessor_kwargs"] = {"size": 1, "device": device}
|
|
85
|
+
# logging to TensorBoard and write checkpoints (in timesteps)
|
|
86
|
+
cfg["experiment"]["write_interval"] = 500
|
|
87
|
+
cfg["experiment"]["checkpoint_interval"] = 5000
|
|
88
|
+
cfg["experiment"]["directory"] = "runs/skrl/torch/"
|
|
89
|
+
cfg["experiment"]["experiment_name"] = (
|
|
90
|
+
os.path.splitext(os.path.basename(__file__))[0] + "_" + datetime.now().strftime("%Y-%m-%d_%H:%M:%S")
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
params = {
|
|
94
|
+
"models": models,
|
|
95
|
+
"memory": memory,
|
|
96
|
+
"cfg": cfg,
|
|
97
|
+
"observation_space": env.observation_space,
|
|
98
|
+
"action_space": env.action_space,
|
|
99
|
+
"device": device,
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if models["policy"].is_rnn:
|
|
103
|
+
agent = PPO_RNN(**params)
|
|
104
|
+
else:
|
|
105
|
+
agent = PPO(**params)
|
|
106
|
+
|
|
107
|
+
# configure and instantiate the RL trainer
|
|
108
|
+
cfg_trainer = {"timesteps": 100000, "headless": True}
|
|
109
|
+
trainer = SequentialTrainer(cfg=cfg_trainer, env=env, agents=[agent])
|
|
110
|
+
|
|
111
|
+
# start training
|
|
112
|
+
trainer.train()
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
import gymnasium as gym
|
|
4
|
+
|
|
5
|
+
# import the skrl components to build the RL system
|
|
6
|
+
from skrl.agents.torch.ppo import PPO, PPO_DEFAULT_CONFIG, PPO_RNN
|
|
7
|
+
from skrl.envs.wrappers.torch.gymnasium_envs import GymnasiumWrapper
|
|
8
|
+
from skrl.memories.torch import RandomMemory
|
|
9
|
+
from skrl.resources.preprocessors.torch import RunningStandardScaler
|
|
10
|
+
from skrl.resources.schedulers.torch import KLAdaptiveRL
|
|
11
|
+
from skrl.trainers.torch import SequentialTrainer
|
|
12
|
+
from skrl.utils import set_seed
|
|
13
|
+
|
|
14
|
+
import torch.nn as nn
|
|
15
|
+
|
|
16
|
+
from rlmodule.skrl.torch import SharedRLModelCfg, build_model
|
|
17
|
+
from rlmodule.skrl.torch.network import MlpCfg
|
|
18
|
+
from rlmodule.skrl.torch.output_layer import DeterministicLayerCfg, GaussianLayerCfg
|
|
19
|
+
from rlmodule.source.network import RnnMlpWithForwardedInput
|
|
20
|
+
from rlmodule.source.network_cfg import RnnCfg, RnnMlpCfg
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_model(env):
|
|
24
|
+
"""Instantiate the agent's models (function approximators)."""
|
|
25
|
+
|
|
26
|
+
net_cfg = RnnMlpCfg(
|
|
27
|
+
input_states=env.observation_space,
|
|
28
|
+
module=RnnMlpWithForwardedInput,
|
|
29
|
+
rnn=RnnCfg(
|
|
30
|
+
num_envs=env.num_envs,
|
|
31
|
+
num_layers=1,
|
|
32
|
+
hidden_size=32,
|
|
33
|
+
sequence_length=16,
|
|
34
|
+
),
|
|
35
|
+
mlp=MlpCfg(
|
|
36
|
+
hidden_units=[64, 64],
|
|
37
|
+
activation=nn.ReLU,
|
|
38
|
+
),
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
model = build_model(
|
|
42
|
+
SharedRLModelCfg(
|
|
43
|
+
network=net_cfg,
|
|
44
|
+
device=device,
|
|
45
|
+
policy_output_layer=GaussianLayerCfg(
|
|
46
|
+
output_size=env.action_space,
|
|
47
|
+
min_log_std=-1.2,
|
|
48
|
+
max_log_std=2,
|
|
49
|
+
initial_log_std=0.0,
|
|
50
|
+
),
|
|
51
|
+
value_output_layer=DeterministicLayerCfg(),
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
print(model)
|
|
56
|
+
return {"policy": model, "value": model}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# set seed for reproducibility
|
|
60
|
+
seed = 42
|
|
61
|
+
set_seed(seed)
|
|
62
|
+
|
|
63
|
+
# load and wrap the gymnasium environment.
|
|
64
|
+
env = gym.make_vec("Pendulum-v1", num_envs=4, vectorization_mode="sync")
|
|
65
|
+
env.reset(seed=seed)
|
|
66
|
+
env = GymnasiumWrapper(env)
|
|
67
|
+
device = env.device
|
|
68
|
+
|
|
69
|
+
# instantiate a memory as rollout buffer (any memory can be used for this)
|
|
70
|
+
memory = RandomMemory(memory_size=1024, num_envs=env.num_envs, device=device)
|
|
71
|
+
|
|
72
|
+
models = get_model(env)
|
|
73
|
+
|
|
74
|
+
# configure and instantiate the agent (visit its documentation to see all the options)
|
|
75
|
+
# https://skrl.readthedocs.io/en/latest/api/agents/ppo.html#configuration-and-hyperparameters
|
|
76
|
+
cfg = PPO_DEFAULT_CONFIG.copy()
|
|
77
|
+
cfg["rollouts"] = 1024 # memory_size
|
|
78
|
+
cfg["learning_epochs"] = 10
|
|
79
|
+
cfg["mini_batches"] = 32
|
|
80
|
+
cfg["discount_factor"] = 0.9
|
|
81
|
+
cfg["lambda"] = 0.95
|
|
82
|
+
cfg["learning_rate"] = 3e-4
|
|
83
|
+
cfg["learning_rate_scheduler"] = KLAdaptiveRL
|
|
84
|
+
cfg["learning_rate_scheduler_kwargs"] = {"kl_threshold": 0.008}
|
|
85
|
+
cfg["grad_norm_clip"] = 0.5
|
|
86
|
+
cfg["ratio_clip"] = 0.2
|
|
87
|
+
cfg["value_clip"] = 0.2
|
|
88
|
+
cfg["clip_predicted_values"] = False
|
|
89
|
+
cfg["entropy_loss_scale"] = 0.0
|
|
90
|
+
cfg["value_loss_scale"] = 0.5
|
|
91
|
+
cfg["kl_threshold"] = 0
|
|
92
|
+
cfg["state_preprocessor"] = RunningStandardScaler
|
|
93
|
+
cfg["state_preprocessor_kwargs"] = {"size": env.observation_space, "device": device}
|
|
94
|
+
cfg["value_preprocessor"] = RunningStandardScaler
|
|
95
|
+
cfg["value_preprocessor_kwargs"] = {"size": 1, "device": device}
|
|
96
|
+
# logging to TensorBoard and write checkpoints (in timesteps)
|
|
97
|
+
cfg["experiment"]["write_interval"] = 500
|
|
98
|
+
cfg["experiment"]["checkpoint_interval"] = 5000
|
|
99
|
+
cfg["experiment"]["directory"] = "runs/skrl/torch/"
|
|
100
|
+
cfg["experiment"]["experiment_name"] = (
|
|
101
|
+
os.path.splitext(os.path.basename(__file__))[0] + "_" + datetime.now().strftime("%Y-%m-%d_%H:%M:%S")
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
params = {
|
|
105
|
+
"models": models,
|
|
106
|
+
"memory": memory,
|
|
107
|
+
"cfg": cfg,
|
|
108
|
+
"observation_space": env.observation_space,
|
|
109
|
+
"action_space": env.action_space,
|
|
110
|
+
"device": device,
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if models["policy"].is_rnn:
|
|
114
|
+
agent = PPO_RNN(**params)
|
|
115
|
+
else:
|
|
116
|
+
agent = PPO(**params)
|
|
117
|
+
|
|
118
|
+
# configure and instantiate the RL trainer
|
|
119
|
+
cfg_trainer = {"timesteps": 100000, "headless": True}
|
|
120
|
+
trainer = SequentialTrainer(cfg=cfg_trainer, env=env, agents=[agent])
|
|
121
|
+
|
|
122
|
+
# start training
|
|
123
|
+
trainer.train()
|