大家好, 欢迎学习本教程｡
再次祝贺你完成了三个｡
看, 我们成功了
我们制造大脑并训练它们｡
但是现在我们还是要做一个测试代理, 它根本不会更新模型,
只会使用共享的模型进行自己的探索｡
当然, 在这段代码中, 我们将录制一些视频,
这些视频是测试代理以一定的分数进行突破的视频｡
让我们来看看这段代码｡
最重要的是完成｡
正如我告诉你们的, 我们不会逐行编码, 但我认为重要的是你们要理解这里发生了什么｡
这就是我们的代码｡
在第一部分中, 正如您所注意到的, 我们导入了库, 然后我们定义了这个测试函数,
它将使这个测试代理进行自己的探索, 并进行突破游戏｡
好了, 我们走吧｡
此测试函数采用三个参数｡
第一个是rank, 这仍然是为了同步测试代理, 就像我们对训练代理所做的那样｡
然后我们有了参数, 当然, 因为我们需要一些参数｡
当然, 我们有共享模型, 因为这个测试代理将使用共享模型来进行自己的探索｡
好的, 然后, 我们进入这行代码中的函数,
我们确实像之前一样同步了测试代理｡
然后导入环境｡
所以我提醒大家, 在主代码中, 这将在下一个教程中,
名字的结尾将被替换为breakout with zero, 这样我们就可以进入breakout zero的环境来玩这个游戏了.
视频等于真意味着我们将获得管道突破的视频｡
基本上, 这行代码意味着我们在一个环境中运行视频｡
然后在下一行代码中, 我们同步了这个环境, 这与训练函数中的原理完全相同｡
然后我们得到我们的模型, 为了做到这一点, 我们创建了一个活动类的对象, 我们用我们的环境､
观察､ 空间和形状零输入输入形状｡
就像火车函数和我们的输出一样, 也就是有一个动作空间的动作｡
所以完全像以前那么新的东西在这里｡
由于我们已经完成了训练, 我们不想让模型进入训练模式,
因为我们不想让它训练, 我们想让它进入瓦尔模式, 这就是我们在这里对模型. val所做的｡
这基本上就是将测试代理置于一种模式中, 该模式将基本上测试它, 测试其性能评估｡
这里我们得到了输入状态, 也就是游戏中的输入图像, 这一点是通过数组来实现的.
然后在这里我们把它们转换成手电筒传感器｡
这里我们初始化一些奖励｡
这里我们初始化为true｡
所以还是跟上次一样, 后来又有了新的东西｡
我们引入第三个时间变量, 用时间到时间函数来度量计算时间｡
这是因为我们想要得到一个起点, 然后在这里, 对于操作,
我们使用了一种非常实用的提示类型, 它允许从右边或左边向队列中添加元素｡
这非常实用, 我会在推荐的代码版本中给你参考链接｡
大家可以看看这个日队列是什么, 这就是我们能够做到这一点的原因｡
然后我们把一个事件的长度初始化为零, 当然, 然后我们会在这个井循环中增加长度｡
所以我们用同样的技巧, 当为真时, 在循环中, 我们把一集的长度加1｡
当游戏完成时, 当游戏结束时, 我们重新加载最后一组共享模型｡
由其他模型更新的共享模型｡
请记住, 此处不再更新此共享模型｡
然后, 如果游戏结束了, 如果游戏结束了, 我们就在里面｡
我们重新初始化单元格状态, 见x和隐藏状态, 如果游戏还没有结束, 那么,
我们保持相同的单元格状态和隐藏状态, 但我们要确保它们在一个总变量中, 这样它们就可以被附加到一个梯度上｡
这是我们在train函数中已经做过的, 在wild循环中仍是如此｡
并且在以正确的方式更新隐藏状态中的单元状态之后, 这取决于这里的两种情况｡
那我们怎么办？
我们得到了模型的预测｡
这就是我们在这行代码中所做的｡
所以我们得到的值, 是评论家的输出, 行动值, 是行动者的输出, 然后是顶部,
所有的隐藏状态, h, x和细胞状态见x｡
然后我们生成一个行为的概率分布, 它是Q值的行为值｡
我们用max函数来做这个｡
当然, 我们不需要在这里得到对数概率, 因为这只是为了训练测试代理｡
它只会播放我们要用的动作, 比如doom, 一个柔软的max body来播放它｡
但我们在这里不做任何训练, 所以我们只有道具｡
从这个探测器中, 我们通过直接取这些概率的最大值来进行行动｡
也就是说, 它会采取概率最高的操作｡
原因是测试代理不做任何探索｡
记住我们要｡
有机会挑选一些概率较低的行为, 当我们想对这些行为做一些探索的时候, 你知道,
不是每次都采取概率最高的行为｡
但这里的测试代理不会做任何探索｡
因此, 这就是为什么我们直接采取具有最大可能性的行动｡
然后一旦我们玩了这个动作, 我们就到达了下一个状态, 我们得到了下一个奖励, 完成是更新的,
不管游戏是否结束｡
所以我们用这行代码得到了这一切, 在用max选择了动作后, 播放动作｡
所以我们在这里玩动作, 我们得到状态, 我们得到奖励, 然后向下更新｡
因为我们刚刚得到了一个新的奖励, 我们将通过简单地添加这个新的奖励来更新奖励的总和｡
最后, 当游戏结束时｡
如果done是指游戏结束的时候,
当AI玩完游戏的时候, 我们会打印出结果和时间, 这一集的奖励是这一集的长度, 也就是它最后玩了多少时间？
这就是我们用时间技巧打印出所有变量的方法｡
时间到了｡
然后奖励有的只是一个变量为奖励的总和, 而插曲的长度则是变量为一个插曲的长度｡
当我们打印出所有的结果后, 既然游戏结束了我们要开始新的游戏,
我们要重新初始化所有的奖励之和为零.
一集的长度为零｡
我们将使用clear函数重新初始化所有操作｡
重置输入图像, 你知道, 通过重新把所有的砖在一起｡
最后, 我们利用这段60秒的睡眠时间休息一分钟, 让其他代理进行练习,
如果游戏结束, 最后我们有了最后一行代码, 它将使我们进入新的状态, 然后我们可以继续前进｡
我们可以继续这个新游戏｡
好了, 我们走吧｡
这就是测试函数, 我们将在一个或两个教程中看到视频｡
我希望我们能像上次一样聚在一起观看比赛结果｡
那是你卡罗尔和我的事｡
那会很有趣的｡
我告诉你, 期待看到好的结果｡
但请记住, 这个突破游戏是超级具有挑战性的｡
我们认为这是最简单的游戏先玩, 但根本不是｡
它实际上比毁灭战士要难得多, 这就是为什么我们把它放在最后一个模块｡
但不管怎样, 让我们在下一个教程中把这个主函数说成是这里最重要的｡
现在a3c已经全部实现了｡
所以我们不会逐行编码｡
我将扩展代码, 很快就能得到结果｡
在那之前, 好好享受吧｡
一､