使用 tensor.zeros() 和 tensor.shape() 作为参数的 Theano 错误

Posted

技术标签:

【中文标题】使用 tensor.zeros() 和 tensor.shape() 作为参数的 Theano 错误【英文标题】:Error in Theano with tensor.zeros() and tensor.shape() as arg 【发布时间】:2018-01-14 20:31:10 【问题描述】:

我正在尝试对T.zeros() 进行一个简单的操作,其中两个向量的形状之间的差异作为 Theano 中的参数。

类似这样的:

import theano as theano
import theano.tensor as T

x1 = T.ivector('x1')
x2 = T.ivector('x2')
shape_sub = T.sub(T.shape(x1),T.shape(x2))

zeros = T.zeros(shape_sub)

f = theano.function([x1, x2], zeros)        

但我得到一个值错误

ValueError: length not known: Elemwisesub,no_inplace [id A] ''   
|Shape [id B] ''   
| |x1 [id C]
|Shape [id D] ''   
  |x2 [id E]

这可能是因为 T.zeros() 的参数必须是包含形状的元组或列表,而不是包含减去形状的 ivector tensorType,这是 shape_sub 的输出。但是我应该如何实现这段代码呢?我不能在这里使用T.zeros_like(),因为它将整个张量作为输入,而不是它的形状。

我能想到的解决这个问题的唯一方法是对 shape_sub 的值使用共享变量,对其进行评估,然后将其提供给 T.zeros() 函数,但这似乎不是很有效。

【问题讨论】:

【参考方案1】:

这个问题的核心是,在编译时:

Theano 必须知道张量秩。 Theano 对张量形状的确切数字一无所知。 [1]

我认为这是针对 Tensorflow 中的静态张量形状的缺陷。

在您的代码中,Theano 知道 shape_sub 是一个向量,但不知道该向量的 长度。因此它无法确定zeros 调用的等级。 (实际上它应该知道,但是由于内部缺陷它只是忘记该信息)

您可以使用此代码得到相同的错误:

shp = T.ivector()
zs = T.zeros(shp)

一种可能的解决方案是对其进行硬编码:

x1_shp = T.shape(x1)
x2_shp = T.shape(x2)
assert x1.ndim == x2.ndim
zeros = T.zeros([x1_shp[i] - x2_shp[i] for i in range(x1.ndim)])

[1] 实际上 Theano 知道广播维度,因此可以判断哪些轴的形状具有大小 1,但仅此而已。

【讨论】:

以上是关于使用 tensor.zeros() 和 tensor.shape() 作为参数的 Theano 错误的主要内容,如果未能解决你的问题,请参考以下文章

如何使用tfrecord

ipython notebook的安装和使用

不同类型的TensorFlow SignatureDefs的目的是什么?

tensorflow基础-数据类型

TensorFlow一文弄懂CNN中的padding参数

详解Tensorboard及使用教程