Nous allons implémenter la distribution mixte de Bernoulli de PRML 9.3.3. À titre d'exemple de l'algorithme EM, l'estimation la plus probable de la distribution gaussienne mixte, qui est la somme de plusieurs distributions gaussiennes, est courante, mais elle peut également être appliquée à l'estimation la plus probable de la distribution mixte de Bernoulli, qui est la somme des distributions de Bernoulli. La distribution gaussienne a deux paramètres, la moyenne et la variance, tandis que la distribution de Bernoulli n'a qu'un seul paramètre, ce qui est plutôt plus facile. Cette fois, nous utiliserons la distribution mixte de Bernoulli et l'appliquerons à MNIST comme PRML pour regrouper chaque nombre.
Le modèle utilisé cette fois est basé sur la distribution multidimensionnelle de Bernoulli. Ceci représente la distribution des vecteurs binaires en D.
{\rm Bern}({\bf x}|{\bf\mu}) = \prod_{i=1}^D \mu_i^{x_i}(1-\mu_i)^{(1-x_i)}
La distribution mixte de Bernoulli est obtenue en pondérant cela avec le coefficient de mélange K-dimensionnel $ {\ bf \ pi} $ et en ajoutant K pièces ensemble. Si les données d'entraînement sont $ {\ bf X} = \ {{\ bf x} \ _1, \ dots, {\ bf x} \ _N \} $
p({\bf X}|{\bf\mu},{\bf\pi}) = \prod_{n=1}^N\left\{\sum_{k=1}^K\pi_k{\rm Bern}({\bf x}_n|{\bf\mu}_k)\right\}
Sera. Maintenant, introduisez la variable latente $ {\ bf Z} = \ {{\ bf z} \ _1, \ dots, {\ bf z} \ _N \} $ pour chaque donnée. Le vecteur de variable latente binaire à K dimensions $ {\ bf z} $ n'a qu'une seule des K composantes étant 1, et toutes les autres composantes étant 0. Étant donné les données complètes $ {\ bf X, Z} $, la fonction de vraisemblance est:
p({\bf X, Z}|{\bf\mu,\pi}) = \prod_{n=1}^N\left\{\prod_{k=1}^K\pi_k^{z_{nk}}{\rm Bern}({\bf x}_n|{\bf\mu}_k)^{z_{nk}}\right\}
import
Si la distribution multidimensionnelle de Bernoulli est utilisée telle quelle, la probabilité est trop faible et elle n'est pas pratique pour l'ordinateur, alors utilisez logsumexp
pour utiliser la logarithmique.
import numpy as np
from scipy.misc import logsumexp
Si vous êtes une personne de type python2, veuillez remplacer @
par une fonction qui calcule le produit interne de numpy.
#Distribution mixte de Bernoulli
class BernoulliMixtureDistribution(object):
def __init__(self, n_components):
#Nombre de clusters
self.n_components = n_components
def fit(self, X, iter_max=100):
self.ndim = np.size(X, 1)
#Initialisation des paramètres
self.weights = np.ones(self.n_components) / self.n_components
self.means = np.random.uniform(0.25, 0.75, size=(self.n_components, self.ndim))
self.means /= np.sum(self.means, axis=-1, keepdims=True)
#Répétez l'étape EM
for i in range(iter_max):
params = np.hstack((self.weights.ravel(), self.means.ravel()))
#Étape E
stats = self._expectation(X)
#Étape M
self._maximization(X, stats)
if np.allclose(params, np.hstack((self.weights.ravel(), self.means.ravel()))):
break
self.n_iter = i + 1
#Formule PRML(9.52)Logistique de
def _log_bernoulli(self, X):
np.clip(self.means, 1e-10, 1 - 1e-10, out=self.means)
return np.sum(X[:, None, :] * np.log(self.means) + (1 - X[:, None, :]) * np.log(1 - self.means), axis=-1)
def _expectation(self, X):
#Formule PRML(9.56)
log_resps = np.log(self.weights) + self._log_bernoulli(X)
log_resps -= logsumexp(log_resps, axis=-1)[:, None]
resps = np.exp(log_resps)
return resps
def _maximization(self, X, resps):
#Formule PRML(9.57)
Nk = np.sum(resps, axis=0)
#Formule PRML(9.60)
self.weights = Nk / len(X)
#Formule PRML(9.58)
self.means = (X.T @ resps / Nk).T
Comme ceci jupyter notebook 9.3.3 En appliquant la distribution mixte de Bernoulli à l'ensemble de données MNIST (200 images choisies au hasard de 0 à 4 chacune), la moyenne des distributions individuelles de Bernoulli est comme indiqué dans la figure ci-dessous.
Puisque l'apprentissage de l'algorithme EM s'inscrit dans la solution locale (bien que ce ne soit peut-être pas la solution locale en réalité), ce n'est pas seulement que chaque nombre est clairement reflété comme indiqué ci-dessus. J'ai senti qu'il était difficile d'apprendre s'il y avait des paires avec des formes similaires telles que 1 et 7 et 3 et 8.
Recommended Posts