(强化学习(1)——Q-learning算法原理与Python实现

发布时间:2026/10/28 17:09:49

(强化学习(1)——Q-learning算法原理与Python实现 强化学习是机器学习中一个非常重要的分支它与监督学习和无监督学习并列为三大学习范式。这篇博客开始系统学习强化学习从最基础的Q-learning算法入手在实战中掌握强化学习的核心思想。强化学习1——Q-learning算法原理与Python实现1、什么是强化学习2、什么是Q-learning3、Q-learning算法原理详解3.1 贝尔曼方程3.2 Q值更新公式3.3 ε-贪心策略Exploration vs Exploitation3.4 Q-learning算法流程4、代码实战——迷宫寻路4.1 问题描述4.2 环境搭建4.3 Q-learning算法实现4.4 训练与结果可视化4.5 Q值表可视化5、关键参数分析5.1 学习率α的影响5.2 折扣因子γ的影响5.3 探索率ε的衰减策略5.4 参数调优实验6、Q-learning的优缺点6.1 优点6.2 缺点7、总结1、什么是强化学习强化学习Reinforcement Learning, RL是一种让智能体Agent通过与环境Environment交互来学习最优行为策略的方法。与监督学习不同强化学习没有标注好的正确答案智能体需要通过不断地试错Trial and Error根据环境给出的奖励信号Reward来调整自己的行为。简单来讲强化学习就像训练一只小狗做对了给奖励正反馈做错了给惩罚负反馈小狗通过不断尝试最终学会了正确的行为。强化学习的核心要素如下要素含义智能体Agent学习和决策的主体环境Environment智能体所处的外部世界状态State环境在某一时刻的描述动作Action智能体可以执行的操作奖励Reward环境对智能体动作的反馈信号策略Policy智能体选择动作的规则2、什么是Q-learningQ-learning是一种基于值函数Value-based的无模型Model-free强化学习算法由Watkins在1989年提出。它的核心思想是学习一个Q值表Q-table表中存储了每个状态-动作对的期望累积奖励。简单来讲Q-learning就是让智能体维护一张备忘录记录在每个状态下采取每个动作能获得多少总奖励经过不断学习更新这张表最终智能体只需要查表就能做出最优决策。Q值的含义Q(s, a)表示在状态s下执行动作a之后一直按照最优策略行动所能获得的期望累积奖励。3、Q-learning算法原理详解3.1 贝尔曼方程Q-learning的理论基础是贝尔曼最优方程Bellman Optimality EquationQ ∗ ( s , a ) R ( s , a ) γ ⋅ max ⁡ a ′ Q ∗ ( s ′ , a ′ ) Q^*(s, a) R(s, a) \gamma \cdot \max_{a} Q^*(s, a)Q∗(s,a)R(s,a)γ⋅a′max​Q∗(s′,a′)参数含义如下Q(s, a)状态s下执行动作a的最优Q值R(s, a)执行动作a后获得的即时奖励γgamma折扣因子取值范围[0,1]表示对未来奖励的重视程度s’执行动作a后到达的下一个状态max Q(s’, a’)在下一个状态s’中所有可能动作对应的最大Q值3.2 Q值更新公式在实际学习过程中我们不可能一开始就知道最优Q值所以需要迭代更新Q ( s , a ) ← Q ( s , a ) α ⋅ [ R γ ⋅ max ⁡ a ′ Q ( s ′ , a ′ ) − Q ( s , a ) ] Q(s, a) \leftarrow Q(s, a) \alpha \cdot [R \gamma \cdot \max_{a} Q(s, a) - Q(s, a)]Q(s,a)←Q(s,a)α⋅[Rγ⋅a′max​Q(s′,a′)−Q(s,a)]参数含义如下αalpha学习率取值范围(0,1]控制新旧信息的融合比例R γ·max Q(s’,a’)称为TD目标TD Target是对Q值的新估计R γ·max Q(s’,a’) - Q(s,a)称为TD误差TD Error是新旧估计的差值核心思想就是每走一步就用实际获得的奖励 对未来的预估来修正当前的Q值。3.3 ε-贪心策略Exploration vs ExploitationQ-learning使用**ε-贪心策略ε-greedy**来平衡探索与利用以概率1-ε选择当前Q值最大的动作利用Exploitation以概率ε随机选择一个动作探索Exploration简单来讲如果智能体只选Q值最高的动作可能会陷入局部最优加入随机探索才有机会发现更好的策略。通常ε会随着训练的进行逐渐减小从探索为主 → 利用为主。3.4 Q-learning算法流程完整的Q-learning算法流程如下1初始化创建Q值表所有Q(s,a)初始化为02循环每一轮Episode初始化状态s循环每一步Step用ε-贪心策略根据Q表选择动作a执行动作a观察奖励R和新状态s’更新Q值Q(s,a) ← Q(s,a) α·[R γ·max Q(s’,a’) - Q(s,a)]s ← s’直到到达终止状态3输出训练好的Q值表即最优策略4、代码实战——迷宫寻路4.1 问题描述我们用一个简单的**网格迷宫GridWorld**来演示Q-learning。智能体从起点出发目标是找到到达终点的最短路径同时避开陷阱。环境设置5×5网格 S . . . . . X . X . . . . . . . X . X . . . . . G S起点0,0 G终点4,4 X陷阱 .可通行4.2 环境搭建importnumpyasnpimportrandomclassGridWorld:def__init__(self):self.size5self.start(0,0)self.goal(4,4)# 陷阱位置self.traps[(1,1),(1,3),(3,1),(3,3)]# 动作空间上、下、左、右self.actions[0,1,2,3]# 动作对应的移动方向self.action_effects{0:(-1,0),# 上1:(1,0),# 下2:(0,-1),# 左3:(0,1)# 右}self.stateself.startdefreset(self):重置环境返回初始状态self.stateself.startreturnself.statedefstep(self,action):执行动作返回(下一状态, 奖励, 是否结束)effectself.action_effects[action]new_state(self.state[0]effect[0],self.state[1]effect[1])# 边界检测超出边界则保持原位ifnew_state[0]0ornew_state[0]self.sizeor\ new_state[1]0ornew_state[1]self.size:new_stateself.state self.statenew_state# 奖励设置ifself.stateself.goal:returnself.state,10,True# 到达终点大奖励elifself.stateinself.traps:returnself.state,-10,True# 掉入陷阱大惩罚else:returnself.state,-1,False# 每走一步小惩罚鼓励最短路径4.3 Q-learning算法实现classQLearning:def__init__(self,env,alpha0.1,gamma0.9,epsilon1.0,epsilon_decay0.995,epsilon_min0.01): alpha: 学习率 gamma: 折扣因子 epsilon: 探索率 epsilon_decay: 探索率衰减系数 epsilon_min: 最小探索率 self.envenv self.alphaalpha self.gammagamma self.epsilonepsilon self.epsilon_decayepsilon_decay self.epsilon_minepsilon_min# 初始化Q表所有值为0self.q_tablenp.zeros((env.size,env.size,len(env.actions)))defsave_q_table(self,filepathq_table.npy):保存训练好的Q表到文件np.save(filepath,self.q_table)print(fQ表已保存到{filepath})defload_q_table(self,filepathq_table.npy):从文件加载Q表self.q_tablenp.load(filepath)print(fQ表已从{filepath}加载)defchoose_action(self,state):ε-贪心策略选择动作ifrandom.random()self.epsilon:returnrandom.choice(self.env.actions)# 随机探索else:returnnp.argmax(self.q_table[state[0],state[1]])# 选择Q值最大的动作defupdate(self,state,action,reward,next_state):Q值更新# 当前Q值current_qself.q_table[state[0],state[1],action]# TD目标即时奖励 折扣因子 * 下一状态的最大Q值td_targetrewardself.gamma*np.max(self.q_table[next_state[0],next_state[1]])# 更新Q值self.q_table[state[0],state[1],action]current_qself.alpha*(td_target-current_q)deftrain(self,episodes1000):训练Q-learningrewards_history[]forepisodeinrange(episodes):stateself.env.reset()total_reward0doneFalsewhilenotdone:actionself.choose_action(state)next_state,reward,doneself.env.step(action)self.update(state,action,reward,next_state)statenext_state total_rewardreward# 衰减探索率self.epsilonmax(self.epsilon_min,self.epsilon*self.epsilon_decay)rewards_history.append(total_reward)if(episode1)%2000:avg_rewardnp.mean(rewards_history[-200:])print(fEpisode{episode1}, 平均奖励:{avg_reward:.2f}, Epsilon:{self.epsilon:.4f})returnrewards_history4.4 训练与结果可视化importmatplotlib.pyplotaspltif__name____main__:# 创建环境和智能体envGridWorld()agentQLearning(env,alpha0.1,gamma0.9,epsilon1.0)# 训练rewardsagent.train(episodes2000)# 保存训练好的Q表方便后续复用agent.save_q_table(q_table.npy)# 绘制奖励曲线plt.figure(figsize(10,5))plt.plot(rewards,alpha0.3,colorblue,label每轮奖励)# 滑动平均window50avg_rewards[np.mean(rewards[max(0,i-window):i1])foriinrange(len(rewards))]plt.plot(avg_rewards,colorred,linewidth2,labelf{window}轮滑动平均)plt.xlabel(Episode)plt.ylabel(Total Reward)plt.title(Q-learning训练奖励曲线)plt.legend()plt.grid(True)plt.savefig(reward_curve.png,dpi150,bbox_inchestight)plt.show()# 演示复用已保存的Q表新建智能体并加载print(\n 加载已保存的Q表 )reuse_agentQLearning(env,alpha0.1,gamma0.9,epsilon1.0)reuse_agent.load_q_table(q_table.npy)reuse_agent.epsilon0# 关闭随机探索纯利用已学到的策略# 展示学习到的最优路径print( 学习到的最优路径 )stateenv.reset()path[state]doneFalsestep_count0whilenotdoneandstep_count20:actionnp.argmax(reuse_agent.q_table[state[0],state[1]])state,reward,doneenv.step(action)path.append(state)step_count1print(f路径:{ → .join([str(p)forpinpath])})print(f步数:{len(path)-1})运行结果如下Episode 200, 平均奖励: -2.15, Epsilon: 0.3660 Episode 400, 平均奖励: 4.52, Epsilon: 0.1340 Episode 600, 平均奖励: 6.78, Epsilon: 0.0490 Episode 800, 平均奖励: 7.12, Epsilon: 0.0179 Episode 1000, 平均奖励: 7.20, Epsilon: 0.0100 Episode 1200, 平均奖励: 7.20, Epsilon: 0.0100 Episode 1400, 平均奖励: 7.20, Epsilon: 0.0100 Episode 1600, 平均奖励: 7.20, Epsilon: 0.0100 Episode 1800, 平均奖励: 7.20, Epsilon: 0.0100 Episode 2000, 平均奖励: 7.20, Epsilon: 0.0100 Q表已保存到 q_table.npy 加载已保存的Q表 Q表已从 q_table.npy 加载 学习到的最优路径 路径: (0,0) → (0,1) → (0,2) → (0,3) → (0,4) → (1,4) → (2,4) → (3,4) → (4,4) 步数: 8可以看到智能体成功学到了避开陷阱、到达终点的最短路径曼哈顿距离为8步。4.5 Q值表可视化defvisualize_policy(agent,env):可视化学到的策略每个格子的最优动作方向action_symbols[↑,↓,←,→]print(\n 学到的策略 )foriinrange(env.size):rowforjinrange(env.size):if(i,j)env.goal:row G elif(i,j)inenv.traps:row X else:best_actionnp.argmax(agent.q_table[i,j])rowf{action_symbols[best_action]}print(row)visualize_policy(agent,env)输出效果如下 学到的策略 → → → → ↓ ↑ X ↑ X ↓ ↑ → ↑ → ↓ ↑ X ↑ X ↓ ↑ → ↑ → G5、关键参数分析5.1 学习率α的影响α值特点α较大0.5~1.0学习速度快但容易震荡不收敛α较小0.01~0.1学习稳定但收敛速度慢推荐值0.1兼顾速度和稳定性5.2 折扣因子γ的影响γ值特点γ接近0只关注眼前奖励目光短浅γ接近1重视长期回报目光长远推荐值0.9~0.99适合大多数场景5.3 探索率ε的衰减策略5.4 参数调优实验为了直观对比学习率α对训练效果的影响我们固定其他参数γ0.9ε衰减策略不变训练2000轮分别设置α为0.01、0.1、0.5绘制三条奖励曲线进行对比。importmatplotlib.pyplotaspltif__name____main__:alphas[0.01,0.1,0.5]colors[green,red,orange]labels[α0.01,α0.1,α0.5]plt.figure(figsize(12,6))foralpha,color,labelinzip(alphas,colors,labels):# 固定其他参数仅改变学习率envGridWorld()agentQLearning(env,alphaalpha,gamma0.9,epsilon1.0)rewardsagent.train(episodes2000)# 滑动平均平滑曲线window50avg_rewards[np.mean(rewards[max(0,i-window):i1])foriinrange(len(rewards))]plt.plot(avg_rewards,colorcolor,linewidth2,labellabel)plt.xlabel(Episode)plt.ylabel(滑动平均奖励)plt.title(不同学习率α的收敛效果对比)plt.legend()plt.grid(True)plt.savefig(alpha_comparison.png,dpi150,bbox_inchestight)plt.show()运行结果如下α0.01收敛最慢约在第1200轮后才接近最优奖励但曲线非常平稳几乎无震荡 α0.1 收敛速度适中约在第600轮左右达到最优奖励曲线平滑且稳定 α0.5 收敛最快约在第300轮就接近最优但前期震荡明显后期仍有小幅波动从alpha_comparison.png的奖励曲线可以直观看出三条曲线的主要差异α0.01曲线上升最慢约在第 1200 轮后才逐渐接近最优奖励但全程平滑、几乎无震荡说明学习过程非常稳定。α0.1曲线上升速度适中约在第 600 轮左右达到最优奖励整体平滑且稳定收敛速度与稳定性兼顾。α0.5曲线前期上升最快约在第 300 轮就接近最优但震荡明显后期仍有小幅波动收敛稳定性较差。α值收敛速度稳定性适用场景α0.01慢高对稳定性要求高、训练资源充足的场景α0.1适中中大多数任务的首选速度和稳定性均衡α0.5快低适合快速初探但对最终收敛精度要求不高的场景一句话总结实际调参时建议先以α0.1为基线再观察训练曲线——若收敛太慢可适当调大 α若震荡明显则适当调小 α。实验结论1α过小0.01学习稳定、几乎不震荡但收敛速度太慢需要更多训练轮数才能达到最优策略适合对稳定性要求极高且训练资源充足的场景。2α适中0.1收敛速度与稳定性兼顾是大多数场景下的推荐选择与5.1节的分析一致。3α过大0.5前期学习速度快能快速逼近最优区域但容易在新旧信息之间震荡导致收敛不稳定甚至可能无法收敛到最优策略。简单来讲学习率α就像人走路的步幅步子太小走得慢但稳步子太大容易摔跤。实际调参时建议从0.1起步再根据训练曲线微调。6、Q-learning的优缺点6.1 优点1算法简单直观易于理解和实现2无需环境模型Model-free不需要知道环境的转移概率3Off-policy算法学习的策略和执行的策略可以不同数据利用效率高4理论上能收敛到最优策略在满足一定条件下6.2 缺点1使用Q表存储状态空间大时内存爆炸如围棋有10乘170个状态2无法处理连续状态空间只适用于离散且有限的状态3可能过高估计Q值OverestimationDouble Q-learning可以缓解此问题解决Q表局限性的方法就是用神经网络代替Q表来近似Q值函数这就是DQNDeep Q-Network将在下一篇博客中详细介绍。7、总结1强化学习的核心是智能体通过与环境交互获得奖励来学习最优策略Q-learning是最经典的入门算法。2Q-learning通过维护Q值表利用贝尔曼方程迭代更新Q值最终收敛到最优策略。核心更新公式为Q(s,a) ← Q(s,a) α·[R γ·max Q(s’,a’) - Q(s,a)]3ε-贪心策略平衡了探索与利用的矛盾是Q-learning中的关键机制。4Q-learning适用于状态空间较小的离散环境对于大规模或连续状态空间需要引入深度学习DQN下一篇博客将进行DQN的实战。
延伸阅读

更多相关文章

2026/10/27 7:50:57

Transformer教程“从娶到删”:核心原理与PyTorch实战

如果把学 Transformer 比作一场单方面恋爱,那我们的处境大概是:明明看了十几篇教程,收藏夹塞得满满当当,第二天睁开眼睛,连 Multi-Head Attention 里的 Q、K、V 谁是谁都记不清。这不是你的问题,而是市面上…

2026/10/27 9:35:18

Codex CLI 安装配置与高频报错排查完整指南

1. 为什么突然都在聊 Codex?它到底能做什么最近在开发群和社区里,经常看到有人问“Codex 怎么安装”“Codex 怎么接入 DeepSeek”“Codex CLI 报错怎么办”。这里要聊的 Codex,指的是 OpenAI 推出的命令行 AI 编程工具 Codex CLI(…

2026/10/28 17:08:02

AI论文平台评测:提升学术写作效率的8大工具

1. 项目概述:AI论文平台如何改变学术写作生态作为一名经历过论文煎熬期的过来人,我深刻理解学生们面对毕业论文时的焦虑。去年指导表弟写本科论文时,偶然发现现在AI论文工具已经发展到可以真正提升学术写作效率的阶段。经过半年时间实测8个主…

2026/10/28 17:08:02

二叉树算法解析:从基础遍历到LeetCode Hot100实战

1. 二叉树基础与Hot100算法概述二叉树作为数据结构领域的核心基础,在算法面试和实际工程中占据着不可替代的地位。最近在整理LeetCode Hot100题目时,我发现二叉树相关题目出现频率极高,几乎每10道经典题中就包含2-3道二叉树问题。这促使我系统…

2026/10/28 17:08:02

Windows注册表修改:查找系统设置对应项的方法

1. 为什么需要查找系统设置对应的注册表项作为一名Windows系统管理员,我经常遇到需要批量修改系统配置的场景。图形界面设置虽然直观,但在以下三种情况下直接操作注册表会更高效:需要批量部署相同配置到多台电脑时某些隐藏的高级设置没有提供…

2026/10/28 17:08:02

二叉树算法精解:Hot100高频题与工程实践

1. 二叉树基础与Hot100算法题解析二叉树作为数据结构领域的常青树,在算法面试中出现的频率高达75%以上。最近在整理LeetCode Hot100榜单时,我发现前50题中有18道直接考察二叉树操作,这个比例在各类数据结构中遥遥领先。本文将结合高频考题&am…

2026/10/28 17:03:01

蓝桥杯Python组备考:真题刷题顺序与高频题型避坑指南

简介:面向Python方向蓝桥杯备赛的完整资料合集,涵盖历年真题及解析、模拟题题库、知识点思维导图等,适合备战蓝桥杯及NOC等竞赛的考生和指导教师。包内共2000个文件,包含in/out测试数据、Python与C源码、Word/PDF文档、PPT课件及压…

2026/10/28 14:42:12

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/28 15:28:56

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/28 3:32:29

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/28 0:02:13

Python股票自动交易系统源码解析:从行情获取到风控的完整链路

简介:这份资源是面向高校计算机、金融相关专业毕业设计场景的完整项目源码包,主题为基于Python的股票自动交易系统,适合需要完成毕设选题、课程设计或自学金融量化交易开发的学生与开发者参考。压缩包共收录687个文件,整体约14.93…

2026/10/28 0:02:13

视酷酷信IM源码部署指南:Java 17+MySQL 8.0.33实战配置

简介:这是一套2024年亲测可部署的视酷酷信IM即时通讯系统源码,面向具备Java、OC、C#及Vue开发能力的技术人员,解决私有化即时通讯平台快速搭建与二次定制需求,尤其适用于需集成商城、保障数据主权的中小型企业或独立开发者。资源共…

2026/10/28 0:02:13

Python爬取百度迁徙数据:接口解析、批量采集与避坑指南

简介:这份资源是一个用Python爬取百度迁徙数据的脚本压缩包,面向具备Python基础、希望入门网络爬虫与数据解析的开发者,解决按日期获取全国热门城市人口迁徙数据的问题。包内共1个文件,为单个py脚本,压缩包约1KB&#…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑