broadcasting linalg.pinv on a 3D theano tensor

2019-09-06 15:25发布

问题:

in the example below, there is a 3d numpy matrix of size (4, 3, 3)+ a solution about how to calculate pinv of each of 4 of those 3*3 matrices in numpy. I also tried to use the same function worked in numpy, in theano hoping that it is implemented the same, but it failed. Any idea how to do it in theano?

dt = np.dtype(np.float32)

a=[[[12,3,1],
   [2,4,1],
   [2,4,2],],
   [[12,3,3],
   [2,4,4],
   [2,4,5],],
   [[12,3,6],
   [2,4,5],
   [2,4,4],],
   [[12,3,3],
   [2,4,5],
   [2,4,6]]]

a=np.asarray(a,dtype=dt)
print(a.shape)

apinv=np.zeros((4,3,3))
print(np.linalg.pinv(a[0,:,:]).shape)

#numpy solution
apinv = map(lambda n: np.linalg.pinv(n), a)
apinv = np.asarray(apinv,dtype=dt)

#theano solution (not working)
at=T.tensor3('a')
apinvt = map(lambda n: T.nlinalg.pinv(n), at)

The error is:

Original exception was:
Traceback (most recent call last):
  File "pydevd.py", line 2403, in <module>
    globals = debugger.run(setup['file'], None, None, is_module)
  File "pydevd.py", line 1794, in run
    launch(file, globals, locals)  # execute the script
  File "exp_thn_pinv_map.py", line 35, in <module>
    apinvt = map(lambda n: T.nlinalg.pinv(n), at)
  File "theano/tensor/var.py", line 549, in __iter__
    raise TypeError(('TensorType does not support iteration. '
TypeError: TensorType does not support iteration. Maybe you are using builtin.sum instead of theano.tensor.sum? (Maybe .max?)

回答1:

The error message is

Traceback (most recent call last):
  File "D:/Dropbox/source/intro_theano/pinv.py", line 32, in <module>
    apinvt = map(lambda n: T.nlinalg.pinv(n), at)
  File "d:\dropbox\source\theano\theano\tensor\var.py", line 549, in __iter__
    raise TypeError(('TensorType does not support iteration. '
TypeError: TensorType does not support iteration. Maybe you are using builtin.sum instead of theano.tensor.sum? (Maybe .max?)

This is occurring because, as the error message indicates, the symbolic variable at is not iterable.

The fundamental problem here is that you're incorrectly mixing immediately executed Python code with delayed execution Theano symbolic code.

You need to use a symbolic loop, not a Python loop. The correct solution is to use Theano's scan operator:

at=T.tensor3('a')
apinvt, _ = theano.scan(lambda n: T.nlinalg.pinv(n), at, strict=True)
f = theano.function([at], apinvt)
print np.allclose(f(a), apinv)