1. 无模型问题
在很多时候,我们无法得知模型信息,比如前几节的蛇棋中,我们不知道棋盘梯子的信息和骰子的信息,用数学化的方法来说,就是我们用于决策的智能体不知道状态转移概率 。
2. 采样的方法
2.1 计算公式
当我们无法得知
的时候,一个直观的想法就是使用大量的采样去进行估计。
为了方便,我们把策略迭代算法中策略评估的公式进行一下拆解:
无法使用迭代的方法计算得到,因此使用蒙特卡洛法,采样得到大量的样本序列:
…
状态行动集(
,
)的值函数可以近似为:
。再根据策略
就可以计算出
了。
具体计算时,我们是使用更新的方法计算
,而不是等遍历完再取均值。令
则更新公式为:
可以证明:
更新公式和梯度下降法非常相像。
2.2 采样随机探索
在使用蒙特卡洛法采样的时候,我们有很多前进的方法。一方面,我们要保证行动
的最优性,这样才能准确估计出
;另一方面,我们要保证行动的随机性,这样我们才能访问到更多状态,避免陷入局部最优。
一种常见的策略是在采样的时候加入一定的随机性,比如
-greedy策略,即以一定的概率采取随机行动,其他情况采取最优策略行动。
2.3 every visit和first visit
加入我们在行动的过程中,又碰到了
怎么办?一种方法是将其加入
的计算之中,称为every visit方法;另一种方法是不加入,称为first visit方法。
在有限状态的序贯决策问题中,不同时间段访问同样状态的
值可能会差很大。这种情况下建议使用first visit方法,减少
值的方差,加快收敛速度。
3. 代码与测试
class MonteCarlo(object):
def __init__(self, epsilon=0.0):
self.epsilon = epsilon
# 一轮蒙特卡洛采样
def monte_carlo_eval(self, agent, env):
state = env.reset()
episode = []
while True:
ac = agent.play(state, self.epsilon)
next_state, reward, terminate, _ = env.step(ac)
episode.append((state, ac, reward))
state = next_state
if terminate:
break
value = []
return_val = 0
# 逆向计算q值
for item in reversed(episode):
return_val = return_val * agent.gamma + item[2]
value.append((item[0], item[1], return_val))
# 进行更新
for item in reversed(value):
if agent.value_n[item[0]][item[1]] == 0: # 这里是first visit方法;every visit把这句判断删除即可
agent.value_n[item[0]][item[1]] += 1 # 访问次数
agent.value_q[item[0]][item[1]] += (item[2] - \
agent.value_q[item[0]][item[1]]) / \
agent.value_n[item[0]][item[1]]
def policy_improve(self, agent):
new_policy = np.zeros_like(agent.pi)
for i in range(1, agent.s_len):
new_policy[i] = np.argmax(agent.value_q[i,:])
if np.all(np.equal(new_policy, agent.pi)):
return False
else:
agent.pi = new_policy
return True
# monte carlo法
def monte_carlo_opt(self, agent, env):
for i in range(10): # 进行10轮迭代
for j in range(100): # 每次采样100轮
self.monte_carlo_eval(agent, env)
self.policy_improve(agent)
对比测试结果如下:
ladders info:
{14: 65, 18: 48, 41: 68, 30: 45, 68: 41, 48: 18, 49: 89, 71: 79, 65: 14, 70: 18, 73: 41, 45: 30, 89: 49, 79: 71}
Iter 3 rounds converge
Timer PolicyIter COST:0.2772650718688965
return_pi=64
Timer MonteCarlo COST:0.22463107109069824
return_pi=30
MonteCarlo法的效果一般,主要是因为前几轮迭代的值方差很大,而我们对迭代次数进行了限制,因此较难收敛。下一节将介绍可以减小方差的时序差分法。