Python-Implementierung der Kostenfunktion in der logistischen Regression: Warum Punktmultiplikation in einem Ausdruck, aber elementweise Multiplikation in einem anderen?

18

Ich habe eine sehr grundlegende Frage, die sich auf Python, Numpy und Multiplikation von Matrizen im Rahmen der logistischen Regression bezieht.

Lassen Sie mich zunächst entschuldigen, dass ich keine mathematische Notation verwende.

Ich bin verwirrt über die Verwendung der Matrixpunktmultiplikation gegenüber der elementweisen Multiplikation. Die Kostenfunktion ist gegeben durch:

Bildbeschreibung hier eingeben

Und in Python habe ich das geschrieben als

    cost = -1/m * np.sum(Y * np.log(A) + (1-Y) * (np.log(1-A)))

Aber zum Beispiel dieser Ausdruck (der erste - die Ableitung von J in Bezug auf w)

Bildbeschreibung hier eingeben

ist

   dw = 1/m * np.dot(X, dz.T)

Ich verstehe nicht, warum es richtig ist, die Punktmultiplikation oben zu verwenden, aber verwende die elementweise Multiplikation in der Kostenfunktion, dh warum nicht:

   cost = -1/m * np.sum(np.dot(Y,np.log(A)) + np.dot(1-Y, np.log(1-A)))

Ich verstehe voll und ganz, dass dies nicht ausführlich erklärt wird, aber ich vermute, dass die Frage so einfach ist, dass jeder, der selbst über grundlegende Erfahrungen mit logistischen Regressionen verfügt, mein Problem verstehen wird.

Geisterfahrer
quelle
2
Hinterfragen Sie die mathematischen Formeln oder die Übersetzung zwischen den mathematischen Formeln und dem Code? Das heißt, Sie möchten wissen, warum die Kostenfunktion als Summe und die Gradientenberechnung als Matrixmultiplikation ausgedrückt wird. Oder möchten Sie verstehen, warum wird, während wird ? yichLog(einich)Y * np.log(A)X(EIN-Y.)Tnp.dot(X, dz.T)
Neil Slater
2
Vielen Dank, Neil. Entschuldigen Sie die Unklarheit. Der Zweite. Ich verstehe die mathematischen Formeln. Ich kann mich einfach nicht mit der Intuition für die Punktmultiplikation in der einen und die elementweise Multiplikation in der anderen beschäftigen
GhostRider

Antworten:

12

In diesem Fall zeigen Ihnen die beiden mathematischen Formeln die richtige Art der Multiplikation:

  • yichLog(einich)yein

  • EINBC=EINBCichk=jEINichjBjknp.dot

Zum Teil ist Ihre Verwirrung auf die Vektorisierung der Gleichungen in den Kursmaterialien zurückzuführen, die sich auf komplexere Szenarien freuen. Sie könnten in der Tat verwenden cost = -1/m * np.sum( np.multiply(np.log(A), Y) + np.multiply(np.log(1-A), (1-Y)))oder cost = -1/m * np.sum( np.dot(np.log(A), Y.T) + np.dot(np.log(1-A), (1-Y.T)))während Yund AForm haben (m,1)und es sollte das gleiche Ergebnis geben. NB das reduziert np.sumgerade einen einzelnen Wert darin, also könntest du es fallen lassen und stattdessen [0,0]am Ende haben. Dies wird jedoch nicht auf andere Ausgabeformen verallgemeinert, (m,n_outputs)sodass der Kurs diese nicht verwendet.

Neil Slater
quelle
1
Neil - Ja, du hast recht. Andrew Ngs neuer DL-Kurs. Und auch Ihre Antwort macht durchaus Sinn. Danke für die Eingabe.
GhostRider
"Also interagiert jedes Element von y nur mit seinem passenden Element in a, was im Grunde die Definition von elementweise ist" - eine unglaublich klare Erklärung.
GhostRider
2

Fragen Sie sich, was ist der Unterschied zwischen einem Punktprodukt zweier Vektoren und der Summierung ihres elementweisen Produkts? Sie sind gleich. np.sum(X * Y)ist np.dot(X, Y). Die Punktversion wäre im Allgemeinen effizienter und einfacher zu verstehen.

Y.np.dot

Ich denke, die Antwort ist, dass es sich um unterschiedliche Operationen handelt, die unterschiedliche Aufgaben ausführen. Diese Situationen sind unterschiedlich, und der Hauptunterschied besteht im Umgang mit Vektoren gegenüber Matrizen.

Sean Owen
quelle
Vielen Dank. Das ist nicht ganz das, wonach ich frage. Siehe den alternativen Code, den ich für die Kostenfunktion habe (letztes Stück Code). Das ist falsch, aber ich versuche zu verstehen, warum es falsch ist.
GhostRider
2
In dem Fall, dass das OP np.sum(a * y)nicht dasselbe ist wie np.dot(a, y)weil aund ySpaltenvektoren geformt sind (m,1), wird die dotFunktion einen Fehler auslösen. Ich bin mir ziemlich sicher, dass dies alles von coursera.org/learn/neural-networks-deep-learning stammt (ein Kurs, den ich mir kürzlich angesehen habe), da die Notation und der Code genau übereinstimmen.
Neil Slater
0

In Bezug auf "In dem Fall des OP wird np.sum (a * y) nicht dasselbe sein wie np.dot (a, y), weil a und y die Form von Spaltenvektoren (m, 1) sind, also wird die Punktfunktion einen Fehler auslösen. "...

(Ich habe nicht genug Kudos, um mit dem Kommentarbutton zu kommentieren, aber ich dachte, ich würde hinzufügen.)

Wenn die Vektoren Spaltenvektoren sind und die Form (1, m) haben, besteht ein übliches Muster darin, dass der zweite Operator für die Punktfunktion mit einem ".T" -Operator nachfixiert wird, um ihn in die Form (m, 1) und dann in den Punkt zu transponieren Produkt arbeitet als (1, m). (m, 1). z.B

np.dot (np.log (1-A), (1-Y) .T)

Der gemeinsame Wert für m ermöglicht die Anwendung des Skalarprodukts (Matrixmultiplikation).

Ähnlich würde man für Spaltenvektoren die Transponierung auf die erste Zahl anwenden, z. B. np.dot (wT, X), um die Dimension, die> 1 ist, in die Mitte zu setzen.

Das Muster, um einen Skalar von np.dot zu erhalten, besteht darin, dass die beiden Vektorformen die Dimension '1' auf der 'Außenseite' und die gemeinsame Dimension> 1 auf der 'Innenseite' haben:

(1, X). (X, 1) oder np.dot (V1, V2) Wobei V1 Form (1, X) und V2 Form (X, 1) ist

Das Ergebnis ist also eine (1,1) -Matrix, dh ein Skalar.

Gordon Hutchison
quelle