def compareToTranspose(self, batch_size, out_height, out_width, in_channels, block_size, data_format, use_gpu): in_height = out_height * block_size in_width = out_width * block_size nhwc_input_shape = [batch_size, in_height, in_width, in_channels] nchw_input_shape = [batch_size, in_channels, in_height, in_width] total_size = np.prod(nhwc_input_shape) if data_format == "NCHW_VECT_C": # Initialize the input tensor with qint8 values that circle -127..127. x = [((f + 128) % 255) - 127 for f in range(total_size)] t = constant_op.constant(x, shape=nhwc_input_shape, dtype=dtypes.float32) expected = self.spaceToDepthUsingTranspose(t, block_size, "NHWC") t = test_util.NHWCToNCHW_VECT_C(t) t, _, _ = gen_array_ops.quantize_v2(t, -128.0, 127.0, dtypes.qint8) t = array_ops.space_to_depth(t, block_size, data_format="NCHW_VECT_C") t = gen_array_ops.dequantize(t, -128, 127) actual = test_util.NCHW_VECT_CToNHWC(t) else: # Initialize the input tensor with ascending whole numbers as floats. x = [f * 1.0 for f in range(total_size)] shape = nchw_input_shape if data_format == "NCHW" else nhwc_input_shape t = constant_op.constant(x, shape=shape, dtype=dtypes.float32) expected = self.spaceToDepthUsingTranspose(t, block_size, data_format) actual = array_ops.space_to_depth(t, block_size, data_format=data_format) with self.cached_session(use_gpu=use_gpu) as sess: actual_vals, expected_vals = sess.run([actual, expected]) self.assertTrue(np.array_equal(actual_vals, expected_vals))
def testSpaceToDepth(self): for dtype in self.numeric_types: self._assertOpOutputMatchesExpected( lambda x: array_ops.space_to_depth(x, block_size=2), np.array([[[[1], [2]], [[3], [4]]]], dtype=dtype), expected=np.array([[[[1, 2, 3, 4]]]], dtype=dtype)) self._assertOpOutputMatchesExpected( lambda x: array_ops.space_to_depth(x, block_size=2), np.array([[[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]], dtype=dtype), expected=np.array([[[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]]]], dtype=dtype)) self._assertOpOutputMatchesExpected( lambda x: array_ops.space_to_depth(x, block_size=2), np.array([[[[1], [2], [5], [6]], [[3], [4], [7], [8]], [[9], [10], [13], [14]], [[11], [12], [15], [16]]]], dtype=dtype), expected=np.array([[[[1, 2, 3, 4], [5, 6, 7, 8]], [[9, 10, 11, 12], [13, 14, 15, 16]]]], dtype=dtype))
def compareToTranspose(self, batch_size, out_height, out_width, in_channels, block_size, data_format, data_type, use_gpu): in_height = out_height * block_size in_width = out_width * block_size nhwc_input_shape = [batch_size, in_height, in_width, in_channels] nchw_input_shape = [batch_size, in_channels, in_height, in_width] total_size = np.prod(nhwc_input_shape) # Construct the input tensor in data_type and NHWC. # force_cpu is needed because quantize_v2 runs on only CPU. with test_util.force_cpu(): if data_type == dtypes.qint8: # Initialize the input tensor with qint8 values that circle -127..127. x = [((f + 128) % 255) - 127 for f in range(total_size)] t = constant_op.constant(x, shape=nhwc_input_shape, dtype=dtypes.float32) t, _, _ = gen_array_ops.quantize_v2(t, -128.0, 127.0, dtypes.qint8) else: assert data_type == dtypes.float32 # Initialize the input tensor with ascending whole numbers as floats. x = [f * 1.0 for f in range(total_size)] shape = nchw_input_shape if data_format == "NCHW" else nhwc_input_shape t = constant_op.constant(x, shape=shape, dtype=dtypes.float32) with test_util.device(use_gpu): if data_format == "NCHW_VECT_C": assert data_type == dtypes.qint8 # Convert to int8, then NHWCToNCHW_VECT_C, and then back to qint8. actual = array_ops.bitcast(t, dtypes.int8) actual = test_util.NHWCToNCHW_VECT_C(actual) actual = array_ops.bitcast(actual, dtypes.qint8) actual = array_ops.space_to_depth(actual, block_size, data_format=data_format) actual = array_ops.bitcast(actual, dtypes.int8) actual = test_util.NCHW_VECT_CToNHWC(actual) actual = array_ops.bitcast(actual, dtypes.qint8) expected = array_ops.bitcast(t, dtypes.int8) expected = math_ops.cast(expected, dtypes.float32) expected = self.spaceToDepthUsingTranspose( expected, block_size, "NHWC") expected = math_ops.cast(expected, dtypes.int8) expected = array_ops.bitcast(expected, dtypes.qint8) else: # Initialize the input tensor with ascending whole numbers as floats. actual = array_ops.space_to_depth(t, block_size, data_format=data_format) expected = self.spaceToDepthUsingTranspose( t, block_size, data_format) actual_vals, expected_vals = self.evaluate([actual, expected]) self.assertTrue(np.array_equal(actual_vals, expected_vals))
def _testOne(self, inputs, block_size, outputs, dtype=dtypes.float32): input_nhwc = math_ops.cast(inputs, dtype) # test NHWC (default) x_tf = array_ops.space_to_depth(input_nhwc, block_size) self.assertAllEqual(self.evaluate(x_tf), outputs) if test_util.is_gpu_available(): with test_util.force_gpu(): # test NCHW on GPU input_nchw = test_util.NHWCToNCHW(input_nhwc) output_nchw = array_ops.space_to_depth(input_nchw, block_size, data_format="NCHW") output_nhwc = test_util.NCHWToNHWC(output_nchw) self.assertAllEqual(self.evaluate(output_nhwc), outputs)
def testBlockSizeOne(self): # The block size is 1. The block size needs to be > 1. x_np = [[[[1], [2]], [[3], [4]]]] block_size = 1 with self.assertRaises(ValueError): out_tf = array_ops.space_to_depth(x_np, block_size) self.evaluate(out_tf)
def testBlockSizeLarger(self): # The block size is too large for this input. x_np = [[[[1], [2]], [[3], [4]]]] block_size = 10 with self.assertRaises(ValueError): out_tf = array_ops.space_to_depth(x_np, block_size) out_tf.eval()
def testBlockSizeLargerThanInput(self): # The block size is too large for this input. x_np = [[[[1], [2]], [[3], [4]]]] block_size = 10 with self.assertRaises(ValueError): out_tf = array_ops.space_to_depth(x_np, block_size) out_tf.eval()
def testBlockSizeOne(self): # The block size is 1. The block size needs to be > 1. x_np = [[[[1], [2]], [[3], [4]]]] block_size = 1 with self.assertRaises(ValueError): out_tf = array_ops.space_to_depth(x_np, block_size) out_tf.eval()
def testInputWrongDimMissingDepth(self): # The input is missing the last dimension ("depth") x_np = [[[1, 2], [3, 4]]] block_size = 2 with self.assertRaises(ValueError): out_tf = array_ops.space_to_depth(x_np, block_size) self.evaluate(out_tf)
def testBlockSize0(self): # The block size is 0. x_np = [[[[1], [2]], [[3], [4]]]] block_size = 0 with self.assertRaises(ValueError): out_tf = array_ops.space_to_depth(x_np, block_size) self.evaluate(out_tf)
def testInputWrongDimMissingDepth(self): # The input is missing the last dimension ("depth") x_np = [[[1, 2], [3, 4]]] block_size = 2 with self.assertRaises(ValueError): out_tf = array_ops.space_to_depth(x_np, block_size) out_tf.eval()
def testBlockSizeLarger(self): # The block size is too large for this input. x_np = [[[[1], [2]], [[3], [4]]]] block_size = 10 with self.assertRaises((ValueError, errors.InvalidArgumentError)): out_tf = array_ops.space_to_depth(x_np, block_size) self.evaluate(out_tf)
def compareToTranspose(self, data_format, use_gpu): if use_gpu and not test.is_gpu_available(): print("gpu not available") return dtype = dtypes.float32 batch_size = 3 height = 4 width = 6 channels = 4 block_size = 2 if data_format == "NHWC": input_shape = [batch_size, height, width, channels] elif data_format == "NCHW": input_shape = [batch_size, channels, height, width] else: print("unsupported format") # Initialize the input tensor with ascending whole numbers. total_size = 1 for dim_size in input_shape: total_size *= dim_size x = [f for f in range(total_size)] inputs = constant_op.constant(x, shape=input_shape, dtype=dtype) expected = self.spaceToDepthUsingTranspose(inputs, block_size, data_format) actual = array_ops.space_to_depth( inputs, block_size, data_format=data_format) with self.test_session(use_gpu=use_gpu) as sess: actual_vals, expected_vals = sess.run([actual, expected]) self.assertTrue(np.array_equal(actual_vals, expected_vals))
def testBlockSize0(self): # The block size is 0. x_np = [[[[1], [2]], [[3], [4]]]] block_size = 0 with self.assertRaises(ValueError): out_tf = array_ops.space_to_depth(x_np, block_size) out_tf.eval()
def testBatchSize0(self): block_size = 2 batch_size = 0 input_nhwc = array_ops.ones([batch_size, 4, 6, 3]) x_out = array_ops.ones([batch_size, 2, 3, 12]) with self.session(use_gpu=False): # test NHWC (default) on CPU x_tf = array_ops.space_to_depth(input_nhwc, block_size) self.assertAllEqual(x_tf.shape, x_out.shape) x_tf.eval() if test.is_gpu_available(): with self.session(use_gpu=True): # test NHWC (default) on GPU x_tf = array_ops.space_to_depth(input_nhwc, block_size) self.assertAllEqual(x_tf.shape, x_out.shape) x_tf.eval()
def _DepthToSpaceGrad(op, grad): # Its gradient is the opposite op: SpaceToDepth. block_size = op.get_attr("block_size") data_format = op.get_attr("data_format") if data_format == "NCHW_VECT_C": raise ValueError("Cannot compute DepthToSpace gradient with NCHW_VECT_C. " "NCHW_VECT_C requires qint8 data type.") return array_ops.space_to_depth(grad, block_size, data_format=data_format)
def testBatchSize0(self): block_size = 2 batch_size = 0 input_nhwc = array_ops.ones([batch_size, 4, 6, 3]) x_out = array_ops.ones([batch_size, 2, 3, 12]) with self.test_session(use_gpu=False): # test NHWC (default) on CPU x_tf = array_ops.space_to_depth(input_nhwc, block_size) self.assertAllEqual(x_tf.shape, x_out.shape) x_tf.eval() if test.is_gpu_available(): with self.test_session(use_gpu=True): # test NHWC (default) on GPU x_tf = array_ops.space_to_depth(input_nhwc, block_size) self.assertAllEqual(x_tf.shape, x_out.shape) x_tf.eval()
def _testOne(self, inputs, block_size, outputs): input_nhwc = math_ops.to_float(inputs) with self.test_session(use_gpu=False): # test NHWC (default) on CPU x_tf = array_ops.space_to_depth(input_nhwc, block_size) self.assertAllEqual(x_tf.eval(), outputs) if test.is_gpu_available(): with self.test_session(use_gpu=True): # test NHWC (default) on GPU x_tf = array_ops.space_to_depth(input_nhwc, block_size) self.assertAllEqual(x_tf.eval(), outputs) # test NCHW on GPU input_nchw = test_util.NHWCToNCHW(input_nhwc) output_nchw = array_ops.space_to_depth( input_nchw, block_size, data_format="NCHW") output_nhwc = test_util.NCHWToNHWC(output_nchw) self.assertAllEqual(output_nhwc.eval(), outputs)
def _testOne(self, inputs, block_size, outputs, dtype=dtypes.float32): input_nhwc = math_ops.cast(inputs, dtype) with self.cached_session(use_gpu=False): # test NHWC (default) on CPU x_tf = array_ops.space_to_depth(input_nhwc, block_size) self.assertAllEqual(x_tf.eval(), outputs) if test.is_gpu_available(): with self.cached_session(use_gpu=True): # test NHWC (default) on GPU x_tf = array_ops.space_to_depth(input_nhwc, block_size) self.assertAllEqual(x_tf.eval(), outputs) # test NCHW on GPU input_nchw = test_util.NHWCToNCHW(input_nhwc) output_nchw = array_ops.space_to_depth( input_nchw, block_size, data_format="NCHW") output_nhwc = test_util.NCHWToNHWC(output_nchw) self.assertAllEqual(output_nhwc.eval(), outputs)
def testBlockSizeNotDivisibleDepth(self): # The depth is not divisible by the square of the block size. x_np = [[[[1, 1, 1, 1], [2, 2, 2, 2]], [[3, 3, 3, 3], [4, 4, 4, 4]]]] block_size = 3 with self.assertRaises(ValueError): _ = array_ops.space_to_depth(x_np, block_size)
def testBatchSize0(self): block_size = 2 batch_size = 0 input_nhwc = array_ops.ones([batch_size, 4, 6, 3]) x_out = array_ops.ones([batch_size, 2, 3, 12]) with test_util.force_cpu(): # test NHWC (default) on CPU x_tf = array_ops.space_to_depth(input_nhwc, block_size) self.assertAllEqual(x_tf.shape, x_out.shape) self.evaluate(x_tf) if test.is_gpu_available(): with test_util.use_gpu(): # test NHWC (default) on GPU x_tf = array_ops.space_to_depth(input_nhwc, block_size) self.assertAllEqual(x_tf.shape, x_out.shape) self.evaluate(x_tf)
def _testOne(self, inputs, block_size, outputs, dtype=dtypes.float32): input_nhwc = math_ops.cast(inputs, dtype) with test_util.force_cpu(): # test NHWC (default) on CPU x_tf = array_ops.space_to_depth(input_nhwc, block_size) self.assertAllEqual(self.evaluate(x_tf), outputs) if test_util.is_gpu_available(): with test_util.force_gpu(): # test NHWC (default) on GPU x_tf = array_ops.space_to_depth(input_nhwc, block_size) self.assertAllEqual(self.evaluate(x_tf), outputs) # test NCHW on GPU input_nchw = test_util.NHWCToNCHW(input_nhwc) output_nchw = array_ops.space_to_depth( input_nchw, block_size, data_format="NCHW") output_nhwc = test_util.NCHWToNHWC(output_nchw) self.assertAllEqual(self.evaluate(output_nhwc), outputs)
def testSpaceToDepthTranspose(self): x = np.arange(5 * 10 * 16 * 7, dtype=np.float32).reshape([5, 10, 16, 7]) block_size = 2 paddings = np.zeros((2, 2), dtype=np.int32) y1 = self.space_to_batch(x, paddings, block_size=block_size) y2 = array_ops.transpose( array_ops.space_to_depth(array_ops.transpose(x, [3, 1, 2, 0]), block_size=block_size), [3, 1, 2, 0]) with self.session(): self.assertAllEqual(y1, y2)
def testSpaceToDepthTranspose(self): x = np.arange(5 * 10 * 16 * 7, dtype=np.float32).reshape([5, 10, 16, 7]) block_size = 2 paddings = np.zeros((2, 2), dtype=np.int32) y1 = self.space_to_batch(x, paddings, block_size=block_size) y2 = array_ops.transpose( array_ops.space_to_depth( array_ops.transpose(x, [3, 1, 2, 0]), block_size=block_size), [3, 1, 2, 0]) with self.test_session(use_gpu=True): self.assertAllEqual(y1.eval(), y2.eval())
def _checkGrad(self, x, block_size): assert 4 == x.ndim with self.test_session(use_gpu=True): tf_x = ops.convert_to_tensor(x) tf_y = array_ops.space_to_depth(tf_x, block_size) epsilon = 1e-2 ((x_jacob_t, x_jacob_n)) = gradient_checker.compute_gradient( tf_x, x.shape, tf_y, tf_y.get_shape().as_list(), x_init_value=x, delta=epsilon) self.assertAllClose(x_jacob_t, x_jacob_n, rtol=1e-2, atol=epsilon)
def _checkGrad(self, x, block_size, data_format): # NCHW is implemented for only GPU. if data_format == "NCHW" and not test.is_gpu_available(): return assert 4 == x.ndim with self.cached_session(use_gpu=True): tf_x = ops.convert_to_tensor(x) tf_y = array_ops.space_to_depth(tf_x, block_size, data_format=data_format) epsilon = 1e-2 ((x_jacob_t, x_jacob_n)) = gradient_checker.compute_gradient( tf_x, x.shape, tf_y, tf_y.get_shape().as_list(), x_init_value=x, delta=epsilon) self.assertAllClose(x_jacob_t, x_jacob_n, rtol=1e-2, atol=epsilon)
def testUnknownShape(self): t = array_ops.space_to_depth( array_ops.placeholder(dtypes.float32), block_size=4) self.assertEqual(4, t.get_shape().ndims)
def testBlockSizeNotDivisibleBoth(self): # The block size does not divide neither width or height. x_np = [[[[1], [2]], [[3], [4]]]] block_size = 3 with self.assertRaises(ValueError): _ = array_ops.space_to_depth(x_np, block_size)
def _DepthToSpaceGrad(op, grad): # Its gradient is the opposite op: SpaceToDepth. block_size = op.get_attr("block_size") return array_ops.space_to_depth(grad, block_size)
def testUnknownShape(self): # Testing an unkown shape in graph. with ops.Graph().as_default(): t = array_ops.space_to_depth(array_ops.placeholder(dtypes.float32), block_size=4) self.assertEqual(4, t.get_shape().ndims)
def func(x): return array_ops.space_to_depth(x, block_size, data_format=data_format)
def testInputWrongDimMissingBatch(self): # The input is missing the first dimension ("batch") x_np = [[[1], [2]], [[3], [4]]] block_size = 2 with self.assertRaises(ValueError): _ = array_ops.space_to_depth(x_np, block_size)
def _testOne(self, inputs, block_size, outputs): with self.test_session(use_gpu=True): x_tf = array_ops.space_to_depth(math_ops.to_float(inputs), block_size) self.assertAllEqual(x_tf.eval(), outputs)
def op(x): return array_ops.space_to_depth(x, block_size=2, data_format=data_format)
def testBlockSizeNotDivisibleWidth(self): # The block size divides width but not height. x_np = [[[[1], [2], [3]], [[3], [4], [7]]]] block_size = 3 with self.assertRaises(ValueError): _ = array_ops.space_to_depth(x_np, block_size)
def op(x): return array_ops.space_to_depth( x, block_size=2, data_format=data_format)
def testBlockSizeNotDivisibleHeight(self): # The block size divides height but not width. x_np = [[[[1], [2]], [[3], [4]], [[5], [6]]]] block_size = 3 with self.assertRaises(ValueError): _ = array_ops.space_to_depth(x_np, block_size)
def testUnknownShape(self): t = array_ops.space_to_depth(array_ops.placeholder(dtypes.float32), block_size=4) self.assertEqual(4, t.get_shape().ndims)
def loop_fn(i): x1 = array_ops.gather(x, i) return array_ops.space_to_depth(x1, 2, data_format="NHWC")