Generative Adversarial Imitation Learning (GAIL)¶
GAIL performs imitation learning via an actor–discriminator adversarial game: the policy learns to generate trajectories indistinguishable from expert demonstrations without an explicit reward function.
Components¶
- Actor-Critic:
ActorCriticoutputs actions and estimates \(V(s)\) - Discriminator:
Discriminatordistinguishes expert from agent pairs \((s,a)\) - Policy optimizer: PPO-style clipped surrogate updates
Theory¶
- Min–max objective:
- Discriminator-derived pseudo reward (for the actor):
- PPO actor update (as implemented):
- Advantage via GAE:
Expert data¶
Expect expert_data as an array of shape [N, obs_dim + act_dim]: state concatenated with action.
Training loop¶
- Generate agent rollouts \(s_t, a_t \sim \pi\); store
log_prob,V(s) - Compute pseudo rewards
r_D = -log D([s,a]), then GAE returns/advantages - Update actor/critic with PPO mini-batches
- Train the discriminator with BCE:
D(fake)=1,D(real)=0 - Periodically evaluate the policy and early-stop based on
max_reward
Example (LinearLongitudinalF16‑v0)¶
import gymnasium as gym
import numpy as np
from tensoraerospace.agent.gail.model import GAIL
from tensoraerospace.utils import generate_time_period
from tensoraerospace.signals.standard import unit_step
dt = 0.01
tp = generate_time_period(tn=20, dt=dt)
number_time_steps = len(tp)
reference_signals = unit_step(degree=5, tp=tp, time_step=1000, output_rad=True).reshape(1, -1)
env = gym.make('LinearLongitudinalF16-v0',
number_time_steps=number_time_steps,
initial_state=[[0],[0],[0]],
reference_signal=reference_signals,
use_reward=False,
state_space=["theta","alpha","q"],
output_space=["theta","alpha","q"],
control_space=["ele"],
tracking_states=["alpha"],)
expert_data = np.load('expert_f16.npy')
agent = GAIL(env, learning_rate=3e-3, max_steps=20, mini_batch_size=16, epochs=4, data=expert_data)
agent.learn(max_frames=5000, max_reward=-1)
# Unified API (wraps learn)
agent.train(num_episodes=250, max_steps=20, max_reward=-1)
Unified training interface¶
GAIL exposes the shared unified train() API from BaseRLModel.
Internally it delegates to the legacy learn() method, translating
num_episodes * max_steps into a max_frames budget. GAIL-specific
options accepted via **kwargs:
max_frames(int): override the computed step budget.max_reward(float): early-stop threshold for the mean test reward.
Tip
High-quality expert_data is crucial—include demonstrations with varied initial states and maneuvers.
Gymnasium 5-tuple API
This implementation uses the modern Gymnasium 5-tuple step API internally:
If you are migrating from older code that used the 4-tuple API (next_state, reward, done, info = env.step(action)), ensure your environment is compatible with Gymnasium and returns the 5-tuple.
API reference¶
GAIL(env, learning_rate, max_steps, mini_batch_size, epochs, data, log_dir=None, wandb_project=None, wandb_entity=None, wandb_run_name=None, wandb_tags=None, wandb_config=None, device=None)
¶
Generative Adversarial Imitation Learning trainer.
Initialize the GAIL algorithm.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
env
|
Env
|
Environment instance. |
required |
learning_rate
|
float
|
Learning rate. |
required |
max_steps
|
int
|
Maximum steps per rollout/episode. |
required |
mini_batch_size
|
int
|
Mini-batch size. |
required |
epochs
|
int
|
Number of training epochs. |
required |
data
|
Array
|
Expert demonstrations (states/actions). |
required |
log_dir
|
Union[str, Path, None]
|
Optional TensorBoard log directory. When provided, a
|
None
|
device
|
Optional[Union[str, device]]
|
Torch device for the networks. Defaults to |
None
|
expert_reward(state, action)
¶
Compute imitation reward using the discriminator.
test_env()
¶
Run one evaluation rollout and return total reward.
ppo_update(ppo_epochs, mini_batch_size, states, actions, log_probs, returns, advantages, clip_param=0.2, env_step=0)
¶
PPO update function.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ppo_epochs
|
int
|
Number of epochs. |
required |
mini_batch_size
|
int
|
Mini-batch size. |
required |
states
|
Tensor
|
Batch of states. |
required |
actions
|
Tensor
|
Batch of actions. |
required |
log_probs
|
Tensor
|
Batch of action log probabilities. |
required |
returns
|
Tensor
|
Batch of discounted rewards. |
required |
advantages
|
Tensor
|
Batch of advantage function values. |
required |
clip_param
|
float
|
Clipping constant. |
0.2
|
env_step
|
int
|
Cumulative environment-step counter used as the x-axis for any TensorBoard scalars written from inside this update. Defaults to 0. |
0
|
train(num_episodes=100, *, max_steps=None, save_best=False, save_path=None, verbose=True, **kwargs)
¶
Train GAIL (unified interface wrapper around :meth:learn).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_episodes
|
int
|
Number of episodes. Combined with
|
100
|
max_steps
|
Optional[int]
|
Max steps per episode. Defaults to
|
None
|
save_best
|
bool
|
Reserved for API consistency. |
False
|
save_path
|
Optional[str]
|
Reserved for API consistency. |
None
|
verbose
|
bool
|
Reserved for symmetry. |
True
|
**kwargs
|
Any
|
GAIL-specific options:
|
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
dict |
dict
|
Empty dict (GAIL does not yet collect metrics). |
learn(max_frames, max_reward)
¶
Agent training function.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_frames
|
int
|
Maximum number of steps in the environment. |
required |
max_reward
|
int
|
Reward threshold for stopping training. |
required |
get_param_env()
¶
Return serializable configuration of environment and policy.
save(path=None, save_gradients=False)
¶
Save GAIL model to the specified directory.
Saves actor-critic network, discriminator network, and configuration. Optionally saves optimizer states for resuming training.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path | None
|
Base save directory. If None, saves to the current working directory. |
None
|
save_gradients
|
bool
|
If True, also save optimizer state dicts. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
Path |
Path
|
The directory where the model was saved. |
from_pretrained(repo_name, env=None, data=None, access_token=None, version=None, load_gradients=False)
classmethod
¶
Load pretrained model from a local directory or Hugging Face Hub.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
repo_name
|
str
|
Path to a local folder or a Hugging Face repo id
(e.g. |
required |
env
|
Optional[Env]
|
Environment instance (required). |
None
|
data
|
Optional[ndarray]
|
Expert demonstration data (optional). |
None
|
access_token
|
Optional[str]
|
Hugging Face access token for private repos. |
None
|
version
|
Optional[str]
|
Revision / branch / tag on Hugging Face. |
None
|
load_gradients
|
bool
|
Restore optimizer states for continued training. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
GAIL |
GAIL
|
Initialized agent. |
publish_to_hub(repo_name, folder_path, access_token=None)
¶
Upload a saved model folder to Hugging Face Hub.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
repo_name
|
str
|
Repository id on Hugging Face (e.g. |
required |
folder_path
|
Union[str, Path]
|
Local folder produced by :meth: |
required |
access_token
|
Optional[str]
|
Hugging Face access token. |
None
|
References¶
Tested on¶
- Unity environment
- LinearLongitudinalF16‑v0 (repository example)