Theano 的奇怪类型错误

Strange TypeError with Theano

Traceback (most recent call last):
      File "test.py", line 37, in <module>
        print convLayer1.output.shape.eval({x:xTrain})
      File "/Volumes/TONY/anaconda/lib/python2.7/site-packages/theano/gof/graph.py", line 415, in eval
        rval = self._fn_cache[inputs](*args)
      File "/Volumes/TONY/anaconda/lib/python2.7/site-packages/theano/compile/function_module.py", line 513, in __call__
        allow_downcast=s.allow_downcast)
      File "/Volumes/TONY/anaconda/lib/python2.7/site-packages/theano/tensor/type.py", line 180, in filter
        "object dtype", data.dtype)
    TypeError

这是我的代码:

import scipy.io as sio
import numpy as np
import theano.tensor as T
from theano import shared

from convnet3d import ConvLayer, NormLayer, PoolLayer, RectLayer
from mlp import LogRegr, HiddenLayer, DropoutLayer
from activations import relu, tanh, sigmoid, softplus

dataReadyForCNN = sio.loadmat("DataReadyForCNN.mat")

xTrain = dataReadyForCNN["xTrain"]
# xTrain = np.random.rand(10, 1, 5, 6, 2).astype('float64')
xTrain.shape

dtensor5 = T.TensorType('float64', (False,)*5)
x = dtensor5('x') # the input data

yCond = T.ivector()

# input = (nImages, nChannel(nFeatureMaps), nDim1, nDim2, nDim3)

kernel_shape = (5,6,2)
fMRI_shape = (51, 61, 23)
n_in_maps = 1 # channel
n_out_maps = 5 # num of feature maps, aka the depth of the neurons
num_pic = 2592

layer1_input = x

# layer1_input.eval({x:xTrain}).shape
# layer1_input.shape.eval({x:numpy.zeros((2592, 1, 51, 61, 23))})

convLayer1 = ConvLayer(layer1_input, n_in_maps, n_out_maps, kernel_shape, fMRI_shape, 
                       num_pic, tanh)

print convLayer1.output.shape.eval({x:xTrain})

这真的很奇怪,因为错误没有在 Jupyter 中抛出(但它需要很长时间才能 运行 最后内核关闭我真的不知道为什么),但是当我移动它时shell 和 运行 python fileName.py 错误被抛出。

问题出在scipy中的loadmat。您得到的类型错误是由 Theano 中的这段代码抛出的:

if not data.flags.aligned:
    ...
    raise TypeError(...)

现在,当您从原始数据在 numpy 中创建一个新数组时,它通常会对齐:

>>> a = np.array(2)
>>> a.flags.aligned
True

但是如果你 savemat / loadmat 它,标志的值会丢失:

>>> savemat('test', {'a':a})
>>> a2 = loadmat('test')['a']
>>> a2.flags.aligned
False

(似乎讨论了这个特定问题 here

解决它的一种快速而肮脏的方法是从您加载的数组创建一个新的 numpy 数组:

>>> a2 = loadmat('test')['a']
>>> a3 = np.array(a2)
>>> a3.flags.aligned
True

因此,对于您的代码:

dataReadyForCNN = np.array(sio.loadmat("DataReadyForCNN.mat"))