Skip to content
AI360Xpert
Beta

Gradient Bandits

Gradient bandits optimize numerical preferences for each action rather than estimating payoff values, shifting probabilities upward for choices that outperform the average reward baseline.

Gradient bandits parameterize action probabilities through a softmax distribution over unconstrained preferences, updating them via stochastic gradient ascent relative to a reward baseline.
Gradient bandits parameterize action probabilities through a softmax distribution over unconstrained preferences, updating them via stochastic gradient ascent relative to a reward baseline.

Why Does This Exist?

Most foundational multi-armed bandit algorithms—such as ε\varepsilon-greedy, Upper Confidence Bound (UCB), and Thompson Sampling—are action-value methods. They maintain numerical estimates Q(a)Q(a) of the true expected payoff q∗(a)q_*(a) for each arm, selecting actions based on which estimate is highest.

However, estimating absolute reward values introduces several practical and theoretical challenges:

  1. Relative order matters, absolute magnitude does not: If arm 1 produces an expected return of +102+102 and arm 2 produces +100+100, an agent does not need to estimate the number 102102 to understand that arm 1 is superior. Value estimators waste statistical effort calibrating arbitrary scales and offsets.
  2. Rigid exploration policies: Action-value methods select actions through discontinuous operations (like arg⁡max⁡\arg\max) combined with heuristic random exploration (ε\varepsilon). They lack a natural, smooth mechanism to continuously adjust the probability of taking actions in proportion to evidence.
  3. No direct path to policy optimization: In complex or continuous decision problems, estimating values everywhere is intractable. We need methods that directly parameterize and optimize the decision policy itself.

Gradient bandits resolve this by abandoning reward estimation altogether. Instead of tracking expected payouts, the agent assigns an unconstrained numerical preference Ht(a)∈RH_t(a) \in \mathbb{R} to each action. These preferences are converted into a probability distribution via a softmax transformation and optimized directly using stochastic gradient ascent on the expected total reward. Gradient bandits serve as the direct conceptual foundation for modern Policy Gradient Methods.

Think of It Like This

A radio DJ tuning genre weights against listener mood

Imagine a radio DJ deciding which genre of music—Pop, Rock, Hip-Hop, or Jazz—to broadcast next. Instead of trying to predict the exact number of phone calls or ratings each individual song will receive, the DJ maintains an internal "preference dial" for each genre.

Whenever it is time to queue a track, the DJ spins a roulette wheel where each genre's slice corresponds to its current preference dial (the softmax distribution). Higher dials get played more often, but every genre retains a chance to hit the airwaves.

After playing a song, the DJ checks listener feedback (the reward RtR_t) against the station's recent running average satisfaction score (the baseline Rˉt\bar{R}_t):

  • Above-average reaction (Rt>RˉtR_t > \bar{R}_t): A hip-hop track scores 8.58.5 when the station average is 6.06.0. The DJ nudges the hip-hop dial upward. Because all probabilities must sum to 100%100\%, the other genres automatically surrender a fraction of their airtime.
  • Below-average reaction (Rt<RˉtR_t < \bar{R}_t): An indie rock track scores 4.54.5. Even though the rating is positive and listeners did not boycott the station, it scored below the room average. The DJ dials down indie rock, causing the other genres to gain relative probability.

The DJ never needs to define what a "perfect 10" track feels like. They simply boost choices that beat the baseline and suppress choices that lag behind it.

Where the analogy stops: A human DJ must consider listener fatigue, time-of-day dynamics, and smooth transitions between songs. In a gradient bandit, trials are independent, arm payoff distributions are stationary, and there are no sequential state transitions.

How It Actually Works

Action Preferences and Stochastic Gradient Ascent

Rather than estimating expected payoffs Q(a)≈q∗(a)Q(a) \approx q_*(a), a gradient bandit maintains a numerical preference Ht(a)∈RH_t(a) \in \mathbb{R} for each action a∈{1,2,…,k}a \in \{1, 2, \dots, k\}.

Preferences have no units of reward. Only the relative differences between preferences dictate action selection. If you add an arbitrary constant cc to every preference, the action probabilities remain completely unchanged:

eHt(a)+c∑b=1keHt(b)+c=ec⋅eHt(a)ec∑b=1keHt(b)=eHt(a)∑b=1keHt(b)=πt(a)\frac{e^{H_t(a) + c}}{\sum_{b=1}^k e^{H_t(b) + c}} = \frac{e^c \cdot e^{H_t(a)}}{e^c \sum_{b=1}^k e^{H_t(b)}} = \frac{e^{H_t(a)}}{\sum_{b=1}^k e^{H_t(b)}} = \pi_t(a)

1. Softmax Action Selection

At time step tt, the probability of selecting action aa is determined by the softmax (Boltzmann / Gibbs) distribution:

πt(a)=Pr⁡(At=a)=eHt(a)∑b=1keHt(b)\pi_t(a) = \Pr(A_t = a) = \frac{e^{H_t(a)}}{\sum_{b=1}^k e^{H_t(b)}}

Every action always has a strictly positive probability (πt(a)>0\pi_t(a) > 0), guaranteeing continuous exploration without requiring an artificial ε\varepsilon-greedy exploration floor.

2. The Objective Function

The agent seeks to maximize expected reward across trials:

E[Rt]=∑x=1kπt(x)q∗(x)\mathbb{E}[R_t] = \sum_{x=1}^k \pi_t(x) q_*(x)

where q∗(x)=E[Rt∣At=x]q_*(x) = \mathbb{E}[R_t \mid A_t = x] is the true underlying mean reward of action xx.

3. Deriving the Gradient

To perform gradient ascent, we take the derivative of expected reward with respect to preference Ht(a)H_t(a):

∂E[Rt]∂Ht(a)=∑x=1kq∗(x)∂πt(x)∂Ht(a)\frac{\partial \mathbb{E}[R_t]}{\partial H_t(a)} = \sum_{x=1}^k q_*(x) \frac{\partial \pi_t(x)}{\partial H_t(a)}

Using the derivative of the softmax function ∂πt(x)∂Ht(a)=πt(x)(1x=a−πt(a))\frac{\partial \pi_t(x)}{\partial H_t(a)} = \pi_t(x)(\mathbf{1}_{x=a} - \pi_t(a)), we can introduce an arbitrary baseline BtB_t that does not depend on the action xx. Because probabilities sum to 1 (∑xπt(x)=1\sum_x \pi_t(x) = 1), the gradient of the baseline term vanishes:

∑x=1kBt∂πt(x)∂Ht(a)=Bt∂∂Ht(a)∑x=1kπt(x)=Bt∂(1)∂Ht(a)=0\sum_{x=1}^k B_t \frac{\partial \pi_t(x)}{\partial H_t(a)} = B_t \frac{\partial}{\partial H_t(a)} \sum_{x=1}^k \pi_t(x) = B_t \frac{\partial (1)}{\partial H_t(a)} = 0

Subtracting this zero-valued baseline yields:

∂E[Rt]∂Ht(a)=∑x=1k(q∗(x)−Bt)πt(x)(1x=a−πt(a))=E[(Rt−Rˉt)(1At=a−πt(a))]\frac{\partial \mathbb{E}[R_t]}{\partial H_t(a)} = \sum_{x=1}^k (q_*(x) - B_t) \pi_t(x) \left(\mathbf{1}_{x=a} - \pi_t(a)\right) = \mathbb{E}\left[ (R_t - \bar{R}_t) (\mathbf{1}_{A_t=a} - \pi_t(a)) \right]

Replacing the true expectation with the sampled reward RtR_t gives an unbiased stochastic gradient sample!

4. The Preference Update Rule

After taking action AtA_t and observing reward RtR_t, the preferences are updated via:

Ht+1(a)=Ht(a)+α(Rt−Rˉt)(1a=At−πt(a))for all aH_{t+1}(a) = H_t(a) + \alpha (R_t - \bar{R}_t) \left(\mathbf{1}_{a=A_t} - \pi_t(a)\right) \quad \text{for all } a

Breaking this into the chosen versus unchosen actions:

  • For the chosen arm (a=Ata = A_t): Ht+1(At)=Ht(At)+α(Rt−Rˉt)(1−πt(At))H_{t+1}(A_t) = H_t(A_t) + \alpha (R_t - \bar{R}_t)(1 - \pi_t(A_t))
  • For all other arms (a≠Ata \neq A_t): Ht+1(a)=Ht(a)−α(Rt−Rˉt)πt(a)H_{t+1}(a) = H_t(a) - \alpha (R_t - \bar{R}_t)\pi_t(a)

where:

  • α>0\alpha > 0 is the step-size parameter (learning rate).
  • 1a=At\mathbf{1}_{a=A_t} is the indicator function (11 if a=Ata = A_t, else 00).
  • Rˉt\bar{R}_t is the average reward baseline up to time tt, tracked incrementally:

Rˉt=Rˉt−1+1t(Rt−Rˉt−1)(with Rˉ1=R1)\bar{R}_t = \bar{R}_{t-1} + \frac{1}{t} (R_t - \bar{R}_{t-1}) \quad (\text{with } \bar{R}_1 = R_1)

5. Role of the Average Reward Baseline

The baseline Rˉt\bar{R}_t acts as a comparative anchor. If an arm yields Rt>RˉtR_t > \bar{R}_t, its preference climbs and all other preferences decline. If Rt<RˉtR_t < \bar{R}_t, its preference falls even if Rt>0R_t > 0. While any baseline leaves the expected gradient mathematically unbiased, using the running average Rˉt\bar{R}_t dramatically reduces the variance of the gradient estimates, stabilizing learning.


Worked numerical example

Consider a 2-armed bandit (k=2k = 2) with step-size α=0.20\alpha = 0.20.

Initial State (t=1t = 1)

  • Initial preferences: H1(a1)=0.00H_1(a_1) = 0.00, H1(a2)=0.00H_1(a_2) = 0.00.
  • Initial probabilities: π1(a1)=e0e0+e0=0.5000,π1(a2)=0.5000\pi_1(a_1) = \frac{e^0}{e^0 + e^0} = 0.5000, \quad \pi_1(a_2) = 0.5000
  • Running baseline prior: Rˉ1=4.00\bar{R}_1 = 4.00.

Round 1: Good Outcome on Arm 1

  1. Action selected: The agent samples Arm a1a_1 (A1=a1A_1 = a_1).
  2. Reward received: R1=6.00R_1 = 6.00.
  3. Advantage calculation: R1−Rˉ1=6.00−4.00=+2.00R_1 - \bar{R}_1 = 6.00 - 4.00 = +2.00 (performed above baseline).
  4. Update chosen arm (a1a_1): H2(a1)=0.00+0.20×(+2.00)×(1−0.5000)=0.00+0.2000=+0.2000H_2(a_1) = 0.00 + 0.20 \times (+2.00) \times (1 - 0.5000) = 0.00 + 0.2000 = +0.2000
  5. Update unchosen arm (a2a_2): H2(a2)=0.00−0.20×(+2.00)×0.5000=0.00−0.2000=−0.2000H_2(a_2) = 0.00 - 0.20 \times (+2.00) \times 0.5000 = 0.00 - 0.2000 = -0.2000
  6. Update baseline: Rˉ2=4.00+12(6.00−4.00)=5.00\bar{R}_2 = 4.00 + \frac{1}{2}(6.00 - 4.00) = 5.00
  7. New probabilities for Round 2: eH2(a1)=e+0.20≈1.2214,eH2(a2)=e−0.20≈0.8187e^{H_2(a_1)} = e^{+0.20} \approx 1.2214, \quad e^{H_2(a_2)} = e^{-0.20} \approx 0.8187 Sum=1.2214+0.8187=2.0401\text{Sum} = 1.2214 + 0.8187 = 2.0401 π2(a1)=1.22142.0401≈0.5987  (59.87%),π2(a2)=0.81872.0401≈0.4013  (40.13%)\pi_2(a_1) = \frac{1.2214}{2.0401} \approx 0.5987 \; (59.87\%), \quad \pi_2(a_2) = \frac{0.8187}{2.0401} \approx 0.4013 \; (40.13\%)

Arm a1a_1's probability jumped from 50.0%50.0\% to 59.9%59.9\% because it outperformed the average baseline.

Round 2: Poor Outcome on Arm 2

  1. Action selected: The agent explores Arm a2a_2 (A2=a2A_2 = a_2).
  2. Reward received: R2=2.00R_2 = 2.00.
  3. Advantage calculation: R2−Rˉ2=2.00−5.00=−3.00R_2 - \bar{R}_2 = 2.00 - 5.00 = -3.00 (performed below baseline).
  4. Update chosen arm (a2a_2): H3(a2)=−0.2000+0.20×(−3.00)×(1−0.4013)=−0.2000−0.60×0.5987=−0.2000−0.3592=−0.5592H_3(a_2) = -0.2000 + 0.20 \times (-3.00) \times (1 - 0.4013) = -0.2000 - 0.60 \times 0.5987 = -0.2000 - 0.3592 = -0.5592
  5. Update unchosen arm (a1a_1): H3(a1)=+0.2000−0.20×(−3.00)×0.5987=+0.2000+0.3592=+0.5592H_3(a_1) = +0.2000 - 0.20 \times (-3.00) \times 0.5987 = +0.2000 + 0.3592 = +0.5592
  6. New probabilities for Round 3: eH3(a1)=e+0.5592≈1.7493,eH3(a2)=e−0.5592≈0.5717e^{H_3(a_1)} = e^{+0.5592} \approx 1.7493, \quad e^{H_3(a_2)} = e^{-0.5592} \approx 0.5717 Sum=1.7493+0.5717=2.3210\text{Sum} = 1.7493 + 0.5717 = 2.3210 π3(a1)=1.74932.3210≈0.7537  (75.37%),π3(a2)=0.57172.3210≈0.2463  (24.63%)\pi_3(a_1) = \frac{1.7493}{2.3210} \approx 0.7537 \; (75.37\%), \quad \pi_3(a_2) = \frac{0.5717}{2.3210} \approx 0.2463 \; (24.63\%)

Even though Arm a2a_2 delivered a positive reward of +2.00+2.00, because it fell short of the +5.00+5.00 baseline, its preference plummeted and Arm a1a_1's selection probability climbed to 75.4%75.4\%.

Code

Below is a self-contained, type-hinted Python implementation of the Gradient Bandit algorithm with running baseline tracking.

import mathimport randomfrom typing import List

class GradientBandit:    """Gradient Bandit algorithm with numerical preferences and baseline tracking.
    Optimizes numerical action preferences H(a) via stochastic gradient ascent    on expected reward, parameterizing a softmax exploration policy.    """
    def __init__(        self,        k_arms: int,        alpha: float = 0.1,        use_baseline: bool = True,    ) -> None:        self.k: int = k_arms        self.alpha: float = alpha        self.use_baseline: bool = use_baseline        # Action preferences H_t(a), initialized to 0.0        self.preferences: List[float] = [0.0] * k_arms        # Running average reward baseline R_bar        self.baseline: float = 0.0        # Time step counter        self.step_count: int = 0
    def get_probabilities(self) -> List[float]:        """Compute action probabilities using numerically stable softmax."""        max_h = max(self.preferences)        # Subtract max preference to prevent floating-point exponential overflow        exp_h = [math.exp(h - max_h) for h in self.preferences]        total_exp = sum(exp_h)        return [e / total_exp for e in exp_h]
    def select_action(self) -> int:        """Sample an action according to softmax probabilities pi_t."""        probs = self.get_probabilities()        r = random.random()        cumulative = 0.0        for action_idx, p in enumerate(probs):            cumulative += p            if r < cumulative:                return action_idx        return self.k - 1
    def update(self, action: int, reward: float) -> None:        """Update action preferences and baseline following an observed reward."""        self.step_count += 1        probs = self.get_probabilities()
        # Update average reward baseline incrementally if enabled        if self.use_baseline:            self.baseline += (reward - self.baseline) / self.step_count            baseline_val = self.baseline        else:            baseline_val = 0.0
        advantage = reward - baseline_val
        # Stochastic gradient update rule:        # H_{t+1}(a) = H_t(a) + alpha * (R_t - R_bar) * (1_{a=A_t} - pi_t(a))        for a in range(self.k):            indicator = 1.0 if a == action else 0.0            self.preferences[a] += self.alpha * advantage * (indicator - probs[a])

# Example demonstration on a 3-armed bandit:if __name__ == "__main__":    random.seed(42)
    # 3-armed bandit environment with true payout means    k = 3    true_means = [2.0, 5.0, 3.0]  # Arm index 1 is optimal    agent = GradientBandit(k_arms=k, alpha=0.2, use_baseline=True)
    print("Initial preferences:", [round(h, 3) for h in agent.preferences])    print("Initial probabilities:", [round(p, 3) for p in agent.get_probabilities()])
    # Train for 500 interaction rounds    for _ in range(500):        a = agent.select_action()        # Sample reward with Gaussian noise around true arm mean        r = random.gauss(true_means[a], 1.0)        agent.update(action=a, reward=r)
    probs = agent.get_probabilities()    print("Final preferences:", [round(h, 3) for h in agent.preferences])    print("Final probabilities:", [round(p, 3) for p in probs])    print(f"Optimal arm (index 1) probability: {probs[1]:.1%}")    print(f"Average baseline reward: {agent.baseline:.2f}")
# -> Expected output:# Initial preferences: [0.0, 0.0, 0.0]# Initial probabilities: [0.333, 0.333, 0.333]# Final preferences: [-2.359, 4.792, -2.433]# Final probabilities: [0.001, 0.998, 0.001]# Optimal arm (index 1) probability: 99.8%# Average baseline reward: 4.90

Watch Out For

Omitting the reward baseline in positive-reward environments

A common mistake when implementing gradient bandits is omitting the reward baseline (Rˉt=0\bar{R}_t = 0), assuming that stochastic gradient ascent will still converge because the baseline term has an expected gradient of zero.

The failure mode: If all observed rewards are strictly positive (for example, payouts centered around +100+100), every single action pull produces Rt−0>0R_t - 0 > 0. As a consequence:

  1. Every time any arm is pulled, its preference Ht(a)H_t(a) is bumped upward.
  2. Even severely suboptimal arms receive continuous positive reinforcement simply by being explored.
  3. Preferences of all actions grow large and positive simultaneously. Suboptimal arms only experience relative decreases through the normalizer ∑beH(b)\sum_b e^{H(b)}, but their probabilities decline at an agonizingly slow rate.

The symptom: The agent exhibits massive gradient variance, takes thousands of extra steps to converge, or prematurely locks onto the first arm tested simply because early rewards boosted its preference ahead of the pack.

The fix: Always maintain a running average reward baseline Rˉt=Rˉt−1+1t(Rt−Rˉt−1)\bar{R}_t = \bar{R}_{t-1} + \frac{1}{t}(R_t - \bar{R}_{t-1}). The baseline centers the reward signals around zero, ensuring that below-average rewards actively depress preferences (Rt−Rˉt<0R_t - \bar{R}_t < 0) and quickly reallocate exploration budget to promising arms.

The Quick Version

  • Preferences, not values: Gradient bandits maintain unbounded numerical preferences Ht(a)∈RH_t(a) \in \mathbb{R} rather than estimating expected reward values Q(a)Q(a).
  • Softmax exploration: Action selection probabilities πt(a)∝eHt(a)\pi_t(a) \propto e^{H_t(a)} naturally balance exploration without requiring hard cutoff thresholds or artificial ε\varepsilon-greedy coin flips.
  • Relative performance drives updates: The update rule Ht+1(a)=Ht(a)+α(Rt−Rˉt)(1a=At−πt(a))H_{t+1}(a) = H_t(a) + \alpha (R_t - \bar{R}_t)(\mathbf{1}_{a=A_t} - \pi_t(a)) rewards actions that beat the running average baseline Rˉt\bar{R}_t and penalizes actions that fall below it.
  • The baseline is vital: While theoretically unbiased without a baseline, omitting Rˉt\bar{R}_t causes preferences to drift upward unboundedly when rewards are positive, resulting in severe variance and crippled convergence.
  • Foundation of policy gradients: Gradient bandits are the single-state formulation of the Policy Gradient Theorem, directly inspiring algorithms like REINFORCE and PPO.