网易首页 > 网易号 > 正文 申请入驻

Q-Learning 入门:从零写一个 Gymnasium 的 grid world 项目

0
分享至

来源:市场资讯

(来源:DeepHub IMBA)

这篇文章的目标是要做的是一个自定义的 8×8 grid world。agent 从左上角出发,绕开墙壁,找到右下角的 goal。

agent 用 Q-Learning 训练,纯靠试错学习,没有任何的硬编码路径,也没有地图。


读到这个项目主要包括一下三个目标

  • 一个从零写起的自定义 Gymnasium 环境

  • 一个训练好的 Q-Learning agent,100% 到达 goal

  • 三张可视化:训练曲线、学到的 policy,以及和随机 agent 的并排对比

项目结构

 gridworld/├── grid_env.py       # 自定义 Gymnasium 环境├── agent.py          # Q-Learning agent├── train.py          # 训练循环 + 图表├── visualize.py      # 动画运行 + 对比└── requirements.txt

环境

Gymnasium 里一切都围绕一个类:gym.Env。继承它实现几个方法,这样创造的环境就和任意 RL 算法兼容。

 class GridWorldEnv(gym.Env):def __init__(self, render_mode=None):self.grid_size = 8self.max_steps = 200self.action_space = spaces.Discrete(4)          # up, right, down, leftself.observation_space = spaces.Discrete(64)    # 8x8 = 64 statesself.walls = {(1,1),(1,2),(1,3),(2,5),(3,5),(4,5),(5,2),(5,3),(5,4),(6,6)}self.start = (0, 0)self.goal  = (7, 7)

state space 就是 agent 在 grid 上的位置,被压平成 0 到 63 之间的一个整数。action space 有 4 个离散动作 —— up、right、down、left。

环境的逻辑全在step()方法。每次 agent 做出一个动作,step() 都会跑一遍:

 def step(self, action):moves = {0: (-1,0), 1: (0,1), 2: (1,0), 3: (0,-1)}dr, dc = moves[action]nr, nc = r + dr, c + dc# Stay in place if wall or boundaryif 0 <= nr < self.grid_size and (nr, nc) not in self.walls:self.agent_pos = [nr, nc]terminated = (tuple(self.agent_pos) == self.goal)if terminated:reward = 1.0else:dist = abs(self.agent_pos[0] - 7) + abs(self.agent_pos[1] - 7)reward = -0.01 - 0.001 * dist

两点要说明,一是 agent 撞墙不会崩只是停在原地,这是处理边界比较简单且实用的写法。二是 reward 由两部分组成:-0.01 的步长惩罚用来鼓励效率;一个基于距离的小惩罚,在训练早期把 agent 往正确方向轻轻推一下。+1.0 的大奖励只在到达 goal 那一刻给出。

这就是 reward shaping 加一些中间信号来引导学习,但不改变最优 policy。

agent.py

整个项目的核心是 Q-Learning 更新规则:

 Q(s,a) ← Q(s,a) + α * [r + γ * max_a' Q(s',a') - Q(s,a)]

代码如下:

 def update(self, state, action, reward, next_state, done):best_next = 0.0 if done else np.max(self.Q[next_state])td_target = reward + self.gamma * best_nexttd_error  = td_target - self.Q[state, action]self.Q[state, action] += self.alpha * td_error

Q-table 是一个形状 (64, 4) 的 NumPy 数组:每个 state 一行,每个 action 一列。从全零开始每一步之后就更新一次。

action 选择用 epsilon-greedy:

 def select_action(self, state):if np.random.rand() < self.epsilon:return np.random.randint(self.n_actions)   # explorereturn np.argmax(self.Q[state])                # exploit

训练初期 epsilon 接近 1.0,agent 几乎在乱走。随着训练推进epsilon 衰减到 0.05,agent 越来越多地利用已经学到的东西。这种探索-利用的权衡是 RL 的基本问题。

训练

训练循环就是本系列第 1 部分写过的那个 agent-environment 循环,落到代码就是:

 for ep in range(1, n_episodes + 1):obs, _ = env.reset()done = Falsewhile not done:action = agent.select_action(obs)next_obs, reward, terminated, truncated, _ = env.step(action)agent.update(obs, action, reward, next_obs, terminated or truncated)obs = next_obsagent.decay_epsilon()

重置环境,循环到 done,挑动作,走一步,更新 Q-table,重复。

运行:

 python train.py

训练 2000 个 episode 大约 10 秒。输出长这样:

Episode     Reward   Steps   Epsilon   Success200     -0.113    59.8     0.367     92.5%400      0.704    18.3     0.135    100.0%600      0.754    15.4     0.050    100.0%2000      0.764    14.9     0.050    100.0%

到第 400 个 episode,agent 已经 100% 能到达 goal,用大约 15 步完成。

训练曲线如下


训练结束后 train.py 会生成三张图,保存为 training_curves.png:

  • Episode reward —— 从低且嘈杂开始,随着 agent 学习上升并稳定下来

  • Steps per episode —— 随着 agent 找到更短路径而急剧下降

  • Success rate —— 达到 100% 并保持

reward 图早期那段噪声是 agent 在探索,乱走且经常失败,正常现象。

可视化学到的 policy


训练完成后可以把 greedy policy 提出来 —— 每个 state 上的最佳 action —— 画成一张箭头图,保存为 policy_values.png。

左图是 value function V(s) 的热力图。靠近 goal 的 state 是绿色(高 value),远离或被墙挡住的是红色(低 value)。可以看到 value 从 goal 一路向回传播 —— Bellman 方程在实践中就是这个样子。

右图把 policy 画成 grid 上的箭头。每个非墙、非 goal 的格子上标出 agent 会朝哪个方向走。箭头连成一条从 start 到 goal 的连贯路径,绕开每一堵墙。

def plot_policy_and_values(agent):V = np.max(agent.Q, axis=1).reshape(grid, grid)   # V(s) = max_a Q(s,a)policy = np.argmax(agent.Q, axis=1).reshape(grid, grid)arrows = {0: '↑', 1: '→', 2: '↓', 3: '←'}

随机 vs 已训练


整个项目里最有说服力的结果来自对比:

Random    TrainedAvg steps               182.6       14.0Success rate            23.5%     100.0%Best steps                 31         14============

随机 agent 在 grid 上漫无目的地走,200 步限制内只有 23% 的概率能找到 goal,找到时平均要 182 步。已训练的 agent 每次都直接到 goal14 步搞定。

强化学习的全部意义就在这里 —— 用一个能在所有 state 间泛化的 policy,替换掉随机试错。

跑可视化脚本还会生成 agent_run.gif,实时展示 agent 在 grid 上导航,身后还会画出路径轨迹:

python visualize.py

总结

Q-Learning 是 off-policy。 agent 可以用一个随机 policy 探索,仍然能学到最优 policy。原因在于更新里那个 max_a' Q(s', a'):它总是朝最优可能动作更新,与实际采取的动作无关。

Q-table 就是 policy。训练完之后环境就不再需要了。agent 学到的一切都在 Q-table 里。用 agent.save() 存起来,下次用 agent.load() 加载。

reward shaping 有用。去掉距离惩罚,agent 也能学会,只是慢。整形之后的 reward 在训练早期给了一个关于方向的提示,当 goal 离 start 较远、reward 又是稀疏的(只有成功才给 +1),这种提示能省掉大量从 goal 反向传播到 start 的 episode。

agent-environment 循环是通用的。从表格 Q-Learning 到 PPO 再到 RLHF,每一种 RL 算法跑的都是同一个基本循环。变化的只是 policy 怎么表示,以及更新规则怎么写。

代码

https://github.com/ES7/Reinforcement-Learning-Projects/tree/main

by Ebad Sayed

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
长得太美被导演占为己有,25岁生下3个孩子,如今个个都给她争光

长得太美被导演占为己有,25岁生下3个孩子,如今个个都给她争光

真的八卦小学弟
2026-05-08 17:10:05
我们为了圆明园憋屈了一百多年,一铲子挖出地下的降维打击,真正的硬骨头全在泥里

我们为了圆明园憋屈了一百多年,一铲子挖出地下的降维打击,真正的硬骨头全在泥里

马蹄烫嘴说美食
2026-05-09 04:34:47
为什么发达国家对中国都不友好?

为什么发达国家对中国都不友好?

新浪财经
2026-05-04 07:26:54
特朗普心腹到访北京,开口就要中国采购波音,王毅外长这次没惯着

特朗普心腹到访北京,开口就要中国采购波音,王毅外长这次没惯着

一个有灵魂的作者
2026-05-08 17:01:13
中国永不破产的15家央企:一铁、两核、三航、四油、五电

中国永不破产的15家央企:一铁、两核、三航、四油、五电

蜉蝣说
2026-05-08 16:54:18
3.6万公里外,两瓦功率:中国科学家捅破了大气层的“天花板”

3.6万公里外,两瓦功率:中国科学家捅破了大气层的“天花板”

科学火箭叔
2026-04-04 20:50:06
眼红啊!南宁一教师月薪14044元的截图引热议,网友:副高五级吧

眼红啊!南宁一教师月薪14044元的截图引热议,网友:副高五级吧

火山詩话
2026-05-06 07:43:22
再爆冷!雨果0-3,法国队大胜,5月10日凌晨王楚钦领衔战勒布伦兄弟

再爆冷!雨果0-3,法国队大胜,5月10日凌晨王楚钦领衔战勒布伦兄弟

林子说事
2026-05-09 11:32:49
你发现了没?在一个公司里但凡下属和领导发生过一次正面冲突,不管谁对谁错,但两人的关系绝对不可能再像以前一样

你发现了没?在一个公司里但凡下属和领导发生过一次正面冲突,不管谁对谁错,但两人的关系绝对不可能再像以前一样

励职派
2026-04-29 19:45:13
这就是烈士江姐的真实的样貌,并非演员扮演,货真价实的罕见照片

这就是烈士江姐的真实的样貌,并非演员扮演,货真价实的罕见照片

浩渺青史
2026-05-04 00:50:25
美媒终于意识到中国根本不期待特朗普访华,早已不再仰视美国!

美媒终于意识到中国根本不期待特朗普访华,早已不再仰视美国!

阿龙聊军事
2026-05-09 11:34:16
“4只皮皮虾1035元”店主事发次日病逝,年仅43岁;家人称其有基础病,事发前已脑出血,店铺收到多起威胁电话,不打算继续开业

“4只皮皮虾1035元”店主事发次日病逝,年仅43岁;家人称其有基础病,事发前已脑出血,店铺收到多起威胁电话,不打算继续开业

扬子晚报
2026-05-08 12:46:41
大搞权色钱色交易、利用职权为亲属吸收存款提供帮助,江西省政协原副主席胡幼桃被公诉

大搞权色钱色交易、利用职权为亲属吸收存款提供帮助,江西省政协原副主席胡幼桃被公诉

都市快报橙柿互动
2026-05-09 10:31:44
副总师说枭龙Block3不是终极版本,但改进潜力被发动机锁死了

副总师说枭龙Block3不是终极版本,但改进潜力被发动机锁死了

起喜电影
2026-05-09 11:50:02
“天下第一人”河北彩花出道8周年,2026年夏季相约台北!

“天下第一人”河北彩花出道8周年,2026年夏季相约台北!

吃瓜党二号头目
2026-05-09 10:07:58
五一各地旅游收入排名,河南381亿第二,北京没进前五,第一是谁

五一各地旅游收入排名,河南381亿第二,北京没进前五,第一是谁

丁丁鲤史纪
2026-05-07 14:04:42
与李荣浩的讨伐风波才结束,单依纯再破天花板,让整个娱圈沉默了

与李荣浩的讨伐风波才结束,单依纯再破天花板,让整个娱圈沉默了

何揎室内设计
2026-05-09 05:34:00
张志坤:关于解放台湾实现国家统一的若干意见(近2万字长文)

张志坤:关于解放台湾实现国家统一的若干意见(近2万字长文)

秦安战略
2026-05-09 11:58:24
日本可能与中国开战?日专家:与中国发生冲突,最长只能坚持一周

日本可能与中国开战?日专家:与中国发生冲突,最长只能坚持一周

原谅你
2026-05-09 10:54:00
中国对辽宁舰做了什么?为何俄海军司令刚一登舰,顿时脸色大变

中国对辽宁舰做了什么?为何俄海军司令刚一登舰,顿时脸色大变

蜉蝣说
2026-05-08 16:49:36
2026-05-09 14:00:49
新浪财经 incentive-icons
新浪财经
新浪财经是一家创建于1999年8月的财经平台
3156339文章数 7262关注度
往期回顾 全部

科技要闻

美国政府强力下场 苹果英特尔达成代工协议

头条要闻

牛弹琴:全世界十分意外 俄乌战场突然传来两个好消息

头条要闻

牛弹琴:全世界十分意外 俄乌战场突然传来两个好消息

体育要闻

成立128年后,这支升班马首夺顶级联赛冠军

娱乐要闻

张艺谋《印象刘三姐》全裸镜头引争议

财经要闻

Meta疯狂拥抱人工智能:员工苦不堪言

汽车要闻

轴距加长/智驾拉满 阿维塔07L定位大五座SUV

态度原创

数码
手机
本地
公开课
军事航空

数码要闻

国产电视称霸中国市场!三星、索尼等外资品牌合并份额不足3%

手机要闻

1299元!REDMI Pad 2 SE 4G版明日开售:双卡双待 随时上网/通话

本地新闻

用苏绣的方式,打开江西婺源

公开课

李玫瑾:为什么性格比能力更重要?

军事要闻

美伊突然再次交火 伊朗外长:战争准备程度是1000%

无障碍浏览 进入关怀版