需要源码请点赞关注收藏后评论区留言私信~~~
随机性策略
首先生成一个随机初始化的随机性策略
def create_random_policy(env): pi = np.ones([env.observation_space.n, env.action_space.n]) # 用数组来存储策略 p = 1 / env.action_space.n return pi * p pi = create_random_policy(env) print( pi )
然后按随机性策略进行尝试
def episode_random(env, pi, render = False): env.reset() if render: env.render() episode = [] done = False while not done: s = env.env.s # 读取环境状态 timestep = [] timestep.append(s) action = np.random.choice(env.action_space.n, p=pi[s]) # 执行动作并记录 next_s, r, done, info = env.step(action) timestep.append(action) timestep.append(r) episode.append(timestep) if render: env.render() return episode tau = episode_random(env, pi, False) print( tau )
蒙特卡洛法基本思想
在没有环境模型时,在策略评估阶段,用随机近似方法来求值函数的近似值:
动作值函数: Q_π(s,a)=E_π[G_t|S_t=s┤,A_t=a]
求函数f(x)关于 x的分布p(x)的期望E[f(x)]=∫▒p(x)f(x)□dx,可以先依概率p(x)采样x_i,然后根据大数定律用样本均值来近似:
流程图如下
一次尝试的轨迹如下:
更新动作值函数:对所有s和a对应的动作值函数重新求均值
主体的轨迹中可能会出现相同的状态值和动作值对(s,a),也就是说,主体在探索时,可能会回到以前的状态并做出与上次相同的动作。如上述示例轨迹中的第1步和第2步。
对重复状态和动作值对(s,a)的处理,有两种方法,分别称为每次访问统计和初次访问统计。
每次访问统计是对每个出现的(s,a)都进行采样用于后续统计。 初次访问统计是只对第一次出现的(s,a)进行采样。
步骤(3)是对每一(s,a),统计它的所有采样的累积折扣回报的均值,即得到动作值函数Q(s,a)的近似估计值。
在统计累积折扣回报的均值时,如果按照保存所有G值再平均的常规方法会占用大量的存储空间,此时,可采用所谓的递增计算均值的方法。
对(s,a)新增的累积折扣回报G,动作值函数Q(s,a)的递增计算式为:
式中,N(s,a)表示已经统计的次数。
使用同策略蒙特卡洛法求解冰湖问题结果如下
部分代码如下
def mc_on_policy(env, epsilon=0.01, n_episodes=100): pi = create_random_policy(env) # 产生随机策略,数组形式 Q_value = np.zeros([env.observation_space.n, env.action_space.n]) N_s_a = np.zeros([env.observation_space.n, env.action_space.n]) for k in range(n_episodes): G = 0 # 累积回报 tau = episode_random(env, pi, False) # 采样得到轨迹τ for i in reversed( range( 0, len(tau) ) ): s_t, a_t, r_t = tau[i] G += r_t if not (s_t, a_t) in [(x[0], x[1]) for x in tau[0:i]]: # 初次访问统计 N_s_a[s_t, a_t] += 1 Q_value[s_t, a_t] = Q_value[s_t, a_t] + ( G - Q_value[s_t, a_t] ) / N_s_a[s_t, a_t] for value[s] == np.max(Q_value[s])) tag_max_Q = random.choice(indices[0]) pi[s][tag_max_Q] += 1 - epsilon # 最优动作的增加概率 return pi
创作不易 觉得有帮助请点赞关注收藏~~~