在二进制交叉熵损失计算中,np.dot和np.multiply与np.sum之间的差异

时间:2018-01-11 07:21:47

标签: python numpy neural-network sum difference

我尝试过以下代码,但未找到 np.dot np.multiply与np.sum

之间的区别

这是 np.dot 代码

public boolean onNavigationItemSelected(@NonNull MenuItem item) 

          {

            View v=null;

            int id = item.getItemId();

            switch (id){

                case R.id.search:
                    fragment = new Search();

                    break;
                case R.id.todo:
                    fragment = new ServiceTable();
                    break;
                case R.id.info:
                    fragment = new Orderlist();
                    break;
                case R.id.close:

                    //have to implement double click here.

                    break;

            }

            final FragmentTransaction transaction = fragmentManager.beginTransaction();
            transaction.replace(R.id.main_container, fragment).commit();
            return true;
        }


    });

    if (savedInstanceState == null) {
        bottomNavigation.setSelectedItemId(R.id.search);
    }
}

它的输出是

logprobs = np.dot(Y, (np.log(A2)).T) + np.dot((1.0-Y),(np.log(1 - A2)).T)
print(logprobs.shape)
print(logprobs)
cost = (-1/m) * logprobs
print(cost.shape)
print(type(cost))
print(cost)

以下是 np.multiply与np.sum的代码

(1, 1)
[[-2.07917628]]
(1, 1)
<class 'numpy.ndarray'>
[[ 0.693058761039 ]]

它的输出是

logprobs = np.sum(np.multiply(np.log(A2), Y) + np.multiply((1 - Y), np.log(1 - A2)))
print(logprobs.shape)         
print(logprobs)
cost = - logprobs / m
print(cost.shape)
print(type(cost))
print(cost)

我无法理解类型和形状差异,而结果值在两种情况下都相同

即使在挤压前代码的情况下,成本值也会与以后相同但类型保持不变

()
-2.07917628312
()
<class 'numpy.float64'>
0.693058761039

输出

cost = np.squeeze(cost)
print(type(cost))
print(cost)

4 个答案:

答案 0 :(得分:37)

<div ng-repeat="book in books"> <input type="radio" ng-checked="book.selected" ng-click="function($event)"> </div> 是两个矩阵的dot product

np.dot

|A B| . |E F| = |A*E+B*G A*F+B*H| |C D| |G H| |C*E+D*G C*F+D*H| 执行element-wise multiplication两个矩阵。

np.multiply

|A B| ⊙ |E F| = |A*E B*F| |C D| |G H| |C*G D*H| 一起使用时,结果相同只是巧合。

np.sum

答案 1 :(得分:12)

你正在做的是计算binary cross-entropy loss,它衡量模型与真实输出(此处:A2)的预测(这里:Y)有多糟糕

以下是针对您的案例的可重现示例,它应该解释为什么您使用np.sum

在第二种情况下获得标量
In [88]: Y = np.array([[1, 0, 1, 1, 0, 1, 0, 0]])

In [89]: A2 = np.array([[0.8, 0.2, 0.95, 0.92, 0.01, 0.93, 0.1, 0.02]])

In [90]: logprobs = np.dot(Y, (np.log(A2)).T) + np.dot((1.0-Y),(np.log(1 - A2)).T)

# `np.dot` returns 2D array since its arguments are 2D arrays
In [91]: logprobs
Out[91]: array([[-0.78914626]])

In [92]: cost = (-1/m) * logprobs

In [93]: cost
Out[93]: array([[ 0.09864328]])

In [94]: logprobs = np.sum(np.multiply(np.log(A2), Y) + np.multiply((1 - Y), np.log(1 - A2)))

# np.sum returns scalar since it sums everything in the 2D array
In [95]: logprobs
Out[95]: -0.78914625761870361

请注意np.dot总和仅与内部维度匹配(1x8) and (8x1)。因此,8 s将在点积或矩阵乘法期间消失,产生的结果为(1x1),它只是标量,但返回为形状的{2}数组{{1} }}

另外,最重要的是请注意这里np.dot is exactly same as doing np.matmul,因为输入是2D数组(即矩阵)

(1,1)

将结果作为标量

返回

np.dotnp.matmul根据输入数组返回生成的数组形状。即使使用In [107]: logprobs = np.matmul(Y, (np.log(A2)).T) + np.matmul((1.0-Y),(np.log(1 - A2)).T) In [108]: logprobs Out[108]: array([[-0.78914626]]) In [109]: logprobs.shape Out[109]: (1, 1) 参数,如果输入是2D数组,也不可能返回标量。但是,如果结果数组的形状为out=(或者更通常是包含在nD数组中的标量值),我们可以对结果使用np.asscalar()将其转换为标量)

(1,1)
  

ndarray ,大小为1,标量

In [123]: np.asscalar(logprobs)
Out[123]: -0.7891462576187036

In [124]: type(np.asscalar(logprobs))
Out[124]: float

答案 2 :(得分:3)

如果YA2是(1,N)数组,那么np.dot(Y,A.T)将产生(1,1)结果。它正在进行(1,N)与(N,1)的矩阵乘法。 N's总和,留下(1,1)。

使用multiply,结果为(1,N)。对所有值求和,结果为标量。

如果YA2为(N,)形状(相同数量的元素,但是1d),则np.dot(Y,A2)(无.T)也会生成标量。来自np.dot文档:

  

对于二维数组,它相当于矩阵乘法,对于一维数组到向量的内积

     

返回a和b的点积。如果a和b都是标量或两个1-D数组,则返回标量;否则返回一个数组。

squeeze会缩小所有1个尺寸,但仍会返回一个数组。在numpy中,数组可以具有任意数量的维度(从0到32)。因此可以使用0d数组。比较np.array(3)np.array([3])np.array([[3]])的形状。

答案 3 :(得分:0)

In this example it just not a coincidence. Lets take an example we have two (1,3) and (1,3) matrices. 
// Lets code 

import numpy as np

x1=np.array([1, 2, 3]) // first array
x2=np.array([3, 4, 3]) // second array

//Then 

X_Res=np.sum(np.multiply(x1,x2)) 
// will result 20 as it will be calculated as - (1*3)+(2*4)+(3*3) , i.e element wise
// multiplication followed by sum.

Y_Res=np.dot(x1,x2.T) 

// in order to get (1,1) matrix) from a dot of (1,3) matrix and //(1,3) matrix we need to //transpose second one. 
//Hence|1 2 3| * |3|
//               |4| = |1*3+2*4+3*3| = |20|
//               |3|
// will result 20 as it will be (1*3)+(2*4)+(3*3) , i.e. dot product of two matrices

print X_Res //20

print Y_Res //20