rlmodule 0.1.6.2__tar.gz → 0.1.6.3__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.6.2/rlmodule.egg-info → rlmodule-0.1.6.3}/PKG-INFO +2 -2
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/README.md +1 -1
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/pyproject.toml +1 -1
- rlmodule-0.1.6.3/rlmodule/skrl/torch/examples/gymnasium/cnn_experimental.py +152 -0
- {rlmodule-0.1.6.2/rlmodule/skrl/torch → rlmodule-0.1.6.3/rlmodule/skrl/torch/examples}/gymnasium/pendulum_ppo_mlp_separate_model.py +0 -3
- rlmodule-0.1.6.3/rlmodule/skrl/torch/network/__init__.py +29 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/source/build.py +4 -4
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/source/network.py +51 -102
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/source/network_cfg.py +16 -1
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/source/output_layer.py +11 -11
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/source/utils.py +29 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3/rlmodule.egg-info}/PKG-INFO +2 -2
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule.egg-info/SOURCES.txt +11 -10
- rlmodule-0.1.6.2/rlmodule/skrl/torch/network/__init__.py +0 -20
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/LICENSE +0 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/__init__.py +0 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/skrl/__init__.py +0 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/skrl/torch/__init__.py +0 -0
- {rlmodule-0.1.6.2/rlmodule/skrl/torch → rlmodule-0.1.6.3/rlmodule/skrl/torch/examples}/gymnasium/pendulum_ppo_mlp_shared_model.py +0 -0
- {rlmodule-0.1.6.2/rlmodule/skrl/torch → rlmodule-0.1.6.3/rlmodule/skrl/torch/examples}/gymnasium/pendulum_ppo_rnn_forwarded_input_shared_model.py +0 -0
- {rlmodule-0.1.6.2/rlmodule/skrl/torch → rlmodule-0.1.6.3/rlmodule/skrl/torch/examples}/gymnasium/pendulum_ppo_rnn_separate_model.py +0 -0
- {rlmodule-0.1.6.2/rlmodule/skrl/torch → rlmodule-0.1.6.3/rlmodule/skrl/torch/examples}/gymnasium/pendulum_ppo_rnn_shared_model.py +0 -0
- {rlmodule-0.1.6.2/rlmodule/skrl/torch → rlmodule-0.1.6.3/rlmodule/skrl/torch/examples}/gymnasium/pendulum_sac_mlp_separate_model.py +0 -0
- {rlmodule-0.1.6.2/rlmodule/skrl/torch → rlmodule-0.1.6.3/rlmodule/skrl/torch/examples}/gymnasium/skrl_no_module.py +0 -0
- {rlmodule-0.1.6.2/rlmodule/skrl/torch → rlmodule-0.1.6.3/rlmodule/skrl/torch/examples}/gymnasium/skrl_no_module_rnn.py +0 -0
- {rlmodule-0.1.6.2/rlmodule/skrl/torch → rlmodule-0.1.6.3/rlmodule/skrl/torch/examples}/gymnasium/skrl_sac.py +0 -0
- {rlmodule-0.1.6.2/rlmodule/skrl/torch → rlmodule-0.1.6.3/rlmodule/skrl/torch/examples}/gymnasium/temp.py +0 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/skrl/torch/output_layer/__init__.py +0 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/source/__init__.py +0 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/source/log_std.py +0 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/source/log_std_cfg.py +0 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/source/model.py +0 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/source/nvidia_utils/__init__.py +0 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/source/nvidia_utils/configclass.py +0 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/source/nvidia_utils/dict.py +0 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/source/nvidia_utils/string.py +0 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/source/output_layer_cfg.py +0 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/source/rlmodel.py +0 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule/source/rlmodel_cfg.py +0 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule.egg-info/dependency_links.txt +0 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule.egg-info/requires.txt +0 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/rlmodule.egg-info/top_level.txt +0 -0
- {rlmodule-0.1.6.2 → rlmodule-0.1.6.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: rlmodule
|
|
3
|
-
Version: 0.1.6.
|
|
3
|
+
Version: 0.1.6.3
|
|
4
4
|
Summary: Flexible reinforcement learning models instantiators library
|
|
5
5
|
Author: Lopatovsky
|
|
6
6
|
Author-email: lopatovsky@gmail.com
|
|
@@ -79,7 +79,7 @@ rm -rf runs
|
|
|
79
79
|
|
|
80
80
|
### Run chosen example
|
|
81
81
|
```
|
|
82
|
-
python3 rlmodule/skrl/torch/gymnasium/pendulum_ppo_mlp_separate_model.py
|
|
82
|
+
python3 rlmodule/skrl/torch/examples/gymnasium/pendulum_ppo_mlp_separate_model.py
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
Optional: observe run results in Tensorboard
|
|
@@ -46,7 +46,7 @@ rm -rf runs
|
|
|
46
46
|
|
|
47
47
|
### Run chosen example
|
|
48
48
|
```
|
|
49
|
-
python3 rlmodule/skrl/torch/gymnasium/pendulum_ppo_mlp_separate_model.py
|
|
49
|
+
python3 rlmodule/skrl/torch/examples/gymnasium/pendulum_ppo_mlp_separate_model.py
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
Optional: observe run results in Tensorboard
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
from typing import Tuple
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
import gymnasium as gym
|
|
6
|
+
|
|
7
|
+
# import the skrl components to build the RL system
|
|
8
|
+
from skrl.agents.torch.ppo import PPO, PPO_DEFAULT_CONFIG, PPO_RNN
|
|
9
|
+
from skrl.envs.wrappers.torch.gymnasium_envs import GymnasiumWrapper
|
|
10
|
+
from skrl.memories.torch import RandomMemory
|
|
11
|
+
from skrl.resources.preprocessors.torch import RunningStandardScaler
|
|
12
|
+
from skrl.resources.schedulers.torch import KLAdaptiveRL
|
|
13
|
+
from skrl.trainers.torch import SequentialTrainer
|
|
14
|
+
from skrl.utils import set_seed
|
|
15
|
+
|
|
16
|
+
import numpy as np
|
|
17
|
+
import torch.nn as nn
|
|
18
|
+
|
|
19
|
+
from rlmodule.skrl.torch import SharedRLModelCfg, build_model
|
|
20
|
+
from rlmodule.skrl.torch.network import CnnCfg
|
|
21
|
+
from rlmodule.skrl.torch.output_layer import DeterministicLayerCfg, GaussianLayerCfg, ParameterLogStdCfg
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# CNN is in an experimental phase. Some combination of inputs may not be yet supported
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class DummyEnv(gym.Env):
|
|
28
|
+
"""Dummy env producing random observations of given shape."""
|
|
29
|
+
|
|
30
|
+
def __init__(self):
|
|
31
|
+
super(DummyEnv, self).__init__()
|
|
32
|
+
# Define observation space:
|
|
33
|
+
self.observation_space = gym.spaces.Box(low=0, high=255, shape=(169,), dtype=np.uint8)
|
|
34
|
+
# Define action space: Continuous values between -1.0 and 1.0, with 6 action dimensions
|
|
35
|
+
self.action_space = gym.spaces.Box(low=-1.0, high=1.0, shape=(6,), dtype=np.float32)
|
|
36
|
+
|
|
37
|
+
def reset(self) -> Tuple[np.ndarray, dict]:
|
|
38
|
+
# Reset environment and return initial random observation
|
|
39
|
+
observation = self._get_random_observation()
|
|
40
|
+
return observation, {}
|
|
41
|
+
|
|
42
|
+
def step(self, action: np.ndarray) -> Tuple[np.ndarray, float, bool, bool, dict]:
|
|
43
|
+
# Create a new random observation
|
|
44
|
+
observation = self._get_random_observation()
|
|
45
|
+
reward = 0.0 # No meaningful reward in this dummy environment
|
|
46
|
+
terminated = False # This dummy environment never ends
|
|
47
|
+
truncated = False
|
|
48
|
+
info = {}
|
|
49
|
+
return observation, reward, terminated, truncated, info
|
|
50
|
+
|
|
51
|
+
def _get_random_observation(self) -> np.ndarray:
|
|
52
|
+
# Generate a random observation with values between 0 and 255
|
|
53
|
+
return np.random.randint(0, 256, 169, dtype=np.uint8)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def get_model(env):
|
|
57
|
+
"""Instantiate the agent's models (function approximators)."""
|
|
58
|
+
|
|
59
|
+
net_cfg = CnnCfg(
|
|
60
|
+
input_states=(13, 13, 1),
|
|
61
|
+
layers=[
|
|
62
|
+
nn.Conv2d(in_channels=1, out_channels=64, kernel_size=3, stride=2),
|
|
63
|
+
nn.ReLU(),
|
|
64
|
+
nn.Flatten(),
|
|
65
|
+
],
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
model = build_model(
|
|
69
|
+
SharedRLModelCfg(
|
|
70
|
+
network=net_cfg,
|
|
71
|
+
device=device,
|
|
72
|
+
policy_output_layer=GaussianLayerCfg(
|
|
73
|
+
output_size=env.action_space,
|
|
74
|
+
log_std=ParameterLogStdCfg(
|
|
75
|
+
min_log_std=-1.2,
|
|
76
|
+
max_log_std=2,
|
|
77
|
+
initial_log_std=0.0,
|
|
78
|
+
),
|
|
79
|
+
),
|
|
80
|
+
value_output_layer=DeterministicLayerCfg(),
|
|
81
|
+
)
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
print(model)
|
|
85
|
+
return {"policy": model, "value": model}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
# set seed for reproducibility
|
|
89
|
+
seed = 42
|
|
90
|
+
set_seed(seed)
|
|
91
|
+
|
|
92
|
+
env = DummyEnv()
|
|
93
|
+
# env = gym.make_vec("ALE/Pong-v5", num_envs=4, vectorization_mode="sync")
|
|
94
|
+
env = GymnasiumWrapper(env)
|
|
95
|
+
|
|
96
|
+
device = env.device
|
|
97
|
+
|
|
98
|
+
# instantiate a memory as rollout buffer (any memory can be used for this)
|
|
99
|
+
memory = RandomMemory(memory_size=1024, num_envs=env.num_envs, device=device)
|
|
100
|
+
|
|
101
|
+
models = get_model(env)
|
|
102
|
+
|
|
103
|
+
# configure and instantiate the agent (visit its documentation to see all the options)
|
|
104
|
+
# https://skrl.readthedocs.io/en/latest/api/agents/ppo.html#configuration-and-hyperparameters
|
|
105
|
+
cfg = PPO_DEFAULT_CONFIG.copy()
|
|
106
|
+
cfg["rollouts"] = 1024 # memory_size
|
|
107
|
+
cfg["learning_epochs"] = 10
|
|
108
|
+
cfg["mini_batches"] = 32
|
|
109
|
+
cfg["discount_factor"] = 0.9
|
|
110
|
+
cfg["lambda"] = 0.95
|
|
111
|
+
cfg["learning_rate"] = 1e-3
|
|
112
|
+
cfg["learning_rate_scheduler"] = KLAdaptiveRL
|
|
113
|
+
cfg["learning_rate_scheduler_kwargs"] = {"kl_threshold": 0.008}
|
|
114
|
+
cfg["grad_norm_clip"] = 0.5
|
|
115
|
+
cfg["ratio_clip"] = 0.2
|
|
116
|
+
cfg["value_clip"] = 0.2
|
|
117
|
+
cfg["clip_predicted_values"] = False
|
|
118
|
+
cfg["entropy_loss_scale"] = 0.0
|
|
119
|
+
cfg["value_loss_scale"] = 0.5
|
|
120
|
+
cfg["kl_threshold"] = 0
|
|
121
|
+
cfg["state_preprocessor"] = RunningStandardScaler
|
|
122
|
+
cfg["state_preprocessor_kwargs"] = {"size": env.observation_space, "device": device}
|
|
123
|
+
cfg["value_preprocessor"] = RunningStandardScaler
|
|
124
|
+
cfg["value_preprocessor_kwargs"] = {"size": 1, "device": device}
|
|
125
|
+
# logging to TensorBoard and write checkpoints (in timesteps)
|
|
126
|
+
cfg["experiment"]["write_interval"] = 500
|
|
127
|
+
cfg["experiment"]["checkpoint_interval"] = 5000
|
|
128
|
+
cfg["experiment"]["directory"] = "runs/skrl/torch/"
|
|
129
|
+
cfg["experiment"]["experiment_name"] = (
|
|
130
|
+
os.path.splitext(os.path.basename(__file__))[0] + "_" + datetime.now().strftime("%Y-%m-%d_%H:%M:%S")
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
params = {
|
|
134
|
+
"models": models,
|
|
135
|
+
"memory": memory,
|
|
136
|
+
"cfg": cfg,
|
|
137
|
+
"observation_space": env.observation_space,
|
|
138
|
+
"action_space": env.action_space,
|
|
139
|
+
"device": device,
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if models["policy"].is_rnn:
|
|
143
|
+
agent = PPO_RNN(**params)
|
|
144
|
+
else:
|
|
145
|
+
agent = PPO(**params)
|
|
146
|
+
|
|
147
|
+
# configure and instantiate the RL trainer
|
|
148
|
+
cfg_trainer = {"timesteps": 100000, "headless": True}
|
|
149
|
+
trainer = SequentialTrainer(cfg=cfg_trainer, env=env, agents=[agent])
|
|
150
|
+
|
|
151
|
+
# start training
|
|
152
|
+
trainer.train()
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
__all__ = [
|
|
2
|
+
# modules:
|
|
3
|
+
"MLP",
|
|
4
|
+
"RNN",
|
|
5
|
+
"GRU",
|
|
6
|
+
"LSTM",
|
|
7
|
+
"RnnBase",
|
|
8
|
+
"RnnMlp",
|
|
9
|
+
"RnnMlpWithForwardedInput",
|
|
10
|
+
# configs:
|
|
11
|
+
"NetworkCfg",
|
|
12
|
+
"MlpCfg",
|
|
13
|
+
"RnnBaseCfg",
|
|
14
|
+
"RnnCfg",
|
|
15
|
+
"GruCfg",
|
|
16
|
+
"LstmCfg",
|
|
17
|
+
"RnnMlpCfg",
|
|
18
|
+
]
|
|
19
|
+
from rlmodule.source.network import CNN, GRU, LSTM, MLP, RNN, RnnBase, RnnMlp, RnnMlpWithForwardedInput # noqa: F401
|
|
20
|
+
from rlmodule.source.network_cfg import ( # noqa: F401
|
|
21
|
+
CnnCfg,
|
|
22
|
+
GruCfg,
|
|
23
|
+
LstmCfg,
|
|
24
|
+
MlpCfg,
|
|
25
|
+
NetworkCfg,
|
|
26
|
+
RnnBaseCfg,
|
|
27
|
+
RnnCfg,
|
|
28
|
+
RnnMlpCfg,
|
|
29
|
+
)
|
|
@@ -10,9 +10,9 @@ def build_model(cfg: BaseRLCfg):
|
|
|
10
10
|
actions_as_input = hasattr(network_cfg, "input_actions") and network_cfg.input_actions is not None
|
|
11
11
|
|
|
12
12
|
# process input size
|
|
13
|
-
network_cfg.
|
|
13
|
+
network_cfg.input_size = get_space_size(network_cfg.input_states)
|
|
14
14
|
if actions_as_input:
|
|
15
|
-
network_cfg.
|
|
15
|
+
network_cfg.input_size += get_space_size(network_cfg.input_actions)
|
|
16
16
|
|
|
17
17
|
# build base network of function approximator
|
|
18
18
|
net = network_cfg.module(network_cfg)
|
|
@@ -21,10 +21,10 @@ def build_model(cfg: BaseRLCfg):
|
|
|
21
21
|
net.input_actions = True
|
|
22
22
|
|
|
23
23
|
# get output size to be used as output layer input
|
|
24
|
-
network_output_size = get_output_size(net, network_cfg.
|
|
24
|
+
network_output_size = get_output_size(net, network_cfg.input_size)
|
|
25
25
|
|
|
26
26
|
def build_output_layer(layer_cfg):
|
|
27
|
-
return layer_cfg.class_type(device=cfg.device,
|
|
27
|
+
return layer_cfg.class_type(device=cfg.device, input_size=network_output_size, cfg=layer_cfg)
|
|
28
28
|
|
|
29
29
|
# build function approximator
|
|
30
30
|
if isinstance(cfg, RLModelCfg):
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import torch
|
|
2
2
|
import torch.nn as nn
|
|
3
3
|
|
|
4
|
+
from rlmodule.source.utils import get_cnn_shape
|
|
5
|
+
|
|
4
6
|
|
|
5
7
|
class MLP(nn.Module):
|
|
6
8
|
"""Configurable multilayer perceptron module.
|
|
@@ -10,7 +12,7 @@ class MLP(nn.Module):
|
|
|
10
12
|
Example of use:
|
|
11
13
|
|
|
12
14
|
cfg = MlpCfg(
|
|
13
|
-
|
|
15
|
+
input_size = 517,
|
|
14
16
|
hidden_units = [2048, 1024, 1024, 512],
|
|
15
17
|
activation = nn.ELU,
|
|
16
18
|
)
|
|
@@ -22,7 +24,7 @@ class MLP(nn.Module):
|
|
|
22
24
|
|
|
23
25
|
# input layer
|
|
24
26
|
layers = [
|
|
25
|
-
nn.Linear(cfg.
|
|
27
|
+
nn.Linear(cfg.input_size, cfg.hidden_units[0]),
|
|
26
28
|
cfg.activation(),
|
|
27
29
|
]
|
|
28
30
|
|
|
@@ -66,7 +68,7 @@ class LSTM(RnnBase):
|
|
|
66
68
|
Example of use:
|
|
67
69
|
|
|
68
70
|
cfg = LstmCfg(
|
|
69
|
-
|
|
71
|
+
input_size = 517,
|
|
70
72
|
num_envs = 2048,
|
|
71
73
|
num_layers = 1,
|
|
72
74
|
hidden_size = 512 + 256,
|
|
@@ -79,7 +81,7 @@ class LSTM(RnnBase):
|
|
|
79
81
|
super().__init__(cfg)
|
|
80
82
|
|
|
81
83
|
self.lstm = nn.LSTM(
|
|
82
|
-
input_size=cfg.
|
|
84
|
+
input_size=cfg.input_size,
|
|
83
85
|
hidden_size=cfg.hidden_size,
|
|
84
86
|
num_layers=cfg.num_layers,
|
|
85
87
|
batch_first=True,
|
|
@@ -235,7 +237,7 @@ class RNN(RnnModule):
|
|
|
235
237
|
Example of use:
|
|
236
238
|
|
|
237
239
|
cfg = RnnCfg(
|
|
238
|
-
|
|
240
|
+
input_size = 517,
|
|
239
241
|
num_envs = 2048,
|
|
240
242
|
num_layers = 1,
|
|
241
243
|
hidden_size = 512 + 256,
|
|
@@ -248,7 +250,7 @@ class RNN(RnnModule):
|
|
|
248
250
|
super().__init__(cfg)
|
|
249
251
|
|
|
250
252
|
self.rnn = nn.RNN(
|
|
251
|
-
input_size=cfg.
|
|
253
|
+
input_size=cfg.input_size,
|
|
252
254
|
hidden_size=cfg.hidden_size,
|
|
253
255
|
num_layers=cfg.num_layers,
|
|
254
256
|
batch_first=True,
|
|
@@ -266,7 +268,7 @@ class GRU(RnnModule):
|
|
|
266
268
|
Example of use:
|
|
267
269
|
|
|
268
270
|
cfg = GruCfg(
|
|
269
|
-
|
|
271
|
+
input_size = 517,
|
|
270
272
|
num_envs = 2048,
|
|
271
273
|
num_layers = 1,
|
|
272
274
|
hidden_size = 512 + 256,
|
|
@@ -279,7 +281,7 @@ class GRU(RnnModule):
|
|
|
279
281
|
super().__init__(cfg)
|
|
280
282
|
|
|
281
283
|
self.rnn = nn.GRU(
|
|
282
|
-
input_size=cfg.
|
|
284
|
+
input_size=cfg.input_size,
|
|
283
285
|
hidden_size=cfg.hidden_size,
|
|
284
286
|
num_layers=cfg.num_layers,
|
|
285
287
|
batch_first=True,
|
|
@@ -298,7 +300,7 @@ class RnnMlp(RnnBase):
|
|
|
298
300
|
1) Example of use (with RNN module):
|
|
299
301
|
|
|
300
302
|
cfg = RnnMlpCfg(
|
|
301
|
-
|
|
303
|
+
input_size = 517,
|
|
302
304
|
rnn = RnnCfg(
|
|
303
305
|
num_envs = 2048,
|
|
304
306
|
num_layers = 1,
|
|
@@ -315,7 +317,7 @@ class RnnMlp(RnnBase):
|
|
|
315
317
|
2) Example of use (with GRU module):
|
|
316
318
|
|
|
317
319
|
cfg = RnnMlpCfg(
|
|
318
|
-
|
|
320
|
+
input_size = 517,
|
|
319
321
|
rnn = GruCfg(
|
|
320
322
|
num_envs = 2048,
|
|
321
323
|
num_layers = 1,
|
|
@@ -332,7 +334,7 @@ class RnnMlp(RnnBase):
|
|
|
332
334
|
3) Example of use (with LSTM module):
|
|
333
335
|
|
|
334
336
|
cfg = RnnMlpCfg(
|
|
335
|
-
|
|
337
|
+
input_size = 517,
|
|
336
338
|
rnn = LstmCfg(
|
|
337
339
|
num_envs = 2048,
|
|
338
340
|
num_layers = 1,
|
|
@@ -349,9 +351,9 @@ class RnnMlp(RnnBase):
|
|
|
349
351
|
|
|
350
352
|
def __init__(self, cfg):
|
|
351
353
|
super().__init__(cfg.rnn)
|
|
352
|
-
cfg.rnn.
|
|
354
|
+
cfg.rnn.input_size = cfg.input_size
|
|
353
355
|
self.rnn = cfg.rnn.module(cfg.rnn)
|
|
354
|
-
cfg.mlp.
|
|
356
|
+
cfg.mlp.input_size = self.hidden_size
|
|
355
357
|
self.mlp = MLP(cfg.mlp)
|
|
356
358
|
|
|
357
359
|
def forward(self, states, terminated, rnn_inputs):
|
|
@@ -372,7 +374,7 @@ class RnnMlpWithForwardedInput(RnnBase):
|
|
|
372
374
|
1) Example of use (with RNN module):
|
|
373
375
|
|
|
374
376
|
cfg = RnnMlpCfg(
|
|
375
|
-
|
|
377
|
+
input_size = 517,
|
|
376
378
|
module = RnnMlpWithForwardedInput,
|
|
377
379
|
rnn = RnnCfg(
|
|
378
380
|
num_envs = 2048,
|
|
@@ -390,7 +392,7 @@ class RnnMlpWithForwardedInput(RnnBase):
|
|
|
390
392
|
2) Example of use (with GRU module):
|
|
391
393
|
|
|
392
394
|
cfg = RnnMlpCfg(
|
|
393
|
-
|
|
395
|
+
input_size = 517,
|
|
394
396
|
module = RnnMlpWithForwardedInput,
|
|
395
397
|
rnn = GruCfg(
|
|
396
398
|
num_envs = 2048,
|
|
@@ -408,7 +410,7 @@ class RnnMlpWithForwardedInput(RnnBase):
|
|
|
408
410
|
3) Example of use (with LSTM module):
|
|
409
411
|
|
|
410
412
|
cfg = RnnMlpCfg(
|
|
411
|
-
|
|
413
|
+
input_size = 517,
|
|
412
414
|
module = RnnMlpWithForwardedInput,
|
|
413
415
|
rnn = LstmCfg(
|
|
414
416
|
num_envs = 2048,
|
|
@@ -430,9 +432,9 @@ class RnnMlpWithForwardedInput(RnnBase):
|
|
|
430
432
|
|
|
431
433
|
def __init__(self, cfg):
|
|
432
434
|
super().__init__(cfg.rnn)
|
|
433
|
-
cfg.rnn.
|
|
435
|
+
cfg.rnn.input_size = cfg.input_size
|
|
434
436
|
self.rnn = cfg.rnn.module(cfg.rnn)
|
|
435
|
-
cfg.mlp.
|
|
437
|
+
cfg.mlp.input_size = cfg.input_size + self.hidden_size
|
|
436
438
|
self.mlp = MLP(cfg.mlp)
|
|
437
439
|
|
|
438
440
|
def forward(self, states, terminated, rnn_inputs):
|
|
@@ -442,93 +444,40 @@ class RnnMlpWithForwardedInput(RnnBase):
|
|
|
442
444
|
return self.mlp(mlp_input), output_dict
|
|
443
445
|
|
|
444
446
|
|
|
445
|
-
|
|
447
|
+
class CNN(nn.Module):
|
|
448
|
+
"""Experimental implementation of Convolutional neural network.
|
|
449
|
+
Architecture is defined by providing modules_cfg.MlpCfg.
|
|
446
450
|
|
|
447
|
-
|
|
448
|
-
# """
|
|
449
|
-
# Create a CNN layer based on the provided parameters and activation function.
|
|
450
|
-
|
|
451
|
-
# Args:
|
|
452
|
-
# params (dict): Dictionary containing the parameters for the layer.
|
|
453
|
-
# Expected keys are:
|
|
454
|
-
# - 'type' (str): Type of the layer ('conv' for convolutional, 'pool' for pooling,
|
|
455
|
-
# 'dense' for fully connected).
|
|
456
|
-
# - 'in_channels' (int): Number of input channels (required for 'conv' type).
|
|
457
|
-
# - 'out_channels' (int): Number of output channels (required for 'conv' type).
|
|
458
|
-
# - 'kernel_size' (int or tuple): Size of the kernel (required for 'conv' or 'pool' type).
|
|
459
|
-
# - 'stride' (int or tuple): Stride of the convolution or pooling operation
|
|
460
|
-
# (required for 'conv' or 'pool' type).
|
|
461
|
-
# - 'in_features' (int): Number of input features (required for 'dense' type).
|
|
462
|
-
# - 'out_features' (int): Number of output features (required for 'dense' type).
|
|
463
|
-
# - 'activation' (str): Activation function to use after the layer (only for 'conv' and 'dense' types).
|
|
464
|
-
|
|
465
|
-
# Returns:
|
|
466
|
-
# list: List containing the created layer(s). For 'conv' type, it includes the convolutional
|
|
467
|
-
# layer followed by the activation function. For 'pool' type, it includes only the pooling layer.
|
|
468
|
-
# For 'dense' type, it includes the fully connected layer followed by the activation function.
|
|
469
|
-
|
|
470
|
-
# Raises:
|
|
471
|
-
# ValueError: If the 'type' specified in params is not supported.
|
|
472
|
-
# """
|
|
473
|
-
# if params['type'] == 'conv':
|
|
474
|
-
# return [
|
|
475
|
-
# nn.Conv2d(
|
|
476
|
-
# in_channels=params['in_channels'],
|
|
477
|
-
# out_channels=params['out_channels'],
|
|
478
|
-
# kernel_size=params['kernel_size'],
|
|
479
|
-
# stride=params['stride'],
|
|
480
|
-
# ),
|
|
481
|
-
# _get_activation_function(params['activation']),
|
|
482
|
-
# ]
|
|
483
|
-
# elif params['type'] == 'pool':
|
|
484
|
-
# return [
|
|
485
|
-
# nn.MaxPool2d(
|
|
486
|
-
# kernel_size=params['kernel_size'],
|
|
487
|
-
# stride=params['stride'],
|
|
488
|
-
# )
|
|
489
|
-
# ]
|
|
490
|
-
# elif params['type'] == 'dense':
|
|
491
|
-
# return [
|
|
492
|
-
# nn.Flatten(), # if there is 2D layer before need to be flatten to 1D.
|
|
493
|
-
# nn.Linear(
|
|
494
|
-
# in_features=params['in_features'],
|
|
495
|
-
# out_features=params['out_features'],
|
|
496
|
-
# ),
|
|
497
|
-
# _get_activation_function(params['activation']),
|
|
498
|
-
# ]
|
|
499
|
-
# else:
|
|
500
|
-
# raise ValueError(f"Unsupported layer type: {params['type']}")
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
# class CNN(nn.Module):
|
|
504
|
-
# def __init__(self, params):
|
|
505
|
-
# super().__init__()
|
|
451
|
+
Warning: CNN is in an experimental phase. Some combination of inputs may not be yet supported.
|
|
506
452
|
|
|
507
|
-
|
|
508
|
-
# self.cnn = nn.Sequential(*layers, nn.Flatten())
|
|
453
|
+
Example of use:
|
|
509
454
|
|
|
510
|
-
|
|
511
|
-
#
|
|
455
|
+
cfg = CnnCfg(
|
|
456
|
+
input_size = (13, 13, 1) # input states in order (x,y,channels)
|
|
457
|
+
layers=[
|
|
458
|
+
nn.Conv2d(in_channels=1, out_channels=64, kernel_size=3, stride=2),
|
|
459
|
+
nn.ReLU(),
|
|
460
|
+
nn.Flatten()
|
|
461
|
+
]
|
|
462
|
+
)
|
|
463
|
+
net = CNN(cfg)
|
|
464
|
+
"""
|
|
512
465
|
|
|
466
|
+
def __init__(self, cfg):
|
|
467
|
+
super().__init__()
|
|
468
|
+
self._input_size = cfg.input_size
|
|
513
469
|
|
|
514
|
-
|
|
515
|
-
# params = {
|
|
516
|
-
# 'input_shape': [1, 13, 13],
|
|
517
|
-
# 'layers': [
|
|
518
|
-
# {'type': 'conv', 'kernel_size': 3, 'stride': 2, 'in_channels': 1,
|
|
519
|
-
# 'out_channels': 32, 'activation': 'relu'},
|
|
520
|
-
# {
|
|
521
|
-
# 'type': 'conv',
|
|
522
|
-
# 'kernel_size': 3,
|
|
523
|
-
# 'stride': 1,
|
|
524
|
-
# 'in_channels': 32,
|
|
525
|
-
# 'out_channels': 64,
|
|
526
|
-
# 'activation': 'relu',
|
|
527
|
-
# },
|
|
528
|
-
# ],
|
|
529
|
-
# }
|
|
470
|
+
self._input_shape = get_cnn_shape(cfg.input_states)
|
|
530
471
|
|
|
531
|
-
|
|
472
|
+
modules = []
|
|
473
|
+
for layer in cfg.layers:
|
|
474
|
+
modules.append(layer)
|
|
475
|
+
|
|
476
|
+
self.cnn = nn.Sequential(*modules)
|
|
477
|
+
|
|
478
|
+
def forward(self, input):
|
|
479
|
+
# Cnn expects inputs in shape (batch, channels, x, y)
|
|
480
|
+
return self.cnn(input.view(-1, *self._input_shape).permute(0, 3, 1, 2))
|
|
532
481
|
|
|
533
482
|
|
|
534
483
|
# class TripleCnnAndMlp(nn.Module):
|
|
@@ -570,7 +519,7 @@ class RnnMlpWithForwardedInput(RnnBase):
|
|
|
570
519
|
|
|
571
520
|
# self.cnns = nn.ModuleList([CNN(cnn_params) for _ in range(self.cnn_number)])
|
|
572
521
|
|
|
573
|
-
# mlp_params['
|
|
522
|
+
# mlp_params['input_size'] = self.prefix_length + self.cnn_number * get_output_size(
|
|
574
523
|
# self.cnns[0], self.input_shape
|
|
575
524
|
# )
|
|
576
525
|
|
|
@@ -630,13 +579,13 @@ class RnnMlpWithForwardedInput(RnnBase):
|
|
|
630
579
|
|
|
631
580
|
# self.cnns = nn.ModuleList([CNN(cnn_params) for _ in range(self.cnn_number)])
|
|
632
581
|
|
|
633
|
-
# rnn_params['
|
|
582
|
+
# rnn_params['input_size'] = self.prefix_length + self.cnn_number * get_output_size(
|
|
634
583
|
# self.cnns[0], self.input_shape
|
|
635
584
|
# )
|
|
636
585
|
|
|
637
586
|
# self.rnn = rnn_class(rnn_params)
|
|
638
587
|
|
|
639
|
-
# mlp_params['
|
|
588
|
+
# mlp_params['input_size'] = self.rnn.hidden_size + self.rnn.input_size
|
|
640
589
|
|
|
641
590
|
# self.mlp = MLP(mlp_params)
|
|
642
591
|
|
|
@@ -8,7 +8,7 @@ import gymnasium
|
|
|
8
8
|
import torch.nn as nn
|
|
9
9
|
|
|
10
10
|
from rlmodule import logger
|
|
11
|
-
from rlmodule.source.network import GRU, LSTM, MLP, RNN, RnnBase, RnnMlp
|
|
11
|
+
from rlmodule.source.network import CNN, GRU, LSTM, MLP, RNN, RnnBase, RnnMlp
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
# use isaac-lab native configclass if available to avoid it being declared twice
|
|
@@ -22,6 +22,8 @@ except ImportError:
|
|
|
22
22
|
@configclass
|
|
23
23
|
class NetworkCfg:
|
|
24
24
|
module: Union[nn.Module, Callable[..., nn.Module]] = MISSING
|
|
25
|
+
input_size: int = None
|
|
26
|
+
"""Size of all network inputs. This field should be automatically derived from input_states/input_actions."""
|
|
25
27
|
input_states: Union[int, Sequence[int], gym.Space, gymnasium.Space] = None
|
|
26
28
|
"""Observations passed to the network as an input."""
|
|
27
29
|
input_actions: Union[int, Sequence[int], gym.Space, gymnasium.Space] = None
|
|
@@ -65,3 +67,16 @@ class RnnMlpCfg(NetworkCfg):
|
|
|
65
67
|
|
|
66
68
|
rnn: RnnBaseCfg = MISSING
|
|
67
69
|
mlp: MlpCfg = MISSING
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@configclass
|
|
73
|
+
class CnnCfg(NetworkCfg):
|
|
74
|
+
"""Config for convolutional neural network.
|
|
75
|
+
For network to work properly the input states need to be specified as a triple in order (x,y,channels)
|
|
76
|
+
Warning: CNN is in an experimental phase. Some combination of inputs may not be yet supported.
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
module: type[CNN] = CNN
|
|
80
|
+
|
|
81
|
+
layers: Sequence[nn.Module] = MISSING
|
|
82
|
+
"""Layers of convolutional neural network."""
|
|
@@ -11,7 +11,7 @@ from rlmodule.source.utils import get_space_size
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class OutputLayer(nn.Module):
|
|
14
|
-
def __init__(self, device: Union[str, torch.device],
|
|
14
|
+
def __init__(self, device: Union[str, torch.device], input_size: int, cfg):
|
|
15
15
|
"""Base class for OutputLayer class hierarchy."""
|
|
16
16
|
super().__init__()
|
|
17
17
|
self.device = device
|
|
@@ -26,26 +26,26 @@ class OutputLayer(nn.Module):
|
|
|
26
26
|
self._clip_actions_min = torch.tensor(cfg.output_size.low, device=self.device, dtype=torch.float32)
|
|
27
27
|
self._clip_actions_max = torch.tensor(cfg.output_size.high, device=self.device, dtype=torch.float32)
|
|
28
28
|
|
|
29
|
-
self.
|
|
29
|
+
self._input_size = input_size
|
|
30
30
|
self._output_size = get_space_size(cfg.output_size)
|
|
31
31
|
|
|
32
32
|
self._output_scale = cfg.output_scale
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
class GaussianLayer(OutputLayer):
|
|
36
|
-
def __init__(self, device: Union[str, torch.device],
|
|
36
|
+
def __init__(self, device: Union[str, torch.device], input_size: int, cfg):
|
|
37
37
|
"""Gaussian output layer
|
|
38
38
|
|
|
39
39
|
:param device: Device on which a tensor/array is or will be allocated
|
|
40
40
|
:type device: str or torch.device
|
|
41
|
-
:param
|
|
41
|
+
:param input_size
|
|
42
42
|
:type int
|
|
43
43
|
:param cfg: Configuration of Gaussian output layer
|
|
44
44
|
:type OutputLayerCfg
|
|
45
45
|
|
|
46
46
|
:raises ValueError: If the reduction method is not valid
|
|
47
47
|
"""
|
|
48
|
-
super().__init__(device,
|
|
48
|
+
super().__init__(device, input_size, cfg)
|
|
49
49
|
|
|
50
50
|
self._cached_log_std = None
|
|
51
51
|
self._num_samples = None
|
|
@@ -59,9 +59,9 @@ class GaussianLayer(OutputLayer):
|
|
|
59
59
|
else torch.sum if cfg.reduction == "sum" else torch.prod if cfg.reduction == "prod" else None
|
|
60
60
|
)
|
|
61
61
|
|
|
62
|
-
self._net = nn.Sequential(nn.Linear(self.
|
|
62
|
+
self._net = nn.Sequential(nn.Linear(self._input_size, self._output_size), cfg.output_activation())
|
|
63
63
|
|
|
64
|
-
self._log_std = cfg.log_std.class_type(device,
|
|
64
|
+
self._log_std = cfg.log_std.class_type(device, input_size, self._output_size, cfg.log_std)
|
|
65
65
|
|
|
66
66
|
def forward(self, input, taken_actions, outputs_dict):
|
|
67
67
|
"""Act stochastically in response to the state of the environment
|
|
@@ -185,20 +185,20 @@ class GaussianLayer(OutputLayer):
|
|
|
185
185
|
|
|
186
186
|
|
|
187
187
|
class DeterministicLayer(OutputLayer):
|
|
188
|
-
def __init__(self, device: Union[str, torch.device],
|
|
188
|
+
def __init__(self, device: Union[str, torch.device], input_size: int, cfg):
|
|
189
189
|
"""Deterministic output layer
|
|
190
190
|
|
|
191
191
|
:param device: Device on which a tensor/array is or will be allocated
|
|
192
192
|
:type device: str or torch.device
|
|
193
|
-
:param
|
|
193
|
+
:param input_size
|
|
194
194
|
:type int
|
|
195
195
|
:param cfg: Configuration of Gaussian output layer
|
|
196
196
|
:type OutputLayerCfg
|
|
197
197
|
"""
|
|
198
198
|
|
|
199
|
-
super().__init__(device,
|
|
199
|
+
super().__init__(device, input_size, cfg)
|
|
200
200
|
|
|
201
|
-
self._net = nn.Sequential(nn.Linear(
|
|
201
|
+
self._net = nn.Sequential(nn.Linear(input_size, cfg.output_size), cfg.output_activation())
|
|
202
202
|
|
|
203
203
|
def forward(self, input, taken_actions, outputs_dict):
|
|
204
204
|
"""Act deterministically in response to the state of the environment
|
|
@@ -28,6 +28,35 @@ def get_output_size(module, input_shape):
|
|
|
28
28
|
return module(dummy_input).view(-1).shape[0]
|
|
29
29
|
|
|
30
30
|
|
|
31
|
+
def get_cnn_shape(space: Union[int, Sequence[int], gym.Space, gymnasium.Space]):
|
|
32
|
+
"""Experimental function to get shape of cnn input.
|
|
33
|
+
|
|
34
|
+
:param space: Space or shape from which to obtain the number of elements
|
|
35
|
+
:type space: int, sequence of int, gym.Space, or gymnasium.Space
|
|
36
|
+
|
|
37
|
+
:raises ValueError: If the space is not supported
|
|
38
|
+
:rtype: tuple
|
|
39
|
+
|
|
40
|
+
Example::
|
|
41
|
+
# from sequence of int
|
|
42
|
+
>>> model._get_space_size([2, 3])
|
|
43
|
+
(2, 3)
|
|
44
|
+
|
|
45
|
+
# Box space
|
|
46
|
+
>>> space = gym.spaces.Box(low=-1, high=1, shape=(2, 3))
|
|
47
|
+
>>> model._get_space_size(space)
|
|
48
|
+
(2, 3)
|
|
49
|
+
|
|
50
|
+
# Other types are currently not supported as a cnn input
|
|
51
|
+
"""
|
|
52
|
+
if type(space) in [tuple, list]:
|
|
53
|
+
return tuple(space)
|
|
54
|
+
elif issubclass(type(space), gym.spaces.Box):
|
|
55
|
+
return space.shape
|
|
56
|
+
else:
|
|
57
|
+
raise ValueError(f"Space type {type(space)} is not supported as cnn input.")
|
|
58
|
+
|
|
59
|
+
|
|
31
60
|
def get_space_size(
|
|
32
61
|
space: Union[int, Sequence[int], gym.Space, gymnasium.Space], number_of_elements: bool = True
|
|
33
62
|
) -> int:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: rlmodule
|
|
3
|
-
Version: 0.1.6.
|
|
3
|
+
Version: 0.1.6.3
|
|
4
4
|
Summary: Flexible reinforcement learning models instantiators library
|
|
5
5
|
Author: Lopatovsky
|
|
6
6
|
Author-email: lopatovsky@gmail.com
|
|
@@ -79,7 +79,7 @@ rm -rf runs
|
|
|
79
79
|
|
|
80
80
|
### Run chosen example
|
|
81
81
|
```
|
|
82
|
-
python3 rlmodule/skrl/torch/gymnasium/pendulum_ppo_mlp_separate_model.py
|
|
82
|
+
python3 rlmodule/skrl/torch/examples/gymnasium/pendulum_ppo_mlp_separate_model.py
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
Optional: observe run results in Tensorboard
|
|
@@ -9,16 +9,17 @@ rlmodule.egg-info/requires.txt
|
|
|
9
9
|
rlmodule.egg-info/top_level.txt
|
|
10
10
|
rlmodule/skrl/__init__.py
|
|
11
11
|
rlmodule/skrl/torch/__init__.py
|
|
12
|
-
rlmodule/skrl/torch/gymnasium/
|
|
13
|
-
rlmodule/skrl/torch/gymnasium/
|
|
14
|
-
rlmodule/skrl/torch/gymnasium/
|
|
15
|
-
rlmodule/skrl/torch/gymnasium/
|
|
16
|
-
rlmodule/skrl/torch/gymnasium/
|
|
17
|
-
rlmodule/skrl/torch/gymnasium/
|
|
18
|
-
rlmodule/skrl/torch/gymnasium/
|
|
19
|
-
rlmodule/skrl/torch/gymnasium/
|
|
20
|
-
rlmodule/skrl/torch/gymnasium/
|
|
21
|
-
rlmodule/skrl/torch/gymnasium/
|
|
12
|
+
rlmodule/skrl/torch/examples/gymnasium/cnn_experimental.py
|
|
13
|
+
rlmodule/skrl/torch/examples/gymnasium/pendulum_ppo_mlp_separate_model.py
|
|
14
|
+
rlmodule/skrl/torch/examples/gymnasium/pendulum_ppo_mlp_shared_model.py
|
|
15
|
+
rlmodule/skrl/torch/examples/gymnasium/pendulum_ppo_rnn_forwarded_input_shared_model.py
|
|
16
|
+
rlmodule/skrl/torch/examples/gymnasium/pendulum_ppo_rnn_separate_model.py
|
|
17
|
+
rlmodule/skrl/torch/examples/gymnasium/pendulum_ppo_rnn_shared_model.py
|
|
18
|
+
rlmodule/skrl/torch/examples/gymnasium/pendulum_sac_mlp_separate_model.py
|
|
19
|
+
rlmodule/skrl/torch/examples/gymnasium/skrl_no_module.py
|
|
20
|
+
rlmodule/skrl/torch/examples/gymnasium/skrl_no_module_rnn.py
|
|
21
|
+
rlmodule/skrl/torch/examples/gymnasium/skrl_sac.py
|
|
22
|
+
rlmodule/skrl/torch/examples/gymnasium/temp.py
|
|
22
23
|
rlmodule/skrl/torch/network/__init__.py
|
|
23
24
|
rlmodule/skrl/torch/output_layer/__init__.py
|
|
24
25
|
rlmodule/source/__init__.py
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
__all__ = [
|
|
2
|
-
# modules:
|
|
3
|
-
"MLP",
|
|
4
|
-
"RNN",
|
|
5
|
-
"GRU",
|
|
6
|
-
"LSTM",
|
|
7
|
-
"RnnBase",
|
|
8
|
-
"RnnMlp",
|
|
9
|
-
"RnnMlpWithForwardedInput",
|
|
10
|
-
# configs:
|
|
11
|
-
"NetworkCfg",
|
|
12
|
-
"MlpCfg",
|
|
13
|
-
"RnnBaseCfg",
|
|
14
|
-
"RnnCfg",
|
|
15
|
-
"GruCfg",
|
|
16
|
-
"LstmCfg",
|
|
17
|
-
"RnnMlpCfg",
|
|
18
|
-
]
|
|
19
|
-
from rlmodule.source.network import GRU, LSTM, MLP, RNN, RnnBase, RnnMlp, RnnMlpWithForwardedInput # noqa: F401
|
|
20
|
-
from rlmodule.source.network_cfg import GruCfg, LstmCfg, MlpCfg, NetworkCfg, RnnBaseCfg, RnnCfg, RnnMlpCfg # noqa: F401
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|