Q-learning是一种很常用很传统的强化学习方法,DQN是Q-learning和神经网络的结合,是近年来很火的强化学习方法。
Q-learning会输出一张Q值表,如果有m个状态,n个动作,这个Q值表的size就是m*n;使用时,查表就行,先确定当前状态s,在看这个状态s对应的那一行,在输出这一行Q 值最大的动作,就完成了一次决策过程。
所以,使用Q-learning,首先要设计状态空间s(会有哪些状态),动作空间a(会有哪些动作),以及reward。最最简单的例子,一维迷宫,假如一共有五个格子,最后一个格子是出口(T,target),机器(A,agent)最开始处于第一个格子,机器可以选择的动作是向左走一格或者向右走一格,初始状态如下:
A _ _ _ T A ~\_~ \_~ \_~ T A _ _ _ T
不难想到,我们的状态空间可以设置成5个状态(对应A处于五个格子的状态),动作空间可以设置成两个动作(对应A向左向右的动作),reward可以设置如下,其中 s ′ s' s′表示在当前状态s采取动作a后,会跳转到的下一个状态。
r e w a r d ( s , a ) = { 1 s ′ = T 0 e l s e reward(s,a)=\begin{cases} 1 & s'= T \\ 0 & else \end{cases} reward(s,a)={10s′=Telse
如果机器在初始状态选择向右走这一动作,下一个状态就变成下面,这个转换带来的reward就是0。
_ A _ _ T \_ ~A~ \_~ \_~ T _ A _ _ T
Q值的更新利用贝尔曼方程
Q t a r g e t = R + γ max a ′ Q ( s ′ , a ′ ) (1) Q_{target} = R + \gamma \max_{a'} Q(s', a') \tag{1} Qtarget=R+γa′maxQ(s′,a′)(1)
Q ( s , a ) = Q ( s , a ) + α ( Q t a r g e t − Q ( s , a ) ) (2) Q(s,a) = Q(s,a)+\alpha(Q_{target}-Q(s,a)) \tag{2} Q(s,a)=Q(s,a)+α(Qtarget−Q(s,a))(2)
其中, s ′ s' s′表示在状态 s s s选择了动作 a a a后跳转到的下一个状态, max a ′ Q ( s ′ , a ′ ) \max_{a'} Q(s', a') maxa′Q(s′,a′)表示选取下一个状态 s ′ s' s′中的最大Q值(对应Q值表中 s ′ s' s′这一行的最大值)。 α \alpha α是学习率, γ \gamma γ是未来reward换算到当前时刻状态的衰减,表示未来Q值对当前状态的带有衰减的影响,如果我们一直套用迭代公式(1),
Q t a r g e t = R + γ max a ′ Q ( s ′ , a ′ ) = R + γ ( R ′ + γ max a ′ ′ Q ( s ′ ′ , a ′ ′ ) ) = R + γ ( R ′ + γ ( R ′ ′ + γ max a ′ ′ ′ Q ( s ′ ′ ′ , a ′ ′ ′ ) ) ) = … = R + γ R ′ + γ 2 R ′ ′ + γ 3 R ′ ′ ′ + … \begin{aligned} Q_{target} & = R + \gamma \max_{a'} Q(s', a') \\ & = R + \gamma(R'+\gamma\max_{a''} Q(s'', a'')) \\ & = R + \gamma(R'+\gamma(R''+\gamma \max_{a'''} Q(s''', a'''))) \\ & = \dots \\ & = R + \gamma R'+\gamma^2 R''+\gamma^3 R'''+\dots \\ \end{aligned} Qtarget=R+γa′maxQ(s′,a′)=R+γ(R′+γa′′maxQ(s′′,a′′))=R+γ(R′+γ(R′′+γa′′′maxQ(s′′′,a′′′)))=…=R+γR′+γ2R′′+γ3R′′′+…
可以看到,当前时刻Q的目标值其实是未来reward 按照 γ \gamma γ衰减的和。如果 γ = 0 \gamma=0 γ=0,则说明当前状态的Q值更新,只和跳转的下一状态有关;如果 γ = 1 \gamma=1 γ=1,则说明未来决策的所有reward对当前状态的Q值更新有影响,且影响程度一样。
transition:一次transition就是执行一次下列过程,对当前状态 s s s,选取动作 a a a后,进入下一时刻状态 s ′ s' s′,拿到奖励 r r r;可以表示为 ( s , a , r , s ′ ) (s,a,r,s') (s,a,r,s′)。
episode:一次episode就是一套完整的决策过程,按照上面的一维迷宫的例子,就是从初始状态,到找到出口target,之间包含的所有transition。有点类似监督学习中的epoch。
Q值表会有一个初始值,为了让Q值表在学习之初,能够尽可能的探索更多的状态,可以设置一个 ϵ \epsilon ϵ概率,即对于每一次transition,有 1 − ϵ 1-\epsilon 1−ϵ概率,会随机选择动作 a a a,而不是选取状态 s s s对应的Q值最大的 a a a,这样就能进入不同的下一时刻状态 s ′ s' s′,探索更多的可能。
随着episode的增加, ϵ \epsilon ϵ可以逐渐增大,这样在学习晚期能够更深入的挖掘已经学习到的好的决策过程,减少对未知的探索,所以这是一个explore vs exploit的过程。
超参数:learning_rate( α \alpha α), reward_decay( γ \gamma γ), e_greedy( ϵ \epsilon ϵ)
Q-learning如果状态很多,动作很多时,需要建立的Q值表也会十分的庞大,因此我们可以利用神经网络来计算Q值,利用神经网络的输出来代替查找Q值表得到的Q值。
有两种可选方案,我们把神经网络抽象成 f ( ⋅ ) f(·) f(⋅),方案一: Q = f ( s , a ) Q=f(s,a) Q=f(s,a),即利用神经网络学习状态s和采用状态a对应的Q值,相当于学习Q值表的一个表格;方案二: Q = f ( s ) Q=f(s) Q=f(s),即利用神经网络,一次性学习状态s采取各个动作的Q值,神经网络输出 Q Q Q是一个向量,长度是动作总数,相当于学习Q值表的一行。
DQN还使用了两个有效的策略,即Experience replay和Fixed Q-target,来打乱经历之间的相关性,有助于收敛。
记忆库会存储过去出现的transition。如果我们设置记忆库的大小N=500,则超过N之后,存入的transition会覆盖掉记忆库中最早存入的transition。
这样,神经网络就可以利用批学习,例如设置batch=32,从记忆库中打乱顺序随机取出batch个transition,进入神经网络利用反向传播学习参数。为何要随机取transition,这是为了打乱transition之间的相关性。
我们知道,在监督学习中,神经网络的更新需要计算loss的梯度反向传播,在DQN中也是如此,那么DQN的label是什么呢?这就需要另一个策略————Fixed Q-target。
在这个策略下,需要维持两个一模一样结构的神经网络,两个网络分别叫做eval_net和target_net。看名字就知道,eval_net是用来计算估计值的,target_net是用来计算目标值的。对于一个transition(s, a, r, s’),s会输入eval_net来计算估计Q值q_eval,s‘会输入target_net来计算目标Q值q_target,q_target再经过贝尔曼方程得到真正的目标label y
y = r + γ × q _ t a r g e t y = r + \gamma \times q\_target y=r+γ×q_target
在训练神经网络参数时用损失函数(Loss function)计算q_eval和y的损失,在梯度反向传递即可,就不再用公式(2)了。这个反向更新只更新eval_net。
所谓Fixed Q-targets,就是使得target_net的参数更新延迟发生,从而打乱相关性。经过若干步骤eval_net的更新会发生一次taregt_net的更新,由于taregt_net于eval_net的结构一模一样,所以taregt_net的更新很简单,传值就可以了。
t a r g e t _ n e t = e v a l _ n e t target\_net = eval\_net target_net=eval_net
初始化过程:初始化操作。初始化神经网络的参数,同时也会执行若干次transition来初始化记忆库。例如,记忆库的容量N=500,可以选择执行200次transition来初始化记忆库,这样学习过程可以从记忆库中抽取batch个transition,进行学习了。
存储过程:更新记忆库。每发生一次transition,都会存入记忆库,超出记忆库容量N,会先删去记忆库中最早存入的transition。在存储过程中,只执行eval_net来获取Q值,进而根据实际情况,得到动作,奖励,和下一状态。
学习过程:更新eval_net参数。可以选择发生若干步存储过程,执行一次学习过程。
更新过程:更新target_net参数。一般发生若干步学习过程,执行一次更新过程。
参考文献:
Q-learning(莫凡):https://morvanzhou.github.io/tutorials/machine-learning/reinforcement-learning/2-1-A-q-learning/
Q-learning参考代码(莫凡):https://github.com/MorvanZhou/Reinforcement-learning-with-tensorflow/blob/master/contents/2_Q_Learning_maze/RL_brain.py
DQN(莫凡):https://morvanzhou.github.io/tutorials/machine-learning/reinforcement-learning/4-2-DQN2/
DQN参考代码(莫凡):https://github.com/MorvanZhou/Reinforcement-learning-with-tensorflow/tree/master/contents/5_Deep_Q_Network
强化学习——值函数与Bellman方程:https://blog.csdn.net/VictoriaW/article/details/78839929?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase
AI学习笔记——深度Q-Learning(Deep Q-Learing(DQN)):https://www.jianshu.com/p/72cab5460ebe