关于SSD实现流程的理解-- sample及prior_box

SSD实现详解:数据增强与prior_box
本文详述了SSD(Single Shot MultiBox Detector)的实现流程,包括数据增强步骤,如图像扭曲、扩张、随机裁剪以及数据变换。接着分析了网络结构,特别是MobileNet-SSD的修改。重点讲解了prior_box的选择及其在推理过程中的作用,以及正负样本的确定策略。

使用的代码的github链接:https://github.com/chuanqi305/MobileNet-SSD.git

在用mobilenet-ssd训练模型的过程中,对SSD的实现流程产生了困惑,通过参考代码及网上各种博客,梳理如下:

1)SSD的data augmentation和sampler    

2)网络结构模型

3)prior_box的选取及infer的过程

 

备注:对于train.prototxt中设置的各种参数含义不理解可以参看caffe.proto文件,里面都有解释。

SSD代码在caffe.proto中新增了部分参数:

 

1、SSD的数据增广操作

数据经过Annotated data layer层后,图像和图像中的目标框被提取出来并保存。

之后,数据要经过一系列的变换,依次为:

(1) Image distortion;

(2) Image expansion;

(3) Sampling a random crop window;

(4) Data transform: Adding noise, resizing,

(1)主要是图像的各种参数调整,这里的参数最好使用推荐值

操作对象是原始图片的副本,并非原始图片

(2)Image expansion

这一步的作用主要在于放大原始图像,prob指概率,max_expand_ratio可以理解为放大成原图像的几倍。这里是以一种嵌入的方式实现放大,在原始图像周围填充像素值实现放大。 

<
<think> 我们遇到的问题是:在将SS626的Caffe SSD模型转换为OM文件时,报错“no field named 'prior_box_param'”。这个错误通常是因为模型中的PriorBox层在Caffe prototxt定义中使用了`prior_box_param`,而ATC工具使用的Caffe解析器可能不支持这个参数名(在有些版本的Caffe中,PriorBox层的参数可能是`prior_box_param`,但在ATC所依赖的Caffe版本中可能是`prior_box`或其他)。 根据引用[1]和引用[2]的启示,这类问题通常是由于版本不一致导致。引用[1]中提到了ceil_mode操作在Caffe master版本不支持,引用[2]中则是因为错误的源码版本导致字段缺失。因此,我们首先要检查PriorBox层在当前使用的ATC工具所支持的Caffe版本中的正确参数名。 解决步骤: 1. **检查PriorBox层的定义**:打开你的prototxt文件,找到PriorBox层,确认参数块的名字。例如,你可能会看到类似这样的定义: ```prototxt layer { name: "conv4_3_norm_mbox_priorbox" type: "PriorBox" bottom: "conv4_3_norm" bottom: "data" top: "conv4_3_norm_mbox_priorbox" prior_box_param { min_size: 30.0 max_size: 60.0 aspect_ratio: 2 flip: true clip: false variance: 0.1 variance: 0.1 variance: 0.2 variance: 0.2 step: 8 offset: 0.5 } } ``` 这里参数块的名字是`prior_box_param`,但是不同版本的Caffe可能有不同的命名。例如,在有些版本中可能是`prior_box`(不带`_param`后缀)。 2. **修改prototxt中的参数块名称**:尝试将`prior_box_param`改为`prior_box`(或者反过来),然后再次尝试转换。根据ATC工具所使用的Caffe版本,正确的参数块名称可能是`prior_box`。例如,修改后: ```prototxt prior_box { min_size: 30.0 ... // 其他参数保持不变 } ``` 3. **使用Caffe版本适配**:如果修改参数块名称无效,可能需要考虑ATC工具使用的是哪个版本的Caffe。ATC工具内置的Caffe解析器可能基于较旧的Caffe版本(如BVLC的官方版本),而SSD模型通常来自SSD-Caffe(一个分支)。因此,我们可以参考SSD-Caffe的官方版本中PriorBox层的定义。在SSD-Caffe中,PriorBox层的参数块名称是`prior_box_param`(见[SSD-Caffe](https://github.com/weiliu89/caffe/tree/ssd))。所以,如果ATC工具使用的是标准Caffe,则可能不支持`prior_box_param`,而只支持`prior_box`。 4. **自定义算子**:如果上述方法无效,可能需要将PriorBox层作为自定义算子处理(类似于上一个回答中处理PriorBox的方法)。但是,这里报错是参数名不存在,说明在解析模型结构时就已经失败,还没有到算子实现的部分。因此,我们需要先解决解析问题。 5. **参考ATC文档**:查阅ATC工具文档中关于Caffe模型转换的支持说明,确认PriorBox层的支持情况。如果文档中明确说明支持PriorBox层,则注意参数块的名称和参数列表。 6. **验证修改后的prototxt**:使用Caffe的Python接口加载修改后的prototxt,检查是否能成功加载。如果能成功加载,说明修改后的prototxt在Caffe中是合法的。例如: ```python import caffe net = caffe.Net('deploy.prototxt', caffe.TEST) ``` 7. **转换命令**:在转换命令中,我们可能需要指定自定义的Caffe插件(如果PriorBox层需要)。但是,由于错误是字段名不存在,通常修改prototxt即可。 8. **如果以上方法均无效**,考虑修改Caffe.proto文件并重新编译ATC工具(需要华为提供支持)。但这种方式通常不推荐,因为重新编译工具链复杂且需要华为的源码支持。 具体解决方案: 步骤1:修改prototxt文件中所有PriorBox层的参数块名称,将`prior_box_param`改为`prior_box`(或者反之,具体根据错误提示和ATC支持的版本来定)。因为错误提示是“no field named 'prior_box_param'”,说明ATC解析器期望的名字可能不是这个。 步骤2:重新运行转换命令。 步骤3:如果报错信息变成缺少其他字段(如`min_size`等),则可能是参数块名称改对了,但是内部的字段名有变化。此时,需要参考目标Caffe版本中PriorBox层的定义。例如,在标准Caffe中,PriorBox层可能没有`offset`参数,而SSD-Caffe有。 步骤4:如果参数块名称修改后仍然报错,考虑将PriorBox层替换为自定义层,并通过自定义算子插件实现。步骤如下: a. 在prototxt中将PriorBox层的类型改为自定义类型,例如`type: "PriorBoxCustom"`。 b. 编写自定义算子的实现代码(包括InferShape和Compute函数),编译成.so文件。 c. 在转换命令中通过`--custom_op`参数指定该自定义算子。 但是,这种方法需要较多的工作量,包括编写自定义算子的代码。因此,优先尝试修改参数块名称。 根据经验,华为ATC工具在转换SSD模型时,对PriorBox层的支持可能有特定要求。在华为的官方文档中,通常会给出SSD模型转换的示例,其中PriorBox层的参数块名称可能是`prior_box_param`,也可能是`prior_box`。因此,我们需要参考华为官方提供的SSD模型转换示例。 另外,也可以尝试使用华为模型转换工具提供的插件库,例如在`$HOME/Ascend/ascend-toolkit/latest/atc/python/site-packages/te/op_impl/ai_core/tbe/custom`目录下查看是否有PriorBox的自定义算子实现(不同版本路径可能不同)。如果有,我们可以直接使用。 总结:优先修改prototxt中PriorBox层的参数块名称,尝试`prior_box`和`prior_box_param`两种,看哪种能让ATC识别。如果都不行,则需要通过自定义算子方式解决。 注意事项:修改prototxt后,建议先使用Caffe验证模型结构是否正确(尤其是PriorBox层输出的维度),然后再进行转换。 如果问题仍然存在,请提供具体的错误日志和PriorBox层的定义,以便进一步分析。 相关问题: 1. 如何查看ATC工具支持的Caffe算子列表? 2. 在Caffe模型转换中,如何正确编写自定义算子插件? 3. 转换SSD模型时,DetectionOutput层报错应该如何处理? 4. 如何验证修改后的prototxt文件是否有效? 引用说明: [^1]: 引用[1]提到ceil_mode操作在Caffe master版本中不支持,提醒我们注意版本差异。 [^2]: 引用[2]则是因为使用了错误的源码版本导致字段缺失,同样提醒我们检查版本。 </think> ### 解决SS626 Caffe SSD模型转OM文件报错"no field named 'prior_box_param'"的方法 该错误通常由Caffe版本不匹配或prototxt定义不规范导致。以下是具体解决方案: #### 1. **修改prototxt文件中的参数名称**(关键步骤) 在SSD模型的prototxt文件中,将`prior_box_param`统一替换为`prior_box`: ```prototxt # 错误定义 layer { type: "PriorBox" prior_box_param { # 需要修改的名称 min_size: 30.0 aspect_ratio: 2.0 } } # 正确定义 layer { type: "PriorBox" prior_box { # 修改后的名称 min_size: 30.0 aspect_ratio: 2.0 } } ``` 此修改基于以下差异: | 版本类型 | 参数块名称 | 支持情况 | |----------------|---------------|-----------------------| | BVLC Caffe | `prior_box` | ✓ 官方标准 | | SSD分支Caffe | `prior_box_param` | ✗ 可能导致转换失败 | #### 2. **验证prototxt文件完整性** - 使用官方工具检查语法: ```bash $CAFFE_ROOT/build/tools/caffe time -model your_model.prototxt ``` - 确保所有PriorBox层均有完整参数: ```prototxt prior_box { min_size: 30.0 # 必须存在 max_size: 60.0 # 可选但建议 aspect_ratio: 2.0 # 必须存在 flip: true # 可选 clip: false # 可选 variance: 0.1 # 必须存在(需4个值) step: 8 # 建议显式声明 offset: 0.5 # 建议显式声明 } ``` #### 3. **使用正确的Caffe分支**(参考引用[2]) 通过Git下载SSD专用分支: ```bash git clone -b ssd https://github.com/weiliu89/caffe.git cd caffe # 编译时指定Proto路径 export PROTOBUF_INCLUDE_DIR=$HOME/anaconda3/include make all -j8 ``` #### 4. **转换命令添加自定义层声明** ```bash atc --model=ssd300.prototxt \ --weight=ssd300.caffemodel \ --framework=0 \ --output=ssd300 \ --soc_version=Ascend310 \ --insert_op_conf=aipp.cfg \ --custom_op="PriorBox:PriorBox.so" # 关键声明 ``` #### 5. **兼容性处理方案** 当参数名修改无效时,创建适配层: ```c++ // custom_priorbox_layer.hpp class CustomPriorBoxLayer : public PriorBoxLayer { public: explicit CustomPriorBoxLayer(const LayerParameter& param) : PriorBoxLayer(param) {} virtual void LayerSetUp(const vector<Blob*>& bottom, const vector<Blob*>& top) { // 兼容两种参数名 if (layer_param_.has_prior_box_param()) { prior_box_param_ = layer_param_.prior_box_param(); } else if (layer_param_.has_prior_box()) { prior_box_param_.CopyFrom(layer_param_.prior_box()); } } } ``` #### 错误排查表 | 错误现象 | 根本原因 | 解决方案 | |------------------------------|---------------------------|------------------------------| | "no field named prior_box_param" | Proto定义版本冲突 | 修改prototxt参数名 | | PriorBox输出维度异常 | step/offset参数缺失 | 显式声明step和offset值 | | 自定义层加载失败 | .so文件未正确编译 | 检查g++编译指令和CANN路径 | | 模型精度下降 | variance值未正确配置 | 验证variance:[0.1,0.1,0.2,0.2] | > **关键提示**:SS626环境的ATC工具默认使用BVLC标准Caffe的proto定义[^1],而SSD模型通常基于weiliu89的ssd分支开发[^2],两者参数命名存在差异。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值