您的位置:首页 > Web前端

分析一下weiliu89的caffe-ssd代码吧

2018-01-03 18:31 435 查看
weiliu89在caffe里面加了这么一堆东西,来做他的ssd,我觉得作者实在是有点overdesign了,把代码搞的可读性很差。而且很关键的一点是,这哥们不喜欢在代码里加任何空行,所有代码都密密麻麻挤在一起。你的屏幕面积就那么宝贵么?

费了好几天劲,终于大概看完了他的代码,大概有这么些东西:

数据集准备

caffe/data/coco

caffe/tools/convert_annoset.cpp

caffe proto

LabelMapItem, LabelMap,

NormalizedBBox, Annotation, AnnotationGroup, AnnotatedDatum

ExpansionParameter,

SaltPepperParameter, NoiseParameter, DistortionParameter, 

Sampler, SampleConstraint, BatchSampler, EmitConstraint

ResizeParameter, 

AnnotatedDataParameter

PriorBoxParameter

MultiBoxLossParameter

NonMaximumSuppressionParameter, SaveOutputParameter, DetectionOutputParameter

新增的h/cpp/cu代码

layers/annotated_data_layer.hpp/cpp

layers/detection_evaluate_layer.hpp/cpp

layers/detection_output_layer.hpp/cpp/cu

layers/multibox_loss_layer.hpp/cpp

layers/prior_box_layer.hpp/cpp

layers/smooth_L1_loss_layer.hpp/cpp/cu

util/bbox_util.hpp/cpp/cu

util/im_transforms.hpp/cpp

util/samper.hpp/cpp

data_transformer.hpp/cpp

然后其实他的算法过程就是这么些东西:

Annotated data layer和data transformer

Annotated data layer产生图像以及图像中标记的目标框。图像以及目标框经过data 

transformer进行一系列变换,依次为:

(1) Image distortion;

(2) Image expansion;

(3) Sampling a random crop window;

(4) Data transform: Adding noise, resizing, 

步骤(1)中,使用了caffe proto中的DistortionParameter.

步骤(2)中,使用了caffe proto中的ExpansionParameter。

步骤(3)中,使用了caffe proto中的Sampler, SampleConstraint, BatchSampler。

步骤(4)中,使用了caffe proto中的ResizeParameter和NoiseParameter,先resize 然后加

noise,并且将去掉中心点落到图像外的目标框。

AnnotatedDataLayer输出的目标表示为N*8*1*1的tensor,有N个目标,8个值分别为:

(0) - 来自batch中的第i张图片;

(1) - 目标类别;

(2) - 目标序号;

(3-7) - xmin, ymin, xmax, ymax坐标,均为相对图像宽高归一化到[0, 1]之间的值;

(8) - 是否difficult。

Prior box layer产生prior box

Prior box layer根据图像大小和feature map大小,以及预设的参数,生成prior box。

PriorBoxParameter中,指定了min_size,max_size,和aspect_ratio。另外还有参数flip

和clip,如果flip为true,则将有一组额外的aspect ratio。如果clip为true,则将超出图

像边缘的prior box固定到图像内。作者给的训练网络中flip为true,clip为false。

每个min_size和aspect_ratio的组合生成一个prior box,每个max_size 再生成一个额外的

prior box。在作者的训练网络中,每个prior box用xmin,ymin,xmax,ymax表示,均为相

对于图像宽高的归一化值。此外每个prior box还有4个variance值,用于计算损失时对坐标

进行归一化。作者在训练网络中将这4个variance分别设置为0.1, 0.1, 0.2, 0.2。

Multi box loss layer计算multi box loss

在计算multi box loss时,依次进行如下操作:

(1) GetGroundTruth,从blob复原回NormalizedBBox。

(2) GetPriorBoxes,获取feature map上每个点对应的prior box。

(3) GetLocPredictions,获取feature map上每个点的预测的目标框。注意对不同类别共用

    一个目标框。

(4) FindMatches,将prior box与groundtruth box进行匹配,找到prior box中哪些应作为

    正样本。这里如下参数发挥作用:

    - use_prior_for_matching:在作者的代码中为true,即匹配prior box与gnd box。

    - overlap_threshold:控制了判定样本为正样本的覆盖率阈值。

    - match_type:在作者的代码中设置为PER_PREDICTION,即对每个 gnd box,选择最佳

      匹配的prior box作为positive box,以及对每个prior box,如果与其覆盖率最高的

      gnd box的覆盖率超过overlap_threshold,也将其作为positive box。

(5) MinHardExamples,选择hard negative window。这里如下参数发挥作用:

    - do_neg_mining

    - mining_type

    - use_prior_for_nms

    - nms_param

    - neg_pos_ratio:

    - neg_overlap:如果prior box与gnd box的覆盖率超过此值,则不作为negative。

    - sample_size

    在进行hard neg mining时,按如下步骤进行计算:

    - 计算每个prior box的confidence loss。

    - 如果mining_type为HARD_EXAMPLE,计算location loss,并将location loss和conf

      loss加起来作为损失。注意prior box和gnd box为(xmin, ymin, xmax, ymax)格式,

      但location pred为(ncx, ncy, nw, nh)格式,其中ncx,ncy为中心点偏移,用prior

      box宽高和variance[0]和 variance[1]归一化。nw和nh为宽度和高度偏移,用prior 

      box宽高和variance[2]和variance[3]归一化。需要依次调用EncodeLocPrediction和

      ComputeLocLoss计算位置损失。

    - 如果has_nms_param为true,则对negative window进行nms后再选取。

      如果use_prior_for_nms,则使用prior box进行nms,否则使用pred box进行nms。在

      进行nms之前需要先调用DecodeBBoxes将pred bbox转化为(xmin, ymin, xmax, ymax)

      格式,然后再调用ApplyNMS。

    - 如果mining_type为MAX_NEGATIVE,则根据neg_pos_ratio以及positive数目确定选取

      的negative数目,否则根据sample_size确定要选取的negative数目。

上面这几步完了之后,就是调用具体的loss layer计算损失值了。在backward时,也只需要

将loss layer传回来的diff拷贝到对应窗口的feature map的diff中即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: