Anpassen eines Gaußschen Mischungsmodells unter Verwendung eines stochastischen Gradientenabfalls

8

Ich arbeite an einem Online-Lernmodell für Kategorien, das einen stochastischen Gradientenabstieg verwendet, um ein Gaußsches Mischungsmodell anzupassen. Das Modell basiert auf dem Online-Lernmodell von Toscano & McMurray (2010).

Während der Gradientenabstieg ziemlich gut zu funktionieren scheint, um die Mittelwerte und Häufigkeiten / Mischungswahrscheinlichkeiten der Kategorien abzuschätzen, habe ich Probleme mit der Schätzung der Kovarianzen von Mischungskomponenten. Die partiellen Ableitungen, die ich für das Gradientenabstiegs-Update verwendet habe, stammen von Petersen & Pedersen (2008) (S. 44).

Beginnen mit

p(x)=kρkNx(μk,Σk)

Petersen & Pedersen geben die partielle Ableitung bezüglich der Kovarianzmatrix as anΣ

δlnp(x)δΣj=ρjNx(μj,Σj)kρkNx(μk,Σk)12[Σj1+Σj1(xμj)(xμj)TΣj1]

Der Gradientenabstiegsschritt für jedes , wie ich es in Python implementiert habe, ist (dies ist eine leichte Vereinfachung und das für alle Komponenten wird berechnet, bevor das Update durchgeführt wird): Δ ΣΣjΔΣ

j.sigma += learning_rate*(G(x)/M(x))*0.5*(-inv(j.sigma) + inv(j.sigma).dot((x-j.mu).dot((x-j.mu).transpose())).dot(inv(j.sigma)))

Wobei j ein Objekt ist, das die te Komponente der Mischung darstellt, und j.sigma und j.mu der Mittelwert und die Varianz dieser Komponente sind. G (x) / M (x) steht für einen Code, derρ j N x ( μ j , Σ j )jρjNx(μj,Σj)kρkNx(μk,Σk)

Ich frage mich also, ob mit meinem Code etwas nicht stimmt (höchstwahrscheinlich) oder ob dies nur ein wirklich schlechter Weg ist, um diese Art von Modell anzupassen, wenn Daten mit mehr als zwei Dimensionen verarbeitet werden (siehe Toscano & McMurray für Algorithmen für univariate und bivariate Daten, die definitiv funktionieren).

Referenzen: Toscano, JC & McMurray, B. (2010). Cue-Integration in Kategorien: Gewichtung akustischer Cues in der Sprache mithilfe unbeaufsichtigter Lern- und Verteilungsstatistiken. Cognitive Science, 34, 434 & ndash; 464.

Petersen & Pederson. Das Matrix-Kochbuch, Version: 14. November 2008

phased_chirp
quelle

Antworten:

3

Daß unter der Annahme mus[d]ist , ist , und zwar berechnet die posterior Wahrscheinlichkeits der Komponente in Anbetracht der Daten , der Gradient selbst scheint mir korrekt zu sein. Aber hier sind einige Dinge, die mir aufgefallen sind und die Ihnen helfen könnten, Ihr Problem zu finden:μjj.sigmaΣjG(x)/M(x)jx

p(jx)=ρjN.x(μj,Σj)kρkN.x(μk,Σk),
  • Ich würde erwarten, dass der Zugriff auf den Mittelwert, die Kovarianz und die Berechnung des Seitenzahns für alle entweder joder die dVariable umfasst, für die Sie den Gradienten in Ihrem Code berechnen möchten. Wenn Sie uns sagen, wofür jund wofür Sie dstehen, können wir Ihnen möglicherweise mehr sagen.
  • Wenn Sie G(x)/M(x)auf j.Sigmadie Berechnung des Seitenzahns zugreifen , berechnet Ihr Code möglicherweise nicht das, was Sie denken. Es ist möglicherweise besser, zuerst alle Gradienten aller Parameter zu berechnen und dann die Aktualisierung durchzuführen.
  • Der stochastische Gradientenabstieg ist normalerweise nicht die erste Wahl, um Mischungen von Gaußschen zu optimieren. Am häufigsten wird die Erwartungsmaximierung (EM) verwendet (siehe beispielsweise Bishop, 2007). Auch wenn Sie EM nicht verwenden, sollten Sie BFGS oder L-BFGS (implementiert in scipy.optimize) in Betracht ziehen, bevor Sie SGD verwenden. Und selbst wenn Sie sich an SGD halten, sollten Sie in Betracht ziehen, mehrere Datenpunkte ("Stapel") gleichzeitig zu verwenden, um den Gradienten zu schätzen oder zumindest einen Momentumterm einzuschließen . Wenn ich mir kurz Toscano und McMurrays Artikel anschaue, schätze ich, dass sie sich für SGD entschieden haben, weil sie daran interessiert waren, die Spracherfassung auf biologisch plausibelere Weise zu modellieren, anstatt die bestmögliche Anpassung zu erhalten und dies online zu tun (dh Daten) Punkt zu einem Zeitpunkt). Wenn Sie dies nicht benötigen, würde ich Ihnen raten, EM zu verwenden.

    (Ich habe gerade festgestellt, dass Sie speziell nach Online- Lernen gefragt haben. Daher besteht die einzig praktikable Option für Sie darin, den Momentum-Begriff hinzuzufügen, um die Dinge etwas zu beschleunigen.)

  • Die Art und Weise, wie Sie den Gradienten berechnen, ist ziemlich ineffizient, was das Lernen weiter verlangsamt. Möglicherweise haben Sie keine vernünftigen Ergebnisse erzielt, da es ewig dauert, bis der Algorithmus zu etwas Interessantem konvergiert. Hier ist eine etwas bessere Methode zur Berechnung des Gradienten:

    sigmaInv = inv(j.sigma)
    dSigma = G(x)/M(x) * 0.5 * (-sigmaInv + numpy.sum(sigmaInv.dot(x - mus[d]) * x))
    

    Es gibt noch Möglichkeiten, die Berechnung des Gradienten weiter zu verbessern. Zum Beispiel erhalten wir immer noch eine gültige Aufstiegsrichtung (obwohl keine steilste Aufstiegsrichtung), wenn wir den Gradienten mit einer positiven bestimmten Matrix (wie , was den Gradienten ein wenig vereinfachen würde). Es könnte auch besser funktionieren, wenn wir eine andere Parametrisierung der Kovarianz verwenden, z. B. Cholesky-Faktoren , und stattdessen die Gradienten dieser berechnen.Σj

Lucas
quelle
Danke für die Vorschläge @Lucas. Entschuldigung für den etwas unklaren Code. Es ist Teil einer größeren Funktion, die ich neu geschrieben habe, damit es für sich genommen etwas sinnvoller ist. SigmaInv wird nur einmal berechnet und alle Farbverläufe werden vor der Aktualisierung berechnet. Dies muss ein Online-Modell für meine Arbeit sein, daher kann ich EM nicht verwenden. Ich habe eine etwas andere Version ausprobiert, die die Cholesky-Faktorisierung von Sigma verwendet, aber sie hat sich etwas seltsam verhalten.
phased_chirp