Q-learning算法
最近在学强化学习,看了不少的教程,还是觉得莫烦大神的强化学习教程写的不错。所以,特意仔细研究莫烦的RL代码。在这贴上自己的理解。
莫烦RL教程:https://morvanzhou.github.io/tutorials/machine-learning/reinforcement-learning/
代码:https://github.com/MorvanZhou/Reinforcement-learning-with-tensorflow/tree/master/contents
1.Q-learning算法的决策
Q-learning算法是如何决策的呢?
原来Q-learning算法会生成一个Q表,agent每一次要采取的action,都会根据当前agent的state去Q表中查找奖励(reward)最高的动作。
就这样,agent每次采取动作都去Q表中查找.以此来决策agent的下一步的action。
2.Q-learning算法的更新
假如有如下的Q表
- | a1 | a2 |
---|---|---|
s1 | -2 | 1 |
s2 | -4 | 2 |
现在agent在s1状态,根据前文说的算法决策方法Q(s1,a1) < Q(s1,a2),所以接下来会采取a2这个动作,并到达s2状态。
我们来更新Q表。接下来的我们没有在实际中采取任何动作,而是想想自己在S2状态下采取的动作,分别看看在S2状态下哪个动作的Q值最大。
比如说Q(s2,a2) > Q(s2,a1),所以把大的Q(s2,a2)乘一个gamma并加上到达s2时的奖励R,把这个作为现实中Q(s1,a2)的值。也就是 ‘Q现实’。 Q现实 = R + γ*maxQ(s2)
之前的根据Q表得到的Q(s1,a2)是Q表估计的值,也就是‘Q估计’。 Q估计 = Q(s1,a2)
有了 Q现实 和 Q估计,就可以更新Q(s1,a2)。
Q(s1,a2) = Q(s1,a2) + α * (Q现实 - Q估计)
但时刻记住, 我们虽然用 maxQ(s2) 估算了一下 s2 状态, 但还没有在 s2 做出任何的行为, s2 的行为决策要等到更新完了以后再重新另外做. 这就是 off-policy 的 Q learning 是如何决策和学习优化决策的过程.
3.Q-learning整体算法
[站外图片上传中…(image-6af5ac-1563434302631)]
这一张图概括了我们之前所有的内容. 这也是 Q learning 的算法, 每次更新我们都用到了 Q 现实和 Q 估计, 而且 Q learning 的迷人之处就是 在 Q(s1, a2) 现实 中, 也包含了一个 Q(s2) 的最大估计值, 将对下一步的衰减的最大估计和当前所得到的奖励当成这一步的现实, 很奇妙吧. 最后我们来说说这套算法中一些参数的意义. Epsilon greedy 是用在决策上的一种策略, 比如 epsilon = 0.9 时, 就说明有90% 的情况我会按照 Q 表的最优值选择行为, 10% 的时间使用随机选行为. alpha是学习率, 来决定这次的误差有多少是要被学习的, alpha是一个小于1 的数. gamma 是对未来 reward 的衰减值。
4.探索者小游戏——代码实现
会用 tabular Q-learning 的方法实现一个小例子, 例子的环境是一个一维世界, 在世界的右边有宝藏, 探索者只要得到宝藏尝到了甜头, 然后以后就记住了得到宝藏的方法, 这就是他用强化学习所学习到的行为.
-o---T
# T 就是宝藏的位置, o 是探索者的位置
4.1模块和参数
import numpy as np
import pandas as pd
import time
N_STATES = 6 # 1维世界的宽度 -o---T
ACTIONS = ['left', 'right'] # 动作列表
EPSILON = 0.9 # 贪婪度
ALPHA = 0.1 # 学习率
GAMMA = 0.9 # 奖励衰减值
MAX_EPISODES = 13 # 训练次数(回合数)/游戏运行次数
FRESH_TIME = 0.3 # 移动间隔时间
4.2创建Q表
## 创建Q表
def build_q_table(n_states, actions):
table = pd.DataFrame(
np.zeros((n_states, len(actions))), # 初始化Q表,值为0
columns=actions, # 列的名字为动作的名称
)
#print(table) # show table
return table
4.3动作的选择
## 在某状态时,选择动作
def choose_action(state, q_table):
# iloc 选择state行的 动作的值,类型还是 Dataframe
state_actions = q_table.iloc[state, :]
''' np.random.uniform(low=0.0, high=1.0, size=None) 随机数'''
# 大于贪婪度 or 这个 state 未探索过, 则随机选择一个动作
if (np.random.uniform() > EPSILON) or ((state_actions == 0).all())