2017-08-07 35 views
0

我試圖做一個簡單的T.zeros()操作,兩個向量的形狀在Theano中作爲參數的區別。Theano with tensor.zeros()和tensor.shape()作爲arg時的錯誤

事情是這樣的:

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: Elemwise{sub,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()函數,但它看起來效率不高。

回答

0

這個問題的核心是,在編譯時:

  • 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知道廣播尺寸,所以它的possbile告訴哪些形狀的軸的尺寸爲1,但不能更多。