稍微对问题进行一些定义, 将在时刻 t 时选择的动作记作 A t A_t At,并将对应的收益记作 R t R_t Rt,任意动作 a a a 对应的价值(即收益的期望)记作 q ∗ ( a ) q_*(a) q∗(a),即
q ∗ ( a ) ≐ E [ R t ∣ A t = a ] q_*(a) \doteq \mathbb{E}[R_t|A_t=a] q∗(a)≐E[Rt∣At=a] 虽然我们不知道 q ∗ ( a ) q_*(a) q∗(a) 的具体值,但我们可以进行估计,将 t 时刻对动作 a a a 的价值估计记作 Q t ( a ) Q_t(a) Qt(a),我们希望它接近 q ∗ ( a ) q_*(a) q∗(a)
如果我们持续对动作价值进行估计,那么任一时刻都会至少有一个动作的估计价值是最高的,我们将这些对应最高估计价值的动作成为 贪心动作
。在选择动作时,有两种选择
开发
:利用当前所知的关于动作价值的知识,从贪心动作中选择一个执行试探
:选择某个非贪心动作执行显然,“开发” 可以最大化当前时刻的期望收益,但是合理地 “试探” 从长远来看可能带来总体收益的最大化,因为 “试探” 有助于我们更准确地估计当前非贪心动作的价值,进而找到真正的最优动作。注意,同一次动作选择时,开发和试探是不可能同时进行的,这就要求我们在开发和试探间进行平衡
在一个具体问题中,对于不同的数学建模,有多种复杂的方法可以直接求解最好的平衡方法,但是这些方法往往都对平稳情况和先验知识做出了很强的假设,在复杂一些的问题中,这些假设要么难以满足,要么难以验证,使得这些方法的最优性或有界损失性缺乏保证。本文中讨论的方法避开了这些强假设,虽然性能稍差,但是通用性更强,且易于推广到真正的强化学习问题。
平衡开发和试探是强化学习中的一个关键问题,k 臂赌博机的简单抽象让我们可以清楚地了解这一点。
下面我们讨论一种增量式计算方法,以高效地计算上述均值。为了简化标记,我们这里仅关注单个动作,令 R i R_i Ri 表示这一动作被选中 i i i 次后获得的收益, Q n Q_n Qn 表示选中 n-1 次后对其动作价值的估计,则有
Q n ≐ R 1 + R 2 + . . . + R n − 1 n − 1 Q_n \doteq \frac{R_1+R_2+...+R_{n-1}}{n-1} Qn≐n−1R1+R2+...+Rn−1 这种计算方式要求维护所有收益记录,然后在每次需要估计价值时计算,随着记录增加,内存和计算资源的需求随之增长。
使用下面这种递推式计算方法,可以以小而恒定的计算资源来更新均值,给出 Q n Q_n Qn 和第n次收益 R n R_n Rn,价值更新如下
Q n + 1 = 1 n ∑ i = 1 n R i = 1 n ( R n + ∑ i = 1 n − 1 R i ) = 1 n ( R n + ( n − 1 ) 1 ( n − 1 ) ∑ i = 1 n − 1 R i ) = 1 n ( R n + ( n − 1 ) Q n ) = 1 n ( R n + n Q n − Q n ) = Q n + 1 n [ R n − Q n ] \begin{aligned} Q_{n+1} &= \frac{1}{n} \sum_{i=1}^n R_i \\ &= \frac{1}{n}(R_n+\sum_{i=1}^{n-1}R_i) \\ &= \frac{1}{n}(R_n+(n-1)\frac{1}{(n-1)}\sum_{i=1}^{n-1}R_i) \\ &= \frac{1}{n}(R_n+(n-1)Q_n) \\ &= \frac{1}{n}(R_n + nQ_n-Q_n) \\ &= Q_n + \frac{1}{n}[R_n-Q_n] \end{aligned} Qn+1=n1i=1∑nRi=n1(Rn+i=1∑n−1Ri)=n1(Rn+(n−1)(n−1)1i=1∑n−1Ri)=n1(Rn+(n−1)Qn)=n1(Rn+nQn−Qn)=Qn+n1[Rn−Qn]这个式子对于 n=1 也有效,可得 Q 2 = R 1 Q_2 = R_1 Q2=R1,对于每个新的收益,只需要存储 Q n Q_n Qn 和 n 即可
上式的一般形式为
新估计值 ← 旧估计值 + 步长 × [ 目标 − 旧估计值 ] ← 旧估计值 + 步长 × 误差 \begin{aligned} 新估计值 &\leftarrow 旧估计值 + 步长 \times [目标 - 旧估计值] \\ &\leftarrow 旧估计值 + 步长 \times 误差 \end{aligned} 新估计值←旧估计值+步长×[目标−旧估计值]←旧估计值+步长×误差 虽然 “目标” 可能存在噪声,但我们假定 “目标” 会告诉我们前进的方向,上述例子中,“目标” 就是第 n 次的收益
值得注意的是,“步长” 可能随时间变化,比如上述例子中的步长就是关于动作 a 执行次数 n 的函数 1 n \frac{1}{n} n1,通常把步长记作 α \alpha α,或更普适地记作 α t ( a ) \alpha_t(a) αt(a)
现在考虑如何利用动作价值的估计来选择动作
贪心
:总是贪心地选择目前具有最大价值的动作,即
A t ≐ arg max a Q t ( a ) A_t \doteq \argmax_{a} Q_t(a) At≐aargmaxQt(a) 这种策略只最大化眼前的收益,但是完全不去尝试目前看来劣质的动作,事实上,如果进行一些试探,很可能发现现在看来劣质的动作其实更好
ϵ-贪心
:大部分时候表现得贪心,但偶尔(以小概率 ϵ \epsilon ϵ)以独立与动作-价值估计值的方式从所有动作中等概率地做出随机选择。这种方式的好处在于:如果时刻可以无限长,则所有动作都会被无限次采样,从而确保所有的 Q t ( a ) Q_t(a) Qt(a) 收敛到 q ∗ ( a ) q_*(a) q∗(a),这也意味着选择最优动作的概率会收敛到大于 1 − ϵ 1-\epsilon 1−ϵ
ϵ-贪心
相比普通贪心
方法的优势依赖于任务
总之,对于绝大多数情况,尤其是非平稳、非确定性任务, ϵ \epsilon ϵ-贪心都由于普通贪心方法
用 1.3 节 描述的十臂测试平台对比动作选择时的 ϵ-贪心 和 贪心 方法。动作价值估计都使用采样平均方法,实验结果如下
示例代码
# 十臂赌博机
import numpy as np
import matplotlib.pyplot as plt
class Bandit:
def __init__(self,K):
self.K = K
self.values = np.random.randn(K) # 从标准正态分布采样K个拉杆的收益均值
self.bestAction = np.argmax(self.values) # 最优动作索引
self.QValues = np.zeros(K) # 价值评估值
self.N = np.zeros(K) # 动作选择次数
self.setPolicy() # 缺省策略为greedy
def setPolicy(self,mode='greedy',epsilon=0):
self.mode = mode
self.epsilon = epsilon
def greedy(self):
return np.random.choice([a for a in range(self.K) if self.QValues[a] == np.max(self.QValues)])
def epsilonGreedy(self):
if np.random.binomial(1,self.epsilon) == 1:
return np.random.randint(self.K)
else:
return self.greedy()
def takeAction(self):
if self.mode == 'greedy':
return self.greedy()
else:
return self.epsilonGreedy()
def play(self,times):
G = 0 # 当前收益
B = 0 # 当前最优选择次数
returnCurve = np.zeros(times) # 收益曲线
proportionCurve = np.zeros(times) # 比例曲线
self.QValues = np.zeros(self.K)
self.N = np.zeros(self.K)
for i in range(times):
a = self.takeAction()
r = np.random.normal(self.values[a],1,1)
B += a == self.bestAction
self.N[a] += 1
self.QValues[a] += 1/self.N[a]*(r-self.QValues[a]) # 增量式计算均值
returnCurve[i] = G/(i+1)
proportionCurve[i] = B/(i+1)
G += r
return returnCurve,proportionCurve
if __name__ == '__main__':
K = 10 # 摇臂数
Num = 100 # 赌博机数量
times = 2000 # 交互次数
paraList = [('greedy',0,'greedy'),('epsilon',0.1,'0.1-greedy'),('epsilon',0.01,'0.01-greedy')]
# 解决 plt 中文显示的问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
fig = plt.figure(figsize=(12,8))
a1 = fig.add_subplot(2,1,1,label='a1')
a2 = fig.add_subplot(2,1,2,label='a2')
a1.set_xlabel('训练步数')
a1.set_ylabel('平均收益')
a2.set_xlabel('训练步数')
a2.set_ylabel('最优动作比例')
# 实例化 Num 个赌博机
bandits = []
for i in range(Num):
bandit = Bandit(K)
bandit.setPolicy('greedy')
bandits.append(bandit)
# 测试三种策略
for paraMode,paraEpsilon,paraLabel in paraList:
aveRCurve,avePCurve = np.zeros(times),np.zeros(times)
for i in range(Num):
print(paraLabel,i)
bandits[i].setPolicy(paraMode,paraEpsilon)
returnCurve,proportionCurve = bandits[i].play(times)
aveRCurve += 1/(i+1)*(returnCurve-aveRCurve) # 增量式计算均值
avePCurve += 1/(i+1)*(proportionCurve-avePCurve) # 增量式计算均值
a1.plot(aveRCurve,'-',linewidth=2, label=paraLabel)
a2.plot(avePCurve,'-',linewidth=2, label=paraLabel)
a1.legend(fontsize=10) # 显示图例,即每条线对应 label 中的内容
a2.legend(fontsize=10)
plt.show()
在非平稳情况下,一种合理的处理方式是给近期的收益赋予较大的权重,最流行的方法之一是使用固定的步长,这时,如下更新动作价值估计
Q n + 1 ≐ Q n + α [ R n − Q n ] Q_{n+1} \doteq Q_n+\alpha[R_n-Q_n] Qn+1≐Qn+α[Rn−Qn] 其中,步长参数 α ∈ ( 0 , 1 ] \alpha \in (0,1] α∈(0,1] 是一个常数
这本质上是进行了一个加权平均处理,把 Q n + 1 Q_{n+1} Qn+1 展开
Q n + 1 = Q n + α [ R n − Q n ] = α R n + ( 1 − α ) Q n = α R n + ( 1 − α ) [ α R n − 1 + ( 1 − α ) Q n − 1 ] = α R n + ( 1 − α ) α R n − 1 + ( 1 − α ) 2 Q n − 1 = α R n + ( 1 − α ) α R n − 1 + ( 1 − α ) 2 R n − 2 + . . . + ( 1 − α ) n − 1 α R 1 + ( 1 − α ) n Q 1 = ( 1 − α ) n Q 1 + ∑ i = 1 n α ( 1 − α ) n − i R i \begin{aligned} Q_{n+1} &= Q_n+\alpha[R_n-Q_n] \\ &= \alpha R_n + (1-\alpha) Q_n\\ &= \alpha R_n + (1-\alpha)[ \alpha R_{n-1} + (1-\alpha) Q_{n-1}] \\ &= \alpha R_n + (1-\alpha) \alpha R_{n-1} + (1-\alpha)^2 Q_{n-1} \\ &= \alpha R_n + (1-\alpha) \alpha R_{n-1} + (1-\alpha)^2 R_{n-2} +...+(1-\alpha)^{n-1}\alpha R_1+(1-\alpha)^n Q_1\\ &= (1-\alpha)^n Q_1+\sum_{i=1}^n \alpha(1-\alpha)^{n-i} R_i \end{aligned} Qn+1=Qn+α[Rn−Qn]=αRn+(1−α)Qn=αRn+(1−α)[αRn−1+(1−α)Qn−1]=αRn+(1−α)αRn−1+(1−α)2Qn−1=αRn+(1−α)αRn−1+(1−α)2Rn−2+...+(1−α)n−1αR1+(1−α)nQ1=(1−α)nQ1+i=1∑nα(1−α)n−iRi 可见 Q n + 1 Q_{n+1} Qn+1 是对过去收益 R i ( i = 1 , 2 , . . . , n ) R_i(i=1,2,...,n) Ri(i=1,2,...,n) 和初始估计值 Q 1 Q_1 Q1 的加权和,分析权重,有
( 1 − α ) n + ∑ i = 1 n α ( 1 − α ) n − i = ( 1 − α ) n + α [ ( 1 − α ) 0 ( 1 − α ) n − 1 − α ] = ( 1 − α ) n + 1 − ( 1 − α ) n = 1 \begin{aligned} (1-\alpha)^n + \sum_{i=1}^n \alpha(1-\alpha)^{n-i} &= (1-\alpha)^n+\alpha[(1-\alpha)^0\frac{(1-\alpha)^n-1}{-\alpha}] \\ &= (1-\alpha)^n + 1- (1-\alpha)^n \\ &= 1 \end{aligned} (1−α)n+i=1∑nα(1−α)n−i=(1−α)n+α[(1−α)0−α(1−α)n−1]=(1−α)n+1−(1−α)n=1 权重之和为1,因此 Q n + 1 Q_{n+1} Qn+1 是对过去收益 R i ( i = 1 , 2 , . . . , n ) R_i(i=1,2,...,n) Ri(i=1,2,...,n) 和初始估计值 Q 1 Q_1 Q1 的加权平均,赋予 R i R_i Ri 的权重随着相隔次数的增加而递减,如果 1 − α = 0 1-\alpha=0 1−α=0,根据 0 0 = 1 0^0=1 00=1,所有权重都赋予最近收益 R n R_n Rn。注意到收益权重以指数形式递减,因此这个方法有时也称为 “指数近因加权平均”
利用十臂测试平台对比采样平均方法和指数近因加权平均方法。这个测试中,所有动作初始的真实价值 q ∗ ( a ) q_*(a) q∗(a) 设为 0,在每一步迭代时都加上一个从正态分布 N ( 0 , 0.01 ) N(0,0.01) N(0,0.01) 采样的增量。除了估计动作价值方式不同外,选择动作时两种方法都使用 ϵ = 0.1 \epsilon=0.1 ϵ=0.1 的 ϵ \epsilon ϵ-贪心方法
代码
# 十臂赌博机
import numpy as np
import matplotlib.pyplot as plt
class Bandit:
def __init__(self,K):
self.K = K
self.values = np.zeros(K) # 所有动作初始价值为0
self.bestAction = np.argmax(self.values) # 最优动作索引
self.QValues = np.zeros(K) # 价值评估值
self.N = np.zeros(K) # 动作选择次数
self.setPolicy() # 缺省策略为greedy
def setPolicy(self,mode='SA',epsilon=0.1):
self.mode = mode
self.epsilon = epsilon
def takeAction(self):
if np.random.binomial(1,self.epsilon) == 1:
return np.random.randint(self.K)
else:
return np.random.choice(np.argwhere(self.QValues == np.max(self.QValues)).flatten().tolist())
def play(self,times):
G = 0 # 当前收益
B = 0 # 当前最优选择次数
returnCurve = np.zeros(times) # 收益曲线
proportionCurve = np.zeros(times) # 比例曲线
self.QValues = np.zeros(self.K)
self.N = np.zeros(self.K)
for i in range(times):
self.values += np.random.normal(0,0.01,self.K) # 价值随机游走
self.bestAction = np.argmax(self.values)
a = self.takeAction()
r = np.random.normal(self.values[a],1,1)
if self.mode == 'SA':
self.N[a] += 1
self.QValues[a] += 1/self.N[a]*(r-self.QValues[a]) # 采样平均
else:
self.QValues[a] += 0.1*(r-self.QValues[a]) # 指数近因加权平均
returnCurve[i] = G/(i+1)
proportionCurve[i] = B/(i+1)
G += r
B += a == self.bestAction
return returnCurve,proportionCurve
if __name__ == '__main__':
K = 10 # 摇臂数
Num = 200 # 赌博机数量
times = 10000 # 交互次数
paraList = [('SA',0.1,'Sample Average'),('ERW',0.1,'Exponential Recency Weighted')]
# 解决 plt 中文显示的问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
fig = plt.figure(figsize=(12,8))
a1 = fig.add_subplot(2,1,1,label='a1')
a2 = fig.add_subplot(2,1,2,label='a2')
a1.set_xlabel('训练步数')
a1.set_ylabel('平均收益')
a2.set_xlabel('训练步数')
a2.set_ylabel('最优动作比例')
# 实例化 Num 个赌博机
bandits = []
for i in range(Num):
bandit = Bandit(K)
bandit.setPolicy('greedy')
bandits.append(bandit)
# 测试策略
for paraMode,paraEpsilon,paraLabel in paraList:
aveRCurve,avePCurve = np.zeros(times),np.zeros(times)
for i in range(Num):
print(paraLabel,i)
bandits[i].setPolicy(paraMode,paraEpsilon)
returnCurve,proportionCurve = bandits[i].play(times)
aveRCurve += 1/(i+1)*(returnCurve-aveRCurve) # 增量式计算均值
avePCurve += 1/(i+1)*(proportionCurve-avePCurve) # 增量式计算均值
a1.plot(aveRCurve,'-',linewidth=2, label=paraLabel)
a2.plot(avePCurve,'-',linewidth=2, label=paraLabel)
a1.legend(fontsize=10) # 显示图例,即每条线对应 label 中的内容
a2.legend(fontsize=10)
plt.show()
上述的指数近因加权平均方法,由于使用恒定步长,虽然适用于非平稳问题,但其对价值的估计是有偏的。
要兼顾恒定步长和无偏估计,可以使用如下步长
β n ≐ α o ˉ n \beta_n \doteq \frac{\alpha}{\bar{o}_n} βn≐oˉnα 其中 α > 0 \alpha>0 α>0 是一个传统的恒定步长, o ˉ n \bar{o}_n oˉn 是一个从零时刻开始计算的修正系数
o ˉ n ≐ o ˉ n − 1 + α ( 1 − o ˉ n − 1 ) , 对 n ≥ 0 , 满足 o ˉ 0 ≐ 0 \bar{o}_n \doteq \bar{o}_{n-1} + \alpha(1-\bar{o}_{n-1}),对 n\geq 0,满足 \bar{o}_0 \doteq 0 oˉn≐oˉn−1+α(1−oˉn−1),对n≥0,满足oˉ0≐0
乐观初始价值
,需要注意的是,这不是一个鼓励试探的普适方法,因为其试探的驱动力天生是暂时的,一旦任务发生变化,这种方法就无法再提供帮助。
因为对动作价值的估计总是存在不确定性,所以试探是必须的。 ϵ \epsilon ϵ-贪心允许试探,但是其试探是盲目的。
在非贪心动作中,最好是根据它们的潜力来选择可能事实上最优的动作,这就要考虑它们的估计有多接近最大值,以及这些估计的不确定性。
综合考虑这两个因素,可以使用 “基于置信度上界的动作选择方法
”(UCB),它根据下式选择动作
A t ≐ arg max a [ Q t ( a ) + c l n t N t ( a ) ] A_t \doteq \argmax_a[Q_t(a)+c\sqrt{\frac{lnt}{N_t(a)}}] At≐aargmax[Qt(a)+cNt(a)lnt]
其中, N t ( a ) N_t(a) Nt(a) 代表时刻 t t t 之前 a 被选择的次数,若 N t ( a ) = 0 N_t(a) = 0 Nt(a)=0,则认为a是满足最大化条件的动作之一
该方法思想源自
霍夫丁不等式Hoeffding's inequality
,它给出了 “随机变量的和” 与其 “期望值” 偏差的概率上限。具体而言,令 X 1 , . . . , X n X_1,...,X_n X1,...,Xn 为 n n n 个独立同分布的随机变量,取值范围 [ 0 , 1 ] [0,1] [0,1],其样本值的经验期望为 x ˉ n = 1 n ∑ j = 1 n X j \bar{x}_n=\frac{1}{n}\sum_{j=1}^n X_j xˉn=n1∑j=1nXj,则有
P [ E [ X ] ≥ x ˉ n + u ] ≤ exp ( − 2 n u 2 ) P\big[\mathbb{E}[X]\geq \bar{x}_n+u\big]\leq \exp({-2nu^2}) P[E[X]≥xˉn+u]≤exp(−2nu2) 其中 u u u 代表当前经验期望的不确定度, ≥ \geq ≥ 右边形成 X X X 真实期望 E [ X ] \mathbb{E}[X] E[X] 的一个上界,这个式子反映了该当前经验期不确定度超过 u u u 的最大概率。把该不等式应用到多臂赌博机问题中,有
- 真实价值 Q ( a ) Q(a) Q(a) 相当于上面被估计的 E [ X ] \mathbb{E}[X] E[X]
- 当前估计的经验期望 Q ^ t ( a ) = 1 N t ( a ) ∑ i = 1 N t ( a ) r i ( a ) \hat{Q}_t(a)=\frac{1}{N_t(a)}\sum_{i=1}^{N_t(a)}r_i(a) Q^t(a)=Nt(a)1∑i=1Nt(a)ri(a) 相当于上面的 x ˉ n \bar{x}_n xˉn
- 当前估计的不确定度 u u u 记为 U ^ t ( a ) \hat{U}_t(a) U^t(a),设 p = exp ( − 2 N t ( a ) U t ( a ) 2 ) p = \exp({-2N_t(a)U_t(a)^2}) p=exp(−2Nt(a)Ut(a)2),给定一个概率 p p p 就能找到对应的不确定度为 U ^ t ( a ) = − log p 2 N t ( a ) \hat{U}_t(a) = \sqrt{\frac{-\log p}{2N_t(a)}} U^t(a)=2Nt(a)−logp
这样处理后,可以直观地理解为:在当前时刻 t t t,真实价值 Q ( a ) Q(a) Q(a) 和当前估计 Q ^ t ( a ) \hat{Q}_t(a) Q^t(a) 的差距大于 U ^ t ( a ) = − log p 2 N t ( a ) \hat{U}_t(a) = \sqrt{\frac{-\log p}{2N_t(a)}} U^t(a)=2Nt(a)−logp 的概率不超过 p p p,当 p p p 很小时 Q ^ t ( a ) + U ^ t ( a ) \hat{Q}_t(a)+\hat{U}_t(a) Q^t(a)+U^t(a) 就成为 Q ( a ) Q(a) Q(a) 的可靠上界。这样我们的策略就可以设计为 “挑选期望奖励上界最大的拉杆”,从而选择最有可能获得最大期望奖励的拉杆,即
A t = arg max a [ Q ^ t ( a ) + U ^ t ( a ) ] A_t = \argmax_{a} \big[\hat{Q}_t(a)+\hat{U}_t(a)\big] At=aargmax[Q^t(a)+U^t(a)] 在实际操作中,可以设 p = 1 t p=\frac{1}{t} p=t1 使其逐渐减小,实现早期偏重探索,后期偏向利用的效果(类似 ϵ \epsilon ϵ 逐渐减小的 ϵ \epsilon ϵ-greedy),并用系数 c c c 来控制不确定性的比重,并且在开方项分母加 1 来避免分母为 0,此时
A t = arg max a [ Q ^ t ( a ) + c l n t 2 ( N t ( a ) + 1 ) ] A_t =\argmax_a\big[\hat{Q}_t(a)+c\sqrt{\frac{lnt}{2(N_t(a)+1)}}\big] At=aargmax[Q^t(a)+c2(Nt(a)+1)lnt]
从直观上看 l n t N t ( a ) \sqrt{\frac{lnt}{N_t(a)}} Nt(a)lnt 项,随着动作a被选中次数 N t ( a ) N_t(a) Nt(a) 增加,这一项会随之减小,而选则其他动作时, l n t lnt lnt增大,这一项也随之增大,因此开方项是对动作a估计价值的不确定性或方差的度量,系数 c 决定置信水平。随着时间的流逝,所有动作最终都将被选中,但具有较低估计价值或已经被选中更多次的动作,被选中的概率较低
利用十臂测试平台,赌博机设定同第 1.2 节,对比 UCB 和 ϵ \epsilon ϵ-贪心
从长远来看, N t N_t Nt 和 t 是同一个数量级,而 l i m t → ∞ l n t t = 0 lim_{t\to\infin} \frac{lnt}{t} =0 limt→∞tlnt=0,因此 UCB 方法是 “渐进贪心” 的
我们针对每个动作a考虑学习一个数值化的偏好函数 H t ( a ) H_t(a) Ht(a)。偏好函数越大,动作就越频繁地被选择。需要注意的是,偏好函数并不是从 “收益” 的意义上提出的,而是从动作间比较优势的角度提出
利用偏好函数 H t ( a ) H_t(a) Ht(a),使用 softmax 分布定义 t 时刻各个动作被选中的概率为
P r { A t = a } ≐ e H t ( a ) ∑ b = 1 k e H t ( b ) ≐ π t ( a ) Pr\{A_t=a\} \doteq \frac{e^{H_t(a)}}{\sum_{b=1}^k e^{H_t(b)}} \doteq \pi_t(a) Pr{At=a}≐∑b=1keHt(b)eHt(a)≐πt(a) 在初始时刻,所有动作的初始值都设为相同(比如全为0),这时各个动作被选中的概率是相等的。
注意:当只有两个动作 { a 1 , a 2 } \{a_1,a_2\} {a1,a2} 的情况下,softmax 分布与 logistic 回归或 sigmoid 函数给出的结果相同
P r { A t = a 1 } = e H t ( a 1 ) e H t ( a 1 ) + e H t ( a 2 ) = 1 1 + e − x Pr\{A_t=a_1\} = \frac{e^{H_t(a_1)}}{e^{H_t(a_1)}+e^{H_t(a_2)}} = \frac{1}{1+e^{-x}}\\ Pr{At=a1}=eHt(a1)+eHt(a2)eHt(a1)=1+e−x1 其中 x = H t ( a 1 ) − H t ( a 2 ) x = H_t(a_1)-H_t(a_2) x=Ht(a1)−Ht(a2)
在每个步骤中,选中动作 A t A_t At 并获得收益 R t R_t Rt 后,偏好函数按照以下方式更新
{ H t + 1 ( A t ) ≐ H t ( A t ) + α ( R t − R t ˉ ) ( 1 − π t ( A t ) ) , A t 是选中动作 H t + 1 ( a ) ≐ H t ( a ) − α ( R t − R t ˉ ) π t ( a ) , a ≠ A t 是非选中动作 \left\{ \begin{aligned} H_{t+1}(A_t) &\doteq H_t(A_t) + \alpha(R_t-\bar{R_t})(1-\pi_t(A_t)) &&,A_t是选中动作\\ H_{t+1}(a) &\doteq H_t(a) - \alpha(R_t-\bar{R_t})\pi_t(a) &&,a\neq A_t是非选中动作 \end{aligned} \right. {Ht+1(At)Ht+1(a)≐Ht(At)+α(Rt−Rtˉ)(1−πt(At))≐Ht(a)−α(Rt−Rtˉ)πt(a),At是选中动作,a=At是非选中动作
利用十臂测试平台进行测试,这个测试中所有动作的真实价值 q ∗ ( a ) q_*(a) q∗(a) 从正态分布 N ( 4 , 1 ) N(4,1) N(4,1) 中采样得到,其他设定同第3节。步长 α \alpha α 分别设定为0.1和0.4,对比基准项存在和不存在( R t ˉ ≐ 0 \bar{R_t} \doteq 0 Rtˉ≐0)时的性能
可见,基准项使得智能体可以马上适应新的收益水平,若取消基准项,性能显著下降。
把性能梯度展开
∂ E [ R t ] ∂ H t ( a ) = ∂ ∂ H t ( a ) [ ∑ x π t ( x ) q ∗ ( x ) ] = ∑ x q ∗ ( x ) ∂ π t ( x ) ∂ H t ( a ) = ∑ x ( q ∗ ( x ) − B t ) ∂ π t ( x ) ∂ H t ( a ) \begin{aligned} \frac{\partial \mathbb{E}[R_t]}{\partial H_t(a)} &= \frac{\partial}{\partial H_t(a)}[\sum_x\pi_t(x)q_*(x)] \\ &= \sum_xq_*(x)\frac{\partial \pi_t(x)}{\partial H_t(a)} \\ &= \sum_x(q_*(x)-B_t) \frac{\partial \pi_t(x)}{\partial H_t(a)} \end{aligned} ∂Ht(a)∂E[Rt]=∂Ht(a)∂[x∑πt(x)q∗(x)]=x∑q∗(x)∂Ht(a)∂πt(x)=x∑(q∗(x)−Bt)∂Ht(a)∂πt(x)
其中 B t B_t Bt 称为 “基准项”,可以是任意不依赖于 x x x 的标量。注意到概率之和 ∑ x π t ( x ) = 1 \sum_x\pi_t(x) = 1 ∑xπt(x)=1 是一个常数,因此随着 H t ( a ) H_t(a) Ht(a) 的变化,一些动作的概率会增加和减少,但这些变化的总和为0,即 ∑ x ∂ π t ( x ) ∂ H t ( a ) = 0 \sum_x\frac{\partial \pi_t(x)}{\partial H_t(a)} = 0 ∑x∂Ht(a)∂πt(x)=0,因此引入 “基准项” 后等号仍然成立。
接下来将求和公式中每项都乘以 π t ( x ) / π t ( x ) \pi_t(x)/\pi_t(x) πt(x)/πt(x),转换为求期望
∂ E [ R t ] ∂ H t ( a ) = ∑ x π t ( x ) ( q ∗ ( x ) − B t ) ∂ π t ( x ) ∂ H t ( a ) 1 π t ( x ) = E A t [ ( q ∗ ( A t ) − B t ) ∂ π t ( A t ) ∂ H t ( a ) 1 π t ( A t ) ] = E A t [ ( R t − R t ˉ ) ∂ π t ( A t ) ∂ H t ( a ) 1 π t ( A t ) ] \begin{aligned} \frac{\partial \mathbb{E}[R_t]}{\partial H_t(a)} &= \sum_x \pi_t(x) (q_*(x)-B_t) \frac{\partial \pi_t(x)}{\partial H_t(a)}\frac{1}{\pi_t(x)} \\ &= \mathbb{E}_{A_t}[(q_*(A_t)-B_t) \frac{\partial \pi_t(A_t)}{\partial H_t(a)}\frac{1}{\pi_t(A_t)} ] \\ &= \mathbb{E}_{A_t}[(R_t-\bar{R_t}) \frac{\partial \pi_t(A_t)}{\partial H_t(a)}\frac{1}{\pi_t(A_t)} ] \end{aligned} ∂Ht(a)∂E[Rt]=x∑πt(x)(q∗(x)−Bt)∂Ht(a)∂πt(x)πt(x)1=EAt[(q∗(At)−Bt)∂Ht(a)∂πt(At)πt(At)1]=EAt[(Rt−Rtˉ)∂Ht(a)∂πt(At)πt(At)1] 这里我们选择 B t = R t ˉ B_t = \bar{R_t} Bt=Rtˉ,注意到有 E [ R t ∣ A t ] = q ∗ ( A t ) \mathbb{E}[R_t|A_t] = q_*(A_t) E[Rt∣At]=q∗(At),因此这里用 R t R_t Rt 代替 q ∗ ( A t ) q_*(A_t) q∗(At)
下面展开偏导项 ∂ π t ( A t ) ∂ H t ( a ) \frac{\partial \pi_t(A_t)}{\partial H_t(a)} ∂Ht(a)∂πt(At),这里要用到商的求导法则
回代,有
∂ E [ R t ] ∂ H t ( a ) = E A t [ ( R t − R t ˉ ) ∂ π t ( A t ) ∂ H t ( a ) 1 π t ( A t ) ] = E A t [ ( R t − R t ˉ ) π t ( A t ) ( 1 a = A t − π t ( a ) ) 1 π t ( A t ) ] = E A t [ ( R t − R t ˉ ) ( 1 a = A t − π t ( a ) ) ] \begin{aligned} \frac{\partial \mathbb{E}[R_t]}{\partial H_t(a)} &= \mathbb{E}_{A_t}[(R_t-\bar{R_t}) \frac{\partial \pi_t(A_t)}{\partial H_t(a)}\frac{1}{\pi_t(A_t)} ] \\ &= \mathbb{E}_{A_t}[(R_t-\bar{R_t})\pi_t(A_t)(\mathbb{1}_{a=A_t}-\pi_t(a))\frac{1}{\pi_t(A_t)} ] \\ &= \mathbb{E}_{A_t}[(R_t-\bar{R_t})(\mathbb{1}_{a=A_t}-\pi_t(a)) ] \end{aligned} ∂Ht(a)∂E[Rt]=EAt[(Rt−Rtˉ)∂Ht(a)∂πt(At)πt(At)1]=EAt[(Rt−Rtˉ)πt(At)(1a=At−πt(a))πt(At)1]=EAt[(Rt−Rtˉ)(1a=At−πt(a))]
这样,我们就把性能指标的梯度写成了 ( R t − R t ˉ ) ( 1 a = A t − π t ( a ) ) (R_t-\bar{R_t})(\mathbb{1}_{a=A_t}-\pi_t(a)) (Rt−Rtˉ)(1a=At−πt(a)) 关于 A t A_t At 的期望,这样我们就可以在每个时刻进行采样,再进行与采样成比例的更新,即
H t + 1 ( a ) = H t ( a ) + α ( R t − R t ˉ ) ( 1 a = A t − π t ( a ) ) , 对所有 a \begin{aligned} H_{t+1}(a) = H_t(a) + \alpha (R_t-\bar{R_t})(\mathbb{1}_{a=A_t}-\pi_t(a)), 对所有a \end{aligned} Ht+1(a)=Ht(a)+α(Rt−Rtˉ)(1a=At−πt(a)),对所有a 即
{ H t + 1 ( A t ) ≐ H t ( A t ) + α ( R t − R t ˉ ) ( 1 − π t ( A t ) ) , A t 是选中动作 H t + 1 ( a ) ≐ H t ( a ) − α ( R t − R t ˉ ) π t ( a ) , a ≠ A t 是非选中动作 \left\{ \begin{aligned} H_{t+1}(A_t) &\doteq H_t(A_t) + \alpha(R_t-\bar{R_t})(1-\pi_t(A_t)) &&,A_t是选中动作\\ H_{t+1}(a) &\doteq H_t(a) - \alpha(R_t-\bar{R_t})\pi_t(a) &&,a\neq A_t是非选中动作 \end{aligned} \right. {Ht+1(At)Ht+1(a)≐Ht(At)+α(Rt−Rtˉ)(1−πt(At))≐Ht(a)−α(Rt−Rtˉ)πt(a),At是选中动作,a=At是非选中动作
这正是梯度赌博机算法中的更新公式,这样我们就证明了梯度赌博机算法是随机梯度上升算法的一种,这就保证了其有很强的收敛性
注意,对于 “基准项”,除了要求它不依赖于所选择动作外,不需要任何其他假设,我们可以将其设为0或1000,算法依然是随机梯度上升的特例。虽然 “基准项” 不影响算法的预期更新,但它确实影响更新值的方差,从而影响收敛速度。使用收益均值作为基准项可能不是最好的,但很简单,且在实践中表现良好