☰
Q-learning入门:从Q-table到Python迷宫实战,强化学习第一课
2026/10/5 6:05:10 网站建设 项目流程

1. 内容整体设计与思路拆解

1.1 为什么从Q-learning而不是深度学习入门强化学习

我接触强化学习也有几年了,带过不少新人入门,一个非常明确的体会是:如果直接扔给新手一套DQN(深度Q网络)代码,大多数人会当场懵掉——又是神经网络、又是经验回放、又是目标网络,光是跑通代码就要折腾半天,更别提理解背后的逻辑了。

而Q-learning这个算法,恰恰是强化学习里最适合作为“第一个算法”的那种存在。它的核心思想非常朴素:用一个表格(Q-table)记录“在某个状态下做某个动作,长期来看能拿到多少回报”,然后通过不断试错来更新这张表。没有反向传播,没有卷积网络,没有梯度下降,只需要一张几行几列的表格和一条更新公式,就能让一个智能体学会完成任务。

这一点对新手特别友好。我记得自己当年入门的时候,跑通第一个Q-learning迷宫示例时,那种“原来AI是这样学会走路的”的震撼感,要比后来调通第一个神经网络模型强烈得多。因为你能直观地看到知识是怎么进入表格的——某个格子的数值从0变成0.1,再变成0.5,渐渐地就能画出一条从起点到终点的“价值等高线”。

所以如果你准备学习强化学习,我的建议很清楚:先花一个晚上把Q-learning吃透,再决定要不要往深度方向走。这篇博文我会从最基础的思想讲到完整可跑的Python实现,最后分享一些我实际调试中踩过的坑和心得体会。全程只需要Python基础语法和一点点NumPy知识,用到的代码我都会完整贴出来。

1.2 一个生活化的类比:Q-learning到底在学什么

在接触公式之前,先打一个比方。想象你是一个刚搬进新城市的人,每天要从家(起点)走去公司(终点)。刚开始你完全不认识路,只能瞎走——碰到十字路口就随缘选一个方向。但每走一段路,你会有一些“反馈”:走到了死胡同,你记住了“这条路下次别选”;抄到了一条近道,你记住了“这条路以后可以优先考虑”。

时间一长,你对这个城市就有了自己的“认知地图”:每个路口对应着几个可选方向,每个方向在你心里都有一个“推荐分值”——分高的优先选,分低的尽量避开。这个“认知地图”,就是Q-table;也就是Q-learning中那个Q名字的来源——Quality,价值。

用术语来说:每个路口是“状态”(State),每个可选方向是“动作”(Action),走了某条路后获得的感受是“奖励”(Reward)。Q-learning要解决的,正是“在状态S下选动作A,到底值多少钱”这样一个问题。它不像人那样能观察全局,它只能靠一次次试错,把每个“状态-动作”组合的长期收益逐步估计准确。

这个类比贯穿全文。后面我们写的代码,本质上就是在帮一个“路痴智能体”建立一张类似的认知表格。区别只是它所在的环境比城市简单得多——通常是一个几个格子的迷宫网格。

2. 核心细节解析与实操要点

2.1 Q-table、状态、动作与奖励:四个必须吃透的概念

写代码之前,先把四个基本概念彻底讲透。它们不复杂,但如果你带着模糊的理解去写代码,后面调参的时候会非常痛苦。

状态(State):智能体在环境中每一个时刻所处的情形。在迷宫例子里,状态就是“当前在第几行第几列的格子”,比如(0, 0)表示左上角起点,(2, 2)表示右下角终点。在代码里,状态通常被编码成一个整数索引,比如0表示第一个格子,15表示第十六个格子,这样查表方便。动作(Action):智能体在某个状态下可以执行的决策。迷宫例子里就是“上、下、左、右”四个方向,代码里用0到3的整数代表。

奖励(Reward):环境对智能体行为的即时反馈。这里很多人容易糊涂——奖励不是“每一步应该拿多少分”的预设答案,而是环境设计者对任务目标的表达。比如走到终点给+1,撞墙给-1,普通步数给0。奖励设计是整个强化学习里最考验功力的部分,后面我会专门讲。

Q值(Q-value):Q(S, A)这个数字代表“在状态S下选择动作A,从这一刻开始一直到任务结束,能获得的期望累计奖励”。注意“累计”两个字——Q值不是只看眼前这一步,而是包含未来的收益。这正是Q-learning区别于普通贪心算法的关键所在:它懂得为了长远利益放弃眼前诱惑。

有了这四个概念,Q-table就是一张二维表格:行是状态数量,列是动作数量,单元格里存的就是Q值。比如我们的迷宫有16个格子(状态),上下左右4个动作,那Q-table就是一个16x4的矩阵。这个矩阵初始可以全部置零,然后智能体通过一次次与环境互动,不断修正表格里的数字。

2.2 奖励设置与折扣因子:长期收益如何计算

奖励设置直接决定智能体学到什么行为。还是拿迷宫来说,如果我把奖励设计成“到达终点获得+100”,那智能体学到的就是“怎么最快走到终点”;但如果我不小心把奖励设计成“每一步都给+1”,那智能体就会学到一个匪夷所思的策略——绕着迷宫转圈,永远不要到达终点,因为只要不结束就能一直拿分。

这个例子看起来夸张,实际上做强化学习项目时,奖励设计翻车是常态。我自己调过一个无人机避障的小项目,初期奖励没设好,无人机学出来的策略就是原地悬停——因为悬停不会有惩罚,而尝试飞行随时可能撞到障碍物。所以奖励设计有一条铁律:你奖励什么,它就学会什么。

再说折扣因子γ(gamma)。Q-learning的更新公式里有一项γ乘以“下一个状态的最大Q值”,它的含义是“未来收益的折现率”。γ取0.9,表示一步之后的收益在当前看来打九折;γ越接近1,智能体越“有远见”,愿意为了很远以后的收益牺牲当下的行动;γ越接近0,智能体越“短视”,只看重眼前利益。

迷宫这种短任务场景,γ取0.9到0.99都很常见。但假设你在做一个自动驾驶的模拟任务,任务时间跨度很长,γ就得非常接近1,否则几秒之后的收益在当前看来几乎等于零,智能体根本不会为长远规划付出努力。

2.3 epsilon-greedy策略:探索与利用的平衡艺术

这是Q-learning里最容易被新手忽略、却最影响训练效果的部分。

想象一个吃货去新城市找餐厅:如果只去自己评分最高的那家,永远不会发现更好的新店——这叫“只利用,不探索”;如果每天都随机挑一家从没吃过的店,又可能连续踩雷,而且已有的经验完全用不上——这叫“只探索,不利用”。合理的方式是:大部分时候选已知最好的,但留一部分概率去试试新店。

epsilon-greedy就是这个思想的实现:每次决策前,以epsilon的概率随机选一个动作(探索),以1-epsilon的概率选当前Q值最大的动作(利用)。epsilon通常从一个较大的值开始,比如0.9——前期的智能体基本在乱走,疯狂收集环境信息;随着训练推进,epsilon逐渐衰减到0.1甚至0.01,智能体越来越依赖已经学到的东西。

这里有一个关键心得:epsilon的衰减速度直接影响训练成败。衰减太快,智能体还没探索够就过早“锁定”策略,容易陷入局部最优;衰减太慢,智能体长期乱走,学到的Q值始终不稳定。我的经验是:先跑一个快速实验看大致的收敛步数,然后把主要训练阶段安排在epsilon从0.5衰减到0.1的这个区间内,这样效果通常比较稳。

3. 实操过程与核心环节实现

3.1 场景定义:一个4x4的网格迷宫

我们用一个经典的4x4网格迷宫来落地。迷宫结构很简单:

  • 16个格子,编号从0到15,第0格在左上角,第15格在右下角
  • 智能体从第0格出发(左上角)
  • 终点在第15格(右下角)
  • 动作有4个:0=上,1=下,2=左,3=右
  • 如果某方向越界(比如在最左边还要往左走),就视为撞墙,停在原地
  • 到达终点奖励+10;其他普通移动奖励0;撞墙奖励0但位置不变

代码实现里,我习惯用一个函数来封装“状态转移逻辑”,输入当前状态和动作,输出下一个状态、奖励、是否结束。这样一来,环境逻辑和算法逻辑分离,后面想换一个更复杂的环境,只需要替换这个函数。

这个例子虽然简单,但足够展示Q-learning的完整工作流程。如果你用gym库的话,类似的地图对应gym里的FrozenLake环境,区别是FrozenLake的地面是滑的(动作有概率不按预期执行),而且奖励设在“冰面坑洞”上。新手建议先在自己写的确定性环境上跑通,再碰gym的随机环境。

3.2 完整Python代码:不到100行实现Q-learning

下面是完整实现。我用纯Python加NumPy来实现,不引入任何深度学习框架,保证每一行你都能看懂。

import numpy as np import random # 环境参数 GRID_SIZE = 4 # 4x4网格 NUM_STATES = GRID_SIZE * GRID_SIZE # 16个状态 NUM_ACTIONS = 4 # 0=上, 1=下, 2=左, 3=右 # Q-learning 超参数 ALPHA = 0.1 # 学习率 GAMMA = 0.9 # 折扣因子 EPSILON_START = 0.9 # 初始探索率 EPSILON_END = 0.1 # 最小探索率 EPSILON_DECAY = 0.995 # 探索率衰减系数 NUM_EPISODES = 500 # 训练轮数 # 终点状态编号:右下角 (3, 3) -> 3 * 4 + 3 = 15 GOAL_STATE = 15 def get_next_state(state, action): """根据当前状态和动作,返回下一状态。越界则原地不动。""" row = state // GRID_SIZE col = state % GRID_SIZE if action == 0: # 上 row = max(row - 1, 0) elif action == 1: # 下 row = min(row + 1, GRID_SIZE - 1) elif action == 2: # 左 col = max(col - 1, 0) elif action == 3: # 右 col = min(col + 1, GRID_SIZE - 1) next_state = row * GRID_SIZE + col return next_state def get_reward(state): """到达终点的奖励为+10,其他为0。""" return 10 if state == GOAL_STATE else 0 def choose_action(state, q_table, epsilon): """epsilon-greedy策略选择动作。""" if random.uniform(0, 1) < epsilon: return random.randint(0, NUM_ACTIONS - 1) else: return int(np.argmax(q_table[state])) # 初始化Q表,16行4列全零 q_table = np.zeros((NUM_STATES, NUM_ACTIONS)) # 记录每个episode的总奖励,用于观察收敛情况 episode_rewards = [] epsilon = EPSILON_START for episode in range(NUM_EPISODES): state = 0 total_reward = 0 done = False while not done: action = choose_action(state, q_table, epsilon) next_state = get_next_state(state, action) reward = get_reward(next_state) done = (next_state == GOAL_STATE) # Q-learning核心更新公式 best_next_q = np.max(q_table[next_state]) q_table[state, action] += ALPHA * ( reward + GAMMA * best_next_q - q_table[state, action] ) state = next_state total_reward += reward # 防止极端情况死循环(正常情况下不会触发) if total_reward > 1000: break episode_rewards.append(total_reward) # epsilon衰减,但不低于下限 epsilon = max(EPSILON_END, epsilon * EPSILON_DECAY) # 每50轮打印一次训练进度 if (episode + 1) % 50 == 0: print(f"Episode {episode + 1}: Total Reward = {total_reward}, Epsilon = {epsilon:.4f}") print("\n训练完成!最终Q-table:") print(q_table)

这段代码的运行逻辑非常清晰。外层循环控制训练轮数(episode),内层循环让智能体从起点出发执行一系列动作直到到达终点。每一轮训练里,智能体执行四件事:根据epsilon-greedy选动作、环境返回下一个状态和奖励、用Q-learning公式更新表格、判断是否到达终点。

整个训练结束后打印出来的Q-table就是我们学习到的“认知地图”。观察每一行的最大值,就能解读出智能体在每个格子里最倾向往哪走。

3.3 核心更新公式逐项拆解

Q-learning的灵魂就是那一行更新公式,很多人因为看不懂这行就放弃了,其实拆开非常直白:

Q(S, A) = Q(S, A) + α * (R + γ * max(Q(S', a)) - Q(S, A))

从左往右逐项解释:

  • Q(S, A)是更新前的旧估值:之前我认为“在状态S下做动作A值多少分”。
  • R是刚拿到的即时奖励:这一步做了动作A之后,环境立刻给的反馈。
  • γ * max(Q(S', a))是未来收益的估计:到了新状态S'之后,如果后面每一步都选最好的动作,长期还能拿多少分,打个折扣算到现在。
  • R + γ * max(Q(S', a))是“现实”:根据实际观察到的结果,这一步动作真正值多少分。
  • Q(S, A) - 旧估值是“误差”:现实和原先想法的差距。
  • α是学习率,控制“用多快速度修正误差”。α越接近1,越相信新信息,旧经验一股脑推翻;越接近0,越保守,新信息的影响越小。

所以整行公式读起来就是一句话:新估值 = 旧估值 + 学习率 × (现实 - 旧估值)。这个形式和机器学习里常见的梯度下降更新非常像,理解了这个,以后看其他强化学习算法会轻松很多。

举个例子。假设智能体在状态5(就是第2行第1列),选择动作1(向下)走到了状态9(第3行第1列),当时Q值全是0,所以本来的估计是0。到了状态9发现它不是终点,即时奖励是0,但是状态9往下走到状态13那条路的Q值已经有8了(那是之前训练中探索出来的)。那“现实”就是0 + 0.9 × 8 = 7.2。于是状态5向下这个动作的Q值就从0更新为0.1 × 7.2 = 0.72。智能体逐渐意识到:虽然这一步本身没得分,但往下走以后能吃到肉,连锁反应就这样一环一环地从终点往回传导。

这个过程就是所谓的“时序差分学习”(Temporal-Difference Learning)。不需要等一整条轨迹走完再更新,而是每走一步就立刻用下一步的信息更新这一步的估值,效率非常高。

3.4 训练过程观察

跑完500轮训练后,你会看到类似这样的输出(因为随机性,每次运行的数字会略有差别):

Episode 50: Total Reward = 10, Epsilon = 0.7784 Episode 100: Total Reward = 10, Epsilon = 0.6007 ...

到了后期,绝大多数episode都返回10——也就是智能体总能找到终点。但你很可能注意到,前面几十轮经常返回0,也就是走了很久也没找到终点,这完全正常。前期的智能体基本在迷宫里瞎撞,Q-table里一片空白,只能靠epsilon高概率随机探索来“摸地图”。

这里我强烈建议你画一张“每轮总奖励”的曲线图,观察训练的收敛过程。画出图来你会发现一个有意思的现象:总奖励不是一个平滑上升的曲线,而是锯齿状跳动的——有时候连续十几轮都是10,突然又掉到0。那是因为epsilon还有一定概率让智能体随机乱走,它可能在一个曾经学会的路口做出错误动作,然后一路迷路。这是epsilon探索机制的正常副作用,不是bug。判断训练是否成功,看的是整体趋势和频率,而不是单个episode的表现。

如果你想画训练曲线,加几行代码就行:

import matplotlib.pyplot as plt plt.plot(episode_rewards) plt.xlabel('Episode') plt.ylabel('Total Reward') plt.title('Q-learning Training Curve') plt.show()

如果曲线在后期大部分时间都贴在上边界,说明策略已经稳定。如果还频繁掉下来,那就试试把epsilon的下限调低一点,或者增加训练轮数。

3.5 如何验证学习成果:回放策略

训练完了,怎么确认智能体真的学会了?光看Q-table的数字矩阵不够直观。一个非常有效的办法是回放:把epsilon强制设成0,让智能体每一步都走Q值最大的动作,然后把每一步的状态打印出来。

def show_policy(q_table): """用训练好的Q表走一次迷宫,打印完整路径。""" state = 0 path = [state] max_steps = 50 step = 0 while state != GOAL_STATE and step < max_steps: action = int(np.argmax(q_table[state])) state = get_next_state(state, action) path.append(state) step += 1 print("路径:", path) return path show_policy(q_table)

正常训练完毕后输出可能是:

路径: [0, 1, 2, 6, 10, 14, 15]

这条路径就很有讲究——从左上角出发,先右走两步,再一路向下,最后到达右下角。有些路径可能是 [0, 4, 8, 9, 13, 14, 15],先下到底再往右,同样是合法最短路径。因为终止条件是“到达终点即结束”,Q-learning不区分路径长短,只保证能找到终点。如果你追求“最短路径”,需要在训练中引入“每多走一步给一点负奖励”的设计,这是奖励塑形(Reward Shaping)的范畴了,后面我在扩展思路里会提。

我建议你把这个函数封装好,每次训练完都跑一遍,目测一下路径合不合理。很多时候Q-table里数字看上去很大、很好看,但回放路径乱七八糟,那八成是训练参数有问题,可以用这个手段快速debug。

4. 常见问题与排查技巧实录

4.1 Q-learning调参避坑清单

根据我的实操经验和带新人的记录,下面这些错误是新手踩得最频繁的。我整理成一张速查表,碰到问题先对照检查一遍:

问题现象常见原因排查方法
训练很久不收敛,总奖励一直在0附近学习率α太大,Q值震荡;或epsilon衰减太慢,一直乱探索把α调小到0.05~0.1;检查epsilon衰减曲线
前期收敛很快,后期效果崩坏epsilon衰减太快,早早丧失了探索能力调低epsilon衰减系数,让探索期拉长
Q-table数值爆炸式增长γ设置过大导致Q值发散,或奖励设计有循环刷分漏洞检查γ是否接近1,检查奖励设置是否有漏洞
每次运行结果差异巨大随机种子没固定,或训练轮数不够设置random.seed,增加训练轮数
回放路径绕路但能到达终点奖励设计没有对步数惩罚,智能体不追求最短路径在奖励里加“每步-0.1”之类的惩罚项

再补充两个容易被忽略的细节。

第一,如果使用NumPy和random库,固定随机种子的方式有两种,都写上才稳妥:

import random import numpy as np random.seed(42) np.random.seed(42)

不要以为固定了一个库的种子就万事大吉,两个库的随机流是独立的。

第二,在极小的地图(比如3x3)上训练时,Q-learning收敛得非常快,可能50轮就完全学会了。但这会带来一个陷阱——你以为自己已经完全理解了算法,实际上只是环境太简单,掩盖了理解漏洞。我建议你拿到代码后,立刻把地图改成5x5或者6x6,再加几堵墙进去,看看自己还能不能设计出合理的状态编码和奖励函数,这样才算是真的懂了。

4.2 死循环问题:为什么智能体永远走不到终点

这是我被问得最多的问题之一。很多初学者的代码里没有保护机制,当奖励全为0、终点又难找时,一个episode内智能体会一直走,永远不会结束,程序就卡死了。

有几个办法。一是给每个episode设置最大步数上限,比如100步、200步,到了就直接强制结束,进入下一个episode。我在上面的代码里写了total_reward超过1000就break的判断,实际项目里更通用的是用step计数器。二是检查移动逻辑:当动作导致越界时,很多人的写法会让状态保持在原地,但在密集奖励的场景(比如每走一步-0.1分)下,智能体可能会学会“在墙边反复撞墙”——因为撞墙不产生负奖励,什么也不做同样不产生负奖励,但探索新格子反而可能被扣分。这时候就会出现一个看起来极其笨、但完全符合奖励函数的策略。解决办法是给撞墙设置负奖励,比如-1。

from_state = get_next_state(state, action) if from_state == state: reward = -1 # 撞墙惩罚

这也再次印证了那个核心观点:智能体不会“理解”任务,它只会最大化你给的数字。

4.3 学习率和折扣因子的选择逻辑

关于α和γ,很多教程只会给“经验值”,从不解释为什么。我自己总结了三个判断维度,直接照着判断会比硬套经验值靠谱。

第一,任务是否随机。如果环境是确定的(就像本节的迷宫,每次动作的结果完全可预期),α可以取大一点,比如0.1到0.5,因为每条信息都是准确的,可以放心大胆地修改估值。如果环境有随机性(比如滑冰面,动作有20%概率不按预期执行),α就要调小,比如0.05到0.1,否则一次意外事件就会把学好的估值冲击得乱七八糟。

第二,任务奖励的稀疏程度。如果奖励很稀疏(比如只有终点才有奖励,中途全为0),γ要取得大一点(0.95以上),因为遥远未来的收益需要通过折扣链一步步反向传播,γ太小的话,终点奖励传不到几步就会衰减得接近于零,智能体根本感知不到。

第三,任务是否需要长远规划。一个episode内步数很少(比如小于20步)的任务,γ取0.9完全足够;但如果任务需要走几百步才能完成,γ至少0.99起步。这是一个很容易被忽略的计算:γ的N次方代表N步以后的收益折算到当下的比例,如果γ=0.9,10步以后的收益只剩0.9^10=0.35;但如果γ=0.99,100步以后的收益还有0.99^100=0.37。说白了,γ决定了智能体的“视野范围”。

拿这个逻辑来对照本节的迷宫:任务确定、奖励稀疏(只在终点有+10)、一个episode通常不超过10步,所以α=0.1、γ=0.9都是合理的。如果你把迷宫改成“每走一步-0.1”的版本,α可以不动,但γ可能要适当提高,因为奖励在每一站都出现,智能体更需要远期视距。

4.4 两种“迷宫”对比:自己的实现 vs OpenAI Gym的FrozenLake

很多教程把Q-learning的入门例子放在OpenAI Gym的FrozenLake环境里跑。FrozenLake是一个4x4的网格,和我们的自定义迷宫非常相似,但有一个关键区别:地面是滑的,动作不是百分之百生效——你选择“向右”,实际有三分之一的概率滑到旁边去。

这个随机性会显著改变学习难度。我实际跑下来的体感是:在确定性迷宫里,300轮左右就能稳定收敛;在FrozenLake里,2000轮也就勉强把成功率从0%拉到60%到70%左右。很多初学者在自定义迷宫上信心满满,换到FrozenLake后立刻被打击——Q值震荡、成功率上不去、训练曲线锯齿特别密集,于是以为自己代码写错了。

其实这不是代码问题,而是对随机环境的适应问题。随机环境里,优化目标从“找到一条确定的路径”变成了“找到一条在平均意义上期望收益最高的策略”,智能体必须学会在被“滑走”的情况下依然做出风险可控的选择。这类问题用Q-learning可以解,但效率一般,更高效的方案是Sarsa算法——它比Q-learning保守,在随机环境下表现往往更好。想到这一层,你就不再是“会跑代码”的程度,而是开始有算法选型的意识了,这才是入门之后的重要进阶方向。

如果你想把代码无缝切到FrozenLake上做对比,只需改动环境部分,核心的Q-learning更新代码一行都不用动:

# 用gym创建FrozenLake环境(需要安装gym库) import gym env = gym.make('FrozenLake-v1', is_slippery=True) state = env.reset()[0] ... next_state, reward, done, _, _ = env.step(action)

这种“环境替换、算法不变”的体验,是理解强化学习框架设计的最好练习之一。

5. 扩展思路与进阶方向

Q-learning代码跑通、迷宫学会走路之后,很多人会问“然后呢”。这确实是最关键的岔路口。我常把Q-learning的价值比作“学自行车”——它本身可能不够快,但帮你建立了平衡感,以后学摩托车、汽车就有了基础。从这个例子出发,至少有四个方向值得往前走一步。

第一个方向是奖励塑形。在迷宫例子里,奖励只在终点生效,智能体前期纯粹靠乱走碰运气。你可以试试给每步加上微小的负奖励(-0.1),看看智能体能不能学出更短路径;也可以在中途放一个“检查点”格子,走过就+5,看看它会怎么规划路线。这些改动会直观地让你体会到奖励设计对策略带来的巨大影响。

第二个方向是环境复杂度升级。把4x4网格扩展到8x8,加几堵墙,甚至做一个多楼层地图,这时候你会发现Q-table的行数越来越多,训练时间明显变长。这个痛感恰恰是引出深度强化学习的绝佳时机——当状态空间大到表格装不下,或者状态本身是连续值(比如坐标是浮点数)的时候,Q-table的方案彻底失效,这时你才会真正理解DQN用神经网络来替代Q-table的意义。

第三个方向是算法对比。把Q-learning和Sarsa放在同一个随机环境里比拼,观察两者的成功率差异,再引入一种叫做“期望Sarsa”的折中方案。这种对比实验是理解强化学习算法设计哲学的最佳路径,比单纯背公式有用得多。

第四个方向是应用场景迁移。Q-learning框架其实不局限于迷宫,把环境的状态、动作、奖励重新定义一下,就能迁移到非常多场景:在订单派发场景,状态可以定义为订单分布和骑手位置,动作是分配方案,奖励是配送时效;在游戏AI场景,状态是角色坐标和敌人位置,动作是移动方向,奖励是击杀得分;在推荐系统场景,状态是用户最近交互序列,动作是推荐内容,奖励是点击和停留时长。你会发现,环境定义的能力,才是应用强化学习的核心能力——算法本身反而是最标准化的部分。

我个人建议按这个顺序去探索,每个方向都花时间亲自动手改代码,而不是只看文章。尤其是奖励塑形,动手改上三五个版本,你对强化学习“如何引导智能体行为”的理解会上升一个台阶。

最后再分享一个实操中的小技巧:调试Q-learning代码时,把Q-table打印出来,用NumPy的argmax找出每个状态的最佳动作,再把动作翻译成箭头字符,直接输出成一张可视化地图。比如用“↑↓←→”象征四个方向,一眼就能看出智能体学到的策略长什么样——是不是在绕路、哪里存在策略漏洞、收敛状态如何,全部一目了然。这个小工具我直到现在做实验还会用,比盯着数字矩阵高效太多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询