Apprenticeship Learning via Inverse RL
You do not need the expert's hidden reward to match them. Match how often their behavior visits each feature, and the return gap stays small no matter the reward weights.
Why Does This Exist?
Copying actions directly fails in a familiar way. Behavioral cloning fits state action pairs, then one small steering mistake puts the car somewhere the expert never visited. Errors compound along the trajectory, so performance can degrade with the square of the horizon.
Guessing the hidden reward is no easier. Inverse reinforcement learning tries to recover the reward that made the expert optimal, but the problem is underdetermined. Many rewards, including all zeros, make any demo look optimal.
Apprenticeship learning asks for less and still gets a guarantee. Assume reward is linear in known features, with feature vector and weights . Then matching the expert's discounted feature counts is enough. If your feature averages sit within of the expert's, your return sits within of the expert's for any valid . This page covers that matching loop. Neighbor pages cover inferring a full reward in inverse reinforcement learning, handling ambiguity in maximum entropy IRL, and skipping rewards with adversarial matching in GAIL.
You only need Markov decision processes first: states, actions, transitions, discount , and expected return.
Think of It Like This
An apprentice cook matching the master's pantry totals
You apprentice under a chef whose exact taste weights you will never know. Copying every wrist flick fails the moment the kitchen changes. Instead you match pantry totals over a month: kilos of tomatoes, liters of stock, grams of salt.
Those totals are the feature expectations . The judge's hidden scoring weights are . If your monthly totals sit close to the master's on every ingredient, any judge who scores as a weighted mix of those ingredients will score you close to the master.
Where it stops: a real pantry has substitutes and spoilage, and totals hide order and timing. The math here assumes the listed features capture everything the reward cares about, and that you can roll out fresh trajectories to measure your own totals exactly.
How It Actually Works
Write for the discounted feature expectation of a policy :
Here in is the discount factor, is the state at step , and averages over start states and transitions. The expert's version is the same average measured from demos. Return under weights is then a dot product:
So the gap obeys Cauchy-Schwarz. With :
That is the whole guarantee. Get the feature distance below and the return gap follows.
The projection loop
The Abbeel and Ng projection method builds this match iteratively. Keep the convex hull of feature points found so far, project the expert onto it to get , point the next reward from toward , solve that forward RL problem, add the new point, repeat. Stop when .
Worked example
Take two features, , and expert point:
Start from a random policy with , so . The first gap vector is and:
That exceeds , so solve the induced reward and get . The new gap is and:
Still above threshold. Solve again and get . The gap is and:
Now , so stop. The return gap to the expert is at most for any allowed .
Code
This snippet recomputes the three margins above. Nothing else is hidden inside.
import numpy as np
def margin(mu_e: np.ndarray, mu_bar: np.ndarray) -> float: """Euclidean distance between expert and learner feature points.""" return float(np.linalg.norm(mu_e - mu_bar))
mu_e = np.array([0.80, 0.60])mu0 = np.array([0.20, 0.20])mu1 = np.array([0.55, 0.35])mu2 = np.array([0.75, 0.52])
print(f"{margin(mu_e, mu0):.4f}") # -> 0.7211print(f"{margin(mu_e, mu1):.4f}") # -> 0.3536print(f"{margin(mu_e, mu2):.4f}") # -> 0.0943The prints match the hand arithmetic: , then , then below the stop line.
Watch Out For
Features that miss what the expert cares about
The guarantee assumes the true reward is linear in your . If the expert cares about something you never encoded, say smoothness or risk, matching your features proves nothing.
Symptom: margins shrink to zero yet the learned policy still drives badly or looks nothing like the demos. Fix: add the missing feature and rerun. The failure is in representation, not in the projection math.
Paying for a full RL solve every round
Each outer step trains a fresh policy for a new reward guess. With deep policies that means millions of env steps per iteration.
Symptom: two outer loops take longer than the whole baseline budget. Fix: warm start each policy from the previous one, or move to a single loop method such as GAIL when the budget bites.
The Quick Version
- Apprenticeship learning matches discounted feature averages , not raw actions and not the hidden weights .
- The bound holds for any allowed linear reward once features match.
- The projection loop points each new reward from the current hull toward and stops below .
- In the 2D example the gap falls to to , so the return gap is at most .
- Bad features or a costly inner RL loop are the two failures to check first.