在Tensorflow中使用tf.nn.fractional_max_pool
函数时,除了返回输出的池化张量外,还会返回row_pooling_sequence
和col_pooling_sequence
。我认为这些是在反向传播中用于计算梯度的。这与普通的$2 \times 2$最大池化形成对比,后者只返回池化张量。
我的问题是:我们是否需要自己处理row_pooling
和col_pooling
的值?如何将它们包含在网络中以正确进行反向传播?我修改了一个简单的卷积神经网络,使用分数最大池化代替$2 \times 2$最大池化,而没有使用这些值,结果表现得更差,这让我相信我们必须明确处理这些值。
这是我使用FMP的代码相关部分:
def add_layer_ops_FMP(conv_func, x_input, W, keep_prob_layer, training_phase): h_conv = conv_func(x_input, W, stride_l = 1) h_BN = batch_norm(h_conv, training_phase, epsilon) h_elu = tf.nn.elu(h_BN) # 整流层 - 根据需要更改 def dropout_no_training(h_elu=h_elu): return dropout_op(h_elu, keep_prob = 1.0) def dropout_in_training(h_elu=h_elu, keep_prob_layer=keep_prob_layer): return dropout_op(h_elu, keep_prob = keep_prob_layer) h_drop = tf.cond(training_phase, dropout_in_training, dropout_no_training) h_pool, row_pooling_sequence, col_pooling_sequence = tf.nn.fractional_max_pool(h_drop) # FMP层。参见Ben Graham的论文 return h_pool
回答:
- 我们是否需要处理
row_pooling_sequence
和col_pooling_sequence
?
尽管tf.nn.fractional_max_pool
文档说明它返回了2个额外的张量,这些张量是计算梯度所需的,但我认为我们不需要特别处理这两个额外的张量并将它们添加到梯度计算操作中。TensorFlow中tf.nn.fractional_max_pool
的反向传播已被注册到梯度计算流程中,通过_FractionalMaxPoolGrad
函数实现。正如您在_FractionalMaxPoolGrad
中看到的,row_pooling_sequence
和col_pooling_sequence
通过op.outputs[1]
和op.outputs[2]
提取,并用于计算梯度。
@ops.RegisterGradient("FractionalMaxPool")def _FractionalMaxPoolGrad(op, grad_0, unused_grad_1, unused_grad_2): """...""" return gen_nn_ops._fractional_max_pool_grad(op.inputs[0], op.outputs[0], grad_0, op.outputs[1], op.outputs[2], op.get_attr("overlapping"))
- 使用
fractional_max_pool
后性能变差的可能原因(我的个人观点)。
在分数最大池化论文中,作者在一个空间稀疏卷积网络中使用了分数最大池化。根据他的空间稀疏卷积网络设计,他实际上通过填充零来扩展图像输入的空间大小。此外,分数最大池化通过pooling_ratio
因子缩小输入,通常小于2。这两者结合在一起使得可以堆叠比使用常规最大池化更多的卷积层,从而构建更深的网络。(例如,想象使用CIFAR-10数据集,输入的空间大小为32×32,经过3个卷积层和3次最大池化操作后,空间大小下降到4×4。如果使用pooling_ratio=1.4
的分数最大池化,经过6个卷积层和6次分数最大池化层后,空间大小下降到4×4)。我尝试在MNIST数据集上构建了一个具有2个卷积层+2个池化层(常规最大池化与pooling_ratio=1.47
的分数最大池化)+2个全连接层的CNN。使用常规最大池化的模型表现优于使用分数最大池化的模型(性能下降了15~20%)。在输入全连接层之前比较空间大小,使用常规最大池化的模型的空间大小为7×7,使用分数最大池化的模型的空间大小为12×12。在后者的模型中增加一个conv+fractional_max_pool层(最终空间大小降至8×8)将性能提高到与前者使用常规最大池化的模型更为 comparable的水平。
总之,我个人认为分数最大池化论文中的良好表现是通过结合使用空间稀疏CNN与分数最大池化以及小滤波器(和网络中的网络)实现的,这些使得即使输入图像空间大小较小时也能构建深层网络。因此,在常规CNN网络中,简单地用分数最大池化替换常规最大池化并不一定能带来更好的性能。