• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ==============================================================================
15"""Tests for image preprocessing layers."""
16
17from __future__ import absolute_import
18from __future__ import division
19from __future__ import print_function
20
21from absl.testing import parameterized
22import numpy as np
23
24from tensorflow.python.compat import compat
25from tensorflow.python.distribute.mirrored_strategy import MirroredStrategy
26from tensorflow.python.framework import errors
27from tensorflow.python.keras import keras_parameterized
28from tensorflow.python.keras import testing_utils
29from tensorflow.python.keras.engine import sequential
30from tensorflow.python.keras.layers.preprocessing import image_preprocessing
31from tensorflow.python.keras.utils.generic_utils import CustomObjectScope
32from tensorflow.python.ops import gen_stateful_random_ops
33from tensorflow.python.ops import gen_stateless_random_ops_v2
34from tensorflow.python.ops import image_ops_impl as image_ops
35from tensorflow.python.ops import math_ops
36from tensorflow.python.ops import random_ops
37from tensorflow.python.ops import stateless_random_ops
38from tensorflow.python.platform import test
39
40
41@keras_parameterized.run_all_keras_modes(always_skip_v1=True)
42class ResizingTest(keras_parameterized.TestCase):
43
44  def _run_test(self, kwargs, expected_height, expected_width):
45    np.random.seed(1337)
46    num_samples = 2
47    orig_height = 5
48    orig_width = 8
49    channels = 3
50    kwargs.update({'height': expected_height, 'width': expected_width})
51    with testing_utils.use_gpu():
52      testing_utils.layer_test(
53          image_preprocessing.Resizing,
54          kwargs=kwargs,
55          input_shape=(num_samples, orig_height, orig_width, channels),
56          expected_output_shape=(None, expected_height, expected_width,
57                                 channels))
58
59  @parameterized.named_parameters(('down_sample_bilinear_2_by_2', {
60      'interpolation': 'bilinear'
61  }, 2, 2), ('down_sample_bilinear_3_by_2', {
62      'interpolation': 'bilinear'
63  }, 3, 2), ('down_sample_nearest_2_by_2', {
64      'interpolation': 'nearest'
65  }, 2, 2), ('down_sample_nearest_3_by_2', {
66      'interpolation': 'nearest'
67  }, 3, 2), ('down_sample_area_2_by_2', {
68      'interpolation': 'area'
69  }, 2, 2), ('down_sample_area_3_by_2', {
70      'interpolation': 'area'
71  }, 3, 2))
72  def test_down_sampling(self, kwargs, expected_height, expected_width):
73    with CustomObjectScope({'Resizing': image_preprocessing.Resizing}):
74      self._run_test(kwargs, expected_height, expected_width)
75
76  @parameterized.named_parameters(('up_sample_bilinear_10_by_12', {
77      'interpolation': 'bilinear'
78  }, 10, 12), ('up_sample_bilinear_12_by_12', {
79      'interpolation': 'bilinear'
80  }, 12, 12), ('up_sample_nearest_10_by_12', {
81      'interpolation': 'nearest'
82  }, 10, 12), ('up_sample_nearest_12_by_12', {
83      'interpolation': 'nearest'
84  }, 12, 12), ('up_sample_area_10_by_12', {
85      'interpolation': 'area'
86  }, 10, 12), ('up_sample_area_12_by_12', {
87      'interpolation': 'area'
88  }, 12, 12))
89  def test_up_sampling(self, kwargs, expected_height, expected_width):
90    with CustomObjectScope({'Resizing': image_preprocessing.Resizing}):
91      self._run_test(kwargs, expected_height, expected_width)
92
93  def test_down_sampling_numeric(self):
94    for dtype in (np.int64, np.float32):
95      with testing_utils.use_gpu():
96        input_image = np.reshape(np.arange(0, 16), (1, 4, 4, 1)).astype(dtype)
97        layer = image_preprocessing.Resizing(
98            height=2, width=2, interpolation='nearest')
99        output_image = layer(input_image)
100        # pyformat: disable
101        expected_output = np.asarray([
102            [5, 7],
103            [13, 15]
104        ]).astype(dtype)
105        # pyformat: enable
106        expected_output = np.reshape(expected_output, (1, 2, 2, 1))
107        self.assertAllEqual(expected_output, output_image)
108
109  def test_up_sampling_numeric(self):
110    for dtype in (np.int64, np.float32):
111      with testing_utils.use_gpu():
112        input_image = np.reshape(np.arange(0, 4), (1, 2, 2, 1)).astype(dtype)
113        layer = image_preprocessing.Resizing(
114            height=4, width=4, interpolation='nearest')
115        output_image = layer(input_image)
116        # pyformat: disable
117        expected_output = np.asarray([
118            [0, 0, 1, 1],
119            [0, 0, 1, 1],
120            [2, 2, 3, 3],
121            [2, 2, 3, 3]
122        ]).astype(dtype)
123        # pyformat: enable
124        expected_output = np.reshape(expected_output, (1, 4, 4, 1))
125        self.assertAllEqual(expected_output, output_image)
126
127  @parameterized.named_parameters(('reshape_bilinear_10_by_4', {
128      'interpolation': 'bilinear'
129  }, 10, 4))
130  def test_reshaping(self, kwargs, expected_height, expected_width):
131    with CustomObjectScope({'Resizing': image_preprocessing.Resizing}):
132      self._run_test(kwargs, expected_height, expected_width)
133
134  def test_invalid_interpolation(self):
135    with self.assertRaises(NotImplementedError):
136      image_preprocessing.Resizing(5, 5, 'invalid_interpolation')
137
138  def test_config_with_custom_name(self):
139    layer = image_preprocessing.Resizing(5, 5, name='image_preproc')
140    config = layer.get_config()
141    layer_1 = image_preprocessing.Resizing.from_config(config)
142    self.assertEqual(layer_1.name, layer.name)
143
144
145def get_numpy_center_crop(images, expected_height, expected_width):
146  orig_height = images.shape[1]
147  orig_width = images.shape[2]
148  height_start = int((orig_height - expected_height) / 2)
149  width_start = int((orig_width - expected_width) / 2)
150  height_end = height_start + expected_height
151  width_end = width_start + expected_width
152  return images[:, height_start:height_end, width_start:width_end, :]
153
154
155@keras_parameterized.run_all_keras_modes(always_skip_v1=True)
156class CenterCropTest(keras_parameterized.TestCase):
157
158  def _run_test(self, expected_height, expected_width):
159    np.random.seed(1337)
160    num_samples = 2
161    orig_height = 5
162    orig_width = 8
163    channels = 3
164    kwargs = {'height': expected_height, 'width': expected_width}
165    input_images = np.random.random(
166        (num_samples, orig_height, orig_width, channels)).astype(np.float32)
167    expected_output = get_numpy_center_crop(input_images, expected_height,
168                                            expected_width)
169    with testing_utils.use_gpu():
170      testing_utils.layer_test(
171          image_preprocessing.CenterCrop,
172          kwargs=kwargs,
173          input_shape=(num_samples, orig_height, orig_width, channels),
174          input_data=input_images,
175          expected_output=expected_output,
176          expected_output_shape=(None, expected_height, expected_width,
177                                 channels))
178
179  @parameterized.named_parameters(('center_crop_3_by_4', 3, 4),
180                                  ('center_crop_3_by_2', 3, 2))
181  def test_center_crop_aligned(self, expected_height, expected_width):
182    with CustomObjectScope({'CenterCrop': image_preprocessing.CenterCrop}):
183      self._run_test(expected_height, expected_width)
184
185  @parameterized.named_parameters(('center_crop_4_by_5', 4, 5),
186                                  ('center_crop_4_by_3', 4, 3))
187  def test_center_crop_mis_aligned(self, expected_height, expected_width):
188    with CustomObjectScope({'CenterCrop': image_preprocessing.CenterCrop}):
189      self._run_test(expected_height, expected_width)
190
191  @parameterized.named_parameters(('center_crop_4_by_6', 4, 6),
192                                  ('center_crop_3_by_2', 3, 2))
193  def test_center_crop_half_mis_aligned(self, expected_height, expected_width):
194    with CustomObjectScope({'CenterCrop': image_preprocessing.CenterCrop}):
195      self._run_test(expected_height, expected_width)
196
197  @parameterized.named_parameters(('center_crop_5_by_12', 5, 12),
198                                  ('center_crop_10_by_8', 10, 8),
199                                  ('center_crop_10_by_12', 10, 12))
200  def test_invalid_center_crop(self, expected_height, expected_width):
201    # InternelError is raised by tf.function MLIR lowering pass when TFRT
202    # is enabled.
203    with self.assertRaisesRegex(
204        (errors.InvalidArgumentError, errors.InternalError),
205        r'assertion failed|error: \'tf.Slice\' op'):
206      self._run_test(expected_height, expected_width)
207
208  def test_config_with_custom_name(self):
209    layer = image_preprocessing.CenterCrop(5, 5, name='image_preproc')
210    config = layer.get_config()
211    layer_1 = image_preprocessing.CenterCrop.from_config(config)
212    self.assertEqual(layer_1.name, layer.name)
213
214
215@keras_parameterized.run_all_keras_modes(always_skip_v1=True)
216class RandomCropTest(keras_parameterized.TestCase):
217
218  def _run_test(self, expected_height, expected_width):
219    np.random.seed(1337)
220    num_samples = 2
221    orig_height = 5
222    orig_width = 8
223    channels = 3
224    kwargs = {'height': expected_height, 'width': expected_width}
225    with testing_utils.use_gpu():
226      testing_utils.layer_test(
227          image_preprocessing.RandomCrop,
228          kwargs=kwargs,
229          input_shape=(num_samples, orig_height, orig_width, channels),
230          expected_output_shape=(None, expected_height, expected_width,
231                                 channels))
232
233  @parameterized.named_parameters(('random_crop_5_by_12', 5, 12),
234                                  ('random_crop_10_by_8', 10, 8),
235                                  ('random_crop_10_by_12', 10, 12))
236  def test_invalid_random_crop(self, expected_height, expected_width):
237    # InternelError is raised by tf.function MLIR lowering pass when TFRT
238    # is enabled.
239    with self.assertRaises((errors.InvalidArgumentError, errors.InternalError)):
240      with CustomObjectScope({'RandomCrop': image_preprocessing.RandomCrop}):
241        self._run_test(expected_height, expected_width)
242
243  def test_training_with_mock(self):
244    np.random.seed(1337)
245    height, width = 3, 4
246    height_offset = np.random.randint(low=0, high=3)
247    width_offset = np.random.randint(low=0, high=5)
248    mock_offset = [0, height_offset, width_offset, 0]
249    with test.mock.patch.object(
250        stateless_random_ops,
251        'stateless_random_uniform',
252        return_value=mock_offset):
253      with testing_utils.use_gpu():
254        layer = image_preprocessing.RandomCrop(height, width)
255        inp = np.random.random((12, 5, 8, 3))
256        actual_output = layer(inp, training=1)
257        expected_output = inp[:, height_offset:(height_offset + height),
258                              width_offset:(width_offset + width), :]
259        self.assertAllClose(expected_output, actual_output)
260
261  @parameterized.named_parameters(('random_crop_4_by_6', 4, 6),
262                                  ('random_crop_3_by_2', 3, 2))
263  def test_random_crop_output_shape(self, expected_height, expected_width):
264    with CustomObjectScope({'RandomCrop': image_preprocessing.RandomCrop}):
265      self._run_test(expected_height, expected_width)
266
267  def test_random_crop_full_height(self):
268    self._run_test(5, 2)
269
270  def test_random_crop_full_width(self):
271    self._run_test(3, 8)
272
273  def test_random_crop_full(self):
274    np.random.seed(1337)
275    height, width = 8, 16
276    inp = np.random.random((12, 8, 16, 3))
277    with testing_utils.use_gpu():
278      layer = image_preprocessing.RandomCrop(height, width)
279      actual_output = layer(inp, training=0)
280      self.assertAllClose(inp, actual_output)
281
282  def test_predicting_with_mock_longer_height(self):
283    np.random.seed(1337)
284    height, width = 3, 3
285    inp = np.random.random((12, 10, 6, 3))
286    with testing_utils.use_gpu():
287      layer = image_preprocessing.RandomCrop(height, width)
288      actual_output = layer(inp, training=0)
289      resized_inp = image_ops.resize_images_v2(inp, size=[5, 3])
290      expected_output = resized_inp[:, 1:4, :, :]
291      self.assertAllClose(expected_output, actual_output)
292
293  def test_predicting_with_mock_longer_width(self):
294    np.random.seed(1337)
295    height, width = 4, 6
296    inp = np.random.random((12, 8, 16, 3))
297    with testing_utils.use_gpu():
298      layer = image_preprocessing.RandomCrop(height, width)
299      actual_output = layer(inp, training=0)
300      resized_inp = image_ops.resize_images_v2(inp, size=[4, 8])
301      expected_output = resized_inp[:, :, 1:7, :]
302      self.assertAllClose(expected_output, actual_output)
303
304  def test_config_with_custom_name(self):
305    layer = image_preprocessing.RandomCrop(5, 5, name='image_preproc')
306    config = layer.get_config()
307    layer_1 = image_preprocessing.RandomCrop.from_config(config)
308    self.assertEqual(layer_1.name, layer.name)
309
310
311class RescalingTest(keras_parameterized.TestCase):
312
313  @keras_parameterized.run_all_keras_modes(always_skip_v1=True)
314  def test_rescaling_base(self):
315    kwargs = {'scale': 1. / 127.5, 'offset': -1.}
316    testing_utils.layer_test(
317        image_preprocessing.Rescaling,
318        kwargs=kwargs,
319        input_shape=(2, 5, 6, 3),
320        expected_output_shape=(None, 5, 6, 3))
321
322  @testing_utils.run_v2_only
323  def test_rescaling_correctness_float(self):
324    layer = image_preprocessing.Rescaling(scale=1. / 127.5, offset=-1.)
325    inputs = random_ops.random_uniform((2, 4, 5, 3))
326    outputs = layer(inputs)
327    self.assertAllClose(outputs.numpy(), inputs.numpy() * (1. / 127.5) - 1)
328
329  @testing_utils.run_v2_only
330  def test_rescaling_correctness_int(self):
331    layer = image_preprocessing.Rescaling(scale=1. / 127.5, offset=-1)
332    inputs = random_ops.random_uniform((2, 4, 5, 3), 0, 100, dtype='int32')
333    outputs = layer(inputs)
334    self.assertEqual(outputs.dtype.name, 'float32')
335    self.assertAllClose(outputs.numpy(), inputs.numpy() * (1. / 127.5) - 1)
336
337  def test_config_with_custom_name(self):
338    layer = image_preprocessing.Rescaling(0.5, name='rescaling')
339    config = layer.get_config()
340    layer_1 = image_preprocessing.Rescaling.from_config(config)
341    self.assertEqual(layer_1.name, layer.name)
342
343
344@keras_parameterized.run_all_keras_modes(always_skip_v1=True)
345class RandomFlipTest(keras_parameterized.TestCase):
346
347  def _run_test(self, mode, expected_output=None, mock_random=None):
348    np.random.seed(1337)
349    num_samples = 2
350    orig_height = 5
351    orig_width = 8
352    channels = 3
353    if mock_random is None:
354      mock_random = [1 for _ in range(num_samples)]
355      mock_random = np.reshape(mock_random, [2, 1, 1, 1])
356    inp = np.random.random((num_samples, orig_height, orig_width, channels))
357    if expected_output is None:
358      expected_output = inp
359      if mode == 'horizontal' or mode == 'horizontal_and_vertical':
360        expected_output = np.flip(expected_output, axis=2)
361      if mode == 'vertical' or mode == 'horizontal_and_vertical':
362        expected_output = np.flip(expected_output, axis=1)
363    with test.mock.patch.object(
364        random_ops, 'random_uniform', return_value=mock_random):
365      with testing_utils.use_gpu():
366        layer = image_preprocessing.RandomFlip(mode)
367        actual_output = layer(inp, training=1)
368        self.assertAllClose(expected_output, actual_output)
369
370  @parameterized.named_parameters(
371      ('random_flip_horizontal', 'horizontal'),
372      ('random_flip_vertical', 'vertical'),
373      ('random_flip_both', 'horizontal_and_vertical'))
374  def test_random_flip(self, mode):
375    with CustomObjectScope({'RandomFlip': image_preprocessing.RandomFlip}):
376      self._run_test(mode)
377
378  def test_random_flip_horizontal_half(self):
379    with CustomObjectScope({'RandomFlip': image_preprocessing.RandomFlip}):
380      np.random.seed(1337)
381      mock_random = [1, 0]
382      mock_random = np.reshape(mock_random, [2, 1, 1, 1])
383      input_images = np.random.random((2, 5, 8, 3)).astype(np.float32)
384      expected_output = input_images.copy()
385      expected_output[0, :, :, :] = np.flip(input_images[0, :, :, :], axis=1)
386      self._run_test('horizontal', expected_output, mock_random)
387
388  def test_random_flip_vertical_half(self):
389    with CustomObjectScope({'RandomFlip': image_preprocessing.RandomFlip}):
390      np.random.seed(1337)
391      mock_random = [1, 0]
392      mock_random = np.reshape(mock_random, [2, 1, 1, 1])
393      input_images = np.random.random((2, 5, 8, 3)).astype(np.float32)
394      expected_output = input_images.copy()
395      expected_output[0, :, :, :] = np.flip(input_images[0, :, :, :], axis=0)
396      self._run_test('vertical', expected_output, mock_random)
397
398  def test_random_flip_inference(self):
399    with CustomObjectScope({'RandomFlip': image_preprocessing.RandomFlip}):
400      input_images = np.random.random((2, 5, 8, 3)).astype(np.float32)
401      expected_output = input_images
402      with testing_utils.use_gpu():
403        layer = image_preprocessing.RandomFlip()
404        actual_output = layer(input_images, training=0)
405        self.assertAllClose(expected_output, actual_output)
406
407  def test_random_flip_default(self):
408    with CustomObjectScope({'RandomFlip': image_preprocessing.RandomFlip}):
409      input_images = np.random.random((2, 5, 8, 3)).astype(np.float32)
410      expected_output = np.flip(np.flip(input_images, axis=1), axis=2)
411      mock_random = [1, 1]
412      mock_random = np.reshape(mock_random, [2, 1, 1, 1])
413      with test.mock.patch.object(
414          random_ops, 'random_uniform', return_value=mock_random):
415        with self.cached_session():
416          layer = image_preprocessing.RandomFlip()
417          actual_output = layer(input_images, training=1)
418          self.assertAllClose(expected_output, actual_output)
419
420  @testing_utils.run_v2_only
421  def test_config_with_custom_name(self):
422    layer = image_preprocessing.RandomFlip(name='image_preproc')
423    config = layer.get_config()
424    layer_1 = image_preprocessing.RandomFlip.from_config(config)
425    self.assertEqual(layer_1.name, layer.name)
426
427
428@keras_parameterized.run_all_keras_modes(always_skip_v1=True)
429class RandomContrastTest(keras_parameterized.TestCase):
430
431  def _run_test(self, lower, upper, expected_output=None, mock_random=None):
432    np.random.seed(1337)
433    num_samples = 2
434    orig_height = 5
435    orig_width = 8
436    channels = 3
437    if mock_random is None:
438      mock_random = 0.2
439    inp = np.random.random((num_samples, orig_height, orig_width, channels))
440    if expected_output is None:
441      # reduce mean on height.
442      inp_mean = np.mean(inp, axis=1, keepdims=True)
443      # reduce mean on width.
444      inp_mean = np.mean(inp_mean, axis=2, keepdims=True)
445      expected_output = (inp - inp_mean) * mock_random + inp_mean
446    with test.mock.patch.object(
447        random_ops, 'random_uniform', return_value=mock_random):
448      with testing_utils.use_gpu():
449        layer = image_preprocessing.RandomContrast((lower, upper))
450        actual_output = layer(inp, training=True)
451        self.assertAllClose(expected_output, actual_output)
452
453  @parameterized.named_parameters(('random_contrast_2_by_5', 0.2, 0.5),
454                                  ('random_contrast_2_by_13', 0.2, 1.3),
455                                  ('random_contrast_5_by_2', 0.5, 0.2))
456  def test_random_contrast(self, lower, upper):
457    with CustomObjectScope(
458        {'RandomContrast': image_preprocessing.RandomContrast}):
459      self._run_test(lower, upper)
460
461  @parameterized.named_parameters(('random_contrast_amplitude_2', 0.2),
462                                  ('random_contrast_amplitude_5', 0.5))
463  def test_random_contrast_amplitude(self, amplitude):
464    with CustomObjectScope(
465        {'RandomContrast': image_preprocessing.RandomContrast}):
466      input_images = np.random.random((2, 5, 8, 3))
467      with testing_utils.use_gpu():
468        layer = image_preprocessing.RandomContrast(amplitude)
469        layer(input_images)
470
471  def test_random_contrast_inference(self):
472    with CustomObjectScope(
473        {'RandomContrast': image_preprocessing.RandomContrast}):
474      input_images = np.random.random((2, 5, 8, 3)).astype(np.float32)
475      expected_output = input_images
476      with testing_utils.use_gpu():
477        layer = image_preprocessing.RandomContrast((0.1, 0.2))
478        actual_output = layer(input_images, training=False)
479        self.assertAllClose(expected_output, actual_output)
480
481  def test_random_contrast_int_dtype(self):
482    with CustomObjectScope(
483        {'RandomContrast': image_preprocessing.RandomContrast}):
484      input_images = np.random.randint(low=0, high=255, size=(2, 5, 8, 3))
485      with testing_utils.use_gpu():
486        layer = image_preprocessing.RandomContrast((0.1, 0.2))
487        layer(input_images)
488
489  def test_random_contrast_invalid_bounds(self):
490    with self.assertRaises(ValueError):
491      image_preprocessing.RandomContrast((-0.1, .5))
492
493    with self.assertRaises(ValueError):
494      image_preprocessing.RandomContrast((1.1, .5))
495
496    with self.assertRaises(ValueError):
497      image_preprocessing.RandomContrast((0.1, -0.2))
498
499  @testing_utils.run_v2_only
500  def test_config_with_custom_name(self):
501    layer = image_preprocessing.RandomContrast((.5, .6), name='image_preproc')
502    config = layer.get_config()
503    layer_1 = image_preprocessing.RandomContrast.from_config(config)
504    self.assertEqual(layer_1.name, layer.name)
505
506
507@keras_parameterized.run_all_keras_modes(always_skip_v1=True)
508class RandomTranslationTest(keras_parameterized.TestCase):
509
510  def _run_test(self, height_factor, width_factor):
511    np.random.seed(1337)
512    num_samples = 2
513    orig_height = 5
514    orig_width = 8
515    channels = 3
516    kwargs = {'height_factor': height_factor, 'width_factor': width_factor}
517    with testing_utils.use_gpu():
518      testing_utils.layer_test(
519          image_preprocessing.RandomTranslation,
520          kwargs=kwargs,
521          input_shape=(num_samples, orig_height, orig_width, channels),
522          expected_output_shape=(None, orig_height, orig_width, channels))
523
524  @parameterized.named_parameters(
525      ('random_translate_4_by_6', .4, .6), ('random_translate_3_by_2', .3, .2),
526      ('random_translate_tuple_factor', (-.5, .4), (.2, .3)))
527  def test_random_translation(self, height_factor, width_factor):
528    self._run_test(height_factor, width_factor)
529
530  def test_random_translation_up_numeric_reflect(self):
531    for dtype in (np.int64, np.float32):
532      with testing_utils.use_gpu():
533        input_image = np.reshape(np.arange(0, 25), (1, 5, 5, 1)).astype(dtype)
534        # Shifting by -.2 * 5 = 1 pixel.
535        layer = image_preprocessing.RandomTranslation(
536            height_factor=(-.2, -.2), width_factor=0.)
537        output_image = layer(input_image)
538        # pyformat: disable
539        expected_output = np.asarray([
540            [5, 6, 7, 8, 9],
541            [10, 11, 12, 13, 14],
542            [15, 16, 17, 18, 19],
543            [20, 21, 22, 23, 24],
544            [20, 21, 22, 23, 24]
545        ]).astype(dtype)
546        # pyformat: enable
547        expected_output = np.reshape(expected_output, (1, 5, 5, 1))
548        self.assertAllEqual(expected_output, output_image)
549
550  def test_random_translation_up_numeric_constant(self):
551    for dtype in (np.int64, np.float32):
552      with testing_utils.use_gpu():
553        input_image = np.reshape(np.arange(0, 25), (1, 5, 5, 1)).astype(dtype)
554        # Shifting by -.2 * 5 = 1 pixel.
555        layer = image_preprocessing.RandomTranslation(
556            height_factor=(-.2, -.2), width_factor=0., fill_mode='constant')
557        output_image = layer(input_image)
558        # pyformat: disable
559        expected_output = np.asarray([
560            [5, 6, 7, 8, 9],
561            [10, 11, 12, 13, 14],
562            [15, 16, 17, 18, 19],
563            [20, 21, 22, 23, 24],
564            [0, 0, 0, 0, 0]
565        ]).astype(dtype)
566        # pyformat: enable
567        expected_output = np.reshape(expected_output, (1, 5, 5, 1))
568        self.assertAllEqual(expected_output, output_image)
569
570  def test_random_translation_down_numeric_reflect(self):
571    for dtype in (np.int64, np.float32):
572      with testing_utils.use_gpu():
573        input_image = np.reshape(np.arange(0, 25), (1, 5, 5, 1)).astype(dtype)
574        # Shifting by .2 * 5 = 1 pixel.
575        layer = image_preprocessing.RandomTranslation(
576            height_factor=(.2, .2), width_factor=0.)
577        output_image = layer(input_image)
578        # pyformat: disable
579        expected_output = np.asarray([
580            [0, 1, 2, 3, 4],
581            [0, 1, 2, 3, 4],
582            [5, 6, 7, 8, 9],
583            [10, 11, 12, 13, 14],
584            [15, 16, 17, 18, 19]
585        ]).astype(dtype)
586        # pyformat: enable
587        expected_output = np.reshape(expected_output, (1, 5, 5, 1))
588        self.assertAllEqual(expected_output, output_image)
589
590  def test_random_translation_asymmetric_size_numeric_reflect(self):
591    for dtype in (np.int64, np.float32):
592      with testing_utils.use_gpu():
593        input_image = np.reshape(np.arange(0, 16), (1, 8, 2, 1)).astype(dtype)
594        # Shifting by .5 * 8 = 1 pixel.
595        layer = image_preprocessing.RandomTranslation(
596            height_factor=(.5, .5), width_factor=0.)
597        output_image = layer(input_image)
598        # pyformat: disable
599        expected_output = np.asarray([
600            [6, 7],
601            [4, 5],
602            [2, 3],
603            [0, 1],
604            [0, 1],
605            [2, 3],
606            [4, 5],
607            [6, 7],
608        ]).astype(dtype)
609        # pyformat: enable
610        expected_output = np.reshape(expected_output, (1, 8, 2, 1))
611        self.assertAllEqual(expected_output, output_image)
612
613  def test_random_translation_down_numeric_constant(self):
614    for dtype in (np.int64, np.float32):
615      with testing_utils.use_gpu():
616        input_image = np.reshape(np.arange(0, 25), (1, 5, 5, 1)).astype(dtype)
617        # Shifting by -.2 * 5 = 1 pixel.
618        layer = image_preprocessing.RandomTranslation(
619            height_factor=(.2, .2), width_factor=0., fill_mode='constant')
620        output_image = layer(input_image)
621        # pyformat: disable
622        expected_output = np.asarray([
623            [0, 0, 0, 0, 0],
624            [0, 1, 2, 3, 4],
625            [5, 6, 7, 8, 9],
626            [10, 11, 12, 13, 14],
627            [15, 16, 17, 18, 19]
628        ]).astype(dtype)
629        # pyformat: enable
630        expected_output = np.reshape(expected_output, (1, 5, 5, 1))
631        self.assertAllEqual(expected_output, output_image)
632
633  def test_random_translation_left_numeric_reflect(self):
634    for dtype in (np.int64, np.float32):
635      with testing_utils.use_gpu():
636        input_image = np.reshape(np.arange(0, 25), (1, 5, 5, 1)).astype(dtype)
637        # Shifting by .2 * 5 = 1 pixel.
638        layer = image_preprocessing.RandomTranslation(
639            height_factor=0., width_factor=(-.2, -.2))
640        output_image = layer(input_image)
641        # pyformat: disable
642        expected_output = np.asarray([
643            [1, 2, 3, 4, 4],
644            [6, 7, 8, 9, 9],
645            [11, 12, 13, 14, 14],
646            [16, 17, 18, 19, 19],
647            [21, 22, 23, 24, 24]
648        ]).astype(dtype)
649        # pyformat: enable
650        expected_output = np.reshape(expected_output, (1, 5, 5, 1))
651        self.assertAllEqual(expected_output, output_image)
652
653  def test_random_translation_left_numeric_constant(self):
654    for dtype in (np.int64, np.float32):
655      with testing_utils.use_gpu():
656        input_image = np.reshape(np.arange(0, 25), (1, 5, 5, 1)).astype(dtype)
657        # Shifting by -.2 * 5 = 1 pixel.
658        layer = image_preprocessing.RandomTranslation(
659            height_factor=0., width_factor=(-.2, -.2), fill_mode='constant')
660        output_image = layer(input_image)
661        # pyformat: disable
662        expected_output = np.asarray([
663            [1, 2, 3, 4, 0],
664            [6, 7, 8, 9, 0],
665            [11, 12, 13, 14, 0],
666            [16, 17, 18, 19, 0],
667            [21, 22, 23, 24, 0]
668        ]).astype(dtype)
669        # pyformat: enable
670        expected_output = np.reshape(expected_output, (1, 5, 5, 1))
671        self.assertAllEqual(expected_output, output_image)
672
673  def test_random_translation_inference(self):
674    with CustomObjectScope(
675        {'RandomTranslation': image_preprocessing.RandomTranslation}):
676      input_images = np.random.random((2, 5, 8, 3)).astype(np.float32)
677      expected_output = input_images
678      with testing_utils.use_gpu():
679        layer = image_preprocessing.RandomTranslation(.5, .5)
680        actual_output = layer(input_images, training=0)
681        self.assertAllClose(expected_output, actual_output)
682
683  @testing_utils.run_v2_only
684  def test_config_with_custom_name(self):
685    layer = image_preprocessing.RandomTranslation(.5, .6, name='image_preproc')
686    config = layer.get_config()
687    layer_1 = image_preprocessing.RandomTranslation.from_config(config)
688    self.assertEqual(layer_1.name, layer.name)
689
690
691@keras_parameterized.run_all_keras_modes(always_skip_v1=True)
692class RandomTransformTest(keras_parameterized.TestCase):
693
694  def _run_random_transform_with_mock(self,
695                                      transform_matrix,
696                                      expected_output,
697                                      mode,
698                                      fill_value=0.0,
699                                      interpolation='bilinear'):
700    inp = np.arange(15).reshape((1, 5, 3, 1)).astype(np.float32)
701    with self.cached_session():
702      output = image_preprocessing.transform(
703          inp,
704          transform_matrix,
705          fill_mode=mode,
706          fill_value=fill_value,
707          interpolation=interpolation)
708    self.assertAllClose(expected_output, output)
709
710  def test_random_translation_reflect(self):
711    # reflected output is (dcba|abcd|dcba)
712
713    # Test down shift by 1.
714    # pyformat: disable
715    expected_output = np.asarray(
716        [[0., 1., 2.],
717         [0., 1., 2.],
718         [3., 4., 5.],
719         [6., 7., 8],
720         [9., 10., 11]]).reshape((1, 5, 3, 1)).astype(np.float32)
721    # pyformat: enable
722    transform_matrix = np.asarray([[1., 0., 0., 0., 1., -1., 0., 0.]])
723    self._run_random_transform_with_mock(transform_matrix, expected_output,
724                                         'reflect')
725
726    # Test up shift by 1.
727    # pyformat: disable
728    expected_output = np.asarray(
729        [[3., 4., 5.],
730         [6., 7., 8],
731         [9., 10., 11.],
732         [12., 13., 14.],
733         [12., 13., 14.]]).reshape((1, 5, 3, 1)).astype(np.float32)
734    # pyformat: enable
735    transform_matrix = np.asarray([[1., 0., 0., 0., 1., 1., 0., 0.]])
736    self._run_random_transform_with_mock(transform_matrix, expected_output,
737                                         'reflect')
738
739    # Test left shift by 1.
740    # reflected output is (dcba|abcd|dcba)
741    # pyformat: disable
742    expected_output = np.asarray(
743        [[1., 2., 2.],
744         [4., 5., 5.],
745         [7., 8., 8.],
746         [10., 11., 11.],
747         [13., 14., 14.]]).reshape((1, 5, 3, 1)).astype(np.float32)
748    # pyformat: enable
749    transform_matrix = np.asarray([[1., 0., 1., 0., 1., 0., 0., 0.]])
750    self._run_random_transform_with_mock(transform_matrix, expected_output,
751                                         'reflect')
752
753    # Test right shift by 1.
754    # pyformat: disable
755    expected_output = np.asarray(
756        [[0., 0., 1.],
757         [3., 3., 4],
758         [6., 6., 7.],
759         [9., 9., 10.],
760         [12., 12., 13.]]).reshape((1, 5, 3, 1)).astype(np.float32)
761    # pyformat: enable
762    transform_matrix = np.asarray([[1., 0., -1., 0., 1., 0., 0., 0.]])
763    self._run_random_transform_with_mock(transform_matrix, expected_output,
764                                         'reflect')
765
766  def test_random_translation_wrap(self):
767    # warpped output is (abcd|abcd|abcd)
768
769    # Test down shift by 1.
770    # pyformat: disable
771    expected_output = np.asarray(
772        [[12., 13., 14.],
773         [0., 1., 2.],
774         [3., 4., 5.],
775         [6., 7., 8],
776         [9., 10., 11]]).reshape((1, 5, 3, 1)).astype(np.float32)
777    # pyformat: enable
778    transform_matrix = np.asarray([[1., 0., 0., 0., 1., -1., 0., 0.]])
779    self._run_random_transform_with_mock(transform_matrix, expected_output,
780                                         'wrap')
781
782    # Test up shift by 1.
783    # pyformat: disable
784    expected_output = np.asarray(
785        [[3., 4., 5.],
786         [6., 7., 8],
787         [9., 10., 11.],
788         [12., 13., 14.],
789         [0., 1., 2.]]).reshape((1, 5, 3, 1)).astype(np.float32)
790    # pyformat: enable
791    transform_matrix = np.asarray([[1., 0., 0., 0., 1., 1., 0., 0.]])
792    self._run_random_transform_with_mock(transform_matrix, expected_output,
793                                         'wrap')
794
795    # Test left shift by 1.
796    # pyformat: disable
797    expected_output = np.asarray(
798        [[1., 2., 0.],
799         [4., 5., 3.],
800         [7., 8., 6.],
801         [10., 11., 9.],
802         [13., 14., 12.]]).reshape((1, 5, 3, 1)).astype(np.float32)
803    # pyformat: enable
804    transform_matrix = np.asarray([[1., 0., 1., 0., 1., 0., 0., 0.]])
805    self._run_random_transform_with_mock(transform_matrix, expected_output,
806                                         'wrap')
807
808    # Test right shift by 1.
809    # pyformat: disable
810    expected_output = np.asarray(
811        [[2., 0., 1.],
812         [5., 3., 4],
813         [8., 6., 7.],
814         [11., 9., 10.],
815         [14., 12., 13.]]).reshape((1, 5, 3, 1)).astype(np.float32)
816    # pyformat: enable
817    transform_matrix = np.asarray([[1., 0., -1., 0., 1., 0., 0., 0.]])
818    self._run_random_transform_with_mock(transform_matrix, expected_output,
819                                         'wrap')
820
821  def test_random_translation_nearest(self):
822    # nearest output is (aaaa|abcd|dddd)
823
824    # Test down shift by 1.
825    # pyformat: disable
826    expected_output = np.asarray(
827        [[0., 1., 2.],
828         [0., 1., 2.],
829         [3., 4., 5.],
830         [6., 7., 8],
831         [9., 10., 11]]).reshape((1, 5, 3, 1)).astype(np.float32)
832    # pyformat: enable
833    transform_matrix = np.asarray([[1., 0., 0., 0., 1., -1., 0., 0.]])
834    self._run_random_transform_with_mock(transform_matrix, expected_output,
835                                         'nearest')
836
837    # Test up shift by 1.
838    # pyformat: disable
839    expected_output = np.asarray(
840        [[3., 4., 5.],
841         [6., 7., 8],
842         [9., 10., 11.],
843         [12., 13., 14.],
844         [12., 13., 14.]]).reshape((1, 5, 3, 1)).astype(np.float32)
845    # pyformat: enable
846    transform_matrix = np.asarray([[1., 0., 0., 0., 1., 1., 0., 0.]])
847    self._run_random_transform_with_mock(transform_matrix, expected_output,
848                                         'nearest')
849
850    # Test left shift by 1.
851    # pyformat: disable
852    expected_output = np.asarray(
853        [[1., 2., 2.],
854         [4., 5., 5.],
855         [7., 8., 8.],
856         [10., 11., 11.],
857         [13., 14., 14.]]).reshape((1, 5, 3, 1)).astype(np.float32)
858    # pyformat: enable
859    transform_matrix = np.asarray([[1., 0., 1., 0., 1., 0., 0., 0.]])
860    self._run_random_transform_with_mock(transform_matrix, expected_output,
861                                         'nearest')
862
863    # Test right shift by 1.
864    # pyformat: disable
865    expected_output = np.asarray(
866        [[0., 0., 1.],
867         [3., 3., 4],
868         [6., 6., 7.],
869         [9., 9., 10.],
870         [12., 12., 13.]]).reshape((1, 5, 3, 1)).astype(np.float32)
871    # pyformat: enable
872    transform_matrix = np.asarray([[1., 0., -1., 0., 1., 0., 0., 0.]])
873    self._run_random_transform_with_mock(transform_matrix, expected_output,
874                                         'nearest')
875
876  def test_random_translation_constant_0(self):
877    # constant output is (0000|abcd|0000)
878
879    # Test down shift by 1.
880    # pyformat: disable
881    expected_output = np.asarray(
882        [[0., 0., 0.],
883         [0., 1., 2.],
884         [3., 4., 5.],
885         [6., 7., 8],
886         [9., 10., 11]]).reshape((1, 5, 3, 1)).astype(np.float32)
887    # pyformat: enable
888    transform_matrix = np.asarray([[1., 0., 0., 0., 1., -1., 0., 0.]])
889    self._run_random_transform_with_mock(transform_matrix, expected_output,
890                                         'constant')
891
892    # Test up shift by 1.
893    # pyformat: disable
894    expected_output = np.asarray(
895        [[3., 4., 5.],
896         [6., 7., 8],
897         [9., 10., 11.],
898         [12., 13., 14.],
899         [0., 0., 0.]]).reshape((1, 5, 3, 1)).astype(np.float32)
900    # pyformat: enable
901    transform_matrix = np.asarray([[1., 0., 0., 0., 1., 1., 0., 0.]])
902    self._run_random_transform_with_mock(transform_matrix, expected_output,
903                                         'constant')
904
905    # Test left shift by 1.
906    # pyformat: disable
907    expected_output = np.asarray(
908        [[1., 2., 0.],
909         [4., 5., 0.],
910         [7., 8., 0.],
911         [10., 11., 0.],
912         [13., 14., 0.]]).reshape((1, 5, 3, 1)).astype(np.float32)
913    # pyformat: enable
914    transform_matrix = np.asarray([[1., 0., 1., 0., 1., 0., 0., 0.]])
915    self._run_random_transform_with_mock(transform_matrix, expected_output,
916                                         'constant')
917
918    # Test right shift by 1.
919    # pyformat: disable
920    expected_output = np.asarray(
921        [[0., 0., 1.],
922         [0., 3., 4],
923         [0., 6., 7.],
924         [0., 9., 10.],
925         [0., 12., 13.]]).reshape((1, 5, 3, 1)).astype(np.float32)
926    # pyformat: enable
927    transform_matrix = np.asarray([[1., 0., -1., 0., 1., 0., 0., 0.]])
928    self._run_random_transform_with_mock(transform_matrix, expected_output,
929                                         'constant')
930
931  def test_random_translation_constant_1(self):
932    with compat.forward_compatibility_horizon(2020, 8, 6):
933      # constant output is (1111|abcd|1111)
934
935      # Test down shift by 1.
936      # pyformat: disable
937      expected_output = np.asarray(
938          [[1., 1., 1.],
939           [0., 1., 2.],
940           [3., 4., 5.],
941           [6., 7., 8],
942           [9., 10., 11]]).reshape((1, 5, 3, 1)).astype(np.float32)
943      # pyformat: enable
944      transform_matrix = np.asarray([[1., 0., 0., 0., 1., -1., 0., 0.]])
945      self._run_random_transform_with_mock(
946          transform_matrix, expected_output, 'constant', fill_value=1.0)
947
948      # Test up shift by 1.
949      # pyformat: disable
950      expected_output = np.asarray(
951          [[3., 4., 5.],
952           [6., 7., 8],
953           [9., 10., 11.],
954           [12., 13., 14.],
955           [1., 1., 1.]]).reshape((1, 5, 3, 1)).astype(np.float32)
956      # pyformat: enable
957      transform_matrix = np.asarray([[1., 0., 0., 0., 1., 1., 0., 0.]])
958      self._run_random_transform_with_mock(
959          transform_matrix, expected_output, 'constant', fill_value=1.0)
960
961      # Test left shift by 1.
962      # pyformat: disable
963      expected_output = np.asarray(
964          [[1., 2., 1.],
965           [4., 5., 1.],
966           [7., 8., 1.],
967           [10., 11., 1.],
968           [13., 14., 1.]]).reshape((1, 5, 3, 1)).astype(np.float32)
969      # pyformat: enable
970      transform_matrix = np.asarray([[1., 0., 1., 0., 1., 0., 0., 0.]])
971      self._run_random_transform_with_mock(
972          transform_matrix, expected_output, 'constant', fill_value=1.0)
973
974      # Test right shift by 1.
975      # pyformat: disable
976      expected_output = np.asarray(
977          [[1., 0., 1.],
978           [1., 3., 4],
979           [1., 6., 7.],
980           [1., 9., 10.],
981           [1., 12., 13.]]).reshape((1, 5, 3, 1)).astype(np.float32)
982      # pyformat: enable
983      transform_matrix = np.asarray([[1., 0., -1., 0., 1., 0., 0., 0.]])
984      self._run_random_transform_with_mock(
985          transform_matrix, expected_output, 'constant', fill_value=1.0)
986
987  def test_random_translation_nearest_interpolation(self):
988    # nearest output is (aaaa|abcd|dddd)
989
990    # Test down shift by 1.
991    # pyformat: disable
992    expected_output = np.asarray(
993        [[0., 0., 0.],
994         [0., 1., 2.],
995         [3., 4., 5.],
996         [6., 7., 8],
997         [9., 10., 11]]).reshape((1, 5, 3, 1)).astype(np.float32)
998    # pyformat: enable
999    transform_matrix = np.asarray([[1., 0., 0., 0., 1., -1., 0., 0.]])
1000    self._run_random_transform_with_mock(
1001        transform_matrix,
1002        expected_output,
1003        mode='constant',
1004        interpolation='nearest')
1005
1006    # Test up shift by 1.
1007    # pyformat: disable
1008    expected_output = np.asarray(
1009        [[3., 4., 5.],
1010         [6., 7., 8],
1011         [9., 10., 11.],
1012         [12., 13., 14.],
1013         [0., 0., 0.]]).reshape((1, 5, 3, 1)).astype(np.float32)
1014    # pyformat: enable
1015    transform_matrix = np.asarray([[1., 0., 0., 0., 1., 1., 0., 0.]])
1016    self._run_random_transform_with_mock(
1017        transform_matrix,
1018        expected_output,
1019        mode='constant',
1020        interpolation='nearest')
1021
1022    # Test left shift by 1.
1023    # pyformat: disable
1024    expected_output = np.asarray(
1025        [[1., 2., 0.],
1026         [4., 5., 0.],
1027         [7., 8., 0.],
1028         [10., 11., 0.],
1029         [13., 14., 0.]]).reshape((1, 5, 3, 1)).astype(np.float32)
1030    # pyformat: enable
1031    transform_matrix = np.asarray([[1., 0., 1., 0., 1., 0., 0., 0.]])
1032    self._run_random_transform_with_mock(
1033        transform_matrix,
1034        expected_output,
1035        mode='constant',
1036        interpolation='nearest')
1037
1038    # Test right shift by 1.
1039    # pyformat: disable
1040    expected_output = np.asarray(
1041        [[0., 0., 1.],
1042         [0., 3., 4],
1043         [0., 6., 7.],
1044         [0., 9., 10.],
1045         [0., 12., 13.]]).reshape((1, 5, 3, 1)).astype(np.float32)
1046    # pyformat: enable
1047    transform_matrix = np.asarray([[1., 0., -1., 0., 1., 0., 0., 0.]])
1048    self._run_random_transform_with_mock(
1049        transform_matrix,
1050        expected_output,
1051        mode='constant',
1052        interpolation='nearest')
1053
1054
1055@keras_parameterized.run_all_keras_modes(always_skip_v1=True)
1056class RandomRotationTest(keras_parameterized.TestCase):
1057
1058  def _run_test(self, factor):
1059    np.random.seed(1337)
1060    num_samples = 2
1061    orig_height = 5
1062    orig_width = 8
1063    channels = 3
1064    kwargs = {'factor': factor}
1065    with testing_utils.use_gpu():
1066      testing_utils.layer_test(
1067          image_preprocessing.RandomRotation,
1068          kwargs=kwargs,
1069          input_shape=(num_samples, orig_height, orig_width, channels),
1070          expected_output_shape=(None, orig_height, orig_width, channels))
1071
1072  @parameterized.named_parameters(('random_rotate_4', .4),
1073                                  ('random_rotate_3', .3),
1074                                  ('random_rotate_tuple_factor', (-.5, .4)))
1075  def test_random_rotation(self, factor):
1076    self._run_test(factor)
1077
1078  def test_random_rotation_inference(self):
1079    with CustomObjectScope(
1080        {'RandomTranslation': image_preprocessing.RandomRotation}):
1081      input_images = np.random.random((2, 5, 8, 3)).astype(np.float32)
1082      expected_output = input_images
1083      with testing_utils.use_gpu():
1084        layer = image_preprocessing.RandomRotation(.5)
1085        actual_output = layer(input_images, training=0)
1086        self.assertAllClose(expected_output, actual_output)
1087
1088  def test_distribution_strategy(self):
1089    """Tests that RandomRotation can be created within distribution strategies.
1090    """
1091    input_images = np.random.random((2, 5, 8, 3)).astype(np.float32)
1092    with testing_utils.use_gpu():
1093      strat = MirroredStrategy(devices=['cpu', 'gpu'])
1094      with strat.scope():
1095        layer = image_preprocessing.RandomRotation(.5)
1096        output = strat.run(lambda: layer(input_images, training=True))
1097      values = output.values
1098      self.assertAllEqual(2, len(values))
1099
1100  @testing_utils.run_v2_only
1101  def test_config_with_custom_name(self):
1102    layer = image_preprocessing.RandomRotation(.5, name='image_preproc')
1103    config = layer.get_config()
1104    layer_1 = image_preprocessing.RandomRotation.from_config(config)
1105    self.assertEqual(layer_1.name, layer.name)
1106
1107
1108@keras_parameterized.run_all_keras_modes(always_skip_v1=True)
1109class RandomZoomTest(keras_parameterized.TestCase):
1110
1111  def _run_test(self, height_factor, width_factor):
1112    np.random.seed(1337)
1113    num_samples = 2
1114    orig_height = 5
1115    orig_width = 8
1116    channels = 3
1117    kwargs = {'height_factor': height_factor, 'width_factor': width_factor}
1118    with testing_utils.use_gpu():
1119      testing_utils.layer_test(
1120          image_preprocessing.RandomZoom,
1121          kwargs=kwargs,
1122          input_shape=(num_samples, orig_height, orig_width, channels),
1123          expected_output_shape=(None, orig_height, orig_width, channels))
1124
1125  @parameterized.named_parameters(
1126      ('random_zoom_4_by_6', -.4, -.6), ('random_zoom_2_by_3', -.2, -.3),
1127      ('random_zoom_tuple_factor', (-.4, -.5), (-.2, -.3)))
1128  def test_random_zoom_in(self, height_factor, width_factor):
1129    self._run_test(height_factor, width_factor)
1130
1131  @parameterized.named_parameters(
1132      ('random_zoom_4_by_6', .4, .6), ('random_zoom_2_by_3', .2, .3),
1133      ('random_zoom_tuple_factor', (.4, .5), (.2, .3)))
1134  def test_random_zoom_out(self, height_factor, width_factor):
1135    self._run_test(height_factor, width_factor)
1136
1137  def test_random_zoom_in_numeric(self):
1138    for dtype in (np.int64, np.float32):
1139      with testing_utils.use_gpu():
1140        input_image = np.reshape(np.arange(0, 25), (5, 5, 1)).astype(dtype)
1141        layer = image_preprocessing.RandomZoom((-.5, -.5), (-.5, -.5),
1142                                               interpolation='nearest')
1143        output_image = layer(np.expand_dims(input_image, axis=0))
1144        # pyformat: disable
1145        expected_output = np.asarray([
1146            [6, 7, 7, 8, 8],
1147            [11, 12, 12, 13, 13],
1148            [11, 12, 12, 13, 13],
1149            [16, 17, 17, 18, 18],
1150            [16, 17, 17, 18, 18]
1151        ]).astype(dtype)
1152        # pyformat: enable
1153        expected_output = np.reshape(expected_output, (1, 5, 5, 1))
1154        self.assertAllEqual(expected_output, output_image)
1155
1156  def test_random_zoom_out_numeric(self):
1157    for dtype in (np.int64, np.float32):
1158      with testing_utils.use_gpu():
1159        input_image = np.reshape(np.arange(0, 25), (5, 5, 1)).astype(dtype)
1160        layer = image_preprocessing.RandomZoom((.5, .5), (.8, .8),
1161                                               fill_mode='constant',
1162                                               interpolation='nearest')
1163        output_image = layer(np.expand_dims(input_image, axis=0))
1164        # pyformat: disable
1165        expected_output = np.asarray([
1166            [0, 0, 0, 0, 0],
1167            [0, 5, 7, 9, 0],
1168            [0, 10, 12, 14, 0],
1169            [0, 20, 22, 24, 0],
1170            [0, 0, 0, 0, 0]
1171        ]).astype(dtype)
1172        # pyformat: enable
1173        expected_output = np.reshape(expected_output, (1, 5, 5, 1))
1174        self.assertAllEqual(expected_output, output_image)
1175
1176  def test_random_zoom_out_numeric_preserve_aspect_ratio(self):
1177    for dtype in (np.int64, np.float32):
1178      with testing_utils.use_gpu():
1179        input_image = np.reshape(np.arange(0, 25), (5, 5, 1)).astype(dtype)
1180        layer = image_preprocessing.RandomZoom((.5, .5),
1181                                               fill_mode='constant',
1182                                               interpolation='nearest')
1183        output_image = layer(np.expand_dims(input_image, axis=0))
1184        # pyformat: disable
1185        expected_output = np.asarray([
1186            [0, 0, 0, 0, 0],
1187            [0, 6, 7, 9, 0],
1188            [0, 11, 12, 14, 0],
1189            [0, 21, 22, 24, 0],
1190            [0, 0, 0, 0, 0]
1191        ]).astype(dtype)
1192        # pyformat: enable
1193        expected_output = np.reshape(expected_output, (1, 5, 5, 1))
1194        self.assertAllEqual(expected_output, output_image)
1195
1196  def test_random_zoom_inference(self):
1197    with CustomObjectScope({'RandomZoom': image_preprocessing.RandomZoom}):
1198      input_images = np.random.random((2, 5, 8, 3)).astype(np.float32)
1199      expected_output = input_images
1200      with testing_utils.use_gpu():
1201        layer = image_preprocessing.RandomZoom(.5, .5)
1202        actual_output = layer(input_images, training=0)
1203        self.assertAllClose(expected_output, actual_output)
1204
1205  @testing_utils.run_v2_only
1206  def test_config_with_custom_name(self):
1207    layer = image_preprocessing.RandomZoom(.5, .6, name='image_preproc')
1208    config = layer.get_config()
1209    layer_1 = image_preprocessing.RandomZoom.from_config(config)
1210    self.assertEqual(layer_1.name, layer.name)
1211
1212
1213@keras_parameterized.run_all_keras_modes(always_skip_v1=True)
1214class RandomHeightTest(keras_parameterized.TestCase):
1215
1216  def _run_test(self, factor):
1217    np.random.seed(1337)
1218    num_samples = 2
1219    orig_height = 5
1220    orig_width = 8
1221    channels = 3
1222    with testing_utils.use_gpu():
1223      img = np.random.random((num_samples, orig_height, orig_width, channels))
1224      layer = image_preprocessing.RandomHeight(factor)
1225      img_out = layer(img, training=True)
1226      self.assertEqual(img_out.shape[0], 2)
1227      self.assertEqual(img_out.shape[2], 8)
1228      self.assertEqual(img_out.shape[3], 3)
1229
1230  @parameterized.named_parameters(('random_height_4_by_6', (.4, .6)),
1231                                  ('random_height_3_by_2', (-.3, .2)),
1232                                  ('random_height_3', .3))
1233  def test_random_height_basic(self, factor):
1234    self._run_test(factor)
1235
1236  def test_valid_random_height(self):
1237    # need (maxval - minval) * rnd + minval = 0.6
1238    mock_factor = 0
1239    with test.mock.patch.object(
1240        gen_stateful_random_ops, 'stateful_uniform', return_value=mock_factor):
1241      with test.mock.patch.object(
1242          gen_stateless_random_ops_v2,
1243          'stateless_random_uniform_v2',
1244          return_value=mock_factor):
1245        with testing_utils.use_gpu():
1246          img = np.random.random((12, 5, 8, 3))
1247          layer = image_preprocessing.RandomHeight(.4)
1248          img_out = layer(img, training=True)
1249          self.assertEqual(img_out.shape[1], 3)
1250
1251  def test_random_height_longer_numeric(self):
1252    for dtype in (np.int64, np.float32):
1253      with testing_utils.use_gpu():
1254        input_image = np.reshape(np.arange(0, 6), (2, 3, 1)).astype(dtype)
1255        layer = image_preprocessing.RandomHeight(factor=(1., 1.))
1256        # Return type of RandomHeight() is float32 if `interpolation` is not
1257        # set to `ResizeMethod.NEAREST_NEIGHBOR`; cast `layer` to desired dtype.
1258        output_image = math_ops.cast(
1259            layer(np.expand_dims(input_image, axis=0)), dtype=dtype)
1260        # pyformat: disable
1261        expected_output = np.asarray([
1262            [0, 1, 2],
1263            [0.75, 1.75, 2.75],
1264            [2.25, 3.25, 4.25],
1265            [3, 4, 5]
1266        ]).astype(dtype)
1267        # pyformat: enable
1268        expected_output = np.reshape(expected_output, (1, 4, 3, 1))
1269        self.assertAllEqual(expected_output, output_image)
1270
1271  def test_random_height_shorter_numeric(self):
1272    for dtype in (np.int64, np.float32):
1273      with testing_utils.use_gpu():
1274        input_image = np.reshape(np.arange(0, 8), (4, 2, 1)).astype(dtype)
1275        layer = image_preprocessing.RandomHeight(
1276            factor=(-.5, -.5), interpolation='nearest')
1277        output_image = layer(np.expand_dims(input_image, axis=0))
1278        # pyformat: disable
1279        expected_output = np.asarray([
1280            [2, 3],
1281            [6, 7]
1282        ]).astype(dtype)
1283        # pyformat: enable
1284        expected_output = np.reshape(expected_output, (1, 2, 2, 1))
1285        self.assertAllEqual(expected_output, output_image)
1286
1287  def test_random_height_invalid_factor(self):
1288    with self.assertRaises(ValueError):
1289      image_preprocessing.RandomHeight((-1.5, .4))
1290
1291  def test_random_height_inference(self):
1292    with CustomObjectScope({'RandomHeight': image_preprocessing.RandomHeight}):
1293      input_images = np.random.random((2, 5, 8, 3)).astype(np.float32)
1294      expected_output = input_images
1295      with testing_utils.use_gpu():
1296        layer = image_preprocessing.RandomHeight(.5)
1297        actual_output = layer(input_images, training=0)
1298        self.assertAllClose(expected_output, actual_output)
1299
1300  @testing_utils.run_v2_only
1301  def test_config_with_custom_name(self):
1302    layer = image_preprocessing.RandomHeight(.5, name='image_preproc')
1303    config = layer.get_config()
1304    layer_1 = image_preprocessing.RandomHeight.from_config(config)
1305    self.assertEqual(layer_1.name, layer.name)
1306
1307
1308@keras_parameterized.run_all_keras_modes(always_skip_v1=True)
1309class RandomWidthTest(keras_parameterized.TestCase):
1310
1311  def _run_test(self, factor):
1312    np.random.seed(1337)
1313    num_samples = 2
1314    orig_height = 5
1315    orig_width = 8
1316    channels = 3
1317    with testing_utils.use_gpu():
1318      img = np.random.random((num_samples, orig_height, orig_width, channels))
1319      layer = image_preprocessing.RandomWidth(factor)
1320      img_out = layer(img, training=True)
1321      self.assertEqual(img_out.shape[0], 2)
1322      self.assertEqual(img_out.shape[1], 5)
1323      self.assertEqual(img_out.shape[3], 3)
1324
1325  @parameterized.named_parameters(('random_width_4_by_6', (.4, .6)),
1326                                  ('random_width_3_by_2', (-.3, .2)),
1327                                  ('random_width_3', .3))
1328  def test_random_width_basic(self, factor):
1329    self._run_test(factor)
1330
1331  def test_valid_random_width(self):
1332    # need (maxval - minval) * rnd + minval = 0.6
1333    mock_factor = 0
1334    with test.mock.patch.object(
1335        gen_stateful_random_ops, 'stateful_uniform', return_value=mock_factor):
1336      with test.mock.patch.object(
1337          gen_stateless_random_ops_v2,
1338          'stateless_random_uniform_v2',
1339          return_value=mock_factor):
1340        with testing_utils.use_gpu():
1341          img = np.random.random((12, 8, 5, 3))
1342          layer = image_preprocessing.RandomWidth(.4)
1343          img_out = layer(img, training=True)
1344          self.assertEqual(img_out.shape[2], 3)
1345
1346  def test_random_width_longer_numeric(self):
1347    for dtype in (np.int64, np.float32):
1348      with testing_utils.use_gpu():
1349        input_image = np.reshape(np.arange(0, 6), (3, 2, 1)).astype(dtype)
1350        layer = image_preprocessing.RandomWidth(factor=(1., 1.))
1351        # Return type of RandomWidth() is float32 if `interpolation` is not
1352        # set to `ResizeMethod.NEAREST_NEIGHBOR`; cast `layer` to desired dtype.
1353        output_image = math_ops.cast(
1354            layer(np.expand_dims(input_image, axis=0)), dtype=dtype)
1355        # pyformat: disable
1356        expected_output = np.asarray([
1357            [0, 0.25, 0.75, 1],
1358            [2, 2.25, 2.75, 3],
1359            [4, 4.25, 4.75, 5]
1360        ]).astype(dtype)
1361        # pyformat: enable
1362        expected_output = np.reshape(expected_output, (1, 3, 4, 1))
1363        self.assertAllEqual(expected_output, output_image)
1364
1365  def test_random_width_shorter_numeric(self):
1366    for dtype in (np.int64, np.float32):
1367      with testing_utils.use_gpu():
1368        input_image = np.reshape(np.arange(0, 8), (2, 4, 1)).astype(dtype)
1369        layer = image_preprocessing.RandomWidth(
1370            factor=(-.5, -.5), interpolation='nearest')
1371        output_image = layer(np.expand_dims(input_image, axis=0))
1372        # pyformat: disable
1373        expected_output = np.asarray([
1374            [1, 3],
1375            [5, 7]
1376        ]).astype(dtype)
1377        # pyformat: enable
1378        expected_output = np.reshape(expected_output, (1, 2, 2, 1))
1379        self.assertAllEqual(expected_output, output_image)
1380
1381  def test_random_width_invalid_factor(self):
1382    with self.assertRaises(ValueError):
1383      image_preprocessing.RandomWidth((-1.5, .4))
1384
1385  def test_random_width_inference(self):
1386    with CustomObjectScope({'RandomWidth': image_preprocessing.RandomWidth}):
1387      input_images = np.random.random((2, 5, 8, 3)).astype(np.float32)
1388      expected_output = input_images
1389      with testing_utils.use_gpu():
1390        layer = image_preprocessing.RandomWidth(.5)
1391        actual_output = layer(input_images, training=0)
1392        self.assertAllClose(expected_output, actual_output)
1393
1394  @testing_utils.run_v2_only
1395  def test_config_with_custom_name(self):
1396    layer = image_preprocessing.RandomWidth(.5, name='image_preproc')
1397    config = layer.get_config()
1398    layer_1 = image_preprocessing.RandomWidth.from_config(config)
1399    self.assertEqual(layer_1.name, layer.name)
1400
1401
1402@keras_parameterized.run_all_keras_modes(always_skip_v1=True)
1403class LearningPhaseTest(keras_parameterized.TestCase):
1404
1405  def test_plain_call(self):
1406    layer = image_preprocessing.RandomWidth(.5, seed=123)
1407    shape = (12, 12, 3)
1408    img = np.random.random((12,) + shape)
1409    out = layer(img)  # Default to training=True
1410    self.assertNotEqual(tuple(int(i) for i in out.shape[1:]), shape)
1411
1412    out = layer(img, training=True)
1413    self.assertNotEqual(tuple(int(i) for i in out.shape[1:]), shape)
1414
1415    out = layer(img, training=False)
1416    self.assertEqual(tuple(int(i) for i in out.shape[1:]), shape)
1417
1418  def test_call_in_container(self):
1419    layer1 = image_preprocessing.RandomWidth(.5, seed=123)
1420    layer2 = image_preprocessing.RandomHeight(.5, seed=123)
1421    seq = sequential.Sequential([layer1, layer2])
1422
1423    shape = (12, 12, 3)
1424    img = np.random.random((12,) + shape)
1425    out = seq(img)  # Default to training=True
1426    self.assertNotEqual(tuple(int(i) for i in out.shape[1:]), shape)
1427
1428    out = seq(img, training=True)
1429    self.assertNotEqual(tuple(int(i) for i in out.shape[1:]), shape)
1430
1431    out = seq(img, training=False)
1432    self.assertEqual(tuple(int(i) for i in out.shape[1:]), shape)
1433
1434
1435if __name__ == '__main__':
1436  test.main()
1437