• 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 Uniform distribution."""
16
17from __future__ import absolute_import
18from __future__ import division
19from __future__ import print_function
20
21import importlib
22
23import numpy as np
24
25from tensorflow.python.eager import backprop
26from tensorflow.python.framework import constant_op
27from tensorflow.python.framework import errors
28from tensorflow.python.framework import tensor_shape
29from tensorflow.python.framework import test_util
30from tensorflow.python.ops import array_ops
31from tensorflow.python.ops import math_ops
32from tensorflow.python.ops.distributions import uniform as uniform_lib
33from tensorflow.python.platform import test
34from tensorflow.python.platform import tf_logging
35
36
37def try_import(name):  # pylint: disable=invalid-name
38  module = None
39  try:
40    module = importlib.import_module(name)
41  except ImportError as e:
42    tf_logging.warning("Could not import %s: %s" % (name, str(e)))
43  return module
44
45
46stats = try_import("scipy.stats")
47
48
49class UniformTest(test.TestCase):
50
51  @test_util.run_in_graph_and_eager_modes
52  def testUniformRange(self):
53    a = 3.0
54    b = 10.0
55    uniform = uniform_lib.Uniform(low=a, high=b)
56    self.assertAllClose(a, self.evaluate(uniform.low))
57    self.assertAllClose(b, self.evaluate(uniform.high))
58    self.assertAllClose(b - a, self.evaluate(uniform.range()))
59
60  @test_util.run_in_graph_and_eager_modes
61  def testUniformPDF(self):
62    a = constant_op.constant([-3.0] * 5 + [15.0])
63    b = constant_op.constant([11.0] * 5 + [20.0])
64    uniform = uniform_lib.Uniform(low=a, high=b)
65
66    a_v = -3.0
67    b_v = 11.0
68    x = np.array([-10.5, 4.0, 0.0, 10.99, 11.3, 17.0], dtype=np.float32)
69
70    def _expected_pdf():
71      pdf = np.zeros_like(x) + 1.0 / (b_v - a_v)
72      pdf[x > b_v] = 0.0
73      pdf[x < a_v] = 0.0
74      pdf[5] = 1.0 / (20.0 - 15.0)
75      return pdf
76
77    expected_pdf = _expected_pdf()
78
79    pdf = uniform.prob(x)
80    self.assertAllClose(expected_pdf, self.evaluate(pdf))
81
82    log_pdf = uniform.log_prob(x)
83    self.assertAllClose(np.log(expected_pdf), self.evaluate(log_pdf))
84
85  @test_util.run_in_graph_and_eager_modes
86  def testUniformShape(self):
87    a = constant_op.constant([-3.0] * 5)
88    b = constant_op.constant(11.0)
89    uniform = uniform_lib.Uniform(low=a, high=b)
90
91    self.assertEqual(self.evaluate(uniform.batch_shape_tensor()), (5,))
92    self.assertEqual(uniform.batch_shape, tensor_shape.TensorShape([5]))
93    self.assertAllEqual(self.evaluate(uniform.event_shape_tensor()), [])
94    self.assertEqual(uniform.event_shape, tensor_shape.TensorShape([]))
95
96  @test_util.run_in_graph_and_eager_modes
97  def testUniformPDFWithScalarEndpoint(self):
98    a = constant_op.constant([0.0, 5.0])
99    b = constant_op.constant(10.0)
100    uniform = uniform_lib.Uniform(low=a, high=b)
101
102    x = np.array([0.0, 8.0], dtype=np.float32)
103    expected_pdf = np.array([1.0 / (10.0 - 0.0), 1.0 / (10.0 - 5.0)])
104
105    pdf = uniform.prob(x)
106    self.assertAllClose(expected_pdf, self.evaluate(pdf))
107
108  @test_util.run_in_graph_and_eager_modes
109  def testUniformCDF(self):
110    batch_size = 6
111    a = constant_op.constant([1.0] * batch_size)
112    b = constant_op.constant([11.0] * batch_size)
113    a_v = 1.0
114    b_v = 11.0
115    x = np.array([-2.5, 2.5, 4.0, 0.0, 10.99, 12.0], dtype=np.float32)
116
117    uniform = uniform_lib.Uniform(low=a, high=b)
118
119    def _expected_cdf():
120      cdf = (x - a_v) / (b_v - a_v)
121      cdf[x >= b_v] = 1
122      cdf[x < a_v] = 0
123      return cdf
124
125    cdf = uniform.cdf(x)
126    self.assertAllClose(_expected_cdf(), self.evaluate(cdf))
127
128    log_cdf = uniform.log_cdf(x)
129    self.assertAllClose(np.log(_expected_cdf()), self.evaluate(log_cdf))
130
131  @test_util.run_in_graph_and_eager_modes
132  def testUniformEntropy(self):
133    a_v = np.array([1.0, 1.0, 1.0])
134    b_v = np.array([[1.5, 2.0, 3.0]])
135    uniform = uniform_lib.Uniform(low=a_v, high=b_v)
136
137    expected_entropy = np.log(b_v - a_v)
138    self.assertAllClose(expected_entropy, self.evaluate(uniform.entropy()))
139
140  @test_util.run_in_graph_and_eager_modes
141  def testUniformAssertMaxGtMin(self):
142    a_v = np.array([1.0, 1.0, 1.0], dtype=np.float32)
143    b_v = np.array([1.0, 2.0, 3.0], dtype=np.float32)
144
145    with self.assertRaisesWithPredicateMatch(errors.InvalidArgumentError,
146                                             "x < y"):
147      uniform = uniform_lib.Uniform(low=a_v, high=b_v, validate_args=True)
148      self.evaluate(uniform.low)
149
150  @test_util.run_in_graph_and_eager_modes
151  def testUniformSample(self):
152    a = constant_op.constant([3.0, 4.0])
153    b = constant_op.constant(13.0)
154    a1_v = 3.0
155    a2_v = 4.0
156    b_v = 13.0
157    n = constant_op.constant(100000)
158    uniform = uniform_lib.Uniform(low=a, high=b)
159
160    samples = uniform.sample(n, seed=137)
161    sample_values = self.evaluate(samples)
162    self.assertEqual(sample_values.shape, (100000, 2))
163    self.assertAllClose(
164        sample_values[::, 0].mean(), (b_v + a1_v) / 2, atol=1e-1, rtol=0.)
165    self.assertAllClose(
166        sample_values[::, 1].mean(), (b_v + a2_v) / 2, atol=1e-1, rtol=0.)
167    self.assertFalse(
168        np.any(sample_values[::, 0] < a1_v) or np.any(sample_values >= b_v))
169    self.assertFalse(
170        np.any(sample_values[::, 1] < a2_v) or np.any(sample_values >= b_v))
171
172  @test_util.run_in_graph_and_eager_modes
173  def _testUniformSampleMultiDimensional(self):
174    # DISABLED: Please enable this test once b/issues/30149644 is resolved.
175    batch_size = 2
176    a_v = [3.0, 22.0]
177    b_v = [13.0, 35.0]
178    a = constant_op.constant([a_v] * batch_size)
179    b = constant_op.constant([b_v] * batch_size)
180
181    uniform = uniform_lib.Uniform(low=a, high=b)
182
183    n_v = 100000
184    n = constant_op.constant(n_v)
185    samples = uniform.sample(n)
186    self.assertEqual(samples.get_shape(), (n_v, batch_size, 2))
187
188    sample_values = self.evaluate(samples)
189
190    self.assertFalse(
191        np.any(sample_values[:, 0, 0] < a_v[0]) or
192        np.any(sample_values[:, 0, 0] >= b_v[0]))
193    self.assertFalse(
194        np.any(sample_values[:, 0, 1] < a_v[1]) or
195        np.any(sample_values[:, 0, 1] >= b_v[1]))
196
197    self.assertAllClose(
198        sample_values[:, 0, 0].mean(), (a_v[0] + b_v[0]) / 2, atol=1e-2)
199    self.assertAllClose(
200        sample_values[:, 0, 1].mean(), (a_v[1] + b_v[1]) / 2, atol=1e-2)
201
202  @test_util.run_in_graph_and_eager_modes
203  def testUniformMean(self):
204    a = 10.0
205    b = 100.0
206    uniform = uniform_lib.Uniform(low=a, high=b)
207    if not stats:
208      return
209    s_uniform = stats.uniform(loc=a, scale=b - a)
210    self.assertAllClose(self.evaluate(uniform.mean()), s_uniform.mean())
211
212  @test_util.run_in_graph_and_eager_modes
213  def testUniformVariance(self):
214    a = 10.0
215    b = 100.0
216    uniform = uniform_lib.Uniform(low=a, high=b)
217    if not stats:
218      return
219    s_uniform = stats.uniform(loc=a, scale=b - a)
220    self.assertAllClose(self.evaluate(uniform.variance()), s_uniform.var())
221
222  @test_util.run_in_graph_and_eager_modes
223  def testUniformStd(self):
224    a = 10.0
225    b = 100.0
226    uniform = uniform_lib.Uniform(low=a, high=b)
227    if not stats:
228      return
229    s_uniform = stats.uniform(loc=a, scale=b - a)
230    self.assertAllClose(self.evaluate(uniform.stddev()), s_uniform.std())
231
232  @test_util.run_in_graph_and_eager_modes
233  def testUniformNans(self):
234    a = 10.0
235    b = [11.0, 100.0]
236    uniform = uniform_lib.Uniform(low=a, high=b)
237
238    no_nans = constant_op.constant(1.0)
239    nans = constant_op.constant(0.0) / constant_op.constant(0.0)
240    self.assertTrue(self.evaluate(math_ops.is_nan(nans)))
241    with_nans = array_ops.stack([no_nans, nans])
242
243    pdf = uniform.prob(with_nans)
244
245    is_nan = self.evaluate(math_ops.is_nan(pdf))
246    self.assertFalse(is_nan[0])
247    self.assertTrue(is_nan[1])
248
249  @test_util.run_in_graph_and_eager_modes
250  def testUniformSamplePdf(self):
251    a = 10.0
252    b = [11.0, 100.0]
253    uniform = uniform_lib.Uniform(a, b)
254    self.assertTrue(
255        self.evaluate(
256            math_ops.reduce_all(uniform.prob(uniform.sample(10)) > 0)))
257
258  @test_util.run_in_graph_and_eager_modes
259  def testUniformBroadcasting(self):
260    a = 10.0
261    b = [11.0, 20.0]
262    uniform = uniform_lib.Uniform(a, b)
263
264    pdf = uniform.prob([[10.5, 11.5], [9.0, 19.0], [10.5, 21.0]])
265    expected_pdf = np.array([[1.0, 0.1], [0.0, 0.1], [1.0, 0.0]])
266    self.assertAllClose(expected_pdf, self.evaluate(pdf))
267
268  @test_util.run_in_graph_and_eager_modes
269  def testUniformSampleWithShape(self):
270    a = 10.0
271    b = [11.0, 20.0]
272    uniform = uniform_lib.Uniform(a, b)
273
274    pdf = uniform.prob(uniform.sample((2, 3)))
275    # pylint: disable=bad-continuation
276    expected_pdf = [
277        [[1.0, 0.1], [1.0, 0.1], [1.0, 0.1]],
278        [[1.0, 0.1], [1.0, 0.1], [1.0, 0.1]],
279    ]
280    # pylint: enable=bad-continuation
281    self.assertAllClose(expected_pdf, self.evaluate(pdf))
282
283    pdf = uniform.prob(uniform.sample())
284    expected_pdf = [1.0, 0.1]
285    self.assertAllClose(expected_pdf, self.evaluate(pdf))
286
287  def testFullyReparameterized(self):
288    a = constant_op.constant(0.1)
289    b = constant_op.constant(0.8)
290    with backprop.GradientTape() as tape:
291      tape.watch(a)
292      tape.watch(b)
293      uniform = uniform_lib.Uniform(a, b)
294      samples = uniform.sample(100)
295    grad_a, grad_b = tape.gradient(samples, [a, b])
296    self.assertIsNotNone(grad_a)
297    self.assertIsNotNone(grad_b)
298
299  # Eager doesn't pass due to a type mismatch in one of the ops.
300  def testUniformFloat64(self):
301    uniform = uniform_lib.Uniform(
302        low=np.float64(0.), high=np.float64(1.))
303
304    self.assertAllClose(
305        [1., 1.],
306        self.evaluate(uniform.prob(np.array([0.5, 0.6], dtype=np.float64))))
307
308    self.assertAllClose(
309        [0.5, 0.6],
310        self.evaluate(uniform.cdf(np.array([0.5, 0.6], dtype=np.float64))))
311
312    self.assertAllClose(0.5, self.evaluate(uniform.mean()))
313    self.assertAllClose(1 / 12., self.evaluate(uniform.variance()))
314    self.assertAllClose(0., self.evaluate(uniform.entropy()))
315
316
317if __name__ == "__main__":
318  test.main()
319