【强化学习】第七章:深度强化学习原理、DQN算法
一、本章节在整个强化学习体系中的位置
强化学习分三种范式:基于价值的强化学习、基于策略的强化学习、基于AC框架的强化学习。其中基于AC框架的强化学习是前两种的大一统范式。这三种范式可以说是强化学习领域的三个独立技术分支。基于价值的强化学习(包括状态价值和动作价值)就是我们常说的传统强化学习,本章之前所有章节的所有算法都属于这一分支。而本章的深度强化学习和传统强化学习的区别仅仅是计算价值函数的形式不一样:一个是表格型,一个是函数的形式。所以从强化学习的范式上看,深度强化学习和传统强化学习是没有什么突破的,都是基于价值的强化学习。也就是都是基于价值对策略进行评估->评估完毕后进行策略提升,如此循环直到最优策略。
后面第八章我们讲基于策略的强化学习以及第九章基于AC框架的强化,这两章是和本章并驾齐驱的不同范式的强化学习技术线路,届时大家可以对比学习、灵活运用到你的实际问题中。
二、深度强化学习简介
1、重大飞跃:从表格型强化学习-->函数型强化学习
本系列前六章讲的都是传统的强化学习,也叫表格型的强化学习tabular representation。为什么叫表格型呢?因为不管是贝尔曼公式、DP、MC、TD算法、还是sarsa、Q-learning算法,它们都要求状态价值或者动作价值。也就是我们需要把实际问题分门别类的整理成一个个状态,或者整理成一个个(s,a)状态动作对儿,然后求状态价值或者动作价值。这样我们求出来的价值就是一个表格的形式,所以也叫表格型学习tabular representation。
所以,很明显,当实际问题中的状态和动作非常多时,比如无人机飞行,显然也是一个马尔可夫序列,但是这个序列的状态和动作实在无法用表格枚举出来,此时传统算法就显得无能为力了。于是人们就想,能不能用一个函数来表示所有状态动作对儿的价值呢?此时就诞生了深度强化学习:用深度神经网络来拟合这个函数。也就是输入神经网络一个状态动作对儿,网络就输出一个价值值。于是强化学习从表格的离散性进化到了函数的连续性,也即从tabular representation进化到function representation。这是强化学习领域的一次重大跳跃。也正是这个飞跃,使得强化学习可以应用到更加复杂的场景中,解决更加复杂的问题:
2、价值函数逼近(Value Function Approximation)
深度强化学习和传统强化学习的区别是:计算价值函数的方式不一样。传统强化学习算出来的是表格形式的离散数据,是一个准确的价值值。而深度强化学习是用函数来拟合,所以通过函数算出来的价值值只是对表格数据的一个近似,不是准确的价值值,是一个近似的价值值,所以深度强化学习也叫Value Function Approximation(价值函数近似),也叫价值函数逼近。这个函数则叫逼近函数,也叫逼近器,function approximators。
深度强化学习最大的优点是解决了large or continuous state or action spaces中的存储(storage)问题和泛化(generalization ability)问题。由于用函数代替了表格,我们只需要把函数的参数w存储下来即可,来一个s或者一个(s,a)对儿,可以根据函数输出其价值值。此外,对于像直升机飞行这种无法描述状态和动作的问题,根据函数的连续性特性,就可以轻松得到价值插值。
所以深度强化学习的这种存储要求小、泛化能力强的特点,使得它可以解决复杂问题的预测和控制,或者说求解复杂问题的价值函数或者策略优化极具优势,这是表格性强化学习无法做到的:
3、本章的写作脉络
(1)先介绍深度学习中的概念、思路,是如何被引入到强化学习中的?这些概率、思路在强化学习中解决的是哪些环节的问题?和传统强化学习一样,我们先讲如何进行价值评估,也就是如何估计state value。
(2)此后讲Sarsa with funtion approximation,也就是讲如何估计动作价值action value。
(3)最后讲Q-learning with function approximation和DeepQ-learning(DQN),如何估计最优动作价值optimal action value,也就是如何搜索到最优策略。
(1)(2)(3)的顺序也是我们前面学传统强化学习的学习过程,这是一个从简到难、逻辑闭环的过程。所以这里深度强化学习也遵照这个主线。
上面(1)是基础中的基础,是我们前面所学的所有内容和深度学习融合的新知识,要占非常大的一个篇幅,主要讲解深度强化学习的原理、思想、概念、细节等。后面的(2)(3)就是顺水推舟,理所当然的事情了,篇幅会非常少。
三、从逼近函数->目标函数->优化目标函数->状态价值评估
(一)逼近函数(function approximatiors)
1、如何定义逼近函数?
下图是从逼近函数的输入和输出角度、以及逼近函数的形式,来说明选择逼近函数的原则:(1)从逼近函数的输入和输出角度看:
如果我们要逼近的是状态价值函数,就用上图的A形式。目标函数A的参数是w,输入s,输出价值值。
如果我们要逼近的是动作价值函数,就用上图的B或C形式。其中:
B的输入是(s,a),输出动作值。
C的输入只有s,输出是状态s下的所有动作的价值值。当然这种情况就要求动作都是离散型的,如果动作也连续,那就没法输出了。
(2)从逼近函数的形式来看,我们倾向于使用可微分的逼近器,因为可微分工具在求导(也就是求最优值)时比较方便,即时再复杂,用链式法则就可以轻松求解嘛。
其实逼近函数可以是线性逼近器也可以是非线性逼近器,至于你选择何种逼近器,主要就取决于模型效果,以效果为导向。当你的模型或者场景非常简单,那可以一个简单的线性函数就可以拟合,就没必要上非线性的。当你的场景非常复杂,那你就得用比如深度神经网络才能更好的拟合。所以逼近器的复杂度是要和你的任务以及模型效果匹配的。
2、如何定义逼近函数的输入?
我们用深度强化学习解决的实际问题一般都是比较复杂的问题,所以我们一般用特征向量作为输入。所以当逼近函数的输入是s或者(s,a),那第一步就是考虑如何将s或者(s,a)表示成向量的形式:这个过程也叫状态的向量化过程,上图直升机例子中,我们用右边的这个9维的向量基本就可以表示直升机的当前状态s,当然,如果你要表示直升机的(s,a),那你在这个9维向量后面继续加动作向量即可。
说明:其实这里和NLP中的词嵌入操作是同理的,所以这里的操作可以借鉴NLP中词嵌入的各种技巧。但是话说回来,技巧终归是技巧,是锦上添花的东西,最基础最重要的还是你得非常好的理解你自己的实际问题,你对你要解决的实际问题的深刻理解,你才能根据你的具体需求设计出表征能力比较强的输入向量。
(二)目标函数(Objective function)
1、为什么要定义目标函数?
如果把逼近函数类比成深度网络,那目标函数就可以类比深度学习中的损失函数。
和深度学习一样,我们是先搭建网络模型,然后构建损失函数,优化损失函数,就得到了模型的参数。
深度强化学习也同理,逼近函数就是等同于是网络模型,目标函数就等同于损失函数。有了损失函数,就可以优化损失函数了。优化损失函数的过程也就是迭代逼近函数参数的过程。当损失函数优化到收敛,就得到了一组最优的逼近函数参数,我们就有了逼近函数。逼近函数有了就可以输入状态或者状态动作对儿,输出价值值了。也就是可以进行策略评估了。上图是赵世钰老师的课件,它描述了深度强化学习的大框架。
2、如何定义目标函数
目标函数的形式可以有多种,具体你要选取哪种目标函数是根据你的实际情况决定的。这就类似深度学习中的损失函数,如果你是回归任务,那你的损失函数就得用均方误差;如果你的任务是分类任务,那损失函数就用交叉熵损失;如果你的任务是输出一个分布,那你就得用KL散度来度量损失。同理强化学习也是:(1)上图的objective function1是用真实的状态价值与逼近函数预测的状态价值之间的均方误差的期望作为损失,构建目标函数J(w)。通过求目标函数J(w)的最小值,就可以得到逼近函数v(s,w)的参数,进而可以进行策略评估了。
这种目标函数是最简单最直观的一种。你想通过逼近函数得到状态价值值,或者是得到状态价值对儿的价值值,所以逼近函数一定是一个回归模型,而不是分类模型,当然如果要得到多个动作的价值值,可以回归多个结果。回归模型的损失函数一般用样本的均方误差Σ(y-yhat)^2作为损失函数,然后最小化这个损失函数,进而求得模型参数的。所以这种目标函数也叫True value error。因为是最小化决定误差量的嘛。
但是上图A处,为什么不像深度学习中的损失函数一样去求和Σ,而是求期望E呢?因为二者从根上就不一样,没有可类比性。强化学习是依赖稀疏且延迟的奖励信号r(如成功或失败的反馈),智能体需通过探索平衡短期奖励与长期收益,目标是最大化累积奖励或者是寻找最优策略;机器学习则使用精确的标签或损失函数(如分类正确性或预测误差),目标是直接最小化训练数据上的误差。二者从根本上就不一样。这里的期望是从强化学习本身概念出发而写出来的式子。
如果我们想优化function1,也就是minimize J(w),或者说训练J(w):
一是要把A处的期望E给展开。上图B处,就是把A处的求期望E给展开了,所以就变成求vhat(预测值)和v(真实值)的求模了。脚标D表示求模时的权重。D具体表示什么样的权重呢?下面我们会讲uniform distribution和stationary distribution两种权重,就是D的具体表示。
二是我们还得要知道真实的vп:
如果是有模型场景,那通过系统奖励和状态转移矩阵,我们就可以求出真实的vп。此时J(w)就可以被正常训练了。
如果是无模型场景,我们是无法准确求出真实的vп的。无模型就得有经验数据。此时我们可以用经验数据代替vп。一种最简单的代替法就是前面学的蒙特卡洛方法MC,通过一条条episode,计算出所有s的vп,当作真实的vп,来训练J(w)。
所以True value error目标函数适用于有模型场景和可以得到完整episode经验数据的无模型场景。
(2)上图的objective function2叫贝尔曼误差Bellman error。其中的D和function1中的一样,只是把真实的vп(s)值用经验数据代替了,而且代替的方式和function1有点不一样:
如果是有模型场景,那通过系统奖励和状态转移矩阵,我们就可以求出真实的vп(s),此时用绿框中的式子,就可以优化J(w)了。
如果是无模型场景,那就用经验数据计算蓝框中的式子。但是蓝框中式子的计算是不需要完整的episode经验数据的,用Trajectory片段就可以,因为它计算状态价值是用时序差分学习的,也就是TD学习。
所以,如果你是无模型,经验数据只是一些Trajectory片段,那你最好用Bellman error作为目标函数,因为这样才能被训练。
(3)上图的objective function3叫贝尔曼投影误差Projected Bellman error。只是在Bellman error的前面加了一个投影矩阵M。我们知道矩阵的作用就是变换维度空间。当Bellman error无法被最小化到接近0时,我们加一个投影矩阵就可以了!就这么简单。就是如果你的逼近函数永远也无法逼近你的经验数据时,给逼近函数前面乘以一个M矩阵,就是把逼近函数的结果投影到另外一个空间,这样目标函数就可以最小化到0了。
为什么会出现“无法被最小化到接近0”?比如真实的vп(s)是一个曲面,如果我们的逼近函数是一个平面,显然这个逼近函数是无法无限逼近真实的vп(s)的,此时目标函数J(w)怎么优化都不可能趋向0的,此时加一个M矩阵,就可以优化到趋近0的效果了。
3、uniform distribution(平均分布)、stationary distribution(平稳分布)(1)我们的目标是去掉E,E是期望的意思,所以我们可以把系统状态看作是随机变量。那求随机变量的期望,只要知道随机变量的分布,期望就可以求出来了。
(2)所以求随机变量s的期望,换个角度说就是求随机变量s的平均值。所以最朴素的一个方法就是假设所有状态的分布都是相同的,我们按照状态s的平均分布,就把E给去掉了:
uniform distribution假设每个状态的重要性都是一样的,那求状态价值时,所有状态的权重就都是一样的。如果系统中的状态有S个,那每个状态s的权重就是1/S。
但是在实际问题中,这个假设有点武断。比如在网格游戏中,显然目标格子或者靠近目标格子的格子,这些格子的价值值应该是更大一些,所以我们应该给这些格子分配一个更大的权重,让其价值大一些。所以人们又假设了stationary distribution(平稳分布).
(3)stationary distribution(平稳分布):
一是,上图中的dп(s)是随机变量s在策略п下的一个概率分布。所以dп(s)是在0-1之间的。当dп(s)知道了,J(w)中的期望E就可以按照dп(s)的权重展开了。
二是,dп(s)分布可以描述long-run hehavior(长期行为)。long-run hehavior的意思是:假如是打游戏,假如在策略п下,我打了足够多轮这个游戏,那么游戏中的所有状态s出现的频次其实就会趋向一个稳定的数(概率值)。这个稳定的概率分布就是dп(s)。下面用一个例子直观的理解一下dп(s):可见,出现频率越高的状态s,其概率值就越大,也就是dп越大,也就是在J(w)中的权重值就越大。当我们最小化J(w)时,v(s)的估计误差就越小。
也可见,如果一个状态的dп越大,就说明这个状态被agent访问的概率越大。
(三)梯度下降法优化目标函数
其实在讲如何定义目标函数时,已经从目标函数的形式出发,讲了一些关于优化目标函数的知识点,这里再从优化算法gradient-descent algorithm的角度,再讲一遍优化目标函数的计算过程:上图红框中的式子就是梯度下降优化算法中的参数迭代过程,这个过程就是最最原始的梯度下降算法的最一般的形式,数学推导过程并不复杂。上图最大的细节就是把梯度下降计算过程中的步长参数、求期望中的常数2、以及去掉期望E的dп参数,统统合并到at中了。
但是上图红框中的公式还是没法进行迭代的,因为还有vп(st)不知道呢。如何得到vп(st)呢?无模型,自然就是从agent和环境的交互数据中估计得到的呀。所以按照如何计算vп(st),深度强化学习状态价值评估的优化算法就分Monte Carlo learning with function approximation和TD learning with function approximation两种:(1)用蒙特卡洛方法学习到的gt来代替vп(st)。比如agent在策略Π下,去和环境进行交互,获取一条episode,那么沿着这条episode上的所有s都可以计算出其discounted return,这个就是gt,我们用这个gt来作为vп(st)的估计值。
(2)用TD learning来代替vп(st)。右边是伪代码。TD learning更新w时,用的是Trajectory经验数据,用每个step数据来更新w的。也所以TD learning with function approximation其实是在minimize Bellman error的。MC是最小化true value error的。
注意:上面都只是状态价值评估。不是一个完整的强化学习流程。完整的强化学习流程是要搜索到最优策略的。这里只讲如何逼近策略Π下的状态价值值。
至此,价值函数逼近(Value Function Approximation)的理论部分都讲完了,可以实操状态价值评估了。
(四)案例:用TD linear估计状态价值
我们现在学的是深度强化学习,所以大家都默认是用深度神经网络当作逼近器,也就是非线性逼近器。其实并不是说线性逼近器有多好,只是线性逼近器更简单、更直观,更方便我们从理论上深刻理解这个算法。当你非常深刻的理解了线性逼近器,非线性的就顺水推舟了。所以下面我用TD linear给大家展示一个例子,更加直观的理解一下value function approximation。
1、案例介绍这个例子是一个5x5的网格世界,每个格子对应5种action:上、下、左、右、不动。 策略Π是:每种动作的概率都是0.2的随机策略。
我们的目标是评估在策略Π下,每个格子的价值值。这就是一个价值评估问题。
模型参数设置:如果agent进入黄色格子或者碰到四壁,系统奖励-1分。如果agent到达蓝色目标格子,系统奖励1分。回报的折扣系数γ是0.9。
上图右边的表格是基于模型、用贝尔曼公式,求解出来的所有格子的价值值。右边的3D图是表格的可视化效果。
2、下图是表格型TD算法的结果左边是经验数据:agent在策略Π下,跑了500个episodes,每个episode有500步,每个episode的起始(s,a)是随机选取的,并且服从均匀分布。
中间3D图,是利用这些经验数据,使用传统的TD算法,最终迭代出所有格子的价值值并绘制成3D图的效果。
右图是,随着使用的episode越来越多,估计的误差也逐渐减小到0。说明传统的TD算法还是效果非常好的。
3、用线性函数逼近方法:TD linear估计每个格子的价值值
(1)下图是用一个平面函数来逼近真实的状态价值值:
(2)下图是用一个更加复杂的曲面函数来逼近:可见逼近函数越复杂拟合得越好。上图用的都是线性逼近函数,所以即时增加复杂度,它也无法拟合非线性问题。也所以上图的拟合误差依然没有趋近0。也所以我们一般都用神经网络来逼近,因为神经网络可以拟合任何非线性问题。
当然你要很好的trade off,平衡逼近函数和实际问题。如果实际问题特别简单,那你用非常复杂的函数逼近,就会过拟合;如果实际问题非常复杂,你用非常简单的逼近函数拟合,那就会出现欠拟合的情况。这需要我们做平衡和取舍。
四、动作价值估计:Sarsa with function approximation
1、前面我们用function approximation估计的是状态价值值。下面我们开始估计动作价值,下面是逼近函数的迭代原理:
2、下面是Sarsa with function approximation的伪代码。用Sarsa可以直接计算出动作价值,但为了获得最优策略,我们还得进行策略提升,搜索最优策略。所以下面的伪代码添加了策略提升部分。
3、案例: Sarsa with linear function approximation
五、Q-learning with function approximation、Deep Q-learning
本部分是估计最优动作价值optimal action value。
(一)Q-learning with function approximation


Q-learning可以on policy也可以off policy,这里给了一个on policy的版本,其他也没什么详细说明,因为Q-learning的在轨版本和Sarsa是一样的,所以不用过度解释了。下面讲Deep Q-learning,我会给出一个off policy版本,届时大家可以对比看。
(二)Deep Q-learning
Deep Q-learning也叫deep Q-network(DQN),是Q-learning的一个变种,是把深度学习引入强化学习的最成功的一个算法,就是2013年玩Atari游戏超越了人类水平的那个算法。DQN展现了深度学习与强化学习结合的强大力量,自此深度强化学习迅速成为AI领域的宠儿,大量研究者蜂拥而入,提出了A3C、PPO、TRPO、DDPG等一系列重要的算法框架。
深度强化学习普遍是用于复杂的无模型场景,当前深度强化学习的大部分算法都是以Q-learning算法为基础演变而生的。一是因为,Q-learning中Q是动作价值的意思,深度强化学习基本上学的都是动作价值,基本不会再学状态价值了。二是因为,Q-learning算法可以用于离轨学习,这就更适合无模型的复杂场景。
1、DQN的逼近函数(1)上图最右边的逼近函数是Q-learning with function approximation的逼近函数,这里的function一般是linear function,输入是(s,a)向量,输出q(s,a)值。
DQN是神经网络+Q-learning,它对右边的逼近函数进行了改进,用非线性函数替代了线性函数,具体说就是用神经网络替代了线性函数,所以叫Deep Q-learning,也就是上面的左图。 那既然是神经网络,我们只要在输出层多加几个神经元,就可以回归多个数字了。所以DQN的输入可以只输入s,输出s对应的所有动作的价值值。这也是DQN有别于Q-learning with function approximation的重大区别之一。也是DQN比Q-learning with function approximation更高效的因素之一。
(2)DQN的逼近函数是一个浅层的神经网络,shallow neural network, 总共有3层,输入层、1个隐藏层、输出层。其中隐藏层有100个神经元。隐藏层就是用来进行非线性变换的。
经验:一般情况下,深度强化学习的逼近网络都不需要太深的网络。
(3)DQN是搭建了两个一模一样的逼近网络,一个取名叫target net,另一个取名叫main net。至于原因后面有详细解释。此后再看到target net 或者 main net你知道是逼近网络即可。
2、DQN的目标函数上图的J(w)就是DQN的目标函数,其实就是最优贝尔曼误差。
表格的Q-learning迭代的也是最优贝尔曼方程。在期望E的加持下,上图A处就等于q(s,a),所以就是贝尔曼最优方程。
DQN的目标函数不难理解,难点在于优化,也就是DQN的训练。
3、优化目标函数存在的问题上图就是一个悖论:因为是无模型,我们就不知道max q(st+1,a);不知道max q(st+1,a),J(w)红框部分(B处)就不知道;不知道B处,那就没法优化J(w)。
所以DQN的J(w)的B处用了max q(st+1,a,w)来求解替代max q(st+1,a),所以J(w)从E(Rt+1 + γmaxq(st+1,a) - qhat(s,a,w))的平方,变成了E(Rt+1 + γmaxq(st+1,a,w) - qhat(s,a,w))的平方(也就是B处)。
这么一变就意味着,max q(st+1,a)得从逼近网络qhat中求得!那么现在的问题就又变成:我就是要求qhat的,就是想求qhat中的参数的,现在你还让我根据qhat求max q(st+1,a)。这不就变成了:从一个不靠谱的函数中求max q(st+1,a),其结果也是一个不靠谱的东西,我再用这个不靠谱的结果去优化这个函数!
其实这个现象这就类似 blog.csdn.net/friday1203/… 这篇文章中的用贝尔曼最优方程求解最优策略的迭代过程一样。当时我们也是假设初始所有q=0,然后根据最优贝尔曼方程一步步迭代,依然可以迭代到真实的最优的q。这篇文章中有具体例子,大家可以自行查阅。
所以上图中把max q(st+1,a)用max q(st+1,a,w)来替换也是没有问题的。但问题就是,这个问题会带来另外一个问题:怎么求梯度,迭代w呢?也就是怎么训练?DQN的第一个tricky就是搭建两个网络来训练!
4、搭建两个网络,间隔训练(1)DQN是分别搭建了两个一模一样的网络,一个取名为main network,参数为w;另一个取名为target network,参数为wT。这两个网络的参数w和wT在最开始初始化时都一样。这和深度学习中的对抗网络GAN的思想非常相似,二者在训练上也类似,感兴趣的可以参考blog.csdn.net/friday1203/… 。
(2)DQN在训练时,是先保持target newwork的参数wT不变,也就是已知的,这样训练数据经验target newwork时,就会得到所有动作的确切的价值值,选择一个最大价值的动作值作为yT,这样yT就是一个常数。
当数据经过main network时,J(w)=E(yT-qhat(s,a,w)),此时反向传播求参数w的梯度,更新w。当w更新几轮后,我们直接将main network的参数赋值给target network,重复上面的w迭代即可。
如此循环,最后J(w)也能收敛到趋近于0的水平。
(3)当然,模型训练离不开数据,下面就讲解DQN在数据方面的tricky。
5、训练数据:经验回放(Experience replay)本部分讲的DQN是离轨学习。离轨学习不是边打边学,不是边打游戏,边更新网络参数的那种。离轨学习是先把所有的游戏数据都拿到,不管是啥策略下的游戏数据,只要是游戏数据都可以,你可以是一条条按照时序的episode序列,也可以仅仅是一些Trajectory片段也可以,我们称这些数据为经验数据。DQN就是从这样的经验数据中去寻找最优策略。
所以当我们拿到经验数据后,不是按照数据的原来顺序来训练的,而是把所有的数据都切成(s,a,r,s')片段,每个(s,a,r,s')片段叫experience sample,把所有的、打散的experience sample放到一个集合B中,这个集合B叫replay buffer。
当我们训练模型时,也就是优化J(w)时,我们是在replay buffer中抽取一个个mini-batch的方式来训练模型的。这和深度学习的训练方式是一样的。
-
怎么取一个mini-batch呢?
目标是:mini-batch中的样本要服从均匀分布uniform distribution。
具体操作是:把所有的(s,a)看成是一个个索引,或者是一个个随机变量,从打散的B中均匀抽取即可。
我们这样取mini-batch的方法就叫experience replay,经验回放。
- 必须得是均匀分布吗?
其实也不一定,但是我们一般都用均匀分布,除非你有先验知识,你提前就知道哪些(s,a)对儿是重要的,哪些(s,a)对儿不重要,此时你可以用其他分布,比如高斯分布,当然你采样时也是重要的(s,a)经验对儿采样次数多一些,不重要的采集的次数少一些。在我们无任何先验知识的情况下,用均匀分布是普遍做法。
下面是表格型Q-learning和函数型Q-learning在数据分布方面的不同要求:tabular Q-learning当然也能用experience replay。因为tabular Q-learning也是off policy的算法,off policy算法是提前收集数据,而且不用care你的数据是什么策略下的数据、是整个episode还是只有一段Trajectory,就是不管是什么经验数据都是可以的。
经验回放的好处就是,同一个sample可以使用多次,也就是可以让你的sample更加efficient,就是可以充分利用你的经验样本数据,因为放在一个replay buffer中,你是多次均匀采样的嘛。
这样可以节省数据,我们之前例子tabular Q-learning中的episodes需要10万步,而DQN只要1000步就可以达到非常好的效果。因为在状态转移是确定的情况下,或者说在策略确定时,我们只要保证每一个(s,a)对儿都被访问过一次就可以了,我们可以反复用这1次的经验。tabular Q-learning的10万步,都是一条条episode,当我们用了这条episode中的某个(s,a)对儿后,序列中其他的数据就被丢弃了,是一种浪费。
6、DQN的伪代码(off-policy版本)
DQN是deep Q-learning的变体。因为Q-learning有on-policy版本和off-policy版本,两个版本。所以DQN也是有两个版本。本部分是off-policy版本。就是先收集经验数据,然后用经验数据训练网络,也就是计算出所有的q(s,a)后,最后一次性找到最优策略的算法:(1)在Πb下收集经验数据,然后把数据切分成(s,a,r,s'),打散,放入集合B中。
(2)开始循环:
第一步:从B中随机的、均匀的采样,采集一个nimi-batch样本。
第二步:对nimi-batch中的每一个样本计算yT。计算过程是:即时奖励r + 下一个状态s'的最大动作价值。
“下一个状态s'的最大动作价值”是把s'输入target net,target net输出s'所有动作的价值值,然后选取最大值的动作乘以折扣系数γ即可。
第三步:根据main net网络的参数,计算nimi-batch中所有样本的yT-qhat(s,a,w)平方和-->然后反向传播求main net的参数w的梯度-->根据梯度更新main net网络参数。
(3)如此训练C次,就把main net的参数赋值给target net。然后重复(2)循环。
说明:为什么DQN没有进行policy update?
因为这里的DQN是off policy的。如果是on policy,那就是我们前面讲的Q-learning with function approximation,当时也附上了伪代码了。它是一个边打边提升策略的过程。就是打一条经验数据->用这条经验数据更新最优策略->然后用更新的策略继续打游戏,再打一条经验数据->用这条经验数据更新最优策略-->然后再用新策略打游戏....这是policy update的过程。但是这里的DQN是利用所有的经验数据,计算完所有的q(s,a)后,一次性就得到了最优的policy。
7、DQN效果DQN只要1000步的经验数据就可以得到最优策略,一是因为函数逼近本身就有比较强的泛化能力;二是DQN用到了经验回放Experience replay,使得经验可以被反复使用,所以效率比较高。下面看看我们只有100步经验数据的效果:
可见,再强大的算法也得有高质量的数据,数据不行,巧妇难为无米之炊。
===========本篇完结。