对theano函数的错误参数,维数错误

时间:2016-03-26 07:34:10

标签: shape theano mismatch lasagne

我使用烤宽面条和theano预测来自VGG的回归任务的20个数字。对于我写的一个示例脚本,图像的数量是100.我认为我做了一些愚蠢的事情,但我被卡住了。

在线查看,对于使用nolearn的用户,可以通过指定regression=True来修复,但我只是使用烤宽面条

所以:

('X.shape', (100, 3, 224, 224))
('y.shape', (100, 20))

这是确切的错误消息

Traceback (most recent call last):
  File "script_1.py", line 167, in <module>
    loss = train_batch()
  File "script_1.py", line 90, in train_batch
    return train_fn(X_tr[ix], y_tr[ix])
  File "/usr/local/lib/python2.7/dist-packages/Theano-0.8.0rc1-py2.7.egg/theano/compile/function_module.py", line 786, in __call__
    allow_downcast=s.allow_downcast)
  File "/usr/local/lib/python2.7/dist-packages/Theano-0.8.0rc1-py2.7.egg/theano/tensor/type.py", line 177, in filter
    data.shape))
TypeError: ('Bad input argument to theano function with name "script_1.py:159"  at index 1(0-based)', 'Wrong number of dimensions: expected 1, got 2 with shape (16, 20).')

这是模型

def build_model():
    net = {}
    net['input'] = InputLayer((None, 3, 224, 224))
    net['conv1'] = ConvLayer(net['input'], num_filters=96, filter_size=7, stride=2, flip_filters=False)
     ...............
    net['drop7'] = DropoutLayer(net['fc7'], p=0.5)
    net['fc8'] = DenseLayer(net['drop7'], num_units=20, nonlinearity=None)
    return net

发电机:

def batches(iterable, N):
    chunk = []
    for item in iterable:
        chunk.append(item)
        if len(chunk) == N:
            yield chunk
            chunk = []
    if chunk:
        yield chunk
def train_batch():
    ix = range(len(y_tr))
    np.random.shuffle(ix)
    ix = ix[:BATCH_SIZE]
    return train_fn(X_tr[ix], y_tr[ix])

相关培训代码段

X_sym = T.tensor4()
y_sym = T.ivector()
output_layer = net['fc8']
prediction = lasagne.layers.get_output(output_layer, X_sym)
loss = lasagne.objectives.squared_error(prediction, y_sym)
loss = loss.mean()
acc = T.mean(T.eq(T.argmax(prediction, axis=1), y_sym), dtype=theano.config.floatX)
params = lasagne.layers.get_all_params(output_layer, trainable=True)
updates = lasagne.updates.nesterov_momentum(loss, params, learning_rate=0.0001, momentum=0.9)

train_fn = theano.function([X_sym, y_sym], loss, updates=updates)
val_fn = theano.function([X_sym, y_sym], [loss, acc])
pred_fn = theano.function([X_sym], prediction)

for epoch in range(5):
    for batch in range(25):
       loss = train_batch()
.....

1 个答案:

答案 0 :(得分:1)

你的预测输出有形状(batchsize,20),但你的y_sym变量是一个ivector类型,所以它是一个长度为batchsize的向量,大概是。我不确定这是否是造成错误的原因,但我不认为你可以计算这两个量的平方误差项。一个是矩阵,另一个是矢量,它们的形状似乎没有对齐?

你的回归目标是什么?如果您预测每个数据点的20个数字,您的y_sym可能应该是一个矩阵,那么您可以计算平方误差项。

另一种可能性是改变你的最后一层,使非线性成为sigmoid。这样,您就可以将卷积神经网络解释为生成多标签概率。然后,您可以综合生成回归的多标签概率目标变量。一个例子是,比如数据点x有多个标签0,1,10。你可以创建一个20长度的向量,其中0,1,10对于一些小的a就像1-a,其他条目是小的正数。

您还可以将目标函数切换为二进制交叉熵。在这种情况下,我们不执行回归。但是,我们仍然认为我们的网络输出的是分数矩阵,而不是 vector 。这通常是在检测图像中存在K个不同物体时使用的损失函数(例如猫,狗,人,汽车,自行车等),例如,多标签分类。如果您想尝试这条路线,我们将按如下方式更改最后一层:

net['fc8'] = DenseLayer(net['drop7'], num_units=20, nonlinearity=sigmoid)

现在我将把我的网络解释为输出概率;每个概率将表示关于我们的网络是否认为对象类在图像中的置信度分数。

我们现在将有以下损失功能:

X_sym = T.tensor4()
y_sym = T.imatrix() 
output_layer = net['fc8']
probabilities = lasagne.layers.get_output(output_layer, X_sym)
loss = lasagne.objectives.binary_crossentropy(probabilities, y_sym)
loss = loss.mean()
... the rest of the update stuff...
train_fn = theano.function([X_sym, y_sym], loss, updates=updates)

这里的关键区别是我们的目标变量y_sym现在是一个imatrix。这必须是{0,1}值(批量大小,K)大小的矩阵,其中0表示图像中不存在的对象,1表示图像中存在的对象。

为了计算多标签预测的准确性,通常使用F1分数。 Here是如何使用scikit-learn计算F1得分的参考。在这种情况下,我们的验证功能会有所不同,它可能看起来像这样:

 from sklearn.metrics import f1_score
 probabilities_fn = theano.function([X_sym], probabilities)
 confidence_threshold = .5 
 predictions = np.where(probabilities_fn(X_sym) > confidence_threshold, 1, 0)  
 f1_score(y_true, predictions, average='micro')

上面的代码片段返回了我们网络的概率/置信度分数,以及我们置信度阈值参数的任何概率,我选择.5,我们将其解释为存在的类标签。