强化学习13 —— Deep Deterministic Policy Gradient(DDPG)算法原理与 tensorflow 2.0 实现

上篇文章介绍了强化学习——Actor-Critic算法详解加实战 介绍了Actor-Critic,本篇文章将介绍 DDPG 算法,DDPG 全称是 Deep Deterministic Policy Gradient(深度确定性策略梯度算法) 其中 PG 就是前面介绍的 Policy Gradient,在强化学习10——Policy Gradient 推导 已经讨论过,那什么是确定性策略梯度呢?

一、确定性策略

与确定性策略对应的是随机性策略,就是神经网络输出的是动作的分布,在确定每一步动作时,需要得到的策略分布进行采样,对于某些高纬的连续值动作,频繁的在高维空间对动作进行采样,是很耗费计算能力的。

同样,对于DQN算法,其只适用于低维、离散动作的问题,对于连续动作问题,DQN要计算所有可能动作的概率,并计算可能的动作的价值,动作的数量随着自由度的数量呈指数增长,那需要非常的样本量与计算量,所以就有了确定性策略来简化这个问题。

作为随机策略,在相同的策略,在同一个状态处,采用的动作是基于一个概率分布的,即是不确定的。而确定性策略就简单的多,即使用相同的策略,在同一状态下,动作是唯一确定的:
a t = μ ( s ∣ θ μ ) a_t = \mu(s|\theta^\mu) at=μ(sθμ)

二、DDPG

首先要注意一点,DDPG从名字上像一个策略梯度(PG)算法,但是其实它更接近DQN,或者说DDPG是使用的 Actor-Critic 架构来解决DQN不能处理连续动作控制问题的一个算法,这点一定要注意。下面来详细解释为什么这么说

1、从 Q-Learning 到 DQN

先回忆下Q-Learning的算法流程,在 强化学习4——时序差分控制算法 中已经详细介绍过Q-Learning算法:首先基于状态 S t S_t St,用 ϵ − \epsilon- ϵ贪婪法选择到动作 A t A_t At 并执行,进入状态 S t + 1 S_{t+1} St+1,并得到奖励 R t R_{t} Rt,然后利用得到的 < S , A , R , S ′ > <S,A,R,S'> <S,A,R,S> 来更新Q表格,注意在更新Q表格时,基于状态 S t + 1 S_{t+1} St+1 使用贪心策略选择 A ′ A' A
A ′ = m a x a ′ Q ( S ′ , a ′ ) A' = max_{a'} Q(S',a') A=maxaQ(S,a)
也就是选择使 Q ( S t + 1 , a ) Q(S_{t+1}, a) Q(St+1,a) 最大的 a a a 来作为 A ′ A' A 来更新价值函数。对应到上图中就是在图下方的三个黑圆圈动作中选择一个使 Q ( S ′ , a ) Q(S', a) Q(S,a) 最大的动作作为 A ′ A' A

ar0z9A.png

由于Q-Learning 使用Q表格存储每个状态的所有动作价值,所以面对连续状态既如果状态非常多的情况就不能胜任,所有就用函数逼近的方法,使用神经网络来代替 Q 表格,其余流程不变,这样就得到了DQN算法。在强化学习7——DQN算法详解 中已经详细介绍过 DQN算法,下面就简单回忆下DQN算法流程:

在这里插入图片描述

可以看出,DQN用神经网络代替Q表格,loss 函数就是神经网络当前的输出与target之间的差距,然后对损失函数求导更新网络 参数。

2、从DQN 到DDPG

而target的计算方式为 r + γ    m a x a ′ q ^ ( s ′ , a ′ , w ) r + \gamma\;max_{a'}\hat{q}(s',a',w) r+γmaxaq^(s,a,w) ,即从下一个状态使用max函数选一个最大的动作 Q,当具有有限数量的离散动作值时,计算max不是问题,因为可以对所有动作计算其Q值(这也能够得到能够最大化Q值的动作)。但是当动作空间连续时,却不能穷举所有的可能,这也是DQN不能处理连续动作控制任务的原因。

那么该如何解决这个问题呢?前面知道,DQN用神经网络解决了Q-Learning不能解决的连续状态空间问题。那可不可以也使用一个神经网络来代替 m a x a Q ( s , a ) max_aQ(s,a) maxaQ(s,a) 呢?当然是可以的,DDPG就是这样做的,即用一个函数来代替这个过程:
m a x a Q ( s , a ) ≈ Q ( s , μ ( s ∣ θ ) ) max_aQ(s,a) \approx Q(s,\mu(s|\theta)) maxaQ(s,a)Q(s,μ(sθ))
其中的 θ \theta θ 就是策略网络的参数,根据前面讲过的AC算法,可以联想到使用策略网络充当 Actor,使用DQN中的价值网络充当 Critic(注意这里估计的是 Q值,而不是 V值,不要和AC算法搞混了),Actor部分不使用带 Reward 的加权梯度更新(PG算法更新方式),而是使用Critic网络对action 的梯度对 actor更新。

DDPG既然来自DQN,那当然也有经验回放与双网络,所以在 Critic 部分增加一个目标网络去计算目标 Q值,但是还需要选取动作用来估计目标Q值,目前已经有一个Actor策略网络,用类似的做法,再增加一个Actor目标网络,所以DDPG算法一共包含了四个网络,分别是:Actor当前网络,Actor目标网络,Critic当前网络,Critic目标网络,2个Actor网络的结构相同,2个Critic网络的结构相同,这四个网络的功能如下:

  • Actor当前网络:负责策略网络参数 θ \theta θ 的迭代更新,负责根据当前状态 S 选择当前动作 A,用于和环境交互生成 S’和 R。
  • Actor目标网络:负责根据经验回放池中采样的下一状态 S’ 选择最优下一动作 A’,网络参数 θ \theta θ 定期从 θ \theta θ 复制。
  • Critic当前网络:负责价值网络参数 w w w的迭代更新,输出当前Q值 Q ( S , A , w ) Q(S,A,w) Q(S,A,w)
  • Critic目标网络:负责输出 Q ′ ( S ′ , A ′ , w ′ ) Q'(S',A',w') Q(S,A,w) ,从而计算目标Q值(td-target),网络参数 w ′ w' w 定期从 w w w 复制。

注意:Critic 网络的输入有两个:动作和状态,需要一起 输入到 Critic 中

值得一提的是,DDPG从当前网络到目标网络的复制和之前讲到了DQN不一样。在DQN中是直接把将当前Q网络的参数复制到目标Q网络,即 w ′ = w w' = w w=w,这样的更新方式为硬更新,与之对应的是软更新,DDPG就是使用的软更新,即每次参数只更新一点点,即:
w ′ ← τ w + ( 1 − τ ) w ′ θ ← τ θ + ( 1 − τ ) θ ′ w' \leftarrow \tau w + (1-\tau)w' \\ \theta \leftarrow \tau \theta + (1-\tau)\theta' wτw+(1τ)wθτθ+(1τ)θ
其中 τ \tau τ 是更新系数,一般取的比较小。同时,为了学习过程可以增加一些随机性,探索潜在的更优策略,通过Ornstein-Uhlenbeck process(OU过程)为action添加噪声,最终输出的动作A为:
A = π θ ( s ) + O U n o i s e A = \pi_\theta(s) + OU_{noise} A=πθ(s)+OUnoise
对于损失函数,Critic部分和DQN类似,都是使用均方误差:
J ( w ) = 1 m ∑ i = 1 m ( y i − Q ( S i , A i , w ) ) 2 J(w) = \frac{1}{m}\sum_{i=1}^m(y_i - Q(S_i, A_i, w))^2 J(w)=m1i=1m(yiQ(Si,Ai,w))2
对于Actor部分的损失函数,原论文定义的比较复杂,这里采取一种简单的方式来理解,由于Actor 的作用是输出一个动作 A,希望这个动作 A输入到 Critic 后,可以获得最大的 Q 值。 所以Actor的损失可以简单的理解为得到的反馈Q值越大损失越小,得到的反馈Q值越小损失越大,因此只要对状态估计网络返回的Q值取个负号即可,即:
J ( θ ) = − 1 m ∑ i = 1 m Q ( s i , a i , w ) J(\theta) = -\frac{1}{m}\sum_{i=1}^mQ(s_i, a_i, w) J(θ)=m1i=1mQ(si,ai,w)
关于DDPG算法完整的流程如下:

asY5ng.png

三、代码实现

代码使用 Pendulum-v0 连续环境,采用 tensorflow 学习框架

1、搭建网络

Actor 网络
def get_actor(input_state_shape):
    input_layer = tl.layers.Input(input_state_shape)
    layer = tl.layers.Dense(n_units=64, act=tf.nn.relu)(input_layer)
    layer = tl.layers.Dense(n_units=64, act=tf.nn.relu)(layer)
    layer = tl.layers.Dense(n_units=action_dim, act=tf.nn.tanh)(layer)
    layer = tl.layers.Lambda(lambda x: action_range * x)(layer)
    return tl.models.Model(inputs=input_layer, outputs=layer)

Actor 网络输入状态 ,输出动作,注意的是,连续环境的动作一般都有一个范围,这个范围在环境中已经定以好,使用 action_bound = env.action_space.high 即可获取。

如果 actor 输出的动作超出范围会导致程序异常,所以在网络末端使用 tanh 函数把输出映射到 [-1.0, 1.0]之间。然后使用 lamda 表达式,把动作映射到相应的范围。

Critic 网络
def get_critic(input_state_shape, input_action_shape):
    state_input = tl.layers.Input(input_state_shape)
    action_input = tl.layers.Input(input_action_shape)
    layer = tl.layers.Concat(1)([state_input, action_input])
    layer = tl.layers.Dense(n_units=64, act=tf.nn.relu)(layer)
    layer = tl.layers.Dense(n_units=64, act=tf.nn.relu)(layer)
    layer = tl.layers.Dense(n_units=1, name='C_out')(layer)
    return tl.models.Model(inputs=[state_input, action_input], outputs=layer)

在DDPG中把状态和动作同时输入到 Critic 网络中,去估计 Q ( s , a ) Q(s,a) Q(s,a) 。所以定义两个输入层,然后连接起来,最后模型的输入部分定义两个输入。

2、主流程

for episode in range(TRAIN_EPISODES):
    state = env.reset()
    for step in range(MAX_STEPS):
        if RENDER: env.render()
        # Add exploration noise
        action = agent.get_action(state)
        state_, reward, done, info = env.step(action)
        agent.store_transition(state, action, reward, state_)

        if agent.pointer > MEMORY_CAPACITY:
            agent.learn()

        state = state_
        if done: break

可以看到,DDPG流程与DQN基本相同,重置状态,然后选择动作,与环境交互,获得S’ ,R后,把数据保存起来。如多数据量足够,就对数据 进行抽样,更新网络参数。然后开始更新 s,开始下一步循环。

这里重点看一下 get_action() 函数:

def get_action(self, s, greedy=False):
    a = self.actor(np.array([s], dtype=np.float32))[0]
    if greedy:
        return a
    return np.clip(
        np.random.normal(a, self.var), -self.action_range, self.action_range)

get_action() 函数用以选取一个动作,然后与环境交互。为了更好的探索环境,在训练过程中为动作加入噪声,原始的DDPG作者推荐加入与时间相关的OU噪声,但是更近的结果表明高斯噪声表现地更好。由于后者更为简单,因此其更为常用。

这里就采用的后者,为动作添加高斯噪声:Actor 输出的 a 作为一个正态分布的平均值,然后加上参数 VAR,作为正太分布的方差,就可以构造一个正态分布。然后从正太分布中随机选取一个动作 ,由于正太分布是有很大概率采样到平均值附近的点,所以利用这个方法,就可以实现一定的探索行为。此外,也可以控制 VAR 的大小,来控制探索概率的大小。

当测试的时候,选取动作时就不需要探索,因为这时 Actor 要输入有最大 Q 值的动作,直接输出动作就可以。所以在get_action() 函数中用 一个参数 greedy 来控制这两种情况。

3、网络更新

Critic 更新

在这里插入图片描述

如上图所示,Critic 部分的更新和 DQN 是一样的,使用td-error来更新。用目标网络构造 target,然后和当前网络输出的 q 计算MSE损失,然后更新网络参数。

with tf.GradientTape() as tape:
    actions_ = self.actor_target(states_)
    q_ = self.critic_target([states_, actions_])
    target = rewards + GAMMA * q_
    q_pred = self.critic([states, actions])
    td_error = tf.losses.mean_squared_error(target, q_pred)
critic_grads = tape.gradient(td_error, self.critic.trainable_weights)
self.critic_opt.apply_gradients(zip(critic_grads, self.critic.trainable_weights))
Actor 更新
with tf.GradientTape() as tape:
    actions = self.actor(states)
    q = self.critic([states, actions])
    actor_loss = -tf.reduce_mean(q)  # maximize the q
actor_grads = tape.gradient(actor_loss, self.actor.trainable_weights)
self.actor_opt.apply_gradients(zip(actor_grads, self.actor.trainable_weights))

DDPG采用梯度上升法,Actor作用就是输出一个动作,这个动作输入Critic 网络能得到最大的 Q 值。由于和梯度下降方向相反,所以需要在 loss 函数前面加上负号。

完整代码地址: 强化学习——DDPG算法Tensorflow2.0实现 还望随手给个star,再次不胜感激

四、总结

DDPG通过借鉴AC的架构,在DQN算法的基础上引入了Actor网络,解决了连续控制问题,可以看做是DQN在连续问题上的改进算法。

下篇会介绍DDPG的进化版本的算法,就是TD3算法。

参考:
知乎专栏:白话强化学习

  • 15
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 25
    评论
### 回答1: Deep Deterministic Policy GradientDDPG)是一种基于深度神经网络的强化学习算法。它是用来解决连续控制问题的,即输出动作的取值是连续的。DDPG是在DPG(Deterministic Policy Gradient)的基础上进行改进得到的,DPG是一种在连续动作空间中的直接求导策略梯度的方法。DDPG和DPG都属于策略梯度算法的一种,与其他策略梯度算法(如REINFORCE)的不同之处在于,DPG和DDPG都是基于偏微分方程的直接求导,而不是蒙特卡罗方法进行计算。DDPG使用一个确定性策略来生成动作,但同时使用一个噪声过程来扰动输出的动作,以产生更多的状态动作样本。这样一来,DDPG就具有了良好的探索能力,使得它在解决复杂的连续动作问题时能取得较好的效果。 ### 回答2: 深度确定性策略梯度(Deep Deterministic Policy GradientDDPG)是一种用于解决深度强化学习问题的方法。 DDPG是基于确定性策略梯度(Deterministic Policy Gradient,DPG)的算法,可以在连续动作空间下进行强化学习。与传统的策略梯度方法不同,DDPG直接学习确定性策略,在给定状态下选择最优的动作。 DDPG主要由两个网络组成:一个是Actor网络,用于学习确定性策略;另一个是Critic网络,用于估计状态-动作对的Q值。Actor网络根据当前状态选择动作,Critic网络根据当前状态和动作的组合估计其对应的Q值。通过不断地交互环境、收集数据和更新网络参数,DDPG算法逐渐优化确定性策略和Q值估计,以使得智能体在环境中获得更高的累积奖励。 DDPG算法的核心思想是通过使用Experience Replay和目标网络来提高学习的稳定性和收敛性。Experience Replay将智能体与环境的交互经验存储在一个经验回放缓冲区中,然后从中随机采样进行训练;目标网络通过延迟更新目标网络的方式,减小训练中的目标值变动,从而提高算法的稳定性。 DDPG算法在解决连续控制任务中表现出良好的性能和收敛性,可以应用于机器人控制、无人驾驶、金融交易等复杂任务中。然而,DDPG算法也存在一些挑战和问题,如对超参数的敏感性、样本效率较低等,这些问题是DDPG算法持续改进的方向之一。 ### 回答3: Deep Deterministic Policy GradientDDPG)是一种用于连续动作空间的深度强化学习算法。它结合了深度神经网络和确定性策略梯度的优势,可以应用于诸如机器人控制和金融投资等领域。 DDPG算法的核心思想是通过在连续动作空间中学习一个行动者-评论家系统。行动者使用确定性策略,即给定状态输出一个具体的动作,而评论家则评估行动者的动作质量。这两个网络都是用深度神经网络来表示,并通过梯度下降来进行优化。 在训练过程中,DDPG使用了经验回放缓冲区来存储之前的转换并随机采样进行训练。这样做可以解决样本相关性和非稳定性问题。同时,为了保持算法的探索性,DDPG采用了一个目标网络,用于与主网络进行定期的软更新。 DDPG的优点在于能够处理连续动作空间,通过近似价值函数和策略函数,对高维、非线性状态空间进行建模。此外,DDPG还有很好的收敛性和稳定性,可以在复杂任务中取得较好性能。 然而,DDPG也存在一些挑战。由于使用了神经网络近似值函数,对网络结构的选择和超参数的调整都非常重要。此外,训练过程中可能会出现训练不稳定的问题,需要进行合适的技巧和调整。 总结来说,DDPG是一种深度强化学习算法,适用于连续动作空间的问题。通过结合确定性策略梯度和深度神经网络的优势,DDPG能够解决高维、非线性状态空间的问题,并在复杂任务中取得好的性能。然而,对网络结构和超参数的选择需要仔细调整,且训练过程中可能存在稳定性问题。
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值