2015-10-15 69 views
6

我注意到,在theano,當一個創建基於1D numpy的陣列上的共享變量,這成爲一個載體,但不是排:創建theano共享行

import theano.tensor as T 
import theano, numpy 

shared_vector = theano.shared(numpy.zeros((10,))) 
print(shared_vector.type) 
# TensorType(float64, vector) 
print(shared_vector.broadcastable) 
# (False,) 

這同樣適用於一個1×N個矩陣,它成爲一個矩陣,但不是排:

shared_vector = theano.shared(numpy.zeros((1,10,))) 
print(shared_vector.type) 
# TensorType(float64, matrix) 
print(shared_vector.broadcastable) 
# (False, False) 

這是麻煩的,當我想一個M×N的矩陣添加至1 XN行向量,因爲共享矢量不在broadcastable第一個維度。首先,這是不行的:

row = T.row('row') 
mat=T.matrix('matrix') 
f=theano.function(
    [], 
    mat + row, 
    givens={ 
     mat: numpy.zeros((20,10), dtype=numpy.float32), 
     row: numpy.zeros((10,), dtype=numpy.float32) 
    }, 
    on_unused_input='ignore' 
) 

與錯誤:

TypeError: Cannot convert Type TensorType(float32, vector) (of Variable <TensorType(float32, vector)>) into Type TensorType(float32, row). You can try to manually convert <TensorType(float32, vector)> into a TensorType(float32, row). 

好吧,這是明確的,我們不能分配向量行。不幸的是,這也是不精:

row = T.matrix('row') 
mat=T.matrix('matrix') 
f=theano.function(
    [], 
    mat + row, 
    givens={ 
     mat: numpy.zeros((20,10), dtype=numpy.float32), 
     row: numpy.zeros((1,10,), dtype=numpy.float32) 
    }, 
    on_unused_input='ignore' 
) 
f() 

與錯誤:

ValueError: Input dimension mis-match. (input[0].shape[0] = 20, input[1].shape[0] = 1) 
Apply node that caused the error: Elemwise{add,no_inplace}(<TensorType(float32, matrix)>, <TensorType(float32, matrix)>) 
Inputs types: [TensorType(float32, matrix), TensorType(float32, matrix)] 
Inputs shapes: [(20, 10), (1, 10)] 
Inputs strides: [(40, 4), (40, 4)] 
Inputs values: ['not shown', 'not shown'] 

Backtrace when the node is created: 
    File "<ipython-input-55-0f03bee478ec>", line 5, in <module> 
    mat + row, 

HINT: Use the Theano flag 'exception_verbosity=high' for a debugprint and storage map footprint of this apply node. 

因此,我們不能只用一個1×N矩陣作爲行以及(因爲的第一維1×N矩陣不可廣播)。

問題依然存在,我們該做什麼?我如何創建一個類型行的共享變量,這樣我可以使用矩陣行添加進行廣播?

+0

我看來,我已經找到了,發佈後秒。我想我可以在矢量上使用.reshape,創建一個1×N矩陣,它具有可廣播(True,False) – Herbert

回答

2

使用reshape(1, N)的替代方法是使用​​作爲described in the documentation

下面是兩種方法的演示:

import numpy 
import theano 

x = theano.shared(numpy.arange(10)) 
print x 
print x.dimshuffle('x', 0).type 
print x.dimshuffle(0, 'x').type 
print x.reshape((1, x.shape[0])).type 
print x.reshape((x.shape[0], 1)).type 

f = theano.function([], outputs=[x, x.dimshuffle('x', 0), x.reshape((1, x.shape[0]))]) 
theano.printing.debugprint(f) 

這將打印

<TensorType(int32, vector)> 
TensorType(int32, row) 
TensorType(int32, col) 
TensorType(int32, row) 
TensorType(int32, col) 
DeepCopyOp [@A] '' 2 
|<TensorType(int32, vector)> [@B] 
DeepCopyOp [@C] '' 4 
|InplaceDimShuffle{x,0} [@D] '' 1 
    |<TensorType(int32, vector)> [@B] 
DeepCopyOp [@E] '' 6 
|Reshape{2} [@F] '' 5 
    |<TensorType(int32, vector)> [@B] 
    |MakeVector{dtype='int64'} [@G] '' 3 
    |TensorConstant{1} [@H] 
    |Shape_i{0} [@I] '' 0 
     |<TensorType(int32, vector)> [@B] 

證明該dimshuffle可能是優選的,因爲它涉及到比reshape更少的工作。

+0

爲了可讀性的原因,我總是喜歡重塑,但現在我會考慮使用dimshuffle。謝謝! – Herbert

1

我會用:

shared_row = theano.shared(numpy.zeros((1,10,)), broadcastable=(True, False)) 
print(shared_row.type) 
# TensorType(float64, row) 
print(shared_row.broadcastable) 
(True, False) 
+0

這不是正確答案嗎? –