首先,当group 是input_channel 和output_channel 的倍数时,Caffe 仅确定行为。我们可以通过source code 确认这一点:
CHECK_EQ(channels_ % group_, 0);
CHECK_EQ(num_output_ % group_, 0)
<< "Number of output should be multiples of group.";
其次,参数group与filter参数的个数有关,具体来说与filter的通道大小有关。
每个过滤器的实际数量为input_channel/group。这也可以从source code得到确认:
vector<int> weight_shape(2);
weight_shape[0] = conv_out_channels_;
weight_shape[1] = conv_in_channels_ / group_;
注意这里weight_shape[0]是filer的编号。
所以,w.r.t 你的问题:
在 Caffe 中,如果 input_channel 为 40,group 为 20:
-
output_channel 可能不是 50。
- 如果
output_channel是20(记住这意味着你有20个过滤器),每2个输入通道负责一个输出通道。例如,第 0 个输出通道是根据第 0 个和第 1 个输入通道计算得出的,与其他输入通道没有关系。
- 如果
output_channel等于input_channel(即output_channel = 40),这实际上就是众所周知的depthwise convolution。每个输出通道仅根据一个不同的输入通道计算得出。
w.r.t 反卷积:
我们几乎总是设置group = output_channels。这是来自official doc 的Deconvolution 层的建议配置:
layer {
name: "upsample", type: "Deconvolution"
bottom: "{{bottom_name}}" top: "{{top_name}}"
convolution_param {
kernel_size: {{2 * factor - factor % 2}} stride: {{factor}}
num_output: {{C}} group: {{C}}
pad: {{ceil((factor - 1) / 2.)}}
weight_filler: { type: "bilinear" } bias_term: false
}
param { lr_mult: 0 decay_mult: 0 }
}
使用以下指令:
通过指定 num_output: {{C}} group: {{C}},它的行为如下
通道卷积。这个反卷积层的滤波器形状
将是 (C, 1, K, K),其中 K 是 kernel_size,并且此填充符将设置
滤波器每个通道的 (K, K) 插值内核
同样。顶部特征图的最终形状将是 (B, C,
因数 * H,因数 * W)。注意学习率和权重
衰减设置为 0 以保持双线性的系数值
训练期间插值不变。