Theano:为什么在这种情况下索引失败?

6

我将尝试在给定布尔值的情况下获取向量的最大值。

使用Numpy:

>>> this = np.arange(10)
>>> this[~(this>=5)].max()
4

但是使用Theano:
>>> that = T.arange(10, dtype='int32')
>>> that[~(that>=5)].max().eval()
9
>>> that[~(that>=5).nonzero()].max().eval()
Traceback (most recent call last):
  File "<pyshell#146>", line 1, in <module>
    that[~(that>=5).nonzero()].max().eval()
AttributeError: 'TensorVariable' object has no attribute 'nonzero'

为什么会发生这种情况?这是我忽略的微妙细节吗?

你的第二个程序出现了字面上的回溯,指出该数组没有nonzero()方法/属性,因此你不能像使用numpy数组那样使用它。 - Jeff Tratner
@JeffTratner:这与网站上提供的示例相反... - Noob Saibot
1
@NoobSailbot 你是否使用了正确的版本? - Jeff Tratner
@JeffTratner:theano.version.version 给我的回复是 '0.6.0rc3'。在这个版本中不支持 nonzero() 吗? - Noob Saibot
1个回答

9

您正在使用过于陈旧的Theano版本。实际上,tensor_var.nonzero()函数并未在任何发布版本中出现。您需要更新到最新版本。

在最新开发版中,我有以下内容:

>>> that[~(that>=5).nonzero()].max().eval()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: bad operand type for unary ~: 'tuple'

这是因为您的代码中缺少括号。下面是正确的代码:

>>> that[(~(that>=5)).nonzero()].max().eval()
array(9, dtype=int32)

但是我们仍然得到了意外的结果!问题在于Theano不支持bool类型。对int8进行~操作,实际上是对8位进行按位取反,而不是只对1位进行取反。它会得到这个结果:

>>> (that>=5).eval()
array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1], dtype=int8)
>>> (~(that>=5)).eval()
array([-1, -1, -1, -1, -1, -2, -2, -2, -2, -2], dtype=int8)

您可以使用以下方法移除 ~ :
>>> that[(that<5).nonzero()].max().eval()
array(4, dtype=int32)

1
很好的东西,谢谢。但是我有点困惑您所说的“development version”是什么意思?那就是我所读到的“bleeding-edge”吗?那不是应该是实验性的吗? - Noob Saibot
@nouiz,我只想说,非常感谢你的精彩回答+1。 - Tshilidzi Mudau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接