内容提要
主要讨论(Deep)Reinforcement learning 中 policy based算法本身,以及其与value-based算法结合的state-of-art的算法框架相关内容。
内容搬运了 https://www.jianshu.com/p/8750b3fb5d07; https://www.jianshu.com/p/428b640046aa;
参考资料有 百度飞桨强化学习7天课程;李宏毅强化学习课程 ;PARL框架github:https://github.com/PaddlePaddle/PARL/blob/develop/parl/algorithms/*
- 1.PG算法
- 2.AC算法-增量说明
- 3.A2C算法-增量说明
- 4.PARL框架A2C算法核心代码
- 5.应用A2C玩Atari游戏
1、PG算法回顾
在Policy Gradient算法中,我们直接求解行动策略π,通常用一个神经网络表示(即下面的Actor),输入为state,输出为action,参数为θ。
从任一个特定的状态state出发,Actor不断与环境交互,一直到任务的结束,整个过程称为一个完整的eposide,在每一步,我们都能获得一个奖励r,一个完整的任务所获得的最终奖励被称为R。
一个有T个step的eposide,Actor不断与环境交互,形成如下的序列τ:
这样一个序列τ是不确定的,因为Actor在不同state下所采取的action可能是不同的,一个序列τ发生的概率为:
序列τ所获得的奖励为每个阶段所得到的奖励的和,称为R(τ)。因此,在Actor的策略为π的情况下,所能获得的期望奖励为:
而我们的期望是调整Actor的策略π,使得期望奖励最大化,于是我们有了策略梯度的方法,既然我们的期望函数已经有了,我们只要使用梯度提升的方法更新我们的网络参数θ(即更新策略π)就好了,所以问题的重点变为了求参数的梯度。梯度的求解过程如下:
上面的过程中,我们首先利用log函数求导的特点进行转化,随后用N次采样的平均值来近似期望,最后,我们将pθ展开,将与θ无关的项去掉,即得到了最终的结果。
所以,一个PG方法的完整过程如下:
首先采集数据,然后以回合数据为基础,利用梯度提升更新参数,随后再根据更新后的策略再采集数据,再更新参数,如此循环进行。注意到图中的大红字only used once,因为在更新参数后,我们的策略已经变了,而先前的数据是基于更新参数前的策略得到的。
2、Actor-Critic(AC)
通俗解释一下actor-critic方法。
Actor(玩家):为了玩转这个游戏得到尽量高的reward,你需要实现一个函数:输入state,输出action。可以用神经网络来近似这个函数。剩下的任务就是如何训练神经网络,让它的表现更好(得更高的reward)。这个网络就被称为actor
Critic(评委):为了训练actor,你需要知道actor的表现到底怎么样,根据表现来决定对神经网络参数的调整。这就要用到强化学习中的“Q-value”。但Q-value也是一个未知的函数,所以也可以用神经网络来近似。这个网络被称为critic。
Actor-Critic的训练。
Actor看到游戏目前的state,做出一个action。
Critic根据state和action两者,对actor刚才的表现打一个分数。
Actor依据critic(评委)的打分,调整自己的策略(actor神经网络参数),争取下次做得更好。
Critic根据系统给出的reward(相当于ground truth)和下一步的打分(critic target)来调整自己的打分策略(critic神经网络参数)。
一开始actor随机表演,critic随机打分。但是由于reward的存在,critic评分越来越准,actor表现越来越好。
在PG策略中,如果我们用Q函数来代替R,同时我们创建一个Critic网络来计算Q函数值,那么我们就得到了Actor-Critic方法。
3、Advantage Actor-Critic(A2C)
A2C全称为优势动作评论算法(Advantage Actor Critic)。
A2C使用优势函数代替Critic网络中的原始回报,可以作为衡量选取动作值和所有动作平均值好坏的指标。什么是优势函数?
状态值函数:该状态下所有可能动作所对应的动作值函数乘以采取该动作的概率的和。
动作值函数:该状态下的a动作对应的值函数。
优势函数:动作值函数相比于当前状态值函数的优势。
如果优势函数大于零,则说明该动作比平均动作好,如果优势函数小于零,则说明当前动作还不如平均动作好。
4、PARL框架A2C算法核心代码
def learn(self, obs, actions, advantages, target_values, learning_rate,
entropy_coeff):
"""
Args:
obs: An float32 tensor of shape ([B] + observation_space).
E.g. [B, C, H, W] in atari.
actions: An int64 tensor of shape [B].
advantages: A float32 tensor of shape [B].
target_values: A float32 tensor of shape [B].
learning_rate: float scalar of learning rate.
entropy_coeff: float scalar of entropy coefficient.
"""
# 动作分布one-hot化
logits = self.model.policy(obs)
policy_distribution = CategoricalDistribution(logits)
actions_log_probs = policy_distribution.logp(actions)
# Actor的损失函数
pi_loss = -1.0 * layers.reduce_sum(actions_log_probs * advantages)
# Critic的损失函数
values = self.model.value(obs)
delta = values - target_values
vf_loss = 0.5 * layers.reduce_sum(layers.square(delta))
# The entropy loss
policy_entropy = policy_distribution.entropy()
entropy = layers.reduce_sum(policy_entropy)
total_loss = (
pi_loss + vf_loss * self.vf_loss_coeff + entropy * entropy_coeff)
fluid.clip.set_gradient_clip(
clip=fluid.clip.GradientClipByGlobalNorm(clip_norm=40.0))
optimizer = fluid.optimizer.AdamOptimizer(learning_rate)
optimizer.minimize(total_loss)
return total_loss, pi_loss, vf_loss, entropy
5.Atari游戏应用
官方A2C example踩坑:
1.本地mac os + python2.7 + parl 1.3.1 + paddlepaddle1.6.3 + atari0.3.1:
首次启动pongnoskipV4的A2C example报错:
with open(file_name + '.py') as t_file: 这行拼出来一个actor..py的文件名报NF,修改解决;
2.xparl 开启localhost的server后 启动client训练
接下来报no vacant cpu ,是要独占干净的核吗?然后重试300s后报错:
注意到A2C的demo代码里应用的算法已经是A3C,且actor用remote_class做了装饰,应该是默认采用分布式训练,需要部署多卡高算力的机器?
没关系,可以单机跑个简单一点的,直接用AC模型跑个cartpole吧:
"7天强化学习营"后社区挂起一阵EL风啊,感谢楼主分享!
wow, 好详细啊
学习了
很强
赞一个!