第16篇给出了强化学习算法框架,随后的第17、18篇给出了该框架下如何进行策略评估以估计出Q ( s , a ) (s,a) (s,a),第19篇给出了该框架下如何进行策略控制以改进 π ( a ∣ s ) \pi(a|s) π(a∣s),至此就可以给出MC强化学习算法的更具体的完整描述。
为了描述MC强化学习所处的环境,定义一个名为Env的类,这个类包含了reset方法和step方法,分别用来返回初始状态和返回当前状态下,执行一个行为后智能体获得的立即回报和转移后的状态。下面是这个类的框架代码:
class Env:
def __init__(self,nS:int,nA:int):
'''
初始化
args:
ns: 状态空间长度
nA:行为空间长度
'''
self.nS = nS
self.nA = nA
random.random.seed(0) # 初始化随机数发生器
self.current_state = 0
def reset(self)->Tuple[int,bool]:
'''
重置环境的当前状态为随机状态
return:
状态索引号,是否为终止状态
'''
...
self.current_state = [0,nS-1]上的一个随机整数
return random.randomint(0,self.nS)
def step(self,k:int)->Tuple[float,int,bool]:
'''
在当前状态下,执行行为空间中索引号为k的行为(有的资料称为动作),返回立即回报(有的资料称为即时奖励)、下一个状态索引号、下一个状态是否为终止状态,该方法执行后,环境的当前状态变为下一个状态索引号
args:
k :当前状态下执行的行为的索引号(索引号从0开始编号)
return:
本次行为的立即回报,下一状态索引号
'''
pass
上面的代码是无模型强化学习的环境的一般框架表示,这个设计其实和gymnasium扩展库的核心抽象类Env类似(它考虑更全面,比如定义了抽象方法render,用来实现基于pygame扩展库的界面的更新,可视化智能体与环境的交互过程,这个原则上我们也能够设计出来,单需要相当大的精力去做这件事,至少我没有这个精力)。因此,在无模型强化学习中,完全可以从gymnasium.Env派生出实际的具体环境类(有兴趣,可参考本专栏中的第14篇)。之所以要在这里单独设计,是希望从宏观上把握强化学习算法的一般编程架构。
在MC强化学习算法,是一个智能体,用类描述如下:
class Agent:
def __init__(self,env:Env,pi:NDArray,epsilon:float=0.5,mcSample:NDArray=None):
'''
env:该智能体交互的环境
pi:智能体所采取的策略初始策略,二维数组
epsilon:贪婪系数,(0,1)上的数
mcSample:MC轨迹采样策略,为None时将使用和pi同样的策略。
'''
self.env = Env
self.pi = pi
self.epsilon = epsilon
self.q = 维度为(nS,nA)的零矩阵 # q[i,j]对应Q(s_i,s_j),i,j从0开始
if not mcSample:
self.sample_policy = mcSample
else
self.sample_policy = pi
...
def train(self)->NDArray:
'''采样获得完整轨迹,并训练获得优化后的策略'''
while True:
episode = self.get_episode() # 获取一条完整轨迹
使用增量式策略评估算法根据episode估计行为值函数,用估计结果直接更新self.q
pi_old = self.pi
根据self.q,使用\epsilon-贪婪法求更新策略pi
if self.pi-pi_old<阈值:
break
return self.pi
def get_episode(self):
...
你可能已经注意到,获得完整轨迹时所使用的策略(采样策略)与要评估改进的策略可能一样,也可能不一样,这就把MC方法进一步分为两类:
这两大类算法各有什么优劣,下一篇再讨论。晚安。