文章说明:本文主要内容来自吴恩达老师的神经网络课程的课后练习,结合何宽的博客,希望能为大家更加通俗清晰地理解和解决一些在使用Python实现神经网络中可能遇到的一些问题。


文章目录

  • 常见的科学计算库中的易错点和技巧
  • 矩阵相加
  • 矩阵乘法
  • 广播机制的缺点


常见的科学计算库中的易错点和技巧

矩阵相加

看一下下面的这两个随机数组“a”和“b”:

a = np.random.randn(2, 3) # a.shape = (2, 3)
b = np.random.randn(2, 1) # b.shape = (2, 1)
c = a + b

问数组c的维度是多少?

答: 因为B的列维数为1,所以先为B的列向量复制3次,使得A与B的行维数与列维数都相等,然后进行每项元素的相加,得:c.shape = (2, 3)

这个其实就是Python语法中的广播机制


另一种情况是A、B矩阵元素相乘,即A * B,只有当A与B的矩阵之间维数相等时,A、B才能相乘,若A矩阵的列数不等于B矩阵的列数,或A矩阵的行数不等于B矩阵的行数,则不能将两个矩阵相乘,程序会报错,如下:

a = np.random.randn(4, 3) # a.shape = (4, 3)
b = np.random.randn(3, 2) # b.shape = (3, 2)
c = a * b
# ValueError: operands could not be broadcast together with shapes (4,3) (3,2)

然而,当a,b矩阵的行数或列数中有一个相等时,乘法是可以成立的,如下:

# a,b矩阵的行数相等,列数不相等
a = np.random.randn(3, 3)
b = np.random.randn(3, 1)
c = a * b
"""
[[ 0.30044552  0.32163572  0.83089828]
 [-0.41384331  0.140933    0.20342014]
 [ 0.15084242 -0.24968459  0.06532467]]
"""

在这种情况下,将会使用广播机制,b会被复制三次,就会变成(3,3),再使用元素乘法。所以有: c.shape = (3, 3).

矩阵乘法

np.dot(a,b在a和b上执行矩阵乘法,而a * b执行元素方式的乘法。

例如下面的两个随机数组ab

a = np.random.randn(4, 3) # a.shape = (4, 3
b = np.random.randn(3, 2) # b.shape = (3, 2)
c = np.dot(a, b)

问c的维度是多少?

答: 两个矩阵相乘,获得的矩阵行数等于前一个矩阵的行数,列数等于后一个矩阵的列数c.shape = (4, 2)

广播机制的缺点

当使用numpy进行科学计算的时候,可能对产生一个秩为1的矩阵,例如:

import numpy as np
a = np.random.randn(5)
a.shape
# (5,)

此时,如果将a矩阵与a矩阵的转置相乘,你猜结果会如果

print(np.dot(a,a.T))
# 3.948322708713407

结果竟然得到一个数,而不是矩阵。

在来看看另一个例子:

A = np.random.randn(4,3)
B = np.sum(A, axis = 0)
B.shape

来猜测一些结果如何

答案是:(3,) 。这是因为对A矩阵进行行纵向相加后,返回了一个秩为1的矩阵。

那么为了确保A.shape(4,1)而不是(4,),则需要在sum函数中添加参数keepdims = True,这使我们的代码更加地严谨。

小结

在写神经网络时,不推荐使用类似的秩为1的矩阵,可能会造成一些误差。

但是可以将a转变为一个数组:

a = np.random.randn(5,1)
a.shape
# (5,1)

这个时候,就不会发生刚才的状况了。

小技巧

当自己不确定矩阵a的形状是否正确,则可以使用assert(a.shape==(m,n)来断言a的形状,此时如果a的形状错误,则程序会抛出异常,这样就不怕出错了。


未完待续~~~