强化学习笔记+代码(三):Q-learning算法原理和Agent实现

£神魔★判官ぃ 2023-07-18 02:35 121阅读 0赞

本文主要整理和参考了李宏毅的强化学习系列课程和莫烦python的强化学习教程
本系列主要分几个部分进行介绍

  1. 强化学习背景介绍
  2. SARSA算法原理和Agent实现
  3. Q-learning算法原理和Agent实现
  4. DQN算法原理和Agent实现(tensorflow)
  5. Double-DQN、Dueling DQN算法原理和Agent实现(tensorflow)
  6. Policy Gradients算法原理和Agent实现(tensorflow)
  7. Actor-Critic、A2C、A3C算法原理和Agent实现(tensorflow)

一、Q-learning算法原理

先回顾一下RL的一些知识和SARSA。
Q-learning是一种value_based的方法。Q-learning与SARSA算法形式十分相近,但 Q-learning再执行动作a到达状态s’后,无需再执行动作a_来得到 Q ∗ ( s , a ) = r + γ Q ( s ′ , a ′ ) Q_*(s,a)=r+γQ(s’,a’) Q∗(s,a)=r+γQ(s′,a′)
而直接从s’观察状态所执行的动作得到的最大值, Q ∗ ( s , a ) = r + γ m a x [ Q ( s ′ , _ ) ] Q_*(s,a)=r+γmax[Q(s’,\_)] Q∗(s,a)=r+γmax[Q(s′,_)]。可见, Q-learning并未真实实行动作a’,而是通过观察来获得s’状态下的动作的最大价值。因此属于off-policy的方法。
Q-learning具体算法流程如下:
在这里插入图片描述
红色框中是观察到的 m a x [ Q ( s ′ , a ′ ) max[Q(s’,a’) max[Q(s′,a′),从黄色框中可以看到状态变为s’带如下次循环中后,并未指定执行动作a’,因此属于off-policy。

二、Q-learning Agent代码

此处直接参考莫烦python的强化学习教程进行代码编写,在基础上说明每一行代码的用途
对于环境environment的编写,仍沿用上一节中的环境environment
下面是对agent的编写和注释

  1. from maze_env import Maze
  2. import numpy as np
  3. import pandas as pd
  4. import tensorflow as tf
  5. #RL的父类定义
  6. class RL(object):
  7. #初始化
  8. #actions为可选动作, learning_rate为学习率,reward_decay为传递奖励是的递减系数gamma,1-e_greed为随机选择其他动作的概率
  9. def __init__(self, actions, learning_rate=0.01, reward_decay=0.9, e_greedy=0.9):
  10. self.actions = actions
  11. self.lr = learning_rate
  12. self.gamma = reward_decay
  13. self.epsilon = e_greedy
  14. #初始化qtable,行为observation的state, 列为当前状态可以选择的action(对于所有列,可以选择的action一样)
  15. self.q_table = pd.DataFrame(columns = self.actions, dtype=np.float64)
  16. def choose_action(self, observation):
  17. self.check_state_exist(observation) #检查当前状态是否存在,不存在就添加这个状态
  18. if np.random.uniform() < self.epsilon:
  19. state_action = self.q_table.loc[observation, :] #找到当前状态可以选择的动作
  20. #由于初始化或更新后一个状态下的动作值可能是相同的,为了避免每次都选择相同动作,用random.choice在值最大的action中损及选择一个
  21. action = np.random.choice(state_action[state_action==np.max(state_action)].index)
  22. else:
  23. action = np.random.choice(self.actions) #0.1的几率随机选择动作
  24. return action
  25. def check_state_exist(self, state):
  26. if state not in self.q_table.index:
  27. #若找不到该obversation的转态,则添加该状态到新的qtable
  28. #新的state的动作的q初始值赋值为0,列名为dataframe的列名,index为state
  29. self.q_table = self.q_table.append(pd.Series([0]*len(self.actions), index=self.q_table.columns, name=state))
  30. #不同方式的学习方法不同,用可变参数,直接pass
  31. def learning(self, *args):
  32. pass
  33. #QLearning继承RL
  34. class QLearningTable(RL):
  35. #初始化
  36. #参数自己定义,含义继承父类RL
  37. #类方法choose_action、check_state_exist自动继承RL,参数不变
  38. def __init__(self, actions, learning_rate=0.01, reward_decay=0.9, e_greedy=0.9):
  39. super(QLearningTable, self).__init__(actions, learning_rate, reward_decay, e_greedy)
  40. #根绝当前观察状态s,选择动作a,选择动作后的奖励r,和执行动作后的状态s_,来更新qtable
  41. def learning(self, s, a,r, s_):
  42. self.check_state_exist(s_) #检查动作后状态s_是否存在
  43. q_old = self.q_table.loc[s, a] #旧的q[s,a]值
  44. if s_!='terminal':
  45. #下个状态下最大的值
  46. max_s_ = self.q_table.loc[s_, :].max()
  47. q_new = r+self.gamma*max_s_ #计算新的值
  48. else:
  49. q_new = r
  50. self.q_table.loc[s,a] = q_old - self.lr*(q_new - q_old) #根据更新公式更新,类似于梯度下降
  51. def update():
  52. for episode in range(100):
  53. # 初始化 state 的观测值
  54. observation = env.reset() #每轮训练都要初始化观测值,即回到原点状态
  55. while True:
  56. env.render()
  57. # RL 大脑根据 state 的观测值挑选 action
  58. action = RL.choose_action(str(observation)) #qlearning采用greeed方法,选择q值最大的action
  59. # 探索者在环境中实施这个 action, 并得到环境返回的下一个 state 观测值, reward 和 done (是否是掉下地狱或者升上天堂)
  60. #是根据当前选择动作,观察到的采取动作后的状态和奖励
  61. observation_,reward,done = env.step(action)
  62. # RL 从这个序列 (state, action, reward, state_) 中学习
  63. #根绝旧observation的q值,和采取动作,以及奖励和采取动作后的observation_的最大q值进行更新
  64. RL.learning(str(observation), action, reward, str(observation_))
  65. # 将下一个 state 的值传到下一次循环
  66. observation = observation_
  67. if done:
  68. break
  69. # 结束游戏并关闭窗口
  70. print('game over')
  71. env.destroy()
  72. if __name__ == "__main__":
  73. # 定义环境 env 和 RL 方式
  74. env = Maze()
  75. RL = QLearningTable(actions=list(range(env.n_actions)))
  76. # 开始可视化环境 env
  77. env.after(100, update)
  78. env.mainloop()

发表评论

表情:
评论列表 (有 0 条评论,121人围观)

还没有评论,来说两句吧...

相关阅读