ARTICLE DETAIL

资讯详情

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

ML-For-Beginners Q-Learning 进阶作业实战:用能量与疲劳建模“更真实的世界“并学习战胜狼

ML-For-Beginners Q-Learning 进阶作业实战:用能量与疲劳建模“更真实的世界“并学习战胜狼 ML-For-Beginners Q-Learning 进阶作业实战用能量与疲劳建模更真实的世界并学习战胜狼【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners本篇指南基于 Microsoft ML-For-Beginners 强化学习课程中 Q-Learning 一课的进阶作业文档 assignment.it.md原文为 assignment.md 的意大利语译文展开结合仓库中的环境实现 rlboard.py、原始课件 notebook.ipynb 以及官方参考解答 assignment-solution.ipynb完整讲解如何把原版找苹果世界改造成带能量、疲劳与狼战斗的系统重定义状态空间、修改奖励函数、跑通 Q-Learning 训练流程并用随机游走基线做量化对比。读完后你将掌握如何为马尔可夫决策过程扩展状态表示、如何按游戏规则设计奖励函数、如何调 epochs / 学习率衰减等超参数以应对成功事件罕见的训练难题。1. 任务背景从找苹果到打狼本作业隶属于课程第 8 章 Reinforcement Learning 的第 1 课 1-QLearning。前序课件README 与 notebook中Peter 在一个 8x8 棋盘上几乎可以无限移动只要吃到苹果10就赢碰到狼或水-10就输奖励函数只与格子类型有关。作业文档开篇直接指出了这个世界的不真实之处并给出改造目标——在更真实的世界里Peter 必须偶尔停下来休息也要进食。作业要求实现以下5 条新规则移动消耗Peter 每从一处移动到另一处会损失能量energy并累积疲劳fatigue进食回能Peter 可以吃苹果apple来补充能量休息解乏Peter 可以在树tree或草地绿色格子上休息以消除疲劳即走到棋盘上带树或草的位置即可新目标Peter 需要找到狼并将其杀死而非原版中躲开狼战斗条件要杀死狼Peter 必须满足一定的能量与疲劳水平否则他会输掉战斗。注意规则 4 与原版 notebook 的关键差异原版中狼是纯粹的负奖励终止格end_reward -10而新世界中狼变成了博弈对象——到达狼的格子不再是必死而是触发一次取决于当前能量/疲劳的战斗判定。这正是本次作业奖励函数与状态空间都要重写的原因。2. 作业指令起点、必做项与两条关键提示作业 assignment.md 的Instructions部分给出三步操作要求译文版与英文版内容一致以原始 notebook 为起点使用 notebook.ipynb 作为解决方案的起点它包含 Board 环境、随机游走基线与 Q-Learning 训练循环改写奖励函数并训练按游戏规则修改奖励函数运行强化学习算法学习获胜的最佳策略保留随机游走并对比在自己的方案中保留负责随机游走策略的代码最后对比自己的算法与随机游走在胜/负局数上的结果。文档还给出两条重要的Note提示它们直接决定了解法的设计方向状态表示更复杂新世界中状态除了 Peter 的棋盘位置还必须包含疲劳与能量水平。作业允许三种等价实现路线把状态表示为元组(Board, energy, fatigue)为状态定义一个独立类可以让它继承自Board或者直接修改 rlboard.py 里的原始Board类。超参数需要调整尤其是 epochs 数量因为新游戏中成功事件与狼战斗并获胜是罕见事件rare event可以预期训练时间会远长于原版课件原版 5000 epochs。这两条提示与仓库中的证据相互印证参考解答 assignment-solution.ipynb 正是采用了独立state类路线并把训练轮数提升到了10000 epochs原版为 5000学习率衰减常数也从原版的np.exp(-n / 10e5)调整为np.exp(-n / 3000)衰减得更快。3. 状态建模state类承载棋盘 能量 疲劳原版世界中状态 棋盘 Peter 位置Q 表形状为width x height x len(actions)。新世界中若仍只用位置作状态Peter 走到狼时是否获胜就无法由状态决定——这违反马尔可夫性结果还取决于历史累积的能量/疲劳。因此参考解答新增了state类把三要素封装在一起class state: def __init__(self, board, energy10, fatigue0, initTrue): self.board board self.energy energy # 初始能量 10 self.fatigue fatigue # 初始疲劳 0 self.dead False if init: self.board.random_start() self.update() def at(self): return self.board.at() def update(self): if self.at() Board.Cell.water: self.dead True return if self.at() Board.Cell.tree: self.fatigue 0 # 规则3树下休息疲劳清零 if self.at() Board.Cell.apple: self.energy 10 # 规则2吃苹果能量回满到 10 def move(self, a): self.board.move(a) self.energy - 1 # 规则1移动扣 1 能量 self.fatigue 1 # 规则1移动加 1 疲劳 self.update() def is_winning(self): return self.energy self.fatigue # 规则5战斗判定条件以上代码取自 assignment-solution.ipynb。从参考实现的取值看具体游戏规则被落实为机制数值/条件对应作业规则初始能量 / 疲劳energy10, fatigue0初始状态设定每次移动energy - 1, fatigue 1规则 1踩到苹果energy 重置为 10规则 2踩到树/草地fatigue 重置为 0规则 3战斗判定energy fatigue 则胜规则 5到达狼格按战斗判定返回胜/负规则 4其中energy fatigue是参考解答对规则 5 中一定水平certain levels的具体化选择——作业文档本身只要求满足一定水平把阈值、权重改成你自己喜欢的形式如energy fatigue 2是允许的这正是评分标准里定义新世界规则的考察点。Board.Cell的格子类型常量定义在 rlboard.pyempty0, water1, wolf2, tree3, apple4。参考解答用m.randomize(seed13)固定随机种子默认参数num_water3, num_wolves1, num_trees5, num_apples3见 rlboard.py 的randomize方法保证所有实验在同一张棋盘上进行对比结果才可复现。4. 游戏循环新终止条件与随机游走基线原 notebook 的walk函数只有到苹果成功/ 到狼或水死亡两种结局。新世界里结局分成三种参考解答重写了walkdef random_policy(state): return random.choice(list(actions)) def walk(board, policy): n 0 # 步数 s state(board) while True: if s.at() Board.Cell.wolf: if s.is_winning(): return n # 成功杀死狼返回正步数 else: return -n # 失败战斗不敌返回负步数 if s.at() Board.Cell.water: return 0 # 溺水第三种结局 a actions[policy(m)] s.move(a) n 1返回值约定正数 胜狼值为步数、负数 败于狼、0 溺水。对应地统计函数改为按胜/负/溺三类计数def print_statistics(policy): s, w, n 0, 0, 0 for _ in range(100): z walk(m, policy) if z 0: w 1 # 被狼击败 elif z 0: n 1 # 溺水 else: s 1 # 获胜 print(fKilled by wolf {w}, won: {s} times, drown: {n} times)先跑随机游走基线。参考解答 notebook 中记录的输出为Killed by wolf 5, won: 1 times, drown: 94 times也就是说 100 局里随机游走只有约 1% 的胜率1 次杀死狼、94% 直接溺水。这组基线数字很重要它量化了新世界里随机策略有多弱也是作业要求的对比基准。由于获胜需要同时满足存活到狼与能量 疲劳两个条件而每次移动都会拉开能量与疲劳的差距随机游走几乎注定在战斗前就溺死或战败——这也解释了作业 Note 中战斗成功是罕见事件、训练会更慢的论断。5. 奖励函数把状态好坏写成可学习的信号作业的核心要求是Modify the reward function above according to the rules of the game。参考解答给出的奖励函数把即时状态量与终止奖励结合def reward(s): r s.energy - s.fatigue # 基础分能量减疲劳 if s.at() Board.Cell.wolf: return 100 if s.is_winning() else -100 if s.at() Board.Cell.water: return -100 return r设计要点非终止步的奖励r energy - fatigue始终为正初始为 10随移动逐步衰减。这意味着多走路本身是持续亏损的agent 被激励尽快找到有利路径同时也把能量/疲劳比这一隐变量直接写进了奖励梯度里agent 不需要显式理解体力规则也能从奖励差值中学到别走太久尽快去树下休息。终止奖励 ±100 量级远大于步进奖励保证最终结果战斗胜负、溺水主导价值估计符合 Q-Learning 处理延迟奖励的假设真正的大奖励只在回合末尾出现算法必须靠 Bellman 更新把信用回溯到前面的步。训练终止条件参考解答的学习循环用abs(r) 100判断回合结束——即只有到达狼格无论胜负或溺水才终止回合吃苹果和树下休息都只是状态重置不构成终止。6. Q-Learning 训练循环状态索引与超参数细节Q 表仍按位置索引形状width x height x len(actions)因为参考解答选择把 energy/fatigue 放进奖励与状态类而不是展开 Q 表的维度Q np.ones((width, height, len(actions)), dtypenp.float) * 1.0 / len(actions) # 初值 0.25 def probs(v, eps1e-4): v v - v.min() eps v v / v.sum() return v训练循环10000 epochs如下每一行都对应 Q-Learning 的标准步骤lpath [] for epoch in range(10000): # 随机起点新建一局energy10, fatigue0 s state(m) n 0 while True: x, y s.board.human v probs(Q[x, y]) # 由 Q 值导出动作概率探索/利用平衡 while True: a random.choices(list(actions), weightsv)[0] dpos actions[a] if s.board.is_valid(s.board.move_pos(s.board.human, dpos)): break # 只允许落在棋盘内的合法移动 s.move(dpos) # 移动并更新 energy/fatigue r reward(s) if abs(r) 100: # 终止胜/负狼 或 溺水 lpath.append(n) break alpha np.exp(-n / 3000) # 学习率随步数指数衰减 gamma 0.5 # 折扣因子 ai action_idx[a] Q[x, y, ai] (1 - alpha) * Q[x, y, ai] alpha * (r gamma * Q[x dpos[0], y dpos[1]].max()) n 1与原版课件notebook.ipynbREADME 中的 code block 8逐条对比关键差异及原因超参数/逻辑原版课件本作业参考解答原因epochs500010000获胜事件罕见需要更多探索作业 Note 明确提示学习率衰减np.exp(-n / 10e5)np.exp(-n / 3000)更快衰减后期稳定 Q 表折扣因子 gamma0.50.5不变越界处理check_correctnessFalse允许走出棋盘并终止回合内层 while 循环拒绝非法移动重抽动作新世界回合只在打狼/溺水时终止避免越界提前截断回合终止r end_reward or cum_reward -1000abs(r) 100新奖励函数只有 ±100 是终止信号这里体现了一个工程取舍参考解答通过动作重采样把 agent 约束在棋盘内使每回合必然走到终止格lpath每回合步数列表曲线因此更有统计意义。probs()中加eps1e-4是为了避免初始 Q 值全相等时出现 0/0这一点在 README 的 Python implementation 一节有同样说明。7. 结果对比Q-Learning 显著优于随机游走训练完成后用 Q 表派生的策略按 Q 值加权采样兼顾利用与残余探索走 100 局def qpolicy(m): x, y m.human v probs(Q[x, y]) a random.choices(list(actions), weightsv)[0] return a print_statistics(qpolicy)参考解答 notebook 中记录的输出为Killed by wolf 1, won: 9 times, drown: 90 times与基线won: 1, killed: 5, drown: 94相比胜率从约 1% 提升到约 9%战败数从 5 降到 1溺水占比基本持平。参考解答对此的结论是溺水案例明显减少但 Peter 仍不能总是杀死狼并建议读者继续做超参数实验epochs、alpha 衰减常数、gamma来进一步改善——这恰好呼应了作业 Note 中你可能需要调整超参数的要求也说明本作业的设计目标是让学习者亲身体验超参数优化hyperparameter optimization这一独立主题README 末尾Investigating the learning process一节同样强调学习率、学习率衰减与折扣因子这类超参数直接决定学习质量。最后参考解答把每回合步数lpath画成曲线plt.plot(lpath)来观察学习过程。结合 README 对原版学习曲线的三点解读先升后降、中途可能因 Q 表被覆写而突跳你可以用同一方法诊断自己的训练曲线持续下降说明策略在收敛突跳说明需要放缓学习率衰减。8. 评分标准Rubric作业文档附带的评分表用于自评你的解法达到哪个等级以下依据 assignment.md 的 Rubric 翻译整理等级标准优秀Exemplary提交的 notebook 包含新世界规则的完整定义、Q-Learning 算法实现与必要的文字说明Q-Learning显著优于随机游走。合格Adequatenotebook 已提交Q-Learning 已实现且优于随机游走但改进不显著或者 notebook 文档质量差、代码组织混乱。需改进Needs Improvement对重定义世界规则做了一些尝试但 Q-Learning 算法无法正常工作或奖励函数未完整定义。对照参考解答可以看出优秀档的构成要件完整的规则形式化state类 三条数值化机制、可运行的训练循环、保留随机游走基线并输出对比统计、以及m.plot(Q)/lpath曲线等文字化解释。9. 小结与延伸这篇作业的本质是一次MDP 重设计练习状态空间从位置扩展为位置 能量 疲劳终止集合从苹果/狼/水改为战斗胜负 溺水奖励从离散档位改为状态量函数 终止大奖。仓库中的完整证据链为规则定义见 assignment.md环境底层见 rlboard.py教学推导Bellman 方程、探索/利用、超参数讨论见 README.md 与 notebook.ipynb可运行参考解答见 assignment-solution.ipynb同目录还有 R 与 Julia 版本。在参考解答之上可以继续做的实验把is_winning的阈值改为energy fatigue k观察胜率对战斗条件的敏感度将 Q 表维度扩展到(width, height, energy_bins, fatigue_bins)以严格满足马尔可夫性或调整alpha衰减常数与 epochs验证作业 Note 中罕见事件导致长训练的判断。下一课 2-Gym 会把这些手工搭建的环境迁移到通用强化学习框架中。【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表