当前位置: 首页 > 知识库问答 >
问题:

广播失败:如何指挥广播的轴心?

赏彭薄
2023-03-14

我有一个大小为(1000,30,16,16)的张量。我正在做如何使其正常化的实验。我正在尝试跨案例进行规范化,可能是频率轴等。

以下工作:

a = np.random.rand(1000, 30, 16, 16)
a - a.mean(axis=(0, )) #==> it works
a - a.mean(axis=(0, 1)) #==> successful broadcast
a - a.mean(axis=(0, 1, 2)) #==> works well
a - a.mean(axis=(0, 1, 2, 3)) #==> succesful broadcast of scalar mean to all a values


#Those however fail:
a - a.mean(axis=(2, 3)) 
#OR:
a - a.mean(axis=(0, 2, 3))

我得到:

操作数不能与形状一起广播(1000, 30, 16, 16) (30,)

它似乎在(30,16,16)这样的简单情况下成功地完成了丢失的轴

(16, 16)

(16,)

(1,)

但是当丢失的轴是右边而不是左边时失败,例如:(1000,30),它不能将其广播到(1000, 30, 16, 16)。

具体来说,我的问题是,我如何能规定广播是如何进行的?例如,我有(30,),我想把它广播给(1000, 30, 16, 16)

它抛出一个错误,因为它无法广播。我有一个奇怪的解决方案,排列轴,使(30)排在最后,这样广播就可以工作了,但是我想知道是否有办法规定广播应该如何进行。此外,为什么这不是自动完成的?

共有2个答案

华修永
2023-03-14

您可以通过对每个要添加的轴使用None进行切片来创建用于显式广播的附加轴,而不是隐式广播。

要播放(30,)到(1000,30,16,16),请按如下方式进行切片:

a[None,:,None,None]

您可以看到,第二个轴被切片为,表示“所有数据”,其余轴为None,表示“在此处创建一个新轴用于广播”。

如果你仔细想想,隐式广播对其工作方式有严格的规定是件好事。想象一下,它可以自动以这种方式广播——如果这是真的,它将如何广播(30,)到(30,30)?这将是模棱两可的。根据目前的规则,这并不含糊。

翟誉
2023-03-14

默认情况下,NumPy通过在左侧添加新坐标轴进行广播。例如,如果数组具有形状(30, 16, 16),那么它可以自动广播到形状(1, 30, 16, 16)。长度为1的新轴可以进一步广播到与它正在广播到的阵列相匹配的任何必要大小。

这就解释了为什么广播在所有这些情况下都有效:

a = np.random.rand(1000, 30, 16, 16)
a - a.mean(axis=(0, )) #==> it works
a - a.mean(axis=(0, 1)) #==> successful broadcast
a - a.mean(axis=(0, 1, 2)) #==> works well
a - a.mean(axis=(0, 1, 2, 3)) #==> succesful broadcast of scalar mean to all a values

在每种情况下,a.平均值(…) 从左侧删除轴,并(可能)将轴保留在右侧。因此,自动将新轴添加回左侧没有问题。

相比之下,a-a.mean(axis=(2,3))失败,因为a.mean(axis=(2,3))具有形状(1000,30),并且只能广播多达(1,1000,30)(1,1000,30)等形状。由于a具有形状(1000,30,16,16),因此从右侧开始的最后两个轴的长度冲突。

要在这种情况下成功广播,需要使用在右侧显式添加新轴

a - a.mean(axis=(2, 3))[..., np.newaxis, np.newaxis]

或者

a - a.mean(axis=(2, 3))[..., None, None]

现在a.mean(轴=(2,3))[...,无,无]具有形状(1000, 30, 1, 1)并且可以广播到(1000, 30, 16, 16)以在形状上兼容用a.

医生解释广播时说

根据广播规则排列这些阵列的后轴大小,表明它们是兼容的:

    Image  (3d array): 256 x 256 x 3
    Scale  (1d array):             3
    Result (3d array): 256 x 256 x 3

请注意,对齐是通过正确对齐形状来完成的。空轴用1填充。说在左边增加新的轴只是谈论同样想法的另一种方式。

 类似资料:
  • 输出如下: 如果两个数组的维数不相同,则元素到元素的操作是不可能的。 然而,在 NumPy 中仍然可以对形状不相似的数组进行操作,因为它拥有广播功能。 较小的数组会广播到较大数组的大小,以便使它们的形状可兼容。 如果满足以下规则,可以进行广播: 如果输入在每个维度中的大小与输出大小匹配,或其值正好为 1,则在计算中可它。 如果上述规则产生有效结果,并且满足以下条件之一,那么数组被称为可广播的。 数

  • 原文:Broadcasting 另见:numpy.broadcast 术语广播描述了NumPy在算术运算时如何处理不同形状的数组。 在某些条件下,较小的数组“广播”成较大的数组以便有相同的形状。 广播提供了一种矢量化操作数组的方法,这样可以在C而不是Python中进行循环。 它可以在不制作不必要的数据副本的情况下实现这一点,并且通常可以实现高效 然而,有些情况下广播是一个坏主意,因为它会导致内存使

  • SocketIO另外一个非常有用的特性就是广播消息。Flask-SocketIO中,只要将broadcast = True这个可选参数加到send()和emit()中即可: @socketio.on('my event') def handle_my_custom_event(data): emit('my response', data, broadcast=True) 当一个消息以广播选

  • 我们所有的例子这一点利用传输方式称为“单播”:“将消息发送给一个网络拥有唯一地址的目的地”,这种模式支持连接和无连接协议。 然而,UDP 提供了额外的传输模式对多个接收者发送消息: 多播:传送给一组主机 广播:传送到网络上的所有主机(或子网) 示例应用程序在本章将说明使用 UDP 广播发送消息,可以接收到所有主机在同一网络。为此我们将使用特殊的“有限广播”或“零”网络地址255.255.255.2

  • 广播意味着向所有连接的客户端发送消息。 广播可以在多个级别完成。 我们可以将消息发送到所有连接的客户端,命名空间上的客户端和特定房间中的客户端。 要向所有客户端广播事件,我们可以使用io.sockets.emit方法。 Note - 这将向ALL连接的客户端发出事件(事件可能触发了此事件的套接字)。 在此示例中,我们将向所有用户广播已连接客户端的数量。 更新app.js文件以包含以下内容。 var

  • 术语broadcasting是指NumPy在算术运算期间处理不同形状的阵列的能力。 对数组的算术运算通常在相应的元素上完成。 如果两个阵列具有完全相同的形状,则可以平滑地执行这些操作。 例子1 (Example 1) import numpy as np a = np.array([1,2,3,4]) b = np.array([10,20,30,40]) c = a * b print