实现强化学习练习2.5 K-Arms Bandit Epsilon-Greedy策略结果不符求助
问题定位
你的代码存在4处核心错误,直接导致运行结果不符合预期:
- 动作选择逻辑错误:多了不必要的判断条件
or self.qStar.argmax() == 0,只要当前Q值最大的动作索引为0就强制随机选择动作,完全破坏了epsilon-greedy的贪婪选择逻辑,导致智能体无法稳定选择收益高的动作。 - 奖励分布设置错误:标准10臂赌博机的每个臂都有独立的真实期望收益,你目前所有臂的奖励都从
N(0, 0.01)采样,所有臂的期望收益完全一致,不存在最优臂,智能体自然无法学习到更高的收益。如果是练习2.5的非平稳设置,还需要在每一步给所有臂的真实q*加上小的随机游走噪声。 - 记录的收益值错误:你在
pull方法返回的是更新后的动作价值估计self.qStar[a],而非本次动作获得的真实奖励r,所以rewards数组存储的是估计值而非真实收益,绘制出来的曲线自然和预期不符。 - 初始判断逻辑冗余:你不需要单独判断初始时Q值全为0的情况,在Q值全相等时
np.argmax会默认返回第一个索引,此时你的epsilon概率已经覆盖了随机探索的需求,额外的判断反而会带来逻辑错误。
修正后参考代码
import numpy as np class k_arm: def __init__(self, iter, method="incrementally", is_nonstationary=True): self.iter = iter self.k = 10 self.eps = .1 # 初始化每个臂的真实期望q*,标准设置为服从N(0,1)分布 self.q_true = np.random.normal(0, 1, self.k) self.q_est = np.zeros(self.k) self.n = np.zeros(self.k) self.method = method self.is_nonstationary = is_nonstationary def pull(self): # 练习2.5非平稳设置:每一步给所有真实q*加随机游走噪声 if self.is_nonstationary: self.q_true += np.random.normal(0, 0.001, self.k) # 标准epsilon-greedy动作选择 if np.random.uniform() < self.eps: a = np.random.randint(self.k) else: a = self.q_est.argmax() # 采样当前动作的真实奖励 r = np.random.normal(self.q_true[a], 1) self.n[a] += 1 if self.method == "incrementally": self.q_est[a] += (r - self.q_est[a]) / self.n[a] # 返回真实奖励用于后续统计 return r
测试运行代码:
iter_num = 1000 rewards = np.zeros(iter_num) c = k_arm(iter_num, method="incrementally") for i in range(iter_num): rewards[i] = c.pull()
修正后运行即可得到符合预期的 reward 上升曲线。
内容的提问来源于stack exchange,提问作者merkwur
相关产品推荐
相关产品推荐

