共计 3203 个字符,预计需要花费 9 分钟才能阅读完成。
卷积神经网络 (CNN) 是解决图像分类、宰割、指标检测等工作的风行模型。本文将 CNN 利用于解决简略的二维门路布局问题。次要应用 Python, PyTorch, NumPy 和 OpenCV。
工作
简略地说,给定一个网格图,二维门路布局就是寻找从给定终点到所需指标地位(指标)的最短门路。机器人技术是门路布局至关重要的次要畛域之一。A、D、D* lite 和相干变体等算法就是为解决此类问题而开发的。现在强化学习被宽泛用于解决这一问题。本文将尝试仅应用卷积神经网络来解决简略的门路布局实例。
数据集
咱们的次要问题是(在机器学习中判若两人)在哪里能够找到数据。尽管没有现成的数据集可用,然而咱们能够通过制作随机二维地图创立本人的门路布局数据集。创立地图的过程非常简单:
从一个 100×100 像素的方形空矩阵 M 开始。
对于矩阵中的每一项(像素),从 0 到 1 均匀分布抽取一个随机数 r。如果 r > diff,则将该像素设置为 1;否则,将其设置为 0。这里的 diff 是一个参数,示意像素成为障碍物(即无奈穿梭的地位)的概率,它与在该地图上找到可行门路的难度成正比.
而后让咱们利用形态学来取得更相似于实在占用网格地图的“块状”成果。通过扭转状态构造元素的大小和 diff 参数,可能生成具备不同难度级别的地图。
对于每张地图须要抉择 2 个不同的地位:终点 (s) 和起点 (g)。该抉择同样是随便的,但这次必须确保 s 和 g 之间的欧几里得间隔大于给定阈值(使实例具备挑战性)。
最初须要找到从 s 到 g 的最短门路。这是咱们训练的指标。所以能够间接应用了风行的 D* lite 算法。
咱们生成的数据集蕴含大概 230k 个样本(170k 用于训练,50k 用于测试,15k 用于验证)。数据量很大,所以我应用 Boost c++ 库将自定义的 D lite 重写为 python 扩大模块。应用这个模块,生成超过 10k 个样本 / 小时,而应用纯 python 实现,速率约为 1k 个样本 / 小时(i7–6500U 8GB 内存)。自定义 D lite 实现的代码会在文末提供
而后就是对数据做一些简略的查看,比方删掉余弦类似度很高,终点和起点坐标太近的地图。数据和代码也都会在文末提供.
模型架构
模型是经典的编码器 - 解码器架构,将 20 个卷积层分为 3 个卷积块(编码局部),而后是另外 3 个转置卷积块(解码局部)。每个块由 3 个 3×3 卷积层组成,每个层之间有 BN 和 ReLU 激活。最初,还有另外 2 个 conv 层,加上输入层。编码器的指标是找出输出压缩后的相干示意。解码器局部将尝试重建雷同的输出映射,但这次嵌入的有用信息应该有助于找到从 s 到 g 的最佳门路。
该网络的输出是:
map:一个 [n, 3, 100, 100] 张量,示意占用网格图。n 是批量大小。这里的通道数是 3 而不是简略的 1。稍后会具体介绍。
start: 一个 [n, 2] 张量,蕴含每个地图中终点 s 的坐标
goal:一个 [n, 2] 张量,蕴含每个地图中指标点 g 的坐标
网络的输入层利用 sigmoid 函数,无效地提供了一个“分数图”,其中每个我的项目的值都在 0 和 1 之间,与属于从 s 到 g 的最短门路的概率成正比。而后能够通过从 s 开始并迭代地抉择以后 8 邻域中得分最高的点来重建门路。一旦找到与 g 具备雷同坐标的点,该过程就会完结。为了提高效率,我为此应用了双向搜索算法。
在模型的编码器和解码器块之间,我还插入了 2 个跳过连贯。该模型当初十分相似于 U-Net 的架构。跳过连贯将给定暗藏层的输入注入网络中更深的其余层。在咱们的工作中关怀的细节是 s、g 的确切地位,以及咱们在轨迹中必须避开的所有障碍物。所以退出跳过链接大大提高了成果。
训练
在 Google Colab 上对模型进行了大概 15 小时或 23 个周期的训练。应用的损失函数是均方误差 (MSE)。可能有比 MSE 更好的抉择,但我始终保持应用它,因为它简略易用。
学习率最后应用 CosineAnnealingWithWarmRestarts 调度程序设置为 0.001(稍微批改以升高每次重启后的最大学习率)。批量大小设置为 160。
我尝试对输出图利用高斯含糊,并在第一个卷积层利用一个小的 dropout。这些技术都没有带来任何相干成果,所以我最终放弃了它们。
上面是训练后模型原始输入的可视化。
卷积的一些问题
起初应用输出是一个形态为 [n, 1, 100, 100](加上起始地位和指标地位)的张量。但无奈取得任何令人满意的后果。重建的门路只是齐全偏离指标地位并穿过障碍物的随机轨迹。
卷积算子的一个要害特色是它是地位不变的。卷积滤波器学习的实际上是一种特定的像素模式,这种像素模式在它所训练的数据分布中重复呈现。例如上面的图案能够示意角或垂直边缘。
无论过滤器学习什么模式,要害的问题是它学会独立于图像中的地位来辨认它。对于像图像分类这样的工作来说,这无疑是一个现实的个性,因为在这些工作中,表征指标类的模式可能呈现在图像的任何中央。但在咱们的状况下,地位是至关重要的! 咱们须要这个网络十分分明的晓得轨迹从哪里开始,从哪里完结。
地位编码
地位编码是一种通过将数据嵌入 (通常是简略的和) 到数据自身中来注入对于数据地位的信息的技术。它通常利用于自然语言解决 (NLP) 中,使模型意识到句子中单词的地位。我想这样的货色对咱们的工作也有帮忙。
我通过在输出占用图中增加这样的地位编码进行了一些试验,但成果并不好。可能是因为通过增加对于地图上每个可能地位的信息,违反了卷积的地位不变性,所以滤波器当初是无用的。
所以这里基于对门路布局的察看,咱们对相对地位不感兴趣,而只对绝对范畴感兴趣。也就是说,咱们感兴趣的是占用图中每个单元格绝对于终点 s 和指标点 g 的地位。例如,以坐标 (x, y) 为单元格。我并不真正关怀 (x, y) 是否等于 (45,89) 还是 (0,5)。咱们关怀的是(x, y) 间隔 s 34 格,间隔 g 15 格。
所以我为每个占用网格图创立 2 个额定的通道,当初它的形态为[3,100,100]。第一个通道是图像。第二个通道示意一个地位编码,它为每个像素调配一个绝对于起始地位的值。第三通道则是绝对于完结地位的值。这样的编码是通过别离从以 s 和 g 为核心的二维高斯函数创立 2 个特色映射来实现的。Sigma 被选为核大小的五分之一(通常在高斯滤波器中)。在咱们的例子中是 20,地图大小是 100。
在注入对于冀望的轨迹起始和最终地位的有用信息的同时,咱们还局部地保留了与过滤器地位不变性的一致性。可学习的模式当初只依赖于绝对于给定点的间隔,而不是地图上每个可能的地位。间隔 s 或 g 雷同间隔的 2 个相等的图案当初将触发雷同的过滤器激活。通过试验这个小技巧在收敛训练中十分无效。
后果和论断
通过测试了超过 51103 个样本的训练模型。
95% 的总测试样本可能应用双向搜寻提供解决方案。也就是说,该算法应用模型给出的得分图能够在 48556 个样本中找到从 s 到 g 的门路,而对于其余 2547 个样本则无奈找到。
总测试样本的 87% 提供了无效的解决方案。也就是说从 s 到 g 的轨迹不穿梭任何障碍物(该值不思考 1 个单元格的障碍物边缘束缚)。
在无效样本上,实在门路与模型提供的解决方案之间的平均误差为 33 个单元格。思考到地图是 100×100 单元格,这是相当高的。谬误范畴从最小 0(即,在 2491 个样本中的实在门路被“完满”的重建了)到最大……745 个单元(这个必定还有一些问题)
上面能够看看咱们测试集中的一些后果。图像的左侧形容了训练过的网络提供的解决方案,而右侧显示了 D * lite 算法的解决方案。
咱们网络提供的解决方案比 D * lite 给出的解决方案短
上面就是一些谬误的图
看着应该是感触野不太大,所以在感触野的区域内没有找到任何的边缘,这个可能还要再改良模型
最初,这项工作远非最先进的后果,如果你有趣味的话能够持续改良。
https://avoid.overfit.cn/post/c595e81d1dea445187d17ccfca3cf79b
作者:Davide Caffagni