PPO for Beginners

repository·master·Indexed 23 days ago

https://github.com/ericyangyu/ppo-for-beginners

A bare-bones, highly documented PyTorch implementation of the Proximal Policy Optimization (PPO) algorithm designed as an educational resource. It supports training from scratch or resuming from existing actor and critic models, and is designed for environments with continuous observation and action spaces. The repository includes tools for automating data collection and generating comparison graphs against Stable Baselines PPO2.

Tokens
1.9K
Snippets
8
Records
12
Agent score
79%

What's inside ppo-for-beginners

  1. Overview of the PPO for Beginners architecture

    master

    The project is structured into several key modules:

    • main.py: The primary executable. It parses arguments via arguments.py, initializes the environment and PPO model, and executes either training or testing. Training is triggered by calling the learn function.
    • arguments.py: Handles command-line argument parsing.
    • ppo.py: The core implementation of the PPO model. It follows the OpenAI Spinning Up pseudocode (referenced by ALG STEP # in the code).
    • network.py: Provides a sample Feed Forward Neural Network used to define actor and critic networks.
    • eval_policy.py: A standalone module for evaluating the policy.
    • graph_code/: Contains scripts for data collection and graph generation.
  2. Compatible environments for PPO

    master

    This implementation is designed for continuous observation and action spaces. When selecting environments (e.g., from OpenAI Gym), ensure they use the Box space for both observations and actions.

    To change hyperparameters or the environment, modify the configurations directly in main.py.

  3. Understand the data generation and graphing workflow

    master

    The automation workflow consists of several components working together:

    • generate_data.bash: The entry point for data collection. It accepts environment names as CLI arguments, calculates random seeds, and iterates through each environment. For every seed, it runs both the 'PPO for Beginners' implementation and 'Stable Baselines PPO2'.
    • run.py: Orchestrates the actual training execution. It is called by the bash script and applies the correct hyperparameters for either the custom PPO implementation or Stable Baselines.
    • graph_data/: The directory where all training outputs are stored. The data is structured hierarchically:
      1. environment/ (e.g., Pendulum-v0/)
      2. code/ (either PPO for Beginners/ or Stable Baselines PPO2/, including a seeds.txt file)
      3. seed_xxx.txt (the raw training output for a specific seed)
    • make_graph.py: Reads the files in graph_data/ to generate plots. In the resulting graphs, thick lines represent the average across all seeds, and highlighted regions represent the variance.
  4. Setup the PPO for Beginners environment

    master

    To set up the project, create a Python virtual environment, activate it, and install the required dependencies using pip.

    python -m venv venv
    source venv/bin/activate
    pip install -r requirements.txt
    python -m venv venv
    source venv/bin/activate
    pip install -r requirements.txt
  5. Generate and graph training data

    master

    You can automate the process of collecting training data across multiple environments and generating comparison graphs.

    Warning: The code in the graph_code directory is considered out of date and may be difficult to read as it uses advanced automation techniques not intended for beginners.

    1. Prepare the script

    Before running the data generation script, ensure it has execution permissions:

    chmod u+x generate_data.bash

    2. Generate data

    Run the generate_data.bash script by passing the names of the environments you wish to test as command-line arguments. The script will run both ppo_for_beginners and Stable Baselines PPO2 across multiple random seeds for each environment.

    ./generate_data.bash <environment_name_1> <environment_name_2>

    Example:

    ./generate_data.bash Pendulum-v0 BipedalWalker-v3

    3. Create graphs

    Once data collection is complete, use make_graph.py to plot the results stored in the graph_data directory. The resulting graphs display thick lines representing the averages across all seeds and highlighted regions representing the variance.

    python make_graph.py
    # Sample Use
    ./generate_data.bash Pendulum-v0 BipedalWalker-v3
    python make_graph.py
  6. Configure PPO hyperparameters in main()

    master

    Hyperparameters for the PPO algorithm are defined as a dictionary within the main() function. To change the training behavior, modify the following keys in the hyperparameters dictionary:

    • timesteps_per_batch: Number of timesteps collected before an update.
    • max_timesteps_per_episode: Maximum length of an episode.
    • gamma: Discount factor for future rewards.
    • n_updates_per_iteration: Number of gradient updates per iteration.
    • lr: Learning rate.
    • clip: PPO clipping parameter.
    • render: Boolean to enable rendering.
    • render_every_i: Frequency of rendering during training.
    hyperparameters = {
        'timesteps_per_batch': 2048, 
        'max_timesteps_per_episode': 200, 
        'gamma': 0.99, 
        'n_updates_per_iteration': 10,
        'lr': 3e-4, 
        'clip': 0.2,
        'render': True,
        'render_every_i': 10
    }
  7. Resume training with existing actor and critic models

    master

    To continue training using existing weights, provide both the actor and critic model files using the --actor_model and --critic_model flags.

    python main.py --actor_model ppo_actor.pth --critic_model ppo_critic.pth
    python main.py --actor_model ppo_actor.pth --critic_model ppo_critic.pth
  8. Evaluate a trained policy using test()

    master

    The test() function is used to evaluate a previously trained actor model in a Gymnasium environment. It demonstrates that the trained policy can exist independently of the training algorithm.

    Workflow:

    1. Extracts observation and action dimensions from the environment.
    2. Reconstructs the policy using FeedForwardNN with the correct dimensions.
    3. Loads the saved weights from the actor_model file.
    4. Calls eval_policy to run the environment with the loaded policy (with render=True).

    Note: An actor_model path must be provided, otherwise the function exits.

    test(env, actor_model)
  9. Train a PPO model using train()

    master

    The train() function orchestrates the training process for a Proximal Policy Optimization (PPO) model. It initializes a PPO instance using a FeedForwardNN policy class and a provided Gymnasium environment.

    Key behaviors:

    • Training from scratch: If no actor or critic models are provided, training starts from scratch.
    • Resuming training: If both actor_model and critic_model paths are provided, the function loads the existing state dicts into the model to continue training.
    • Error handling: If only one model path is provided, the function exits to prevent accidental overwriting of partial weights.
    • Timesteps: The training runs for a fixed number of total_timesteps (defaulting to 200,000,000 in the implementation).
    train(env, hyperparameters, actor_model, critic_model)
  10. Run PPO via CLI

    master

    The main.py file serves as the CLI entrypoint. It uses get_args() to parse command-line arguments which determine the execution mode (train or test) and the model file paths.

    Modes:

    • train: Executes the training loop. Requires --actor_model and --critic_model if you wish to resume training from existing weights.
    • test: Executes the evaluation loop. Requires --actor_model to load the policy weights.

    Environment Requirements: Custom environments must inherit from gym.Env and feature both continuous observation and action spaces.