Home | History | Annotate | Download | only in kernel_tests
      1 # Copyright 2016 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 
     16 from __future__ import absolute_import
     17 from __future__ import division
     18 from __future__ import print_function
     19 
     20 import numpy as np
     21 from scipy import stats
     22 from tensorflow.contrib.distributions.python.ops import inverse_gamma
     23 from tensorflow.python.client import session
     24 from tensorflow.python.framework import constant_op
     25 from tensorflow.python.framework import tensor_shape
     26 from tensorflow.python.ops import nn_ops
     27 from tensorflow.python.platform import test
     28 
     29 
     30 class InverseGammaTest(test.TestCase):
     31 
     32   def testInverseGammaShape(self):
     33     with self.test_session():
     34       alpha = constant_op.constant([3.0] * 5)
     35       beta = constant_op.constant(11.0)
     36       inv_gamma = inverse_gamma.InverseGamma(concentration=alpha, rate=beta)
     37 
     38       self.assertEqual(inv_gamma.batch_shape_tensor().eval(), (5,))
     39       self.assertEqual(inv_gamma.batch_shape,
     40                        tensor_shape.TensorShape([5]))
     41       self.assertAllEqual(inv_gamma.event_shape_tensor().eval(), [])
     42       self.assertEqual(inv_gamma.event_shape, tensor_shape.TensorShape(
     43           []))
     44 
     45   def testInverseGammaLogPDF(self):
     46     with self.test_session():
     47       batch_size = 6
     48       alpha = constant_op.constant([2.0] * batch_size)
     49       beta = constant_op.constant([3.0] * batch_size)
     50       alpha_v = 2.0
     51       beta_v = 3.0
     52       x = np.array([2.5, 2.5, 4.0, 0.1, 1.0, 2.0], dtype=np.float32)
     53       inv_gamma = inverse_gamma.InverseGamma(concentration=alpha, rate=beta)
     54       expected_log_pdf = stats.invgamma.logpdf(x, alpha_v, scale=beta_v)
     55       log_pdf = inv_gamma.log_prob(x)
     56       self.assertEqual(log_pdf.get_shape(), (6,))
     57       self.assertAllClose(log_pdf.eval(), expected_log_pdf)
     58 
     59       pdf = inv_gamma.prob(x)
     60       self.assertEqual(pdf.get_shape(), (6,))
     61       self.assertAllClose(pdf.eval(), np.exp(expected_log_pdf))
     62 
     63   def testInverseGammaLogPDFMultidimensional(self):
     64     with self.test_session():
     65       batch_size = 6
     66       alpha = constant_op.constant([[2.0, 4.0]] * batch_size)
     67       beta = constant_op.constant([[3.0, 4.0]] * batch_size)
     68       alpha_v = np.array([2.0, 4.0])
     69       beta_v = np.array([3.0, 4.0])
     70       x = np.array([[2.5, 2.5, 4.0, 0.1, 1.0, 2.0]], dtype=np.float32).T
     71       inv_gamma = inverse_gamma.InverseGamma(concentration=alpha, rate=beta)
     72       expected_log_pdf = stats.invgamma.logpdf(x, alpha_v, scale=beta_v)
     73       log_pdf = inv_gamma.log_prob(x)
     74       log_pdf_values = log_pdf.eval()
     75       self.assertEqual(log_pdf.get_shape(), (6, 2))
     76       self.assertAllClose(log_pdf_values, expected_log_pdf)
     77 
     78       pdf = inv_gamma.prob(x)
     79       pdf_values = pdf.eval()
     80       self.assertEqual(pdf.get_shape(), (6, 2))
     81       self.assertAllClose(pdf_values, np.exp(expected_log_pdf))
     82 
     83   def testInverseGammaLogPDFMultidimensionalBroadcasting(self):
     84     with self.test_session():
     85       batch_size = 6
     86       alpha = constant_op.constant([[2.0, 4.0]] * batch_size)
     87       beta = constant_op.constant(3.0)
     88       alpha_v = np.array([2.0, 4.0])
     89       beta_v = 3.0
     90       x = np.array([[2.5, 2.5, 4.0, 0.1, 1.0, 2.0]], dtype=np.float32).T
     91       inv_gamma = inverse_gamma.InverseGamma(concentration=alpha, rate=beta)
     92       expected_log_pdf = stats.invgamma.logpdf(x, alpha_v, scale=beta_v)
     93       log_pdf = inv_gamma.log_prob(x)
     94       log_pdf_values = log_pdf.eval()
     95       self.assertEqual(log_pdf.get_shape(), (6, 2))
     96       self.assertAllClose(log_pdf_values, expected_log_pdf)
     97 
     98       pdf = inv_gamma.prob(x)
     99       pdf_values = pdf.eval()
    100       self.assertEqual(pdf.get_shape(), (6, 2))
    101       self.assertAllClose(pdf_values, np.exp(expected_log_pdf))
    102 
    103   def testInverseGammaCDF(self):
    104     with self.test_session():
    105       batch_size = 6
    106       alpha_v = 2.0
    107       beta_v = 3.0
    108       alpha = constant_op.constant([alpha_v] * batch_size)
    109       beta = constant_op.constant([beta_v] * batch_size)
    110       x = np.array([2.5, 2.5, 4.0, 0.1, 1.0, 2.0], dtype=np.float32)
    111 
    112       inv_gamma = inverse_gamma.InverseGamma(concentration=alpha, rate=beta)
    113       expected_cdf = stats.invgamma.cdf(x, alpha_v, scale=beta_v)
    114 
    115       cdf = inv_gamma.cdf(x)
    116       self.assertEqual(cdf.get_shape(), (batch_size,))
    117       self.assertAllClose(cdf.eval(), expected_cdf)
    118 
    119   def testInverseGammaMode(self):
    120     with self.test_session():
    121       alpha_v = np.array([5.5, 3.0, 2.5])
    122       beta_v = np.array([1.0, 4.0, 5.0])
    123       inv_gamma = inverse_gamma.InverseGamma(concentration=alpha_v, rate=beta_v)
    124       expected_modes = beta_v / (alpha_v + 1)
    125       self.assertEqual(inv_gamma.mode().get_shape(), (3,))
    126       self.assertAllClose(inv_gamma.mode().eval(), expected_modes)
    127 
    128   def testInverseGammaMeanAllDefined(self):
    129     with self.test_session():
    130       alpha_v = np.array([5.5, 3.0, 2.5])
    131       beta_v = np.array([1.0, 4.0, 5.0])
    132       inv_gamma = inverse_gamma.InverseGamma(concentration=alpha_v, rate=beta_v)
    133       expected_means = stats.invgamma.mean(alpha_v, scale=beta_v)
    134       self.assertEqual(inv_gamma.mean().get_shape(), (3,))
    135       self.assertAllClose(inv_gamma.mean().eval(), expected_means)
    136 
    137   def testInverseGammaMeanAllowNanStats(self):
    138     with self.test_session():
    139       # Mean will not be defined for the first entry.
    140       alpha_v = np.array([1.0, 3.0, 2.5])
    141       beta_v = np.array([1.0, 4.0, 5.0])
    142       inv_gamma = inverse_gamma.InverseGamma(
    143           concentration=alpha_v, rate=beta_v, allow_nan_stats=False)
    144       with self.assertRaisesOpError("x < y"):
    145         inv_gamma.mean().eval()
    146 
    147   def testInverseGammaMeanNanStats(self):
    148     with self.test_session():
    149       # Mode will not be defined for the first two entries.
    150       alpha_v = np.array([0.5, 1.0, 3.0, 2.5])
    151       beta_v = np.array([1.0, 2.0, 4.0, 5.0])
    152       inv_gamma = inverse_gamma.InverseGamma(
    153           concentration=alpha_v, rate=beta_v, allow_nan_stats=True)
    154       expected_means = beta_v / (alpha_v - 1)
    155       expected_means[0] = np.nan
    156       expected_means[1] = np.nan
    157       self.assertEqual(inv_gamma.mean().get_shape(), (4,))
    158       self.assertAllClose(inv_gamma.mean().eval(), expected_means)
    159 
    160   def testInverseGammaVarianceAllDefined(self):
    161     with self.test_session():
    162       alpha_v = np.array([7.0, 3.0, 2.5])
    163       beta_v = np.array([1.0, 4.0, 5.0])
    164       inv_gamma = inverse_gamma.InverseGamma(concentration=alpha_v, rate=beta_v)
    165       expected_variances = stats.invgamma.var(alpha_v, scale=beta_v)
    166       self.assertEqual(inv_gamma.variance().get_shape(), (3,))
    167       self.assertAllClose(inv_gamma.variance().eval(), expected_variances)
    168 
    169   def testInverseGammaVarianceAllowNanStats(self):
    170     with self.test_session():
    171       alpha_v = np.array([1.5, 3.0, 2.5])
    172       beta_v = np.array([1.0, 4.0, 5.0])
    173       inv_gamma = inverse_gamma.InverseGamma(
    174           concentration=alpha_v, rate=beta_v, allow_nan_stats=False)
    175       with self.assertRaisesOpError("x < y"):
    176         inv_gamma.variance().eval()
    177 
    178   def testInverseGammaVarianceNanStats(self):
    179     with self.test_session():
    180       alpha_v = np.array([1.5, 3.0, 2.5])
    181       beta_v = np.array([1.0, 4.0, 5.0])
    182       inv_gamma = inverse_gamma.InverseGamma(
    183           concentration=alpha_v, rate=beta_v, allow_nan_stats=True)
    184       expected_variances = stats.invgamma.var(alpha_v, scale=beta_v)
    185       expected_variances[0] = np.nan
    186       self.assertEqual(inv_gamma.variance().get_shape(), (3,))
    187       self.assertAllClose(inv_gamma.variance().eval(), expected_variances)
    188 
    189   def testInverseGammaEntropy(self):
    190     with self.test_session():
    191       alpha_v = np.array([1.0, 3.0, 2.5])
    192       beta_v = np.array([1.0, 4.0, 5.0])
    193       expected_entropy = stats.invgamma.entropy(alpha_v, scale=beta_v)
    194       inv_gamma = inverse_gamma.InverseGamma(concentration=alpha_v, rate=beta_v)
    195       self.assertEqual(inv_gamma.entropy().get_shape(), (3,))
    196       self.assertAllClose(inv_gamma.entropy().eval(), expected_entropy)
    197 
    198   def testInverseGammaSample(self):
    199     with session.Session():
    200       alpha_v = 4.0
    201       beta_v = 3.0
    202       alpha = constant_op.constant(alpha_v)
    203       beta = constant_op.constant(beta_v)
    204       n = 100000
    205       inv_gamma = inverse_gamma.InverseGamma(concentration=alpha, rate=beta)
    206       samples = inv_gamma.sample(n, seed=137)
    207       sample_values = samples.eval()
    208       self.assertEqual(samples.get_shape(), (n,))
    209       self.assertEqual(sample_values.shape, (n,))
    210       self.assertAllClose(
    211           sample_values.mean(),
    212           stats.invgamma.mean(
    213               alpha_v, scale=beta_v),
    214           atol=.0025)
    215       self.assertAllClose(
    216           sample_values.var(),
    217           stats.invgamma.var(alpha_v, scale=beta_v),
    218           atol=.15)
    219       self.assertTrue(self._kstest(alpha_v, beta_v, sample_values))
    220 
    221   def testInverseGammaSampleMultiDimensional(self):
    222     with session.Session():
    223       alpha_v = np.array([np.arange(3, 103, dtype=np.float32)])  # 1 x 100
    224       beta_v = np.array([np.arange(1, 11, dtype=np.float32)]).T  # 10 x 1
    225       inv_gamma = inverse_gamma.InverseGamma(concentration=alpha_v, rate=beta_v)
    226       n = 10000
    227       samples = inv_gamma.sample(n, seed=137)
    228       sample_values = samples.eval()
    229       self.assertEqual(samples.get_shape(), (n, 10, 100))
    230       self.assertEqual(sample_values.shape, (n, 10, 100))
    231       zeros = np.zeros_like(alpha_v + beta_v)  # 10 x 100
    232       alpha_bc = alpha_v + zeros
    233       beta_bc = beta_v + zeros
    234       self.assertAllClose(
    235           sample_values.mean(axis=0),
    236           stats.invgamma.mean(
    237               alpha_bc, scale=beta_bc),
    238           atol=.25)
    239       self.assertAllClose(
    240           sample_values.var(axis=0),
    241           stats.invgamma.var(alpha_bc, scale=beta_bc),
    242           atol=4.5)
    243       fails = 0
    244       trials = 0
    245       for ai, a in enumerate(np.reshape(alpha_v, [-1])):
    246         for bi, b in enumerate(np.reshape(beta_v, [-1])):
    247           s = sample_values[:, bi, ai]
    248           trials += 1
    249           fails += 0 if self._kstest(a, b, s) else 1
    250       self.assertLess(fails, trials * 0.03)
    251 
    252   def _kstest(self, alpha, beta, samples):
    253     # Uses the Kolmogorov-Smirnov test for goodness of fit.
    254     ks, _ = stats.kstest(samples, stats.invgamma(alpha, scale=beta).cdf)
    255     # Return True when the test passes.
    256     return ks < 0.02
    257 
    258   def testInverseGammaPdfOfSampleMultiDims(self):
    259     with session.Session() as sess:
    260       inv_gamma = inverse_gamma.InverseGamma(
    261           concentration=[7., 11.],
    262           rate=[[5.], [6.]])
    263       num = 50000
    264       samples = inv_gamma.sample(num, seed=137)
    265       pdfs = inv_gamma.prob(samples)
    266       sample_vals, pdf_vals = sess.run([samples, pdfs])
    267       self.assertEqual(samples.get_shape(), (num, 2, 2))
    268       self.assertEqual(pdfs.get_shape(), (num, 2, 2))
    269       self.assertAllClose(
    270           stats.invgamma.mean(
    271               [[7., 11.], [7., 11.]], scale=np.array([[5., 5.], [6., 6.]])),
    272           sample_vals.mean(axis=0),
    273           atol=.1)
    274       self.assertAllClose(
    275           stats.invgamma.var([[7., 11.], [7., 11.]],
    276                              scale=np.array([[5., 5.], [6., 6.]])),
    277           sample_vals.var(axis=0),
    278           atol=.1)
    279       self._assertIntegral(sample_vals[:, 0, 0], pdf_vals[:, 0, 0], err=0.02)
    280       self._assertIntegral(sample_vals[:, 0, 1], pdf_vals[:, 0, 1], err=0.02)
    281       self._assertIntegral(sample_vals[:, 1, 0], pdf_vals[:, 1, 0], err=0.02)
    282       self._assertIntegral(sample_vals[:, 1, 1], pdf_vals[:, 1, 1], err=0.02)
    283 
    284   def _assertIntegral(self, sample_vals, pdf_vals, err=1e-3):
    285     s_p = zip(sample_vals, pdf_vals)
    286     prev = (0, 0)
    287     total = 0
    288     for k in sorted(s_p, key=lambda x: x[0]):
    289       pair_pdf = (k[1] + prev[1]) / 2
    290       total += (k[0] - prev[0]) * pair_pdf
    291       prev = k
    292     self.assertNear(1., total, err=err)
    293 
    294   def testInverseGammaNonPositiveInitializationParamsRaises(self):
    295     with self.test_session():
    296       alpha_v = constant_op.constant(0.0, name="alpha")
    297       beta_v = constant_op.constant(1.0, name="beta")
    298       inv_gamma = inverse_gamma.InverseGamma(
    299           concentration=alpha_v, rate=beta_v, validate_args=True)
    300       with self.assertRaisesOpError("alpha"):
    301         inv_gamma.mean().eval()
    302       alpha_v = constant_op.constant(1.0, name="alpha")
    303       beta_v = constant_op.constant(0.0, name="beta")
    304       inv_gamma = inverse_gamma.InverseGamma(
    305           concentration=alpha_v, rate=beta_v, validate_args=True)
    306       with self.assertRaisesOpError("beta"):
    307         inv_gamma.mean().eval()
    308 
    309   def testInverseGammaWithSoftplusConcentrationRate(self):
    310     with self.test_session():
    311       alpha = constant_op.constant([-0.1, -2.9], name="alpha")
    312       beta = constant_op.constant([1.0, -4.8], name="beta")
    313       inv_gamma = inverse_gamma.InverseGammaWithSoftplusConcentrationRate(
    314           concentration=alpha, rate=beta, validate_args=True)
    315       self.assertAllClose(nn_ops.softplus(alpha).eval(),
    316                           inv_gamma.concentration.eval())
    317       self.assertAllClose(nn_ops.softplus(beta).eval(),
    318                           inv_gamma.rate.eval())
    319 
    320 
    321 if __name__ == "__main__":
    322   test.main()
    323