object detection withSSD in python

SSD网络建立在VGG-16网络上,在单个前向传播网络中完成目标检测和定位。该网络将边界框的输出离散为一组默认框,其中每个特征框的位置具有不同的横纵比和尺寸。在预测目标时,网络为每个默认框中存在的每个对象类别生成分数,并对框进行调整,以便更好的匹配对象形状。

1.1 run

  1. 下载预训练ssd_inception_v2_coco_2017_11_17 模型并使用该模型进行推理。
  • preprocessor

(1)resize image to [300*300*3]

(2)normalization [-1,1]

  • featureextractor

inceptionV2 提取特征,the feature maps generated are used by the anchor generation step to generate default bounding boxes for each feature map.本例中,用于anchor generation的feature maps的尺寸是 [(19x19), (10x10), (5x5), (3x3), (2x2), (1x1)]

  • boxpredictor

产生box encodings和class scores,产生的信息传给postprocessor

  • gridanchorgenerator

产生默认boundingBox。在tensorrt中实现该功能插件层叫做gridAnchorGenerator插件,注册的插件名称是GridAnchor_TRT

  • postprocessor

nms tensorrt中注册插件 NMS_TRT

  • flattenconcat

1.2 process

  1. processing the input graph

tensorflow SSD graph 有一些tensorrt当前不支持的操作,使用GraphSurgeon,可以将graph中的多个操作组合成单个自定义操作,该操作可以使用TensorRT中的插件层实现。目前,GraphSurgeon提供了将命名空间中所有节点缝合到一个自定义节点的能力。

要使用GraphSurgeon,应该使用-p flag 和config file 调用“convert_to_uff”。config script应该包含所有自定义插件的属性,这些插件将嵌入生成的.uff文件中。SSD的当前示例脚本位于/usr/src/tensorrt/samples/sampleUffSSD/config.py

使用GraphSurgeon,能从graph中删除预处理器命名空间,stitch 'GridAnchorGenerator’名称空间以创建’GridAnchorGenerator’插件,将后处理器名称空间sticth到’NMS’插件,并将BoxPredictor中的concat操作标记为’FlatConcat’插件。

TensorFlow graph有一些操作,如’Assert’和’Identity’,可以删除这些操作进行推断。删除像“Assert”这样的操作,然后递归删除剩余节点(一旦删除Assert,就没有输出)。

Identity操作被删除,输入被转发到所有连接的输出。

  1. uff_ssd plugins

GridAnchorGeneration plugin

该插件层在TensorFlow SSD网络中实现网格锚生成步骤。对于每个特征贴图,我们计算每个网格单元的边界框。在该网络中,有6个feature map,每个grid cell的框数如下:

This plugin layer implements the grid anchor generation step in the TensorFlow SSD network. For each feature map we calculate the bounding boxes for each grid cell. In this network, there are 6 feature maps and the number of boxes per grid cell are as follows:

  • [19x19] feature map: 3 boxes (19x19x3x4(co-ordinates/box))
  • [10x10] feature map: 6 boxes (10x10x6x4)
  • [5x5] feature map: 6 boxes (5x5x6x4)
  • [3x3] feature map: 6 boxes (3x3x6x4)
  • [2x2] feature map: 6 boxes (2x2x6x4)
  • [1x1] feature map: 6 boxes (1x1x6x4)

NMS plugin

“NMS”插件根据BoxPredictor生成的位置和置信度预测生成检测输出。该层有三个输入张量,分别对应于位置数据(locData)、置信度数据(confData)和priorbox数据(priorData)。

检测输出插件的输入必须在所有特征图上展平和连接。我们使用示例中实现的“FlattConcat”插件来实现这一点。从box预测器生成的位置数据具有以下维度:

19x19x12 -> Reshape -> 1083x4 -> Flatten -> 4332x1
10x10x24 -> Reshape -> 600x4 -> Flatten -> 2400x1

依此类推,以获取剩余的要素贴图。

串联后,locData输入的输入维度的顺序为7668x1。

从box预测器生成的置信度数据具有以下维度:

19x19x273 -> Reshape -> 1083x91 -> Flatten -> 98553x1
10x10x546 -> Reshape -> 600x91 -> Flatten -> 54600x1

依此类推,以获取剩余的要素贴图。

串联后,confData输入的输入维度为174447x1。

从网格定位生成器插件生成的先前数据具有以下尺寸,例如19x19特征图具有2x4332x1(此处有两个通道,因为一个通道用于存储NMS步骤中使用的每个坐标的方差)。连接后,priorData输入的输入维度为2x7668x1。

struct DetectionOutputParameters
{
	bool shareLocation, varianceEncodedInTarget;
	int backgroundLabelId, numClasses, topK, keepTopK;
	float confidenceThreshold, nmsThreshold;
	CodeTypeSSD codeType;
	int inputOrder[3];
	bool confSigmoid;
	bool isNormalized;
};

shareLocationvarianceEncodedInTarget用于Caffe实现,因此对于TensorFlow网络,它们应分别设置为truefalseconfSigmoidisNormalized参数是TensorFlow实现所必需的。如果confSigmoid设置为true,它将计算所有置信度得分的sigmoid值。isNormalized标志指定是否对数据进行了规范化,并将TensorFlow图设置为true

1.3 code

  1. 下载VOC dataset
wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtest_06-Nov-2007.tar
tar xvf VOCtest_06-Nov-2007.tar

如果下载链接断开,请尝试其他源http://vision.cs.utexas.edu/voc/VOC2007_test/. 如果不想将VOC保存在示例根目录中,则需要在运行之前将 --voc_dir 参数调整为voc_evaluation.py脚本。此参数的默认值为<SAMPLE_ROOT>/VOCdevkit/VOC2007

  1. 运行推理过程

python detect_objects.py <IMAGE_PATH>

第一次运行推理时:

该脚本从TensorFlow对象检测API下载预训练的“ssd_inception_v2_coco_2017_11_17”模型。该脚本将此模型转换为TensorRT格式,并根据此模型的特定版本进行转换。

该脚本构建一个TensorRT推理引擎并将其保存到文件中。在此步骤中,所有TensorRT优化都将应用于冻结图。这是一个耗时的操作,可能需要几分钟。

  1. 运行VOC evaluation 脚本

  2. 使用tensorrt运行脚本
    python voc_evaluation.py

  3. 使用tensorflow运行脚本
    python voc_evaluation.py tensorflow

使用tensorflow运行脚本比用tensorrt慢很多。AP和mAP会在结尾显示

def ssd_unsupported_nodes_to_plugin_nodes(ssd_graph):
    channels = ModelData.get_input_channels()
    height = ModelData.get_input_height()
    width = ModelData.get_input_width()

    Input = gs.create_plugin_node(name="Input",
        op="Placeholder",
        dtype=tf.float32,
        shape=[1, channels, height, width]
    )
    PriorBox = gs.create_plugin_node(
        name="GridAnchor",
        op="GridAnchor_TRT",
        minSize = 0.2,
        maxSize = 0.95,
        aspectRatios = [1.0, 2.0, 0.5, 3.0, 0.33],
        variance=[0.1, 0.1, 0.2,0.2],
        featureMapShapes=[19,10,5,3,2,1],
        numLayers=6
    )
    NMS = gs.create_plugin_node(
        name="NMS",
        op="NMS_TRT",
        shareLocation=1,
        varianceEncodedInTarget=0,
        backgroundLabelId=0,
        confidenceThreshold=1e-8,
        nmsThreshold=0.6,
        topK=100,
        keepTopK=100,
        numClasses=91,
        inputOrder=[0, 2, 1],
        confSigmoid=1,
        isNormalized=1
    )
    concat_priorbox = gs.create_node(
        "concat_priorbox",
        op="ConcatV2",
        dtype=tf.float32,
        axis=2
    )
    concat_box_loc = gs.create_plugin_node(
        "concat_box_loc",
        op="FlattenConcat_TRT",
        dtype=tf.float32,
        axis=1,
        ignoreBatch=0
    )
    concat_box_conf = gs.create_plugin_node(
        "concat_box_conf",
        op="FlattenConcat_TRT",
        dtype=tf.float32,
        axis=1,
        ignoreBatch=0
    )
    namespace_plugin_map = {
        "MultipleGridAnchorGenerator": PriorBox,
        "Postprocessor": NMS,
        "Preprocessor": Input,
        "ToFloat": Input,
        "image_tensor": Input,
        "MultipleGridAnchorGenerator/Concatenate": concat_priorbox,
        "MultipleGridAnchorGenerator/Identity": concat_priorbox,
        "concat": concat_box_loc,
        "concat_1": concat_box_conf
    }
    ssd_graph.collapse_namespaces(namespace_plugin_map)
    ssd_graph.remove(ssd_graph.graph_outputs, remove_exclusive_dependencies=False)
    return ssd_graph
def model_to_uff(model_path, output_uff_path, slient=False):
    dynamic_graph = gs.DynamicGraph(model_path)
    dynamic_graph = ssd_unsupported_nodes_to_plugin_nodes(dynamic_graph)
    uff.from_tensorflow(
        dynamic_graph.as_graph_def(),
        [ModelData.OUTPUT_NAME],
        output_filename = output_uff_path,
        text=True
    )
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本课程适合具有一定深度学习基础,希望发展为深度学习之计算机视觉方向的算法工程师和研发人员的同学们。基于深度学习的计算机视觉是目前人工智能最活跃的领域,应用非常广泛,如人脸识别和无人驾驶中的机器视觉等。该领域的发展日新月异,网络模型和算法层出不穷。如何快速入门并达到可以从事研发的高度对新手和中级水平的学生而言面临不少的挑战。精心准备的本课程希望帮助大家尽快掌握基于深度学习的计算机视觉的基本原理、核心算法和当前的领先技术,从而有望成为深度学习之计算机视觉方向的算法工程师和研发人员。本课程系统全面地讲述基于深度学习的计算机视觉技术的原理并进行项目实践。课程涵盖计算机视觉的七大任务,包括图像分类、目标检测、图像分割(语义分割、实例分割、全景分割)、人脸识别、图像描述、图像检索、图像生成(利用生成对抗网络)。本课程注重原理和实践相结合,逐篇深入解读经典和前沿论文70余篇,图文并茂破译算法难点, 使用思维导图梳理技术要点。项目实践使用Keras架(后端为Tensorflow),学员可快速上手。通过本课程的学习,学员可把握基于深度学习的计算机视觉的技术发展脉络,掌握相关技术原理和算法,有助于开展该领域的研究与开发实战工作。另外,深度学习之计算机视觉方向的知识结构及学习建议请参见本人CSDN博客。本课程提供课程资料的课件PPT(pdf格式)和项目实践代码,方便学员学习和复习。本课程分为上下两部分,其中上部包含课程的前五章(课程介绍、深度学习基础、图像分类、目标检测、图像分割),下部包含课程的后四章(人脸识别、图像描述、图像检索、图像生成)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值