You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现强化学习练习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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 05:54:00