[note] 强化学习RL初窥
pre
title: Continuous control with deep reinforcement learning
accepted: ICLR 2016
paper: https://arxiv.org/abs/1509.02971v6
code: none
ref: https://zhuanlan.zhihu.com/p/439629465
ref: https://zhuanlan.zhihu.com/c_1215667894253830144 (推荐)
ref: https://zhuanlan.zhihu.com/p/47925861
起因是阅读《FontRL: Chinese Font Synthesis via Deep Reinforcement Learning》的时候查阅了不少强化学习的东西,特别是其中用到的DDPG(就是这篇Continuous control with deep reinforcement learning提出的),索性整成一份方便日后回看
马尔科夫链
马尔科夫决策过程:一个由每时刻的状态、动作以及奖励组成的序列来表示,这一序列的核心特点是符合马尔科夫特性
马尔科夫特性:环境下一时刻的状态与奖励均只取决于当前时刻的状态与智能体的动作,也就是说,环境的状态转移概率是不变的。
关于马尔科夫决策过程:(S, A, R, P),分别代表环境状态、动作、奖励跟状态转移概率

马尔科夫链

马尔科夫链-充满不确定的未来
马可洛夫链描述的是智能体和环境进行互动的过程。简单说:智能体在一个状态(用S代表)下,选择了某个动作(用S代表),进入了另外一个状态,并获得奖励(用R代表)的过程。
不确定性包括两方面:
- 策略:智能体的每次选择都不是固定的,而是按照一定的策略分布。这个概率分布称为策略。
- 状态转移概率:这个只跟环境有关关系。例如飞行棋的掷骰子游戏,执行同样的动作,也有可能进入不同的状态。

马尔科夫决策过程
R是短期利益,当前时刻能够获得较多奖励的动作从长远来看也许并不是最佳的
G是收益,定义为未来时刻里所能获得的折扣奖励之和
\(\gamma \in [0,\; 1]\)是折扣因子,且时间越往后,衰减越大,因为时间上越远,存在的不确定越多,对当前时刻的贡献也就越小
Q是价值,针对每个状态-动作对,表示在给定状态-动作对的条件下未来依据某策略所能获得的平均收益
最终目标是学习到一个最优策略,使任意状态都能取到最优价值,定义
对应的动作价值函数是最有价值函数,也就是最优Q值。那么每一状态下对应Q值最大的就是最佳动作。
这里的方法就是基于价值估计的算法,此外还有基于策略优化的强化学习算法
V值和Q值
https://zhuanlan.zhihu.com/p/109498587
- 评估动作的价值,称为Q值:它代表了智能体选择这个动作后,一直到最终状态奖励总和的期望;
- 评估状态的价值,称为V值:它代表了智能体在这个状态下,一直到最终状态的奖励总和的期望。
价值越高,表示我从当前状态到最终状态能获得的平均奖励将会越高。因为智能体的目标数是获取尽可能多的奖励,所以智能体在当前状态,只需要选择价值高的动作就可以了。
假设现在需要求某状态S的V值,那么可以:
- 我们从S点出发,产生多个分身;
- 每个分身按照当前的策略选择行为;
- 每个分身一直走到最终状态,并计算一路上获得的所有奖励总和;
- 我们计算每个分身获得的平均值,这个平均值就是V值。
注意
- V值是会根据不同的策略有所变化的
- Q值和策略并没有直接相关,它与环境的状态转移概率相关,而环境的状态转移概率是不变的。
总结以上的定义,Q值和V值的意义是相通的:
- 都是马可洛夫树上的节点;
- 价值评价的方式是一样的: - 从当前节点出发 - 一直走到最终节点 - 所有的奖励的期望值
- 二者可以换算,但由于折扣率的存在换算未必等值
其他术语
https://zhuanlan.zhihu.com/p/115629505
https://blog.csdn.net/ppp8300885/article/details/78524235
- on-policy: 若交互/采样策略和评估及改善的策略是同一个策略,可翻译为同策略。
- off-policy: 若交互/采样策略和评估及改善的策略是不同的策略,可翻译为异策略。与On-policy的区别在于:更新价值所使用的方法是沿着既定的策略(on-policy)抑或是新策略(off-policy)
- Model-based: 对环境建模,利用这个模型,agent能知道任何状态下执行任何动作获得的回报,可以通过动态规划或贪心算法选取当前应采取的动作
- Model-free: 不用对环境建模,如Q-learning直接对Q值进行估计,估计的越准确就越能确定如何选择动作:选择让Q(s,a)最大的a即可。二者显著差别在于:agent执行动作前,是否能对下一步的状态和回报做出预测,可以就是model-based方法,不能即为model-free方法
- rollout: 经常会出现在 model-based 算法中,在 current state 上,从每一个可能的action出发,根据给定的 policy 进行路径采样,最后根据多次采样的奖励和来对 current state 的每一个action的Q值进行估计,然后做出选择让这一步进入下一个状态
蒙特卡洛(MC)
蒙特卡洛让智能体从某个状态S出发,直到最终状态,然后回过头来给每个节点标记价值G。G代表了某次,智能体在这个节点的价值。

蒙特卡洛流程
多次后,把每个状态的G值取平均,作为该状态的V值。
但为了方便,我们对平均进行一些优化,于是会有状态\(S_t\)下V根据G增量更新公式
时序差分(TD)
由于蒙特卡洛的一些问题:
- 蒙地卡罗算法相对动态规划,不那么准确,因为每一次的路径都不一样。
- 如果环境的状态空间非常大,或者最终状态只有非常小的概率达到,那么蒙地卡罗算法很难处理。
时序差分不需要走到终点再回溯计算V值,它假定从A往前走N步到达的地方B就是终点,于是便开始更新。由于B点的V值表示B状态到最终状态的总价值期望,假设B点处的V值正确,就可以倒推A点处的V值
注意时序差分这里用下一状态的V值加上转移的R作为更新目标,\(R_{t+1} +\gamma V(S_{t+1})\)替换了蒙特卡洛里的\(G_t\)
注:显然第一次的时候B点处也没有V值,还是需要走完全程,慢慢从后往前更新出各点的V值
Qlearning
TD可以估计V值,但直接估计Q值就更好了,因为Q评估动作的价值,根据Q就能选取合适的动作
将TD公式里V(St+1)用一个动作的Q值所代替,就能统一公式只有Q,更方便
Qlearning的想法其实也很直观:既然目标是选取最大收益,那就用所有动作的Q值的最大值替代V(St+1)。
DQN
DQN = Deep network + Qlearning
Qleanrning有一个问题:只能解决离散型状态问题,对连续型状态束手无策。

Q table

DQN状态更新
Qlearning中Qtable的作用是当我们输入状态S,我们通过查表返回能够获得最大Q值的动作A。也就是我们需要找一个S-A的对应关系。
借助神经网络就可以用函数拟合,通过\(Q = F(S)\)选择状态S下的动作A,这样就能处理连续型状态
损失:Q(S,A)(当前Q值)相当于有监督学习中的logits,maxQ(St+1) + R (下一时刻最大Q值代替下一时刻最大V值,加上奖励R即为当前时刻更准确的Q值)相当于有监督学习中的lables,希望logits向labels靠近,可以用mse函数,得出两者的loss
double DQN
由于DQN对Q的估值通常会过大,因为估算用的是下一状态中Q值最大的作为当前状态的估算,下一状态的Q值又以下下状态的最大Q值作为估算...这个Q值越传播就越大。
于是DQN有一个变种:double DQN,核心思想就是用两个网络同时估算Q值,然后取二者间小的值作为最终估算。
经验回放(Experience replay)
把每一步的s,选择的a,进入新的状态s',获得的奖励r,新状态是否为终止状态等数据全部存在一个叫回放缓存的地方(replay buffer)。当数据量足够,便从中抽出一个batch大小的数据放入网络进行训练。训练更加高效,也能减少过拟合
策略梯度(PG)
如果说DQN是一个TD+神经网络的算法,那么PG是一个蒙地卡罗+神经网络的算法
实际上之前算Q跟V都是为了能得到一个好策略,选出合适的动作取得最高分数,那么用P表示策略,直接用神经网络\(F(S) = P\),P可看作概率,比如三个动作,P=[0.5, 0.1, 0.4]表示三者分别被选取的概率。
如果智能体的动作是对的,那么就让这个动作获得更多被选择的几率;相反,如果这个动作是错的,那么这个动作被选择的几率将会减少。
PG中对错的衡量使用蒙特卡洛的G值,从某个state出发,然后一直走直到最终状态,再原路返回,对每个状态评估G值,用G值表示在策略P下,智能体选择的这条路径的好坏
(就是蒙特卡洛MC的公式)
更新流程:
- 开始一场游戏,并重制state
- 根据state,选择action
- 把action代入环境,获得observation_, reward, done, info
- 记录数据
- 计算G值,并开始学习策略。
PG实际效果不太稳定,在某些环境下学习较为困难。而且由于采用MC的方式,需要到最终状态才能进行更新,而且只能进行一次更新,因此效率不高
Actor-Critic(AC)
为了解决PG的问题,尝试将PG里面用的MC改为TD,这样就从估计G值改为估计Q值
Actor-Critic用了两个网络:
- actor: 输入状态S,输出策略,负责选择动作
- critic: 计算actor动作的分数
Actor在台上表演,一开始动作并不好看,Critic根据Actor的动作打分。Actor通过Critic给出的分数,去学习:如果Critic给的分数高,那么Actor会调整这个动作的输出概率;相反,如果Critic给的分数低,那么就减少这个动作输出的概率。

TD-error
为了避免正数陷阱,不能直接用Q值\(Q(s,a)\)更新actor,而应该使用\(Q(s,a)-V(s)\),因为Q值的期望(均值)是V,通过减去V使得权重有正有负,这样更新actor策略时更合理,负的就降低对应动作的概率,正的就提高。
为了避免同时估计Q、V,通过用\(\gamma * V(s') + r\)替换\(Q(s,a)\),得到\(TD-error = \gamma * V(s') + r - V(s)\),这跟DQN更新公式很像,只是这里用的是V。
之后就用TD-error作为actor的权重去更新策略,又因为TD-error是有可能更正确的V值(\(\\gamma * V(s') + r\)跟当前V值的差值,而critic的目的正好就是估计V值,因此TD-error可以作为critic的loss。
ps:感觉这部分看起来有点像GAN...
DDPG
全称是deep deterministic policy gradient,深度确定性策略梯度算法
提出背景
DQN很厉害,在一些Atari游戏中表现很好,也在nature上发了文章,但Q网络的输出是离散的,它根据Q值大小选取动作,比如经典的打砖块游戏可能只有两个动作:向左或向右,但很多其他任务的动作是连续的,自动驾驶油门可能就是一个0-100的连续值
- 把连续的空间切割成离散的。但随着空间的维度增长,状态的数量会指数级增长,没办法scale up
- 把神经网络的输出改为一个连续的值。看似合理,但是之前DQN的那一套就没办法用了。这是DDPG采用的方案,并且提供了一套可以训练网络的方法,这是基于actor-critic架构的。
和PPO不一样,PPO输出的是一个策略,也就是一个概率分布,而DDPG输出的直接是一个动作
DDPG更接近DQN,是用一个actor去弥补DQN不能处理连续控制性问题的缺点,即DQN的动作是离散的。
DDPG通过使用一个神经网络(actor)替代DQN公式中的\(\max Q(s', a)\),即\(a = F(S)\),根据状态S直接得到动作a,且能使得Q值最大
Critic
- Critic网络的作用是预估Q,和AC(Actor-Critic)算法中的Critic不一样,这里预估的是Q不是V;
- Critic的输入有两个:动作和状态;
- Critic网络的loss其还是和AC一样,用TD-error
- 负责的是给特定状态下的动作打分,告诉Actor采取的动作好不好
Actor
- 和AC不同,Actor输出的是一个动作;
- Actor的功能是,输出一个动作a,使这个动作a输入到Crititc后,能够获得最大的Q值。
- Actor的更新方式和AC不同,不是用带权重梯度更新,而是用梯度上升。
ps:这里的梯度上升指的仍是梯度下降,但loss取负号,目标是取得最大值,区别于梯度提升(Gradient Boosting)

DDPG 网络架构
和DQN一样,更新的时候如果更新目标在不断变动,会造成更新困难。因此也用了固定网络(fix network)技术,就是先冻结住target网络。在更新之后,再用原参数更新target网络,因此上图一共有4个网络。
差别在于DQN直接将Q网络的参数定期复制给target,DDPG采取 soft update,\(\theta \leftarrow \tau\theta + (1 - \tau)\theta\)使参数缓慢更新,提升学习稳定性。
DDPG也借鉴了DQN的经验回放 (Experience Replay)技巧。DDPG同样会把一段时间的序列\((s,a,r,s')\)存储到经验池。每次训练的时候,从经验池随机采样一个minibatch来训练。
因为策略是确定的,如果 actor 在一开始的时候,很可能不会尝试足够多的 action 来找到有用的学习信号。
不同于DQN中使用的\(\epsilon\)-greedy的方式平衡exploration和exploitation,DDPG使用的方法是,在选择一个新的动作的时候,给policy函数返回的动作值增加一个噪音:\(\mu'(s_t)=\mu(s_t|\theta_t^{\mu})+\Nu\) ,这里的\(\Nu\)就是一个简单的概率分布,比如高斯分布,而且它的选择是根据不同的环境而设计的。随着训练的进行,可以不断减小噪声,测试时去除噪音

DDPG 算法伪代码
- 首先,初始化Actor和Critic以及其各自的目标网络共4个网络以及经验池replay buffer R。
- 在Actor网络输出动作时,DDPG通过添加随机噪声的方式实现exploration,可以让智能体更好的探索潜在的最优策略。
- 之后是采取经验回放的技巧,把智能体与环境交互的数据\((s_t,a_t,r_t,s_{t+1})\)存储到R。随后每次训练从R中随机采样一个minibatch。
- 在参数更新上,先利用critic的目标网络\(Q'\)来计算\(y_i\),利用\(y_i\)与当前网络Q值的均方误差构造损失函数,更新critic。
- 对于actor,把动作a代进critic Q网络,然后对\(\theta^\mu\)求梯度
- 最终用soft update更新目标网络
本文作者:NoNoe
本文链接:https://www.cnblogs.com/Stareven233/p/16883875.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步