def mcmc(self, mcmc_samples, num_burnin_steps, step_size, num_leapfrog_steps=3, initial_state=None, thinning=2): # Function used to perform the sampling for the posterior distributions of the hyperparameters # Inputs: # mcmc_samples := number of samples to collect for the hyperparameters # num_burnin_steps := number of samples to discard # step_size := step_size for the HMC sampler # num_leapfrog_steps := number of leapfrog steps for the HMC sampler # initial_state := list ([beta, varm, loc]) of tensors providing the initial state for the HMC sampler # Outputs: # hyperpar_samples= list [loc_samples_, varm_samples, beta_samples_] of samples for the posterior # distribution of the hyperparameters # acceptance_rate_ := acceptance rate of the sampling unnormalized_posterior_log_prob = functools.partial( self.joint_log_prob, self.noise) #------- Unconstrained representation--------- unconstraining_bijectors = [ tfb.Softplus(), tfb.Softplus(), tfb.Identity() ] if initial_state == None: beta = 1.2 * tf.ones(self.dim_input, tf.float32) varm = 0.8 loc = 0.0 initial_state = [beta, varm, loc] #----Setting up the mcmc sampler [beta_samples, varm_samples, loc_samples], kernel_results = sample_chain( num_results=mcmc_samples, num_burnin_steps=num_burnin_steps, current_state=initial_state, num_steps_between_results=thinning, kernel=TransformedTransitionKernel( inner_kernel=HamiltonianMonteCarlo( target_log_prob_fn=unnormalized_posterior_log_prob, step_size=step_size, num_leapfrog_steps=num_leapfrog_steps), bijector=unconstraining_bijectors)) acceptance_rate = tf.reduce_mean( tf.to_float(kernel_results.inner_results.is_accepted)) with tf.Session() as sess: [acceptance_rate_, loc_samples_, varm_samples_, beta_samples_] = sess.run( [acceptance_rate, loc_samples, varm_samples, beta_samples]) print('Acceptance rate of the HMC sampling:', acceptance_rate_) hyperpar_samples = [loc_samples_, varm_samples_, beta_samples_] return hyperpar_samples, acceptance_rate_
def testDtype(self): b = tfb.Softplus() self.assertIsNone(b.dtype) b = tfb.Softplus(low=1.75) self.assertEqual(tf.float32, b.dtype) b = tfb.Softplus(hinge_softness=tf.constant(0.5, dtype=tf.float64)) self.assertEqual(tf.float64, b.dtype)
def testScalarCongruency(self): chain = tfb.Chain((tfb.Exp(), tfb.Softplus())) bijector_test_util.assert_scalar_congruency(chain, lower_x=1e-3, upper_x=1.5, rtol=0.05, eval_func=self.evaluate)
def testMinEventNdimsChain(self): chain = tfb.Chain([tfb.Exp(), tfb.Exp(), tfb.Exp()]) self.assertEqual(0, chain.forward_min_event_ndims) self.assertEqual(0, chain.inverse_min_event_ndims) chain = tfb.Chain([ tfb.ScaleMatvecDiag(scale_diag=[1., 1.]), tfb.ScaleMatvecDiag(scale_diag=[1., 1.]), tfb.ScaleMatvecDiag(scale_diag=[1., 1.]) ]) self.assertEqual(1, chain.forward_min_event_ndims) self.assertEqual(1, chain.inverse_min_event_ndims) chain = tfb.Chain( [tfb.Exp(), tfb.ScaleMatvecDiag(scale_diag=[1., 1.])]) self.assertEqual(1, chain.forward_min_event_ndims) self.assertEqual(1, chain.inverse_min_event_ndims) chain = tfb.Chain( [tfb.ScaleMatvecDiag(scale_diag=[1., 1.]), tfb.Exp()]) self.assertEqual(1, chain.forward_min_event_ndims) self.assertEqual(1, chain.inverse_min_event_ndims) chain = tfb.Chain([ tfb.ScaleMatvecDiag(scale_diag=[1., 1.]), tfb.Exp(), tfb.Softplus(), tfb.ScaleMatvecDiag(scale_diag=[1., 1.]) ]) self.assertEqual(1, chain.forward_min_event_ndims) self.assertEqual(1, chain.inverse_min_event_ndims)
def testBijectiveAndFinite32bit(self): bijector = tfb.Softplus() x = np.linspace(-20., 20., 100).astype(np.float32) y = np.logspace(-10, 10, 100).astype(np.float32) bijector_test_util.assert_bijective_and_finite( bijector, x, y, eval_func=self.evaluate, event_ndims=0, rtol=1e-2, atol=1e-2)
def testCompositeTensor(self): exp = tfb.Exp() sp = tfb.Softplus() aff = tfb.Scale(scale=2.) bij = tfb.JointMap(bijectors=[exp, sp, aff]) self.assertIsInstance(bij, tf.__internal__.CompositeTensor) # Bijector may be flattened into `Tensor` components and rebuilt. flat = tf.nest.flatten(bij, expand_composites=True) unflat = tf.nest.pack_sequence_as(bij, flat, expand_composites=True) self.assertIsInstance(unflat, tfb.JointMap) # Bijector may be input to a `tf.function`-decorated callable. @tf.function def call_forward(bij, x): return bij.forward(x) x = [1., 2., 3.] self.assertAllClose(call_forward(unflat, x), bij.forward(x)) # Type spec can be encoded/decoded. struct_coder = tf.__internal__.saved_model.StructureCoder() enc = struct_coder.encode_structure(bij._type_spec) dec = struct_coder.decode_proto(enc) self.assertEqual(bij._type_spec, dec)
def testCompositeTensor(self): exp = tfb.Exp() sp = tfb.Softplus() aff = tfb.Scale(scale=2.) blockwise = tfb.Blockwise(bijectors=[exp, sp, aff]) self.assertIsInstance(blockwise, tf.__internal__.CompositeTensor) # Bijector may be flattened into `Tensor` components and rebuilt. flat = tf.nest.flatten(blockwise, expand_composites=True) unflat = tf.nest.pack_sequence_as(blockwise, flat, expand_composites=True) self.assertIsInstance(unflat, tfb.Blockwise) # Bijector may be input to a `tf.function`-decorated callable. @tf.function def call_forward(bij, x): return bij.forward(x) x = tf.ones([2, 3], dtype=tf.float32) self.assertAllClose(call_forward(unflat, x), blockwise.forward(x)) # Type spec can be encoded/decoded. enc = tf.__internal__.saved_model.encode_structure( blockwise._type_spec) dec = tf.__internal__.saved_model.decode_proto(enc) self.assertEqual(blockwise._type_spec, dec)
def testBijectiveAndFiniteWithNegativeHingeSoftness32Bit(self): bijector = tfb.Softplus(hinge_softness=-0.7) x = np.linspace(-20., 20., 100).astype(np.float32) y = -np.logspace(-10, 10, 100).astype(np.float32) bijector_test_util.assert_bijective_and_finite( bijector, x, y, eval_func=self.evaluate, event_ndims=0, rtol=1e-2, atol=1e-2)
def testScalarCongruencyWithHingeSoftnessAndLowerBound(self): bijector = tfb.Softplus(hinge_softness=1.3, low=1.6) bijector_test_util.assert_scalar_congruency(bijector, lower_x=-2., upper_x=2., eval_func=self.evaluate, rtol=.02)
def testScalarCongruency(self): bijector = tfb.Softplus() bijector_test_util.assert_scalar_congruency(bijector, lower_x=-2., upper_x=2., eval_func=self.evaluate, rtol=.02)
def testMinEventNdimsChain(self): self._validateChainMinEventNdims( bijectors=[tfb.Exp(), tfb.Exp(), tfb.Exp()], forward_min_event_ndims=0, inverse_min_event_ndims=0) self._validateChainMinEventNdims(bijectors=[ tfb.ScaleMatvecDiag(scale_diag=[1., 1.]), tfb.ScaleMatvecDiag(scale_diag=[1., 1.]), tfb.ScaleMatvecDiag(scale_diag=[1., 1.]) ], forward_min_event_ndims=1, inverse_min_event_ndims=1) self._validateChainMinEventNdims( bijectors=[tfb.Exp(), tfb.ScaleMatvecDiag(scale_diag=[1., 1.])], forward_min_event_ndims=1, inverse_min_event_ndims=1) self._validateChainMinEventNdims(bijectors=[ tfb.ScaleMatvecDiag(scale_diag=[1., 1.]), tfb.Exp(), tfb.Softplus(), tfb.ScaleMatvecDiag(scale_diag=[1., 1.]) ], forward_min_event_ndims=1, inverse_min_event_ndims=1)
def testScalarCongruencyWithNegativeHingeSoftness(self): bijector = tfb.Softplus(hinge_softness=-1.3) bijector_test_util.assert_scalar_congruency(bijector, lower_x=-2., upper_x=2., eval_func=self.evaluate, rtol=.02)
def testBijectorForwardInverseWithHingeSoftnessEventDimsZero(self): bijector = tfb.Softplus(hinge_softness=np.float64(1.5)) x = 2 * rng.randn(2, 10) y = 1.5 * self._softplus(x / 1.5) self.assertAllClose(y, self.evaluate(bijector.forward(x))) self.assertAllClose(x, self.evaluate(bijector.inverse(y)))
def testBijector(self): with self.cached_session(): for fwd in [ tfb.Identity(), tfb.Exp(), tfb.Affine(shift=[0., 1.], scale_diag=[2., 3.]), tfb.Softplus(), tfb.SoftmaxCentered(), ]: rev = tfb.Invert(fwd) self.assertEqual("_".join(["invert", fwd.name]), rev.name) x = [[[1., 2.], [2., 3.]]] self.assertAllClose(self.evaluate(fwd.inverse(x)), self.evaluate(rev.forward(x))) self.assertAllClose(self.evaluate(fwd.forward(x)), self.evaluate(rev.inverse(x))) self.assertAllClose( self.evaluate( fwd.forward_log_det_jacobian(x, event_ndims=1)), self.evaluate( rev.inverse_log_det_jacobian(x, event_ndims=1))) self.assertAllClose( self.evaluate( fwd.inverse_log_det_jacobian(x, event_ndims=1)), self.evaluate( rev.forward_log_det_jacobian(x, event_ndims=1)))
def testScalarCongruency(self): with self.test_session(): chain = tfb.Chain((tfb.Exp(), tfb.Softplus())) assert_scalar_congruency(chain, lower_x=1e-3, upper_x=1.5, rtol=0.05)
def testName(self): exp = tfb.Exp() sp = tfb.Softplus() aff = tfb.Affine(scale_diag=[2., 3., 4.]) blockwise = tfb.Blockwise(bijectors=[exp, sp, aff], block_sizes=[2, 1, 3]) self.assertStartsWith(blockwise.name, 'blockwise_of_exp_and_softplus_and_affine')
def testBijectorForwardInverseEventDimsZero(self): bijector = tfb.Softplus() self.assertEqual("softplus", bijector.name) x = 2 * rng.randn(2, 10) y = self._softplus(x) self.assertAllClose(y, self.evaluate(bijector.forward(x))) self.assertAllClose(x, self.evaluate(bijector.inverse(y)))
def testBijectorForwardInverseWithHingeSoftnessEventDimsZero(self): with self.test_session(): bijector = tfb.Softplus(hinge_softness=1.5) x = 2 * rng.randn(2, 10) y = 1.5 * self._softplus(x / 1.5) self.assertAllClose(y, bijector.forward(x).eval()) self.assertAllClose(x, bijector.inverse(y).eval())
def testBijectorForwardInverseEventDimsOne(self): bijector = tfb.Softplus() self.assertStartsWith(bijector.name, 'softplus') x = 2 * rng.randn(2, 10) y = self._softplus(x) self.assertAllClose(y, self.evaluate(bijector.forward(x))) self.assertAllClose(x, self.evaluate(bijector.inverse(y)))
def testBijectorForwardInverseEventDimsOne(self): with self.test_session(): bijector = tfb.Softplus() self.assertEqual("softplus", bijector.name) x = 2 * rng.randn(2, 10) y = self._softplus(x) self.assertAllClose(y, bijector.forward(x).eval()) self.assertAllClose(x, bijector.inverse(y).eval())
def testBijectorLogDetJacobianEventDimsOne(self): bijector = tfb.Softplus() y = 2 * rng.rand(2, 10) ildj_before = self._softplus_ildj_before_reduction(y) ildj = np.sum(ildj_before, axis=1) self.assertAllClose( ildj, self.evaluate(bijector.inverse_log_det_jacobian(y, event_ndims=1)))
def testBijectorLogDetJacobianEventDimsZero(self): bijector = tfb.Softplus() y = 2 * rng.rand(2, 10) # No reduction needed if event_dims = 0. ildj = self._softplus_ildj_before_reduction(y) self.assertAllClose( ildj, self.evaluate(bijector.inverse_log_det_jacobian(y, event_ndims=0)))
def testVariableHingeSoftness(self): hinge_softness = tf.Variable(1.) b = tfb.Softplus(hinge_softness=hinge_softness, validate_args=True) self.evaluate(hinge_softness.initializer) self.assertIs(hinge_softness, b.hinge_softness) self.assertEqual((), self.evaluate(b.forward(0.5)).shape) with self.assertRaisesOpError( 'Argument `hinge_softness` must be non-zero.'): with tf.control_dependencies([hinge_softness.assign(0.)]): self.evaluate(b.forward(0.5))
def testCopyExtraArgs(self): # Note: we cannot easily test all bijectors since each requires # different initialization arguments. We therefore spot test a few. sigmoid = tfb.Sigmoid(low=-1., high=2., validate_args=True) self.assertEqual(sigmoid.parameters, sigmoid.copy().parameters) chain = tfb.Chain( [ tfb.Softplus(hinge_softness=[1., 2.], validate_args=True), tfb.MatrixInverseTriL(validate_args=True) ], validate_args=True) self.assertEqual(chain.parameters, chain.copy().parameters)
def testBijectiveAndFinite16bit(self): bijector = tfb.Softplus() # softplus(-20) is zero, so we can't use such a large range as in 32bit. x = np.linspace(-10., 20., 100).astype(np.float16) # Note that float16 is only in the open set (0, inf) for a smaller # logspace range. The actual range was (-7, 4), so use something smaller # for the test. y = np.logspace(-6, 3, 100).astype(np.float16) bijector_test_util.assert_bijective_and_finite( bijector, x, y, eval_func=self.evaluate, event_ndims=0, rtol=1e-1, atol=1e-3)
def __init__(self, centered_returns, name='stochastic_volatility', pretty_name='Stochastic Volatility'): """Construct the stochastic volatility model. Args: centered_returns: Float `Tensor` of shape `[num_timesteps]` giving the mean-adjusted return (change in asset price, minus the average change) observed at each step. name: Python `str` name prefixed to Ops created by this class. pretty_name: A Python `str`. The pretty name of this model. """ with tf.name_scope(name): num_timesteps = ps.size0(centered_returns) if tf.is_tensor(num_timesteps): raise ValueError( 'Returns series length must be static, but saw ' 'shape {}.'.format(centered_returns.shape)) self._prior_dist = tfd.JointDistributionCoroutine( functools.partial(stochastic_volatility_prior_fn, num_timesteps=num_timesteps)) self._log_likelihood_fn = functools.partial( stochastic_volatility_log_likelihood_fn, centered_returns=centered_returns) def _ext_identity(params): res = collections.OrderedDict() res['persistence_of_volatility'] = params[0] res['mean_log_volatility'] = params[1] res['white_noise_shock_scale'] = params[2] res['log_volatility'] = tf.stack(params[3], axis=-1) return res sample_transformations = { 'identity': model.Model.SampleTransformation( fn=_ext_identity, pretty_name='Identity', ) } super(StochasticVolatility, self).__init__( default_event_space_bijector=(tfb.Sigmoid( -1., 1.), tfb.Identity(), tfb.Softplus()) + ((tfb.Identity(), ) * num_timesteps, ), event_shape=self._prior_dist.event_shape, dtype=self._prior_dist.dtype, name=name, pretty_name=pretty_name, sample_transformations=sample_transformations, )
def testBijectiveAndFiniteWithPositiveHingeSoftness32Bit(self): with self.test_session(): bijector = tfb.Softplus(hinge_softness=1.23) x = np.linspace(-20., 20., 100).astype(np.float32) y = np.logspace(-10, 10, 100).astype(np.float32) assert_bijective_and_finite(bijector, x, y, event_ndims=0, rtol=1e-2, atol=1e-2)
def testBijectiveAndFinite32bit(self): with self.test_session(): bijector = tfb.Softplus() x = np.linspace(-20., 20., 100).astype(np.float32) y = np.logspace(-10, 10, 100).astype(np.float32) assert_bijective_and_finite(bijector, x, y, event_ndims=0, rtol=1e-2, atol=1e-2)
def testBijector(self): chain = tfb.Chain((tfb.Exp(), tfb.Softplus())) self.assertEqual("chain_of_exp_of_softplus", chain.name) x = np.asarray([[[1., 2.], [2., 3.]]]) self.assertAllClose(1. + np.exp(x), self.evaluate(chain.forward(x))) self.assertAllClose(np.log(x - 1.), self.evaluate(chain.inverse(x))) self.assertAllClose( -np.sum(np.log(x - 1.), axis=2), self.evaluate(chain.inverse_log_det_jacobian(x, event_ndims=1))) self.assertAllClose( np.sum(x, axis=2), self.evaluate(chain.forward_log_det_jacobian(x, event_ndims=1)))
def testInvertible(self): # Generate random inputs from an unconstrained space, with # event size 6 to specify 3x3 triangular matrices. batch_shape = [2, 1] x = np.float32(self._rng.randn(*(batch_shape + [6]))) b = tfb.ScaleTriL(diag_bijector=tfb.Softplus(), diag_shift=3.14159) y = self.evaluate(b.forward(x)) self.assertAllEqual(y.shape, batch_shape + [3, 3]) x_ = self.evaluate(b.inverse(y)) self.assertAllClose(x, x_, rtol=1e-4) fldj = self.evaluate(b.forward_log_det_jacobian(x, event_ndims=1)) ildj = self.evaluate(b.inverse_log_det_jacobian(y, event_ndims=2)) self.assertAllClose(fldj, -ildj, rtol=1e-4)