尧图网站设计 尧图网站设计YAOTU DESIGN
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强化学习Reinforcement LearningRL是与监督学习、无监督学习并列的机器学习核心范式之一它解决的是「在不确定环境中持续做决策」的问题。本指南以 ML-For-Beginners 课程第 8 章8-Reinforcement/README.md为骨架围绕童话「彼得与狼」场景系统讲解 RL 的核心概念、环境与奖励函数的建模方式、Q-Learning 算法原理并结合仓库中的棋盘环境实现与 OpenAI Gym 的 CartPole 实验展示从离散状态到连续状态的完整实战路径。读完本文你将理解为什么教计算机玩游戏不能当分类问题处理并能复现一整套从随机游走到 Q-Table 收敛的寻路强化学习流程。机器学习第三大范式强化学习与「决策」课程前几章已经介绍了机器学习的两种基本问题形态监督学习Supervised数据集本身提供问题「示例答案」例如 4-Classification/README.md分类与 2-Regression/README.md回归无监督学习Unsupervised没有带标签的训练数据典型的例子是 5-Clustering/README.md聚类。强化学习RL被视作与此并列的第三大基础范式它的核心不是「拟合标签」也不是「发现结构」而是决策在每一步做出正确的选择或者至少从错误选择中学习。这一章引入两种不依赖人工标注数据的任务类型半监督学习Semi-supervised Learning拥有大量未标注数据可用它们对模型进行预训练强化学习Reinforcement Learning智能体agent通过在某个模拟环境中反复做实验来学会「如何表现」。可以把 RL 理解为「基于经验的试错决策」。例如设想一个受规则约束的模拟环境——股票市场当你施加一项新监管政策时其效果是正向还是负向若结果是负面的你需要接受这一负向强化从中学习并调整路线若结果为正则应基于这份正向强化继续推进。这也是「强化」二字的由来。本仓库为该章节设定的区域主题是**「彼得与狼」俄罗斯**——源自俄国作曲家谢尔盖·普罗科菲耶夫的著名音乐童话年轻的小主人公彼得勇敢地走出家门来到林中空地追捕那只狼。课程中训练机器学习算法帮助彼得完成两件事探索周边环境构建一张最优导航地图对应 Q-Learning 寻路学习使用滑板并在其上保持平衡以便移动得更快对应 CartPole 平衡问题。为什么教电脑玩游戏不是「分类问题」假设我们希望让计算机学会下棋或玩「超级马里奥」。要让电脑玩好游戏需要它在每个游戏状态下预测下一步动作。这看起来很像分类问题但实际上并不是——因为我们并没有「状态→正确动作」的现成数据集。即使我们有部分现成记录例如已收录的棋局、玩家玩马里奥的录像它们也几乎不可能覆盖足够数量的可能状态。因此与其寻找已有游戏数据强化学习的基本思路是「让计算机自己玩很多次然后观察结果」。此时延迟回报问题出现了在 RL 中我们通常要等到整局游戏结束才知道输赢无法仅凭一步棋就断言「这一步是好是坏」——多数情况下只有游戏结束时才会收到一次奖励。为了在这种不确定条件下训练模型应用强化学习必须具备两样东西环境Environment与模拟器Simulator允许我们把游戏反复玩很多次。模拟器要定义游戏的全部规则以及所有可能的状态states与动作actions。奖励函数Reward Function告诉我们每一步或每一局玩得有多好。我们将深入一种经典的 RL 算法——Q-LearningQ 学习它专门用于解决上述「延迟奖励 状态搜索」的问题。实战环境Peter 的 8×8 方格世界第一课 8-Reinforcement/1-QLearning/README.md 把 Peter 的世界建模成一个width×height的方形棋盘每个格子可以是以下六类之一格子类型含义地面 groundPeter 和其他角色可以行走水域 water显然无法行走树 / 草地 tree grass可以休息的地点苹果 apple正向目标Peter 乐于找到它来充饥狼 wolf危险目标应当规避这一环境在仓库中由独立 Python 模块 8-Reinforcement/1-QLearning/rlboard.py 实现。由于环境代码本身不是理解算法概念的关键课程直接在 Notebook 中导入它来生成棋盘from rlboard import * width, height 8, 8 m Board(width, height) m.randomize(seed13) m.plot()在 rlboard.py 源码中Board使用整数常量枚举了格子类型empty0 / water1 / wolf2 / tree3 / apple4randomize()会按num_water / num_wolves / num_trees / num_apples参数随机铺出水域、树林、狼与苹果并用随机数种子保证可复现——seed13正是让每次运行都能得到同一张示例棋盘的原因。Board.at()、is_valid()、move()等成员则分别承担查询当前格内容、校验坐标合法性、执行移动的职责。动作、策略与基线随机游走在上述世界中Peter 的目标是找到苹果、同时避开狼与其他障碍。为此他在任一位置可以选取四个动作之一上U、下D、左L、右R。课程将其定义为坐标增量字典actions { U: (0, -1), D: (0, 1), L: (-1, 0), R: (1, 0) } action_idx { a: i for i, a in enumerate(actions.keys()) }这里的两个关键术语是策略Policy智能体的行动方略是一个「在任意给定状态下返回动作」的函数。本问题中状态即整张棋盘含玩家当前位置目标Goal强化学习最终学到的是一个能高效解决问题的好策略。作为对照基线课程首先实现了最简单的策略——随机游走random walk在到达苹果前每一步都从合法动作中随机挑选一个方向。def random_policy(m): return random.choice(list(actions)) def walk(m, policy, start_positionNone): n 0 # number of steps if start_position: m.human start_position else: m.random_start() while True: if m.at() Board.Cell.apple: return n # success! if m.at() in [Board.Cell.wolf, Board.Cell.water]: return -1 # eaten by wolf or drowned while True: a actions[policy(m)] new_pos m.move_pos(m.human, a) if m.is_valid(new_pos) and m.at(new_pos) ! Board.Cell.water: m.move(a) break n 1把随机策略跑上 100 次并统计walk返回路径长度被狼吃掉或掉进水里返回-1可以看到平均路径长度约 3040 步——而距离最近的苹果平均只有 56 步。这说明随机游走「盲目乱转」是个非常低效的基线。从 rlboard.py 的实现看walk循环会一直持续到触达苹果返回步数或落入狼/水返回-1为止这也是我们评估任意策略的基本框架。奖励函数让「好坏」可以被量化要让策略变得聪明必须定义每个状态的好坏。课程用奖励函数为每个状态返回一个分数分数越高代表越好move_reward -0.1 goal_reward 10 end_reward -10 def reward(m, posNone): pos pos or m.human if not m.is_valid(pos): return end_reward x m.at(pos) if x Board.Cell.water or x Board.Cell.wolf: return end_reward if x Board.Cell.apple: return goal_reward return move_reward奖励函数的取值逻辑非常直白情形奖励走出棋盘 / 落入水域 / 撞上狼-10终局负奖励抵达苹果10目标奖励其他普通移动-0.1时间成本鼓励少绕路奖励函数设计的关键洞见是在绝大多数情况下我们只在游戏结束时才收到实质性奖励。因此算法必须「记住」那些最终带来正收益的中间步骤并提高其权重同时抑制导致坏结果的步骤——这正是接下来 Q-Learning 要解决的问题。Q-Learning 与 Q-Table记忆「每个状态下哪个动作更好」Q-Learning 的策略由一个称为Q-TableQ 表的函数或数据结构定义它记录「在给定状态下每个动作的『优良程度』」。之所以叫 Q-Table是因为通常方便把它表示成一张表或多维数组。棋盘尺寸为width×height于是 Q-Table 可以表示成形状为width × height × len(actions)的 numpy 数组import numpy as np Q np.ones((width, height, len(actions)), dtypenp.float) * 1.0 / len(actions)注意初始化时所有格子的值相等4 个动作即 0.25这正对应「随机游走」策略——每个状态下各动作同等「好」。把 Q 表传给m.plot(Q)后每个格子中央会出现一个指向偏好移动方向的「箭头」当所有方向等概率时便显示为一个圆点。而在 rlboard.py 的image()实现中每个空格箭头方向正是由该格 Q 值经probs()归一化后对四个方向的概率加权计算出来的——可视化与数据模型严格对应。贝尔曼方程处理延迟奖励的核心一旦开始移动每个动作都有对应奖励理论上我们可以依据「即时奖励最高」来选下一步。但大多数状态下的一步并不会立刻达成「吃到苹果」的目标所以无法立刻判断哪个方向更优。记住重要的不是即时结果而是模拟结束时的最终结果。为了刻画这种延迟奖励需要借助动态规划思想把问题递归地看待。假设当前处于状态s准备走到下一个状态s我们会获得即时奖励r(s,a)加上某种未来奖励。若 Q-Table 已正确反映每个动作的「吸引力」则在状态s我们应当选择使Q(s,a)最大的动作a故状态s处可获得的最佳未来奖励就是maxₐ Q(s,a)。由此得到计算 Q 值的贝尔曼公式Bellman EquationQ(s,a) ← (1-α)·Q(s,a) α·( r(s,a) γ·maxₐ Q(s,a) )其中γgamma折扣因子决定你应当更看重当前奖励还是未来奖励。γ 越接近 1智能体越有「远见」γ 偏小则更短视。学习算法伪代码基于贝尔曼方程课程给出了完整的学习算法骨架用相同数值初始化 Q-Table所有状态与动作设定学习率 α ← 1多次重复模拟从随机位置出发重复执行在状态s选择一个动作a执行动作移动到新状态s若触发终局条件或累计奖励过小退出本次模拟在新状态计算奖励r按贝尔曼公式更新 Q 函数Q(s,a)←(1-α)Q(s,a)α(rγ·maxₐQ(s,a))s←s更新总奖励并降低 α。探索与利用的平衡Explore vs. Exploit在上述伪代码第 2.1 步我们尚未说明「如何选动作」如果完全随机选动作智能体是在随机探索explore环境——会频繁「死亡」也会走到常规路线之外反之如果总是利用exploit已知的 Q-Table 取当前最优动作又会阻碍探索其他状态很可能找不到全局最优解。因此最佳策略是按 Q-Table 值的概率比例来选择动作初始 Q 值相等时它等价于随机选择随着对环境了解更多智能体越来越倾向于沿最优路线前进同时偶尔仍会尝试未探索的路径。Python 实战5000 次 Epoch 训练出导航策略在动手实现前需要先把 Q-Table 中的任意数值转成「各动作概率向量」def probs(v, eps1e-4): v v - v.min() eps v v / v.sum() return v加入一个极小量eps是为了避免初始情况下向量各分量相等除以 0。随后跑 5000 次实验epoch并把动作选择做成按 Q 值概率采样以平衡探索与利用lpath [] for epoch in range(5000): m.random_start() # 随机初始位置 n 0 cum_reward 0 while True: x, y m.human v probs(Q[x, y]) a random.choices(list(actions), weightsv)[0] dpos actions[a] m.move(dpos, check_correctnessFalse) # 允许移出棋盘以终止回合 r reward(m) cum_reward r if r end_reward or cum_reward -1000: lpath.append(n) break alpha np.exp(-n / 10e5) # 学习率随时间指数衰减 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.ipynb 完整复现学习率 α 采用指数衰减np.exp(-n / 10e5)训练越往后对 Q-Table 的修正越小折扣因子 γ 取 0.5即中等程度地看重未来奖励更新时直接引用m.move()前后坐标并通过Q[xdpos[0], ydpos[1]].max()实现贝尔曼方程中的「下一状态最大 Q 值」。训练结束后Q-Table 已记录「每个格子上哪个方向更吸引人」用m.plot(Q)即可看到箭头收敛到指向苹果的路径。可以用两种策略验证效果严格最优策略贪心取 Q 值最大方向——注意有时会「卡死」可能出现两个状态互为最优指向、智能体在两者间无限往返的情形此时需要手动中断 Notebook概率策略 qpolicy训练时同款的概率采样print_statistics(qpolicy)会得到36 步的平均路径长度相比随机游走的 3040 步大幅缩短接近「最近苹果距离 56 步」的理论上界。课程还给出了两个进阶挑战限制walk最大步数如 100以观察偶尔超时或禁止走回已访问过的位置以消除死循环。另外观察学习过程中平均路径长度的曲线会发现三个阶段性的现象——初期路径变长对世界一无所知、常被困在坏状态随后逐渐变短知识积累使达成目标更容易但仍会偏离最优路径去探索中期偶有突变随机过程可能用新值「破坏」已学到的 Q-Table 系数应通过降低学习率来缓解。这引出了超参数hyperparameters概念学习率 α、学习率衰减策略、折扣因子 γ 等与训练中直接优化出来的参数如 Q-Table 系数相区分寻找最佳超参数的过程称为超参数优化属于更进一步的专题。从离散走向连续第二课用 OpenAI Gym 让 Peter 学会「滑板」上一节的棋盘世界状态是离散的格点坐标8-Reinforcement/2-Gym/README.md 指出现实中很多问题如下棋同样具备「棋盘 规则 离散状态」的结构但还有大量问题状态是连续的由一个或多个实数描述。为让 Peter 逃离狼的速度更快第二课教他滑滑板并保持平衡——采用著名的CartPole倒立摆简化模型水平滑轨上有一个可左右移动的小车目标是让小车顶上的竖直杆保持平衡。课程使用的模拟环境是 OpenAI 维护的Gym仿真库它提供了从倒立摆到 Atari 游戏的各种环境。安装并初始化环境的代码为import sys !{sys.executable} -m pip install gym import gym import matplotlib.pyplot as plt import numpy as np import random env gym.make(CartPole-v1) print(env.action_space) print(env.observation_space) print(env.action_space.sample())每个 Gym 环境都对应两个关键定义观测空间observation space环境反馈给智能体的信息结构。CartPole 中每次返回 4 个数值——小车位置、小车速度、杆的倾角、杆的旋转速率动作空间action space可选动作集合。CartPole 的动作空间是离散的只有两个动作左和右。值得注意的是CartPole 中每一步的奖励恒为 1因为目标就是「存活得尽可能久」让杆尽量长时间保持竖直。这一环境有一个公认的「解决」判据连续 100 次试验的平均奖励达到 195。由于 Q-Learning 需要离散状态来建表第二课的核心工程问题是状态离散化state discretization课程给出了两种方案分箱bins已知数值区间时将区间切成若干 bin再用 numpy 的np.digitize把值替换为所属 bin 编号状态规模完全可控等比缩放取整把观测值除以固定步长再转整数如tuple((x/np.array([0.25, 0.25, 0.01, 0.1])).astype(np.int))。此法对无上下界的值如速度控制力较弱但极端取值在现实中很罕见实现最简单。与此同时Q-Table 的表示也随之调整上一课用固定形状张量8×8×2即可但 CartPole 观测空间维数不确定、部分取值无界所以第二课改用字典结构以(state, action)为键、Q 值为值未出现过的条目默认返回 0Q {} actions (0, 1) def qvalues(state): return [Q.get((state, a), 0) for a in actions]CartPole 的训练循环与超参数第二课设置的超参数与上一课略有不同保持恒定而非衰减便于对比实验超参数取值含义alpha0.3学习率每步对现有 Q 值修正的程度gamma0.9折扣因子未来奖励相对当前奖励的权重epsilon0.90探索/利用系数90% 情形按 Q-Table 概率选动作其余随机探索训练循环约 10 万次 epoch还引入了两个工程改进按每 5000 次迭代计算平均累计奖励来打印进度同时保存历史最优的Qmax与对应Qbest表——因为训练中平均累计奖励可能下降Q-Table 被「更差」的新值覆盖保留最佳快照可避免模型退化def probs(v, eps1e-4): v v - v.min() eps v v / v.sum() return v Qmax 0 cum_rewards [] rewards [] for epoch in range(100000): obs env.reset() done False cum_reward 0 while not done: s discretize(obs) if random.random() epsilon: # exploitation - 按 Q-Table 概率选动作 v probs(np.array(qvalues(s))) a random.choices(actions, weightsv)[0] else: # exploration - 随机动作 a np.random.randint(env.action_space.n) obs, rew, done, info env.step(a) cum_reward rew ns discretize(obs) Q[(s, a)] (1 - alpha) * Q.get((s, a), 0) alpha * (rew gamma * max(qvalues(ns))) cum_rewards.append(cum_reward) rewards.append(cum_reward) if epoch % 5000 0: print(f{epoch}: {np.average(cum_rewards)}, alpha{alpha}, epsilon{epsilon}) if np.average(cum_rewards) Qmax: Qmax np.average(cum_rewards) Qbest Q cum_rewards []把每个 epoch 的累计奖励画成原始曲线几乎看不出规律随机性太强因此需要计算滑动平均来观察趋势——np.convolve(x, np.ones(window)/window, modevalid)窗口取 100。滑动平均曲线能清楚看到奖励稳步爬升也暴露了「中途奖励回落」的抖动。为了更稳定地收敛可以让 α 从接近 1 逐步衰减后期只微调 Q 值并让 epsilon 缓慢上升逼近 1从探索为主过渡到利用为主。挑战题要求进一步验证把Qbest复制回Q观察效果或用np.argmax每步严格选最大 Q 值动作比较与概率采样的差异。所有步骤均可对照 2-Gym/notebook.ipynb 逐步执行。第二课给出一个重要结论Q-Learning 在「离散状态 离散动作」与「连续状态离散化后 离散动作」两类问题上都能奏效但当动作本身连续、或观测空间极为复杂如 Atari 游戏画面时就需要引入神经网络等更强大的技术——这正是更进阶的深度学习课程的主题。本节课程地图与配套练习整个强化学习章节第 8 章按以下顺序组织方便循序渐进地学习8-Reinforcement/1-QLearning/README.md强化学习与 Q-Learning 入门——Peter 的 8×8 棋盘寻路配套 notebook.ipynb 与 rlboard.py运行 Notebook 时需将二者放在同一目录下课后练习见 assignment.md8-Reinforcement/2-Gym/README.md使用 Gym 模拟环境——CartPole 滑板平衡配套 notebook.ipynb课后练习见 assignment.md目标是训练一个可以爬坡的 Mountain Car。小结通过「彼得与狼」这一贯穿全章的童话设定ML-For-Beginners 把强化学习最核心的思想串成了一条可动手复现的链路先用Board构造离散环境、用奖励函数表达目标、用随机游走建立低效基线再引入 Q-Table 与贝尔曼方程逐步逼近最优导航策略随后把同样的 Q-Learning 移植到 OpenAI Gym 的连续状态 CartPole 环境中借助状态离散化、字典型 Q-Table 与「探索/利用」超参数调优教会智能体在实时物理模拟里保持平衡。学习者只要提供「定义期望状态的奖励函数 允许智能体智能探索的机会」Q-Learning 便能自行学到足够好的策略——这正是强化学习范式区别于监督与无监督学习的独特价值所在。本章内容「Introduction to Reinforcement Learning」由 Dmitry Soshnikov 编写「彼得与狼」主题插画由 Jen Looper 创作。仓库的 sketchnotes/ml-reinforcement.png 还提供了一张覆盖 agent / states / actions / reward 概念的可视化速记图可作为通读本节的辅助材料。【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表