阅读本文前可以先了解我前三篇文章《强化学习之DQN》《强化学习之DDQN》、《强化学习之 Dueling DQN》。
Rainbow结合了DQN算法的6个扩展改进,将它们集成在同一个智能体上,其中包括DDQN,Dueling DQN,Prioritized Replay、Multi-step Learning、Distributional RL、Noisy Net。加上原版的DQN,凑齐七种因素,召唤Rainbow!
参考知乎:https://zhuanlan.zhihu.com/p/261322143
传统DQN中,每次学习的时候都会使用当前策略认为的价值最高的动作,所以会出现对Q值的过高估计,而这个问题表现在神经网络上就是因为选择下一时刻的动作以及计算下一时刻Q值的时候都使用了目标网络。为了将动作选择和价值估计进行解耦,因此有了DDQN。在计算Q实际值是,动作选择由Q网络得到而不是TargetQ网络。价值估计还是由TargetQ网络得到。
这个方法改变的是神经网络的结构,把Q值函数分解为价值函数V和优势函数A的和,即Q= V+A。其中V代表了这种状态的好坏程度,有时函数表明在这个状态下某一个动作相对于其他动作的好坏程度,而Q表明了这个状态下确定的某个动作的价值。为了限制A和V的值使得其在一个合理的范围内,我们可以用一种方法将A的均值限制为0以达到我们的要求。因此Q的计算公式如下:
Q ( s , a ; θ , α ) = V ( s ; θ ) + ( A ( s , a ; θ , α ) − 1 ∣ A ∣ ∑ a ′ A ( s , a ′ ; θ , α ) ) Q(s,a;θ,α) = V(s;θ) + (A(s,a;θ,α) - \frac{1}{|A|}\sum_{a'}A(s,a';θ,α)) Q(s,a;θ,α)=V(s;θ)+(A(s,a;θ,α)−∣A∣1a′∑A(s,a′;θ,α))
在传统DQN中,经验池中的数据采样都是随机的,但其实不同样本的价值是不同的,需要给样本一个优先级,并根据样本的优先级进行采样。
这里需要用到一个指标——TD误差。设目标网络产生的Q值为Q现实值,TargetQ网络产生的Q值为Q估计值。那么TD误差就是Q现实值-Q估计值。用来衡量优先学习的程度,如果TD误差越大,就代表预测精度还有很多的上升空间,这个样本就越需要被学习,即优先级p越高。
那么如何有效进行抽样?如果我们每次抽样都对p进行排序选取其中的最大值,会浪费大量的计算资源,从而使得训练时间变长。常用的解决方法是使用SumTree的树形结构来储存数据。这种树状结构本质上也是采用了概率式的选择方式,优先级p的大小跟选中的概率成正比,和线性的结构相比,这种方法不用逐一检查数据,大大提高了运行效率。
首先我们要对所有的数据建立一个树状结构,叶子节点储存每个样本的优先级p,每个树枝节点只有两个分叉,节点的值是两个分支的和。这样最上面的一层的一个节点是所有优先级p的和。
在抽样的时候,我们会将p的和分成batch_size个区间,然后再每个区间中随机选择一个数。例如我们在[21,28]的区间中选择了24,就按照42往下搜索,从左往右对比,如果这个数比节点小就继续往下走,比节点大则用这个数减去节点的数字然后继续往右进行对比。这里24比13大,因此往右搜索,数字变成24-13=11,11比16小,因此往下走,11比12小,因此我们最终选取的是优先级为12的这组数据。
传统DQN使用当前的即时奖励和下一时刻的价值估计来判断目标的价值,然而这种方法在训练的前期网络参数偏差较大时会导致得到的目标价值也会偏大,进而导致目标价值的估计偏差较大,因此出现了多步学习来解决这个问题。在多步学习中,即时奖励会通过与环境交互确切得到,所以训练前期的目标价值可以得到更准确的估计,从而加快训练的速度。
原DQN使用的是时序差分的更新策略即TD。loss公式为:
( r j + γ max a Q ^ ( s j + 1 , a ; θ − ) − Q ( s j , a j ; θ ) ) 2 (r_j + \gamma \max_a \hat{Q}(s_{j+1},a;\theta^-) - Q(s_j,a_j;\theta))^2 (rj+γamaxQ^(sj+1,a;θ−)−Q(sj,aj;θ))2
以上是one-step的TD算法。
在rainbow中我们采用multi-step方法,对于N步的情况,loss公式变为:
( ∑ k = 0 N − 1 γ k r t + k + γ N max a Q ^ ( s t + N , a ; θ − ) − Q ( s t , a t ; θ ) ) 2 (\sum_{k=0}^{N-1}{\gamma^k r_{t+k}} + \gamma^N \max_a \hat{Q}(s_{t+N},a;\theta^-) - Q(s_t,a_t;\theta))^2 (k=0∑N−1γkrt+k+γNamaxQ^(st+N,a;θ−)−Q(st,at;θ))2
论文原文:https://www.aminer.cn/pub/599c7b58601a182cd272b540/a-distributional-perspective-on-reinforcement-learning
这篇文章开创了一个新的方向,将我们的认知从“Q值”拓展到"Q分布"。
在传统DQN中,网络输出的是动作价值Q的估计,但是其实还是忽略了很多信息。假如两个动作能够获得的价值期望相同都是20,第一个动作有90%的情况是10,10%的情况下是110,第二个动作的50%的情况下是25,50%的情况下是15,那么虽然期望一样,但是要想减少风险,就应该选择后一种动作,只输出期望值看不到背后隐含的风险。
如果采用分布视角(deistributional perspective)来建模DRL的模型,可以的得到更好更稳定的结果。我们可以把价值限定在 [ V m i n , V m a x ] [V_{min},V_{max}] [Vmin,Vmax]之间,选择N个等距的价值采样点,通过神经网络输出这N个采样点的概率,通过Q和TargetQ网络得到估计的价值分布和目标的价值分布,计算两个分布之间的差距。
现在的问题是如何表示这个分布,首先抛弃高斯分布,因为是单峰的,Distributional DQN的论文作者提出了一个叫做C51的算法,用51个等间距的atoms来描述一个分布,类似直方图,选择点的范围和个数取决于你的应用。
这时候网络的架构需要做一定的调整,原DQN输入的是状态s,输出的是一个包含各个动作价值的向量 ( Q ( s , a 1 ) , Q ( s , a 2 ) , . . . , Q ( s , a m ) ) (Q(s,a1),Q(s,a2),...,Q(s,a_m)) (Q(s,a1),Q(s,a2),...,Q(s,am))。在Distributional DQN中,输入不变,输出变成一个矩阵,每一行代表一个动作,而列则代表了直方图中的每一条柱子,这个分布的范围是人为确定的,例如atoms有51个,范围为 ( 0 , 50 ) (0,50) (0,50),则atoms是 0 , 1 , 2 , . . . , 49 , 50 {0,1,2,...,49,50} 0,1,2,...,49,50。而神经网络输出的每一个动作对应每一个atoms的概率,有N个atoms则有N个概率,相加为1,形式是 p 0 a , p 1 a , . . . , p N − 1 a {p_0^a,p_1^a,...,p_{N-1}^a} p0a,p1a,...,pN−1a,每个概率和对应的atoms的值相乘可以得到动作价值的期望,即原本的Q值。
确定了分布的形式之后,接下来就是如何衡量两个分布的距离,以此来决定Loss函数。这里作者采用的是KL散度。
KL散度,也称为相对熵,是衡量两个分布差距的计算公式。公式如下:
D K L ( p ∣ ∣ q ) = ∑ i = 1 N p ( x i ) ∗ ( log p ( x i ) − log q ( x i ) ) = ∑ i = 1 N p ( x i ) ∗ log p ( x i ) q ( x i ) D_{KL} (p||q) = \sum_{i=1}^N p(x_i) * (\log p(x_i) - \log q(x_i)) = \sum_{i=1}^N p(x_i) * \log \frac{p(x_i)}{q(x_i)} DKL(p∣∣q)=i=1∑Np(xi)∗(logp(xi)−logq(xi))=i=1∑Np(xi)∗logq(xi)p(xi)
可以证明这个值大于等于0。当两者分布接近时,这个值会趋近于0,这个值越大,分布差距越大。
从式子中可以看出,KL散度计算的是数据的原分布与近似分布的概率的对数差的期望值。但要注意,散度不具有交换性,不能单纯理解为距离,更准确的说是一个分布相比另一个分布的信息损失。
在原DQN中,动作价值的更新目标是
r + γ max a Q ( s t + 1 , a ) r + \gamma \max_a Q(s_{t+1},a) r+γamaxQ(st+1,a)
在分布式DQN中:
Q ( s t + 1 , a ) = ∑ i z i p i ( s t + 1 , a ) Q(s_{t+1},a) = \sum_i z_i p_i(s_{t+1},a) Q(st+1,a)=i∑zipi(st+1,a)
其中z就是直方图的横坐标的各个值,p就是对应的各个概率。那么更新目标 Z ( s , a ) Z(s,a) Z(s,a)有p0概率为 r + γ z 0 r + \gamma z_0 r+γz0,有p1概率为 r + γ z 1 r + \gamma z_1 r+γz1,以此类推。
当分布更新后,对应直方图的横坐标会发生偏移,因此我们需要调整分布。把 r + γ z i r + \gamma z_i r+γzi的分布均摊到 z i z_i zi上,例如 r + γ z 0 r + \gamma z_0 r+γz0位于z0和z1之间,我们可以计算它到两个点距离的比值决定均摊概率的比值。
RL过程中总会想办法增加agent的探索能力,传统的DQN通常采用ε-greedy的策略,即以ε的概率采取随机策略,通过在训练初期采取较大的ε来增加系统的探索性,训练后期减小ε来实现系统的稳定。另外一种办法就是噪声网络,即通过对参数增加噪声来增加模型的探索能力。一般噪声会添加在全连接层,考虑全连接层的前项计算公式:
y = w x + b y = wx +b y=wx+b
假如两层神经元的个数分别是p和q,那么w是q*p维的,b是q维的,如果b和w满足均值为μ,方差为σ的正态分布,同时存在一定的随机噪声N。假设噪声满足标准正态分布,那么前项计算公式变为:
y = ( μ w + σ w ⊙ N w ) x + μ b + σ b ⊙ N b y = (μ^w + \sigma^w \odot N^w)x + μ^b + \sigma^b \odot N^b y=(μw+σw⊙Nw)x+μb+σb⊙Nb
产生噪声的方法主要有两种一种是Independent Gaussian noise,一种是Factorised Gaussian noise。对于DQN这种很稠密的算法来说我们往往使用Factorised Gaussian noise。对应A3C这种并行更依赖采样的方法我们可以使用Independent Gaussian noise。
independent Gaussian Noise是给每一个权重都添加一个独立的随机噪声,那么一共需要 p ( q + 1 ) p(q+1) p(q+1)个随机噪声。
Factorised Gaussian noise 相对节省计算量,它给每一个神经元一个噪声,图中只需要p + q个随机噪声。
具体到每一个神经元上, w i j w_{ij} wij的噪声为:
N i , j w = f ( N i ) f ( N j ) N_{i,j}^w = f(N_i)f(N_j) Ni,jw=f(Ni)f(Nj)
b j b_j bj的噪声为:
N j b = f ( N j ) N_{j}^b = f(N_j) Njb=f(Nj)
其中:
f ( x ) = s g n ( x ) ∣ x ∣ f(x) = sgn(x) \sqrt{|x|} f(x)=sgn(x)∣x∣