自由空间分割
ISAAC教程合集地址: https://blog.csdn.net/kunhe0512/category_12163211.html
文章目录
- 自由空间分割
- 快速开始
- 推理
- 训练
- 数据
- 模拟数据
- 设置与模拟器的通信
- 来自公共数据集的真实数据
- 具有自主数据收集的自由空间分割的真实数据
- 自主数据收集
- 通过地图规划路径
- 监测机器人位移
- 数据标注
- 估计
- 运行应用程序
- 网络架构
- 训练网络
- 多GPU训练
- 消息类型
- Codelets
自由空间深度神经网络 (DNN) 的目标是将图像分割成感兴趣的类别,例如可驾驶空间和障碍物。 DNN 的输入是单目图像,输出是逐像素分割。 该软件包可以轻松地在模拟中训练自由空间 DNN 并使用它来执行真实世界的推理。 虽然这个模块化包可以为各种应用程序提供动力,但本文档说明了室内自由空间分割和室外人行道分割的工作流程。
本文档首先介绍如何快速开始推理和训练。 有关数据源、网络架构、多 GPU 训练和应用程序布局的详细信息将在后面介绍。
自由空间分割的一个潜在用例是使用单目相机避障。 机器人环境的成本图或障碍物图可以从各种来源创建,例如激光雷达和来自相机的深度信息。 融合来自不同传感器的信息可以微调成本图并使机器人的避障更加稳健。 路径分割模型确定的自由空间可以投影到现实世界坐标系上,作为避障的输入信息。
快速开始
推理
首先,输入以下命令:
bob@desktop:~/isaac/sdk$ bazel run packages/freespace_dnn/apps:freespace_dnn_inference_image -- --config inference:packages/freespace_dnn/apps/freespace_dnn_inference_medium_warehouse_tensorrt.config.json
然后在 http://localhost:3000/ 打开 Sight Web 界面。 您应该看到在仓库中使用用于多类分割的预训练模型对样本图像执行推理。 左边的绿色、黄色、蓝色和红色分别代表地板(自由空间)、障碍物、墙壁和车道线。
提示
要使用 TensorFlow 而不是 TensorRT 执行推理,请在上面的命令中使用 freespace_dnn_inference_medium_warehouse_tensorflow.config.json
文件而不是 freespace_dnn_inference_medium_warehouse_tensorrt.config.json
文件。 结果应该看起来一样,但 TensorRT 提供了更好的性能。
要使用针对室内训练的模型执行推理,请将 freespace_dnn_inference_image.app.json
文件中的 color_filename 参数更改为 ./external/path_segmentation_images/sidewalk1.png
并运行以下命令:
bob@desktop:~/isaac/sdk$ bazel 运行 packages/freespace_dnn/apps:freespace_dnn_inference_image -- --config inference:packages/freespace_dnn/apps/freespace_dnn_inference_sidewalk_tensorrt.config.json
在 Sight 中,您应该会看到使用用于人行道分割的预训练模型对样本图像执行推理。 左边的绿色、黄色、蓝色和红色分别代表道路、路缘、人行道和草地。
要使用针对室内训练的模型执行推理,请将 freespace_dnn_inference_image.app.json 文件中的 color_filename 参数更改为 ./external/path_segmentation_images/indoor1.png 并运行以下命令:
bob@desktop:~/isaac/sdk$ bazel 运行 packages/freespace_dnn/apps:freespace_dnn_inference_image -- --config inference:packages/freespace_dnn/apps/freespace_dnn_inference_indoor_tensorflow.config.json
这次,自由空间和其他空间分别用黑色和红色表示。
如果我们查看上面使用的应用程序文件,它位于 packages/freespace_dnn/apps/freespace_dnn_inference_image.app.json,它的结构非常简单。 推理子图被提供一个图像,该图像是从 color_filename 参数指定的路径中读取的。 有四个应用程序位于 packages/freespace_dnn/apps/。 您可以通过简单地更改下表中列出的图像源来使用它们:
Application Name | Image source |
---|---|
freespace_dnn_inference_image | Image on disk |
freespace_dnn_inference_replay | Video on disk |
freespace_dnn_inference_v4l2 | Camer |
freespace_dnn_inference_unity3d | Simulation with Unity3D |
通过使用推理子图并添加所需的组件(如机器人车轮驱动器和避障),可以创建各种其他应用程序。
要在 Unity 场景中使用推理应用程序,您还必须提供定义相机传送参数的配置文件。 您可以通过在运行应用程序时将路径传递给配置文件来执行此操作。 例如,使用仓库场景运行推理应用程序的命令为:
bob@desktop:~/isaac/sdk$ bazel run packages/freespace_dnn/apps/freespace_dnn_inference_unity3d -- --config inference:packages/freespace_dnn/apps/freespace_dnn_inference_medium_warehouse_tensorrt.config.json,packages/freespace_dnn/apps/freespace_dnn_inference_unity3d_medium_warehouse.config.json
训练
要开始训练,请键入以下命令:
bob@desktop:~/isaac/sdk$ bazel run packages/freespace_dnn/apps:freespace_dnn_training
这将启动一个 TensorFlow 实例并使用通过 TCP 接收的标记图像对其进行训练。
正如后面解释的那样,标记图像可以来自使用 Isaac SDK 或公共数据集捕获和标记的真实数据,但我们鼓励对“无限”标记数据进行模拟训练。
Isaac 目前支持 Unity 3D 引擎来训练自由空间 DNN。 要在 Unity 3D 中进行模拟训练,请运行以下命令启动中型仓库场景的场景 3:
bob@desktop:/<isaac_sim_unity3d_binary_dir>$ ./sample.x86_64 --scene medium_warehouse --scenario 3
场景加载后,您可以按“C”键禁用主摄像头。 这会增加模拟帧速率,从而加快数据生成速度。
训练开始后,Tensorflow 会定期输出日志和检查点,默认情况下会输出以下文件到/tmp/path_segmentation:
-
.meta 文件:表示模型的图结构。
-
.data 文件:存储所有已保存变量的值。
-
.index 文件:存储变量名称和形状的列表。
要查看 Tensorboard 上的训练进度,请运行以下命令并在浏览器中打开 http://localhost:6006。
tensorboard --logdir=/tmp/path_segmentation
训练完成后,使用以下命令将最近的检查点序列化为 protobuf 文件:
bob@desktop:~/isaac/sdk$ python3 packages/freespace_dnn/apps/freespace_dnn_training_freeze_model.py --checkpoint_dir /tmp/path_segmentation --output_nodename prediction/truediv --output_filename model.pb --output_onnx_filename model.onnx
使用生成的 model.onnx 文件,创建一个类似于 packages/freespace_dnn/apps/freespace_dnn_inference_medium_warehouse_tensorrt.config.json 文件的配置文件。 您现在可以执行推理了。
数据
模拟数据
能够通过模拟生成无限的数据点是一项强大的资产,弥合了将模拟机器人技术与真实实验分开的“现实差距”。 模拟器提供了使这成为可能的各种功能,即域随机化和隐形传态。
域随机化试图通过提高无偏数据的可用性来弥合现实差距。 域随机化训练数据使模型在推理过程中对不同光照条件、地板纹理和视野中的随机对象的响应更加稳健。
可以通过多种方式实现域随机化:
-
灯光随机化:改变灯光的颜色和强度
-
材料随机化:在所需表面上应用不同的物质材料
-
纹理随机化:对材质应用不同的纹理
-
颜色随机化:对材料应用不同的颜色
-
材料属性:改变材料属性,例如粗糙度、金属度和镜面反射度。 这可以改变表面的摩擦、反射和折射特性以及其他特性。
Teleportation 允许您在一定范围内(平移和旋转)随机采样相机姿势,以从不同的高度和角度捕获数据。
设置与模拟器的通信
Isaac SDK 和模拟器使用发布/订阅架构进行通信:通过在创建数据的一侧设置 TCP 发布者并在数据摄取的一侧设置 TCP 订阅者,数据在两个进程之间来回传递。
对于Unity 3D模拟,发布ground truth数据的应用是packages/navsim/apps/navsim.app.json。 这是由 NavSim 中的 medium_warehouse 场景直接加载的。
应用程序使用 TcpPublisher 将传感器数据发布到用户定义的端口。 此数据由训练应用程序使用。 训练应用程序依次向 NavSim 应用程序发送传送命令,这些命令通过 TcpSubscriber 节点接收。
使用 Substance 的域随机化在 Unity 场景中默认可用。 这允许您将不同的材质应用于场景中的网格,将随机姿势应用于演员等。地面被标记为“地板”,每像素索引为 1。
来自公共数据集的真实数据
MSCoco 和 ADE20K 等数据集为多个类别提供按像素分割的数据。 路径分割的相关类别包括人行道、道路、地毯、地球、地面和多种类型的地板。 这些图像是在具有多个摄像机角度和遮挡度的各种环境中捕获的,使它们成为训练具有更好泛化能力的模型的良好候选者。 MSCoco 和 ADE20K 都被用于训练室内自由空间的二元分割模型。
具有自主数据收集的自由空间分割的真实数据
Isaac 提供了从现实中自主创建数据以训练模型以检测可穿越地面空间的方法。
自主数据收集
使用机器人进行自主数据收集是在真实条件下引入训练数据的好方法。 这可以大致分为 2 个工作流程:
-
通过地图规划路径
-
监测机器人位移
通过地图规划路径
-
TravellingSalesman:此小代码在地图中可自由穿越的空间上绘制路径点并计算最短路径。 每个航路点表示地图上的一个二维点。
注意
TravellingSalesman路径仅反映通过路点的图形路径。 它没有考虑空间的可达性,并且在可视化时可能会在无法到达的区域上绘制路径。
-
MoveAndScan:这将 2D 航路点列表作为输入并将它们扩展为包括多个方向。 每个 2D 位置包含的方向数是用户定义的。 因此,如果地图中有 N 个航路点和 M 个方向,则输出是一个包含 NxM 个姿势的列表。
-
FollowPath:这将姿势列表作为输入,并将每个姿势(或路径点)作为目标发布到 GoTo codelet。 这使机器人能够按顺序移动到每个路点。
监测机器人位移
-
NavigationMonitor:持续监控机器人的线性和角位移。 如果位移大于用户定义的阈值,它会发布一条 RobotStateProto 消息,其中包含自上次更新以来的当前位姿、当前速度和位移。 在这种情况下,NavigationMonitor codelet 主要充当信号来调节记录器功能何时可以记录一对原型消息。
-
Throttle:相对于另一个信号调节一个信号。 在这种情况下,它根据 NavigationMonitor 的 RobotStateProto 输出调节相机输入。 Throttle 组件的主要目的是确保定期收集数据,以防止日志大小过快膨胀。
数据标注
手动执行数据注释是一项耗时的任务,尤其是在需要每个像素标签的语义分割的情况下。 为现实中收集的数据自动执行此过程可以节省大量时间。
估计
-
RgbdSuperpixels:使用单通道聚类算法计算 RGB-D 图像的超像素聚类,该算法根据颜色和深度的相似性将每个像素分配给局部聚类。
-
RgbdSuperpixelFreespace:将每个超像素标记为自由空间或障碍物。 假设地平面符合等式 Z = 0,超像素将转换为地坐标系。
-
SuperpixelImageLabelling:基于超像素标签创建原始相机的像素分割。
运行应用程序
位于 apps/carter/autonomous_data_collection/carter_data_collection.app.json 的应用程序可用于使用配备英特尔实感摄像头的 Carter 机器人从映射环境中收集颜色和深度图像。 此参考应用程序可用作其他应用程序的基础。 要收集数据,请通过运行以下命令将应用程序部署到 Carter 机器人:
bob@desktop:~/isaac/sdk$ ./../engine/engine/build/deploy.sh -h <robot_ip> -p //apps/carter/autonomous_data_collection:carter_data_collection-pkg -d jetpack45 --remote_user <username_on_nano>
其中 <robot_ip>
是机器人的 IP 地址,<username_on_robot>
是您在机器人上的用户名。 如果未使用 --remote_user 选项指定用户名,则使用默认用户名“nvidia”。
部署后,按以下步骤运行应用程序:
-
登录机器人(通过 SSH)。
-
导航到部署应用程序的目录,默认情况下为 ~
/deploy/<user>
。 -
修改以下命令后运行应用程序:
机器人应在地图上绘制航路点图,导航到每个点,然后转一圈。 NavigationMonitor 小代码监视位移并仅在特定时间间隔启用日志记录。
转到位于 http://<robot_ip>:3000/
的 Sight Web 界面,然后单击记录控制面板上的记录。 这会将颜色和深度图像保存到文件中。
然后,您可以使用 packages/freespace_dnn/apps/freespace_dnn_data_annotation.subgraph.json 文件重放此日志以标记可遍历空间。 该子图产生地面真值数据,可以直接连接到训练子图。
网络架构
对于二进制分割,Isaac SDK 使用 U-Net,因为它满足以下条件:
-
它很容易在小型数据集上进行训练。
-
它能够在较短的推理时间内快速训练。
-
它支持 TensorRT 推理。
-
它具有兼容的许可证,因此可以完全集成到 Isaac SDK 中。
U-Net 是一个端到端的全卷积网络 (FCN)(即它只包含卷积层,没有密集层)。
U-Net 可以支持二分类和多分类。 唯一的区别在于最后一层的激活,它是用于二进制分割的 Sigmoid 和用于多类分割的 Softmax。
训练网络
多GPU训练
在多 GPU 主机系统上,并行处理所有 GPU 上的工作负载可能是一项强大的资产。 Tensorflow中的并行性可以分为两种类型:
-
数据并行性:数据分布在多个 GPU 或主机上。
-
模型并行性:模型本身分布在多台机器或 GPU 上。 例如,单个层可以装入单个机器(或 GPU)的内存中,前向和反向传播涉及将输出从一台主机(或 GPU)传送到另一台主机(或 GPU)。
Tensorflow 通过 MirroredStrategyModule 库支持数据并行,它在每个 GPU 上镜像模型图,因此可以在每个 GPU 上接受独立的数据集进行训练。
消息类型
消息有以下类型:
-
TensorProto:定义了一个 n 维张量,它构成了用于训练的图像和张量对的基础。
-
TensorListProto:定义了一个TensorProto消息列表,主要用来传递张量。
-
ImageProto:保存一个潜在的彩色图像。
-
CameraIntrinsicsProto:保存相机固有信息,包括针孔和畸变参数。
-
SegmentationCameraProto:持有包含图像中每个像素的类标签的图像。
Codelets
-
TcpSubscriber:训练应用程序使用它从模拟器接收数据。 此示例中使用了两个 TcpSubscriber,每个都从模拟中接收彩色图像和检测标签。
-
ColorCameraEncoderCpu:接受 ImageProto 并输出存储在 3D 张量 (WxHx3) 中的下采样图像。 张量作为仅包含一个张量的 TensorListProto 发布。 codelet 还支持下采样,将图像缩小到用户定义的更小尺寸。
-
SegmentationEncoder:接收一个 ImageProto 和一个 LabelProto 并输出一个 3D 张量 (WxHx1)。 该小码负责通过将 1.0 的概率分配给所考虑的类的通道索引并将 0.0 的概率分配给所有其他通道索引来对用于语义分割的标记数据进行编码。 张量作为仅包含一个张量的 TensorListProto 发布。
-
TensorSynchronization:接受两个 TensorListProto 输入并根据它们的获取时间同步它们。 此小代码确保训练代码获得同步的彩色图像和分割标签数据。
-
SampleAccumulator:接受训练对(图像张量和分割标签张量)作为 TensorListProto 并将它们存储在缓冲区中。 此小代码绑定到 Python 脚本,以便训练脚本可以使用 acquire_samples() 函数直接从该缓冲区中采样。 acquire_samples() 函数将 TensorListProto 转换为具有相应维度的 numpy 数组列表,并将其传递给 Python 脚本。
-
Teleportation:以预定义的方式发布 RigidBody3GroupProto 以随机更改生成位置。 它包括一个选项,用于提供样条参数以沿样条的切线执行均匀随机采样。
更多精彩内容:
https://www.nvidia.cn/gtc-global/?ncid=ref-dev-876561