探索与利用权衡
1. 概述
探索(Exploration)与利用(Exploitation)的权衡是强化学习的核心挑战之一。1 智能体需要在利用已知知识以获取即时奖励,和探索未知状态以获取潜在更高未来奖励之间做出权衡。
1.1 核心矛盾
| 方面 | 利用 (Exploitation) | 探索 (Exploration) |
|---|---|---|
| 目标 | 最大化当前期望奖励 | 发现更好的策略 |
| 风险 | 低 | 高 |
| 短期收益 | 高 | 低 |
| 长期收益 | 可能低 | 可能高 |
1.2 探索困境
多臂老虎机问题是最好的例子:
假设有 个老虎机臂,每个臂 的奖励分布为 ,但 未知。
探索-利用权衡:
- 选择已知高奖励的臂:可能错过真正的最佳臂
- 探索未知臂:可能获得更高奖励但也可能是低奖励
2. 探索策略分类
2.1 策略总览
探索策略
├── 随机探索
│ ├── ε-Greedy
│ ├── Boltzmann Exploration
│ └── 噪声注入
├── 确定性探索
│ ├── UCB (Upper Confidence Bound)
│ └── Thompson Sampling
├── 基于不确定性的探索
│ ├── 内在奖励 (Intrinsic Motivation)
│ ├── 不确定性估计
│ └── 信息增益
└── 基于计数的探索
├── 哈希方法
└── 伪计数
2.2 随机探索策略
2.2.1 ε-Greedy
最简单直接的探索策略:
def epsilon_greedy(Q, epsilon, n_arms):
if random.random() < epsilon:
return random.randint(0, n_arms - 1) # 探索
else:
return argmax(Q) # 利用变体:
- 线性衰减:
- 指数衰减:
- 分段常数:2
2.2.2 Boltzmann Exploration
基于softmax的概率探索:
def boltzmann_exploration(Q, tau):
probs = softmax(Q / tau)
return np.random.choice(len(Q), p=probs)温度参数 的影响:
- :趋向贪婪
- :趋向均匀
2.2.3 噪声注入
在动作或策略上添加噪声:
# 动作噪声
action = policy(state) + noise
# 参数空间噪声
policy_params = policy_params + noise3. 确定性探索策略
3.1 UCB (Upper Confidence Bound)
核心思想:不仅考虑平均奖励,还考虑不确定性。
其中:
- :臂 的平均奖励估计
- :臂 被选择的次数
- :探索常数
置信度上界:
3.2 UCB1算法
class UCB1:
def __init__(self, n_arms, c=2.0):
self.n_arms = n_arms
self.c = c
self.counts = [0] * n_arms
self.values = [0.0] * n_arms
def select_arm(self, t):
for arm in range(self.n_arms):
if self.counts[arm] == 0:
return arm # 探索未访问臂
ucb_values = [
self.values[arm] +
self.c * np.sqrt(np.log(t) / self.counts[arm])
for arm in range(self.n_arms)
]
return argmax(ucb_values)
def update(self, arm, reward):
self.counts[arm] += 1
n = self.counts[arm]
value = self.values[arm]
self.values[arm] = ((n - 1) / n) * value + (1 / n) * reward3.3 Thompson Sampling
贝叶斯方法:维护奖励的后验分布。
class ThompsonSampling:
def __init__(self, n_arms, prior_alpha=1, prior_beta=1):
self.n_arms = n_arms
# Beta分布参数 (用于伯努利奖励)
self.alpha = [prior_alpha] * n_arms
self.beta = [prior_beta] * n_arms
def sample(self):
# 从后验分布采样
samples = [np.random.beta(self.alpha[i], self.beta[i])
for i in range(self.n_arms)]
return argmax(samples)
def update(self, arm, reward):
# 更新后验
self.alpha[arm] += reward
self.beta[arm] += (1 - reward)4. 基于不确定性的探索
4.1 内在奖励框架
总奖励分解:
其中 是内在奖励, 是权重。
4.2 好奇驱动学习 (ICM)
ICM模型3 提出预测状态变化作为内在奖励:
class ICM:
def __init__(self, state_dim, action_dim, feature_dim=64):
# 特征编码器
self.encoder = nn.Sequential(
nn.Linear(state_dim, 256),
nn.ReLU(),
nn.Linear(256, feature_dim)
)
# 逆向模型:预测动作
self.inverse_model = nn.Sequential(
nn.Linear(feature_dim * 2, 256),
nn.ReLU(),
nn.Linear(256, action_dim)
)
# 正向模型:预测下一状态特征
self.forward_model = nn.Sequential(
nn.Linear(feature_dim + action_dim, 256),
nn.ReLU(),
nn.Linear(256, feature_dim)
)
def intrinsic_reward(self, state, next_state, action):
with torch.no_grad():
f_s = self.encoder(state)
f_s_next = self.encoder(next_state)
# 预测的动作
pred_action = self.inverse_model(torch.cat([f_s, f_s_next], dim=1))
# 预测的下一状态特征
pred_f_next = self.forward_model(torch.cat([f_s, action], dim=1))
# 预测误差作为内在奖励
reward = 0.5 * F.mse_loss(pred_f_next, f_s_next)
return reward4.3 随机网络蒸馏 (RND)
核心思想:使用随机初始化网络作为预测目标。
class RND:
def __init__(self, state_dim, hidden_dim=256):
# 固定随机网络 (目标)
self.target_net = nn.Sequential(
nn.Linear(state_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, hidden_dim),
)
for p in self.target_net.parameters():
p.requires_grad = False
# 可学习网络 (预测器)
self.predictor_net = nn.Sequential(
nn.Linear(state_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, hidden_dim),
)
def intrinsic_reward(self, state):
with torch.no_grad():
target = self.target_net(state)
prediction = self.predictor_net(state)
# 预测误差
return F.mse_loss(prediction, target, reduction='none').mean(dim=1)4.4 信息增益探索
状态-动作信息增益:
实际计算中的近似:
5. 基于计数的探索
5.1 伪计数方法
在连续状态空间中,使用密度模型估计访问计数。
Hashing Trick:
class HashingCounter:
def __init__(self, state_dim, hash_dim=10):
self.hash_dim = hash_dim
self.projection = np.random.randn(state_dim, hash_dim)
def get_count(self, state):
hash_key = self.hash_state(state)
return self.counts.get(hash_key, 0)
def hash_state(self, state):
return tuple(np.sign(state @ self.projection).astype(int))
def update(self, state):
hash_key = self.hash_state(state)
self.counts[hash_key] = self.counts.get(hash_key, 0) + 15.2 Bitmap方法
使用像素级图像作为状态哈希键。
6. 内在奖励计算方法
6.1 主流内在奖励类型
| 方法 | 内在奖励 | 理论基础 |
|---|---|---|
| ICM | pred_error | 预测误差 = 好奇心 |
| RND | MSE(pred, target) | 预测随机目标 |
| DISagreement | Var(Q values) | 模型不确定性 |
| Count-based | 访问计数 |
6.2 内在奖励归一化
def normalize_intrinsic_reward(reward, eps=1e-8):
"""Running mean normalization"""
if not hasattr(self, 'running_mean'):
self.running_mean = 0
self.running_var = 1
self.count = 0
self.count += 1
delta = reward - self.running_mean
self.running_mean += delta / self.count
delta2 = reward - self.running_mean
self.running_var += delta * delta2
if self.count > 1:
std = np.sqrt(self.running_var)
return (reward - self.running_mean) / (std + eps)
return reward7. 探索策略在深度RL中的应用
7.1 DQN中的探索
def epsilon_decay_schedule(episode, eps_start=1.0, eps_end=0.01, eps_decay=1000):
return max(eps_end, eps_start - episode / eps_decay)7.2 DDPG/TD3中的探索
# 添加时间相关探索噪声
class OUNoise:
def __init__(self, action_dim, mu=0, theta=0.15, sigma=0.2):
self.mu = mu
self.theta = theta
self.sigma = sigma
self.state = np.zeros(action_dim)
def sample(self):
self.state += self.theta * (self.mu - self.state) + \
self.sigma * np.random.randn(len(self.state))
return self.state
# 在TD3中使用
noise = OUNoise(action_dim)
action = policy(state) + noise.sample()7.3 PPO/SAC中的探索
PPO 和 SAC 使用随机策略进行隐式探索:
- PPO:通过熵奖励项
- SAC:通过最大熵框架
8. 探索策略选择指南
8.1 根据任务特性选择
| 任务特性 | 推荐策略 |
|---|---|
| 稀疏奖励 | 内在奖励、ICM、RND |
| 连续状态 | RND、伪计数 |
| 多峰环境 | 最大熵RL、Boltzmann |
| 短horizon | ε-greedy、UCB |
| 长horizon | 内在奖励、信息增益 |
8.2 探索强度调节
class AdaptiveExploration:
def __init__(self, strategy='ucb', initial_eps=1.0, min_eps=0.01):
self.strategy = strategy
self.eps = initial_eps
self.min_eps = min_eps
def update(self, episode, performance_improving):
if self.strategy == 'epsilon_decay':
# 基于表现的衰减
decay_rate = 0.995 if performance_improving else 0.999
self.eps = max(self.min_eps, self.eps * decay_rate)
elif self.strategy == 'annealing':
# 固定衰减
self.eps = max(self.min_eps, self.eps * 0.995)9. 探索评估指标
9.1 覆盖率
9.2 熵
9.3 访问均匀性
10. 总结
探索-利用权衡是强化学习的核心问题:
10.1 策略对比
| 策略 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| ε-Greedy | 简单 | 可能次优 | 基线、离散 |
| UCB | 有理论保证 | 需要离散 | Bandits |
| Thompson | 贝叶斯最优 | 计算成本 | 多臂老虎机 |
| ICM | 处理高维 | 需要额外网络 | 稀疏奖励 |
| RND | 简单有效 | 可能退化 | 视频游戏 |
| 最大熵 | 理论基础 | 温度敏感 | 连续控制 |
10.2 最佳实践
- 任务初期:高探索率
- 任务中期:自适应调整
- 任务后期:低探索率
- 安全关键:保守探索
参考资料
相关主题
- soft-actor-critic — 最大熵RL算法
- maximum-entropy-rl-theory — 最大熵理论
- dqn — DQN及其探索策略
- td3-twin-delayed-ddpg — TD3探索噪声
- ppo — PPO中的熵奖励
Footnotes
-
Sutton, R. S., & Barto, A. G. (2018). Reinforcement Learning: An Introduction (2nd ed.). MIT Press. ↩
-
Tokic, M. (2010). Adaptive ε-greedy exploration in reinforcement learning based on value differences. KI 2010. ↩
-
Pathak, D., Agrawal, P., Efros, A. A., & Darrell, T. (2017). Curiosity-driven Exploration by Self-supervised Prediction. ICML. ↩