查看DeepFace网络的proto文件发现使用Slice做blob数据分割,Eltwise层做blob数据融合,这里详细说明这个layer的用法。
1、Slice Layer
Slice Layer接收top blob的数据,并再指定维度做分割处理。
caffe.proto中定义如下:
message SliceParameter {
// The axis along which to slice -- may be negative to index from the end
// (e.g., -1 for the last axis).
// By default, SliceLayer concatenates blobs along the "channels" axis (1).
#在指定维度上做分割
optional int32 axis = 3 [default = 1];
#指定分割点,不指定则均匀分割
repeated uint32 slice_point = 2;
//等同于axis
// DEPRECATED: alias for "axis" -- does not support negative indexing.
optional uint32 slice_dim = 1 [default = 1];
}
prototxt文件定义示例1:
layer{
name: "slice1"
type:"Slice"
slice_param {
slice_dim: 1 #在维度一上做均匀分割
}
bottom: "conv1"
top: "slice1_1" #分割后的第一部分赋值个blob slice1_1
top: "slice1_2" #分割后的第二部分赋值个blob slice2_2
}
prototxt文件定义示例2:
layer {
name:"data_each"
type:"Slice"
bottom:"data_all"
top:"data_classfier" #输出blob1
top:"data_boundingbox" #输出blob2
top:"data_facialpoints" #输出blob3
slice_param {
axis:0
slice_point:100 #指定blob1和blob2的分割点
slice_point: 150 #指定blob2和blob3的分割点
}
}
其中slice_point的个数等于top的个数减1。
加入的data_all为 250×3×24×24的blob
拆分后的3个输出的维度依次为 100×3×24×24,50×3×24×24,100×3×24×24
2、Eltwise Layer
是对两个blob按位置做数据融合,数据融合方式包括product(点乘)、sum(相加减) 和 max(取大值),其中sum是默认操作。
cafe.proto文件中定义如下:
message EltwiseParameter {
enum EltwiseOp {
PROD = 0;
SUM = 1;
MAX = 2;
}
#支持按位操作类型
optional EltwiseOp operation = 1 [default = SUM]; // element-wise operation
repeated float coeff = 2; // blob-wise coefficient for SUM operation
// Whether to use an asymptotically slower (for >2 inputs) but stabler method
// of computing the gradient for the PROD operation. (No effect for SUM op.)
optional bool stable_prod_grad = 3 [default = true];
}
proto文件语法如下:
layer{
name: "etlwise1"
type: "Eltwise"
bottom: "slice1_1"
bottom: "slice1_2"
top: "eltwise1"
eltwise_param {
operation: MAX #按位取slice1_1和slice1_2中较大值
}
}
在来一段FaceNet中定义,加深理解:
name: "DeepFace_set003_net"
input: "data"
input_dim: 1
input_dim: 1
input_dim: 128
input_dim: 128
layer{
name: "conv1"
type: "Convolution"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
convolution_param {
num_output: 96
kernel_size: 5
stride: 1
pad: 2
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
value: 0.1
}
}
bottom: "data"
top: "conv1"
}
layer{
name: "slice1"
type:"Slice"
slice_param {
slice_dim: 1
}
bottom: "conv1"
top: "slice1_1"
top: "slice1_2"
}
layer{
name: "etlwise1"
type: "Eltwise"
bottom: "slice1_1"
bottom: "slice1_2"
top: "eltwise1"
eltwise_param {
operation: MAX
}
}
layer{
name: "pool1"
type: "Pooling"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
bottom: "eltwise1"
top: "pool1"
}
layer{
name: "conv2a"
type: "Convolution"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
convolution_param {
num_output: 96
kernel_size: 1
stride: 1
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
value: 0.1
}
}
bottom: "pool1"
top: "conv2a"
}
- data 层接收图片数据
- conv1 提取特征,生成96通道的blob
- slice1 将96通道blob分成 48和48的两个blob
- eltwise 按位取Max,合并成一个48通道的blob
- conv2a是一个NIN,实现48通道间的数据融合
这个网络还是很高效的