Implementacja funkcji kosztu w regresji logistycznej w Pythonie: dlaczego mnożenie kropek w jednym wyrażeniu, a mnożenie elementarne w innym

18

Mam bardzo podstawowe pytanie, które dotyczy Pythona, liczby i mnożenia macierzy w ustawieniach regresji logistycznej.

Po pierwsze, przepraszam, że nie używam notacji matematycznej.

Jestem zdezorientowany co do zastosowania mnożenia kropek macierzy w porównaniu do mnożenia elementów. Funkcja kosztu jest dana przez:

wprowadź opis zdjęcia tutaj

A w pythonie napisałem to jako

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

Ale na przykład to wyrażenie (pierwsze - pochodna J w odniesieniu do w)

wprowadź opis zdjęcia tutaj

jest

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

Nie rozumiem, dlaczego poprawne jest użycie mnożenia kropek w powyższym przypadku, ale używam mnożenia elementu w funkcji kosztu, tj. Dlaczego nie:

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

W pełni rozumiem, że nie zostało to szczegółowo wyjaśnione, ale zgaduję, że pytanie jest tak proste, że każdy, kto ma nawet podstawową regresję logistyczną, zrozumie mój problem.

GhostRider
źródło
2
yjalog(zaja)Y * np.log(A)X(ZA-Y)T.np.dot(X, dz.T)
2
Dzięki Neil. Przepraszam za dwuznaczność. Drugi. Rozumiem wzory matematyczne. Po prostu nie mogę
oprzeć

Odpowiedzi:

12

W takim przypadku dwie formuły matematyczne pokazują poprawny typ mnożenia:

  • yjalog(zaja)yza

  • ZAbdo=ZAbdojak=jotZAjajotbjotknp.dot

Częściowo twoje zamieszanie wynika z wektoryzacji zastosowanej do równań w materiałach kursu, które czekają na bardziej złożone scenariusze. Można w rzeczywistości użycia cost = -1/m * np.sum( np.multiply(np.log(A), Y) + np.multiply(np.log(1-A), (1-Y)))lub cost = -1/m * np.sum( np.dot(np.log(A), Y.T) + np.dot(np.log(1-A), (1-Y.T)))jednocześnie Yi Amieć kształt (m,1)i powinna dać taki sam efekt. Uwaga: np.sumspłaszcza tylko jedną wartość, więc możesz ją upuścić i zamiast tego mieć [0,0]na końcu. Nie uogólnia to jednak na inne kształty wyjściowe, (m,n_outputs)więc kurs go nie używa.

Neil Slater
źródło
1
Neil - Tak, masz rację. Nowy kurs DL firmy Andrew Ngs. Twoja odpowiedź ma również sens. Dzięki za wkład.
GhostRider
„Zatem każdy element y oddziałuje tylko z dopasowanym elementem w a, który jest w zasadzie definicją elementu” - niezwykle jasne wyjaśnienie.
GhostRider
2

Pytasz, jaka jest różnica między iloczynem kropkowym dwóch wektorów a sumowaniem ich iloczynu elementarnego? Oni są tacy sami. np.sum(X * Y)jestnp.dot(X, Y) . Wersja kropkowa byłaby ogólnie bardziej wydajna i łatwa do zrozumienia.

Ynp.dotfaktycznie oblicza iloczyn macierzowy, a suma tych elementów nie jest taka sama jak suma elementów iloczynu parowego. (Mnożenie nie będzie nawet zdefiniowane dla tych samych przypadków.)

Sądzę więc, że odpowiedź jest taka, że ​​są to różne operacje, które wykonują różne rzeczy, a te sytuacje są różne, a główna różnica dotyczy radzenia sobie z wektorami w porównaniu z macierzami.

Sean Owen
źródło
Dzięki. Nie o to pytam. Zobacz alternatywny kod, który mam dla funkcji kosztu (ostatni bit kodu). To jest nieprawidłowe, ale staram się zrozumieć, dlaczego to jest nieprawidłowe.
GhostRider
2
W przypadku OP np.sum(a * y)nie będzie taki sam jak np.dot(a, y)ponieważ ai ymają kształt wektorów kolumnowych (m,1), więc dotfunkcja zgłosi błąd. Jestem prawie pewien, że wszystko to pochodzi z coursera.org/learn/neural-networks-deep-learning (kurs, na który niedawno spojrzałem), ponieważ notacja i kod są dokładnie takie same .
Neil Slater,
0

W odniesieniu do „W przypadku PO np. Suma (a * y) nie będzie taka sama jak np.dot (a, y), ponieważ a i y są kształtami wektorów kolumnowych (m, 1), więc funkcja kropki będzie zgłosić błąd. ”...

(Nie mam wystarczającego uznania, aby komentować za pomocą przycisku komentowania, ale pomyślałem, że dodam ...)

Jeśli wektory są wektorami kolumnowymi i mają kształt (1, m), powszechnym wzorem jest to, że drugi operator funkcji kropki jest postfikowany za pomocą operatora „.T” w celu transpozycji jej do kształtu (m, 1), a następnie kropki produkt działa jako (1, m). (m, 1). na przykład

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

Wspólna wartość m umożliwia zastosowanie iloczynu (mnożenie macierzy).

Podobnie w przypadku wektorów kolumnowych transpozycja byłaby zastosowana do pierwszej liczby, np. Np.dot (wT, X), aby umieścić wymiar> 1 w „środku”.

Wzorzec pobierania skalara z np.dot polega na tym, aby dwa kształty wektorów miały wymiar „1” na „zewnątrz” i wspólny> 1 wymiar na „wewnątrz”:

(1, X). (X, 1) lub np.dot (V1, V2) Gdzie V1 to kształt (1, X), a V2 to kształt (X, 1)

Tak więc wynikiem jest macierz (1,1), tj. Skalar.

Gordon Hutchison
źródło