今天看啥  ›  专栏  ›  YottaYuan

使用DetectNetv2进行目标检测

YottaYuan  · 简书  ·  · 2020-03-19 01:54

使用DetectNetv2进行目标检测

Isaac SDK支持使用 DetectNetv2 进行对象检测的训练/推理管道。对于此管道,DetectNetv2利用ResNet主干特征提取器。ResNet是一个工业网络,可与MobileNet和InceptionNet(用于特征提取的两个常用主干模型)相提并论。NVIDIA Transfer Learning Toolkit (TLT)可用于训练,微调和修剪DetectNetv2模型以进行对象检测。

以下各节说明了如何:

  1. 从IsaacSim for Unity3D生成数据集图像。
  2. 在生成的数据集上训练预训练的DetectNetv2模型。
  3. 使用Isaac TensorRT推论小代码对各种输入进行推论。

TLT中模拟图像的训练

训练DetectNetv2模型涉及生成模拟数据,并使用TLT在此数据上训练模型。Isaac SDK提供了一个基于ResNet18的示例模型,已使用此管道对它进行了训练,以检测单个对象:下图所示的小车。以下分步说明介绍了如何训练该模型的过程。使用这些步骤作为指导来训练您自己的对象上的模型。

  1. 为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)。增加此值将导致数据集中包含更多负样本,该样本应存在于数据集中以最大程度地减少推理过程中的假阳性。

  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
            ...
  1. 创建一个本地目录 tlt-experiments 以挂载到Docker容器中。将 unity3d_kitti_dataset 目录移到该目录。

  2. 请按照IVA的 这些说明 设置docker和NGC。

  3. 启动docker容器并使用 此处 概述的命令安装目录。泊坞窗容器包含所有必要的文件,以训练DetectNetv2模型。

  4. 导航到 /workspace/examples/detectnet_v2/ Docker映像中的目录。

  5. /workspace/examples/detectnet_v2/specs 文件夹复制到您的 workspace/tlt-experiments 文件夹中。稍后我们将在已挂载的文件夹中修改这些规范,以便在终止Docker容器后仍可保留培训规范。

  6. 按照 TLT文档中的 描述启动Jupyter笔记本服务器:

jupyter notebook --ip 0.0.0.0 --allow-root
  1. 打开 detectnet_v2.ipynb 笔记本并按照说明进行操作,并考虑到每个步骤的这些特殊说明。
  1. 设置环境变量:
*   `$KEY`:创建一个“密钥”,该密钥将用于保护经过训练的模型,并且必须在推理时知道该密钥以访问模型权重。
*   `$USER_EXPERIMENT_DIR`:将此设置为`/workspace/tlt-experiments`。
*   `$DATA_DOWNLOAD_DIR`:将此设置为您的路径`unity3d_kitti_dataset`。
*   `$SPECS_DIR`:将其设置为步骤6中已安装文件夹中复制的specs目录的路径。
  1. 验证下载的数据集。跳过前两个单元,这会将KITTI对象检测数据集下载到 $DATA_DOWNLOAD_DIR 上面指定的单元中。来自Unity3D的模拟数据集应该已经在此路径上,因此请运行本节的最后两个单元以验证您的模拟数据集。
  1. 从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"
  1. 下载预训练的模型:按照笔记本中的说明运行单元。

  2. $SPECS_DIR/detectnet_v2_train_resnet18_kitti.txt 您的用例中修改对象类的训练参数:

  3. 首先,改变 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"
    }
  1. 更新 target_class_mapping 参数列表,为每个对象类添加一个。对于每个对象, key 此结构的字段应与 LabelSetter 步骤1b中通过组件设置的标签匹配。
target_class_mapping {
    key: "dolly"
    value: "dolly"
}
  1. 在> 下编辑 output_image_width output_image_height 参数 。 augmentation_config``preprocessing
preprocessing {
    output_image_width: 640
    output_image_height: 368
    ...
}
  1. postprocessing_config 标题下,确保 target_class_config 每个对象类都有一个配置。将 clustering_config 设置保留为默认值。
target_class_config {
    key: "dolly"
    value {
    clustering_config {
        ...
    }
}
  1. 使用该 model_config 部分的默认值。

  2. 修改 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 {
            ...
        }
        ...
}
  1. 在中 cost_function_config ,使用结构中的默认值,确保每个对象类都有一个 target_classes 结构。

注意
cost_function_config 部分包含用于设置每类重量以计算损失或成本的参数

  1. 修改 training_config 部分。在这个例子中,该图像是368x640,所以 batch_size_per_gpu 可以提高到16更快的学习,因此允许减少的 num_epochs 为100使用的默认值 learning_rate regularizer optimizer ,和 cost_scaling 参数,同时要注意的是,这些的话可以调整需要。默认情况下,训练将每10个周期输出一个模型检查点;修改 checkpoint_interval 参数以更改此频率。
  1. 修改该 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文档 此博客文章

  1. 使用 tlt-train 笔记本计算机上的命令运行TLT培训。
  1. 评估训练后的模型。运行 tlt-evaluate 笔记本中所示的命令,以评估最终的训练模型。您还可以使用 -m 带有 model.step-xxx.tlt 文件路径的标志来评估任何检查点模型。
  1. 修剪训练后的模型以减少参数的数量,从而减少推理时间和模型的整体大小。要修剪,请运行笔记本中所示的:code:tlt-prune 命令。阅读修剪说明并相应地调整修剪阈值。 pth`0.01 的 值是detectnet_v2模型的一个很好的起点。我们建议修剪比例在0.1到0.3之间。
  1. 通过修改 $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
  1. 评估重新训练的模型。运行 tlt-evaluate 笔记本中所示的命令,以评估最终的训练模型。您还可以使用 -m 带有 model.step-xxx.tlt 文件路径的标志来评估任何检查点模型。
  1. 编辑 $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
}
  1. 使用 tlt-infer 笔记本中所示的命令可视化推断。将 -i 标志更新到模拟数据集的测试目录,并将标志更新 -m 到重新训练的模型的路径。
  1. 对模型进行训练,修剪和评估达到满意程度后,使用 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 配置以匹配。

注意
该样本是在有限的数据集上训练的,不能保证在每种情况和光照条件下都可以工作。为了提高自定义环境中的模型准确性,您可以使用上面提供的说明来训练自己的模型。




原文地址:访问原文地址
快照地址: 访问文章快照