stable-baselines3 2.9.0a2__tar.gz → 2.9.2__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.
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/NOTICE +1 -1
- {stable_baselines3-2.9.0a2/stable_baselines3.egg-info → stable_baselines3-2.9.2}/PKG-INFO +4 -6
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/README.md +14 -9
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/pyproject.toml +7 -4
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/setup.py +3 -5
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/envs/__init__.py +0 -1
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/logger.py +1 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/monitor.py +3 -3
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/noise.py +1 -1
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/off_policy_algorithm.py +12 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/policies.py +3 -3
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/sb2_compat/rmsprop_tf_like.py +1 -1
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/vec_env/base_vec_env.py +2 -2
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/vec_env/subproc_vec_env.py +6 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/ddpg/ddpg.py +4 -1
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/dqn/dqn.py +3 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/ppo/ppo.py +1 -1
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/sac/sac.py +3 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/td3/td3.py +3 -0
- stable_baselines3-2.9.2/stable_baselines3/version.txt +1 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2/stable_baselines3.egg-info}/PKG-INFO +4 -6
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3.egg-info/requires.txt +2 -4
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_cnn.py +10 -3
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_logger.py +8 -2
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_n_step_replay.py +46 -1
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_save_load.py +31 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_spaces.py +16 -1
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_utils.py +56 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_vec_envs.py +1 -1
- stable_baselines3-2.9.0a2/stable_baselines3/version.txt +0 -1
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/LICENSE +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/setup.cfg +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/__init__.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/a2c/__init__.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/a2c/a2c.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/a2c/policies.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/__init__.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/atari_wrappers.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/base_class.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/buffers.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/callbacks.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/distributions.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/env_checker.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/env_util.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/envs/bit_flipping_env.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/envs/identity_env.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/envs/multi_input_envs.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/evaluation.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/on_policy_algorithm.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/preprocessing.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/results_plotter.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/running_mean_std.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/save_util.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/sb2_compat/__init__.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/torch_layers.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/type_aliases.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/utils.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/vec_env/__init__.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/vec_env/dummy_vec_env.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/vec_env/patch_gym.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/vec_env/stacked_observations.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/vec_env/util.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/vec_env/vec_check_nan.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/vec_env/vec_extract_dict_obs.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/vec_env/vec_frame_stack.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/vec_env/vec_monitor.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/vec_env/vec_normalize.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/vec_env/vec_transpose.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/vec_env/vec_video_recorder.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/ddpg/__init__.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/ddpg/policies.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/dqn/__init__.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/dqn/policies.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/her/__init__.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/her/goal_selection_strategy.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/her/her_replay_buffer.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/ppo/__init__.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/ppo/policies.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/py.typed +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/sac/__init__.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/sac/policies.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/td3/__init__.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/td3/policies.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3.egg-info/SOURCES.txt +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3.egg-info/dependency_links.txt +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3.egg-info/top_level.txt +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_buffers.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_callbacks.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_custom_policy.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_deterministic.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_dict_env.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_distributions.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_env_checker.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_envs.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_gae.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_her.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_identity.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_monitor.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_predict.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_preprocessing.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_run.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_sde.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_tensorboard.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_train_eval_mode.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_vec_check_nan.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_vec_extract_dict_obs.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_vec_monitor.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_vec_normalize.py +0 -0
- {stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/tests/test_vec_stacked_obs.py +0 -0
|
@@ -2,7 +2,7 @@ Large portion of the code of Stable-Baselines3 (in `common/`) were ported from S
|
|
|
2
2
|
both licensed under the MIT License:
|
|
3
3
|
|
|
4
4
|
before the fork (June 2018):
|
|
5
|
-
Copyright (c) 2017 OpenAI (
|
|
5
|
+
Copyright (c) 2017 OpenAI (https://openai.com)
|
|
6
6
|
|
|
7
7
|
after the fork (June 2018):
|
|
8
8
|
Copyright (c) 2018-2019 Stable-Baselines Team
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stable_baselines3
|
|
3
|
-
Version: 2.9.
|
|
3
|
+
Version: 2.9.2
|
|
4
4
|
Summary: Pytorch version of Stable Baselines, implementations of reinforcement learning algorithms.
|
|
5
5
|
Home-page: https://github.com/DLR-RM/stable-baselines3
|
|
6
6
|
Author: Antonin Raffin
|
|
@@ -24,14 +24,12 @@ License-File: LICENSE
|
|
|
24
24
|
License-File: NOTICE
|
|
25
25
|
Requires-Dist: gymnasium<2.0,>=0.29.1
|
|
26
26
|
Requires-Dist: numpy<3.0,>=1.20
|
|
27
|
-
Requires-Dist: torch<3.0,>=2.
|
|
27
|
+
Requires-Dist: torch<3.0,>=2.8
|
|
28
28
|
Requires-Dist: cloudpickle
|
|
29
29
|
Provides-Extra: tests
|
|
30
30
|
Requires-Dist: pytest; extra == "tests"
|
|
31
31
|
Requires-Dist: pytest-cov; extra == "tests"
|
|
32
|
-
Requires-Dist:
|
|
33
|
-
Requires-Dist: pytest-xdist; extra == "tests"
|
|
34
|
-
Requires-Dist: mypy<2,>=1.9.0; extra == "tests"
|
|
32
|
+
Requires-Dist: mypy<3,>=1.9.0; extra == "tests"
|
|
35
33
|
Requires-Dist: ruff>=0.5.6; extra == "tests"
|
|
36
34
|
Requires-Dist: black<27,>=26.1.0; extra == "tests"
|
|
37
35
|
Provides-Extra: docs
|
|
@@ -116,7 +114,7 @@ vec_env = model.get_env()
|
|
|
116
114
|
obs = vec_env.reset()
|
|
117
115
|
for i in range(1000):
|
|
118
116
|
action, _states = model.predict(obs, deterministic=True)
|
|
119
|
-
obs,
|
|
117
|
+
obs, rewards, dones, info = vec_env.step(action)
|
|
120
118
|
vec_env.render()
|
|
121
119
|
# VecEnv resets automatically
|
|
122
120
|
# if done:
|
|
@@ -100,7 +100,7 @@ It provides a minimal number of features compared to SB3 but can be much faster
|
|
|
100
100
|
|
|
101
101
|
## Installation
|
|
102
102
|
|
|
103
|
-
**Note:** Stable-Baselines3 supports PyTorch >= 2.
|
|
103
|
+
**Note:** Stable-Baselines3 supports PyTorch >= 2.8
|
|
104
104
|
|
|
105
105
|
### Prerequisites
|
|
106
106
|
Stable Baselines3 requires Python 3.10+.
|
|
@@ -142,8 +142,8 @@ model.learn(total_timesteps=10_000)
|
|
|
142
142
|
vec_env = model.get_env()
|
|
143
143
|
obs = vec_env.reset()
|
|
144
144
|
for i in range(1000):
|
|
145
|
-
|
|
146
|
-
obs,
|
|
145
|
+
actions, _states = model.predict(obs, deterministic=True)
|
|
146
|
+
obs, rewards, dones, info = vec_env.step(actions)
|
|
147
147
|
vec_env.render()
|
|
148
148
|
# VecEnv resets automatically
|
|
149
149
|
# if done:
|
|
@@ -182,23 +182,28 @@ All the following examples can be executed online using Google Colab notebooks:
|
|
|
182
182
|
|
|
183
183
|
| **Name** | **Recurrent** | `Box` | `Discrete` | `MultiDiscrete` | `MultiBinary` | **Multi Processing** |
|
|
184
184
|
| ------------------- | ------------------ | ------------------ | ------------------ | ------------------- | ------------------ | --------------------------------- |
|
|
185
|
-
| ARS<sup>[1](#f1)</sup> | :x: | :heavy_check_mark: | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: |
|
|
186
185
|
| A2C | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
|
187
|
-
|
|
|
186
|
+
| ARS<sup>[1](#f1)</sup> | :x: | :heavy_check_mark: | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: |
|
|
187
|
+
| CrossQ<sup>[1](#f1)[2](#f2)</sup> | :x: | :heavy_check_mark: | :x: | :x: | :x: | :heavy_check_mark: |
|
|
188
188
|
| DDPG | :x: | :heavy_check_mark: | :x: | :x: | :x: | :heavy_check_mark: |
|
|
189
189
|
| DQN | :x: | :x: | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: |
|
|
190
|
+
| DroQ<sup>[2](#f2)</sup> | :x: | :heavy_check_mark: | :x: | :x: | :x: | :heavy_check_mark: |
|
|
190
191
|
| HER | :x: | :heavy_check_mark: | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: |
|
|
192
|
+
| Maskable PPO<sup>[1](#f1)</sup> | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
|
191
193
|
| PPO | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
|
192
194
|
| QR-DQN<sup>[1](#f1)</sup> | :x: | :x: | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: |
|
|
193
195
|
| RecurrentPPO<sup>[1](#f1)</sup> | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
|
194
196
|
| SAC | :x: | :heavy_check_mark: | :x: | :x: | :x: | :heavy_check_mark: |
|
|
197
|
+
| SAC-N<sup>[2](#f2)</sup> | :x: | :heavy_check_mark: | :x: | :x: | :x: | :heavy_check_mark: |
|
|
198
|
+
| SimBa<sup>[2](#f2)</sup> | :x: | :heavy_check_mark: | :x: | :x: | :x: | :heavy_check_mark: |
|
|
195
199
|
| TD3 | :x: | :heavy_check_mark: | :x: | :x: | :x: | :heavy_check_mark: |
|
|
196
200
|
| TQC<sup>[1](#f1)</sup> | :x: | :heavy_check_mark: | :x: | :x: | :x: | :heavy_check_mark: |
|
|
197
201
|
| TRPO<sup>[1](#f1)</sup> | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
|
198
|
-
| Maskable PPO<sup>[1](#f1)</sup> | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
|
|
199
202
|
|
|
200
203
|
<b id="f1">1</b>: Implemented in [SB3 Contrib](https://github.com/Stable-Baselines-Team/stable-baselines3-contrib) GitHub repository.
|
|
201
204
|
|
|
205
|
+
<b id="f2">2</b>: Implemented in [SBX (SB3 + Jax)](https://github.com/araffin/sbx)
|
|
206
|
+
|
|
202
207
|
Actions `gymnasium.spaces`:
|
|
203
208
|
* `Box`: A N-dimensional box that contains every point in the action space.
|
|
204
209
|
* `Discrete`: A list of possible actions, where only one action can be used per timestep.
|
|
@@ -256,7 +261,7 @@ To cite this repository in publications:
|
|
|
256
261
|
volume = {22},
|
|
257
262
|
number = {268},
|
|
258
263
|
pages = {1-8},
|
|
259
|
-
url = {
|
|
264
|
+
url = {https://jmlr.org/papers/v22/20-1364.html}
|
|
260
265
|
}
|
|
261
266
|
```
|
|
262
267
|
|
|
@@ -264,7 +269,7 @@ Note: If you need to refer to a specific version of SB3, you can also use the [Z
|
|
|
264
269
|
|
|
265
270
|
## Maintainers
|
|
266
271
|
|
|
267
|
-
Stable-Baselines3 is currently maintained by [Ashley Hill](https://github.com/hill-a) (aka @hill-a), [Antonin Raffin](https://araffin.github.io/) (aka [@araffin](https://github.com/araffin)), [Maximilian Ernestus](https://github.com/ernestum) (aka @ernestum), [Adam Gleave](https://github.com/adamgleave) (@AdamGleave), [Anssi Kanervisto](https://github.com/Miffyli) (@Miffyli) and [Quentin Gallouédec](https://
|
|
272
|
+
Stable-Baselines3 is currently maintained by [Ashley Hill](https://github.com/hill-a) (aka @hill-a), [Antonin Raffin](https://araffin.github.io/) (aka [@araffin](https://github.com/araffin)), [Maximilian Ernestus](https://github.com/ernestum) (aka @ernestum), [Adam Gleave](https://github.com/adamgleave) (@AdamGleave), [Anssi Kanervisto](https://github.com/Miffyli) (@Miffyli) and [Quentin Gallouédec](https://github.com/qgallouedec) (@qgallouedec).
|
|
268
273
|
|
|
269
274
|
**Important Note: We do not provide technical support, or consulting** and do not answer personal questions via email.
|
|
270
275
|
Please post your question on the [RL Discord](https://discord.com/invite/xhfNqQv), [Reddit](https://www.reddit.com/r/reinforcementlearning/), or [Stack Overflow](https://stackoverflow.com/) in that case.
|
|
@@ -279,7 +284,7 @@ If you want to contribute, please read [**CONTRIBUTING.md**](./CONTRIBUTING.md)
|
|
|
279
284
|
|
|
280
285
|
The initial work to develop Stable Baselines3 was partially funded by the project *Reduced Complexity Models* from the *Helmholtz-Gemeinschaft Deutscher Forschungszentren*, and by the EU Horizon 2020 Research and Innovation Programme under grant number 951992 ([VeriDream](https://www.veridream.eu/)).
|
|
281
286
|
|
|
282
|
-
The original version, Stable Baselines, was created in the [robotics lab U2IS](http://u2is.ensta-
|
|
287
|
+
The original version, Stable Baselines, was created in the [robotics lab U2IS](http://u2is.ensta-paris.fr/?lang=en) ([INRIA Flowers](https://flowers.inria.fr/) team) at [ENSTA ParisTech](https://www.ensta.fr/en).
|
|
283
288
|
|
|
284
289
|
|
|
285
290
|
Logo credits: [L.M. Tenkes](https://www.instagram.com/lucillehue/)
|
|
@@ -36,20 +36,23 @@ exclude = """(?x)(
|
|
|
36
36
|
|
|
37
37
|
[tool.pytest.ini_options]
|
|
38
38
|
# Deterministic ordering for tests; useful for pytest-xdist.
|
|
39
|
-
env = ["PYTHONHASHSEED=0"]
|
|
39
|
+
# env = ["PYTHONHASHSEED=0"]
|
|
40
40
|
|
|
41
41
|
filterwarnings = [
|
|
42
|
+
# multiprocessing and fork method, use of fork may lead to deadlocks
|
|
43
|
+
"ignore::DeprecationWarning:multiprocessing.popen_fork",
|
|
42
44
|
# A2C/PPO on GPU
|
|
43
45
|
"ignore:You are trying to run (PPO|A2C) on the GPU",
|
|
44
46
|
# Tensorboard warnings
|
|
45
47
|
"ignore::DeprecationWarning:tensorboard",
|
|
48
|
+
# Torch tensorboard numpy newshape deprecation
|
|
49
|
+
"ignore:`newshape` keyword argument is deprecated:DeprecationWarning:torch.utils.tensorboard._utils",
|
|
46
50
|
# Gymnasium warnings
|
|
47
51
|
"ignore::UserWarning:gymnasium",
|
|
52
|
+
# Taxi-v3 and CliffWalking-v0
|
|
53
|
+
"ignore::DeprecationWarning:gymnasium.envs.registration",
|
|
48
54
|
# tqdm warning about rich being experimental
|
|
49
55
|
"ignore:rich is experimental",
|
|
50
|
-
# Pygame warnings about pkg_resources
|
|
51
|
-
"ignore:pkg_resources is deprecated",
|
|
52
|
-
"ignore:Deprecated call to `pkg_resources",
|
|
53
56
|
]
|
|
54
57
|
markers = [
|
|
55
58
|
"expensive: marks tests as expensive (deselect with '-m \"not expensive\"')",
|
|
@@ -55,7 +55,7 @@ vec_env = model.get_env()
|
|
|
55
55
|
obs = vec_env.reset()
|
|
56
56
|
for i in range(1000):
|
|
57
57
|
action, _states = model.predict(obs, deterministic=True)
|
|
58
|
-
obs,
|
|
58
|
+
obs, rewards, dones, info = vec_env.step(action)
|
|
59
59
|
vec_env.render()
|
|
60
60
|
# VecEnv resets automatically
|
|
61
61
|
# if done:
|
|
@@ -81,7 +81,7 @@ setup(
|
|
|
81
81
|
install_requires=[
|
|
82
82
|
"gymnasium>=0.29.1,<2.0",
|
|
83
83
|
"numpy>=1.20,<3.0",
|
|
84
|
-
"torch>=2.
|
|
84
|
+
"torch>=2.8,<3.0",
|
|
85
85
|
# For saving models
|
|
86
86
|
"cloudpickle",
|
|
87
87
|
],
|
|
@@ -90,10 +90,8 @@ setup(
|
|
|
90
90
|
# Run tests and coverage
|
|
91
91
|
"pytest",
|
|
92
92
|
"pytest-cov",
|
|
93
|
-
"pytest-env",
|
|
94
|
-
"pytest-xdist",
|
|
95
93
|
# Type check
|
|
96
|
-
"mypy>=1.9.0,<
|
|
94
|
+
"mypy>=1.9.0,<3",
|
|
97
95
|
# Lint code and sort imports (flake8 and isort replacement)
|
|
98
96
|
"ruff>=0.5.6",
|
|
99
97
|
# Reformat
|
|
@@ -428,6 +428,7 @@ class TensorBoardOutputFormat(KVWriter):
|
|
|
428
428
|
self.writer.add_image(key, value.image, step, dataformats=value.dataformats)
|
|
429
429
|
|
|
430
430
|
if isinstance(value, HParam):
|
|
431
|
+
assert self.writer.file_writer is not None
|
|
431
432
|
# we don't use `self.writer.add_hparams` to have control over the log_dir
|
|
432
433
|
experiment, session_start_info, session_end_info = hparams(value.hparam_dict, metric_dict=value.metric_dict)
|
|
433
434
|
self.writer.file_writer.add_summary(experiment)
|
|
@@ -262,10 +262,10 @@ def load_results(path: str) -> "pandas.DataFrame":
|
|
|
262
262
|
# Only empty monitor files, return empty df
|
|
263
263
|
empty_df = pandas.DataFrame(columns=["r", "l", "t"])
|
|
264
264
|
# Create index to have the same columns
|
|
265
|
-
empty_df.reset_index(
|
|
265
|
+
empty_df = empty_df.reset_index()
|
|
266
266
|
return empty_df
|
|
267
267
|
data_frame = pandas.concat(data_frames)
|
|
268
|
-
data_frame.sort_values("t"
|
|
269
|
-
data_frame.reset_index(
|
|
268
|
+
data_frame = data_frame.sort_values("t")
|
|
269
|
+
data_frame = data_frame.reset_index()
|
|
270
270
|
data_frame["t"] -= min(header["t_start"] for header in headers)
|
|
271
271
|
return data_frame
|
|
@@ -51,7 +51,7 @@ class OrnsteinUhlenbeckActionNoise(ActionNoise):
|
|
|
51
51
|
"""
|
|
52
52
|
An Ornstein Uhlenbeck action noise, this is designed to approximate Brownian motion with friction.
|
|
53
53
|
|
|
54
|
-
Based on
|
|
54
|
+
Based on https://math.stackexchange.com/questions/1287634/implementing-ornstein-uhlenbeck-in-matlab
|
|
55
55
|
|
|
56
56
|
:param mean: Mean of the noise
|
|
57
57
|
:param sigma: Scale of the noise
|
|
@@ -52,6 +52,9 @@ class OffPolicyAlgorithm(BaseAlgorithm):
|
|
|
52
52
|
at a cost of more complexity.
|
|
53
53
|
See https://github.com/DLR-RM/stable-baselines3/issues/37#issuecomment-637501195
|
|
54
54
|
:param n_steps: When n_step > 1, uses n-step return (with the NStepReplayBuffer) when updating the Q-value network.
|
|
55
|
+
Note: it is only used when ``replay_buffer_class`` is ``None``, and is not supported for Dict
|
|
56
|
+
observation spaces yet. When passing a custom ``replay_buffer_class``, configure it directly
|
|
57
|
+
with ``replay_buffer_kwargs={"n_steps": ..., "gamma": ...}`` instead.
|
|
55
58
|
:param policy_kwargs: Additional arguments to be passed to the policy on creation
|
|
56
59
|
:param stats_window_size: Window size for the rollout logging, specifying the number of episodes to average
|
|
57
60
|
the reported success rate, mean episode length, and mean reward over
|
|
@@ -175,6 +178,15 @@ class OffPolicyAlgorithm(BaseAlgorithm):
|
|
|
175
178
|
self._setup_lr_schedule()
|
|
176
179
|
self.set_random_seed(self.seed)
|
|
177
180
|
|
|
181
|
+
if self.n_steps > 1 and self.replay_buffer_class is not None:
|
|
182
|
+
warnings.warn(
|
|
183
|
+
f"`n_steps={self.n_steps}` is ignored because a custom `replay_buffer_class` "
|
|
184
|
+
f"(`{self.replay_buffer_class.__name__}`) was passed: n-step returns are only set up "
|
|
185
|
+
"automatically when `replay_buffer_class` is `None`. "
|
|
186
|
+
"To use n-step returns with a custom replay buffer, configure it explicitly, e.g. "
|
|
187
|
+
f'`replay_buffer_kwargs={{"n_steps": {self.n_steps}, "gamma": {self.gamma}}}`.'
|
|
188
|
+
)
|
|
189
|
+
|
|
178
190
|
if self.replay_buffer_class is None:
|
|
179
191
|
if isinstance(self.observation_space, spaces.Dict):
|
|
180
192
|
self.replay_buffer_class = DictReplayBuffer
|
|
@@ -257,7 +257,7 @@ class BaseModel(nn.Module):
|
|
|
257
257
|
obs_ = np.array(obs)
|
|
258
258
|
vectorized_env = vectorized_env or is_vectorized_observation(obs_, obs_space)
|
|
259
259
|
# Add batch dimension if needed
|
|
260
|
-
observation[key] = obs_.reshape((-1, *self.observation_space[key].shape)) # type: ignore[misc]
|
|
260
|
+
observation[key] = obs_.reshape((-1, *self.observation_space[key].shape)) # type: ignore[misc, arg-type]
|
|
261
261
|
|
|
262
262
|
elif is_image_space(self.observation_space):
|
|
263
263
|
# Handle the different cases for images
|
|
@@ -271,7 +271,7 @@ class BaseModel(nn.Module):
|
|
|
271
271
|
# Dict obs need to be handled separately
|
|
272
272
|
vectorized_env = is_vectorized_observation(observation, self.observation_space)
|
|
273
273
|
# Add batch dimension if needed
|
|
274
|
-
observation = observation.reshape((-1, *self.observation_space.shape)) # type: ignore[misc]
|
|
274
|
+
observation = observation.reshape((-1, *self.observation_space.shape)) # type: ignore[misc, arg-type]
|
|
275
275
|
|
|
276
276
|
obs_tensor = obs_as_tensor(observation, self.device)
|
|
277
277
|
return obs_tensor, vectorized_env
|
|
@@ -367,7 +367,7 @@ class BasePolicy(BaseModel, ABC):
|
|
|
367
367
|
with th.no_grad():
|
|
368
368
|
actions = self._predict(obs_tensor, deterministic=deterministic)
|
|
369
369
|
# Convert to numpy, and reshape to the original action shape
|
|
370
|
-
actions = actions.cpu().numpy().reshape((-1, *self.action_space.shape)) # type: ignore[misc, assignment]
|
|
370
|
+
actions = actions.cpu().numpy().reshape((-1, *self.action_space.shape)) # type: ignore[misc, assignment, arg-type]
|
|
371
371
|
|
|
372
372
|
if isinstance(self.action_space, spaces.Box):
|
|
373
373
|
if self.squash_output:
|
|
@@ -20,7 +20,7 @@ class RMSpropTFLike(Optimizer):
|
|
|
20
20
|
- Initialize squared gradient to ones rather than zeros
|
|
21
21
|
|
|
22
22
|
Proposed by G. Hinton in his
|
|
23
|
-
`course <
|
|
23
|
+
`course <https://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf>`_.
|
|
24
24
|
|
|
25
25
|
The centered version first appears in `Generating Sequences
|
|
26
26
|
With Recurrent Neural Networks <https://arxiv.org/pdf/1308.0850v5.pdf>`_.
|
|
@@ -289,7 +289,7 @@ class VecEnv(ABC):
|
|
|
289
289
|
self.env_method("render")
|
|
290
290
|
return None
|
|
291
291
|
|
|
292
|
-
def seed(self, seed: int | None = None) -> Sequence[
|
|
292
|
+
def seed(self, seed: int | None = None) -> Sequence[int | None]:
|
|
293
293
|
"""
|
|
294
294
|
Sets the random seeds for all environments, based on a given seed.
|
|
295
295
|
Each individual environment will still get its own seed, by incrementing the given seed.
|
|
@@ -392,7 +392,7 @@ class VecEnvWrapper(VecEnv):
|
|
|
392
392
|
def step_wait(self) -> VecEnvStepReturn:
|
|
393
393
|
pass
|
|
394
394
|
|
|
395
|
-
def seed(self, seed: int | None = None) -> Sequence[
|
|
395
|
+
def seed(self, seed: int | None = None) -> Sequence[int | None]:
|
|
396
396
|
return self.venv.seed(seed)
|
|
397
397
|
|
|
398
398
|
def set_options(self, options: list[dict] | dict | None = None) -> None:
|
|
@@ -159,6 +159,12 @@ class SubprocVecEnv(VecEnv):
|
|
|
159
159
|
remote.send(("close", None))
|
|
160
160
|
for process in self.processes:
|
|
161
161
|
process.join()
|
|
162
|
+
# Close the parent side of the pipes: otherwise the sockets stay open
|
|
163
|
+
# until this instance (and its ``remotes``) is garbage collected,
|
|
164
|
+
# which can exhaust the file-descriptor limit (``Too many open files``)
|
|
165
|
+
# in long-running loops (e.g. hyperparameter optimization).
|
|
166
|
+
for remote in self.remotes:
|
|
167
|
+
remote.close()
|
|
162
168
|
self.closed = True
|
|
163
169
|
|
|
164
170
|
def get_images(self) -> Sequence[np.ndarray | None]:
|
|
@@ -15,7 +15,7 @@ class DDPG(TD3):
|
|
|
15
15
|
"""
|
|
16
16
|
Deep Deterministic Policy Gradient (DDPG).
|
|
17
17
|
|
|
18
|
-
Deterministic Policy Gradient:
|
|
18
|
+
Deterministic Policy Gradient: https://proceedings.mlr.press/v32/silver14.pdf
|
|
19
19
|
DDPG Paper: https://arxiv.org/abs/1509.02971
|
|
20
20
|
Introduction to DDPG: https://spinningup.openai.com/en/latest/algorithms/ddpg.html
|
|
21
21
|
|
|
@@ -45,6 +45,9 @@ class DDPG(TD3):
|
|
|
45
45
|
at a cost of more complexity.
|
|
46
46
|
See https://github.com/DLR-RM/stable-baselines3/issues/37#issuecomment-637501195
|
|
47
47
|
:param n_steps: When n_step > 1, uses n-step return (with the NStepReplayBuffer) when updating the Q-value network.
|
|
48
|
+
Note: it is only used when ``replay_buffer_class`` is ``None``, and is not supported for Dict
|
|
49
|
+
observation spaces yet. When passing a custom ``replay_buffer_class``, configure it directly
|
|
50
|
+
with ``replay_buffer_kwargs={"n_steps": ..., "gamma": ...}`` instead.
|
|
48
51
|
:param policy_kwargs: additional arguments to be passed to the policy on creation. See :ref:`ddpg_policies`
|
|
49
52
|
:param verbose: Verbosity level: 0 for no output, 1 for info messages (such as device or wrappers used), 2 for
|
|
50
53
|
debug messages
|
|
@@ -45,6 +45,9 @@ class DQN(OffPolicyAlgorithm):
|
|
|
45
45
|
at a cost of more complexity.
|
|
46
46
|
See https://github.com/DLR-RM/stable-baselines3/issues/37#issuecomment-637501195
|
|
47
47
|
:param n_steps: When n_step > 1, uses n-step return (with the NStepReplayBuffer) when updating the Q-value network.
|
|
48
|
+
Note: it is only used when ``replay_buffer_class`` is ``None``, and is not supported for Dict
|
|
49
|
+
observation spaces yet. When passing a custom ``replay_buffer_class``, configure it directly
|
|
50
|
+
with ``replay_buffer_kwargs={"n_steps": ..., "gamma": ...}`` instead.
|
|
48
51
|
:param target_update_interval: update the target network every ``target_update_interval``
|
|
49
52
|
environment steps.
|
|
50
53
|
:param exploration_fraction: fraction of entire training period over which the exploration rate is reduced
|
|
@@ -88,7 +88,7 @@ class PPO(OnPolicyAlgorithm):
|
|
|
88
88
|
gamma: float = 0.99,
|
|
89
89
|
gae_lambda: float = 0.95,
|
|
90
90
|
clip_range: float | Schedule = 0.2,
|
|
91
|
-
clip_range_vf:
|
|
91
|
+
clip_range_vf: float | Schedule | None = None,
|
|
92
92
|
normalize_advantage: bool = True,
|
|
93
93
|
ent_coef: float = 0.0,
|
|
94
94
|
vf_coef: float = 0.5,
|
|
@@ -54,6 +54,9 @@ class SAC(OffPolicyAlgorithm):
|
|
|
54
54
|
at a cost of more complexity.
|
|
55
55
|
See https://github.com/DLR-RM/stable-baselines3/issues/37#issuecomment-637501195
|
|
56
56
|
:param n_steps: When n_step > 1, uses n-step return (with the NStepReplayBuffer) when updating the Q-value network.
|
|
57
|
+
Note: it is only used when ``replay_buffer_class`` is ``None``, and is not supported for Dict
|
|
58
|
+
observation spaces yet. When passing a custom ``replay_buffer_class``, configure it directly
|
|
59
|
+
with ``replay_buffer_kwargs={"n_steps": ..., "gamma": ...}`` instead.
|
|
57
60
|
:param ent_coef: Entropy regularization coefficient. (Equivalent to
|
|
58
61
|
inverse of reward scale in the original SAC paper.) Controlling exploration/exploitation trade-off.
|
|
59
62
|
Set it to 'auto' to learn it automatically (and 'auto_0.1' for using 0.1 as initial value)
|
|
@@ -49,6 +49,9 @@ class TD3(OffPolicyAlgorithm):
|
|
|
49
49
|
at a cost of more complexity.
|
|
50
50
|
See https://github.com/DLR-RM/stable-baselines3/issues/37#issuecomment-637501195
|
|
51
51
|
:param n_steps: When n_step > 1, uses n-step return (with the NStepReplayBuffer) when updating the Q-value network.
|
|
52
|
+
Note: it is only used when ``replay_buffer_class`` is ``None``, and is not supported for Dict
|
|
53
|
+
observation spaces yet. When passing a custom ``replay_buffer_class``, configure it directly
|
|
54
|
+
with ``replay_buffer_kwargs={"n_steps": ..., "gamma": ...}`` instead.
|
|
52
55
|
:param policy_delay: Policy and target networks will only be updated once every policy_delay steps
|
|
53
56
|
per training steps. The Q values will be updated policy_delay more often (update every training step).
|
|
54
57
|
:param target_policy_noise: Standard deviation of Gaussian noise added to target policy
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.9.2
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stable_baselines3
|
|
3
|
-
Version: 2.9.
|
|
3
|
+
Version: 2.9.2
|
|
4
4
|
Summary: Pytorch version of Stable Baselines, implementations of reinforcement learning algorithms.
|
|
5
5
|
Home-page: https://github.com/DLR-RM/stable-baselines3
|
|
6
6
|
Author: Antonin Raffin
|
|
@@ -24,14 +24,12 @@ License-File: LICENSE
|
|
|
24
24
|
License-File: NOTICE
|
|
25
25
|
Requires-Dist: gymnasium<2.0,>=0.29.1
|
|
26
26
|
Requires-Dist: numpy<3.0,>=1.20
|
|
27
|
-
Requires-Dist: torch<3.0,>=2.
|
|
27
|
+
Requires-Dist: torch<3.0,>=2.8
|
|
28
28
|
Requires-Dist: cloudpickle
|
|
29
29
|
Provides-Extra: tests
|
|
30
30
|
Requires-Dist: pytest; extra == "tests"
|
|
31
31
|
Requires-Dist: pytest-cov; extra == "tests"
|
|
32
|
-
Requires-Dist:
|
|
33
|
-
Requires-Dist: pytest-xdist; extra == "tests"
|
|
34
|
-
Requires-Dist: mypy<2,>=1.9.0; extra == "tests"
|
|
32
|
+
Requires-Dist: mypy<3,>=1.9.0; extra == "tests"
|
|
35
33
|
Requires-Dist: ruff>=0.5.6; extra == "tests"
|
|
36
34
|
Requires-Dist: black<27,>=26.1.0; extra == "tests"
|
|
37
35
|
Provides-Extra: docs
|
|
@@ -116,7 +114,7 @@ vec_env = model.get_env()
|
|
|
116
114
|
obs = vec_env.reset()
|
|
117
115
|
for i in range(1000):
|
|
118
116
|
action, _states = model.predict(obs, deterministic=True)
|
|
119
|
-
obs,
|
|
117
|
+
obs, rewards, dones, info = vec_env.step(action)
|
|
120
118
|
vec_env.render()
|
|
121
119
|
# VecEnv resets automatically
|
|
122
120
|
# if done:
|
{stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3.egg-info/requires.txt
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
gymnasium<2.0,>=0.29.1
|
|
2
2
|
numpy<3.0,>=1.20
|
|
3
|
-
torch<3.0,>=2.
|
|
3
|
+
torch<3.0,>=2.8
|
|
4
4
|
cloudpickle
|
|
5
5
|
|
|
6
6
|
[docs]
|
|
@@ -26,8 +26,6 @@ matplotlib
|
|
|
26
26
|
[tests]
|
|
27
27
|
pytest
|
|
28
28
|
pytest-cov
|
|
29
|
-
|
|
30
|
-
pytest-xdist
|
|
31
|
-
mypy<2,>=1.9.0
|
|
29
|
+
mypy<3,>=1.9.0
|
|
32
30
|
ruff>=0.5.6
|
|
33
31
|
black<27,>=26.1.0
|
|
@@ -133,12 +133,19 @@ def test_features_extractor_target_net(model_class, share_features_extractor):
|
|
|
133
133
|
if model_class == DQN and share_features_extractor:
|
|
134
134
|
pytest.skip()
|
|
135
135
|
|
|
136
|
-
env = FakeImageEnv(screen_height=
|
|
136
|
+
env = FakeImageEnv(screen_height=36, screen_width=36, n_channels=1, discrete=model_class not in {SAC, TD3})
|
|
137
137
|
# Avoid memory error when using replay buffer
|
|
138
138
|
# Reduce the size of the features
|
|
139
|
-
kwargs = dict(
|
|
139
|
+
kwargs = dict(
|
|
140
|
+
buffer_size=100,
|
|
141
|
+
learning_starts=50,
|
|
142
|
+
policy_kwargs=dict(features_extractor_kwargs=dict(features_dim=8)),
|
|
143
|
+
learning_rate=1e-3,
|
|
144
|
+
)
|
|
140
145
|
if model_class != DQN:
|
|
141
146
|
kwargs["policy_kwargs"]["share_features_extractor"] = share_features_extractor
|
|
147
|
+
else:
|
|
148
|
+
kwargs["target_update_interval"] = 10
|
|
142
149
|
|
|
143
150
|
# No delay for TD3 (changes when the actor and polyak update take place)
|
|
144
151
|
if model_class == TD3:
|
|
@@ -172,7 +179,7 @@ def test_features_extractor_target_net(model_class, share_features_extractor):
|
|
|
172
179
|
if model_class == TD3:
|
|
173
180
|
params_should_match(model.actor.parameters(), model.actor_target.parameters())
|
|
174
181
|
|
|
175
|
-
model.learn(
|
|
182
|
+
model.learn(100)
|
|
176
183
|
|
|
177
184
|
# Critic and target should differ
|
|
178
185
|
params_should_differ(model.critic.parameters(), model.critic_target.parameters())
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import importlib.util
|
|
2
1
|
import json
|
|
3
2
|
import os
|
|
4
3
|
import sys
|
|
@@ -273,7 +272,14 @@ def test_report_video_to_tensorboard(tmp_path, read_log, capsys):
|
|
|
273
272
|
|
|
274
273
|
|
|
275
274
|
def is_moviepy_installed():
|
|
276
|
-
|
|
275
|
+
try:
|
|
276
|
+
import moviepy
|
|
277
|
+
|
|
278
|
+
# PyTorch doesn't support moviepy >= 2.0
|
|
279
|
+
# See: https://github.com/pytorch/pytorch/issues/147317
|
|
280
|
+
return moviepy.__version__ < "2.0"
|
|
281
|
+
except (ImportError, AttributeError):
|
|
282
|
+
return False
|
|
277
283
|
|
|
278
284
|
|
|
279
285
|
@pytest.mark.parametrize("unsupported_format", ["stdout", "log", "json", "csv"])
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
|
|
1
3
|
import gymnasium as gym
|
|
2
4
|
import numpy as np
|
|
3
5
|
import pytest
|
|
4
6
|
|
|
5
7
|
from stable_baselines3 import DQN, SAC, TD3
|
|
6
|
-
from stable_baselines3.common.buffers import NStepReplayBuffer, ReplayBuffer
|
|
8
|
+
from stable_baselines3.common.buffers import DictReplayBuffer, NStepReplayBuffer, ReplayBuffer
|
|
7
9
|
from stable_baselines3.common.env_util import make_vec_env
|
|
10
|
+
from stable_baselines3.common.envs import BitFlippingEnv
|
|
11
|
+
from stable_baselines3.her import HerReplayBuffer
|
|
8
12
|
|
|
9
13
|
|
|
10
14
|
@pytest.mark.parametrize("model_class", [SAC, DQN, TD3])
|
|
@@ -30,6 +34,47 @@ def test_run(model_class):
|
|
|
30
34
|
model.learn(total_timesteps=150)
|
|
31
35
|
|
|
32
36
|
|
|
37
|
+
@pytest.mark.parametrize("replay_buffer_class", [ReplayBuffer, NStepReplayBuffer])
|
|
38
|
+
def test_n_steps_warns_with_custom_replay_buffer_class(replay_buffer_class):
|
|
39
|
+
"""`n_steps > 1` is ignored when the buffer class is user-provided, so it must warn."""
|
|
40
|
+
with pytest.warns(UserWarning, match="n_steps=3"):
|
|
41
|
+
model = SAC("MlpPolicy", "Pendulum-v1", n_steps=3, buffer_size=200, replay_buffer_class=replay_buffer_class)
|
|
42
|
+
# The buffer is built from the user-provided class, untouched by `n_steps`
|
|
43
|
+
assert type(model.replay_buffer) is replay_buffer_class
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@pytest.mark.parametrize("replay_buffer_class", [None, DictReplayBuffer, HerReplayBuffer])
|
|
47
|
+
def test_n_steps_with_dict_obs(replay_buffer_class):
|
|
48
|
+
"""Dict observation spaces do not support n-step returns: assert on the default path, warn otherwise."""
|
|
49
|
+
env = BitFlippingEnv(n_bits=4, continuous=True)
|
|
50
|
+
if replay_buffer_class is None:
|
|
51
|
+
with pytest.raises(AssertionError, match="Dict observation spaces"):
|
|
52
|
+
SAC("MultiInputPolicy", env, n_steps=3, buffer_size=200)
|
|
53
|
+
else:
|
|
54
|
+
with pytest.warns(UserWarning, match="n_steps=3"):
|
|
55
|
+
SAC("MultiInputPolicy", env, n_steps=3, buffer_size=200, replay_buffer_class=replay_buffer_class)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_n_steps_custom_class_no_warnings():
|
|
59
|
+
with warnings.catch_warnings():
|
|
60
|
+
warnings.simplefilter("error")
|
|
61
|
+
# Note: values must differ from ``NStepReplayBuffer`` defaults (n_steps=3, gamma=0.99)
|
|
62
|
+
# otherwise the assertions below would pass even if nothing was applied.
|
|
63
|
+
model = SAC(
|
|
64
|
+
"MlpPolicy",
|
|
65
|
+
"Pendulum-v1",
|
|
66
|
+
buffer_size=200,
|
|
67
|
+
replay_buffer_class=NStepReplayBuffer,
|
|
68
|
+
replay_buffer_kwargs={"n_steps": 4, "gamma": 0.95},
|
|
69
|
+
)
|
|
70
|
+
assert isinstance(model.replay_buffer, NStepReplayBuffer)
|
|
71
|
+
assert model.replay_buffer.n_steps == 4
|
|
72
|
+
assert model.replay_buffer.gamma == 0.95
|
|
73
|
+
|
|
74
|
+
# Default n-steps
|
|
75
|
+
SAC("MlpPolicy", "Pendulum-v1", buffer_size=200, replay_buffer_class=ReplayBuffer)
|
|
76
|
+
|
|
77
|
+
|
|
33
78
|
def create_buffer(buffer_size=10, n_steps=3, gamma=0.99, n_envs=1):
|
|
34
79
|
obs_space = gym.spaces.Box(low=0, high=1, shape=(4,), dtype=np.float32)
|
|
35
80
|
act_space = gym.spaces.Box(low=0, high=1, shape=(2,), dtype=np.float32)
|
|
@@ -891,3 +891,34 @@ def test_save_load_clip_range_portable(tmp_path, model_class):
|
|
|
891
891
|
assert isinstance(model.clip_range, FloatSchedule)
|
|
892
892
|
assert isinstance(model.clip_range.value_schedule, ConstantSchedule)
|
|
893
893
|
assert model.clip_range.value_schedule.val == 0.2
|
|
894
|
+
|
|
895
|
+
|
|
896
|
+
def test_load_bad_zip(tmp_path):
|
|
897
|
+
"""Test that loading a non-zip file raises a ValueError."""
|
|
898
|
+
# Write a plain text file to the path
|
|
899
|
+
bad_path = tmp_path / "not_a_zip.zip"
|
|
900
|
+
bad_path.write_text("this is not a zip file")
|
|
901
|
+
|
|
902
|
+
with pytest.raises(ValueError, match="wasn't a zip-file"):
|
|
903
|
+
PPO.load(str(bad_path))
|
|
904
|
+
|
|
905
|
+
|
|
906
|
+
@pytest.mark.filterwarnings("error::ResourceWarning")
|
|
907
|
+
def test_open_path_directory_and_missing_parent(tmp_path):
|
|
908
|
+
"""Test IsADirectoryError and FileNotFoundError handling in open_path."""
|
|
909
|
+
# Test IsADirectoryError: path already has the suffix and is a folder
|
|
910
|
+
dir_path = tmp_path / "is_a_folder.pkl"
|
|
911
|
+
dir_path.mkdir()
|
|
912
|
+
with warnings.catch_warnings(record=True) as record:
|
|
913
|
+
open_path(dir_path, "w", suffix="pkl").close()
|
|
914
|
+
assert any("is a folder" in str(warning.message) for warning in record)
|
|
915
|
+
# Verify the fallback file was created
|
|
916
|
+
assert (tmp_path / "is_a_folder.pkl_2").exists()
|
|
917
|
+
|
|
918
|
+
# Test FileNotFoundError: parent folder doesn't exist
|
|
919
|
+
missing_parent_path = tmp_path / "nonexistent_parent" / "sub" / "file"
|
|
920
|
+
with warnings.catch_warnings(record=True) as record:
|
|
921
|
+
open_path(missing_parent_path, "w", suffix="pkl").close()
|
|
922
|
+
assert any("does not exist" in str(warning.message) for warning in record)
|
|
923
|
+
# Verify the parent was created and file was written
|
|
924
|
+
assert (tmp_path / "nonexistent_parent" / "sub" / "file.pkl").exists()
|
|
@@ -123,7 +123,8 @@ def test_sde_multi_dim():
|
|
|
123
123
|
@pytest.mark.parametrize("model_class", [A2C, PPO, DQN])
|
|
124
124
|
@pytest.mark.parametrize("env", ["Taxi-v3"])
|
|
125
125
|
def test_discrete_obs_space(model_class, env):
|
|
126
|
-
|
|
126
|
+
|
|
127
|
+
env = _make_env_safe(env, n_envs=2, seed=0)
|
|
127
128
|
kwargs = {}
|
|
128
129
|
if model_class == DQN:
|
|
129
130
|
kwargs = dict(buffer_size=1000, learning_starts=100)
|
|
@@ -173,3 +174,17 @@ def test_multidim_binary_not_supported():
|
|
|
173
174
|
env = DummyEnv(BOX_SPACE_FLOAT32, spaces.MultiBinary([2, 3]))
|
|
174
175
|
with pytest.raises(AssertionError, match=r"Multi-dimensional MultiBinary\(.*\) action space is not supported"):
|
|
175
176
|
A2C("MlpPolicy", env)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def _make_env_safe(env_id, **kwargs):
|
|
180
|
+
try:
|
|
181
|
+
return make_vec_env(env_id, **kwargs)
|
|
182
|
+
except gym.error.DeprecatedEnv:
|
|
183
|
+
# map deprecated to new (better extendability for this)
|
|
184
|
+
fallback_map = {
|
|
185
|
+
# as of gymnasium 1.3.0 Taxi-v3 is deprecated
|
|
186
|
+
"Taxi-v3": "Taxi-v4",
|
|
187
|
+
}
|
|
188
|
+
if env_id in fallback_map:
|
|
189
|
+
return make_vec_env(fallback_map[env_id], **kwargs)
|
|
190
|
+
raise
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import pickle
|
|
2
3
|
import shutil
|
|
3
4
|
|
|
4
5
|
import ale_py
|
|
@@ -15,6 +16,7 @@ from stable_baselines3.common.env_util import is_wrapped, make_atari_env, make_v
|
|
|
15
16
|
from stable_baselines3.common.evaluation import evaluate_policy
|
|
16
17
|
from stable_baselines3.common.monitor import Monitor
|
|
17
18
|
from stable_baselines3.common.noise import OrnsteinUhlenbeckActionNoise, VectorizedActionNoise
|
|
19
|
+
from stable_baselines3.common.sb2_compat.rmsprop_tf_like import RMSpropTFLike
|
|
18
20
|
from stable_baselines3.common.utils import (
|
|
19
21
|
ConstantSchedule,
|
|
20
22
|
FloatSchedule,
|
|
@@ -628,3 +630,57 @@ def test_deprecated_schedules():
|
|
|
628
630
|
assert np.allclose(fn(0.5), schedule(0.5))
|
|
629
631
|
assert np.allclose(fn(0.5), float_schedule(0.5))
|
|
630
632
|
assert np.allclose(fn(0.5), float_schedule_2(0.5))
|
|
633
|
+
|
|
634
|
+
|
|
635
|
+
class TestRMSpropTFLike:
|
|
636
|
+
"""Tests for the RMSpropTFLike optimizer (sb2_compat)."""
|
|
637
|
+
|
|
638
|
+
def test_invalid_params(self):
|
|
639
|
+
"""Test that invalid optimizer parameters raise ValueError."""
|
|
640
|
+
param = th.nn.Parameter(th.zeros(2))
|
|
641
|
+
with pytest.raises(ValueError, match="Invalid learning rate"):
|
|
642
|
+
RMSpropTFLike([param], lr=-1.0)
|
|
643
|
+
with pytest.raises(ValueError, match="Invalid epsilon"):
|
|
644
|
+
RMSpropTFLike([param], eps=-1.0)
|
|
645
|
+
with pytest.raises(ValueError, match="Invalid momentum"):
|
|
646
|
+
RMSpropTFLike([param], momentum=-1.0)
|
|
647
|
+
with pytest.raises(ValueError, match="Invalid weight_decay"):
|
|
648
|
+
RMSpropTFLike([param], weight_decay=-1.0)
|
|
649
|
+
with pytest.raises(ValueError, match="Invalid alpha"):
|
|
650
|
+
RMSpropTFLike([param], alpha=-1.0)
|
|
651
|
+
|
|
652
|
+
def test_centered_momentum_weight_decay(self):
|
|
653
|
+
"""Test centered=True, momentum>0, weight_decay>0 branches in step()."""
|
|
654
|
+
param = th.nn.Parameter(th.tensor([1.0, 2.0]))
|
|
655
|
+
opt = RMSpropTFLike(
|
|
656
|
+
[param],
|
|
657
|
+
lr=0.1,
|
|
658
|
+
momentum=0.9,
|
|
659
|
+
alpha=0.99,
|
|
660
|
+
eps=1e-8,
|
|
661
|
+
centered=True,
|
|
662
|
+
weight_decay=0.01,
|
|
663
|
+
)
|
|
664
|
+
# Compute gradient
|
|
665
|
+
loss = (param**2).sum()
|
|
666
|
+
loss.backward()
|
|
667
|
+
|
|
668
|
+
# Run step with closure (covers closure branch)
|
|
669
|
+
def closure():
|
|
670
|
+
param.grad.zero_()
|
|
671
|
+
return float((param**2).sum().detach())
|
|
672
|
+
|
|
673
|
+
opt.step(closure=closure)
|
|
674
|
+
# Check state keys exist (covers centered + momentum init)
|
|
675
|
+
state = opt.state[param]
|
|
676
|
+
assert "grad_avg" in state # centered=True
|
|
677
|
+
assert "momentum_buffer" in state # momentum > 0
|
|
678
|
+
|
|
679
|
+
def test_pickle_roundtrip(self):
|
|
680
|
+
"""Test that optimizer survives pickle roundtrip (covers __setstate__)."""
|
|
681
|
+
param = th.nn.Parameter(th.tensor([1.0, 2.0]))
|
|
682
|
+
opt = RMSpropTFLike([param], lr=0.1, momentum=0.5, centered=True)
|
|
683
|
+
opt2 = pickle.loads(pickle.dumps(opt))
|
|
684
|
+
assert opt2.param_groups[0]["lr"] == 0.1
|
|
685
|
+
assert opt2.param_groups[0]["momentum"] == 0.5
|
|
686
|
+
assert opt2.param_groups[0]["centered"] is True
|
|
@@ -317,7 +317,7 @@ def check_vecenv_obs(obs, space):
|
|
|
317
317
|
assert space.contains(value)
|
|
318
318
|
|
|
319
319
|
|
|
320
|
-
@pytest.mark.parametrize("vec_env_class,space", itertools.product(VEC_ENV_CLASSES, SPACES.values()))
|
|
320
|
+
@pytest.mark.parametrize("vec_env_class,space", list(itertools.product(VEC_ENV_CLASSES, SPACES.values())))
|
|
321
321
|
def test_vecenv_single_space(vec_env_class, space):
|
|
322
322
|
def obs_assert(obs):
|
|
323
323
|
return check_vecenv_obs(obs, space)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2.9.0a2
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/atari_wrappers.py
RENAMED
|
File without changes
|
{stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/base_class.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/distributions.py
RENAMED
|
File without changes
|
{stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/env_checker.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/envs/identity_env.py
RENAMED
|
File without changes
|
|
File without changes
|
{stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/evaluation.py
RENAMED
|
File without changes
|
|
File without changes
|
{stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/preprocessing.py
RENAMED
|
File without changes
|
{stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/results_plotter.py
RENAMED
|
File without changes
|
{stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/running_mean_std.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/torch_layers.py
RENAMED
|
File without changes
|
{stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/type_aliases.py
RENAMED
|
File without changes
|
|
File without changes
|
{stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/vec_env/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/vec_env/patch_gym.py
RENAMED
|
File without changes
|
|
File without changes
|
{stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/common/vec_env/util.py
RENAMED
|
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
|
{stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3/her/her_replay_buffer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{stable_baselines3-2.9.0a2 → stable_baselines3-2.9.2}/stable_baselines3.egg-info/top_level.txt
RENAMED
|
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
|