Exemple #1
0
    def _m_step_nu(self, expectations, datas, inputs, masks, tags, optimizer,
                   num_iters, **kwargs):
        K, D = self.K, self.D
        E_taus = np.zeros(K)
        E_logtaus = np.zeros(K)
        weights = np.zeros(K)
        for (
                Ez,
                _,
                _,
        ), data, input, mask, tag in zip(expectations, datas, inputs, masks,
                                         tags):
            # nu: (K,)  mus: (K, D)  sigmas: (K, D)  y: (T, D)  -> w: (T, K, D)
            mus = self._compute_mus(data, input, mask, tag)
            sigmas = self._compute_sigmas(data, input, mask, tag)
            nus = np.exp(self.inv_nus[:, None])

            alpha = nus / 2 + 1 / 2
            beta = nus / 2 + 1 / 2 * (data[:, None, :] - mus)**2 / sigmas

            E_taus += np.sum(Ez[:, :, None] * alpha / beta, axis=(0, 2))
            E_logtaus += np.sum(Ez[:, :, None] *
                                (digamma(alpha) - np.log(beta)),
                                axis=(0, 2))
            weights += np.sum(Ez, axis=0) * D

        E_taus /= weights
        E_logtaus /= weights

        for k in range(K):
            self.inv_nus[k] = np.log(
                generalized_newton_studentst_dof(E_taus[k], E_logtaus[k]))
Exemple #2
0
    def _m_step_nu(self, expectations, datas, inputs, masks, tags):
        """
        The shape parameter nu determines a gamma prior.  We have
        
            tau_n ~ Gamma(nu/2, nu/2)
            y_n ~ N(mu, sigma^2 / tau_n)

        To update nu, we do EM and optimize the expected log likelihood using
        a generalized Newton's method.  See the notebook in doc/students_t for
        complete details.
        """
        K, D = self.K, self.D

        # Compute the precisions w for each data point
        E_taus = np.zeros(K)
        E_logtaus = np.zeros(K)
        weights = np.zeros(K)
        for y, (Ez, _, _) in zip(datas, expectations):
            # nu: (K,)  mus: (K, D)  sigmas: (K, D)  y: (T, D)  -> alpha/beta: (T, K, D)
            nus = np.exp(self.inv_nus[:, None])
            alpha = nus/2 + 1/2
            beta = nus/2 + 1/2 * (y[:, None, :] - self.mus)**2 / np.exp(self.inv_sigmas)
            
            E_taus += np.sum(Ez[:, :, None] * alpha / beta, axis=(0, 2))
            E_logtaus += np.sum(Ez[:, :, None] * (digamma(alpha) - np.log(beta)), axis=(0, 2))
            weights += np.sum(Ez, axis=0) * D

        E_taus /= weights
        E_logtaus /= weights

        for k in range(K):
            self.inv_nus[k] = np.log(generalized_newton_studentst_dof(E_taus[k], E_logtaus[k]))