Implémentation Python de la fonction de coût dans la régression logistique: pourquoi la multiplication par points dans une expression mais la multiplication par élément dans une autre

18

J'ai une question très basique qui concerne Python, numpy et la multiplication des matrices dans le cadre de la régression logistique.

Tout d'abord, permettez-moi de m'excuser de ne pas utiliser la notation mathématique.

Je suis confus quant à l'utilisation de la multiplication matricielle par rapport à la multiplication par éléments. La fonction de coût est donnée par:

entrez la description de l'image ici

Et en python, j'ai écrit ceci comme

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

Mais par exemple cette expression (la première - la dérivée de J par rapport à w)

entrez la description de l'image ici

est

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

Je ne comprends pas pourquoi il est correct d'utiliser la multiplication par points dans ce qui précède, mais utilisez la multiplication par élément dans la fonction de coût, c'est-à-dire pourquoi pas:

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

Je comprends parfaitement que ce n'est pas expliqué de manière détaillée, mais je suppose que la question est si simple que toute personne ayant une expérience de régression logistique, même de base, comprendra mon problème.

Cavalier fantôme
la source
2
Remettez-vous en question les formules mathématiques ou la traduction entre les formules mathématiques et le code? C'est-à-dire que vous voulez savoir pourquoi la fonction de coût est exprimée comme une somme et le calcul du gradient est exprimé comme une multiplication matricielle; ou voulez-vous comprendre pourquoi le devient alors que devient ? yjeJournal(uneje)Y * np.log(A)X(UNE-Oui)Tnp.dot(X, dz.T)
Neil Slater
2
Merci Neil. Désolé pour l'ambiguïté. La deuxième. Je comprends les formules mathématiques. Je n'arrive pas à comprendre l'intuition pour la multiplication de points dans l'un et la multiplication par élément dans l'autre
GhostRider

Réponses:

12

Dans ce cas, les deux formules mathématiques vous indiquent le type de multiplication correct:

  • yje et dans la fonction de coût sont des valeurs scalaires. La composition des valeurs scalaires en une somme donnée sur chaque exemple ne change rien à cela, et vous ne combinez jamais les valeurs d'un exemple avec un autre dans cette somme. Ainsi, chaque élément de interagit uniquement avec son élément correspondant dans , qui est fondamentalement la définition de l'élément par élément.Journal(uneje)yune

  • Les termes dans le calcul du gradient sont des matrices, et si vous voyez deux matrices et multipliées en utilisant une notation comme , alors vous pouvez l'écrire comme une somme plus complexe: . C'est cette somme intérieure à travers plusieurs termes qui est performante.UNEBC=UNEBCjek=jUNEjejBjknp.dot

Votre confusion vient en partie de la vectorisation qui a été appliquée aux équations dans les supports de cours, qui attendent avec impatience des scénarios plus complexes. Vous pouvez utiliser dans des faits cost = -1/m * np.sum( np.multiply(np.log(A), Y) + np.multiply(np.log(1-A), (1-Y)))ou cost = -1/m * np.sum( np.dot(np.log(A), Y.T) + np.dot(np.log(1-A), (1-Y.T)))tout Yet Aont une forme (m,1)et il devrait donner le même résultat. NB: l' np.sumaplatissement d'une seule valeur en ce sens, vous pouvez donc la supprimer et la placer [0,0]à la fin. Cependant, cela ne se généralise pas aux autres formes de sortie, (m,n_outputs)donc le cours ne l'utilise pas.

Neil Slater
la source
1
Neil - Oui, tu as raison. Andrew Ngs nouveau cours DL. Et votre réponse est également parfaitement logique. Merci pour la contribution.
GhostRider
"Donc, chaque élément de y interagit uniquement avec son élément correspondant dans a, qui est fondamentalement la définition de l'élément par élément" - explication incroyablement lucide.
GhostRider
2

Demandez-vous quelle est la différence entre un produit scalaire de deux vecteurs et la somme de leur produit élémentaire? Ce sont les mêmes. np.sum(X * Y)est np.dot(X, Y). La version dot serait généralement plus efficace et plus facile à comprendre.

Ouinp.dot

Donc je suppose que la réponse est que ce sont des opérations différentes qui font des choses différentes, et ces situations sont différentes, et la principale différence concerne les vecteurs et les matrices.

Sean Owen
la source
Merci. Ce n'est pas tout à fait ce que je demande. Voir le code alternatif que j'ai pour la fonction de coût (dernier bit de code). C'est incorrect, mais j'essaie de comprendre pourquoi c'est incorrect.
GhostRider
2
Dans le cas de l'OP np.sum(a * y)ne va pas être le même que np.dot(a, y)parce que aet ysont des vecteurs de colonnes (m,1), donc la dotfonction soulèvera une erreur. Je suis presque sûr que tout cela vient de coursera.org/learn/neural-networks-deep-learning (un cours que je viens de regarder récemment), car la notation et le code sont une correspondance exacte.
Neil Slater
0

En ce qui concerne "Dans le cas de l'OP, np.sum (a * y) ne sera pas identique à np.dot (a, y) car a et y sont des vecteurs de colonnes de forme (m, 1), donc la fonction point sera déclencher une erreur. "...

(Je n'ai pas assez de compliments pour commenter en utilisant le bouton de commentaire mais j'ai pensé que j'ajouterais ..)

Si les vecteurs sont des vecteurs de colonne et ont une forme (1, m), un modèle courant est que le deuxième opérateur pour la fonction point est postfixé avec un opérateur ".T" pour le transposer en forme (m, 1) puis le point produit fonctionne comme un (1, m). (m, 1). par exemple

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

La valeur commune de m permet d'appliquer le produit scalaire (multiplication matricielle).

De même pour les vecteurs colonne, on verrait la transposition appliquée au premier nombre, par exemple np.dot (wT, X) pour mettre la dimension> 1 au «milieu».

Le modèle pour obtenir un scalaire de np.dot est d'obtenir que les deux formes de vecteurs aient la dimension «1» à «l'extérieur» et la dimension commune> 1 à «l'intérieur»:

(1, X). (X, 1) ou np.dot (V1, V2) Où V1 est la forme (1, X) et V2 est la forme (X, 1)

SO le résultat est une matrice (1,1), c'est-à-dire un scalaire.

Gordon Hutchison
la source