[PYTHON] Theano Une astuce pour les amateurs pour faire de leur mieux avec PyMC3

Comme vous le savez, la bibliothèque Python MCMC (Markov Chain Monte Carlo) ** PyMC3 ** est basée sur la bibliothèque de traitement numérique ** Theano **. Grâce à cette combinaison, on dit qu'il a la flexibilité de gérer des problèmes compliqués et une puissance de calcul suffisante, mais Ikansen ** Theano ** est assez difficile pour un amateur. Le concept de définir d'abord la gestion des symboles, puis de lier et de calculer des valeurs numériques le rend difficile à comprendre. Ici, nous allons introduire une astuce pour déboguer sans toucher aux fonctions de ** Theano ** lorsqu'un problème survient dans le travail de simulation PyMC3.


Flux de travail de simulation PyMC3

Le flux de travail général de la simulation est le suivant.

  1. Préparez l'ensemble de données (lisez le fichier).
  2. Description du modèle de simulation. (La distribution a priori est ceci et ceci, la fonction de vraisemblance est ceci, etc.)
  3. Réglage de la valeur initiale. Calcul numérique par procédé MCMC.
  4. Examen des résultats des calculs. Graphisme, etc.

C'est la partie de la «description du modèle statistique» qui mérite attention. S'il s'agit d'un modèle simple, je pense qu'il est facile de créer un modèle en se référant au Tutoriel, mais si le modèle devient compliqué, il ne sera pas calculé ou le résultat calculé sera étrange.

Je souhaite afficher la valeur d'une variable pour le débogage

Il ne fait aucun doute que la sortie de la valeur intermédiaire de la variable est une grande aide pour le débogage, mais ce n'est pas facile dans l'environnement Theano & PyMC3.

Prenez le code suivant comme exemple. C'est une simulation de régression logistique.

import numpy as np
import pymc3 as pm

#1. 1. Préparation du jeu de données
n_betl = np.array([59, 60, 62, 56, 63, 59, 62, 60])
y_betl = np.array([6, 13, 18, 28, 52, 53, 61, 60])
x1 = np.array([1.6907, 1.7242, 1.7552, 1.7842,
    1.8113, 1.8369, 1.8610, 1.8839])

#2. Description du modèle statistique
mymodel1 = pm.Model()
def invlogit(x):
    return pm.exp(x) / (1 + pm.exp(x))

with mymodel1:  # model definition
    mytheta = pm.Normal('theta', mu=0, sd=32, shape=2)   # 2-dim array
    p = invlogit(mytheta[0] + mytheta[1] * x1)
    y_obs = pm.Binomial('y_obs', n=n_betl, p=p, observed=y_betl)

#3. 3. Calcul MCMC
with mymodel1:  # running simulation
    start = pm.find_MAP()
    step = pm.NUTS()
    trace1 = pm.sample(10000, step, start=start)
    
#4. Sortie des résultats de calcul...récapitulatif et tracé
pm.summary(trace1)
pm.traceplot(trace1)

Ce que je veux faire, c'est souvent afficher des valeurs de variable à chaque étape du calcul MCMC, mais où dois-je mettre cette déclaration? Je veux le mettre intuitivement dans la partie calcul MCMC, mais l'instruction de calcul est

    trace1 = pm.sample(10000, step, start=start)

Il est difficile à insérer car il se fait en une seule ligne. Ensuite, je me suis demandé si je pouvais faire quelque chose dans la "Description du modèle statistique" avant cela [document de Theano](http://deeplearning.net/software/theano/tutorial/debug_faq.html#how-do-i-print-an -intermediate-value-in-a-function) a été recherché et la ligne suivante a été ajoutée. (** "theano.printing.Print ()" **.)

import theano
(Omis)
with mymodel1:  # model definition
    mytheta = pm.Normal('theta', mu=0, sd=32, shape=2)   # 2-dim array

	#Je logit au milieu du calcul MCMC_Je veux sortir p. .. ..
    logit_p = mytheta[0] + mytheta[1] * x1
    my_printed = theano.printing.Print('logit_p = ')(logit_p)

    p = invlogit(mytheta[0] + mytheta[1] * x1)
    y_obs = pm.Binomial('y_obs', n=n_betl, p=p, observed=y_betl)

En conséquence, la valeur initiale de tout zéro était sortie.

logit_p =  __str__ = [ 0.  0.  0.  0.  0.  0.  0.  0.]

Par conséquent, cela n'a pas de sens pour le débogage. Après tout, il semble qu'il est inutile d'effectuer une "sortie" dans la description du modèle statistique.

Utiliser la trace PyMC (calcul MCMC)

Comme autre méthode, j'ai proposé une méthode de journalisation en ajoutant une variable arbitraire à la trace de PyMC. Les principales variables du modèle statistique sont enregistrées sous forme de données de trace à chaque étape. J'ai essayé d'ajouter la variable que je voulais voir à cela.

with mymodel1:  # model definition
    mytheta = pm.Normal('theta', mu=0, sd=32, shape=2)   # 2-dim array
    p = invlogit(mytheta[0] + mytheta[1] * x1)

    # for debug
	logit_p = pm.Deterministic('logit_p', (mytheta[0] + mytheta[1] * x1))
 
    y_obs = pm.Binomial('y_obs', n=n_betl, p=p, observed=y_betl)
   

Comme mentionné ci-dessus, la méthode de classe de ** pm.Deterministic () ** a été utilisée. À l'origine, pm.Deterministic est utilisé pour dériver des variables (déterminées de manière déterministe) à partir d'autres variables liées, mais en l'utilisant, il a le nom de ** 'ligit_p' ** passé comme argument. La variable est soumise à un enregistrement de trace. Par conséquent, après le calcul, trace peut y faire référence en tant qu'informations de débogage. Bien sûr, vous pouvez vous référer à d'autres variables qui composent mymodel1, ou vous pouvez entrer des formules supplémentaires et obtenir les résultats.

>>> mylog = trace1['logit_p']
>>> mylog[-5:]  ...Afficher uniquement les 5 dernières étapes
array([[-2.60380812, -1.54381452, -0.56292492,  0.35468148,  1.21216885,
         2.02219381,  2.78475637,  3.50934901],
       [-2.44719254, -1.38360671, -0.39939295,  0.52132315,  1.38171646,
         2.19448653,  2.95963336,  3.68668158],
       [-2.73650878, -1.64559829, -0.63609903,  0.30827125,  1.19076899,
         2.02441999,  2.80922426,  3.55495113],
       [-2.71951223, -1.62859273, -0.61908514,  0.32529294,  1.20779796,
         2.04145585,  2.82626659,  3.57199962],
       [-2.51597252, -1.42300483, -0.41160189,  0.53454925,  1.41871117,
         2.25393425,  3.04021847,  3.78735161]])

De plus, puisqu'il s'agit d'une trace, vous pouvez la tracer avec traceplot ().

additional_traceplot.png

En plus du paramètre de régression theta que nous voulions obtenir en Simulation, logit_p est également affiché. (Il était surprenant que logit_p soit un vecteur de taille = 8 ...)

Puis-je le faire avec PyMC3?

Nous avons pu obtenir plus d'informations de débogage en augmentant les variables à générer pour la trace. Dans le travail de modélisation MCMC, chaque bibliothèque ne donne pas un message d'erreur très utile, donc elle est assez "fatiguée" (et "devient folle"). La situation s'est un peu améliorée avec cette méthode et je sens que je peux faire de mon mieux.

Cette fois, au final, c'était une méthode à gérer sans «descendre» vers Theano, mais on dit que Theano est un outil efficace pour l'apprentissage automatique, non limité à PyMC3, donc c'est aussi difficile. Je veux enquêter petit à petit sans renoncer. En outre, je voudrais augmenter les astuces pour les méthodes générales de débogage Python.

Références (site Web)

Recommended Posts

Theano Une astuce pour les amateurs pour faire de leur mieux avec PyMC3
Expérimentez pour créer un PDF indépendant pour Kindle avec Python
Machine d'inspection par imagerie pour ceux qui ne font pas de leur mieux
Comment lancer avec Theano
Comment créer une étiquette (masque) pour la segmentation avec labelme (masque de segmentation sémantique)
Je souhaite rechercher le texte intégral avec elasticsearch + python
Que faire si vous obtenez une erreur de décodage Unicode avec l'installation de pip
J'ai essayé de faire une étrange citation pour Jojo avec LSTM
Que faire avec l'installation de Magics
Pour faire une récursion avec Python2
Que faire avec la sortie de PYTHON?
Je veux faire ○○ avec les Pandas
[Introduction à Udemy Python3 + Application] 47. Traitez le dictionnaire avec une instruction for
Que faire lorsque TypeError se produit au minimum et au maximum de numpy
Un guide pour faire de l'IoT avec MicroPython facilement jusqu'à la dernière minute