Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dictionary Observations #243

Merged
merged 96 commits into from
May 11, 2021
Merged

Conversation

J-Travnik
Copy link
Contributor

@J-Travnik J-Travnik commented Nov 24, 2020

In machine learning, input comes in the form of matrices. Typically, models take in 1 matrix at a time, such as in the case of image classification where matrix containing the input image is given to the model and the model classifies the image.
However, there are many situations in which taking multiple inputs is necessary. One example is when training a reinforcement learning agent and the observations that the agent sees comes in the form of an image (e.g., camera, grid sensor, etc) and a vector describing the agent's state (e.g., current position, health, etc). In this situation, it is necessary to feed 2 inputs to the model. This PR addresses this.

Description

  • added example environments with multi-input observations
  • added DictReplayBuffer and DictRolloutBuffer to handle dictionaries
  • added CombinedExtractor feature extractor that handles generic dictionary data
  • added StackedObservations and StackedDictObservations to decouple data stacking from the VecFrameStack wrapper
  • added test_dict_env.py test
  • added a is_vectorized_env() method per observation space type in common\utils.py

Motivation and Context

  • I have raised an issue to propose this change (link)

closes #216

closes #287 (image support for HER)
closes #284 (for off-policy algorithms)

Types of changes

  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation (update in the documentation)

Checklist:

  • I've read the CONTRIBUTION guide (required)
  • I have updated the changelog accordingly (required).
  • My change requires a change to the documentation.
  • I have updated the tests accordingly
  • I have updated the documentation accordingly.
  • I have reformatted the code using make format
  • I have checked the codestyle using make check-codestyle and make lint
  • I have ensured make pytest and make type both pass. (required)
  • I have checked that the documentation builds using make doc (required)

TODOs

@Miffyli
Copy link
Collaborator

Miffyli commented Nov 24, 2020

Quick comment before further commits: Make sure your formatter has line lengths set to 127, not 80. Seems like your formatter is splitting lines of allowed length (e.g. this one). black runs perfectly on windows with simple pip install black and then black -l 127.

@J-Travnik
Copy link
Contributor Author

@araffin

After a quick look, I'm not sure we need that much complexity.
You could probably use the BitFlippingEnv together with a small dummy Custom Env.

Thats a good point though, I did want to make sure that it worked with Images though as that was my main use case. I think its important to cover this case (at least in a test) to make sure that VecEnvStacking and multiple environments all played well together when using images. Thoughts?

it would nice to have at least one common "combined extractor " for the Box.

I agree though I still see value in having the option to separate them. Perhaps this could come in the form of a bool with true default of "auto_concatenate_box_obs".

After a quick look at your PR, I think it would be better to almost duplicate the buffer classes, because having too many branches (with the if else) is hard to follow.

Hmm, that seems like a decent idea. Specifically you mean to create:

class DictReplayBuffer(ReplayBuffer):...

class DictRolloutBuffer(RolloutBuffer):...

?

I can run it on my side if you want and push the results. But it would be better for you to setup black and isort at least (you can take a look at the makefile for the details of the commands).

Yea, that'd be awesome. I will figure out black and stuff on my end. @Miffyli thanks for the pointer!

@araffin
Copy link
Member

araffin commented Nov 24, 2020

I think its important to cover this case (at least in a test) to make sure that VecEnvStacking and multiple environments all played well together when using images. Thoughts?

two things: if you want to test performances, then you need your environment (but we may skip the test if it is slow to run).
If you want only to check that the code run, you can use a dummy env that outputs dummy images like this one: https://github.com/DLR-RM/stable-baselines3/blob/master/stable_baselines3/common/identity_env.py#L107
And of course, we want to check that it runs at least with different type of input (otherwise we could just use a "flatten" wrapper).

So, yes, we need to test performance to validate the implementation, but I would not run the test for each commit (maybe use pytest.mark.slow to skip it).

. Perhaps this could come in the form of a bool with true default of "auto_concatenate_box_obs".

sounds like a good compromise.

Hmm, that seems like a decent idea. Specifically you mean to create:

yes!

@Miffyli
Copy link
Collaborator

Miffyli commented Nov 24, 2020

I agree though I still see value in having the option to separate them. Perhaps this could come in the form of a bool with true default of "auto_concatenate_box_obs".

sounds like a good compromise.

After bit of internal discussion we can leave this out completely for now. We can tell people to do stacking on the environment side (or alternatively provide some wrapper that concatenates arrays of specific keys together). Less messy code to worry about (e.g. images of different resolution).

Bit of a heads up: This update would be very desired (I would be using it actively, too!), but being a big change there will be bunch of reviewing and comments ^^.

@araffin araffin added this to the v1.1 milestone Nov 24, 2020
@araffin araffin mentioned this pull request Nov 24, 2020
42 tasks
@J-Travnik
Copy link
Contributor Author

@Miffyli Yea, no worries. I'd rather take the time and to review and fix changes to figure out something that is stable.

And fair enough on the "auto_concatenate_box_obs". Potentially it can take the form of a VecEnv wrapper so that the tensors passed to the CombinedExtractor can be used readily.

@H-Park
Copy link

H-Park commented Nov 26, 2020

Tentative timeframe of this getting merged? I need this feature to start the literature grounded action masking PR

@Miffyli
Copy link
Collaborator

Miffyli commented Nov 26, 2020

@H-Park We will first do first release (v1.0) properly before merging this, soooo most daring estimate is just before end of the year, but more likely in the beginning of January.

On preliminary glances this looks overall the way that things will work, so I would semi-reliably say you can base your work on how things work in @J-Travnik's branch :). Do note that I am not 100% sure action-space masking should be included in the main repo here or in contrib repo. A fresh discussion on topic with new papers/results would be appropriate.

@araffin
Copy link
Member

araffin commented Nov 26, 2020

@J-Travnik I reformated the code and corrected one typing issue in preprocessing, however, it complains about VecFrameStack now
I also fixed the check for HER, so the tests for HER should pass now ;)

@H-Park there is no deadline for this feature (at least after v1.0), it will take some time to have a working and clean solution.
But in the meantime, you could start working on @J-Travnik branch ;) (even though it may change).

EDIT: I did a first pass on the code, I will do another one once you have separated the buffers (quite hard to read for now)

multi_input_tests.py Outdated Show resolved Hide resolved
@J-Travnik
Copy link
Contributor Author

I added DictReplayBuffer and DictRolloutBuffer so that there is only one "if" statement in the policy to choose which one. They are child classes of their respective parents so the typing is preserved throughout the code base.
I'll go back and update the documentation for them probably early next week.

test_offpolicy_normalization fails now but only for HER and I am not completely sure why yet but I feel like there is an assumption of having ObsDictWrapper somewhere.

Going forward, what should the usage of the ObsDictWrapper be if dict observations can be handled by buffers?
I think there are some functions in the ObsDictWrapper that can be moved to a util script but in general I am not sure.

@araffin
Copy link
Member

araffin commented Nov 27, 2020

quick remark: black is run with a line length of 127 (cf contrib guide and PR template)
also, please use the latest version of it

EDIT: and we run isort too

Miffyli and others added 4 commits April 23, 2021 02:13
* Start refactoring HER

* Fixes

* Additional fixes

* Faster tests

* WIP: HER as a custom replay buffer

* New replay only version (working with DQN)

* Add support for all off-policy algorithms

* Fix saving/loading

* Remove ObsDictWrapper and add VecNormalize tests with dict

* Stable-Baselines3 v1.0 (DLR-RM#354)

* Bump version and update doc

* Fix name

* Apply suggestions from code review

Co-authored-by: Adam Gleave <adam@gleave.me>

* Update docs/index.rst

Co-authored-by: Adam Gleave <adam@gleave.me>

* Update wording for RL zoo

Co-authored-by: Adam Gleave <adam@gleave.me>

* Add gym-pybullet-drones project (DLR-RM#358)

* Update projects.rst

Added gym-pybullet-drones

* Update projects.rst

Longer title underline

* Update changelog

Co-authored-by: Antonin Raffin <antonin.raffin@ensta.org>

* Include SuperSuit in projects (DLR-RM#359)

* include supersuit

* longer title underline

* Update changelog.rst

* Fix default arguments + add bugbear (DLR-RM#363)

* Fix potential bug + add bug bear

* Remove unused variables

* Minor: version bump

* Add code of conduct + update doc (DLR-RM#373)

* Add code of conduct

* Fix DQN doc example

* Update doc (channel-last/first)

* Apply suggestions from code review

Co-authored-by: Anssi <kaneran21@hotmail.com>

* Apply suggestions from code review

Co-authored-by: Adam Gleave <adam@gleave.me>

Co-authored-by: Anssi <kaneran21@hotmail.com>
Co-authored-by: Adam Gleave <adam@gleave.me>

* Make installation command compatible with ZSH (DLR-RM#376)

* Add quotes

* Add Zsh bracket info

* Add clarify pip installation line

* Make note bold

* Add Zsh pip installation note

* Add handle timeouts param

* Fixes

* Fixes (buffer size, extend test)

* Fix `max_episode_length` redefinition

* Fix potential issue

* Add some docs on dict obs

* Fix performance bug

* Fix slowdown

* Add package to install (DLR-RM#378)

* Add package to install

* Update docs packages installation command

Co-authored-by: Antonin RAFFIN <antonin.raffin@ensta.org>

* Fix backward compat + add test

* Fix VecEnv detection

* Update doc

* Fix vec env check

* Support for `VecMonitor` for gym3-style environments (DLR-RM#311)

* add vectorized monitor

* auto format of the code

* add documentation and VecExtractDictObs

* refactor and add test cases

* add test cases and format

* avoid circular import and fix doc

* fix type

* fix type

* oops

* Update stable_baselines3/common/monitor.py

Co-authored-by: Antonin RAFFIN <antonin.raffin@ensta.org>

* Update stable_baselines3/common/monitor.py

Co-authored-by: Antonin RAFFIN <antonin.raffin@ensta.org>

* add test cases

* update changelog

* fix mutable argument

* quick fix

* Apply suggestions from code review

* fix terminal observation for gym3 envs

* delete comment

* Update doc and bump version

* Add warning when already using `Monitor` wrapper

* Update vecmonitor tests

* Fixes

Co-authored-by: Antonin RAFFIN <antonin.raffin@ensta.org>

* Reformat

* Fixed loading of ``ent_coef`` for ``SAC`` and ``TQC``, it was not optimized anymore (DLR-RM#392)

* Fix ent coef loading bug

* Add test

* Add comment

* Reuse save path

* Add test for GAE + rename `RolloutBuffer.dones` for clarification (DLR-RM#375)

* Fix return computation + add test for GAE

* Rename `last_dones` to `episode_starts` for clarification

* Revert advantage

* Cleanup test

* Rename variable

* Clarify return computation

* Clarify docs

* Add multi-episode rollout test

* Reformat

Co-authored-by: Anssi "Miffyli" Kanervisto <kaneran21@hotmail.com>

* Fixed saving of `A2C` and `PPO` policy when using gSDE (DLR-RM#401)

* Improve doc and replay buffer loading

* Add support for images

* Fix doc

* Update Procgen doc

* Update changelog

* Update docstrings

Co-authored-by: Adam Gleave <adam@gleave.me>
Co-authored-by: Jacopo Panerati <jacopo.panerati@utoronto.ca>
Co-authored-by: Justin Terry <justinkterry@gmail.com>
Co-authored-by: Anssi <kaneran21@hotmail.com>
Co-authored-by: Tom Dörr <tomdoerr96@gmail.com>
Co-authored-by: Tom Dörr <tom.doerr@tum.de>
Co-authored-by: Costa Huang <costa.huang@outlook.com>
@araffin
Copy link
Member

araffin commented May 3, 2021

@J-Travnik @Miffyli The refactoring of HER is done, tested and merged in here (I also added proper timeout handling).
We mostly need to do a final review of this PR and it is good to be merged =)

Copy link

@JadenTravnik JadenTravnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@araffin The integration of HER looks awesome. :)
I did a pass and didn't find much to comment on so koodos 👍

stable_baselines3/common/env_checker.py Outdated Show resolved Hide resolved
@Miffyli
Copy link
Collaborator

Miffyli commented May 10, 2021

I think its worth doing the check here in the init. We have everything to make an informative error message so we might as well.

@J-Travnik sorry to bother one more time, but could you clarify what error message you meant here? is_image_space is checked inside the transpose_space function because it gets called from other places.

Copy link
Collaborator

@Miffyli Miffyli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks positively brilliant to me! 👍 . If no further changes are required (see above comment), feel free to merge @araffin

@J-Travnik 🍻 / ☕ / 🍵 / hot-chocos on me if we ever get to meet in person! Thanks for all your time and patience! ^^

@araffin araffin merged commit 75b6f3b into DLR-RM:master May 11, 2021
@araffin
Copy link
Member

araffin commented May 11, 2021

Finally merged 🎉
Thanks for the PR =D!

@J-Travnik
Copy link
Contributor Author

@Miffyli @araffin This is wonderful :)
Looking forward to hot cocos in the future ;)

leor-c pushed a commit to leor-c/stable-baselines3 that referenced this pull request Aug 26, 2021
* First commit

* Fixing missing refs from a quick merge from master

* Reformat

* Adding DictBuffers

* Reformat

* Minor reformat

* added slow dict test. Added SACMultiInputPolicy for future. Added private static image transpose helper to common policy

* Ran black on buffers

* Ran isort

* Adding StackedObservations classes used within VecStackEnvs wrappers. Made test_dict_env shorter and removed slow

* Running isort :facepalm

* Fixed typing issues

* Adding docstrings and typing. Using util for moving data to device.

* Fixed trailing commas

* Fix types

* Minor edits

* Avoid duplicating code

* Fix calls to parents

* Adding assert to buffers. Updating changelong

* Running format on buffers

* Adding multi-input policies to dqn,td3,a2c. Fixing warnings. Fixed bug with DictReplayBuffer as Replay buffers use only 1 env

* Fixing warnings, splitting is_vectorized_observation into multiple functions based on space type

* Created envs folder in common. Updated imports. Moved stacked_obs to vec_env folder

* Moved envs to envs directory. Moved stacked obs to vec_envs. Started update on documentation

* Fixes

* Running code style

* Update docstrings on torch_layers

* Decapitalize non-constant variables

* Using NatureCNN architecture in combined extractor. Increasing img size in multi input env. Adding memory reduction in test

* Update doc

* Update doc

* Fix format

* Removing NineRoom env. Using nested preprocess. Removing mutable default args

* running code style

* Passing channel check through to stacked dict observations.

* Running black

* Adding channel control to SimpleMultiObsEnv. Passing check_channels to CombinedExtractor

* Remove optimize memory for dict buffers

* Update doc

* Move identity env

* Minor edits + bump version

* Update doc

* Fix doc build

* Bug fixes + add support for more type of dict env

* Fixes + add multi env test

* Add support for vectranspose

* Fix stacked obs for dict and add tests

* Add check for nested spaces. Fix dict-subprocvecenv test

* Fix (single) pytype error

* Simplify CombinedExtractor

* Fix tests

* Fix check

* Merge branch 'master' into feat/dict_observations

* Fix for net_arch with dict and vector obs

* Fixes

* Add consistency test

* Update env checker

* Add some docs on dict obs

* Update default CNN feature vector size

* Refactor HER (DLR-RM#351)

* Start refactoring HER

* Fixes

* Additional fixes

* Faster tests

* WIP: HER as a custom replay buffer

* New replay only version (working with DQN)

* Add support for all off-policy algorithms

* Fix saving/loading

* Remove ObsDictWrapper and add VecNormalize tests with dict

* Stable-Baselines3 v1.0 (DLR-RM#354)

* Bump version and update doc

* Fix name

* Apply suggestions from code review

Co-authored-by: Adam Gleave <adam@gleave.me>

* Update docs/index.rst

Co-authored-by: Adam Gleave <adam@gleave.me>

* Update wording for RL zoo

Co-authored-by: Adam Gleave <adam@gleave.me>

* Add gym-pybullet-drones project (DLR-RM#358)

* Update projects.rst

Added gym-pybullet-drones

* Update projects.rst

Longer title underline

* Update changelog

Co-authored-by: Antonin Raffin <antonin.raffin@ensta.org>

* Include SuperSuit in projects (DLR-RM#359)

* include supersuit

* longer title underline

* Update changelog.rst

* Fix default arguments + add bugbear (DLR-RM#363)

* Fix potential bug + add bug bear

* Remove unused variables

* Minor: version bump

* Add code of conduct + update doc (DLR-RM#373)

* Add code of conduct

* Fix DQN doc example

* Update doc (channel-last/first)

* Apply suggestions from code review

Co-authored-by: Anssi <kaneran21@hotmail.com>

* Apply suggestions from code review

Co-authored-by: Adam Gleave <adam@gleave.me>

Co-authored-by: Anssi <kaneran21@hotmail.com>
Co-authored-by: Adam Gleave <adam@gleave.me>

* Make installation command compatible with ZSH (DLR-RM#376)

* Add quotes

* Add Zsh bracket info

* Add clarify pip installation line

* Make note bold

* Add Zsh pip installation note

* Add handle timeouts param

* Fixes

* Fixes (buffer size, extend test)

* Fix `max_episode_length` redefinition

* Fix potential issue

* Add some docs on dict obs

* Fix performance bug

* Fix slowdown

* Add package to install (DLR-RM#378)

* Add package to install

* Update docs packages installation command

Co-authored-by: Antonin RAFFIN <antonin.raffin@ensta.org>

* Fix backward compat + add test

* Fix VecEnv detection

* Update doc

* Fix vec env check

* Support for `VecMonitor` for gym3-style environments (DLR-RM#311)

* add vectorized monitor

* auto format of the code

* add documentation and VecExtractDictObs

* refactor and add test cases

* add test cases and format

* avoid circular import and fix doc

* fix type

* fix type

* oops

* Update stable_baselines3/common/monitor.py

Co-authored-by: Antonin RAFFIN <antonin.raffin@ensta.org>

* Update stable_baselines3/common/monitor.py

Co-authored-by: Antonin RAFFIN <antonin.raffin@ensta.org>

* add test cases

* update changelog

* fix mutable argument

* quick fix

* Apply suggestions from code review

* fix terminal observation for gym3 envs

* delete comment

* Update doc and bump version

* Add warning when already using `Monitor` wrapper

* Update vecmonitor tests

* Fixes

Co-authored-by: Antonin RAFFIN <antonin.raffin@ensta.org>

* Reformat

* Fixed loading of ``ent_coef`` for ``SAC`` and ``TQC``, it was not optimized anymore (DLR-RM#392)

* Fix ent coef loading bug

* Add test

* Add comment

* Reuse save path

* Add test for GAE + rename `RolloutBuffer.dones` for clarification (DLR-RM#375)

* Fix return computation + add test for GAE

* Rename `last_dones` to `episode_starts` for clarification

* Revert advantage

* Cleanup test

* Rename variable

* Clarify return computation

* Clarify docs

* Add multi-episode rollout test

* Reformat

Co-authored-by: Anssi "Miffyli" Kanervisto <kaneran21@hotmail.com>

* Fixed saving of `A2C` and `PPO` policy when using gSDE (DLR-RM#401)

* Improve doc and replay buffer loading

* Add support for images

* Fix doc

* Update Procgen doc

* Update changelog

* Update docstrings

Co-authored-by: Adam Gleave <adam@gleave.me>
Co-authored-by: Jacopo Panerati <jacopo.panerati@utoronto.ca>
Co-authored-by: Justin Terry <justinkterry@gmail.com>
Co-authored-by: Anssi <kaneran21@hotmail.com>
Co-authored-by: Tom Dörr <tomdoerr96@gmail.com>
Co-authored-by: Tom Dörr <tom.doerr@tum.de>
Co-authored-by: Costa Huang <costa.huang@outlook.com>

* Update doc and minor fixes

* Update doc

* Added note about MultiInputPolicy in error of NatureCNN

* Merge branch 'master' into feat/dict_observations

* Address comments

* Naming clarifications

* Actually saving the file would be nice

* Fix edge case when doing online sampling with HER

* Cleanup

* Add sanity check

Co-authored-by: Antonin RAFFIN <antonin.raffin@ensta.org>
Co-authored-by: Anssi "Miffyli" Kanervisto <kaneran21@hotmail.com>
Co-authored-by: Adam Gleave <adam@gleave.me>
Co-authored-by: Jacopo Panerati <jacopo.panerati@utoronto.ca>
Co-authored-by: Justin Terry <justinkterry@gmail.com>
Co-authored-by: Tom Dörr <tomdoerr96@gmail.com>
Co-authored-by: Tom Dörr <tom.doerr@tum.de>
Co-authored-by: Costa Huang <costa.huang@outlook.com>
@araffin araffin mentioned this pull request Jan 30, 2023
16 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants