强化学习笔记(2)-异策回合更新算法

在前一篇博客中,我总结了强化学习的同策回合更新的方法,并用这种方法来学习21点游戏的最优策略。这里我将总结一下我学习到的异策回合更新的方法。

同策学习和异策学习的区别在于,同策是边决策边学习,学习者同时也是决策者。异策则是根据之前的历史来学习,学习者和决策者可以不同。以围棋AI为例,如果边对弈边学习,这就是同策学习。如果通过阅读人类的历史对弈记录来学习,那么就是异策学习。

在异策学习中,历史记录中用到的策略和我们要学习的策略是不同的,所以称为异策学习。我们将要学习的策略称为目标策略\pi,用来生成历史记录的另一策略称为行为策略b,我们可以采用统计学中的重要性采样的概念,通过行为策略b生成的轨迹样本来生成目标策略的统计量。

重要性采样比率

考虑从t开始的轨迹S_{t}, A_{t}, R_{t+1}, S_{t+1}, A_{t+1}, R_{t+2}, \cdots S_{T-1}, A_{T-1}, R_{T}, S_{T},在给定S_{t}的条件下,用策略\pi和策略b生成这个轨迹的概率分别为:

Pr_{\pi}[A_{t},R_{t+1},S_{t+1},A_{t+1},\cdots,S_{T-1},A_{T-1},R_{T},S_{T}|S_{t}]

=\pi(A_{t}|S_{t})p(S_{t+1},R_{t+1}|S_{t},A_{t})\pi(A_{t+1}|S_{t+1})\cdots p(S_{T},R_{T}|S_{T-1},A_{T-1})

=\prod_{\tau =t}^{T-1}\pi(A_{\tau}|S_{\tau})\prod_{\tau =t}^{T-1}p(S_{\tau+1},R_{\tau+1}|S_{\tau},A_{\tau})

 Pr_{b}[A_{t},R_{t+1},S_{t+1},A_{t+1},\cdots,S_{T-1},A_{T-1},R_{T},S_{T}|S_{t}]

=b(A_{t}|S_{t})p(S_{t+1},R_{t+1}|S_{t},A_{t})b(A_{t+1}|S_{t+1})\cdots p(S_{T},R_{T}|S_{T-1},A_{T-1})

=\prod_{\tau =t}^{T-1}b(A_{\tau}|S_{\tau})\prod_{\tau =t}^{T-1}p(S_{\tau+1},R_{\tau+1}|S_{\tau},A_{\tau})

我们把这两个概率的比值称为重要性采样比率:

\rho _{t:T-1}=\frac{Pr_{\pi}[A_{t},R_{t+1},S_{t+1},A_{t+1},\cdots ,S_{T-1},A_{T-1},R_{T},S_{T}|S_{t}]}{Pr_{b}[A_{t},R_{t+1},S_{t+1},A_{t+1},\cdots ,S_{T-1},A_{T-1},R_{T},S_{T}|S_{t}]}=\prod_{\tau=t}^{T-1}\frac{\pi(A_{\tau}|S_{\tau})}{b(A_{\tau}|S_{\tau})}

为了让这个比率对于不同的轨迹都有意义,需要使得任何满足\pi(a|s)>0s\in S, a\in A(s),均有b(a|s)>0,这样的关系可以记为\pi\ll b

增量法更新

回合更新总是采用Monte Carlo来估计价值函数的值。同策回合更新得到c个回报g_{1}, g_{2}, \dots, g_{c}后,用平均值\frac{1}{c}\sum_{i=1}^{c}g_{i}来作为价值函数的估计。这个方法默认了这c个回报是等概率出现的。类似的,异策回合更新用行为策略b得到c个回报g_{1}, g_{2}, \dots, g_{c},这c个回报对于行为概率b是等概率出现的,但是对于目标概率\pi不是等概率出现的,这c个回报值出现的概率正是各轨迹的重要性采样比率。因此我们用加权平均来完成Monte Carlo估计。具体而言,若\rho_{i}是回报样本g_{i}对应的权重(轨迹的重要性采样比率),可以有以下两种采样方法:

1. 加权重要性采样:

 \frac{\sum_{i=1}^{c}\rho_{i}g_{i}}{\sum_{i=1}^{c}\rho_{i}}

2. 普通重要性采样: 

\frac{1}{c}\sum_{i=1}^{c}\rho_{i}g_{i}

这两种采样方法的区别在于分母部分,加权重要性采样会排除掉\rho_{i}=0g_{i}参与平均。

对于加权重要性采样方法,采用增量法来更新加权平均值:

c\leftarrow c+\rho

v\leftarrow v+\frac{\rho}{c}(g-v)

证明如下:

对于前n次观测到的回报g_{1},g_{2},\dots,g_{n},根据加权重要性采样的定义,值函数

v_{n}=\frac{\sum_{i=1}^{n-1} \rho_{i}g_{i}}{\sum_{i=1}^{n-1} \rho_{i}}

v_{n+1}-v_{n}=\frac{\sum_{i=1}^{n} \rho_{i}g_{i}}{\sum_{i=1}^{n} \rho_{i}}-\frac{\sum_{i=1}^{n-1} \rho_{i}g_{i}}{\sum_{i=1}^{n-1} \rho_{i}}

a=\sum_{i=1}^{n-1} \rho_{i}g_{i}, b=\sum_{i=1}^{n-1} \rho_{i}

v_{n+1}-v_{n}=\frac{a+\rho_{n}g_{n}}{b+\rho_{n}}-\frac{a}{b}=\frac{ba+b\rho_{n}g_{n}-ab-a\rho_{n}}{b(b+\rho_{n})}=\frac{\rho_{n}(bg_{n}-a)}{b(b+\rho_{n})}=\frac{\rho_{n}(bg_{n}-a)}{b\sum_{i=1}^{n}\rho_{i}}=\frac{\rho_{n}g_{n}}{\sum_{i=1}^{n}\rho_{i}}-\frac{\rho_{n}}{\sum_{i=1}^{n}\rho_{i}}\frac{a}{b}=\frac{\rho_{n}g_{n}}{\sum_{i=1}^{n}\rho_{i}}-\frac{\rho_{n}}{\sum_{i=1}^{n}\rho_{i}}v_{n}

v_{n+1}=v_{n}+\frac{\rho_{n}g_{n}}{\sum_{i=1}^{n}\rho_{i}}-\frac{\rho_{n}}{\sum_{i=1}^{n}\rho_{i}}v_{n}=v_{n}+\frac{\rho_{n}}{\sum_{i=1}^{n}\rho_{i}}(g_{n}-v_{n})

这个就等价于我们刚才定义的

v\leftarrow v+\frac{\rho}{c}(g-v)

对于普通重要性采样,增量法更新为:

c\leftarrow c+1

v\leftarrow v+\frac{1}{c}(\rho g-v)

最优策略求解算法

在求解最优策略的时候,可以指定行为策略b为任意的一个柔性策略,让目标策略\pi为确定性策略,在回合更新中,始终满足\pi\ll b。算法如下:

1. (初始化)初始化动作价值估计q(s,a)为任意值,初始化权重和c(s,a)为0,\pi_{s}=argmax_{a}q(s,a)

2. (回合更新)对每个回合执行以下操作

2.1 (柔性策略)指定b为任意柔性策略

2.2 (采样)用策略b生成轨迹:S_{0},A_{0},R_{1},S{1},A_{1},\dots,S_{T-1},A_{T-1},R_{T},S_{T}

2.3 (初始化回报和权重)G\leftarrow 0, \rho\leftarrow 1

2.4 对于t\leftarrow T-1, T-2,\dots,1,0:

2.4.1 (更新回报)G\leftarrow \gamma G+R_{t+1}

2.4.2 (更新价值)更新q(S_{t}, A_{t})以减少\rho[G-q(S_{t},A_{t})]^{2} (如c(S_{t},A_{t})\leftarrow c(S_{t},A_{t})+\rho, q(S_{t},A_{t})\leftarrow q(S_{t},A_{t})+\frac{\rho}{c(S_{t},A_{t})}[G-q(S_{t},A_{t})])

2.4.3 (策略更新)\pi(S_{t})\leftarrow argmax_{a}q(S_{t},a)

2.4.4 (提前终止)若A_{t}\neq \pi(S_{t})则退出步骤2.4

2.4.5 (更新权重)\rho\leftarrow \rho\frac{1}{b(A_{t},S_{t})}, 因为\pi(S_{t},A_{t})=1

21点的最优策略求解

下面我们可以用异策回合更新算法来找出21点游戏的最优策略。在上一篇博文里面已经介绍了如何用Gym来模拟21点的环境以及用同策回合更新算法来求最优策略,这里不再重复,只是给出异策回合更新的算法,代码如下:

import gym
import numpy as np
import pandas as pd
env = gym.make("Blackjack-v0")

def ob2state(observation):
    return(observation[0], observation[1], int(observation[2]))

def monte_carlo_importance_resample(env, episode_num=500000):
    policy = np.zeros((22,11,2,2))
    policy[:,:,:,0] = 1.
    behavior_policy = np.ones_like(policy)*0.5  #柔性策略
    q = np.zeros_like(policy)   #价值函数
    c = np.zeros_like(policy)   #计数器
    for _ in range(episode_num):
        #每一回合
        state_actions = []
        observation = env.reset()
        while True:
            state = ob2state(observation)
            action = np.random.choice(env.action_space.n, p=behavior_policy[state])
            state_actions.append((state, action))
            observation, reward, done, _ = env.step(action)
            if done:
                break
        g = reward   #每一回合最后结束时的奖励作为回报值
        rho = 1.     #重要性采样比率初始化
        for state, action in reversed(state_actions):
            c[state][action]+=rho
            q[state][action]+=(rho/c[state][action])*(g-q[state][action])
            a = q[state].argmax()
            policy[state] = 0.
            policy[state][a] = 1.
            if a!=action:
                break
            rho /= behavior_policy[state][action]
    return policy, q

p,q = monte_carlo_importance_resample(env)
blackjack_policy = {}
for i in range(4, 20):
    blackjack_policy[str(i)] = []
    for j in range(2, 11):
        if p[i,j,0,0]<p[i,j,0,1]:
            blackjack_policy[str(i)].append('H')
        else:
            blackjack_policy[str(i)].append('S')
    if p[i,1,0,0]<p[i,1,0,1]:
        blackjack_policy[str(i)].append('H') 
    else:
        blackjack_policy[str(i)].append('S') 
for i in range(13, 20):
    key = 'A,'+str(i-11)
    blackjack_policy[key] = []
    for j in range(2, 11):
        if p[i,j,1,0]<p[i,j,1,1]:
            blackjack_policy[key].append('H')
        else:
            blackjack_policy[key].append('S')
    if p[i,1,1,0]<p[i,1,1,1]:
        blackjack_policy[key].append('H') 
    else:
        blackjack_policy[key].append('S') 
with open('blackjack_policy.csv', 'w') as f:
    result = 'Player;2;3;4;5;6;7;8;9;10;A\n'
    for key in blackjack_policy:
        result += (key+';'+';'.join(blackjack_policy[key])+'\n')
    f.write(result)
df = pd.read_csv('blackjack_policy.csv', header=0, index_col=0, sep=';')
df.head(100)

输出结果如下:

Player2345678910A
4HHHHHHHHHH
5HHHHHHHHHH
6HHHHHHHHHH
7HHHHHHHHHH
8HHHHHHHHHH
9HHHHHHHHHH
10HHHHHHHHHH
11HHHHHHHHHH
12HHHSSHHHHH
13SSSSSHHHHH
14SSSSSHHHHH
15SSSSSHHHHH
16SSSSSHHHHH
17SSSSSSSSSH
18SSSSSSSSSS
19SSSSSSSSSS
A,2HHHHHHHHHH
A,3HHHHHHHHHH
A,4HHHHHHHHHH
A,5HHHHHHHHHH
A,6HHHHHHHHHH
A,7SSHHHSSHHH
A,8SSSSSSSSSS
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gzroy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值