大家好, 欢迎学习本教程｡
现在我们有了模型的大脑｡
我们还有优化器｡
所以基本上我们已经准备好训练不同的探员了｡
那是我们不同的大脑｡
所以从现在开始, 我们将创建一个包含所有a3c算法的大型train函数｡
因此我们要在这列火车上实现的, P文件就是这个巨大的火车函数｡
他们将只是这个大火车功能, 没有别的, 没有阶级｡
但我们将在本模块的最后一步中使用此train函数和主代码｡
好了, 我们走吧｡
但是在我们开始之前, 你可以注意到, 首先我们导入一些库｡
这是带torch模块的经典库, 我指的是torch库, 然后是创建Atari环境的最终库,
这将是突破｡
然后, 我们将从模型文件导入活动类｡
最后, 我们将使用火炬大学生的变量来运行高性能的梯度计算, 这要归功于动态图｡
然后我们有一个确保共享梯度的函数, 我不想在这上面花太多时间,
因为首先, 如果代理使用的模型没有任何共享梯度, 这个函数将确保一切都正常工作｡
所以这就是为什么它被称为确保共享grats｡
而另一个原因是我认为这个功能是不必要的, 但我们永远不知道｡
而且至少有了这个, 就可以100%确定代码会正确执行｡
但这并不重要｡
我们必须关注的是我们现在就要开始制作的火车功能｡
我们开始吧, 戴夫和训练｡
我们就简单地称之为火车｡
而这个train函数将采用几个参数｡
第一个是等级｡
我将在第二节中解释它是什么｡
第二个参数是params, 这样所有的参数都是环境的, 第三个参数是要共享的模型｡
大家知道, 共享模型是代理在一定数量的步骤上运行其小探索的模型｡
最后, 最后一个参数是优化器｡
那是我们之前做的那个｡
太完美了｡
这就是我们的四个论点｡
现在, 我们准备开始实施这一列车功能｡
所以我们要做的第一件事是, 你知道, 你记得a3c代表什么｡
它代表一个同步的活跃的批评家代理人｡
所以在a3c中, 有一个同步的｡
正如你所理解的, 我们必须同步每个训练代理, 为了同步它们,
我们将使用秩来移动每个种子｡
所以这里的秩参数只是为了移动种子, 使每个训练代理同步｡
因此, 例如, 如果有n个训练代理, 那么等级将从1到N,
并且每个代理将有一个从1到n的整数｡
因此, 当我们通过一个线程移动种子时, 该线程创建的所有伪随机数将完全独立于其他线程｡
然而, 种子是固定的数字, 所以当我们再现经验时,
我们会发现完全相同的事件, 这是因为它是关于种子的确定性｡
所以理解这点很重要｡
这就是为什么我们要做的第一件事就是同步每个训练代理通过使用这里的秩来移动种子｡
所以我们开始吧｡
为此, 我们要把我们的火炬图书馆｡
然后我们将得到带有手动下划线和种子括号的种子｡
这是一个函数｡
现在我们要取所有代理的种子, 我们可以用params, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,
我们在这里加一个字｡
这将转移种子与排名, 以剥夺每个培训代理, 因为有一个种子, 为每个培训代理｡
好了, 第一件事搞定了｡
现在是下一步｡
下一步是获取环境｡
因此, 我们将创建一个新的变量, 称为env, 现在我们将使用end模块中的create
Atari end函数来创建分线环境｡
那就是得到突围的环境｡
所以我们用这个函数, 创建雅达利和｡
现在我们只需要输入一个参数, 就是环境的参数,
我们有这些参数是因为这是train函数的输入之一｡
此参数将成为接线盒环境的参数｡
因此, 为了获得突破环境, 我们取这个参数, 然后点,
然后我们得到env名称, 它在未来的下一个代码中, 包含将执行整个代码的主函数,
将是突破年｡
好吧, 我会的
这样我们的环境就完美了｡
现在, 下一步是在其中一个代理上对齐环境的种子｡
我们为什么要这么做？
这是因为, 请记住, a3c模型的每个代理人都有自己的环境愿景, 就像它自己的环境副本一样｡
因此, 我们需要在环境的一个特定版本上协调每个代理｡
为了做到这一点, 我们将使用种子, 因为每一个种子都决定了一个特定的环境｡
因此, 通过将不同的种子与每个代理相关联, 我们将得到我们想要的结果｡
也就是说, 每个代理都有自己的环境｡
那么我们如何才能做到这一点呢？
我们可以取环境, 然后添加它, 然后使用seed函数来选择我们想为环境获得的种子｡
现在要将环境的种子与代理的种子对齐, 我们只需要得到这个,
因为它对应于代理的种子, 由于等级的原因, 代理被移动了, 得到了这个同步训练代理,
因为它们都在不同的种子上｡
所以我们只需要把它放在这里｡
这将使环境的种子与其中一个代理对齐｡
好吧, 我会的
现在我们将得到我们的模型, 即我们的三个关键大脑｡
现在我们要使用模型文件中的活动评论家类｡
我们要创建一个演员类的对象, 如果你愿意, 我们可以称之为对象模型或大脑.
但基本上这个对象将包含所有的卷积､ STM､ 线性全连接和传播信号的前向函数｡
所以它基本上包含了演员和评论家的大脑, 能够将信号传播到整个大脑, 以获得最终的输出｡
所以我们开始吧｡
让我们创建模型｡
正如我们所说的, 我们要把这个对象模型称为｡
所以我们创建了一个act类的对象, 然后我们取了我们的类, actor, critic,
现在记住我们需要输入什么参数｡
这实际上是init函数的参数, 所以我们不需要输入它｡
这就是我们在init方法中使用对象所要做的｡
但是我们必须输入的参数是nom输入, 也就是输入形状｡
这是我们输入的维度, 图像和动作空间, 包含了一系列的动作｡
所以让我们把这些参数输入train函数｡
第一个, 我们可以用环境和点得到它, 然后我们用观察空间｡
这是观察空间, 然后是dut, 然后得到输入的个数, 我们得到形状｡
括号零｡
好吧, 我会的
这就是四个数字输入｡
现在是行动空间｡
嗯, 那几乎一样｡
但我们需要从我们的环境中得到我们是进口的｡
然后是dut, 然后是动作空间｡
好吧, 我会的
这就给了我们在创建对象时需要输入的参数｡
创造一个阶级行为的道德｡
现在我们有了模型, 下一步是准备输入状态｡
所以记住, 我们仍然在做深度强化学习｡
因此, 输入状态是输入图像, 因此, 这最初将是一个numpy数组, 它将包含一个通道,
因为我们将处理白色图像, 它将具有42 × 42的维度｡
但重要的是要理解并记住, 输入状态就是输入图像｡
首先, 我们要做的是得到编号, 然后我们将它转换成火炬张量｡
但第一步和我们之前做的一样, 是建立一个正确的帝国, 要建立起来, 其实很简单｡
首先, 我们需要为输入状态创建一个变量, 我们将其命名为state,
为了得到数组, 我们只需要取我们的环境, 然后添加它, 然后使用reset函数｡
这将初始化state为一个1 × 42 × 42的维度数组, 1表示一个通道,
所以黑白图像, 42 × 42当然是图像的维度,
宽度上的像素数和高度上的像素数｡
所以基本上这就是我们要处理的维度｡
现在, 现在我们已经有了这个, 因为这将得到这些阵列中的图像,
现在我们可以把它们转换成手电筒传感器｡
为了做好这一点, 我们将再次更新状态, 因为我们不需要保留病毒｡
这就是我们使用手电筒模块的地方｡
记住, 我们已经为末日做过了｡
我们使用函数from underline num by par括号,
在这个函数中我们需要输入我们想要转换成火炬张量的数字｡
这就是国家｡
numpy数组中的先前版本的状态将通过应用来自它们的by函数而变成一个火炬张量｡
这就从状态中创建了一个张量, 现在我们只需要初始化完成变量｡
请记住done变量通常是表示一集结束或者游戏结束的变量, 这里我们只想引入这个done变量并初始化为true来指定当游戏结束时这个done变量将等于true
这对以后的游戏很有用, 这样AI就不会无限期地玩游戏｡
好吧, 我会的
这基本上就是这个训练函数的开始, 包括一些初始化和一些我们必须做的事情｡
这里最重要的部分是我们必须同步每个训练代理｡
这就是我们必须应用的a3c模型的1/1原理｡
现在, 在下一个教程中, 我们将继续进行与共享模型的同步｡
我们不要忘记, 有不同的模型, 但也有共享模型, 这是一个所有代理共享的模型｡
所以我们必须与这个共享模型同步, 这样每个代理都可以得到这个共享模型,
以进行一定数量步骤的小探索｡
这就是我们在下一个教程中要做的｡
在那之前, 好好享受吧｡
一､