Wie Sie wissen, basiert die Python MCMC-Bibliothek (Markov Chain Monte Carlo) ** PyMC3 ** auf der numerischen Verarbeitungsbibliothek ** Theano **. Dank dieser Kombination soll es die Flexibilität haben, komplizierte Probleme und ausreichende Rechenleistung zu bewältigen, aber Ikansen ** Theano ** ist für einen Amateur ziemlich schwierig. Das Konzept, zuerst den Umgang mit Symbolen zu definieren und dann numerische Werte zu binden und zu berechnen, macht es schwierig zu verstehen. Hier werden wir einen Trick zum Debuggen vorstellen, ohne die Funktionen von ** Theano ** zu berühren, wenn ein Problem in der PyMC3-Simulationsarbeit auftritt.
Der allgemeine Arbeitsablauf der Simulation ist wie folgt.
Es ist der Teil der "Beschreibung des statistischen Modells", der Aufmerksamkeit erfordert. Wenn es sich um ein einfaches Modell handelt, ist es meiner Meinung nach einfach, ein Modell unter Bezugnahme auf das Lernprogramm zu erstellen. Wenn das Modell jedoch kompliziert wird, wird es nicht berechnet oder das berechnete Ergebnis ist seltsam.
Es besteht kein Zweifel, dass die Ausgabe des Zwischenwerts der Variablen eine große Hilfe beim Debuggen ist, aber dies ist in der Theano & PyMC3-Umgebung nicht einfach.
Nehmen Sie den folgenden Code als Beispiel. Es ist eine Simulation der logistischen Regression.
import numpy as np
import pymc3 as pm
#1. 1. Datensatz vorbereiten
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. Beschreibung des statistischen Modells
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. MCMC-Berechnung
with mymodel1: # running simulation
start = pm.find_MAP()
step = pm.NUTS()
trace1 = pm.sample(10000, step, start=start)
#4. Ausgabe des Berechnungsergebnisses...Zusammenfassung und Trace-Plot
pm.summary(trace1)
pm.traceplot(trace1)
Ich möchte häufig bei jedem Schritt der MCMC-Berechnung Variablenwerte ausgeben. Aber wo soll ich diese Anweisung ablegen? Ich möchte es intuitiv in den MCMC-Berechnungsteil einfügen, aber die Berechnungsanweisung lautet
trace1 = pm.sample(10000, step, start=start)
Das Einfügen ist schwierig, da es in einer Zeile erfolgt. Dann fragte ich mich, ob ich in der "Beschreibung des statistischen Modells" vor diesem Theanos Dokument etwas tun könnte -intermediate-value-in-a-function) wurde gesucht und die folgende Zeile hinzugefügt. (Es wird anstelle von ** "theano.printing.Print ()" **.)
import theano
(Weggelassen)
with mymodel1: # model definition
mytheta = pm.Normal('theta', mu=0, sd=32, shape=2) # 2-dim array
#Ich logge mich mitten in der MCMC-Berechnung ein_Ich möchte p ausgeben. .. ..
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)
Infolgedessen wurde der Anfangswert aller Null ausgegeben.
logit_p = __str__ = [ 0. 0. 0. 0. 0. 0. 0. 0.]
Daher ist es für das Debuggen nicht sinnvoll. Schließlich scheint es sinnlos zu sein, in der statistischen Modellbeschreibung eine "Ausgabe" durchzuführen.
Als weitere Methode habe ich eine Protokollierungsmethode entwickelt, bei der der Ablaufverfolgung von PyMC eine beliebige Variable hinzugefügt wurde. Die Hauptvariablen des statistischen Modells werden bei jedem Schritt als Trace-Daten aufgezeichnet. Ich habe versucht, die Variable hinzuzufügen, die ich sehen wollte.
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)
Wie oben erwähnt, wurde die Klassenmethode ** pm.Deterministic () ** verwendet. Ursprünglich wird pm.Deterministic verwendet, um (deterministisch bestimmte) Variablen von anderen verwandten Variablen abzuleiten. Dabei wird jedoch der Name ** 'ligit_p' ** als Argument übergeben. Die Variable wird einer Trace-Aufzeichnung unterzogen. Daher kann Trace nach der Berechnung dies als Debug-Information bezeichnen. Natürlich können Sie auf andere Variablen verweisen, aus denen mymodel1 besteht, oder Sie können zusätzliche Formeln eingeben und die Ergebnisse abrufen.
>>> mylog = trace1['logit_p']
>>> mylog[-5:] ...Nur die letzten 5 Schritte anzeigen
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]])
Da es sich um eine Ablaufverfolgung handelt, können Sie sie auch mit traceplot () zeichnen.
Zusätzlich zu dem Regressionsparameter Theta, den wir in Simulation erhalten wollten, wird auch logit_p ausgegeben. (Es war überraschend, dass logit_p ein Vektor der Größe = 8 war ...)
Wir konnten mehr Debug-Informationen erhalten, indem wir die zu verfolgenden Variablen für die Ablaufverfolgung erhöhten. In der MCMC-Modellierungsarbeit gibt jede Bibliothek keine sehr hilfreiche Fehlermeldung aus, daher ist sie ziemlich "müde" (und "wird verrückt"). Die Situation hat sich mit dieser Methode ein wenig verbessert, und ich habe das Gefühl, mein Bestes geben zu können.
Diesmal war es letztendlich eine Methode, mit der man umgehen musste, ohne zu Theano "runterzukommen", aber es wird gesagt, dass Theano ein effektives Werkzeug für maschinelles Lernen ist, nicht nur PyMC3, daher ist dies auch schwierig. Ich möchte nach und nach nachforschen, ohne aufzugeben. Außerdem möchte ich die Tipps für allgemeine Python-Debugging-Methoden erweitern.
Recommended Posts