首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >广播失败:如何支配广播的轴心?

广播失败:如何支配广播的轴心?
EN

Stack Overflow用户
提问于 2019-07-16 23:43:30
回答 2查看 122关注 0票数 0

我有一个张量的大小(1000,30,16,16)。我在做如何使它正常化的实验。我试图在不同的情况下正常化,可能是频率轴等等。

以下工作:

代码语言:javascript
复制
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))

我得到:

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

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

(16、16)

(16,)

(1,)

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

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

它在广播失败时抛出一个错误。我有一个麻木不仁的解决方案,它使斧头和制造(30,)最后,以便广播工作,但我想知道是否有一个方法来决定如何广播应该做。而且,为什么这不是自动完成的?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-07-16 23:54:58

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

这解释了为什么在所有这些情况下广播工作:

代码语言:javascript
复制
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.mean(...)都从左边移除轴,(可能的话)离开右边的轴。因此,广播可以自动在左边添加新的轴。

相反,a - a.mean(axis=(2, 3))失败是因为a.mean(axis=(2,3))具有形状(1000, 30),并且只能广播到像(1, 1000, 30)(1, 1, 1000, 30)等形状。因为a具有形状(1000, 30, 16, 16),所以从右边的最后两个轴的长度是冲突的。

若要在本例中成功广播,需要在右侧使用添加新的轴

代码语言:javascript
复制
a - a.mean(axis=(2, 3))[..., np.newaxis, np.newaxis]

代码语言:javascript
复制
a - a.mean(axis=(2, 3))[..., None, None]

现在a.mean(axis=(2, 3))[..., None, None]有了shape (1000, 30, 1, 1),并且可以广播到(1000, 30, 16, 16)以使其与a的形状兼容。

医生们解释广播

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

代码语言:javascript
复制
    Image  (3d array): 256 x 256 x 3
    Scale  (1d array):             3
    Result (3d array): 256 x 256 x 3

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

票数 2
EN

Stack Overflow用户

发布于 2019-07-16 23:49:10

与隐式广播不同,您可以创建用于显式广播的附加轴,方法是对要添加的每个轴进行None切片。

要广播(30,)到(1000,30,16),切片如下:

代码语言:javascript
复制
a[None,:,None,None]

您可以看到,第二个轴被:切片,意思是“所有数据”,其余的轴是None,意思是“在这里创建一个用于广播的新轴”。

如果你想一想,这是好的,隐式广播有严格的规则,它如何运作。假设它可以自动以这种方式广播--如果这是真的,它将如何广播(30,30)?这是模棱两可的。就目前的规则而言,它并不含糊不清。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57066770

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档