【问题标题】:Dynamically broadcast a numpy array动态广播一个numpy数组
【发布时间】:2021-04-12 19:47:07
【问题描述】:

我目前有一个 1D numpy 数组 epsilons,它需要对数组 x 执行逐元素乘法。但是,x 的维度是动态的,并且随着以下 for 循环的每次迭代而变化:

for x in grads:
  x = x * epsilons
  print(grad)

epsilons 始终具有(M,) 的形状。但是,对于第一次迭代,x 采用(M,4,2) 的形状,而在第二次迭代中采用(M,4) 的形状(x 的形状随着代码迭代grads 而变化)。有没有办法可以自动将epsilons 广播到x 的形状,以便我可以对x 的任何形状执行这种逐元素乘法?

【问题讨论】:

  • 首先我假设你的意思是 grad = x * epsilons,不是吗?其次,您确定您的毕业生是(M,4)而不是(4,M)吗?如果它们是前者,我会得到一个“值错误:操作数不能与形状 (M, 4) (M,) 一起广播。如果它们是后者,那么可以执行 x * epsilon 并获得预期的结果,如果x.shape 是 (4, M) 或 (2, 4, M),或任何 (..., M)。
  • 你能把x改成(4,2,M)或(4,M)的形状吗?记住最后一个维度是最内层的,所以在 numpy 中添加(或删除)前导维度是最有意义的。
  • 您可能需要考虑使x 尺寸更加一致。在循环中扩大或缩小数组的成本可能很高,并且会导致错误。
  • 是的,没错。不幸的是,我的项目的性质要求我遍历 pytorch 神经网络的 parameter.grad 属性并对其进行修改。这些 parameter.grad 属性的形状和大小各不相同,这解释了我的问题的性质。

标签: python arrays numpy array-broadcasting


【解决方案1】:

您可以将epsilons 重塑为正确的形状。事实上,Numpy 会自动广播矢量形状(如 broadcast_to 调用),如果它具有兼容形状:相同的维度数应该至少相同,并且形状应该是完整的 1对于每个维度。 感谢@hpaulj 改进的解决方案。

# Reshape epsilons so that the vector value are along the first dimension (the least contiguous one)
reshapedEpsilons = epsilons.reshape((M,)+(1,)*(x.ndim-1))

# Broadcast automatically the vector values in the other dimensions so the result have the same shape than x
# Actual element-wise multiplication
x *= reshapedEpsilons

PS:注意a = a * b 应该创建一个新矩阵,并且效率低于a *= b 就地修改值。

【讨论】:

  • 我认为您不需要 broadcast_to 步骤。
  • reshapedEpsilons = epsilons.reshape((M,)+(1,)*(x.ndim-1)) 是另一种选择
  • @hpaulj 确实。谢谢你。我编辑了帖子以改进它。
  • 谢谢大家,这解决了!我需要重塑新的 epsilon,只是不确定需要将什么传递给 .reshape() 才能正确执行此操作!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-26
  • 1970-01-01
  • 1970-01-01
  • 2017-06-18
  • 1970-01-01
相关资源
最近更新 更多