基于循环神经网络创建一个机器人参加AI mini Cup 2018


最初,我没有写文章的计划,尤其是在会议上发表演讲的计划。 但是有一个会议。 在发言之后,观众向我提出了一些有关实施某些技术问题的问题。 因此,结果变成了一个字接一个字的文章。


链接下方的实时录制。


免责声明:本文旨在回答其中一些问题。 如果出现新问题,我将很高兴,回答这些问题将有机会学习自己的新知识。 是的,本文绝不是试图感受铜管的叮当响。


因此,让我们从这个故事的开头开始。 2018年春季,mail.ru宣布了基于Agairo游戏的编程竞赛。 竞争的实质是创造一个游戏机器人。


链接上的竞赛规则。 但是要简短并用自己的语言概述规则,您需要创建一个在Agairo中玩的机器人。 有一次,一种流行的互联网游戏(从浏览器中启动),其本质是吃掉了你的弟弟,而逃离了大个子。 您可以在有限的二维空间中控制色轮。 要在此空间中创建游戏玩法,除了您的圈子外,还有其他圈子也由其他玩家控制。 有食物(彩色圆点)用于增长,另外的障碍物以“病毒”的形式引入,与之碰撞会将您的圈子划分为较小的圈子,这部分使游戏过程变得复杂,因为较小的孩子吃较大的孩子,较大的孩子则更安全。


我将为比赛提供一个变体的图片


此外,所谓玩家,不是机器人开发人员,而是机器人本身。


整个比赛的组织者都保留了游戏的原始概念,但增加了许多创新。 主要是限制对机器人的审查以及引入简单的物理定律(称为惯性)的限制。 物理学已经经历了很长时间了,所以惯性不仅与我们有关,而且与质量,速度和加速度有关。 我们不需要物理学世界的任何其他东西。


我希望文学部分能引起足够的重视,现在是时候继续比赛的技术部分并参加比赛了。


免责声明2:我敢肯定,以下所述的内容可以做得更薄,更优雅,更智能,但它是如何发生的。


因此,写下食谱和主要成分,它们并不是全部都是新的,但是您可以添加自己的口味。


任务:创建一个可以自己玩Agairo的机器人。
主要思想:使用神经网络(以下称为神经网络,神经网络(NN))作为机器人的控制元素。
主要生产工具: Microsoft Visual Studio和带有平滑过渡到c ++的c#。


那么对于作者来说,最重要的是选择或了解他的读者,我正在为谁写作,他是否知道神经网络,遗传算法以及如何详细描述所有这些内容。


就是这样,我选择了我的阅读器,我的阅读器知道所有这些内容,但是在实践中使用它并不那么好。


因此,在撰写本文时,我会想起简单的形式,例如神经元和激活功能。


为了进行可视化,我将使用手绘图片,这些图片应阅读为:如果在那里看到任何错误,请编写并重新绘制为正确的错误。



因此,一切准备就绪,可以发送到bot的软件构建路径。 让我们开始:


我们以周期为例,或者说,竞赛的组织者为我们准备了一个简单的机器人示例。 让我们更深入一点,使用此链接从资源库下载竞赛参与者的档案。 组织者承诺比赛服务器将继续使用,完成后,我们将能够验证这些单词。 我们打开档案,然后选择一种我们可以理解的编程语言。


比赛的文档还描述了客户端(阅读我们的机器人)和生活在某个深处的数据中心服务器的通信技术。 简而言之,通信通过控制台线进行,即通过从控制台线写入和读取命令来进行。


在这里应该提到神奇的词“ 序列化” :它以序列化程序可以理解的格式打包数据,并且可以使用序列化程序将数据读回到程序中。 序列化器很多,最简单的写入txt文件的顺序格式也是序列化器,但是很简单。 关于序列化器,我们需要知道的是它们存在并且就API而言几乎是透明的。 组织者最有可能理解了这一点,因此他们的漫游器示例包含使用序列化程序的所有必要说明。 在我们的例子中,它是JSON


对于序列化器之后的机器人来说,游戏世界看起来像是在上述周期开始时接收到的数据数组。 有关游戏世界的数据由服务器根据与机器人的4半径相等的视图半径进行限制,请记住,机器人是一个圆。 而围绕圆圈的圆圈是评论的外部边界,尽管外部圆圈相对于机器人相对于机器人中心的移动略有偏向,但是在我们的案例中可以忽略不计。



因此,我们有一个周期,周期的度量单位是刻度,经过了多少个周期,运行了多个刻度。 最有可能的是,我们将不再记得此Tick,但它将引入许多重要的限制和简化:计算时间不仅受到单个Tick,周期一次迭代的时间的限制,还受到总计算时间的限制,超过此时间游戏服务器将使您的机器人与管理断开连接。 勾选它,然后花时间向机器人发送命令。 我们将其视为游戏时间的一部分,“滴答”是游戏世界中不可分割的时间。 随之而来的是加号。 由于默认情况下,滴答等于1,因此可以更轻松地计算速度,加速度和其他值。 在所有公式中,我们乘以1,而不是在其中使用某种曲线时间t = 0.0015秒。 这些操作中的错误也很小。


以上所有内容都与电影相似,似乎屏幕上的画面生动活泼,但实际上我们每秒可以看到25个不同的帧,而我们的大脑只是认为这足以充分感知视频的动态情况。 因此,机器人会每隔一定的时间看到世界。 刻度线是游戏世界的框架。


神经网络也将根据滴答声工作。


图片开始从机器人的侧面清除:


服务器将有关世界的已处理数据发送到机器人->滴答开始->机器人接收数据->处理它->将机器人管理命令发送到服务器->服务器读取数据->滴答结束,然后在几乎无限的圈或圈中,最后45,000滴答游戏是相当可观的数字。


重要说明:您可以跳过“勾号”,但一无所获。 在服务器的情况下,每个Tick都需要告诉服务器一些信息,以便服务器不会在控制程序中挂起僵尸。


作者决定不多动服务器,但是我需要说几句话。 服务器上有一个游戏世界的模型,并根据它执行计算和操作。 服务器程序包括以下块:


  • 机器人冲突的计算(处理与游戏世界边界的冲突,谁吃谁,机器人或机器人食物,与病毒的冲突等)
  • 机器人物理计算(机器人运动,机器人速度根据机器人命令或发生的碰撞而变化)
  • 与划分机器人或将它们组合(如果可能),添加食物和其他功能以维护游戏世界有关的计算。
  • 当然,还可以在游戏滴答声中向机器人发送和接收数据。

这样的服务器称为“命令”。 也就是说,所有操作都在服务器端进行,从而消除了数据同步问题。 客户(阅读机器人程序)仅会像其他竞争对手一样,收到一副现成的世界图片,这里实现了机器人程序位置的平等,没有优先级和队列。 同样,机器人的坐标发生在服务器上,例如,机器人发出了移动指令,并且只有在下一个Tick时才会识别其新坐标,而新坐标并不总是与团队一致,作为一种选择,游戏墙的形式是障碍物。


来自组织者网站的图片



我们已经弄清了如何通过机器人和管理服务器读取数据,现在让我们看一下机器人设备的深度。


正如读者可能已经理解的那样,将很少的文字和大量的工作,反之亦然。
该机器人由神经网络控制。 简短而宽敞,但尚不完全清楚。


神经网络的选择及其实现技术。


目前,我们认为神经网络对我们来说是一个具有输入和输出的黑盒子。


我们的输入和输出将是一维数组,输入的维数为N = 16,输出的维数为M = 4。



由于人工神经网络的性质是从自然神经网络粗略复制而来的,因此使输入数据的结构更接近自然数据对我们来说是有好处的。 本质上,各种传感器对此负责。 因此,请坚持使用机器人传感器。


通过实验选择了以下选项(图片简化为8个传感器和4x3神经网络,但这只是让我的读者感到困惑):



机器人的视野分为相等(可能甚至不相等)的扇区。 每个扇区向神经网络的输入之一提供信号。 因此,如果我们将漫游器周围的区域划分为16个扇区(360/12 = 22.5度扇区总览),我们将获得16个神经网络输入。 通常,将-1到1范围内的信号应用于神经网络的输入,因此有必要对输入信号进行归一化。


简化了比例分配,将总信号除以其最大可能值。 当然可以进行动态归一化,即每次搜索最大值并使信号值达到其范数,但是我们将以一个常量的形式设置最大值,该常量等于一个扇区中对象的最大数量,并且不会在机器人上工作的过程中对其进行更改。


信号可以是正值也可以是负值,我们同意从0到1的信号值是机器人的正动机(食物,较小机器人的食物),从-1到0的负信号值是机器人的负动机(墙壁游戏世界,另一个更大的机器人)。


画图



来自扇区的信号是归一化的数量,由各个信号的总和组成。 如前所述,每个信号都有一个符号和大小。 信号的大小定义为距离的比例函数。 最小距离是定义漫游器的圆边界;最大距离是漫游器可见性的边界。 因此,如果我们从例如仅以最大距离进入该区域的食物接收到正信号,则该信号将很弱,并且如果机器人接近食物,则该信号将增加。


扇区形式的传感器最适合这种情况,但可能只是探头天线,这就是幻想。 当然,作者尝试了将选项从4个扇区划分为72个扇区的各种方法,但是实践表明,神经网络在16个扇区中训练得非常成功,即使在四个扇区的情况下,也可以控制机器人。 这里体现了神经网络本质的灵活性。


最后,使用了神经网络训练一词 。 但是到目前为止,我们认为神经网络是一个带有输入和输出的黑匣子,并且由于我们分析了输入数据,因此关于该框的输出数据或信号,如何处理以及如何处理它们尚需说几句话。


我们将输出信号的维数设置为4。该数字表示笛卡尔坐标和极坐标的二元性。 作者并没有忘记阅读者知识的本质,因此以他曾经习得的知识的图画来提醒他。



因此,服务器开发人员在逻辑上使用极坐标来模拟游戏世界,并且机器人及其开发人员会礼貌地提供笛卡尔坐标。 因此,作者必须在此坐标系中选择一个边。 对于神经网络,只包含向量的大小(读取长度)及其偏离角度的极坐标系更容易理解。 毕竟,您还理解“向右转”一词,而不是沿纵坐标移动两步,而沿横坐标移动三步。


因此,有4个输出信号,其中2个关于增加或减小机器人速度矢量的角度的信号,另外2个正在增加或减小速度矢量的大小。
但是由于游戏服务器要求发出命令以笛卡尔坐标控制机器人,因此有两个公式将极坐标转换为笛卡尔坐标,所有这些耻辱都摆在了他们的位置(这是类似于c#的伪代码)。


float rotate1 = outputs[0]; float rotate2 = outputs[1]; float speed1 = outputs[2]; float speed2 = outputs[3]; if (rotate1 > 0.65 && rotate2 < 0.65) angle = angle + 35 * PI / 180; if (rotate1 < 0.65f && rotate2 > 0.65) angle = angle - 35 * PI / 180; if (speed1 > 0.65 && speed2 < 0.65) speed = speed + 2; if (speed1 < 0.65 && speed2 > 0.65) speed = speed - 2; dx = speed * Cos(angle); dy = speed * Sin(angle); 

信号就像机器人一样就位。 似乎他们给了他输入信号,但在输出时,没有什么值得的:它站立或随机移动。


因此,它来打开黑匣子并向里看。


待续。


但是在新的预告片系列之前:


神经网络上的紫色bot在Local Runner中与组织者默认将其缝入的标准bot相对。


Source: https://habr.com/ru/post/zh-CN417311/


All Articles