一.时序差分法(TD)
1.与其他方法的联系
在前一章中我们提出蒙特卡洛法,有效地解决了在环境未知的状态下,强化学习问题的求解。但是,MC方法必须经历一个从起始到结束的完整episode才可以进行一次策略的更新,但现实的问题存在完整经历时间长或根本无法结束的情况,那么MC就不太管用。
那么,如果当我们进行一次交互(在状态下做出动作,导致状态转移并获得对应奖励)之后就进行一次策略的更新,是否可以缓解这个问题?我们该怎么完成这样的更新?借鉴DP方法(动态规划),考虑使用bootstapping对传统的MC进行改进。
该图中,第一个回溯图代表DP方法时进行一个广度的更新。第三张图代表着MC,进行一个深度的更新,中间的图就代表了TD法进行策略更新的方式,兼具了MC的采样形式和DP的自举更新。他不仅具备了在无模型情况下获得信息的能力,又利用自举使得无需等到一个episode结束再进行更新。
2.TD法策略评估
- 在DP方法的自举中,对于回报G的估计值是:(不明白可以参考之前的章节)
- 在MC法中,价值函数的更新公式是:
- TD法中的状态价值函数更新公式是:(就是将自举估计的回报代替蒙特卡洛更新式中的回报,这样我们不需要经过一个完整的epoisode就可以估算出回报)
在TD法的更新公式中,我们有两个定义:
- TD target:
- TD error:
在进行更新的时候,我们的目标就是让TD error变得更小。其中的TD target与剩下的分别代表着当获得新的交互信息之后新的状态价值函数估计值与原先的估计值。在获得了新的信息后,新的估计值肯定是更接近于现实值的,只要旧估计值不断贴近新估计值,新估计值不断贴近真实值,那就完成了我们策略评估的任务:给定策略,求出对应的价值函数。
3.on-policy 与 off-policy
在进行策略优化的时候,我们可以用两个策略来完成。一个策略负责进行环境的探索,用以改进第二个策略,我们输出的也是第二个策略。这种优化的方式叫做off-policy,异策略策略优化。
也可以利用一个策略来完成,即探索和改进的都是同一个策略,把它称为on-policy,同策略策略优化
二.SARSA
sarsa算法是一种典型的on-policy算法,通过伪代码来展示
一次更新的迭代中,我们需要采样的数据有:S,A,R,S,A' ,算法的名字就由此而来。我们选择动作进行探索的策略就是在探索后更新的策略,符合同策略策略优化的特征。
三.Q-Learning
Q-learning是一种离轨的方法,伪代码:
在进行动作的执行和改进的两个策略并不相同。在进行Q表更新时的a'并不会真实作为行动,而是一个假想的动作,是根据其他策略产生的。
当我们初始化一个策略,进行第一次动作的选择利用的是初始策略。紧接着再进行环境的探索使用的是直接贪婪选取当前的最优动作,但是用来改进的,也是下一次做选择的策略并不是同一个策略。而Sarsa在进行更新时,探索利用策略选择动作,并且这个动作就是下一步执行的动作。
四.代码
我们使用一个悬崖模型来进行实践。
4*12网格,红色格子是悬崖,走进悬崖会得到-100的奖励并回到起点36号黄色格子,其余格子对应的奖励都是-1.
1.定义环境:
import numpy as np
import random
import matplotlib
import matplotlib.pyplot as plt
from matplotlib import style
#定义有限的状态集
S = [(i, j) for i in range(4) for j in range(12)]
#定义有限的动作集
A = list[range(4)]
#定义价值函数(v表Q表)
V = np.zeros(shape=(4, 12))
Q = {s:[0]*4 for s in S}#对应每个状态有四个动作(上下左右)
#定义环境
start = (3, 0)
terminals = [(3, 11)]
cliffs = [(3, i) for i in range(1, 11)]
gamma = 1
#方便将数字动作转化为方便看的形式
num_to_action = {0:'↑', 1:'↓', 2:'←', 3:'→'}
2.定义动作导致状态变化
def take_action(s, a):
move = [(-1, 0), (1, 0), (0, -1), (0, 1)]
new_i, new_j = s[0] + move[a][0], s[1] + move[a][1]
#判断是否出格
if new_i > 3:
new_i = 3
if new_i < 0:
new_i = 0
if new_j > 11:
new_j = 11
if new_j < 0:
new_j = 0
s_new = (new_i, new_j)
#判断是否位于悬崖,给予对应奖励
if s_new in cliffs:
reward = -100
s = s_new
else:
reward = -1
s = s_new
return reward, s
3.Q-Learning算法
def Q_learning(n=100000,alpha=0.01,epsilon=0.1):
rewards_Q = [] #用来存储每个episode的回报
k = 0
while k < n:
G = 0
s = start
while s not in cliffs and s not in terminals:
#epsilon贪心选择动作
if random.uniform(0, 1) < 1 - epsilon:
a = np.argmax(Q[s])
else:
a = random.randint(0, 3)
#与环境交互获得新状态和奖励
r,s_ = take_action(s,a)
#更新Q表
Q[s][a] += alpha*(r+gamma*max(Q[s_])-Q[s][a])
s=s_
G = G + r
k += 1
#将这一episode添加
rewards_Q.append(G)
#选择能够得到最好动作价值函数的动作作为策略
for i in range(4):
for j in range(12):
V[i][j] = np.argmax(Q[i, j])
#绘图与输出每100episode的平均回报
print(len(rewards_Q))
plot_list = []
for i in range(1000):
avr = np.sum(rewards_Q[i*100:(i+1)*100])
avr = avr/100
plot_list.append(avr)
L = np.zeros(shape=(4, 12))
show = np.array(L,dtype=str)
for i in range(4):
for j in range(12):
show[i][j] = num_to_action[V[i][j]]
print('Q-Learning')
print(show)
return plot_list
4.SARSA算法
def Q_learning(n=100000,alpha=0.01,epsilon=0.1):
rewards_Q = []
k = 0
while k < n:
G = 0
s = start
while s not in cliffs and s not in terminals:
if random.uniform(0, 1) < 1 - epsilon:
a = np.argmax(Q[s])
else:
a = random.randint(0, 3)
r,s_ = take_action(s,a)
Q[s][a] += alpha*(r+gamma*max(Q[s_])-Q[s][a])
s=s_
G = G + r
k += 1
rewards_Q.append(G)
for i in range(4):
for j in range(12):
V[i][j] = np.argmax(Q[i, j])
print(len(rewards_Q))
plot_list = []
for i in range(1000):
avr = np.sum(rewards_Q[i*100:(i+1)*100])
avr = avr/100
plot_list.append(avr)
L = np.zeros(shape=(4, 12))
show = np.array(L,dtype=str)
for i in range(4):
for j in range(12):
show[i][j] = num_to_action[V[i][j]]
print('Q-Learning')
print(show)
return plot_list
5.绘图
Q_list = Q_learning()
S_list = Sarsa()
y1 = np.array(Q_list)
y2 = np.array(S_list)
x = range(len(y1))
plt.plot(x, y1, color='r', label='Q-learning') # label每个plot指定一个字符串标签
plt.plot(x, y2, color='b', label='SARSA')
plt.show()
6.结果
Q-Learning
[['→' '→' '←' '→' '→' '↑' '→' '→' '→' '→' '↓' '↓']
['→' '→' '→' '↓' '↓' '→' '→' '↓' '→' '→' '↓' '↓']
['→' '→' '→' '→' '→' '→' '→' '→' '→' '→' '→' '↓']
['↑' '↑' '↑' '↑' '↑' '↑' '↑' '↑' '↑' '↑' '↑' '↑']]
100000
SARSA
[['→' '→' '→' '→' '→' '→' '→' '→' '→' '→' '→' '↓']
['↑' '↑' '↑' '↑' '↑' '↑' '→' '↑' '↑' '↑' '→' '↓']
['↑' '↑' '↑' '↑' '↑' '←' '↑' '↑' '↑' '↑' '→' '↓']
['↑' '↑' '↑' '↑' '↑' '↑' '↑' '↑' '↑' '↑' '↑' '↑']]
很容易看见,在进行路径的选择上,Q-Learing更贴近悬崖,获得更优的结果,SARSA比较保守,尽量远离悬崖。
红色为Q-Learning,过于冒进导致均值较低,但最优策略相比SARSA更加优秀。
《EasyRL》中二三章的回答(自己写的,答案以官方为主)
2-1. 为什么在马尔可夫奖励过程中要有折扣因子
(1)在MRP中,对于没有终止状态的环状结构与,衰减函数可以避免奖励无限的叠加,爆炸的情况
(2)相比于当前的已知状态,对于未来的评估不可信,希望未来奖励风险性更大,为了避免风险引出折扣因子
2-2.为什么矩阵形式贝尔曼方程解析解比较难求得
涉及到高维矩阵求逆,在状态量较大的情况下,复杂度高
2-3.计算贝尔曼方程的常见方法有哪些,有什么区别
最基础的方法是直接求解解析解,优点是可以算出精确值,缺点是要求已知模型,并且计算复杂度高,不好实现
基于蒙特卡洛采样的方法,相比于解析法来说要求低,计算复杂度低,更好实现,缺点是如果可能会有基于采样的误差
2-4.MRP和MDP之间的区别
在MRP中,只可以观测到奖励与环境的变化,MDP可以根据变化来操控agent做出动作,参与环境的改变
2-5. 马尔可夫决策过程中的状态转移与马尔可夫奖励过程中的状态转移的结构或者计算方面的差异有哪些?
由于MDP中,智能体做出的动作会影响状态的转移和奖励,所以状态转移不再是P(s'|s),而是P(s"|s,a),与动作有关。r(s)同理r(s,a)
2-6.我们如何寻找最佳策略,寻找最佳策略方法有哪些?
基于价值和基于策略
基于价值方法中,我们用到策略迭代(策略评估与策略改进)和广义策略迭代方法得到接近真实的状态(动作)价值函数,并生成策略
基于策略的方法经典的有策略梯度算法等,直接对策略进行操作
3-1.构成强化学习的马尔可夫决策过程的四元组有哪些变量?
<S, A, R, P>
3-2.请通俗地描述强化学习的“学习”流程
试错。通过不断的尝试,改进自己的表格/策略
3-3.请描述基于 Sarsa 算法的智能体的学习过程。
正如他的名字,SARSA进行一次策略更新需要5个数据
首先我们初始化一个状态,根据从价值函数衍生出的策略(epsilonGreedy)进行一次动作的选择
观察到环境给予的奖励,与状态的转移(下一时刻的状态)
再根据从价值函数衍生出的策略(epsilonGreedy)进行一次动作的选择a'
根据增量式更新方程来进行价值函数的更新,并将下一个状态,动作继承,重复执行上述,直到价值函数收敛
3-4.Q 学习算法和 Sarsa 算法的区别是什么?
SARSA是一种on-policy方法,即更新价值函数和真正执行的动作是出自同一策略,即更新价值函数的动作是真正执行的
Q-Learning是off-policy方法,拥有两套策略,分别来进行执行与更新价值函数,更新价值函数的动作实际上是不执行的
因为a'在SARSA下一回合需要执行,所以为了避免随机的动作造成损失,所以该算法会最大便避免损失,较为稳健
Q-Learning无需执行,所以较为大胆
3-5.同策略和异策略的区别是什么?
同策略:目标策略和行动策略相同
异策略:目标策略和行动策略不同