强化学习实例8:蒙特卡罗法(monte carlo)

在很多实际问题中,我们无法得到游戏的全貌,也就是说,状态转移矩阵无法获知,这被称为“无模型”问题。

Bellman公式,可以通过不断迭代得到状态-行动值函数

而在无模型问题中,状态转移概率将无法知晓,于是用最初的累积回报求得

看到等号右边的期望,我们很自然地联想到了蒙特卡罗法,它是一种通过随机采样估计期望值的方法,全过程总结如下:

(1)让Agent和环境交互后得到交互序列

(2)通过序列计算出每一时刻的价值

(3)将这些价值累积到值函数中进行更新

(4)根据更新的值函数更新策略

代码如下:

# 蒙特卡罗方法
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.0
        # 计算回报 q = sum(r^k*R)
        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):
            agent.value_n[item[0]][item[1]] += 1  # 计数
            # 求期望,qt(N-1) = qt(N-1) + 1/N (q^t(N) - qt(N-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,:])  # 去最大q(a|s)作为下一个策略
        if np.all(np.equal(new_policy, agent.pi)):
            return False
        else:
            agent.pi = new_policy
            return True
    
    def monte_carlo_opt(self, agent, env):
        for i in range(10):
            # 试玩100次
            for j in range(100):
                self.monte_carlo_eval(agent, env)
            self.policy_improve(agent)
from contextlib import contextmanager
import time
@contextmanager
def timer(name):
    start = time.time()
    yield
    end = time.time()
    print('{} COST:{}'.format(name, end - start))

# 没有模型
class ModelFreeAgent(object):
    def __init__(self, env):
        self.s_len = env.observation_space.n
        self.a_len = env.action_space.n

        self.pi = np.array([0 for s in range(0, self.s_len)]) # 转移矩阵
        self.value_q = np.zeros((self.s_len, self.a_len))
        self.value_n = np.zeros((self.s_len, self.a_len))
        self.gamma = 0.8

    def play(self, state, epsilon = 0):
        if np.random.rand() < epsilon:
            return np.random.randint(self.a_len)
        else:
            return self.pi[state]

# 测试
def monte_carlo_demo():
    np.random.seed(101)
    env = SnakeEnv(10, [3,6])
    agent = ModelFreeAgent(env)
    mc = MonteCarlo(0.5)
    with timer('Timer Monte Carlo Iter'):
        mc.monte_carlo_opt(agent, env)
    print('return_pi={}'.format(eval_game(env,agent)))
    print(agent.pi)
monte_carlo_demo()

可以看出,蒙特卡罗法的效果比策略迭代差一些,由于状态转移矩阵未知,因此存在一些差距是可以理解的。

为了保证所有的状态和行动组合全部被Agent经历过,而且经历次数足够多,使用了epsilon-greedy算法,实际上该算法解决了“探索和利用”问题。所谓的探索是指不拘泥于当前的表现,选择一些不同于当前策略的行动;利用就是持续使用当前的最优策略,尽可能地获得更多的回报。

虽然它对期望值的估计是无偏的,但是方差较高,为此提出时序差分法(Temporal Difference)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值