十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

numpy-ml BanditTrainer 实战指南:多臂老虎机策略的训练、对比与可视化

numpy-ml BanditTrainer 实战指南:多臂老虎机策略的训练、对比与可视化 numpy-ml BanditTrainer 实战指南多臂老虎机策略的训练、对比与可视化【免费下载链接】numpy-mlMachine learning, in numpy项目地址: https://gitcode.com/gh_mirrors/nu/numpy-mlBanditTrainer是 numpy-ml 多臂老虎机Multi-Armed Bandit, MAB子模块中的训练与评估引擎位于 numpy_ml/bandits/trainer.py负责在指定老虎机环境上驱动策略policy进行多轮 trial 训练、记录逐 trial 的评估指标、生成平滑奖励与累积遗憾曲线并支持在完全相同的环境下横向对比多个策略。读完本文你将掌握BanditTrainer的全部公开 APItrain/compare、日志与指标结构、指数平滑与均方误差的计算原理并能直接在自己的 MAB 实验中复现仓库自带的可视化结果。一、BanditTrainer 在 numpy-ml bandits 模块中的定位numpy-ml 的 bandits 子模块由三个文件构成形成“环境—策略—训练器”的三层结构numpy_ml/bandits/bandits.py定义各类老虎机环境BernoulliBandit、MultinomialBandit、GaussianBandit、ShortestPathBandit、ContextualBernoulliBandit、ContextualLinearBanditnumpy_ml/bandits/policies.py定义探索策略EpsilonGreedy、UCB1、ThompsonSamplingBetaBinomial、LinUCB统一继承自抽象基类BanditPolicyBasenumpy_ml/bandits/trainer.py实现BanditTrainer把策略与环境“夹”在一起完成训练循环、日志记录、指标计算与绘图。BanditTrainer类只有两个公开方法——train单策略训练与compare多策略对比其文档由 Sphinx autodoc 从源码 docstring 生成对应文档页为 docs/numpy_ml.bandits.trainer.rst并被收录进 docs/numpy_ml.bandits.rst 的 toctree。也就是说该文档页的全部 API 说明、参数语义与返回约定均以trainer.py中的实现与 docstring 为唯一事实来源。从源码结构看trainer.py还额外提供了两个模块级辅助函数mse与smooth以及若干私有绘图/日志方法它们是train/compare的底层支撑下文会逐一展开。二、核心 API 一train()——在单个环境上训练一个策略train是BanditTrainer最常用的入口签名为def train( self, policy, # BanditPolicyBase 实例 bandit, # Bandit 实例环境 n_trials, # 每次运行duplicate内的 trial 数 n_duplicates, # 重复运行的次数 plotTrue, # 是否绘图 axesNone, # 指定 matplotlib 坐标轴可选 verboseTrue, # 是否打印运行统计 print_every100, # 每多少 trial 打印一次进度 smooth_weight0.999, out_dirNone, # 图保存目录None 则不保存 ):2.1 参数语义与默认值参数类型默认值说明policyBanditPolicyBase实例必填待训练的策略对象如EpsilonGreedy(epsilon0.05)banditBandit实例必填训练所在的老虎机环境如BernoulliBandit([...])n_trialsint必填每次运行内的试验trial次数n_duplicatesint必填对同一策略在同一环境上的重复运行次数越大对奖励/遗憾方差的估计越准plotboolTrue是否绘制该策略的平均奖励与遗憾曲线axesmatplotlib Axes 列表None若同时传入plotTrue且axes非空将使用给定的两个坐标轴分别绘制累积奖励与累积遗憾否则自动创建1x2子图verboseboolTrue是否打印运行统计print_everyint100每经过多少个 trial 向 stdout 打印一次当前遗憾verboseFalse时忽略smooth_weightfloat ∈ [0, 1]0.999绘图时的指数平滑权重越接近 0 平滑越弱越接近 1 平滑越强out_dirstr 或 NoneNone若plotTrue且out_dir非空将图以{policy_id}.png保存到该目录dpi300为None则不落盘返回值是训练完成后即最后一次 duplicate 运行结束的policy实例本身方便链式调用。2.2 训练循环与调用链train的核心执行逻辑对应 trainer.py对每个duplicated in range(n_duplicates)先执行bandit.reset()与policy.reset()把环境步数和策略参数如ev_estimates、pull_counts恢复到初始状态在n_trials个 trial 内循环调用私有方法_train_step(bandit, policy)_train_step的调用链为先从环境获取上下文C bandit.get_context()仅上下文环境存在该方法再调用rwd, arm policy.act(B, C)让策略选臂并取得奖励最后调用oracle_rwd, oracle_arm B.oracle_payoff(C)获取“上帝视角”的最优期望奖励与最优臂每个 trial 结束后将当次指标写入日志详见第四节并累加cregret累积遗憾verboseTrue时每print_every个 trial 打印Trial {t}/{T}, {d}/{D}, Regret: {regret}每次 duplicate 结束后调用_print_run_summary输出策略对各臂期望值的估计与真实值的对比。其中policy.act是 policies.py 中BanditPolicyBase定义的模板方法首次调用时自动_initialize_params(bandit)如把ev_estimates初始化为ev_prior随后依次执行_select_arm、_pull_arm、_update_params完成一次“选臂—采样奖励—更新参数”的完整交互。三、核心 API 二compare()——在同一环境下横向对比多个策略compare用于把多个策略放到同一个环境上做公平对比def compare( self, policies, # BanditPolicyBase 实例列表 bandit, # Bandit 实例 n_trials, # 每次运行内的 trial 数 n_duplicates, # 每个策略重复运行的次数 plotTrue, # 是否绘图 seedNone, # 随机种子用于复现 smooth_weight0.999, out_dirNone, # 图保存目录 ):3.1 参数语义参数类型默认值说明policiesBanditPolicyBase列表必填要对比的策略集合banditBandit实例必填所有策略共享的同一环境n_trialsint必填每次运行的 trial 数n_duplicatesint必填每个策略的重复运行次数重复越多对均值和方差的估计越稳健plotboolTrue是否生成对比图seedintNone若指定则对每个策略开始训练前执行np.random.seed(seed)保证各策略在完全相同的随机序列下运行smooth_weightfloat ∈ [0, 1]0.999绘图平滑权重语义同trainout_dirstr 或 NoneNone若plotTrue且非空对比图保存为{out_dir}/bandit_comparison.pngdpi3003.2 对比流程与公平性保证compare内部对每个策略依次调用trainverboseFalse因此n_duplicates、smooth_weight、out_dir等参数会被透传给train。它做了三件保证公平对比的事同一随机流当seed非空时每个策略在训练前都会执行np.random.seed(seed)使各策略面对相同的奖励序列环境与策略复位每个策略开始前都调用bandit.reset()与policy.reset()避免状态污染统一纵轴范围训练结束后compare收集所有子图的ylim取全体最小值与最大值再统一set_ylim让奖励与遗憾曲线可以在同一尺度下直观比较trainer.py。绘图布局为len(policies)行、2 列左列是“平滑平均奖励”右列是“平滑累积遗憾”每行标题为该策略的repr如EpsilonGreedy(epsilon0.05, ev_prior0.5)。文章开头展示的 comparison.png 正是仓库中plot_comparison脚本numpy_ml/plots/bandit_plots.py用compare对EpsilonGreedy、UCB1、ThompsonSamplingBetaBinomial三个策略在同一个随机 Bernoulli 环境10 臂上对比的产物左列蓝色曲线为平滑平均奖励及其 ±1 标准差阴影带右列红色曲线为平滑累积遗憾虚线为最优参照线最优期望奖励 / 零遗憾。四、日志结构 init_logs 与七大评估指标train/compare在执行前都会调用init_logs(policies)初始化训练日志。日志是一个按策略 id 分组的嵌套字典结构为log[model_id][metric][trial_number][duplicate_number]其中model_id是str(policy)即策略__repr__的字符串由hyperparameters字典中的id字段与其余超参数拼成见 policies.py。例如logs[EpsilonGreedy(epsilon0.05, ev_prior0.5)][regret][3][1]表示该策略第 2 次重复运行中第 3 个 trial 的单步遗憾。日志包含 7 个指标字段字段含义reward当次 trial 实际获得的奖励regret当次 trial 的遗憾单步regret oracle_reward - rewardcregret累积遗憾从第 1 个 trial 累加到当前 trialmse策略对每个臂期望值的估计与真实期望值之间的均方误差由模块级函数mse(bandit, policy)计算optimal_arm当次 trial 的最优臂 id来自bandit.oracle_payoffselected_arm策略当次实际选中的臂 idoptimal_reward当次 trial 最优臂的期望奖励oracle reward实现上每个字段都是一个defaultdict(lambda: [])key为 trial 编号从 1 开始value为按 duplicate 顺序追加的列表这正是上节提到的init_logs结构trainer.py。五、评估与可视化的底层原理5.1 mse()策略估计 vs 真实期望值模块级函数mse(bandit, policy)计算策略对臂期望收益估计的均方误差def mse(bandit, policy): if not hasattr(policy, ev_estimates) or len(policy.ev_estimates) 0: return np.nan se [] evs bandit.arm_evs # 环境真实的各臂期望值 ests sorted(policy.ev_estimates.items(), keylambda x: x[0]) for ix, (est, ev) in enumerate(zip(ests, evs)): se.append((est[1] - ev) ** 2) return np.mean(se)实现要点若策略尚无ev_estimates如LinUCB这类没有显式臂期望估计的策略返回np.nan否则按臂 id 排序后与环境的arm_evs逐臂求平方误差再取平均。_print_run_summary也会复用同一思路打印形如Arm 1: 0.3521 v. 0.3000的估计值与真实值对照以及Final MSE与Final Regret。5.2 smooth()指数平滑绘图前所有指标都会经过模块级函数smooth(prev, cur, weight)做指数平滑其递归公式为X̃_t ε·X̃_{t-1} (1 - ε)·X_t其中X_t是第 t 步的原始值X̃_{t-1}是上一步的平滑值ε即smooth_weight默认 0.999。ε越接近 0 平滑程度越弱、曲线越贴近原始信号越接近 1 平滑越激进、曲线越“钝”。smooth支持标量与形状为(N,)的数组因此可以按 duplicate 维度逐点平滑后再用_smoothed_metrics在每个 trial 上取均值sm_{m}_avg和标准差sm_{m}_std作为误差带。5.3 绘图细节_plot_reward使用 matplotlib 绘制左轴蓝色实线为平滑平均奖励sm_reward_avg蓝色虚线为最优期望奖励optimal_rwd并填充 ±1 标准差阴影带右轴红色实线为平滑平均累积遗憾sm_cregret_avg红色虚线为 0同样带阴影当通过compare传入axes时曲线绘于外部子图并设置set_title(str(policy))单独调用train时则自动创建1x2子图、suptitle为策略 repr并在out_dir非空时以{policy.hyperparameters[id]}.png保存dpi300。值得注意的依赖处理trainer.py在导入时try导入matplotlib.pyplot失败则发出DependencyWarning定义于 numpy_ml/utils/testing.py并将模块级开关_PLOTTING置为False。此后plotTrue也不会真正绘图或报错训练日志照常记录——这是纯 NumPy 环境下仍能跑通训练流程的关键设计。六、与策略、环境的配合关系BanditTrainer不关心策略与环境的具体实现只依赖BanditPolicyBase与Bandit的公共接口这使它天然适配仓库内全部组合策略侧policies.pyEpsilonGreedy、UCB1、ThompsonSamplingBetaBinomial、LinUCB均实现act/reset/hyperparameters/ev_estimates等接口环境侧bandits.py非上下文环境MultinomialBandit、BernoulliBandit、GaussianBandit、ShortestPathBandit不实现get_context_train_step会自动回退为C None上下文环境ContextualBernoulliBandit、ContextualLinearBandit提供get_context返回上下文矩阵oracle_payoff也按上下文返回对应最优臂。从源码结构看组合时有两处硬性约束均在策略初始化时以 assert 强制ThompsonSamplingBetaBinomial只允许搭配BernoulliBanditBeta-Bernoulli 共轭假设LinUCB只允许搭配ContextualLinearBandit线性报酬假设训练器本身不做额外校验。七、完整可运行示例仓库在 numpy_ml/plots/bandit_plots.py 中给出了覆盖全部策略与环境的示例脚本plot_epsilon_greedy_multinomial_payoff、plot_ucb1_multinomial_payoff、plot_thompson_sampling_beta_binomial_payoff、plot_lin_ucb、plot_ucb1_gaussian_shortest_path、plot_comparison。按 API 签名推荐的关键字参数写法如下。7.1 单策略训练import numpy as np from numpy_ml.bandits import BernoulliBandit from numpy_ml.bandits.policies import ThompsonSamplingBetaBinomial from numpy_ml.bandits.trainer import BanditTrainer np.random.seed(12345) bandit BernoulliBandit([0.7, 0.5, 0.3]) # 3 臂 Bernoulli 环境 policy ThompsonSamplingBetaBinomial(alpha1, beta1) # 5000 个 trial、重复 5 次绘制并保存图到 ./plots policy BanditTrainer().train( policypolicy, banditbandit, n_trials1, # 每个 trial 独立采样一次 n_duplicates5000, # 重复运行次数可调 plotTrue, verboseTrue, print_every100, smooth_weight0.999, out_dirplots, # 会保存 plots/ThompsonSamplingBetaBinomial.png )说明仓库的示例脚本plot_thompson_sampling_beta_binomial_payoff等以位置参数方式调用train传入顺序与签名(policy, bandit, n_trials, n_duplicates, plot, ...)对应上面改用关键字参数语义更清晰二者等价。若不需要落盘图片令out_dirNone即可。7.2 多策略对比import numpy as np from numpy_ml.bandits import BernoulliBandit from numpy_ml.bandits.policies import EpsilonGreedy, UCB1, ThompsonSamplingBetaBinomial from numpy_ml.bandits.trainer import BanditTrainer np.random.seed(1234) bandit BernoulliBandit([0.7, 0.5, 0.3]) policies [ EpsilonGreedy(epsilon0.05, ev_prior0.5), UCB1(C1, ev_prior0.5), ThompsonSamplingBetaBinomial(alpha1, beta1), ] BanditTrainer().compare( policiespolicies, banditbandit, n_trials1, n_duplicates5000, plotTrue, seed42, # 保证各策略面对相同随机序列 smooth_weight0.999, out_dirplots, # 保存 plots/bandit_comparison.png )运行后会得到 3 行 2 列对比图对应 comparison.png并额外打印每个策略的Estimated vs. Real EV与Final MSE / Final Regret汇总。八、使用注意事项绘图的软依赖没有安装 matplotlib 时绘图功能被静默禁用伴随DependencyWarning训练与日志记录不受影响安装后可通过from numpy_ml.bandits.trainer import BanditTrainer正常使用。复现性compare的seed只对策略训练前的np.random.seed生效train本身不设种子需要复现时可在外部自行np.random.seed如 bandit_plots.py 顶部所示。指标缺失对没有ev_estimates的策略如LinUCBmse指标为np.nan_print_run_summary也会跳过打印属预期行为。环境-策略匹配ThompsonSamplingBetaBinomial与LinUCB对环境的类型有硬性 assert 约束组合前请对照 bandits.py 中的环境清单。日志即数据训练结束后所有指标都保留在trainer.logs中可按第四节描述的log[model_id][metric][trial][duplicate]结构直接读取做进一步统计分析或自定义绘图无需重新训练。至此你可以用BanditTrainer在 numpy-ml 中完成从“单策略训练”到“多策略公平对比”再到“自定义指标分析”的完整 MAB 实验闭环。想进一步深入策略算法与环境实现的读者可继续阅读配套文档页 numpy_ml.bandits.policies.rst 与 numpy_ml.bandits.bandits.rst。【免费下载链接】numpy-mlMachine learning, in numpy项目地址: https://gitcode.com/gh_mirrors/nu/numpy-ml创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表