社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  机器学习算法

自动驾驶算法—利用深度学习进行端到端运动规划

机器人规划与控制研究所 • 9 月前 • 137 次点击  

过去几个月,我对自动驾驶汽车技术非常感兴趣。你可以将机器学习知识应用于开发自动驾驶汽车堆栈的各个部分,这有无数种可能性。

在这篇文章中,我将带您了解为自主机器人开发端到端运动规划器的过程。这个项目深受comma.ai在open pilot中使用的方法的启发。

自动驾驶的不同方法

开发自动驾驶汽车软件的方法有很多种。模型可以采用端到端训练,也可以采用中间到中间方法训练。以下是一些示例:

  • 端到端行为克隆在这种方法中,CNN 是端到端训练的。输入是一系列图像或单个图像,输出直接是转向角。当 Nvidia 大规模训练这种类型的神经网络时,这种方法变得流行起来。相关博客可以在这里找到。我也致力于实现许多类似的模型。repo 的链接可以在这里找到。它包含训练这些模型的分步过程,其中一些是:Nvidia 的模型、Comma AI 的模型、3D CNN、LSTM。这种方法很容易实现,因为模型几乎可以在内部学习所有内容,我们不必实现传统的控制堆栈、定位器、规划器等。但缺点呢?你失去了对模型输出的完全控制,无法解释人类理解的结果(完全黑匣子),难以结合先验知识。


图像输入,控制输出


  • 中间到中间:在这种方法中,网络不是直接输出控制,而是被分解成任意多个部分。例如,训练单独的网络进行物体检测、运动预测、路径规划等。Lyft、Tesla 等都采用了这种方法。下面显示了 Lyft 如何检测其他车辆、将它们放置在周围环境的语义地图上,并预测所有其他事物的运动,其结果将进一步传递给控制器,最终产生转向、油门等输出。


来自 Lyft 的 2020 年运动预测挑战赛


这种方法的缺点是,错误会通过多个步骤不断累积,将所有部分组合在一起会变得困难得多。但另一方面,优点是,这个过程完全可以被人类解释,并且可以轻松推理自动驾驶汽车的决策。除此之外,现在还可以结合先验知识。

  • Comma 的方法: Comma 跳过物体检测、深度估计等,直接输出车辆要遵循的轨迹。然后,该路径由其团队维护的常规控制堆栈跟踪。


理解超级组合模型


超级组合模型制作精良,但重量轻,其输入如下:

  • 2连续的 YUV 格式图像帧

  • 循环细胞 的状态(循环神经网络)

  • 望(稍后讨论)

并预测以下输出:

  • 路径(要遵循的轨迹输出)

  • 左车道

  • 右侧车道

  • 路径和车道的标准偏差(如下所述)

  • 领先车辆信息

  • 未来 n 步的纵向加速度、速度和位移

  • 姿势(如下所述)

  • 还有一些我不太确定的东西

        路径、左车道和右车道是相对于本车辆的“预测轨迹”和自上而下/鸟瞰坐标系中的车道线

超级组合的路径和车道输出

看看模型如何预测右侧道路的曲线。

这里要注意的另一件事是,当看不到车道线时,或者当模型对其预测不太有信心时,车道线也会消失。这个“信心”分数基本上也是由模型预测的,只是“标准偏差”。这些标准偏差是针对每条路径、左车道和右车道以及许多其他输出(包括姿势、领先输出等)预测的。

可以使用贝叶斯神经网络来预测标准差,该网络在计算预测时将不确定性传递到整个网络。

姿态输出是两个输入图像之间预测的平移和旋转。这可能用于执行视觉里程计并根据输出轨迹定位汽车。

数据创建


在考虑训练神经网络之前,我们需要收集数据并将其处理成适合训练的格式。Comma.ai 发布了开源数据集,其中包含大量此类信息,如车道、路径和其他内容。但我想要更多的挑战,所以决定使用 Udacity 的数据集,它只包含:

  • 转向角

  • 速度

  • 陀螺仪读数

  • GPS 读数

  • 来自中心、左侧和右侧安装的摄像机的图像框架。

为了训练自定义模型,我决定只预测未来的路径和速度。

欲望


希望基本上对高级动作进行独热编码,例如“左变道”、“右变道”、“保持在车道内”、“右转”、“左转”等。

Udacity 数据集不包含任何“愿望”。因此需要手动标记 10,000 帧 :(

手动标记 10,000 个帧并不容易。因此,我没有单独标记每个帧,而是为此创建了一个小工具Autolabler


使用这个,我的朋友 Raghav 在 30 分钟内标记了整个数据集。它更像是一个小型视频播放器,您可以根据需要暂停、搜索、快进、减慢输入帧流。它会在播放流时不断动态标记所选标签。有关使用它的完整说明可以在我的repo中找到。


小路

对于轨迹地面实况,我只能使用 udacity 数据集中存在的信息。

首先,我使用了一个简单的自行车模型,通过速度和转向角输入到车辆模型中,随着时间的推移,该模型逐渐变化。

在低速时,使用以质心为参考系的简单自行车模型。

以汽车重心为参考的自行车模型

模型参数


我本可以使用动态模型进行横向控制,但我实际上没有用于收集数据集的车辆参数数据。

现在,可以肯定的是,上述模型非常简单,无法很好地模拟车辆的实际物理特性,因此使用来自陀螺仪和 GPS 的额外数据并将其与卡尔曼滤波器融合在一起绝对有意义。此外,开发算法的另一条规则是,永远不要丢弃任何数据,即使它非常嘈杂。找到整合来自其他数据源的任何信息的方法。这只会改进算法。

幸运的是,GPS 模型是已知的,所以我能够构建卡尔曼滤波器。


不同的跟踪方法的实际应用


观察一段时间后过程模型(红色)如何开始偏离原始轨迹。

我使用了 3 种跟踪方法,并使用卡尔曼滤波器将它们结合在一起。

  • 自行车模型作为流程模式

  • GPS 读数

  • 于 IMU 的里程计

  • 觉里程计

我发现的一个困难是确保所有读数都转换为具有相同参考(汽车)的同一坐标系。例如,对于 GPS 读数,必须将纬度和经度转换为以米为单位的 XY 网格系统。

对于较小的距离,我使用以下公式作为近似值来找到两个纬度经度对之间的距离(以米为单位)。纬度和经度基本上是地球仪上(角度)相对于赤道和本初子午线的测量值。



def latlon_to_xy_grid(lat1, lon1, lat2, lon2):     dx = (lon1-lon2)*40075*math.cos((lat1+lat2)*math.pi/360)/360    dy = (lat1-lat2)*40075/360    return dx, dy

现在,为了收集额外的数据,包括避开障碍物、急转弯和“汽车偏离车道”问题等情况,我使用了 CARLA 模拟器。

紧密的曲线


由于我掌握了用于收集 udacity 数据集的相机的参数,因此我能够在 CARLA 中设计类似的相机模型。从 CARLA 获取真实数据相对容易。

此外,为了避开障碍物,我编写了一个脚本,该脚本可以创建一个场景,将车辆放置在车道边缘,并使用 CARLA 自动驾驶仪生成轨迹以避开障碍物。编写脚本几分钟后,我就有了数千个此类场景。这实际上可能会使模型在现实生活中变得更糟,因为这可能与人类在现实生活中实际做的事情并不接近。



呃,看上去不错?


CARLA 将数据直接保存到磁盘的方式存在一些问题。这导致模拟器速度大幅下降,无法手动控制汽车,也导致数据收集过程变慢。

因此,我必须编写手动缓冲区,以便不断积累数据,直到达到一定大小,然后立即将其转储到磁盘。这极大地提高了数据收集过程的效率。


从数据集中采样的一组轨迹


现在数据收集过程终于完成了。让我们开始模型训练吧!


分析超级组合模型


特征提取器的一部分


对于从帧中提取特征,超级组合使用了大量跳过连接并转换 256 x 128 x 12(两个 YUV 格式的连续帧,带有 3 个额外的 alpha 通道。参见此处)并将它们归结为 1024 维编码。

一旦训练路径规划器,这种编码就会从图像中学习所有信息。


博客文章


“通过在图像上运行视觉模型并尝试使用 GAN 从中重建图像,我们可以深入了解视觉模型的 1024 个输出向量中编码的内容。上图是道路的原始图像,下图是通过几百万张图像和特征向量训练的 GAN 进行的重建。请注意,与规划相关的细节(例如车道和领头车的位置)是如何保留的,而无关的细节(例如汽车的颜色和背景风景)则丢失了。”—— Harald Schäfer

该模型学习将规划所需的所有相关信息编码为压缩形式。此视觉编码随后被分成几个分支,这些分支被独立处理以输出车道、路径等。


分叉成分支


Super Combo 还使用类似 GRU 的层来编码时间信息。网络是有状态的,循环层的状态输出在下一次推理期间被重新输入。

训练模型


为了训练模型,我将以愿望和帧作为输入(RNN 状态仅在推理时间内提供),输出仅仅是未来 50 米/步的路径和速度以及标准差。

贝叶斯神经网络


标准差让我们了解模型对其预测的信心程度。这可以使用一种称为贝叶斯神经网络的特殊网络来实现。

我们不会直接回归车道、路径和速度,而是预测分布。

来源 — https://www.youtube.com/watch?v=z7xV-HYVAZ8


请观看 AI 学生的这段视频,了解对此的精彩解释。

我们可以使用混合密度网络来输出多条路径及其置信度分数,将其转换为混合密度网络。

输出多个高斯分布及其分数、alpha。


我使用批量大小为 16 且包含过去的 16 个时间步骤以及 2 个高斯混合来训练网络。

数据增强


我使用数据增强来使模型对噪声具有鲁棒性。这些包括向图像添加泊松噪声、打乱图像的颜色通道、水平翻转图像、增加/减少图像的对比度、温度等。

数据增强


损失函数


简单点输出(无不确定性 预测):在实际应用中,我们最小化线性函数 μ 的输出的平方误差项 ( μ( x , Θ )− y )²,给定x、其参数Θ和某个数据集 𝔻 中所有 ( x , y ) 对的目标值y。学习函数本质上是在给定数据和参数的情况下“输出”高斯分布 μ( x , Θ ) 的条件均值。它会丢弃与Θ无关的标准差和归一化常数。

我尝试了多种损失函数。对于简单回归输出(如上所述)(简单神经网络,无标准偏差输出),我使用了轨迹之间的 L2 损失和轨迹梯度之间的 L1 损失的加权和。

梯度损失背后的直觉是,我们人类会根据道路上的曲线来估计转动方向盘的“强度”。因此,将其纳入损失函数是有意义的,结果发现它比“仅在轨迹之间使用简单的 L2”表现更好。

MDN 网络:在这种情况下,标准差现在取决于输入,这使我们能够考虑可变的标准差。即使我们只使用单个高斯分布,这一优势也适用。

对于 MDN(也预测标准差),损失计算如下

cat = tfd.Categorical(logits=out_pi)        component_splits = [output_dim] * num_mixes        mus = tf.split(out_mu, num_or_size_splits=component_splits, axis=1)        sigs = tf.split(out_sigma, num_or_size_splits=component_splits, axis=1)        coll = [tfd.MultivariateNormalDiag(loc=loc, scale_diag=scale) for loc, scale in zip(mus, sigs)]mixture = tfd.Mixture(cat=cat, components=coll)        loss = mixture.log_prob(y_true)        


    
loss = tf.negative(loss)        loss = tf.reduce_mean(loss)

我使用了来自这个repo 的实现

(https://github.com/cpmpercussion/keras-mdn-layer)


测试

看看网络如何输出均值(实际路径)和偏差。

最初,模型对预测很有信心,偏差也很低,但随着模型预测未来的轨迹,偏差会增加,这是直观的。



甚至 openpilot 模型也表现出类似的行为。


原始 openpilot 模型中的路径和车道


看看模型在较短距离时如何相当自信,但在较远距离时预测会变得更加嘈杂和不稳定。

我会进行更严格的测试,并很快会发布一个模型运行的视频,既适用于现实生活,也适用于合成数据。现在我们有了轨迹输出,在下一篇文章中,我们可能会讨论如何将轨迹实际转换为控制并控制模拟汽车。但这将需要做很多工作。但让我们尝试一下吧:D

结论

恭喜你读到了最后!这是一篇很长的文章。

因此,这是我训练端到端路径规划器的旅程,这在很大程度上受到了 comma.ai 工作的启发。我想感谢 comma.ai discord 社区解答了我的许多疑问。我不保证这篇文章中的所有内容都是正确的。请随时指出您可能发现的任何错误,并通过下面的评论来帮助纠正它们。

我在这个项目中探索了很多东西。我并没有在这篇文章中深入讨论太多细节,因为我错过了写我在这个项目中遇到的很多挑战。下次,我会尝试将这篇文章并排写出来,这样我就不会忘记添加任何东西。


更多信息请参见原文地址:

https://mankaran32.medium.com/end


    
-to-end-motion-planning-with-deep-learning-comma-ais-approach-5886268515d3



    

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/171527
 
137 次点击