逻辑回归中成本函数的 Python 实现:为什么在一个表达式中进行点乘,而在另一个表达式中进行元素乘法

数据挖掘 Python 逻辑回归 成本函数
2021-09-25 23:37:09

我有一个非常基本的问题,它与逻辑回归设置中的 Python、numpy 和矩阵乘法有关。

首先,让我为没有使用数学符号表示歉意。

我对矩阵点乘法与元素明智乘法的使用感到困惑。成本函数由下式给出:

J=1mi=1my(i)log(a(i))+(1y(i))log(1a(i))

在python中我把它写成

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

但是例如这个表达式(第一个 - J 关于 w 的导数)

Jw=1mX(AY)T

Jb=1mi=1m(a(i)y(i))

   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)))

我完全明白这没有详细解释,但我猜这个问题是如此简单,以至于任何具有基本逻辑回归经验的人都会理解我的问题。

3个回答

在这种情况下,两个数学公式向您展示了正确的乘法类型:

  • yi日志(一个一世)在成本函数中是标量值。将标量值组合成每个示例的给定总和不会改变这一点,并且您永远不会在此总和中将一个示例的值与另一个示例的值组合。所以每个元素是的 只与它的匹配元素交互 一个,这基本上是 element-wise 的定义。

  • 梯度计算中的项是矩阵,如果你看到两个矩阵 一个 使用符号相乘 C=一个,那么你可以把它写成一个更复杂的总和: C一世ķ=j一个一世jjķ. 正是这种跨多个术语的内部总和np.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)))

同时YA具有形状(m,1),它应该给出相同的结果。注意,这np.sum只是将单个值变平,因此您可以将其删除,而将其[0,0]放在最后。但是,这并不能推广到其他输出形状(m,n_outputs),因此本课程不使用它。

您是在问,两个向量的点积与将它们的元素积相加有什么区别?他们是一样的。np.sum(X * Y)np.dot(X, Y)通常,点版本会更有效且易于理解。

但在成本函数中, 是矩阵,不是向量。np.dot实际上计算一个矩阵乘积,并且这些元素的总和与成对积的元素总和不同。(甚至不会为相同的情况定义乘法。)

所以我想答案是它们是不同的操作做不同的事情,这些情况是不同的,主要区别在于处理向量与矩阵。

关于“在 OP 的情况下 np.sum(a * y) 不会与 np.dot(a, y) 相同,因为 a 和 y 是列向量形状 (m,1),所以 dot 函数将引发错误。“...

(我没有足够的荣誉来使用评论按钮发表评论,但我想我会添加..)

如果向量是列向量并且形状为 (1,m),常见的模式是点函数的第二个运算符后缀为“.T”运算符,以将其转置为形状 (m,1),然后是点乘积计算为 (1,m).(m,1)。例如

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

m 的共同值可以应用点积(矩阵乘法)。

类似地,对于列向量,我们会看到应用到第一个数字的转置,例如 np.dot(wT,X) 将大于 1 的维度放在“中间”。

从 np.dot 获取标量的模式是让两个向量形状在“外部”具有“1”维度,在“内部”具有常见的 >1 维度:

(1,X).(X,1) 或 np.dot( V1, V2 ) 其中 V1 是形状 (1,X) 而 V2 是形状 (X,1)

所以结果是一个(1,1)矩阵,即一个标量。