### A3C
advantage actor-critic(A2C)方法(详见第12章)的扩展方法。扩展方法加入了真正的异步环境交互,其全名是asynchronous advantage actor-critic(A3C)。此方法是强化学习从业者使用最广泛的方法之一。
▪ 讨论为什么策略梯度方法从多个环境中收集训练数据很重要。
▪ 实现两种不同的A3C方法。
在深度Q-network(DQN)中,我们通过在回放缓冲区中存储大量先前的状态,并从此缓冲区中采样我们的训练批来解决这个问题。如果缓冲区足够大,则来自该缓冲区的随机样本将更好地表示状态的分布。不幸的是,该解决方案不适用于策略梯度方法,因为它们大多数都是在线策略的,这意味着我们必须根据当前策略生成的样本进行训练,因此记住旧的状态转移将变得不可行。你可以尝试这么做,但是最终的策略梯度是用于生成样本的旧策略的梯度,而不是你想要更新的当前策略的梯度。
在Pong中,我们的A2C智能体在800万帧内收敛,这是第6章和第8章中基本DQN的100万帧的8倍。所以,策略梯度方法并不是完全没用的,这两个方法只是有所不同,并且具有自己的特殊性,你需要在选择时加以考虑。如果你的环境在智能体交互方面很廉价(该环境速度快,内存占用量少,允许并行等),策略梯度方法可能是更好的选择。另外,如果环境昂贵并且获得大量经验可能会减慢训练过程,那么基于价值的方法可能是更明智的选择。
关于actor-critic的并行化,存在两种方法:
1)数据并行化:我们可以有多个进程,每个进程都与一个或多个环境进行通信,并提供状态转移(s, r, a, s')。所有这些样本都被收集在一个训练进程中,该进程计算损失并执行SGD更新。然后,需要将更新的神经网络(NN)参数广播给所有其他进程,用于之后的环境交互。
2)梯度并行化:由于训练进程的目标是计算梯度以更新神经网络,因此我们可以有多个进程在自己的训练样本上计算梯度。可以将这些梯度加在一起以在一个进程中执行SGD更新。当然,还需要将更新的NN权重广播给所有的worker,以保持数据是在线策略的。
**Python包含multiprocessing(一般缩写为mp)模块,以支持进程级并行化和所需的基本通信功能,此模块中的两个主要类:**
▪ mp.Queue:并发的多生产者、多消费者的FIFO(先进先出)队列,对放置在队列中的对象进行透明的序列化和反序列化。
▪ mp.Process:运行在子进程中的代码块以及在父进程中控制它的方法。
PyTorch围绕multiprocessing模块提供了自己的小型包装器,该包装器在CUDA设备和共享内存上添加了对张量和变量的正确处理。它提供的功能与标准库中的multiprocessing模块完全相同,因此你需要做的就是使用import torch.multiprocessing替换import multiprocessing。
**在超参数中,有三个新值:**
▪ PROCESSES_COUNT:指定将为我们收集训练数据的子进程数。此处理过程主要受CPU限制,因为此处最昂贵的操作是Atari帧的预处理,因此此值设置为我的计算机的CPU核心数。
▪ MICRO_BATCH_SIZE:设置每个子进程在将样本发送到主进程之前需要获取的训练样本的数量。
▪ NUM_ENVS:每个子进程用于收集数据的环境数。这个数字乘以进程数即是我们将从中获取训练数据的并行环境的总数。
**创建子进程时,我们将以下几个参数传递给该函数:**
▪ 进程的名称,用于创建TensorBoard写入器。在此示例中,每个子进程都写入自己的TensorBoard数据集。
▪ 共享的NN。
▪ 执行计算的设备(cpu或cuda字符串)。
▪ 队列,用于将计算出的梯度传递到中心进程。
<u>对于策略梯度方法来说,从多个环境中收集训练数据很重要。我们也实现了两种A3C方法,以实现训练过程的并行化和稳定性。</u>