def testBatchShape(self):
        # Check that the model builds with batches of parameters.
        order = 3
        batch_shape = [4, 2]

        # No `_build_placeholder`, because coefficients must have static shape.
        coefficients = np.random.randn(*(batch_shape + [order])).astype(
            self.dtype)

        level_scale = self._build_placeholder(
            np.exp(np.random.randn(*batch_shape)))

        ssm = AutoregressiveStateSpaceModel(
            num_timesteps=10,
            coefficients=coefficients,
            level_scale=level_scale,
            initial_state_prior=tfd.MultivariateNormalDiag(
                scale_diag=self._build_placeholder(np.ones([order]))))
        if self.use_static_shape:
            self.assertAllEqual(ssm.batch_shape.as_list(), batch_shape)
        else:
            self.assertAllEqual(self.evaluate(ssm.batch_shape_tensor()),
                                batch_shape)

        y = ssm.sample()
        if self.use_static_shape:
            self.assertAllEqual(y.shape.as_list()[:-2], batch_shape)
        else:
            self.assertAllEqual(self.evaluate(tf.shape(y))[:-2], batch_shape)
    def testLogprobCorrectness(self):
        # Compare the state-space model's log-prob to an explicit implementation.
        num_timesteps = 10
        observed_time_series_ = np.random.randn(num_timesteps)
        coefficients_ = np.array([.7, -.1]).astype(self.dtype)
        level_scale_ = 1.0

        observed_time_series = self._build_placeholder(observed_time_series_)
        level_scale = self._build_placeholder(level_scale_)

        expected_logp = ar_explicit_logp(observed_time_series_, coefficients_,
                                         level_scale_)

        ssm = AutoregressiveStateSpaceModel(
            num_timesteps=num_timesteps,
            coefficients=coefficients_,
            level_scale=level_scale,
            initial_state_prior=tfd.MultivariateNormalDiag(
                scale_diag=[level_scale, 0.]))

        lp = ssm.log_prob(observed_time_series[..., tf.newaxis])
        self.assertAllClose(self.evaluate(lp), expected_logp)
Exemple #3
0
    def testEqualsAutoregressive(self):

        # An ARMA(p, 0) process is just an AR(p) processes
        num_timesteps = 10
        observed_time_series = self._build_placeholder(
            np.random.randn(num_timesteps, 1))

        level_scale = self._build_placeholder(0.1)

        # We'll test an AR1 process, and also (just for kicks) that the trivial
        # embedding as an AR2 process gives the same model.
        coefficients_order1 = np.array([1.]).astype(self.dtype)
        coefficients_order2 = np.array([1., 1.]).astype(self.dtype)

        ar1_ssm = AutoregressiveStateSpaceModel(
            num_timesteps=num_timesteps,
            coefficients=coefficients_order1,
            level_scale=level_scale,
            initial_state_prior=tfd.MultivariateNormalDiag(
                scale_diag=[level_scale]))
        ar2_ssm = AutoregressiveStateSpaceModel(
            num_timesteps=num_timesteps,
            coefficients=coefficients_order2,
            level_scale=level_scale,
            initial_state_prior=tfd.MultivariateNormalDiag(
                scale_diag=[level_scale, 1.]))
        arma1_ssm = AutoregressiveMovingAverageStateSpaceModel(
            num_timesteps=num_timesteps,
            ar_coefficients=coefficients_order1,
            ma_coefficients=np.array([0.]).astype(self.dtype),
            level_scale=level_scale,
            initial_state_prior=tfd.MultivariateNormalDiag(
                scale_diag=[level_scale, 1.]))
        arma2_ssm = AutoregressiveMovingAverageStateSpaceModel(
            num_timesteps=num_timesteps,
            ar_coefficients=coefficients_order2,
            ma_coefficients=np.array([0.]).astype(self.dtype),
            level_scale=level_scale,
            initial_state_prior=tfd.MultivariateNormalDiag(
                scale_diag=[level_scale, 1.]))

        ar1_lp, arma1_lp, ar2_lp, arma2_lp = (
            ar1_ssm.log_prob(observed_time_series),
            arma1_ssm.log_prob(observed_time_series),
            ar2_ssm.log_prob(observed_time_series),
            arma2_ssm.log_prob(observed_time_series))
        self.assertAllClose(ar1_lp, arma1_lp)
        self.assertAllClose(ar2_lp, arma2_lp)
    def testEqualsLocalLevel(self):
        # An AR1 process with coef 1 is just a random walk, equivalent to a local
        # level model. Test that both models define the same distribution
        # (log-prob).
        num_timesteps = 10
        observed_time_series = self._build_placeholder(
            np.random.randn(num_timesteps, 1))

        level_scale = self._build_placeholder(0.1)

        # We'll test an AR1 process, and also (just for kicks) that the trivial
        # embedding as an AR2 process gives the same model.
        coefficients_order1 = np.array([1.]).astype(self.dtype)
        coefficients_order2 = np.array([1., 0.]).astype(self.dtype)

        ar1_ssm = AutoregressiveStateSpaceModel(
            num_timesteps=num_timesteps,
            coefficients=coefficients_order1,
            level_scale=level_scale,
            initial_state_prior=tfd.MultivariateNormalDiag(
                scale_diag=[level_scale]))
        ar2_ssm = AutoregressiveStateSpaceModel(
            num_timesteps=num_timesteps,
            coefficients=coefficients_order2,
            level_scale=level_scale,
            initial_state_prior=tfd.MultivariateNormalDiag(
                scale_diag=[level_scale, 1.]))

        local_level_ssm = LocalLevelStateSpaceModel(
            num_timesteps=num_timesteps,
            level_scale=level_scale,
            initial_state_prior=tfd.MultivariateNormalDiag(
                scale_diag=[level_scale]))

        ar1_lp, ar2_lp, ll_lp = self.evaluate(
            (ar1_ssm.log_prob(observed_time_series),
             ar2_ssm.log_prob(observed_time_series),
             local_level_ssm.log_prob(observed_time_series)))
        self.assertAllClose(ar1_lp, ll_lp)
        self.assertAllClose(ar2_lp, ll_lp)