def testFuseResizeAndConv(self): with self.cached_session() as sess: inputs = [1, 4, 2, 5, 3, 6, -1, -4, -2, -5, -3, -6] input_op = constant_op.constant( np.array(inputs), shape=[1, 2, 3, 2], dtype=dtypes.float32) resize_op = image_ops.resize_bilinear( input_op, [12, 4], align_corners=False) weights = [1, 2, 3, 4, 0.1, 0.2, 0.3, 0.4] weights_op = constant_op.constant( np.array(weights), shape=[1, 2, 2, 2], dtype=dtypes.float32) nn_ops.conv2d( resize_op, weights_op, [1, 1, 1, 1], padding="VALID", name="output") original_graph_def = sess.graph_def original_result = sess.run(["output:0"]) optimized_graph_def = optimize_for_inference_lib.fuse_resize_and_conv( original_graph_def, ["output"]) with self.cached_session() as sess: _ = importer.import_graph_def( optimized_graph_def, input_map={}, name="optimized") optimized_result = sess.run(["optimized/output:0"]) self.assertAllClose(original_result, optimized_result) for node in optimized_graph_def.node: self.assertNotEqual("Conv2D", node.op) self.assertNotEqual("MirrorPad", node.op)
def preprocess_image( images, height=INCEPTION_DEFAULT_IMAGE_SIZE, width=INCEPTION_DEFAULT_IMAGE_SIZE, scope=None): """Prepare a batch of images for evaluation. This is the preprocessing portion of the graph from http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz. Note that it expects Tensors in [0, 255]. This function maps pixel values to [-1, 1] and resizes to match the InceptionV1 network. Args: images: 3-D or 4-D Tensor of images. Values are in [0, 255]. height: Integer. Height of resized output image. width: Integer. Width of resized output image. scope: Optional scope for name_scope. Returns: 3-D or 4-D float Tensor of prepared image(s). Values are in [-1, 1]. """ is_single = images.shape.ndims == 3 with ops.name_scope(scope, 'preprocess', [images, height, width]): if not images.dtype.is_floating: images = math_ops.to_float(images) if is_single: images = array_ops.expand_dims(images, axis=0) resized = image_ops.resize_bilinear(images, [height, width]) resized = (resized - 128.0) / 128.0 if is_single: resized = array_ops.squeeze(resized, axis=0) return resized
def testGradOnUnsupportedType(self): in_shape = [1, 4, 6, 1] out_shape = [1, 2, 3, 1] x = np.arange(0, 24).reshape(in_shape).astype(np.uint8) with self.test_session(): input_tensor = constant_op.constant(x, shape=in_shape) resize_out = image_ops.resize_bilinear(input_tensor, out_shape[1:3]) grad = gradients_impl.gradients(input_tensor, [resize_out]) self.assertEqual([None], grad)
def testGradFromResizeToSmallerInBothDims(self): in_shape = [1, 4, 6, 1] out_shape = [1, 2, 3, 1] x = np.arange(0, 24).reshape(in_shape).astype(np.float32) with self.test_session(): input_tensor = constant_op.constant(x, shape=in_shape) resize_out = image_ops.resize_bilinear(input_tensor, out_shape[1:3]) err = gradient_checker.compute_gradient_error( input_tensor, in_shape, resize_out, out_shape, x_init_value=x) self.assertLess(err, 1e-3)
def testShapeIsCorrectAfterOp(self): in_shape = [1, 2, 2, 1] out_shape = [1, 4, 6, 1] x = np.arange(0, 4).reshape(in_shape).astype(np.float32) with self.test_session() as sess: input_tensor = constant_op.constant(x, shape=in_shape) resize_out = image_ops.resize_bilinear(input_tensor, out_shape[1:3]) self.assertEqual(out_shape, list(resize_out.get_shape())) resize_out = sess.run(resize_out) self.assertEqual(out_shape, list(resize_out.shape))
def testGradFromResizeToSmallerInBothDims(self): in_shape = [1, 4, 6, 1] out_shape = [1, 2, 3, 1] x = np.arange(0, 24).reshape(in_shape).astype(np.float32) with self.cached_session(): input_tensor = constant_op.constant(x, shape=in_shape) resize_out = image_ops.resize_bilinear(input_tensor, out_shape[1:3]) err = gradient_checker.compute_gradient_error(input_tensor, in_shape, resize_out, out_shape, x_init_value=x) self.assertLess(err, 1e-3)
def testShapes(self, batch_size, channel_count): smaller_shape = [batch_size, 2, 3, channel_count] larger_shape = [batch_size, 4, 6, channel_count] for in_shape, out_shape, align_corners, half_pixel_centers in \ self._itGen(smaller_shape, larger_shape): # Input values should not influence shapes x = np.arange(np.prod(in_shape)).reshape(in_shape).astype(np.float32) input_tensor = constant_op.constant(x, shape=in_shape) resized_tensor = image_ops.resize_bilinear(input_tensor, out_shape[1:3]) self.assertEqual(out_shape, list(resized_tensor.get_shape())) grad_tensor = gradients_impl.gradients(resized_tensor, input_tensor)[0] self.assertEqual(in_shape, list(grad_tensor.get_shape())) with self.cached_session(): resized_values = self.evaluate(resized_tensor) self.assertEqual(out_shape, list(resized_values.shape)) grad_values = self.evaluate(grad_tensor) self.assertEqual(in_shape, list(grad_values.shape))
def testCompareGpuVsCpu(self): in_shape = [2, 4, 6, 3] out_shape = [2, 8, 16, 3] size = np.prod(in_shape) x = 1.0 / size * np.arange(0, size).reshape(in_shape).astype(np.float32) for align_corners in [True, False]: grad = {} for use_gpu in [False, True]: with self.cached_session(use_gpu=use_gpu): input_tensor = constant_op.constant(x, shape=in_shape) resized_tensor = image_ops.resize_bilinear( input_tensor, out_shape[1:3], align_corners=align_corners) grad[use_gpu] = gradient_checker.compute_gradient( input_tensor, in_shape, resized_tensor, out_shape, x_init_value=x) self.assertAllClose(grad[False], grad[True], rtol=1e-4, atol=1e-4)
def testCompareGpuVsCpu(self): in_shape = [2, 4, 6, 3] out_shape = [2, 8, 16, 3] size = np.prod(in_shape) x = 1.0 / size * np.arange(0, size).reshape(in_shape).astype(np.float32) for align_corners in [True, False]: grad = {} for use_gpu in [False, True]: with self.test_session(use_gpu=use_gpu): input_tensor = constant_op.constant(x, shape=in_shape) resized_tensor = image_ops.resize_bilinear( input_tensor, out_shape[1:3], align_corners=align_corners) grad[use_gpu] = gradient_checker.compute_gradient( input_tensor, in_shape, resized_tensor, out_shape, x_init_value=x) self.assertAllClose(grad[False], grad[True], rtol=1e-4, atol=1e-4)
def testTypes(self): in_shape = [1, 4, 6, 1] out_shape = [1, 2, 3, 1] x = np.arange(0, 24).reshape(in_shape) with self.cached_session() as sess: for dtype in [np.float16, np.float32, np.float64]: input_tensor = constant_op.constant(x.astype(dtype), shape=in_shape) resize_out = image_ops.resize_bilinear(input_tensor, out_shape[1:3]) grad = sess.run(gradients_impl.gradients(resize_out, input_tensor))[0] self.assertAllEqual(in_shape, grad.shape) # Not using gradient_checker.compute_gradient as I didn't work out # the changes required to compensate for the lower precision of # float16 when computing the numeric jacobian. # Instead, we just test the theoretical jacobian. self.assertAllEqual([[[[1.], [0.], [1.], [0.], [1.], [0.]], [[0.], [ 0. ], [0.], [0.], [0.], [0.]], [[1.], [0.], [1.], [0.], [1.], [0.]], [[0.], [0.], [0.], [0.], [0.], [0.]]]], grad)
def testTypes(self): in_shape = [1, 4, 6, 1] out_shape = [1, 2, 3, 1] x = np.arange(0, 24).reshape(in_shape) with self.cached_session() as sess: for dtype in [np.float16, np.float32, np.float64]: input_tensor = constant_op.constant(x.astype(dtype), shape=in_shape) resize_out = image_ops.resize_bilinear(input_tensor, out_shape[1:3]) grad = sess.run(gradients_impl.gradients(resize_out, input_tensor))[0] self.assertAllEqual(in_shape, grad.shape) # Not using gradient_checker.compute_gradient as I didn't work out # the changes required to compensate for the lower precision of # float16 when computing the numeric jacobian. # Instead, we just test the theoretical jacobian. self.assertAllEqual([[[[1.], [0.], [1.], [0.], [1.], [0.]], [[0.], [ 0. ], [0.], [0.], [0.], [0.]], [[1.], [0.], [1.], [0.], [1.], [0.]], [[0.], [0.], [0.], [0.], [0.], [0.]]]], grad)
def _getJacobians(self, in_shape, out_shape, align_corners=False, half_pixel_centers=False, dtype=np.float32, use_gpu=False, force_gpu=False): with self.cached_session(use_gpu=use_gpu, force_gpu=force_gpu) as sess: # Input values should not influence gradients x = np.arange(np.prod(in_shape)).reshape(in_shape).astype(dtype) input_tensor = constant_op.constant(x, shape=in_shape) resized_tensor = image_ops.resize_bilinear( input_tensor, out_shape[1:3], align_corners=align_corners, half_pixel_centers=half_pixel_centers) # compute_gradient will use a random tensor as the init value return gradient_checker.compute_gradient(input_tensor, in_shape, resized_tensor, out_shape)
def preprocess_image(image, height=INCEPTION_V3_DEFAULT_IMG_SIZE, width=INCEPTION_V3_DEFAULT_IMG_SIZE, central_fraction=0.875, scope=None): """Prepare one image for evaluation. If height and width are specified it would output an image with that size by applying resize_bilinear. If central_fraction is specified it would crop the central fraction of the input image. Args: image: 3-D Tensor of image. If dtype is tf.float32 then the range should be [0, 1], otherwise it would converted to tf.float32 assuming that the range is [0, MAX], where MAX is largest positive representable number for int(8/16/32) data type (see `tf.image.convert_image_dtype` for details). height: integer width: integer central_fraction: Optional Float, fraction of the image to crop. scope: Optional scope for name_scope. Returns: 3-D float Tensor of prepared image. """ with ops.name_scope(scope, 'eval_image', [image, height, width]): if image.dtype != dtypes.float32: image = image_ops.convert_image_dtype(image, dtype=dtypes.float32) # Crop the central region of the image with an area containing 87.5% of # the original image. image = image_ops.central_crop(image, central_fraction=central_fraction) # Resize the image to the specified height and width. image = array_ops.expand_dims(image, 0) image = image_ops.resize_bilinear(image, [height, width], align_corners=False) image = array_ops.squeeze(image, [0]) image = (image - 0.5) * 2.0 return image
def testCompareGpuVsCpu(self): in_shape = [2, 4, 6, 3] out_shape = [2, 8, 16, 3] size = np.prod(in_shape) x = 1.0 / size * np.arange(0, size).reshape(in_shape).astype(np.float32) # Align corners will be deprecated for tf2.0 and the false version is not # supported by XLA. align_corner_options = [True ] if test_util.is_xla_enabled() else [True, False] for align_corners in align_corner_options: grad = {} for use_gpu in [False, True]: with self.cached_session(use_gpu=use_gpu): input_tensor = constant_op.constant(x, shape=in_shape) resized_tensor = image_ops.resize_bilinear( input_tensor, out_shape[1:3], align_corners=align_corners) grad[use_gpu] = gradient_checker.compute_gradient( input_tensor, in_shape, resized_tensor, out_shape, x_init_value=x) self.assertAllClose(grad[False], grad[True], rtol=1e-4, atol=1e-4)
def preprocess_image( image, height=INCEPTION_V3_DEFAULT_IMG_SIZE, width=INCEPTION_V3_DEFAULT_IMG_SIZE, central_fraction=0.875, scope=None): """Prepare one image for evaluation. If height and width are specified it would output an image with that size by applying resize_bilinear. If central_fraction is specified it would crop the central fraction of the input image. Args: image: 3-D Tensor of image. If dtype is tf.float32 then the range should be [0, 1], otherwise it would converted to tf.float32 assuming that the range is [0, MAX], where MAX is largest positive representable number for int(8/16/32) data type (see `tf.image.convert_image_dtype` for details). height: integer width: integer central_fraction: Optional Float, fraction of the image to crop. scope: Optional scope for name_scope. Returns: 3-D float Tensor of prepared image. """ with ops.name_scope(scope, 'eval_image', [image, height, width]): if image.dtype != dtypes.float32: image = image_ops.convert_image_dtype(image, dtype=dtypes.float32) # Crop the central region of the image with an area containing 87.5% of # the original image. image = image_ops.central_crop(image, central_fraction=central_fraction) # Resize the image to the specified height and width. image = array_ops.expand_dims(image, 0) image = image_ops.resize_bilinear(image, [height, width], align_corners=False) image = array_ops.squeeze(image, [0]) image = (image - 0.5) * 2.0 return image
def _testShapesParameterized(self, use_tape): TEST_CASES = [[1, 1], [2, 3], [5, 4]] # pylint: disable=invalid-name for batch_size, channel_count in TEST_CASES: smaller_shape = [batch_size, 2, 3, channel_count] larger_shape = [batch_size, 4, 6, channel_count] for in_shape, out_shape, _, _ in self._itGen(smaller_shape, larger_shape): with test_util.AbstractGradientTape(use_tape=use_tape) as tape: # Input values should not influence shapes x = np.arange(np.prod(in_shape)).reshape(in_shape).astype(np.float32) input_tensor = constant_op.constant(x, shape=in_shape) tape.watch(input_tensor) resized_tensor = image_ops.resize_bilinear(input_tensor, out_shape[1:3]) self.assertEqual(out_shape, list(resized_tensor.get_shape())) grad_tensor = tape.gradient(resized_tensor, input_tensor) self.assertEqual(in_shape, list(grad_tensor.get_shape())) with self.cached_session(): resized_values = self.evaluate(resized_tensor) self.assertEqual(out_shape, list(resized_values.shape)) grad_values = self.evaluate(grad_tensor) self.assertEqual(in_shape, list(grad_values.shape))
def func(in_tensor): return image_ops.resize_bilinear( in_tensor, out_shape[1:3], align_corners=align_corners, half_pixel_centers=half_pixel_centers)
def testDeterministicGradients(self, align_corners, half_pixel_centers, data_type): if not align_corners and test_util.is_xla_enabled(): # Align corners is deprecated in TF2.0, but align_corners==False is not # supported by XLA. self.skipTest( 'align_corners==False not currently supported by XLA') with self.session(force_gpu=True): seed = (hash(align_corners) % 256 + hash(half_pixel_centers) % 256 + hash(data_type) % 256) np.random.seed(seed) input_shape = (1, 25, 12, 3) # NHWC output_shape = (1, 200, 250, 3) input_image = self._randomDataOp(input_shape, data_type) repeat_count = 3 if context.executing_eagerly(): def resize_bilinear_gradients(local_seed): np.random.seed(local_seed) upstream_gradients = self._randomDataOp( output_shape, dtypes.float32) with backprop.GradientTape(persistent=True) as tape: tape.watch(input_image) output_image = image_ops.resize_bilinear( input_image, output_shape[1:3], align_corners=align_corners, half_pixel_centers=half_pixel_centers) gradient_injector_output = output_image * upstream_gradients return tape.gradient(gradient_injector_output, input_image) for i in range(repeat_count): local_seed = seed + i # select different upstream gradients result_a = resize_bilinear_gradients(local_seed) result_b = resize_bilinear_gradients(local_seed) self.assertAllEqual(result_a, result_b) else: # graph mode upstream_gradients = array_ops.placeholder( dtypes.float32, shape=output_shape, name='upstream_gradients') output_image = image_ops.resize_bilinear( input_image, output_shape[1:3], align_corners=align_corners, half_pixel_centers=half_pixel_centers) gradient_injector_output = output_image * upstream_gradients # The gradient function behaves as if grad_ys is multiplied by the op # gradient result, not passing the upstream gradients through the op's # gradient generation graph. This is the reason for using the # gradient injector resize_bilinear_gradients = gradients_impl.gradients( gradient_injector_output, input_image, grad_ys=None, colocate_gradients_with_ops=True)[0] for i in range(repeat_count): feed_dict = { upstream_gradients: self._randomNDArray(output_shape) } result_a = resize_bilinear_gradients.eval( feed_dict=feed_dict) result_b = resize_bilinear_gradients.eval( feed_dict=feed_dict) self.assertAllEqual(result_a, result_b)
def _resize_image(image, height, width): image = array_ops.expand_dims(image, 0) image = image_ops.resize_bilinear(image, [height, width]) return array_ops.squeeze(image, [0])
def _resize_image(image, height, width): image = array_ops.expand_dims(image, 0) image = image_ops.resize_bilinear(image, [height, width]) return array_ops.squeeze(image, [0])