为什么tf.nn.separable_conv2d使用with_space_to_batch?

时间:2017-05-09 08:43:35

标签: tensorflow

tf.nn.separable_conv2d的实施使用tf.nn.with_space_to_batch。但是,当tf.nn.with_space_to_batch被删除时,我发现输出没有任何差异。空间批处理的目的是什么?这是一个低级优化吗?

相关代码;

import unittest

import numpy as np
import tensorflow as tf


class TestTensorflowSeparableWithoutSpaceToBatch(unittest.TestCase):
    def setUp(self):
        #  filter height, filter width, in_channels, channel_multiplier
        self.depthwise_weights = np.random.rand(3, 3, 16, 3).astype(np.float32)
        self.pointwise_weights = np.random.rand(1, 1, 48, 64).astype(np.float32)
        #  batch size, height, width, channels
        self.input_batch = np.random.rand(20, 224, 224, 16).astype(np.float32)

    def __test_with_configuration(self, strides=1, padding="SAME"):
        with tf.Session() as sess:
            input_placeholder = tf.placeholder(tf.float32, shape=[None, 224, 224, 16])

            # separable without space to batch
            depthwise_nostb = tf.nn.depthwise_conv2d_native(input=input_placeholder,
                                                            filter=self.depthwise_weights,
                                                            strides=[1, strides, strides, 1],
                                                            padding=padding,
                                                            name="depthwise_only")
            separable_nostb = tf.nn.conv2d(depthwise_nostb,
                                           filter=self.pointwise_weights,
                                           strides=[1, 1, 1, 1],
                                           padding=padding)

            # separable with space to batch
            separable_stb = tf.nn.separable_conv2d(input_placeholder,
                                                   depthwise_filter=self.depthwise_weights,
                                                   pointwise_filter=self.pointwise_weights,
                                                   strides=[1, strides, strides, 1],
                                                   padding=padding)
            tf.nn.with_space_to_batch()
            sess.run(tf.global_variables_initializer())

            nostb, stb, = sess.run([separable_nostb, separable_stb], feed_dict={input_placeholder: self.input_batch})

            np.testing.assert_array_equal(stb, nostb,
                                          err_msg="output of tensorflow implementation is different than ours")
            sess.close()

    def test_stride_1_padding_same(self):
        self.__test_with_configuration(strides=1, padding="SAME")

    def test_stride_2_padding_same(self):
        self.__test_with_configuration(strides=2, padding="SAME")

    def test_stride_3_padding_same(self):
        self.__test_with_configuration(strides=3, padding="SAME")

    def test_stride_1_padding_valid(self):
        self.__test_with_configuration(strides=1, padding="VALID")

    def test_stride_2_padding_valid(self):
        self.__test_with_configuration(strides=2, padding="VALID")

    def test_stride_3_padding_valid(self):
        self.__test_with_configuration(strides=3, padding="VALID")


if __name__ == '__main__':
    unittest.main()

1 个答案:

答案 0 :(得分:2)

您可能想要的所有详细信息都在描述with_space_to_batch的评论中 https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/ops/nn_ops.py#L149

特别注意以下文字: "在dilation_rate统一为1的特殊情况下,这只会返回:op(input, num_spatial_dims, padding)"。

所以除非你有扩张的卷积,否则space_to_batch什么都不做。