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