使用DetectNetv2进行目标检测
使用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-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配置以匹配。
注意
该样本是在有限的数据集上训练的,不能保证在每种情况和光照条件下都可以工作。为了提高自定义环境中的模型准确性,您可以使用上面提供的说明来训练自己的模型。