• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2018 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 resampler ops."""
16
17from __future__ import absolute_import
18from __future__ import division
19from __future__ import print_function
20
21import numpy as np
22
23from tensorflow.compiler.tests import xla_test
24from tensorflow.contrib import resampler
25from tensorflow.contrib.resampler.ops import gen_resampler_ops
26from tensorflow.python.ops import array_ops
27from tensorflow.python.platform import test
28
29
30class ResamplerOpsTest(xla_test.XLATestCase):
31
32  def _assertForwardOpMatchesExpected(self, image_np, warp_np, expected):
33    with self.test_session() as sess, self.test_scope():
34      input_image = array_ops.placeholder(image_np.dtype)
35      warp = array_ops.placeholder(warp_np.dtype)
36      resampled = resampler.resampler(input_image, warp, name='resampler')
37      out = sess.run(resampled, {input_image: image_np, warp: warp_np})
38
39      self.assertAllCloseAccordingToType(
40          expected, out, rtol=5e-3, half_rtol=1e-2, bfloat16_rtol=3e-2)
41
42  def _assertBackwardOpMatchesExpected(self, input_np, warp_np, grad_output_np,
43                                       expected_grad_data, expected_grad_warp):
44    with self.cached_session() as sess, self.test_scope():
45      input_image = array_ops.placeholder(input_np.dtype)
46      warp = array_ops.placeholder(warp_np.dtype)
47      grad_output = array_ops.placeholder(grad_output_np.dtype)
48
49      grad_data, grad_warp = gen_resampler_ops.resampler_grad(
50          input_image, warp, grad_output)
51
52      grad_data_tf, grad_warp_tf = sess.run([grad_data, grad_warp], {
53          input_image: input_np,
54          warp: warp_np,
55          grad_output: grad_output_np
56      })
57
58      self.assertAllCloseAccordingToType(
59          expected_grad_warp, grad_warp_tf, half_rtol=1e-2, bfloat16_rtol=3e-2)
60      self.assertAllCloseAccordingToType(
61          expected_grad_data, grad_data_tf, half_rtol=1e-2, bfloat16_rtol=3e-2)
62
63  def testSimple(self):
64    for dtype in self.float_types:
65      input_shape = [1, 2, 2, 1]
66      input_data = [0, 5, 13, 54]
67      input_np = np.array(input_data, dtype=dtype).reshape(input_shape)
68
69      warp_shape = [1, 2]
70      warp_data = [0.7, 0.6]
71      warp_np = np.array(warp_data, dtype=dtype).reshape(warp_shape)
72      expected = [[26.42]]
73      self._assertForwardOpMatchesExpected(input_np, warp_np, expected)
74
75      grad_output = np.ones([1, 1], dtype=dtype)
76
77      expected_grad_data = [[[[0.12], [0.27999997]], [[0.18000001],
78                                                      [0.42000002]]]]
79
80      expected_grad_warp = [[26.60000038, 38.20000076]]
81
82      self._assertBackwardOpMatchesExpected(input_np, warp_np, grad_output,
83                                            expected_grad_data,
84                                            expected_grad_warp)
85
86  def testMultiChannel(self):
87    for dtype in self.float_types:
88      input_shape = [1, 2, 2, 3]
89      input_rgb_data = [0, 5, 13, 54, 135, 226, 37, 8, 234, 90, 255, 1]
90      input_np = np.array(input_rgb_data, dtype=dtype).reshape(input_shape)
91
92      warp_shape = [1, 2]
93      warp_data = [0.7, 0.6]
94      warp_np = np.array(warp_data, dtype=dtype).reshape(warp_shape)
95      expected = [[59.58000183, 146.94000244, 107.37999725]]
96      self._assertForwardOpMatchesExpected(input_np, warp_np, expected)
97
98      grad_output = np.ones([1, 3], dtype=dtype)
99
100      expected_grad_data = [[[[0.12, 0.12, 0.12],
101                              [0.27999997, 0.27999997, 0.27999997]],
102                             [[0.18000001, 0.18000001, 0.18000001],
103                              [0.42000002, 0.42000002, 0.42000002]]]]
104
105      expected_grad_warp = [[199, 30]]
106
107      self._assertBackwardOpMatchesExpected(input_np, warp_np, grad_output,
108                                            expected_grad_data,
109                                            expected_grad_warp)
110
111  def testBatch2Height3byWidth3RGB(self):
112    for dtype in self.float_types:
113      input_shape = [2, 3, 3, 3]
114      input_rgb_data = [
115          0, 5, 13, 54, 135, 226, 37, 8, 234, 90, 255, 1, 30, 105, 2, 40, 115,
116          3, 50, 125, 4, 60, 135, 5, 70, 145, 6, 0, 5, 13, 54, 135, 226, 37, 8,
117          234, 90, 255, 1, 30, 105, 2, 40, 115, 3, 50, 125, 4, 60, 135, 5, 70,
118          145, 6
119      ]
120      input_np = np.array(input_rgb_data, dtype=dtype).reshape(input_shape)
121
122      # 2 batches and 2 samples for each batch.
123      warp_shape = [2, 2, 2]
124      warp_data = [0.7, 0.6, 1, 0.7, 0.9, 1.2, 1.3, 1.6]
125      warp_np = np.array(warp_data, dtype=dtype).reshape(warp_shape)
126
127      expected_forward = [[[43.92, 128.4, 65.86], [37.2, 114., 69.2]],
128                          [[40.6, 122.8, 2.5], [51., 126, 4.1]]]
129
130      self._assertForwardOpMatchesExpected(input_np, warp_np, expected_forward)
131
132      expected_grad_data = [[[[0.12, 0.12, 0.12],
133                              [0.57999998, 0.57999998, 0.57999998],
134                              [0., 0., 0.]],
135                             [[0.18000001, 0.18000001, 0.18000001],
136                              [1.12, 1.12, 1.12], [0., 0., 0.]],
137                             [[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]]],
138                            [[[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]],
139                             [[0.08000001, 0.08000001, 0.08000001],
140                              [0.99999988, 0.99999988, 0.99999988],
141                              [0.11999997, 0.11999997, 0.11999997]],
142                             [[0.02000001, 0.02000001, 0.02000001],
143                              [0.60000008, 0.60000008, 0.60000008],
144                              [0.17999998, 0.17999998, 0.17999998]]]]
145      expected_grad_warp = [[[33.39999008, -96.20000458], [-26.10000229,
146                                                           -278.]],
147                            [[-162.99998474, 39.99999619], [21., 63.]]]
148
149      grad_output = np.ones([2, 2, 3], dtype=dtype)
150      self._assertBackwardOpMatchesExpected(input_np, warp_np, grad_output,
151                                            expected_grad_data,
152                                            expected_grad_warp)
153
154  def testOutOfBoundWarps(self):
155    # (x, y) are both less than 0.
156    for dtype in self.float_types:
157      input_shape = [1, 2, 2, 1]
158      input_data = [10, 5, 13, 54]
159      input_np = np.array(input_data, dtype=dtype).reshape(input_shape)
160
161      warp_shape = [1, 2, 2]
162      warp_data = [-1, -1, 0.7, 0.6]
163      warp_np = np.array(warp_data, dtype=dtype).reshape(warp_shape)
164      expected = [[[0.0], [27.62]]]
165      self._assertForwardOpMatchesExpected(input_np, warp_np, expected)
166
167      expected_grad_data = [[[[0.12], [0.27999997]], [[0.18000001],
168                                                      [0.42000002]]]]
169      expected_grad_warp = [[[0., 0.], [22.60000038, 35.20000076]]]
170
171      grad_output = np.ones([1, 2, 1], dtype=dtype)
172      self._assertBackwardOpMatchesExpected(input_np, warp_np, grad_output,
173                                            expected_grad_data,
174                                            expected_grad_warp)
175
176    # One of (x, y) is less than 0.
177    for dtype in self.float_types:
178      input_shape = [1, 2, 2, 1]
179      input_data = [10, 5, 13, 54]
180      input_np = np.array(input_data, dtype=dtype).reshape(input_shape)
181
182      warp_shape = [1, 2, 2]
183      # -1 is out of bound for grad_warp.
184      warp_data = [-1, 0.1, 0.7, 0.6]
185      warp_np = np.array(warp_data, dtype=dtype).reshape(warp_shape)
186      expected = [[[0.0], [27.62]]]
187      self._assertForwardOpMatchesExpected(input_np, warp_np, expected)
188
189      expected_grad_data = [[[[0.12], [0.27999997]], [[0.18000001],
190                                                      [0.42000002]]]]
191      expected_grad_warp = [[[0., 0.], [22.60000038, 35.20000076]]]
192
193      grad_output = np.ones([1, 2, 1], dtype=dtype)
194      self._assertBackwardOpMatchesExpected(input_np, warp_np, grad_output,
195                                            expected_grad_data,
196                                            expected_grad_warp)
197
198    # Both of (x, y) are greater than image size.
199    for dtype in self.float_types:
200      input_shape = [1, 2, 2, 1]
201      input_data = [10, 5, 13, 54]
202      input_np = np.array(input_data, dtype=dtype).reshape(input_shape)
203
204      warp_shape = [1, 2, 2]
205      # -0.1 is *inbound* for grad_warp and grad_data, 2.1 is out of bound.
206      warp_data = [-0.1, 0.1, 1.2, 2.1]
207      warp_np = np.array(warp_data, dtype=dtype).reshape(warp_shape)
208      expected = [[[0.0], [0.0]]]
209      self._assertForwardOpMatchesExpected(input_np, warp_np, expected)
210
211      expected_grad_data = [[[[0.81], [0.0]], [[0.09], [0.0]]]]
212      expected_grad_warp = [[[10.30, 2.7], [0.0, 0.0]]]
213
214      grad_output = np.ones([1, 2, 1], dtype=dtype)
215      self._assertBackwardOpMatchesExpected(input_np, warp_np, grad_output,
216                                            expected_grad_data,
217                                            expected_grad_warp)
218
219    # One of (x, y) is greater than image size.
220    for dtype in self.float_types:
221      input_shape = [1, 2, 2, 1]
222      input_data = [10, 5, 13, 54]
223      input_np = np.array(input_data, dtype=dtype).reshape(input_shape)
224
225      warp_shape = [1, 2, 2]
226      warp_data = [0.1, -0.1, 1.2, 0.1]
227      warp_np = np.array(warp_data, dtype=dtype).reshape(warp_shape)
228      expected = [[[0.0], [0.0]]]
229      self._assertForwardOpMatchesExpected(input_np, warp_np, expected)
230
231      expected_grad_data = [[[[0.81], [0.81]], [[0.0], [0.08]]]]
232      expected_grad_warp = [[[-4.5, 9.5], [-9.9, 39.20]]]
233
234      grad_output = np.ones([1, 2, 1], dtype=dtype)
235      self._assertBackwardOpMatchesExpected(input_np, warp_np, grad_output,
236                                            expected_grad_data,
237                                            expected_grad_warp)
238
239
240if __name__ == '__main__':
241  test.main()
242