OPENAI Baeslines 详解(八)PPO2

OPENAI Baeslines 详解(八)PPO2

OPENAI 提供了2个版本的PPO PPO1 网上标注是(obsolete version, left here temporarily) PPO2 属于 正式版本吧。 这里粗略描述一下,PPO2的整体过程 。

程序架构

  • ppo2.ppo2

    来创建learner 进行训练和更新网络,主要的流程都在这里

  • common.policy

    建立PPO所需要的值网络和策略网络

  • ppo2.model

    确立静态图中的loss、以及各种梯度

  • ppo2.runner

    利用所创建的策略来进行环境交互

总流程PPO2:

  • 第一步 :建立所需模型、函数
policy = build_policy(env, network, **network_kwargs) 
                    # 88行  建立policy
model = model_fn()# 107行 建立model
runner = Runner(env=env, model=model, nsteps=nsteps, gamma=gamma, lam=lam)           # 114行
  • 循环:
  • 第二步 :跑nsteps个step的轨迹
obs, returns, masks, actions, values, neglogpacs, states, epinfos = runner.run()     # 142行
  • 第三部 循环更新noptepochs次

    mblossvals.append(model.train(lrnow, cliprangenow, *slices))
    # 166行
    
    mblossvals.append(model.train(lrnow, cliprangenow, *slices))
    # 180行 recurrent version
    

创建policy

policy = build_policy(env, network, **network_kwargs) 
# ppo2 第88行

1、建立actor网络(policy网络),建立输入tensor,并进行归一化,送入给定的神经网络,得到网络输出tensor。

​ 建立critic网络,可以选择critic网络与actor 共享参数。

2、首先根据动作类型建立动作分布函数类型(是建立pdtype 还没有建立分布函数)

self.pdtype = make_pdtype(env.action_space) 
# 具体的对应建立请看PPO1 policies 47行

3、利用动作network创建,根据动作分布函数类型,在神经网络的最后一层建立对应的输出层,

self.pd, self.pi = self.pdtype.pdfromlatent(latent, init_scale=0.01)
# policies 47行

其中self.pd 是一个类,该类接受 网络的输出,并计算

neglogp(求概率的对数的复数)、 kl(KL散度)、entropy(熵)、sample(根据输出的概率分布进行采样)等函数。注意 这些计算都是图上的节点 需要输入状态 用sess.run进行计算。

建立model

主要目的是 建立loss
OPENAI Baeslines 详解(八)PPO2_第1张图片

建立loss 之后 建立训练函数:

其中输入为

td_map = {
    self.train_model.X : obs, # 观察 计算pd
    self.A : actions,         # 动作 计算neglogpac
    self.ADV : advs,          # 优势函数 计算pg—loss
    self.R : returns,         # 奖励
    self.LR : lr,             # 学习率
    self.CLIPRANGE : cliprange, # 剪裁范围
    self.OLDNEGLOGPAC : neglogpacs, # 负对数概率密度
    self.OLDVPRED : values     # 老策略值函数
}
if states is not None:
    td_map[self.train_model.S] = states
    td_map[self.train_model.M] = masks

在输出的过程中 进行训练 并利用Loss反向传播

self.loss_names = ['policy_loss', 'value_loss', 'policy_entropy', 'approxkl', 'clipfrac']
self.stats_list = [pg_loss, vf_loss, entropy, approxkl, clipfrac]

建立Runner(交互)

利用policy 动作函数网络 obs 可以得到 动作概率分布pd

actions, values, self.states, neglogpacs = self.model.step(self.obs, S=self.states, M=self.dones)# runner 29行

actions, 对pd采样得到

values, 由于是参数共享,相当于计算Q值,所以可以直接得到(程序中还给出了其他的方法,也可以使用)

self.states,

neglogpacs 负对数概率分布

利用policy 中值函数网络 可以得到 最后的值函数

last_values = self.model.value(self.obs, S=self.states, M=self.dones)# runner 50行

并开始计算优势函数:

for t in reversed(range(self.nsteps)):
# 从最后一个时间时刻开始 依次向前
    if t == self.nsteps - 1:
        nextnonterminal = 1.0 - self.dones
        nextvalues = last_values
    else:
        nextnonterminal = 1.0 - mb_dones[t+1]
        nextvalues = mb_values[t+1]
    # 蒙特卡洛方法依次计算上一个时刻的td 误差
    delta = mb_rewards[t] + self.gamma * nextvalues * nextnonterminal - mb_values[t]
    # 计算优势函数
    mb_advs[t] = lastgaelam = delta + self.gamma * self.lam * nextnonterminal * lastgaelam

最后runner 返回一系列轨迹 (采样并行采样的)

你可能感兴趣的:(baseline,Python,强化学习-读代码懂原理系列)