在SSD中我们发现:
layer {
name: "conv4_3_norm"
type: "Normalize"
bottom: "conv4_3"
top: "conv4_3_norm"
norm_param {
across_spatial: false
scale_filler {
type: "constant"
value: 20.0
}
channel_shared: false
}
}
但是有两个问题:
1. Normalize
层做了什么?
2. 为什么只对conv4_3
进行normalize 操作?
首先说一下Normalize Layer的作用:
在训练深度模型的过程中, 加入normalization操作通常可以增加算法的鲁棒性,类似的操作还有BN(BatchNormalization)。
但如果把feature的模长放缩到刚好等于 1 的长度,会让学到的feature变得很小,网络会难以训练。所以,更可取的做法是将feature的值放大一定倍数,例如20倍,这就是scale_filler的作用: x̂ ←scale∗x̂
across_spatial如果为true的话,则按channel进行norm操作。此处为false,被norm的是像素的feature vector。例如,现在要对大小为m×n×c的feature map进行norm操作,前者是在c个m×n的tensor进行norm操作,后者在m×n个c维向量上操作。
为什么只对conv4_3
进行norm操作?
作者在github上的解释:https://github.com/weiliu89/caffe/issues/241
That was discovered in my other paper (ParseNet) that conv4_3 has different scale from other layers. That is why I add L2 normalization for conv4_3 only.
文献 ICLR 2016, ParseNet: Looking wider to see better 指出,conv4_3 相比较于其他的 layers,有着不同的 feature scale,我们使用 ParseNet 中的 L2 normalization 技术将 conv4_3 feature map 中每一个位置的 feature norm scale 到 20,并且在 back-propagation 中学习这个 scale。
另一个解释:
其中VGG16中的Conv4_3层将作为用于检测的第一个特征图。conv4_3层特征图大小是 ,但是该层比较靠前,其norm较大,所以在其后面增加了一个L2 Normalization层(参见ParseNet),以保证和后面的检测层差异不是很大,这个和Batch Normalization层不太一样,L2 Normalization仅仅是对每个像素点在channle维度做归一化,而Batch Normalization层是在[batch_size, width, height]三个维度上做归一化。