使用DetectNetv2进行目标检测
Isaac SDK支持使用
DetectNetv2
进行对象检测的训练/推理管道。对于此管道,DetectNetv2利用ResNet主干特征提取器。ResNet是一个工业网络,可与MobileNet和InceptionNet(用于特征提取的两个常用主干模型)相提并论。NVIDIA
Transfer Learning Toolkit
(TLT)可用于训练,微调和修剪DetectNetv2模型以进行对象检测。
以下各节说明了如何:
-
从IsaacSim for Unity3D生成数据集图像。
-
在生成的数据集上训练预训练的DetectNetv2模型。
-
使用Isaac TensorRT推论小代码对各种输入进行推论。
TLT中模拟图像的训练
训练DetectNetv2模型涉及生成模拟数据,并使用TLT在此数据上训练模型。Isaac SDK提供了一个基于ResNet18的示例模型,已使用此管道对它进行了训练,以检测单个对象:下图所示的小车。以下分步说明介绍了如何训练该模型的过程。使用这些步骤作为指导来训练您自己的对象上的模型。
-
为Unity3D设置IsaacSim以生成模拟图像。
a. 打开示例场景以生成数据,可在中的
isaac_sim_unity3d
存储库中找到
packages/Nvidia/Samples/ObjectDetection/
。该示例场景可以生成具有随机背景,遮挡对象,光照条件和相机姿势的数据。
b. 在
程序>对象
GameObject 中生成
对象
。培训对象列表在中
packages/Nvidia/Samples/ObjectDetection/ObjectDetectionAssetGroup
。默认情况下,此AssetGroup包含手推车预制件。修改GameObjects列表以匹配您希望用来训练探测器的对象列表。此列表中的每个预制件都应包含一个
LabelSetter
组件,该组件包含对象的名称。
确保在
过程>对象> Collider Asset Spawner
组件中修改
MaxCount
和
MaxTrials
, 以反映要生成每一帧的对象数。另外,“
程序”>“对象”>“对撞机资产Spawner”
下的“
Dropout”
参数表示资产被“
丢出
”框架的可能性(默认值为0.2)。增加此值将导致数据集中包含更多负样本,该样本应存在于数据集中以最大程度地减少推理过程中的假阳性。
-
生成具有对象模拟图像的KITTI格式的数据集。
a. 在中配置数据集的参数
packages/ml/apps/generate_kitti_dataset/generate_kitti_dataset.app.json
。在这里,可以修改配置以在其他参数中改变图像的输出分辨率(为获得最佳结果,请使用16的倍数的尺寸),要创建的训练图像数和测试图像数。默认应用程序生成一个包含10k训练图像和100个测试图像的数据集;所有图像均为PNG格式,分辨率为368x640。
b.运行以下应用程序以生成输入到TLT培训管道的数据集:
bazel run packages/ml/apps/generate_kitti_dataset
完成后,应用程序将创建
/tmp/unity3d_kitti_dataset
具有以下结构的目录(默认情况下):
unity3d_kitti_dataset/
training/
image_2/ [training images]
000001.png
000002.png
...
label_2/ [training labels in kitti format]
000001.txt
000002.txt
...
testing
image_2/ [testing images]
000001.png
000002.png
...
-
创建一个本地目录
tlt-experiments
以挂载到Docker容器中。将
unity3d_kitti_dataset
目录移到该目录。
-
请按照IVA的
这些说明
设置docker和NGC。
-
启动docker容器并使用
此处
概述的命令安装目录。泊坞窗容器包含所有必要的文件,以训练DetectNetv2模型。
-
导航到
/workspace/examples/detectnet_v2/
Docker映像中的目录。
-
将
/workspace/examples/detectnet_v2/specs
文件夹复制到您的
workspace/tlt-experiments
文件夹中。稍后我们将在已挂载的文件夹中修改这些规范,以便在终止Docker容器后仍可保留培训规范。
-
按照
TLT文档中的
描述启动Jupyter笔记本服务器:
jupyter notebook --ip 0.0.0.0 --allow-root
-
打开
detectnet_v2.ipynb
笔记本并按照说明进行操作,并考虑到每个步骤的这些特殊说明。
-
设置环境变量:
* `$KEY`:创建一个“密钥”,该密钥将用于保护经过训练的模型,并且必须在推理时知道该密钥以访问模型权重。
* `$USER_EXPERIMENT_DIR`:将此设置为`/workspace/tlt-experiments`。
* `$DATA_DOWNLOAD_DIR`:将此设置为您的路径`unity3d_kitti_dataset`。
* `$SPECS_DIR`:将其设置为步骤6中已安装文件夹中复制的specs目录的路径。
-
验证下载的数据集。跳过前两个单元,这会将KITTI对象检测数据集下载到
$DATA_DOWNLOAD_DIR
上面指定的单元中。来自Unity3D的模拟数据集应该已经在此路径上,因此请运行本节的最后两个单元以验证您的模拟数据集。
-
从KITTI格式数据集准备tf记录。修改
$SPECS_DIR/detectnet_v2_tfrecords_kitti_trainval.txt
文件以反映正确的数据集路径。然后按照笔记本计算机中的说明运行单元格。下面提供了一个训练小车检测的示例。
kitti_config {
root_directory_path: "/workspace/tlt-experiments/unity3d_kitti_dataset/training"
image_dir_name: "image_2"
label_dir_name: "label_2"
image_extension: ".png"
partition_mode: "random"
num_partitions: 2
val_split: 14
num_shards: 10
}
image_directory_path: "/workspace/tlt-experiments/unity3d_kitti_dataset/training"
-
下载预训练的模型:按照笔记本中的说明运行单元。
-
在
$SPECS_DIR/detectnet_v2_train_resnet18_kitti.txt
您的用例中修改对象类的训练参数:
-
首先,改变
dataset_config
>
data_sources
>
image_directory_path
您生成数据集内的培训文件夹:
dataset_config {
data_sources {
tfrecords_path: "/workspace/tlt-experiments/tfrecords/kitti_trainval/*"
image_directory_path: "/workspace/tlt-experiments/unity3d_kitti_dataset/training"
}
-
更新
target_class_mapping
参数列表,为每个对象类添加一个。对于每个对象,
key
此结构的字段应与
LabelSetter
步骤1b中通过组件设置的标签匹配。
target_class_mapping {
key: "dolly"
value: "dolly"
}
-
在> 下编辑
output_image_width
和
output_image_height
参数 。
augmentation_config``preprocessing
preprocessing {
output_image_width: 640
output_image_height: 368
...
}
-
在
postprocessing_config
标题下,确保
target_class_config
每个对象类都有一个配置。将
clustering_config
设置保留为默认值。
target_class_config {
key: "dolly"
value {
clustering_config {
...
}
}
-
使用该
model_config
部分的默认值。
-
修改
evaluation_config
部分。编辑
validation_period_during_training
参数以更改验证步骤之间的时期数。使用结构中的默认值,确保每个对象类都有一个
minimum_detection_ground_truth_overlap
和一个
evaluation_box_config
结构:
evaluation_config {
validation_period_during_training: 10
first_validation_epoch: 1
minimum_detection_ground_truth_overlap {
key: "dolly"
value: 0.5
}
evaluation_box_config {
key: "dolly"
value {
...
}
...
}
-
在中
cost_function_config
,使用结构中的默认值,确保每个对象类都有一个
target_classes
结构。
注意
本
cost_function_config
部分包含用于设置每类重量以计算损失或成本的参数
-
修改
training_config
部分。在这个例子中,该图像是368x640,所以
batch_size_per_gpu
可以提高到16更快的学习,因此允许减少的
num_epochs
为100使用的默认值
learning_rate
,
regularizer
,
optimizer
,和
cost_scaling
参数,同时要注意的是,这些的话可以调整需要。默认情况下,训练将每10个周期输出一个模型检查点;修改
checkpoint_interval
参数以更改此频率。
-
修改该
bbox_rasterizer_config
节以使
target_class_config
每个对象类具有一个。对于手推车对象,使用了以下值:
bbox_rasterizer_config {
target_class_config {
key: "dolly"
value: {
cov_center_x: 0.5
cov_center_y: 0.5
cov_radius_x: 0.4
cov_radius_y: 0.4
bbox_min_radius: 1.0
}
}
...
}
有关这些培训参数的更多指导,请参阅
TLT文档
和
此博客文章
。
-
使用
tlt-train
笔记本计算机上的命令运行TLT培训。
-
评估训练后的模型。运行
tlt-evaluate
笔记本中所示的命令,以评估最终的训练模型。您还可以使用
-m
带有
model.step-xxx.tlt
文件路径的标志来评估任何检查点模型。
-
修剪训练后的模型以减少参数的数量,从而减少推理时间和模型的整体大小。要修剪,请运行笔记本中所示的:code:tlt-prune
命令。阅读修剪说明并相应地调整修剪阈值。
pth`0.01 的 值是detectnet_v2模型的一个很好的起点。我们建议修剪比例在0.1到0.3之间。
-
通过修改
$SPECS_DIR/detectnet_v2_retrain_resnet18_kitti.txt
文件来重新训练修剪的模型,类似于
$SPECS_DIR/detectnet_v2_train_resnet18_kitti.txt
。更新,
model_config
以便将
load_graph
选项设置为
true
。确保还为上一步中的
pretrained_model_file
参数下的修剪模型设置了正确的路径
model_config
。
-
评估重新训练的模型。运行
tlt-evaluate
笔记本中所示的命令,以评估最终的训练模型。您还可以使用
-m
带有
model.step-xxx.tlt
文件路径的标志来评估任何检查点模型。
-
编辑
$SPECS_DIR/detectnet_v2_clusterfile_kitti.json
文件以设置推理参数。下图显示了用于多莉探测器的簇文件示例。
{
"dbscan_criterion": "IOU",
"dbscan_eps": {
"dolly": 0.3
},
"dbscan_min_samples": {
"dolly": 0.05
},
"min_cov_to_cluster": {
"dolly": 0.005
},
"min_obj_height": {
"dolly": 4,
"default": 2
},
"target_classes": ["dolly"],
"confidence_th": {
"dolly": 0.6
},
"confidence_model": {
"dolly": { "kind": "aggregate_cov"}
},
"output_map": {
"dolly" : "dolly"
},
"color": {
"dolly": "white"
},
"postproc_classes": ["dolly"],
"image_height": 384,
"image_width": 640,
"stride": 16
}
-
使用
tlt-infer
笔记本中所示的命令可视化推断。将
-i
标志更新到模拟数据集的测试目录,并将标志更新
-m
到重新训练的模型的路径。
-
对模型进行训练,修剪和评估达到满意程度后,使用
tlt-export
“部署!”下的命令将其导出 。笔记本部分。这将为您提供
.etlt
格式的文件,您可以将其用于与Isaac进行推理。
!tlt-export $USER_EXPERIMENT_DIR/experiment_dir_retrain/weights/resnet18_detector_pruned.tlt \
-o $USER_EXPERIMENT_DIR/experiment_dir_final/resnet18_detector_dolly_368x640.etlt \
--outputs output_cov/Sigmoid,output_bbox/BiasAdd \
--enc_key $KEY \
--input_dims 3,368,640 \
--export_module detectnet_v2
TLT模型的TensorRT推断
提供了使用上述工作流程训练的样本DetectNetv2模型。此外,中提供了三个示例推理应用程序
packages/detect_net/apps
,它们都利用了
detect_net_inference
位于同一文件夹中的 子图。
-
detect_net_inference_imagefeeder
:对一组真实图像进行推理。
bazel run packages/detect_net/apps:detect_net_inference_imagefeeder
-
detect_net_inference_camerafeed
:对来自Intel Realsense摄像机的摄像机feed进行推断。
bazel run packages/detect_net/apps:detect_net_inference_camerafeed
-
detect_net_inference_replay
:对已记录的Isaac日志运行推断。
bazel run packages/detect_net/apps:detect_net_inference_replay
可以修改这些应用程序以在您自己训练有素的模型上运行推理。为此,请在任何示例应用程序中修改
detect_net_inference.tensor_r_t_inference小
码的配置。还要确保相应地修改此小
代码中的etlt_password
和
输入/输出张量信息
参数。请注意,如果输入张量信息更改,那么 必须更改
detect_net_inference.tensor_encoder
配置以匹配。
注意
该样本是在有限的数据集上训练的,不能保证在每种情况和光照条件下都可以工作。为了提高自定义环境中的模型准确性,您可以使用上面提供的说明来训练自己的模型。