ロジスティック回帰におけるコスト関数のPython実装:ある式ではドット乗算、別の式では要素ごとの乗算


18

ロジスティック回帰の設定におけるPython、numpyおよび行列の乗算に関連する非常に基本的な質問があります。

まず、数学表記を使用していないことをおaび申し上げます。

マトリックスドット乗算と要素ごとのプルティプリケーションの使用について混乱しています。コスト関数は次のように与えられます:

ここに画像の説明を入力してください

そして、Pythonで私はこれを次のように書いています

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

しかし、たとえばこの式(最初の式-wに関するJの微分)

ここに画像の説明を入力してください

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

上記でドット乗算を使用するのが正しい理由がわかりませんが、コスト関数では要素ごとの乗算を使用します。

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

これは詳しく説明されていませんが、質問は非常に単純なので、基本的なロジスティック回帰の経験がある人でも私の問題を理解できると思います。


2
あなたは数学の公式、または数学の公式とコード間の翻訳に疑問を持っていますか?すなわち、コスト関数が合計として表現され、勾配計算が行列乗算として表現される理由を知りたいですかまたは理由を理解したいですなりながらなり?yilog(ai)Y * np.log(A)X(AY)Tnp.dot(X, dz.T)
ニールスレーター

2
ありがとう、ニール。あいまいさでごめんなさい。二番目。私は数学の公式を理解しています。私はちょうど1ドットの乗算、および他の要素毎の乗算のための直感まわりで私の頭を取得することはできません
GhostRider

回答:


12

この場合、2つの数式は正しいタイプの乗算を示しています。

  • log a iy ayiコスト関数のおよびはスカラー値です。各例でスカラー値を特定の合計に構成しても、これは変わりません。また、この合計で1つの例の値を別の例の値と組み合わせることはありません。したがって、各要素は、内の対応する要素とのみ相互作用します。これは、基本的に要素ごとの定義です。log(ai)ya

  • 勾配計算の項は行列であり、2つの行列とがなどの表記を使用して乗算されている場合、これをより複雑な合計として書き出すことができます:。実行しているのは、複数の用語にわたるこの内部合計です。B C = A B C i k = j A i j B j kABC=ABCik=jAijBjknp.dot

一部の混乱は、より複雑なシナリオを楽しみにしているコース教材の方程式に適用されているベクトル化に起因しています。あなたは、実際の使用にできcost = -1/m * np.sum( np.multiply(np.log(A), Y) + np.multiply(np.log(1-A), (1-Y)))たりcost = -1/m * np.sum( np.dot(np.log(A), Y.T) + np.dot(np.log(1-A), (1-Y.T)))しながらYおよびA形状を有し(m,1)、それは同じ結果を与える必要があります。NB np.sumはその中で単一の値を平坦化するだけなので、それをドロップして代わりに持つことができます[0,0]。ただし、これは他の出力形状に一般化されない(m,n_outputs)ため、コースでは使用されません。


1
ニール-はい、あなたは正しいです。Andrew Ngsの新しいDLコース。また、あなたの答えは完全に理にかなっています。入力いただきありがとうございます。
GhostRider

「したがって、yの各要素は、a内の一致する要素とのみ相互作用します。これは基本的に要素ごとの定義です」-信じられないほど明快な説明。
GhostRider

2

2つのベクトルの内積と、それらの要素ごとの積の合計の違いは何ですか?それらは同じです。np.sum(X * Y)ですnp.dot(X, Y)。一般に、ドットバージョンはより効率的で理解しやすいでしょう。

ただし、コスト関数では、はベクトルではなく行列です。実際に行列積を計算し、それらの要素の合計は、ペアワイズ積の要素の合計と同じではありません。(同じケースに対して乗算は定義されません。)Ynp.dot

だから答えは、それらは異なることをしている異なる操作であり、これらの状況は異なり、主な違いはベクトルと行列を扱うことだと思います。


ありがとう。それは私が求めていることとはまったく異なります。コスト関数(コードの最後のビット)の代替コードを参照してください。これは間違っていますが、なぜ間違っているのか理解しようとしています。
GhostRider

2
OPの場合np.sum(a * y)と同じであることを行っていないnp.dot(a, y)ためay列ベクトル形状です(m,1)ので、dot関数はエラーが発生します。表記法とコードが完全に一致するため、これはすべてcoursera.org/learn/neural-networks-deep-learning(最近見たばかりのコース)からのものであると確信しています。
ニールスレーター

0

「OPの場合、aとyは列ベクトル形状(m、1)であるため、np.sum(a * y)はnp.dot(a、y)と同じにはなりません。したがって、ドット関数はエラーを発生させます。 "...

(コメントボタンを使用してコメントするのに十分な賞賛はありませんが、追加したいと思いました。

ベクトルが列ベクトルであり、形状(1、m)を持っている場合、一般的なパターンは、ドット関数の2番目の演算子に ".T"演算子を後置して、形状(m、1)とドットに転置することです。製品は(1、m)。(m、1)として機能します。例えば

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

mの共通値により、ドット積(行列乗算)を適用できます。

同様に、列ベクトルの場合、最初の数に適用される転置が表示されます(例:np.dot(wT、X))。1より大きい次元を「中間」に配置します。

np.dotからスカラーを取得するパターンは、2つのベクトルシェイプを取得して、「外側」に「1」次元、「内側」に共通の> 1次元を持つようにします。

(1、X)。(X、1)またはnp.dot(V1、V2)ここで、V1は形状(1、X)、V2は形状(X、1)です

SO結果は(1,1)行列、つまりスカラーです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.