ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

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

(强化学习(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的实战。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进