numpy的广播和广播机制

NumPy的广播机制和重要,在机器学习、深度学习里的tensorflow和keras里使用了大量的广播计算,需深入理解广播机制。

Posted by Hilda on February 4, 2025

注意【广播】和【广播机制】是两个概念。

NumPy的广播机制和重要,在机器学习、深度学习里的tensorflow和keras里使用了大量的广播计算,需深入理解广播机制。

NumPy 广播(Broadcasting)

在 NumPy 中,广播(Broadcasting) 是一种强大的机制,它允许在不同形状的数组之间进行算术运算。通过广播,NumPy 可以在内部自动扩展数组的形状,使得不同形状的数组能够进行逐元素运算,而不需要显式地复制数据。

广播的核心思想是让不同形状的数组“对齐”,然后进行逐元素操作。广播机制能够使得代码更加高效,减少内存的使用,避免显式地扩展数组。

1 广播的规则:

为了让两个数组能够进行广播,它们的形状必须满足一定的条件。NumPy 在执行数组运算时,会按照以下规则进行广播:

  1. 如果两个数组的维度数不同,较小维度的数组会被扩展到与较大维度数组的维度数相同
  2. 如果两个数组在某个维度上的大小不同,则较小的数组会在该维度上重复扩展,使其与较大的数组匹配。这相当于沿着缺失的维度进行扩展。
  3. 如果两个数组在某个维度上的大小相同,或者其中一个数组的大小为 1,NumPy 会认为它们是兼容的,并按元素进行广播
  4. 如果两个数组的形状在某个维度上不匹配,且不满足上述条件,则会引发错误

2 广播示例

2.1 标量与数组的广播

当我们将一个标量与一个数组进行运算时,标量会自动扩展成一个与数组形状相同的数组,然后进行逐元素运算。

1
2
3
4
5
n = np.arange(12).reshape(3, 4)
n

a = n*2
a

image-20250204185809871

2.2 两个数组的广播

当两个数组具有不同形状时,NumPy 会尝试将它们的形状扩展到一致的形状,然后再进行元素级别的运算。

image-20250204190052268

解释如下:本来\(n1 = \begin{bmatrix} 0 & 1 & 2 \end{bmatrix}\),shape是(3,)而\(n2 = \begin{bmatrix} 0 \\ 1 \\ 2 \end{bmatrix}\),shape是(3, 1);在计算\(n1 + n2\)时,为了维度一致,\(n1\)和\(n2\)的维度都变成了(3, 3).

即,\(n1 = \begin{bmatrix} 0 & 1 & 2 \\ 0 & 1 & 2 \\ 0 & 1 & 2 \end{bmatrix}\),补充了第2行和第3行,用原先的第1行进行补充;\(n2 = \begin{bmatrix} 0 & 0 & 0 \\ 1 & 1 & 1 \\ 2 & 2 & 2 \end{bmatrix}\),补充了第2列和第3列,用原先的第1列的值进行补充。

现在就可以计算n1+n2了。\(n1 + n2 = \begin{bmatrix} 0 & 1 & 2 \\ 0 & 1 & 2 \\ 0 & 1 & 2 \end{bmatrix} + \begin{bmatrix} 0 & 0 & 0 \\ 1 & 1 & 1 \\ 2 & 2 & 2 \end{bmatrix} = \begin{bmatrix} 0 & 1 & 2 \\ 1 & 2 & 3 \\ 2 & 3 & 4 \end{bmatrix}\)

至此,解释清楚了。

2.3 不匹配的维度

如果两个数组的形状不兼容,且无法通过广播规则对其进行扩展,则会引发错误。

image-20250204191255371

广播机制

工作原理

广播的核心是从最后一个维度开始检查两个数组的形状是否匹配。下面是广播的几个步骤:

  1. 从右侧开始对比维度:比较两个数组的每个维度,若维度相同,则认为可以广播。若某个维度的大小不同,且其中一个数组在该维度的大小为 1,则可以沿该维度扩展。
  2. 扩展维度:如果维度大小不相同,且其中一个数组的维度为 1,则该数组会在该维度上“复制”元素,扩展为与另一个数组相同的大小。
  3. 如果形状不匹配且无法扩展,则会抛出 ValueError

总结

  • 广播 允许 NumPy 在不同形状的数组之间进行元素级别的运算,而无需显式地复制数据。
  • 广播机制通过对比数组的维度,从右到左检查是否可以进行扩展,使得不同形状的数组能够进行数学运算。
  • 广播规则非常有用,可以简化代码并提升计算效率,但在使用时要确保两个数组的形状兼容,否则会抛出错误。