解决报错

  代码文件在 spinup/alogs/pytorch/vpg/vpg.py . 我们尝试运行代码, 然后就报错了…

1
2
3
4
5
6
7
8
9
10
...
usage: ipykernel_launcher.py [-h] [--env_name ENV_NAME] [--render] [--lr LR]
ipykernel_launcher.py: error: unrecognized arguments: -f xxxx.json

An exception has occurred, use %tb to see the full traceback.

SystemExit: 2

xxxx/anaconda3/lib/python3.7/site-packages/IPython/core/interactiveshell.py:xxxx: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.
warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)

嗯, 先看篇这篇文章解决. 然后再次运行, 又报错… 这次又是啥 ?!

1
2
3
4
...
--> 342 mpi_fork(args.cpu) # run parallel code with mpi
...
CalledProcessError: Command '['mpirun', '-np', '4', 'xxxx/anaconda3/bin/python', 'xxxx/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py', '-f', 'xxxx/.local/share/jupyter/runtime/kernel-342bc725-7d2c-4cba-95f4-32c9b625dd61.json']' returned non-zero exit status 1.

观察了一下, 于是直接粗暴的删掉这一行 (就是这么任性) . 再次运行, 还是报错 ???

1
2
...
DependencyNotInstalled: No module named 'mujoco_py'. (HINT: you need to install mujoco_py, and also perform the setup instructions here: https://github.com/openai/mujoco-py/.)

这个问题我弄了好久, 最后发现好像是环境的问题, 我们将参数中 env 的值 HalfCheetah-v2 改为 CartPole-v0 , 也就是

1
parser.add_argument('--env', type=str, default='HalfCheetah-v2')

改成

1
parser.add_argument('--env', type=str, default='CartPole-v0')

然后再次运行. 终于, 成功运行了, 这下能够愉快的开启我们的代码研究之旅了.

Vanilla Policy Gradient

伪代码

  使用来进行优势估计. 因此需要拟合价值函数, 进而计算策略梯度进行优化.

代码详解

VPGBuffer

1
2
3
4
5
"""
A buffer for storing trajectories experienced by a VPG agent interacting
with the environment, and using Generalized Advantage Estimation (GAE-Lambda)
for calculating the advantages of state-action pairs.
"""

  从注释以及变量名中我们可以看出 VPGBuffer 是用来储存采样轨迹的各种信息的. 其中定义的函数的注释已经将函数功能写得很清楚了, 这里我就不作翻译了.

VPG

  注释中已经详细介绍了参数的意义和作用. 中间有很多保存变量, 多线程的东西, 我们都略过, 只讲算法主体部分.

ac

1
ac = actor_critic(env.observation_space, env.action_space, **ac_kwargs)

  由 actor_critic 对象生成, actor_critic 是对象 core.MLPActorCritic , 该对象在 core.py 中被定义, 由其从 torch.nn.Module 继承可知这是个神经网络.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class MLPActorCritic(nn.Module):


def __init__(self, observation_space, action_space,
hidden_sizes=(64,64), activation=nn.Tanh):
super().__init__()

obs_dim = observation_space.shape[0]

# policy builder depends on action space
if isinstance(action_space, Box):
self.pi = MLPGaussianActor(obs_dim, action_space.shape[0], hidden_sizes, activation)
elif isinstance(action_space, Discrete):
self.pi = MLPCategoricalActor(obs_dim, action_space.n, hidden_sizes, activation)

# build value function
self.v = MLPCritic(obs_dim, hidden_sizes, activation)

def step(self, obs):
with torch.no_grad():
pi = self.pi._distribution(obs)
a = pi.sample()
logp_a = self.pi._log_prob_from_distribution(pi, a)
v = self.v(obs)
return a.numpy(), v.numpy(), logp_a.numpy()

def act(self, obs):
return self.step(obs)[0]

  self.piself.v 分别是动作函数与价值函数.

  其中出现了判断 action_spaceBox 还是 Discrete 类型的代码. BoxDiscrete 都是 Space 对象, 描述当前动作或环境. 其中 Box 表示多维连续空间, Discrete 表示一维离散空间. MLPGaussianActorMLPCategoricalActor 都分别刻画了一个神经网络. 其输入 obs_dim 个数据, 输出 action_space.n 或者 action_space.shape[0] 个数据, 并且隐层由 hidden_sizes 指定.

  总之, ac 是两个神经网络的集合, 一个是动作函数, 一个是价值函数.

var_counts

  查看定义, 其计算的是神经网络变量的个数 (激活函数也算) .

compute_loss_pi

  计算动作的损失, 对参数求导正是参数的梯度.

compute_loss_v

  计算价值的损失, 采用了均方误差.

update

  一个函数, 是一次 epoch 后更新参数的过程, 其中先优化策略 (pi_optimizer) , 然后依据 train_v_tiers (每次 epoch 优化价值函数参数的次数) 多次优化价值函数 (vf_optimizer) .

训练过程

  先在环境中 “走” 出一个 epoch (一个 epoch 的交互数 (interaction) 由 steps_per_epoch 指定), 然后调用 update 函数优化.