使用DetectNetv2进行目标检测

2020-03-19  本文已影响0人  YottaYuan

使用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组件中修改MaxCountMaxTrials, 以反映要生成每一帧的对象数。另外,“ 程序”>“对象”>“对撞机资产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_widthoutput_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_rateregularizeroptimizer,和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.tensor_r_t_inference小码的配置。还要确保相应地修改此小代码中的etlt_password输入/输出张量信息 参数。请注意,如果输入张量信息更改,那么 必须更改detect_net_inference.tensor_encoder配置以匹配。

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

上一篇下一篇

猜你喜欢

热点阅读