强化学习备忘录

强化学习备忘录

强化学习一直想学没学起来

之前2019年看了点Q_learning,DQN,但是也没看太明白

2020年,因为任务型对话的POL组件需要RL,下定决心把RL搞懂。

简史:
动态规划DP–>Q-learning—>用Q-Network代替Q-Learning的Q表–>DQN–>用RNN来代替DQN中的全连接层–>DRQN等等

Code:

https://github.com/higgsfield/RL-Adventure

一、动态规划

参考:https://www.zhihu.com/question/39948290/answer/883302989
动态规划与其说是一个算法,不如说是一种方法论。该方法论主要致力于将合适的问题拆分成三个子目标一一击破:
建立状态转移方程
缓存并复用以往结果
按顺序从小往大算(迭代)
完成该三个目标,你将所向披靡。
问题就是难在找到 dp[n]代表什么。

把动态规划和中学学的数列递推公式结合,然后去力扣刷几道题,就懂了。

二、强化学习

参考:https://zhuanlan.zhihu.com/p/21340755?refer=intelligentunit

1.扫盲

构建任务 = Action + Observation + Reward。
即Agent执行action以与environment进行交互,导致environment变化,变化的好与坏用Reward来表示。Agent可以获取的关于environment的信息称为Observation或者state。
【Observation与state是同一个东西在不同视角的描述】
每一个step,Agent向environment输出action,然后environment更新state,并将Observation 与 reward向Agent输出。然后再下一个step,如此循环,知道任务完成。任务的完成度用累积获取的Reward来量化。Reward越多,就表示执行得越好。
state与action的关系就是输入与输出的关系。给定state确定action的过程就叫做策略Policy。
现在把上面提到的量用符号总结一下:
action记为a
state记为s
Policy记为 π \pi π

一一对应的表示: a = π ( s ) a=\pi(s) a=π(s)

概率的表示: π ( a ∣ s ) \pi(a|s) π(as)

强化学习的任务就是找到一个最优的策略Policy从而使Reward最多。

强化学习的特点与难点

事实上,寻找的过程往往从随机的策略开始来实验,也就是 一系列的state,action,reward。

{ s 1 , a 1 , r 1 ; s 2 , a 2 , r 2 ; . . . ; s t , a t , r t } \{s_1,a_1,r_1;s_2,a_2,r_2;...;s_t,a_t,r_t\} {s1,a1,r1;s2,a2,r2;...;st,at,rt}

这就是一系列的样本Sample。 增强学习的算法就是需要根据这些样本来改进Policy,从而使得得到的样本中的Reward更好。

【按:强化学习名称由来, Reinforcement ,就是增加Reward的意思。】

【按:上文的描述:寻找最优Policy,很容易让我们想到优化与规划问题。其实,直接对Policy进行优化就是所谓的Policy-Based RL。此外,还有Value-Based RL,即通过对各state的reward的估计(期望)作优化,间接地得到最优的policy。】

MDP

从一个RL sample的样子,看出强化学习在时间上是离散的,即一个一个的时间节点构成的有序序列。而且输入(state)可以确定唯一的输出(action),输出可由输入唯一地确定。

所以,强化学习的state是MDP过程(马尔科夫决策过程):

P ( s t + 1 ∣ s t ) = P ( s t + 1 ∣ s t , s t − 1 , . . . , s 1 , s 0 ) P(s_{t+1}|s_t)=P(s_{t+1}|s_t,s_t-1,...,s_1,s_0) P(st+1st)=P(st+1st,st1,...,s1,s0)

即下一个状态仅取决于当前状态(与当前动作),与更远的状态无关。这里由 s t s_t st a t a_t at转移到 s t + 1 s_{t+1} st+1的概率记为状态转移概率P。

某过程的state,action,P三者均知道 = 得到了该过程的模型Model。

有了model,就可以进而推导未来的最优动作、诸状态。显式地确定出模型,这叫做Model-based方法。

很多问题是很难得到准确的模型的,因此就有Model-free方法来寻找最优的动作。

【按:我的理解,把RL建模为MDP最大的益处,就是证明了计算某个state的回报的期望这件事是有意义的,从而引出value function的概念。】

回报Return

state的好与坏用reward量化.

某个时刻t所具备的累积回报return:

G t = R t + 1 + λ R t + 2 + . . . = ∑ k = 0 λ k R t + k + 1 G_t = R_{t+1}+\lambda R_{t+2}+...=\sum_{k=0}\lambda^kR_{t+k+1} Gt=Rt+1+λRt+2+...=k=0λkRt+k+1

思想是,因为当前时刻做的某一个决定,未来不同时刻都会造成不同形式的奖励。

折扣因子: 一般当下的反馈是比较重要的,时间越久,影响越小。

那么实际上除非整个过程结束,否则显然我们无法获取所有的reward来计算出每个状态的Return,因此,再引入一个概念价值函数Value Function,用value function v ( s ) v(s) v(s)来表示一个状态未来的潜在价值。

value function = return的期望:

v ( s ) = E [ G t ∣ S t = s ] v(s)=E[G_t|S_t=s] v(s)=E[GtSt=s]

引出价值函数,对于获取最优的策略Policy这个目标,我们就会有两种方法:

  • Policy-Based RL:直接对Policy π ( a ∣ s ) \pi(a|s) π(as)或者 a = π ( s ) a=\pi(s) a=π(s)做优化,使得回报更高
  • Value-Based RL:通过估计value function来间接获得优化的策略。即通过对各state的return的估计(期望)作优化,间接地得到最优的policy。道理很简单,既然我知道每一种状态的优劣,那么我就知道我应该怎么选择了,而这种选择正是我们想要的策略。

DQN 就是基于value的算法。

【按:我的理解,Policy与Reward是手段与目的的关系。二者是同一件事的两种体现,即从手段角度看就是确定最优Policy,从结果角度看就是确定最优value】

【按:还有 model-based方法 ,即 估计模型,也就是计算出状态转移函数,从而整个MDP过程得解 】

Value Function的哲学理解

问题:为什么有了Policy,还要提出value function呢?

答:Policy-Based RL的方法,其实相当于确定一个黑盒子Policy,黑盒子输入state,输出action。显然,这种方法最大的缺陷是无法评估每一种action的未来潜在价值。相反,如果使用Value-Based RL的方法,即目的是确定一个黑盒子Value-Function,黑盒子输入state,评估该state的value function,然后输出使得value最高的action。

事实上,Value-Based RL也是有policy的,这个policy就是:

if 某一个动作的价值最大:
    选择这个动作

这就是价值函数的意义。

【按:其实,打个不恰当的比方,policy-based RL与value-based RL的关系,可以类比监督学习与生成对抗网络的关系。前者的loss function需要研究者自己针对具体任务来显式设计的,而后者却能让机器自己自动地定义出潜在的loss隐式表达式以及数据集的分布函数。难怪有人说,GAN与强化学习是人工智能上的两颗钻石。】

实际上强化学习的算法都是基于人类的行为而构建的。比如上面的Value Function价值函数,实际上人类自己做决策的时候也就是那么做的。这里只不过是把它数学化了而已。

Bellman方程

G t G_{t} Gt公式改写成递归形式:

G t = R t + 1 + λ R t + 2 + λ 2 R t + 3 + . . . = R t + 1 + λ ( R t + 2 + λ R t + 3 + . . . ) = R t + 1 + λ G t + 1 G_t = R_{t+1}+\lambda R_{t+2}+\lambda^2 R_{t+3}+...=R_{t+1}+\lambda (R_{t+2}+\lambda R_{t+3}+...)=R_{t+1}+\lambda G_{t+1} Gt=Rt+1+λRt+2+λ2Rt+3+...=Rt+1+λ(Rt+2+λRt+3+...)=Rt+1+λGt+1

再将其与 v ( s ) v(s) v(s)融合一下:

v ( s ) = E [ G t ∣ S t = s ] = E [ R t + 1 + λ G t + 1 ∣ S t = s ] = E [ R t + 1 + λ v ( S t + 1 ) ∣ S t = s ] v(s)=E[G_t|S_t=s]=E[R_{t+1}+\lambda G_{t+1}|S_t=s]=E[R_{t+1}+\lambda v(S_{t+1})|S_t=s] v(s)=E[GtSt=s]=E[Rt+1+λGt+1St=s]=E[Rt+1+λv(St+1)St=s]

【按:最后一步的理解——收获的期望等于收获的期望的期望 。】

对该公式的理解:当前state的value下一步的value以及当前的反馈Reward有关。 由该公式可看出, v ( s ) v(s) v(s)被拆成两个独立的部分,一是该状态的即时奖励期望(就是即时奖励,与下一个时刻无关),二是下一时刻状态的价值期望。

该公式还透露了一个信息:它表明Value Function是可以通过迭代来进行计算的。

【按:所以,bellman方程也被称作动态规划方程(Dynamic Programming Equation) 】

Action-value function

前文定义了value function,即某个state下的(未来潜在)value。

接下来定义Action-Value function,即在某个state下的不同action的value。

value functionAction-Value function
表示 v ( s ) v(s) v(s) Q π ( s , a ) Q^{\pi}(s,a) Qπ(s,a)
Reward多种action对应的reward的期望值执行完action a之后得到的reward
名称价值函数动作价值函数

定义Action-Value function好处多多: 显然,执行action之后的reward更直观、容易理解、建模。 加了 π \pi π,意思是在policy下的动作价值,因为由当前state生成action的value,必须要policy的支撑。而value function则不一定依赖于policy。当然,也可以定义 v π ( s ) v^{\pi}(s) vπ(s)来表示在policy π \pi π下的价值函数。

回忆上文已有结论: 求解最优policy等价于求解最优的value function。

又, 最优的action-value函数就是所有policy下的action-value函数的最大值。

action-value函数:

Q π ( s , a ) = E [ r t + 1 + λ r t + 2 + λ 2 r t + 3 + . . . ∣ s , a ] = E s ′ [ r + λ Q π ( s ′ , a ′ ) ∣ s , a ] Q^{\pi}(s,a)=E[r_{t+1}+\lambda r_{t+2}+\lambda^2 r_{t+3}+...|s,a]=E_{s'}[r+\lambda Q^{\pi}(s',a')|s,a] Qπ(s,a)=E[rt+1+λrt+2+λ2rt+3+...s,a]=Es[r+λQπ(s,a)s,a]

Q ∗ ( s , a ) = E s ′ [ r + λ m a x a ′ Q π ( s ′ , a ′ ) ∣ s , a ] Q^{*}(s,a)=E_{s'}[r+\lambda \bold{max}_{a'} Q^{\pi}(s',a')|s,a] Q(s,a)=Es[r+λmaxaQπ(s,a)s,a]

两种优化pocicy

下面介绍基于Bellman方程的两个最基本的算法,策略迭代和值迭代。

策略迭代Policy Iteration

指的是迭代计算value function价值函数,以找到最优的policy。

迭代过程:根据样本更新value function(policy),然后针对policy使用greedy算法选出最好action,产生新的样本,再用新样本更新policy(value function),往复循环。 最终policy将收敛到最优。

回忆上文的bellman公式:

v ( s ) = E [ R t + 1 + λ v ( S t + 1 ) ∣ S t = s ] v(s)=E[R_{t+1}+\lambda v(S_{t+1})|S_t=s] v(s)=E[Rt+1+λv(St+1)St=s]

我们的目的是迭代更新value function,将一次迭代记为:

v k + 1 ( s ) ≈ E π [ R t + 1 + λ v k ( S t + 1 ) ∣ S t = s ] v_{k+1}(s) \approx E_{\pi}[R_{t+1}+\lambda v_{k}(S_{t+1})|S_t=s] vk+1(s)Eπ[Rt+1+λvk(St+1)St=s]

再改写为概率形式:

v k + 1 ( s ) ≈ ∑ a π ( a ∣ s ) ∑ s ′ , r p ( s ′ , r ∣ s , a ) [ r + γ v k ( s ′ ) ] v_{k+1}(s) \approx \sum_a \pi(a|s)\sum_{s',r} p(s',r|s,a)[r + \gamma v_k(s')] vk+1(s)aπ(as)s,rp(s,rs,a)[r+γvk(s)]

p表示状态转移概率,所谓状态转移指的是对特定state施加特定action造成影响(新state)与回报(reward),而其发生的可能性就是p。

策略优化 = 策略估计 + 策略优化

img

上图的解释:

(1)初始化:

对state空间里每个state,初始化其value function与policy。

(2)策略估计

这里估计一次比较吓唬人,其实说白了,就是已知policy了,(对每种state)把value算出来。

【按:每种state的value,合起来就是所谓的value function。】

【按:虽说policy与value function是一一对应的,但是并无法得到确定解,也就是我们只能通过限定迭代次数或者阈值的办法来让v无限接近真实的value function v π v_{\pi} vπ

(3)策略优化

计算policy的value function的目的是寻找更好的policy,即策略优化。 在每个state s时,对每个可能的action a,都计算一下采取这个action后到达的下一个state的期望value。看看哪个action可以到达的state的期望value函数最大,就选取这个action,从而更新了policy。

如果更新后的policy与更新前一样,说明已经收敛到了最好policy,迭代结果。否则,就继续循环进行估计、优化。。

总结:策略迭代的特点是(1) 状态转移概率p 必须是已知的,即,对特定state施加特定action造成的影响(新state)与回报必须是已知的,否则优化目标无从谈起;(2)action与state都是离散取值的。上述两个条件都比较严苛,只能适用于简单情况。而真实场景是复杂的,P往往未知,且action与state是连续取值(即使的离散取值,空间也会很大,计算复杂度指数提升。)

Value Iteration

我们的目的是迭代更新value function,将一次迭代记为:

v k + 1 ( s ) ≈ m a x a E π [ R t + 1 + λ v k ( S t + 1 ) ∣ S t = s , A t = a ] v_{k+1}(s) \approx \bold {max_a} E_{\pi}[R_{t+1}+\lambda v_{k}(S_{t+1})|S_t=s, A_t=a] vk+1(s)maxaEπ[Rt+1+λvk(St+1)St=s,At=a]

再改写为概率形式:

v k + 1 ( s ) ≈ m a x a ∑ s ′ , r p ( s ′ , r ∣ s , a ) [ r + γ v k ( s ′ ) ] v_{k+1}(s) \approx \bold {max_a}\sum_{s',r} p(s',r|s,a)[r + \gamma v_k(s')] vk+1(s)maxas,rp(s,rs,a)[r+γvk(s)]

img

policy iteration使用bellman方程来更新value,最后收敛的value 即 v π v_{\pi} vπ当前policy下的value值(所以叫做对policy进行评估),目的是为了后面的policy improvement得到新的policy。

这是 贝尔曼最优方程 。其实,可以把值迭代看做是简化版本的策略迭代。与策略迭代不同,在值迭代过程中,算法不会给出明确的策略,而是只得到policy。

就是第一步选个最优策略,接下来的每一步(one step look ahead)也都选最优策略,这样就能保证最终得到全局最优的策略。恩,没毛病。所以在思路上可以从目标点一步一步地往前推,最终可以推出最优的一个价值函数,也对应着相应的最优策略。有点类似策略迭代里边每进行一次价值评估就基于它选出该步骤的最优策略一样。要注意的是在推的过程中产生的价值函数table可能不对应着任何实质性的策略,只是一个理论上的过渡状态。

【按:我怎么觉得俩迭代算法没区别呢?不就是两步并一步吗?】

Q-Learning

基于Value Iteration就可以构建Q learning算法。

Q = Action-Value function,即在某个state下的不同action的value。

在state与action的组合有限的情况下,可以把Q看做一张表格,

m行n列,表示m个状态,每个状态n种动作。表格内容就是value值。通过不断迭代更新得到一张完美的Q表格。

但是Q-Learning并不完全使用Value Iteration,而是:

(1)使用了一种 ϵ − g r e e d y \epsilon -greedy ϵgreedy策略,例如,90%几率取使得value最大的action作为动作,10%几率随机取一个动作。

(2)没有直接将Q值(估计的值)直接赋予新的Q,而是采用渐进的方式类似随机梯度下降,朝target迈近一小步(取决于α),这就能够减少估计误差造成的影响。最后可以收敛到最优的Q值。

Q ( S , A ) ← ( 1 − α ) Q ( S , A ) + α [ R ( S , a ) + γ m a x a Q ( S ′ , a ) ] Q(S,A) \leftarrow (1-\alpha)Q(S,A) + \alpha[R(S,a)+\gamma \bold{max}_aQ(S^{'},a)] Q(S,A)(1α)Q(S,A)+α[R(S,a)+γmaxaQ(S,a)]
当前state: S S S

选择的action: A A A(根据当前Q表,取S下使得value最大的action作为A)

下一个state: S ′ S' S(S + A的影响),新state

回报reward: R R R(S + A的回报)

m a x a Q ( S ′ , a ) max_aQ(S',a) maxaQ(S,a):根据当前Q表,取 S ′ S' S下使得value最大的action施加后的最大value

它即是预估下一步 S ′ S' S能取得的最大value,乘以一个因子,再加上 R R R这个当前反馈,合起来就是当前的Return。

该Return作为一个gradient step累加到 Q ( S , A ) Q(S,A) Q(S,A)上,step是 α \alpha α。然后准备做下一次实验。

用python写一个伪代码即:

while(1):
    A = epsilon_greedy(S)
    S_, R = P_state_transfer_prob(S, A) # S'记作S_是新state
    value = max_a{Q(S_,a)} # 当前Q表下,对state S_,取其能取到的最大value
    Return = R + Lambda * value
    Q(S,A) += Alpha * ( Return - Q(S,A)) # Return即q_target, Q(S,A)即q_predict. q_target是真正的Q值,而q_predict是想象的、估计的q值
    S = S_

最后总结一下:value-iteration最核心的特色就是“多看一步”(one step look ahead), 每一个时间片的Q(s,a)和当前得到的Reward以及下一个时间步的Q(s,a)有关。这里所谓的多看一步,指的是把上一次实验计算得到的Q表拿来使用,即用当前的Reward及上一次实验中下一个时间步的Q值更新当前的Q值了。

DQN

价值函数近似(Value Function Approximation)

(1)思想:连续函数拟合庞大空间的离散Q值

Q-Learning中,Q(s,a)是离散值。

价值近似 = 用一个连续函数来拟合Q值的分布,即各个离散的Q值,实现降维。

Q ( s , a ) = f ( s , a , ω ) Q(s,a)=f(s,a,\omega) Q(s,a)=f(s,a,ω)

(2)高维状态输入,低维动作输出的表示问题

其实,现实的游戏很多是高维状态输入,低维动作输出的,即,我们只需要对高维状态进行降维,而不需要对动作也进行降维处理。 于是:

Q ( s ) = f ( s , ω ) Q(s)=f(s,\omega) Q(s)=f(s,ω)

解决方法就是只把state s作为输入,但是输出的时候输出每一个动作的Q值,即本质上输出是一个向量:

[ Q ( s , a 1 ) , Q ( s , a 2 ) , . . . , Q ( s , a n ) ] = f ( s , ω ) [Q(s,a_1),Q(s,a_2),...,Q(s,a_n)]=f(s,\omega) [Q(s,a1),Q(s,a2),...,Q(s,an)]=f(s,ω)

而且好处是,这样建模更加方便value迭代更新。而且网络可以直接从输出向量里寻找Q最大的s, a组合。

【按:这里的思想非常重要,等于规范了未来一切DQN系列算法的设计模式,即,state s这个张量的维度无所谓,但最后一层基本就是act categories向量 + state s —> act Q值向量。】

Q值网络化

Q值网络化 = 用一个深度神经网络来表示这个函数 f f f。这个神经网络被叫做Q网络(Q-Network)

以DQN为例,输入是4帧连续的图像(经过处理的4个84x84矩阵),然后经过两个卷积层,两个全连接层,最后输出包含每一个动作Q值的向量。

总之,用神经网络来表示Q值非常简单,Q值也就是变成用Q网络来表示。接下来就到了很多人都会困惑的问题,那就是

怎么训练Q网络???

DQN算法

要深度学习,就得有label or target,就要有loss function。

DQN的loss如下图:label就是Q-Learning得来的R+max_a{Q(S_,a)}。

preview

【按:这里label的构建非常巧妙,和传统监督学习顺起来了,只不过它的label同样受模型影响,因为训练样本是随着梯度下降过程不断获得的。】

下一个问题是怎样训练。

由于采集到的样本是一个事件序列,样本之间需要连续性,这就影响了样本的分布。所以, 一个很直接的想法就是把样本先存起来,然后随机采样,称为 Experience Replay ,即经验池 。

【按: 按照脑科学的观点,人的大脑也具有这样的机制,就是在回忆中学习。 】

在DQN中,强化学习Q-Learning算法和深度学习的梯度下降训练是同步进行的。 通过Q-Learning获取无限量的训练样本,然后对神经网络进行训练。反复试验,然后存储数据。接下来数据存到一定程度,就每次随机采用数据,进行梯度下降。

最后总结下DQN训练过程的两大特色:

  • Experience Replay经验池:通过将训练得到的数据储存起来然后随机采样的方法降低了数据样本的相关性。提升了性能。

  • 延迟更新: 每次等训练了一段时间再将当前Q网络的参数值复制给目标Q网络。

小车立杆问题

初学DQN的人可以读一读这个问题的代码,练习用强化学习解决实际问题的思路。

参考:https://so.csdn.net/search?mode=1&q=DQN%20CartPole-v0

Code参考:https://github.com/higgsfield/RL-Adventure/blob/master/1.dqn.ipynb

state:包括4个量,小车位置,小车速度,杆角度,杆尖速度。随机初始化

action:2个,左或右。

reward:只有不导致任务失败,action的reward都是1.

DQN网络结构:输入是4维,中间是一个128*128的线性层,输出是2维。即简单ANN。

DQN的改进

DQN之上,有Double DQN,Prioritised Replay,Dueling Network三大基本改进

简单说明一下:

  • Double DQN:目的是减少因为max Q值计算带来的计算偏差,或者称为过度估计(over estimation)问题,用当前的Q网络来选择动作,用目标Q网络来计算目标Q。

  • Prioritised replay:也就是优先经验的意思。优先级采用目标Q值与当前Q值的差值来表示。优先级高,那么采样的概率就高。

  • Dueling Network:将Q网络分成两个通道,一个输出V,一个输出A,最后再合起来得到Q。如下图所示(引用自Dueling Network论文)。这个方法主要是idea很简单但是很难想到,然后效果一级棒,因此也成为了ICML的best paper。

    img

DQN拓展到连续控制

DQN依靠计算每一个动作的Q值,然后选择最大的Q值对应的动作。那么这种方法在连续控制上完全不起作用。因为,根本就没办法穷举每一个动作,也就无法计算最大的Q值对应的动作。

因为DQN是通过计算Q值的最大值来选择动作。那么对于连续控制,我们已经无法选择动作,我们只能设计一种方法,使得我们输入状态,然后能够输出动作,并且保证输出动作对应的Q值是最大值。

问题来了, 如何构建神经网络,又能输出动作,也能输出Q值,而且动作对应的Q值最大?

NAF

To be continued…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值
>