• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2015 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 tensorflow.ops.ops."""
16
17import numpy as np
18
19from tensorflow.python.framework import constant_op
20from tensorflow.python.framework import dtypes
21from tensorflow.python.framework import errors_impl
22from tensorflow.python.framework import ops
23from tensorflow.python.framework import random_seed
24from tensorflow.python.framework import test_util
25from tensorflow.python.layers import convolutional
26from tensorflow.python.ops import array_ops
27from tensorflow.python.ops import init_ops
28from tensorflow.python.ops import linalg_ops
29from tensorflow.python.ops import math_ops
30from tensorflow.python.ops import partitioned_variables
31from tensorflow.python.ops import random_ops
32from tensorflow.python.ops import variable_scope
33from tensorflow.python.ops import variables
34from tensorflow.python.platform import test
35
36
37# Returns true iff the two initializers produce the same tensor to
38# within a tiny tolerance.
39def identicaltest(tc, init1, init2, shape=None):
40  """Tests if two initializations are identical to within tiny tolerances.
41
42  Args:
43    tc: An instance of TensorFlowTestCase.
44    init1: An Initializer that generates a tensor of a given shape
45    init2: An Initializer that generates a tensor of a given shape
46    shape: Shape of the tensor to initialize or `None` to use a vector of length
47      100.
48
49  Returns:
50    True or False as determined by test.
51  """
52  if shape is None:
53    shape = [100]
54  with tc.test_session(graph=ops.Graph()):
55    t1 = init1(shape).eval()
56  with tc.test_session(graph=ops.Graph()):
57    t2 = init2(shape).eval()
58  return np.allclose(t1, t2, rtol=1e-15, atol=1e-15)
59
60
61def duplicated_initializer(tc, init, graph_seed, shape=None):
62  """Tests duplicated random initializer within the same graph.
63
64  This test generates two random kernels from the same initializer to the same
65  graph, and checks if the results are close enough. Even given the same global,
66  seed, two different instances of random kernels should generate different
67  results.
68
69  Args:
70    tc: An instance of TensorFlowTestCase.
71    init: An Initializer that generates a tensor of a given shape
72    graph_seed: A graph-level seed to use.
73    shape: Shape of the tensor to initialize or `None` to use a vector of length
74      100.
75
76  Returns:
77    True or False as determined by test.
78  """
79  if shape is None:
80    shape = [100]
81  with tc.test_session(graph=ops.Graph()):
82    random_seed.set_random_seed(graph_seed)
83    t1 = init(shape).eval()
84    t2 = init(shape).eval()
85    return np.allclose(t1, t2, rtol=1e-15, atol=1e-15)
86
87
88def _init_sampler(tc, init, num):
89  """Returns a func to generate a random tensor of shape [num].
90
91  Args:
92    tc: An instance of TensorFlowTestCase.
93    init: An Initializer that generates a tensor of a given shape
94    num: Size of 1D tensor to create.
95
96  Returns:
97    Function to generate a random tensor.
98  """
99
100  def func():
101    with tc.test_session():
102      return init([num]).eval()
103
104  return func
105
106
107class ConstantInitializersTest(test.TestCase):
108
109  @test_util.run_deprecated_v1
110  def testZerosInitializer(self):
111    with self.session():
112      shape = [2, 3]
113      x = variable_scope.get_variable(
114          "x", shape=shape, initializer=init_ops.zeros_initializer())
115      self.evaluate(x.initializer)
116      self.assertAllEqual(x, np.zeros(shape))
117
118  @test_util.run_deprecated_v1
119  def testOnesInitializer(self):
120    with self.session():
121      shape = [2, 3]
122      x = variable_scope.get_variable(
123          "x", shape=shape, initializer=init_ops.ones_initializer())
124      self.evaluate(x.initializer)
125      self.assertAllEqual(x, np.ones(shape))
126
127  @test_util.run_deprecated_v1
128  def testConstantZeroInitializer(self):
129    with self.session():
130      shape = [2, 3]
131      x = variable_scope.get_variable(
132          "x", shape=shape, initializer=init_ops.constant_initializer(0.0))
133      self.evaluate(x.initializer)
134      self.assertAllEqual(x, np.zeros(shape))
135
136  @test_util.run_deprecated_v1
137  def testConstantOneInitializer(self):
138    with self.session():
139      shape = [2, 3]
140      x = variable_scope.get_variable(
141          "x", shape=shape, initializer=init_ops.constant_initializer(1.0))
142      self.evaluate(x.initializer)
143      self.assertAllEqual(x, np.ones(shape))
144
145  @test_util.run_deprecated_v1
146  def testConstantIntInitializer(self):
147    with self.session():
148      shape = [2, 3]
149      x = variable_scope.get_variable(
150          "x",
151          shape=shape,
152          dtype=dtypes.int32,
153          initializer=init_ops.constant_initializer(7))
154      self.evaluate(x.initializer)
155      self.assertEqual(x.dtype.base_dtype, dtypes.int32)
156      self.assertAllEqual(x, 7 * np.ones(shape, dtype=np.int32))
157
158  @test_util.run_deprecated_v1
159  def testConstantTupleInitializer(self):
160    with self.session():
161      shape = [3]
162      x = variable_scope.get_variable(
163          "x",
164          shape=shape,
165          dtype=dtypes.int32,
166          initializer=init_ops.constant_initializer((10, 20, 30)))
167      self.evaluate(x.initializer)
168      self.assertEqual(x.dtype.base_dtype, dtypes.int32)
169      self.assertAllEqual(x, [10, 20, 30])
170
171  def _testNDimConstantInitializer(self, name, value, shape, expected):
172    with self.cached_session():
173      init = init_ops.constant_initializer(value, dtype=dtypes.int32)
174      x = variable_scope.get_variable(name, shape=shape, initializer=init)
175      self.evaluate(x.initializer)
176
177      actual = array_ops.reshape(x, [-1]).eval()
178      self.assertEqual(len(actual), len(expected))
179      for a, e in zip(actual, expected):
180        self.assertEqual(a, e)
181
182  @test_util.run_deprecated_v1
183  def testNDimConstantInitializer(self):
184    value = [0, 1, 2, 3, 4, 5]
185    shape = [2, 3]
186    expected = list(value)
187
188    self._testNDimConstantInitializer("list", value, shape, expected)
189    self._testNDimConstantInitializer("ndarray", np.asarray(value), shape,
190                                      expected)
191    self._testNDimConstantInitializer("2D-ndarray",
192                                      np.asarray(value).reshape(tuple(shape)),
193                                      shape, expected)
194
195  def _testNDimConstantInitializerLessValues(self, name, value, shape,
196                                             expected):
197    with self.cached_session():
198      init = init_ops.constant_initializer(value, dtype=dtypes.int32)
199      x = variable_scope.get_variable(name, shape=shape, initializer=init)
200      self.evaluate(x.initializer)
201
202      actual = array_ops.reshape(x, [-1]).eval()
203      self.assertGreater(len(actual), len(expected))
204      for i in range(len(actual)):
205        a = actual[i]
206        e = expected[i] if i < len(expected) else expected[-1]
207        self.assertEqual(a, e)
208
209  @test_util.run_deprecated_v1
210  def testNDimConstantInitializerLessValues(self):
211    value = [0, 1, 2, 3, 4, 5]
212    shape = [2, 4]
213    expected = list(value)
214
215    self._testNDimConstantInitializerLessValues("list", value, shape, expected)
216    self._testNDimConstantInitializerLessValues("ndarray", np.asarray(value),
217                                                shape, expected)
218    self._testNDimConstantInitializerLessValues(
219        "2D-ndarray",
220        np.asarray(value).reshape(tuple([2, 3])), shape, expected)
221
222  def _testNDimConstantInitializerMoreValues(self, value, shape):
223    ops.reset_default_graph()
224    with self.cached_session():
225      init = init_ops.constant_initializer(value, dtype=dtypes.int32)
226      self.assertRaises(
227          ValueError,
228          variable_scope.get_variable,
229          "x",
230          shape=shape,
231          initializer=init)
232
233  @test_util.run_deprecated_v1
234  def testNDimConstantInitializerMoreValues(self):
235    value = [0, 1, 2, 3, 4, 5, 6, 7]
236    shape = [2, 3]
237    self._testNDimConstantInitializerMoreValues(value, shape)
238    self._testNDimConstantInitializerMoreValues(np.asarray(value), shape)
239    self._testNDimConstantInitializerMoreValues(
240        np.asarray(value).reshape(tuple([2, 4])), shape)
241
242  def testInvalidValueTypeForConstantInitializerCausesTypeError(self):
243    c = constant_op.constant([1.0, 2.0, 3.0])
244    with self.assertRaisesRegex(TypeError,
245                                r"Invalid type for initial value=.*Tensor.*"):
246      init_ops.constant_initializer(c, dtype=dtypes.float32)
247    v = variables.Variable([3.0, 2.0, 1.0])
248    with self.assertRaisesRegex(
249        TypeError, r"Invalid type for initial value=.*Variable.*"):
250      init_ops.constant_initializer(v, dtype=dtypes.float32)
251
252
253class RandomNormalInitializationTest(test.TestCase):
254
255  @test_util.run_deprecated_v1
256  def testInitializerIdentical(self):
257    for dtype in [dtypes.float32, dtypes.float64]:
258      init1 = init_ops.random_normal_initializer(0.0, 1.0, seed=1, dtype=dtype)
259      init2 = init_ops.random_normal_initializer(0.0, 1.0, seed=1, dtype=dtype)
260      self.assertTrue(identicaltest(self, init1, init2))
261
262  @test_util.run_deprecated_v1
263  def testInitializerDifferent(self):
264    for dtype in [dtypes.float32, dtypes.float64]:
265      init1 = init_ops.random_normal_initializer(0.0, 1.0, seed=1, dtype=dtype)
266      init2 = init_ops.random_normal_initializer(0.0, 1.0, seed=2, dtype=dtype)
267      self.assertFalse(identicaltest(self, init1, init2))
268
269  @test_util.run_deprecated_v1
270  def testDuplicatedInitializer(self):
271    init = init_ops.random_normal_initializer(0.0, 1.0)
272    self.assertFalse(duplicated_initializer(self, init, 1))
273
274  def testInvalidDataType(self):
275    self.assertRaises(
276        ValueError,
277        init_ops.random_normal_initializer,
278        0.0,
279        1.0,
280        dtype=dtypes.string)
281
282
283class TruncatedNormalInitializationTest(test.TestCase):
284
285  @test_util.run_deprecated_v1
286  def testInitializerIdentical(self):
287    for dtype in [dtypes.float32, dtypes.float64]:
288      init1 = init_ops.truncated_normal_initializer(
289          0.0, 1.0, seed=1, dtype=dtype)
290      init2 = init_ops.truncated_normal_initializer(
291          0.0, 1.0, seed=1, dtype=dtype)
292      self.assertTrue(identicaltest(self, init1, init2))
293
294  @test_util.run_deprecated_v1
295  def testInitializerDifferent(self):
296    for dtype in [dtypes.float32, dtypes.float64]:
297      init1 = init_ops.truncated_normal_initializer(
298          0.0, 1.0, seed=1, dtype=dtype)
299      init2 = init_ops.truncated_normal_initializer(
300          0.0, 1.0, seed=2, dtype=dtype)
301      self.assertFalse(identicaltest(self, init1, init2))
302
303  @test_util.run_deprecated_v1
304  def testDuplicatedInitializer(self):
305    init = init_ops.truncated_normal_initializer(0.0, 1.0)
306    self.assertFalse(duplicated_initializer(self, init, 1))
307
308  def testInvalidDataType(self):
309    self.assertRaises(
310        ValueError,
311        init_ops.truncated_normal_initializer,
312        0.0,
313        1.0,
314        dtype=dtypes.string)
315
316
317class RandomUniformInitializationTest(test.TestCase):
318
319  @test_util.run_deprecated_v1
320  def testInitializerIdentical(self):
321    for dtype in [dtypes.float32, dtypes.float64, dtypes.int64]:
322      init1 = init_ops.random_uniform_initializer(0, 7, seed=1, dtype=dtype)
323      init2 = init_ops.random_uniform_initializer(0, 7, seed=1, dtype=dtype)
324      self.assertTrue(identicaltest(self, init1, init2))
325
326  @test_util.run_deprecated_v1
327  def testInitializerDifferent(self):
328    for dtype in [dtypes.float32, dtypes.float64, dtypes.int32, dtypes.int64]:
329      init1 = init_ops.random_uniform_initializer(0, 7, seed=1, dtype=dtype)
330      init2 = init_ops.random_uniform_initializer(0, 7, seed=2, dtype=dtype)
331      self.assertFalse(identicaltest(self, init1, init2))
332
333  @test_util.run_deprecated_v1
334  def testDuplicatedInitializer(self):
335    init = init_ops.random_uniform_initializer(0.0, 1.0)
336    self.assertFalse(duplicated_initializer(self, init, 1))
337
338
339class UniformUnitScalingInitializationTest(test.TestCase):
340
341  @test_util.run_deprecated_v1
342  def testInitializerIdentical(self):
343    for dtype in [dtypes.float32, dtypes.float64]:
344      init1 = init_ops.uniform_unit_scaling_initializer(seed=1, dtype=dtype)
345      init2 = init_ops.uniform_unit_scaling_initializer(seed=1, dtype=dtype)
346      self.assertTrue(identicaltest(self, init1, init2))
347      init3 = init_ops.uniform_unit_scaling_initializer(
348          1.5, seed=1, dtype=dtype)
349      init4 = init_ops.uniform_unit_scaling_initializer(
350          1.5, seed=1, dtype=dtype)
351      self.assertTrue(identicaltest(self, init3, init4))
352
353  @test_util.run_deprecated_v1
354  def testInitializerDifferent(self):
355    for dtype in [dtypes.float32, dtypes.float64]:
356      init1 = init_ops.uniform_unit_scaling_initializer(seed=1, dtype=dtype)
357      init2 = init_ops.uniform_unit_scaling_initializer(seed=2, dtype=dtype)
358      init3 = init_ops.uniform_unit_scaling_initializer(
359          1.5, seed=1, dtype=dtype)
360      self.assertFalse(identicaltest(self, init1, init2))
361      self.assertFalse(identicaltest(self, init1, init3))
362      self.assertFalse(identicaltest(self, init2, init3))
363
364  @test_util.run_deprecated_v1
365  def testZeroSize(self):
366    shape = [0, 2]
367    with self.cached_session():
368      x = variable_scope.get_variable(
369          "x",
370          shape=shape,
371          initializer=init_ops.uniform_unit_scaling_initializer())
372      self.evaluate(variables.global_variables_initializer())
373      self.assertAllEqual(shape, self.evaluate(x).shape)
374
375  @test_util.run_deprecated_v1
376  def testDuplicatedInitializer(self):
377    init = init_ops.uniform_unit_scaling_initializer()
378    self.assertFalse(duplicated_initializer(self, init, 1))
379
380  def testInvalidDataType(self):
381    self.assertRaises(
382        ValueError,
383        init_ops.uniform_unit_scaling_initializer,
384        dtype=dtypes.string)
385
386
387class VarianceScalingInitializationTest(test.TestCase):
388
389  @test_util.run_deprecated_v1
390  def testTruncatedNormalDistribution(self):
391    shape = [100, 100]
392    expect_mean = 0.
393    expect_var = 1. / shape[0]
394    init = init_ops.variance_scaling_initializer(
395        distribution="truncated_normal")
396
397    with self.session(), \
398      test.mock.patch.object(
399          random_ops, "truncated_normal", wraps=random_ops.truncated_normal) \
400          as mock_truncated_normal:
401      x = init(shape).eval()
402      self.assertTrue(mock_truncated_normal.called)
403
404    self.assertNear(np.mean(x), expect_mean, err=1e-2)
405    self.assertNear(np.var(x), expect_var, err=1e-2)
406
407  @test_util.run_deprecated_v1
408  def testNormalDistribution(self):
409    shape = [100, 100]
410    expect_mean = 0.
411    expect_var = 1. / shape[0]
412    init = init_ops.variance_scaling_initializer(distribution="normal")
413
414    with self.session(), \
415      test.mock.patch.object(
416          random_ops, "truncated_normal", wraps=random_ops.truncated_normal) \
417          as mock_truncated_normal:
418      x = init(shape).eval()
419      self.assertTrue(mock_truncated_normal.called)
420
421    self.assertNear(np.mean(x), expect_mean, err=1e-2)
422    self.assertNear(np.var(x), expect_var, err=1e-2)
423
424  @test_util.run_deprecated_v1
425  def testUntruncatedNormalDistribution(self):
426    shape = [100, 100]
427    expect_mean = 0.
428    expect_var = 1. / shape[0]
429    init = init_ops.variance_scaling_initializer(
430        distribution="untruncated_normal")
431
432    with self.session(), \
433      test.mock.patch.object(
434          random_ops, "random_normal", wraps=random_ops.random_normal) \
435          as mock_random_normal:
436      x = init(shape).eval()
437      self.assertTrue(mock_random_normal.called)
438
439    self.assertNear(np.mean(x), expect_mean, err=1e-2)
440    self.assertNear(np.var(x), expect_var, err=1e-2)
441
442  @test_util.run_deprecated_v1
443  def testUniformDistribution(self):
444    shape = [100, 100]
445    expect_mean = 0.
446    expect_var = 1. / shape[0]
447    init = init_ops.variance_scaling_initializer(distribution="uniform")
448
449    with self.session():
450      x = init(shape).eval()
451
452    self.assertNear(np.mean(x), expect_mean, err=1e-2)
453    self.assertNear(np.var(x), expect_var, err=1e-2)
454
455
456# TODO(vrv): move to sequence_ops_test?
457class RangeTest(test.TestCase):
458
459  def _Range(self, start, limit, delta):
460    with self.cached_session():
461      tf_ans = math_ops.range(start, limit, delta, name="range")
462      self.assertEqual([len(np.arange(start, limit, delta))],
463                       tf_ans.get_shape())
464      return self.evaluate(tf_ans)
465
466  def testBasic(self):
467    self.assertTrue(
468        np.array_equal(self._Range(0, 5, 1), np.array([0, 1, 2, 3, 4])))
469    self.assertTrue(np.array_equal(self._Range(0, 5, 2), np.array([0, 2, 4])))
470    self.assertTrue(np.array_equal(self._Range(0, 6, 2), np.array([0, 2, 4])))
471    self.assertTrue(
472        np.array_equal(self._Range(13, 32, 7), np.array([13, 20, 27])))
473    self.assertTrue(
474        np.array_equal(
475            self._Range(100, 500, 100), np.array([100, 200, 300, 400])))
476    self.assertEqual(math_ops.range(0, 5, 1).dtype, dtypes.int32)
477
478  @test_util.run_deprecated_v1
479  def testLimitOnly(self):
480    with self.session():
481      self.assertAllEqual(np.arange(5), math_ops.range(5))
482
483  def testEmpty(self):
484    for start in 0, 5:
485      self.assertTrue(np.array_equal(self._Range(start, start, 1), []))
486
487  def testNonInteger(self):
488    self.assertTrue(
489        np.allclose(self._Range(0, 2, 0.5), np.array([0, 0.5, 1, 1.5])))
490    self.assertTrue(np.allclose(self._Range(0, 5, 2.5), np.array([0, 2.5])))
491    self.assertTrue(
492        np.allclose(self._Range(0, 3, 0.9), np.array([0, 0.9, 1.8, 2.7])))
493    self.assertTrue(
494        np.allclose(
495            self._Range(100., 500., 100.), np.array([100, 200, 300, 400])))
496    self.assertEqual(math_ops.range(0., 5., 1.).dtype, dtypes.float32)
497
498  def testNegativeDelta(self):
499    self.assertTrue(
500        np.array_equal(self._Range(5, -1, -1), np.array([5, 4, 3, 2, 1, 0])))
501    self.assertTrue(
502        np.allclose(self._Range(2.5, 0, -0.5), np.array([2.5, 2, 1.5, 1, 0.5])))
503    self.assertTrue(
504        np.array_equal(self._Range(-5, -10, -3), np.array([-5, -8])))
505
506  def testDType(self):
507    zero_int32 = math_ops.cast(0, dtypes.int32)
508    zero_int64 = math_ops.cast(0, dtypes.int64)
509    zero_float32 = math_ops.cast(0, dtypes.float32)
510    zero_float64 = math_ops.cast(0, dtypes.float64)
511
512    self.assertEqual(math_ops.range(zero_int32, 0, 1).dtype, dtypes.int32)
513    self.assertEqual(math_ops.range(zero_int64, 0, 1).dtype, dtypes.int64)
514    self.assertEqual(math_ops.range(zero_float32, 0, 1).dtype, dtypes.float32)
515    self.assertEqual(math_ops.range(zero_float64, 0, 1).dtype, dtypes.float64)
516
517    self.assertEqual(
518        math_ops.range(zero_int32, zero_int64, 1).dtype, dtypes.int64)
519    self.assertEqual(
520        math_ops.range(zero_int64, zero_float32, 1).dtype, dtypes.float32)
521    self.assertEqual(
522        math_ops.range(zero_float32, zero_float64, 1).dtype, dtypes.float64)
523    self.assertEqual(
524        math_ops.range(zero_float64, zero_int32, 1).dtype, dtypes.float64)
525
526    self.assertEqual(
527        math_ops.range(0, 0, 1, dtype=dtypes.int32).dtype, dtypes.int32)
528    self.assertEqual(
529        math_ops.range(0, 0, 1, dtype=dtypes.int64).dtype, dtypes.int64)
530    self.assertEqual(
531        math_ops.range(0, 0, 1, dtype=dtypes.float32).dtype, dtypes.float32)
532    self.assertEqual(
533        math_ops.range(0, 0, 1, dtype=dtypes.float64).dtype, dtypes.float64)
534
535  def testMixedDType(self):
536    # Test case for GitHub issue 35710
537    tf_ans = math_ops.range(
538        constant_op.constant(4, dtype=dtypes.int32), dtype=dtypes.int64)
539    self.assertAllEqual(self.evaluate(tf_ans), np.array([0, 1, 2, 3]))
540
541  def testLargeLimits(self):
542    # Test case for GitHub issue 46913.
543    with self.session():
544      with self.assertRaises(errors_impl.ResourceExhaustedError):
545        v = math_ops.range(0, 9223372036854775807)
546        self.evaluate(v)
547
548  def testLargeStarts(self):
549    # Test case for GitHub issue 46899.
550    with self.session():
551      with self.assertRaises((ValueError, errors_impl.InvalidArgumentError)):
552        v = math_ops.range(start=-1e+38, limit=1)
553        self.evaluate(v)
554
555
556# TODO(vrv): move to sequence_ops_test?
557class LinSpaceTest(test.TestCase):
558
559  def _gpu_modes(self):
560    if test.is_gpu_available():
561      return [False, True]
562    else:
563      return [False]
564
565  def _LinSpace(self, start, stop, num):
566    with ops.Graph().as_default() as graph:
567      with self.session(graph=graph, force_gpu=self.force_gpu):
568        tf_ans = math_ops.linspace(start, stop, num, name="linspace")
569        self.assertEqual([num], tf_ans.get_shape())
570        return self.evaluate(tf_ans)
571
572  def testPositive(self):
573    for self.force_gpu in self._gpu_modes():
574      self.assertArrayNear(self._LinSpace(1., 5., 1), np.array([1.]), 1e-5)
575      self.assertArrayNear(self._LinSpace(1., 5., 2), np.array([1., 5.]), 1e-5)
576      self.assertArrayNear(
577          self._LinSpace(1., 5., 3), np.array([1., 3., 5.]), 1e-5)
578      self.assertArrayNear(
579          self._LinSpace(1., 5., 4), np.array([1., 7. / 3., 11. / 3., 5.]),
580          1e-5)
581
582  def testNegative(self):
583    for self.force_gpu in self._gpu_modes():
584      self.assertArrayNear(self._LinSpace(-1., -5., 1), np.array([-1.]), 1e-5)
585      self.assertArrayNear(
586          self._LinSpace(-1., -5., 2), np.array([-1., -5.]), 1e-5)
587      self.assertArrayNear(
588          self._LinSpace(-1., -5., 3), np.array([-1., -3., -5.]), 1e-5)
589      self.assertArrayNear(
590          self._LinSpace(-1., -5., 4), np.array([-1., -7. / 3., -11. / 3.,
591                                                 -5.]), 1e-5)
592
593  def testNegativeToPositive(self):
594    for self.force_gpu in self._gpu_modes():
595      self.assertArrayNear(self._LinSpace(-1., 5., 1), np.array([-1.]), 1e-5)
596      self.assertArrayNear(
597          self._LinSpace(-1., 5., 2), np.array([-1., 5.]), 1e-5)
598      self.assertArrayNear(
599          self._LinSpace(-1., 5., 3), np.array([-1., 2., 5.]), 1e-5)
600      self.assertArrayNear(
601          self._LinSpace(-1., 5., 4), np.array([-1., 1., 3., 5.]), 1e-5)
602
603  def testPoint(self):
604    for self.force_gpu in self._gpu_modes():
605      self.assertArrayNear(self._LinSpace(5., 5., 1), np.array([5.]), 1e-5)
606      self.assertArrayNear(self._LinSpace(5., 5., 2), np.array([5.] * 2), 1e-5)
607      self.assertArrayNear(self._LinSpace(5., 5., 3), np.array([5.] * 3), 1e-5)
608      self.assertArrayNear(self._LinSpace(5., 5., 4), np.array([5.] * 4), 1e-5)
609
610  def testEndpointsAreExact(self):
611    for self.force_gpu in self._gpu_modes():
612      # Test some cases that produce last values not equal to "stop" when
613      # computed via start + (num - 1) * ((stop - start) / (num - 1)), since
614      # float arithmetic will introduce error through precision loss.
615      self.assertAllEqual(
616          self._LinSpace(0., 1., 42)[[0, -1]], np.array([0., 1.], np.float32))
617      self.assertAllEqual(
618          self._LinSpace(-1., 0., 42)[[0, -1]], np.array([-1., 0.], np.float32))
619      self.assertAllEqual(
620          self._LinSpace(.1, .2, 4)[[0, -1]], np.array([.1, .2], np.float32))
621      # Check a case for float64 error too.
622      self.assertAllEqual(
623          self._LinSpace(np.array(0., np.float64), .1, 12)[[0, -1]],
624          np.array([0., .1], np.float64))
625
626
627class LinSpaceNdTest(test.TestCase):
628
629  def _gpu_modes(self):
630    if test.is_gpu_available():
631      return [False, True]
632    else:
633      return [False]
634
635  def _LinSpace(self, start, stop, num, axis=0):
636    with ops.Graph().as_default() as graph:
637      with self.session(graph=graph, force_gpu=self.force_gpu):
638        tf_ans = math_ops.linspace_nd(start, stop, num, axis=axis)
639        return self.evaluate(tf_ans)
640
641  def _LinSpaceNumConstant(self, start, stop, num, axis=0):
642    with ops.Graph().as_default() as graph:
643      num_constant = constant_op.constant(num)
644      with self.session(graph=graph, force_gpu=self.force_gpu):
645        tf_ans = math_ops.linspace_nd(start, stop, num_constant, axis=axis)
646        return self.evaluate(tf_ans)
647
648  def _LinspaceNoneShape(self, start, stop, num, graph_shape=None, axis=0):
649    with ops.Graph().as_default() as graph:
650      num_tensor = array_ops.placeholder(dtypes.int32)
651      start_t = array_ops.placeholder(dtypes.float32, shape=graph_shape)
652      stop_t = array_ops.placeholder(dtypes.float32, shape=graph_shape)
653      ans_tensor = math_ops.linspace_nd(start_t, stop_t, num_tensor, axis=axis)
654
655      with self.session(graph=graph, force_gpu=self.force_gpu) as sess:
656        feed_dict = {start_t: start, stop_t: stop, num_tensor: num}
657        return sess.run(ans_tensor, feed_dict=feed_dict)
658
659  def testPositive(self):
660    for self.force_gpu in self._gpu_modes():
661      self.assertArrayNear(self._LinSpace(1., 5., 1), np.array([1.]), 1e-5)
662      self.assertArrayNear(self._LinSpace(1., 5., 2), np.array([1., 5.]), 1e-5)
663      self.assertArrayNear(
664          self._LinSpace(1., 5., 3), np.array([1., 3., 5.]), 1e-5)
665      self.assertArrayNear(
666          self._LinSpace(1., 5., 4), np.array([1., 7. / 3., 11. / 3., 5.]),
667          1e-5)
668
669  def testNegative(self):
670    for self.force_gpu in self._gpu_modes():
671      self.assertArrayNear(self._LinSpace(-1., -5., 1), np.array([-1.]), 1e-5)
672      self.assertArrayNear(
673          self._LinSpace(-1., -5., 2), np.array([-1., -5.]), 1e-5)
674      self.assertArrayNear(
675          self._LinSpace(-1., -5., 3), np.array([-1., -3., -5.]), 1e-5)
676      self.assertArrayNear(
677          self._LinSpace(-1., -5., 4), np.array([-1., -7. / 3., -11. / 3.,
678                                                 -5.]), 1e-5)
679
680  def testNegativeToPositive(self):
681    for self.force_gpu in self._gpu_modes():
682      self.assertArrayNear(self._LinSpace(-1., 5., 1), np.array([-1.]), 1e-5)
683      self.assertArrayNear(
684          self._LinSpace(-1., 5., 2), np.array([-1., 5.]), 1e-5)
685      self.assertArrayNear(
686          self._LinSpace(-1., 5., 3), np.array([-1., 2., 5.]), 1e-5)
687      self.assertArrayNear(
688          self._LinSpace(-1., 5., 4), np.array([-1., 1., 3., 5.]), 1e-5)
689
690  def testPoint(self):
691    for self.force_gpu in self._gpu_modes():
692      self.assertArrayNear(self._LinSpace(5., 5., 1), np.array([5.]), 1e-5)
693      self.assertArrayNear(self._LinSpace(5., 5., 2), np.array([5.] * 2), 1e-5)
694      self.assertArrayNear(self._LinSpace(5., 5., 3), np.array([5.] * 3), 1e-5)
695      self.assertArrayNear(self._LinSpace(5., 5., 4), np.array([5.] * 4), 1e-5)
696
697  def testEndpointsAreExact(self):
698    for self.force_gpu in self._gpu_modes():
699      # Test some cases that produce last values not equal to "stop" when
700      # computed via start + (num - 1) * ((stop - start) / (num - 1)), since
701      # float arithmetic will introduce error through precision loss.
702      self.assertAllEqual(
703          self._LinSpace(0., 1., 42)[[0, -1]], np.array([0., 1.], np.float32))
704      self.assertAllEqual(
705          self._LinSpace(-1., 0., 42)[[0, -1]], np.array([-1., 0.], np.float32))
706      self.assertAllEqual(
707          self._LinSpace(.1, .2, 4)[[0, -1]], np.array([.1, .2], np.float32))
708      # Check a case for float64 error too.
709      self.assertAllEqual(
710          self._LinSpace(np.array(0., np.float64), .1, 12)[[0, -1]],
711          np.array([0., .1], np.float64))
712
713  def testScalarsCompareToNumpy(self):
714    for self.force_gpu in self._gpu_modes():
715      actual = self._LinSpace(0., 1., 32)
716      expected = np.linspace(0., 1., 32)
717      self.assertArrayNear(expected, actual, 1e-5)
718
719  def _baseNDArrayCompareToNumpy(self, axis):
720    for self.force_gpu in self._gpu_modes():
721      a, b, expected, num = self.create_nd_inputs_and_expected_output(axis)
722      actual = self._LinSpace(a, b, num, axis=axis)
723      self.assert_close(actual, expected)
724
725  def assert_close(self, actual, expected):
726    wrong_indices = np.where(~np.allclose(actual, expected))
727    mess = "Wrong float answer. Wrong indices: {}".format(wrong_indices)
728    self.assertTrue(np.allclose(actual, expected), mess)
729
730  def create_nd_inputs_and_expected_output(self, axis):
731    a = np.arange(2, dtype=np.float32)
732    b = a * 5
733    num = 5
734
735    res = np.array([[0., 0., 0., 0., 0.], [1., 2., 3., 4., 5.]])
736    expected = res if axis != 0 else res.T
737    return a, b, expected, num
738
739  def testNDArrayCompareToNumpyDefaultAxis(self):
740    self._baseNDArrayCompareToNumpy(0)
741
742  def testNDArrayAxisStrictlyPositive(self):
743    self._baseNDArrayCompareToNumpy(1)
744
745  def testNDArrayAxisStrictlyNegative(self):
746    self._baseNDArrayCompareToNumpy(-1)
747
748  def testNumConstant(self):
749    for self.force_gpu in self._gpu_modes():
750      actual = self._LinSpaceNumConstant(0., 1., 32)
751      expected = np.linspace(0., 1., 32)
752      self.assertArrayNear(expected, actual, 1e-5)
753
754  def testUnknownShapeAtGraphCreationTime(self):
755    self.base_test_unknown_shape((2))
756
757  def testNoneValuesInShapeAtGraphCreationTime(self):
758    self.base_test_unknown_shape((None))
759
760  def testNoneShapeAtGraphCreationTime(self):
761    self.base_test_unknown_shape(None)
762
763  def base_test_unknown_shape(self, graph_shape):
764    for self.force_gpu in self._gpu_modes():
765      axis = 1
766      a, b, expected, num = self.create_nd_inputs_and_expected_output(axis)
767      actual = self._LinspaceNoneShape(a, b, num, graph_shape, axis)
768      self.assert_close(actual, expected)
769
770
771class DeviceTest(test.TestCase):
772
773  def testNoDevice(self):
774    with ops.Graph().as_default():
775      var = variables.Variable([[1.0, 1.0]])
776    self.assertDeviceEqual(None, var.device)
777    self.assertDeviceEqual(None, var.initializer.device)
778
779  def testDevice(self):
780    with ops.Graph().as_default():
781      with ops.device("/job:ps"):
782        var = variables.Variable([[1.0, 1.0]])
783    self.assertDeviceEqual("/job:ps", var.device)
784    self.assertDeviceEqual("/job:ps", var.initializer.device)
785
786
787class OrthogonalInitializerTest(test.TestCase):
788
789  @test_util.run_deprecated_v1
790  def testInitializerIdentical(self):
791    for dtype in [dtypes.float32, dtypes.float64]:
792      init1 = init_ops.orthogonal_initializer(seed=1, dtype=dtype)
793      init2 = init_ops.orthogonal_initializer(seed=1, dtype=dtype)
794      self.assertTrue(identicaltest(self, init1, init2, (10, 10)))
795
796  @test_util.run_deprecated_v1
797  def testInitializerDifferent(self):
798    for dtype in [dtypes.float32, dtypes.float64]:
799      init1 = init_ops.orthogonal_initializer(seed=1, dtype=dtype)
800      init2 = init_ops.orthogonal_initializer(seed=2, dtype=dtype)
801      self.assertFalse(identicaltest(self, init1, init2, (10, 10)))
802
803  @test_util.run_deprecated_v1
804  def testDuplicatedInitializer(self):
805    init = init_ops.orthogonal_initializer()
806    self.assertFalse(duplicated_initializer(self, init, 1, (10, 10)))
807
808  def testInvalidDataType(self):
809    self.assertRaises(
810        ValueError, init_ops.orthogonal_initializer, dtype=dtypes.string)
811
812  def testInvalidShape(self):
813    init1 = init_ops.orthogonal_initializer()
814    with self.session(graph=ops.Graph(), use_gpu=True):
815      self.assertRaises(ValueError, init1, shape=[5])
816
817  @test_util.run_deprecated_v1
818  def testGain(self):
819    shape = (10, 10)
820    for dtype in [dtypes.float32, dtypes.float64]:
821      init1 = init_ops.orthogonal_initializer(seed=1, dtype=dtype)
822      init2 = init_ops.orthogonal_initializer(gain=3.14, seed=1, dtype=dtype)
823      with self.session(graph=ops.Graph(), use_gpu=True):
824        t1 = init1(shape).eval()
825        t2 = init2(shape).eval()
826      self.assertAllClose(t1, t2 / 3.14)
827
828  @test_util.run_deprecated_v1
829  def testShapesValues(self):
830    for dtype in [dtypes.float32, dtypes.float64]:
831      for shape in [(10, 10), (10, 9, 8), (100, 5, 5), (50, 40), (40, 50)]:
832        init = init_ops.orthogonal_initializer(dtype=dtype)
833        tol = 1e-5 if dtype == dtypes.float32 else 1e-12
834        with self.session(graph=ops.Graph(), use_gpu=True):
835          # Check the shape
836          t = init(shape).eval()
837          self.assertAllEqual(shape, t.shape)
838          # Check orthogonality by computing the inner product
839          t = t.reshape((np.prod(t.shape[:-1]), t.shape[-1]))
840          if t.shape[0] > t.shape[1]:
841            self.assertAllClose(
842                np.dot(t.T, t), np.eye(t.shape[1]), rtol=tol, atol=tol)
843          else:
844            self.assertAllClose(
845                np.dot(t, t.T), np.eye(t.shape[0]), rtol=tol, atol=tol)
846
847
848class ConvolutionDeltaOrthogonalInitializerTest(test.TestCase):
849
850  @test_util.run_deprecated_v1
851  def testInitializerIdentical(self):
852    for dtype in [dtypes.float32, dtypes.float64]:
853      init1 = init_ops.convolutional_delta_orthogonal(seed=1, dtype=dtype)
854      init2 = init_ops.convolutional_delta_orthogonal(seed=1, dtype=dtype)
855      self.assertTrue(identicaltest(self, init1, init2, (3, 3, 10, 10)))
856
857  @test_util.run_deprecated_v1
858  def testInitializerDifferent(self):
859    for dtype in [dtypes.float32, dtypes.float64]:
860      init1 = init_ops.convolutional_delta_orthogonal(seed=1, dtype=dtype)
861      init2 = init_ops.convolutional_delta_orthogonal(seed=2, dtype=dtype)
862      self.assertFalse(identicaltest(self, init1, init2, (3, 3, 10, 10)))
863
864  @test_util.run_deprecated_v1
865  def testDuplicatedInitializer(self):
866    init = init_ops.convolutional_delta_orthogonal()
867    self.assertFalse(duplicated_initializer(self, init, 1, (3, 3, 10, 10)))
868
869  def testInvalidDataType(self):
870    self.assertRaises(
871        ValueError,
872        init_ops.convolutional_delta_orthogonal,
873        dtype=dtypes.string)
874
875  def testInvalidShape(self):
876    init1 = init_ops.convolutional_delta_orthogonal()
877    with self.session(graph=ops.Graph(), use_gpu=True):
878      self.assertRaises(ValueError, init1, shape=[3, 3, 6, 5])
879
880  @test_util.run_deprecated_v1
881  def testGain(self):
882    shape = (3, 3, 10, 10)
883    for dtype in [dtypes.float32, dtypes.float64]:
884      init1 = init_ops.convolutional_delta_orthogonal(seed=1, dtype=dtype)
885      init2 = init_ops.convolutional_delta_orthogonal(
886          gain=3.14, seed=1, dtype=dtype)
887      with self.session(graph=ops.Graph(), use_gpu=True):
888        t1 = init1(shape).eval()
889        t2 = init2(shape).eval()
890      self.assertAllClose(t1, t2 / 3.14)
891
892  @test_util.run_deprecated_v1
893  def testShapesValues(self):
894    gain = 3.14
895    for dtype in [dtypes.float32]:
896      for kernel_size in [[3], [8], [3, 5], [2, 4], [3, 3, 3], [2, 2, 2]]:
897        tol = 1e-2
898        # Check orthogonality by computing ratio between
899        # the 2-norms of the inputs and outputs.
900        if len(kernel_size) == 1:
901          shape = [4, 32, 64]
902          convolution = convolutional.conv1d
903        elif len(kernel_size) == 2:
904          convolution = convolutional.conv2d
905          shape = [4, 32, 32, 64]
906        else:
907          shape = [4, 16, 16, 16, 64]
908          convolution = convolutional.conv3d
909        inputs = random_ops.random_normal(shape, dtype=dtype)
910        inputs_2norm = linalg_ops.norm(inputs)
911        outputs = convolution(
912            inputs,
913            padding="same",
914            filters=128,
915            kernel_size=kernel_size,
916            use_bias=False,
917            kernel_initializer=init_ops.convolutional_delta_orthogonal(
918                gain=gain))
919        outputs_shape = shape[0:-1] + [128]
920        outputs_2norm = linalg_ops.norm(outputs)
921        ratio = outputs_2norm / inputs_2norm
922        my_ops = variables.global_variables_initializer()
923        with self.session():
924          self.evaluate(my_ops)
925          # Check the shape of the outputs
926          t = self.evaluate(outputs)
927          self.assertAllEqual(t.shape, outputs_shape)
928          # Check isometry of the delta-orthogonal kernel.
929          self.assertAllClose(self.evaluate(ratio), gain, rtol=tol, atol=tol)
930
931  @test_util.run_deprecated_v1
932  def testNonuniformity(self):
933    value = 0
934    abs_value = 0
935    shape = [3, 3, 10, 10]
936    count = 70
937    tol = 1e-5
938    with self.session():
939      for i in range(count):
940        x = variable_scope.get_variable(
941            "{}".format(i),
942            shape=shape,
943            initializer=init_ops.convolutional_delta_orthogonal)
944        self.evaluate(x.initializer)
945        y = self.evaluate(x)[1, 1, :, :]
946        determinant = np.linalg.det(y)
947        value += determinant
948        abs_value += np.abs(determinant)
949
950      # Check there is some variation in the signs of the determinants
951      self.assertLess(value, count - tol)
952      self.assertLess(-count + tol, value)
953      # Check all determinants have absolute value 1
954      # Compute the sum of the absolute values of 'count' determinants
955      self.assertAllClose(abs_value, count, rtol=tol, atol=tol)
956
957
958@test_util.run_all_without_tensor_float_32(
959    "Tests convolutional_orthogonal_1d, which calls matmul")
960class ConvolutionOrthogonal1dInitializerTest(test.TestCase):
961
962  @test_util.run_deprecated_v1
963  def testInitializerIdentical(self):
964    for dtype in [dtypes.float32, dtypes.float64]:
965      init1 = init_ops.convolutional_orthogonal_1d(seed=1, dtype=dtype)
966      init2 = init_ops.convolutional_orthogonal_1d(seed=1, dtype=dtype)
967      self.assertTrue(identicaltest(self, init1, init2, (3, 10, 10)))
968
969  @test_util.run_deprecated_v1
970  def testInitializerDifferent(self):
971    for dtype in [dtypes.float32, dtypes.float64]:
972      init1 = init_ops.convolutional_orthogonal_1d(seed=1, dtype=dtype)
973      init2 = init_ops.convolutional_orthogonal_1d(seed=2, dtype=dtype)
974      self.assertFalse(identicaltest(self, init1, init2, (3, 10, 10)))
975
976  @test_util.run_deprecated_v1
977  def testDuplicatedInitializer(self):
978    init = init_ops.convolutional_orthogonal_1d()
979    self.assertFalse(duplicated_initializer(self, init, 1, (3, 10, 10)))
980
981  def testInvalidDataType(self):
982    self.assertRaises(
983        ValueError, init_ops.convolutional_orthogonal_1d, dtype=dtypes.string)
984
985  def testInvalidShape(self):
986    init1 = init_ops.convolutional_orthogonal_1d()
987    with self.session(graph=ops.Graph(), use_gpu=True):
988      self.assertRaises(ValueError, init1, shape=[3, 6, 5])
989
990  @test_util.run_deprecated_v1
991  def testGain(self):
992    shape = (3, 10, 10)
993    for dtype in [dtypes.float32, dtypes.float64]:
994      init1 = init_ops.convolutional_orthogonal_1d(seed=1, dtype=dtype)
995      init2 = init_ops.convolutional_orthogonal_1d(
996          gain=3.14, seed=1, dtype=dtype)
997      with self.session(graph=ops.Graph(), use_gpu=True):
998        t1 = init1(shape).eval()
999        t2 = init2(shape).eval()
1000      self.assertAllClose(t1, t2 / 3.14)
1001
1002  @test_util.run_deprecated_v1
1003  def testNonuniformity(self):
1004    value = 0
1005    abs_value = 0
1006    shape = [3, 10, 10]
1007    count = 70
1008    tol = 1e-5
1009    with self.session():
1010      for i in range(count):
1011        x = variable_scope.get_variable(
1012            "{}".format(i),
1013            shape=shape,
1014            initializer=init_ops.convolutional_orthogonal_1d)
1015        self.evaluate(x.initializer)
1016        y = np.sum(self.evaluate(x), axis=0)
1017        determinant = np.linalg.det(y)
1018        value += determinant
1019        abs_value += np.abs(determinant)
1020
1021      # Check there is some variation in the signs of the determinants.
1022      self.assertLess(value, count - tol)
1023      self.assertLess(-count + tol, value)
1024      # Check all determinants have absolute value 1
1025      # Compute the sum of the absolute values of 'count' determinants
1026      self.assertAllClose(abs_value, count, rtol=tol, atol=tol)
1027
1028  @test_util.run_deprecated_v1
1029  def testShapesValues(self):
1030
1031    def circular_pad(input_, width, kernel_size):
1032      """Pad input_ for computing (circular) convolution.
1033
1034      Args:
1035        input_: the input tensor
1036        width: the width of the tensor.
1037        kernel_size: the kernel size of the filter.
1038
1039      Returns:
1040        a tensor whose width is (width + kernel_size - 1).
1041      """
1042
1043      beginning = kernel_size // 2
1044      end = kernel_size - 1 - beginning
1045
1046      tmp_up = array_ops.slice(input_, [0, width - beginning, 0],
1047                               [-1, beginning, -1])
1048      tmp_down = array_ops.slice(input_, [0, 0, 0], [-1, end, -1])
1049      tmp = array_ops.concat([tmp_up, input_, tmp_down], 1)
1050
1051      return tmp
1052
1053    cout = 64
1054    shape = [10, 20, 32]
1055    outputs_shape = shape[0:-1] + [cout]
1056    dtype = dtypes.float32
1057    tol = 1e-3
1058    gain = 3.14
1059    # Check orthogonality/isometry by computing the ratio between
1060    # the 2-norms of the inputs and outputs.
1061    for kernel_size in [[1], [2], [3], [4], [5], [6]]:
1062      convolution = convolutional.conv1d
1063      inputs = random_ops.random_normal(shape, dtype=dtype)
1064      inputs_2norm = linalg_ops.norm(inputs)
1065      input_with_circular_pad = circular_pad(inputs, shape[1], kernel_size[0])
1066      outputs = convolution(
1067          input_with_circular_pad,
1068          padding="valid",
1069          filters=cout,
1070          kernel_size=kernel_size[0],
1071          use_bias=False,
1072          kernel_initializer=init_ops.convolutional_orthogonal_1d(gain=gain))
1073      outputs_2norm = linalg_ops.norm(outputs)
1074      ratio = outputs_2norm / inputs_2norm
1075      my_ops = variables.global_variables_initializer()
1076      with self.session():
1077        self.evaluate(my_ops)
1078        # Check the shape of the outputs
1079        t = self.evaluate(outputs)
1080        self.assertAllEqual(t.shape, outputs_shape)
1081        # Check isometry of the orthogonal kernel.
1082        self.assertAllClose(self.evaluate(ratio), gain, rtol=tol, atol=tol)
1083
1084
1085class ConvolutionOrthogonal2dInitializerTest(test.TestCase):
1086
1087  @test_util.run_deprecated_v1
1088  def testInitializerIdentical(self):
1089    for dtype in [dtypes.float32, dtypes.float64]:
1090      init1 = init_ops.convolutional_orthogonal_2d(seed=1, dtype=dtype)
1091      init2 = init_ops.convolutional_orthogonal_2d(seed=1, dtype=dtype)
1092      self.assertTrue(identicaltest(self, init1, init2, (3, 3, 10, 10)))
1093
1094  @test_util.run_deprecated_v1
1095  def testInitializerDifferent(self):
1096    for dtype in [dtypes.float32, dtypes.float64]:
1097      init1 = init_ops.convolutional_orthogonal_2d(seed=1, dtype=dtype)
1098      init2 = init_ops.convolutional_orthogonal_2d(seed=2, dtype=dtype)
1099      self.assertFalse(identicaltest(self, init1, init2, (3, 3, 10, 10)))
1100
1101  @test_util.run_deprecated_v1
1102  def testDuplicatedInitializer(self):
1103    init = init_ops.convolutional_orthogonal_2d()
1104    self.assertFalse(duplicated_initializer(self, init, 1, (3, 3, 10, 10)))
1105
1106  def testInvalidDataType(self):
1107    self.assertRaises(
1108        ValueError, init_ops.convolutional_orthogonal_2d, dtype=dtypes.string)
1109
1110  def testInvalidShape(self):
1111    init1 = init_ops.convolutional_orthogonal_2d()
1112    with self.session(graph=ops.Graph(), use_gpu=True):
1113      self.assertRaises(ValueError, init1, shape=[3, 3, 6, 5])
1114
1115  @test_util.run_deprecated_v1
1116  def testGain(self):
1117    shape = (3, 3, 10, 10)
1118    for dtype in [dtypes.float32, dtypes.float64]:
1119      init1 = init_ops.convolutional_orthogonal_2d(seed=1, dtype=dtype)
1120      init2 = init_ops.convolutional_orthogonal_2d(
1121          gain=3.14, seed=1, dtype=dtype)
1122      with self.session(graph=ops.Graph(), use_gpu=True):
1123        t1 = init1(shape).eval()
1124        t2 = init2(shape).eval()
1125      self.assertAllClose(t1, t2 / 3.14)
1126
1127  @test_util.run_deprecated_v1
1128  def testShapesValues(self):
1129
1130    def circular_pad(input_, width, kernel_size):
1131      """Pad input_ for computing (circular) convolution.
1132
1133      Args:
1134        input_: the input tensor
1135        width: the width of the tensor.
1136        kernel_size: the kernel size of the filter.
1137
1138      Returns:
1139        a tensor whose width is (width + kernel_size - 1).
1140      """
1141      beginning = kernel_size // 2
1142      end = kernel_size - 1 - beginning
1143
1144      tmp_up = array_ops.slice(input_, [0, width - beginning, 0, 0],
1145                               [-1, beginning, width, -1])
1146      tmp_down = array_ops.slice(input_, [0, 0, 0, 0], [-1, end, width, -1])
1147      tmp = array_ops.concat([tmp_up, input_, tmp_down], 1)
1148
1149      new_width = width + kernel_size - 1
1150      tmp_left = array_ops.slice(tmp, [0, 0, width - beginning, 0],
1151                                 [-1, new_width, beginning, -1])
1152      tmp_right = array_ops.slice(tmp, [0, 0, 0, 0], [-1, new_width, end, -1])
1153
1154      final = array_ops.concat([tmp_left, tmp, tmp_right], 2)
1155      return final
1156
1157    cout = 45
1158    shape = [64, 28, 28, 32]
1159    outputs_shape = shape[0:-1] + [cout]
1160    dtype = dtypes.float32
1161    tol = 1e-3
1162    gain = 3.14
1163    # Check orthogonality/isometry by computing the ratio between
1164    # the 2-norms of the inputs and outputs.
1165    for kernel_size in [[1, 1], [2, 2], [3, 3], [4, 4], [5, 5]]:
1166      convolution = convolutional.conv2d
1167      inputs = random_ops.random_normal(shape, dtype=dtype)
1168      inputs_2norm = linalg_ops.norm(inputs)
1169      input_with_circular_pad = circular_pad(inputs, shape[1], kernel_size[0])
1170      outputs = convolution(
1171          input_with_circular_pad,
1172          padding="valid",
1173          filters=cout,
1174          kernel_size=kernel_size,
1175          use_bias=False,
1176          kernel_initializer=init_ops.convolutional_orthogonal_2d(gain=gain))
1177      outputs_2norm = linalg_ops.norm(outputs)
1178      ratio = outputs_2norm / inputs_2norm
1179      my_ops = variables.global_variables_initializer()
1180      with self.session():
1181        self.evaluate(my_ops)
1182        # Check the shape of the outputs
1183        t = self.evaluate(outputs)
1184        self.assertAllEqual(t.shape, outputs_shape)
1185        # Check isometry of the orthogonal kernel.
1186        self.assertAllClose(self.evaluate(ratio), gain, rtol=tol, atol=tol)
1187
1188
1189@test_util.run_all_without_tensor_float_32(
1190    "Tests convolutional_orthogonal_3d, which calls matmul")
1191class ConvolutionOrthogonal3dInitializerTest(test.TestCase):
1192
1193  @test_util.run_deprecated_v1
1194  def testInitializerIdentical(self):
1195    for dtype in [dtypes.float32, dtypes.float64]:
1196      init1 = init_ops.convolutional_orthogonal_3d(seed=1, dtype=dtype)
1197      init2 = init_ops.convolutional_orthogonal_3d(seed=1, dtype=dtype)
1198      self.assertTrue(identicaltest(self, init1, init2, (3, 3, 3, 10, 10)))
1199
1200  @test_util.run_deprecated_v1
1201  def testInitializerDifferent(self):
1202    for dtype in [dtypes.float32, dtypes.float64]:
1203      init1 = init_ops.convolutional_orthogonal_3d(seed=1, dtype=dtype)
1204      init2 = init_ops.convolutional_orthogonal_3d(seed=2, dtype=dtype)
1205      self.assertFalse(identicaltest(self, init1, init2, (3, 3, 3, 10, 10)))
1206
1207  @test_util.run_deprecated_v1
1208  def testDuplicatedInitializer(self):
1209    init = init_ops.convolutional_orthogonal_3d()
1210    self.assertFalse(duplicated_initializer(self, init, 1, (3, 3, 3, 10, 10)))
1211
1212  def testInvalidDataType(self):
1213    self.assertRaises(
1214        ValueError, init_ops.convolutional_orthogonal_3d, dtype=dtypes.string)
1215
1216  def testInvalidShape(self):
1217    init1 = init_ops.convolutional_orthogonal_3d()
1218    with self.session(graph=ops.Graph(), use_gpu=True):
1219      self.assertRaises(ValueError, init1, shape=[3, 3, 3, 6, 5])
1220
1221  @test_util.run_deprecated_v1
1222  def testGain(self):
1223    shape = (3, 3, 3, 10, 10)
1224    for dtype in [dtypes.float32, dtypes.float64]:
1225      init1 = init_ops.convolutional_orthogonal_3d(seed=1, dtype=dtype)
1226      init2 = init_ops.convolutional_orthogonal_3d(
1227          gain=3.14, seed=1, dtype=dtype)
1228      with self.session(graph=ops.Graph(), use_gpu=True):
1229        t1 = init1(shape).eval()
1230        t2 = init2(shape).eval()
1231      self.assertAllClose(t1, t2 / 3.14)
1232
1233  @test_util.run_deprecated_v1
1234  def testNonuniformity(self):
1235    value = 0
1236    abs_value = 0
1237    shape = [3, 3, 3, 5, 5]
1238    count = 20
1239    tol = 1e-5
1240    with self.session():
1241      for i in range(count):
1242        x = variable_scope.get_variable(
1243            "{}".format(i),
1244            shape=shape,
1245            initializer=init_ops.convolutional_orthogonal_3d)
1246        self.evaluate(x.initializer)
1247        y = np.sum(self.evaluate(x), axis=(0, 1, 2))
1248        determinant = np.linalg.det(y)
1249        value += determinant
1250        abs_value += np.abs(determinant)
1251
1252      # Check there is some variation in the signs of the determinants
1253      self.assertLess(value, count - tol)
1254      self.assertLess(-count + tol, value)
1255      # Check all determinants have absolute value 1
1256      # Compute the sum of the absolute values of 'count' determinants
1257      self.assertAllClose(abs_value, count, rtol=tol, atol=tol)
1258
1259  @test_util.run_deprecated_v1
1260  def testShapesValues(self):
1261
1262    def circular_pad(input_, width, kernel_size):
1263      """Padding input_ for computing circular convolution.
1264
1265      Args:
1266        input_: the input tensor
1267        width: the width of the tensor.
1268        kernel_size: the kernel size of the filter.
1269
1270      Returns:
1271        a tensor whose width is (width + kernel_size - 1).
1272      """
1273
1274      beginning = kernel_size // 2
1275      end = kernel_size - 1 - beginning
1276
1277      tmp_up = array_ops.slice(input_, [0, width - beginning, 0, 0, 0],
1278                               [-1, beginning, -1, -1, -1])
1279      tmp_down = array_ops.slice(input_, [0, 0, 0, 0, 0], [-1, end, -1, -1, -1])
1280      tmp = array_ops.concat([tmp_up, input_, tmp_down], 1)
1281
1282      tmp_left = array_ops.slice(tmp, [0, 0, width - beginning, 0, 0],
1283                                 [-1, -1, beginning, -1, -1])
1284      tmp_right = array_ops.slice(tmp, [0, 0, 0, 0, 0], [-1, -1, end, -1, -1])
1285      tmp = array_ops.concat([tmp_left, tmp, tmp_right], 2)
1286
1287      tmp_front = array_ops.slice(tmp, [0, 0, 0, width - beginning, 0],
1288                                  [-1, -1, -1, beginning, -1])
1289      tmp_back = array_ops.slice(tmp, [0, 0, 0, 0, 0], [-1, -1, -1, end, -1])
1290      return array_ops.concat([tmp_front, tmp, tmp_back], 3)
1291
1292    cout = 32
1293    shape = [1, 7, 7, 7, 16]
1294    outputs_shape = shape[0:-1] + [cout]
1295    dtype = dtypes.float32
1296    tol = 1e-3
1297    gain = 3.14
1298    # Check orthogonality/isometry by computing the ratio between
1299    # the 2-norms of the inputs and outputs.
1300    for kernel_size in [[1, 1, 1], [2, 2, 2], [3, 3, 3]]:
1301      convolution = convolutional.conv3d
1302      inputs = random_ops.random_normal(shape, dtype=dtype)
1303      inputs_2norm = linalg_ops.norm(inputs)
1304      input_with_circular_pad = circular_pad(inputs, shape[1], kernel_size[0])
1305      outputs = convolution(
1306          input_with_circular_pad,
1307          padding="valid",
1308          filters=cout,
1309          kernel_size=kernel_size[0],
1310          use_bias=False,
1311          kernel_initializer=init_ops.convolutional_orthogonal_3d(gain=gain))
1312      outputs_2norm = linalg_ops.norm(outputs)
1313      ratio = outputs_2norm / inputs_2norm
1314      my_ops = variables.global_variables_initializer()
1315      with self.cached_session():
1316        self.evaluate(my_ops)
1317        # Check the shape of the outputs
1318        t = self.evaluate(outputs)
1319        self.assertAllEqual(t.shape, outputs_shape)
1320        # Check isometry of the orthogonal kernel.
1321        self.assertAllClose(self.evaluate(ratio), gain, rtol=tol, atol=tol)
1322
1323
1324class IdentityInitializerTest(test.TestCase):
1325
1326  def testInvalidDataType(self):
1327    self.assertRaises(
1328        ValueError, init_ops.orthogonal_initializer, dtype=dtypes.string)
1329
1330  def testInvalidShape(self):
1331    init = init_ops.identity_initializer()
1332    with self.session(graph=ops.Graph(), use_gpu=True):
1333      self.assertRaises(ValueError, init, shape=[5, 7, 7])
1334      self.assertRaises(ValueError, init, shape=[5])
1335      self.assertRaises(ValueError, init, shape=[])
1336
1337  @test_util.run_deprecated_v1
1338  def testNonSquare(self):
1339    init = init_ops.identity_initializer()
1340    shape = (10, 5)
1341    with self.session(graph=ops.Graph(), use_gpu=True):
1342      self.assertAllClose(init(shape), np.eye(*shape))
1343
1344  @test_util.run_deprecated_v1
1345  def testGain(self):
1346    shape = (10, 10)
1347    for dtype in [dtypes.float32, dtypes.float64]:
1348      init_default = init_ops.identity_initializer(dtype=dtype)
1349      init_custom = init_ops.identity_initializer(gain=0.9, dtype=dtype)
1350      with self.session(graph=ops.Graph(), use_gpu=True):
1351        self.assertAllClose(init_default(shape), np.eye(*shape))
1352      with self.session(graph=ops.Graph(), use_gpu=True):
1353        self.assertAllClose(init_custom(shape), np.eye(*shape) * 0.9)
1354
1355  @test_util.run_deprecated_v1
1356  def testPartitions(self):
1357    shape = (10, 10)
1358    init = init_ops.identity_initializer()
1359    partitioner = partitioned_variables.variable_axis_size_partitioner(1)
1360    with self.session(graph=ops.Graph(), use_gpu=True):
1361      with variable_scope.variable_scope(
1362          "foo", partitioner=partitioner, initializer=init):
1363        v = array_ops.identity(variable_scope.get_variable("bar", shape=shape))
1364      self.evaluate(variables.global_variables_initializer())
1365      self.assertAllClose(v, np.eye(*shape))
1366
1367
1368if __name__ == "__main__":
1369  test.main()
1370